mirror of
https://github.com/zhigang1992/GitHawk.git
synced 2026-04-16 08:08:45 +08:00
[ADD] Bookmarks per user account (#738)
This commit is contained in:
committed by
Ryan Nystrom
parent
908463a31a
commit
199ce48047
@@ -9,26 +9,33 @@
|
||||
import Foundation
|
||||
|
||||
final class BookmarksStore {
|
||||
static let shared = BookmarksStore()
|
||||
|
||||
private let archivePath: String = {
|
||||
return FileManager.default
|
||||
.urls(for: .documentDirectory, in: .userDomainMask)
|
||||
// crash intentionally on startup if doesn't exist
|
||||
.first!
|
||||
.appendingPathComponent("bookmarks")
|
||||
.path
|
||||
}()
|
||||
private var _bookmarks: Set<BookmarkModel>
|
||||
private let fileManager = FileManager.default
|
||||
private var documentDirectory: FileManager.SearchPathDirectory {
|
||||
return .documentDirectory
|
||||
}
|
||||
|
||||
private var archivePath: String {
|
||||
guard let path = NSSearchPathForDirectoriesInDomains(documentDirectory, .userDomainMask, true).first else {
|
||||
fatalError("App document directory cannot be found")
|
||||
}
|
||||
|
||||
let folder = URL(fileURLWithPath: path).appendingPathComponent("com.whoisryannystrom.freetime.bookmarks")
|
||||
if !fileManager.fileExists(atPath: folder.path) {
|
||||
try? fileManager.createDirectory(at: folder, withIntermediateDirectories: false, attributes: nil)
|
||||
}
|
||||
return folder.appendingPathComponent(token).path
|
||||
}
|
||||
|
||||
private var token: String
|
||||
private var _bookmarks: Set<BookmarkModel> = []
|
||||
|
||||
// MARK: Init
|
||||
|
||||
init() {
|
||||
if let bookmarks = NSKeyedUnarchiver.unarchiveObject(withFile: archivePath) as? Set<BookmarkModel> {
|
||||
_bookmarks = bookmarks
|
||||
} else {
|
||||
_bookmarks = []
|
||||
}
|
||||
init(_ userToken: String?) {
|
||||
guard let userToken = userToken else { fatalError() }
|
||||
token = userToken
|
||||
refresh()
|
||||
}
|
||||
|
||||
// MARK: Public API
|
||||
@@ -53,13 +60,31 @@ final class BookmarksStore {
|
||||
}
|
||||
|
||||
var bookmarks: [BookmarkModel] {
|
||||
refresh()
|
||||
return Array(_bookmarks)
|
||||
}
|
||||
|
||||
// MARK: Private API
|
||||
|
||||
func archive() {
|
||||
NSKeyedArchiver.archiveRootObject(_bookmarks, toFile: self.archivePath)
|
||||
|
||||
func refresh() {
|
||||
if let bookmarks = NSKeyedUnarchiver.unarchiveObject(withFile: archivePath) as? Set<BookmarkModel> {
|
||||
_bookmarks = bookmarks
|
||||
}
|
||||
}
|
||||
|
||||
func archive() {
|
||||
NSKeyedArchiver.archiveRootObject(_bookmarks, toFile: archivePath)
|
||||
}
|
||||
|
||||
func clearStorage() {
|
||||
do {
|
||||
try FileManager.default.removeItem(atPath: archivePath)
|
||||
} catch {
|
||||
print("Can not delete bookmarks file")
|
||||
}
|
||||
}
|
||||
|
||||
var bookmarkPath: String {
|
||||
return archivePath
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ TabNavRootViewControllerType {
|
||||
|
||||
private let client: GithubClient
|
||||
private let cellIdentifier = "bookmark_cell"
|
||||
private let bookmarkStore = BookmarksStore.shared
|
||||
private let bookmarkStore:BookmarksStore
|
||||
|
||||
private var searchController: UISearchController {
|
||||
let controller = UISearchController(searchResultsController: nil)
|
||||
@@ -39,6 +39,8 @@ TabNavRootViewControllerType {
|
||||
|
||||
init(client: GithubClient) {
|
||||
self.client = client
|
||||
self.bookmarkStore = BookmarksStore(client.userSession?.token)
|
||||
|
||||
super.init(nibName: nil, bundle: nil)
|
||||
}
|
||||
|
||||
|
||||
@@ -282,7 +282,16 @@ IssueCommentSectionControllerDelegate {
|
||||
title: current.title.attributedText.string
|
||||
)
|
||||
|
||||
return AlertAction.bookmark(bookmarkModel)
|
||||
let store = BookmarksStore(client.userSession?.token)
|
||||
let isNewBookmark = !store.contains(bookmark: bookmarkModel)
|
||||
return AlertAction.toggleBookmark(isNewBookmark) { _ in
|
||||
if isNewBookmark {
|
||||
store.add(bookmark: bookmarkModel)
|
||||
} else {
|
||||
store.remove(bookmark: bookmarkModel)
|
||||
}
|
||||
Haptic.triggerNotification(.success)
|
||||
}
|
||||
}
|
||||
|
||||
@objc
|
||||
|
||||
@@ -112,7 +112,17 @@ NewIssueTableViewControllerDelegate {
|
||||
owner: repo.owner,
|
||||
hasIssueEnabled: repo.hasIssuesEnabled
|
||||
)
|
||||
return AlertAction.bookmark(bookmarkModel)
|
||||
let store = BookmarksStore(client.userSession?.token)
|
||||
let isNewBookmark = !store.contains(bookmark: bookmarkModel)
|
||||
return AlertAction.toggleBookmark(isNewBookmark) { _ in
|
||||
if isNewBookmark {
|
||||
store.add(bookmark: bookmarkModel)
|
||||
}
|
||||
else {
|
||||
store.remove(bookmark: bookmarkModel)
|
||||
}
|
||||
Haptic.triggerNotification(.success)
|
||||
}
|
||||
}
|
||||
|
||||
@objc
|
||||
|
||||
@@ -138,19 +138,8 @@ struct AlertAction {
|
||||
return UIAlertAction(title: Constants.Strings.clearAll, style: .destructive, handler: handler)
|
||||
}
|
||||
|
||||
static func bookmark(_ bookmark: BookmarkModel) -> UIAlertAction {
|
||||
let isNewBookmark = !BookmarksStore.shared.contains(bookmark: bookmark)
|
||||
static func toggleBookmark(_ isNewBookmark: Bool, handler: AlertActionBlock? = nil) -> UIAlertAction {
|
||||
let title = isNewBookmark ? Constants.Strings.bookmark : Constants.Strings.removeBookmark
|
||||
return UIAlertAction(
|
||||
title: title,
|
||||
style: isNewBookmark ? .default : .destructive
|
||||
) { _ in
|
||||
if isNewBookmark {
|
||||
BookmarksStore.shared.add(bookmark: bookmark)
|
||||
} else {
|
||||
BookmarksStore.shared.remove(bookmark: bookmark)
|
||||
}
|
||||
Haptic.triggerNotification(.success)
|
||||
}
|
||||
return UIAlertAction(title: title, style: isNewBookmark ? .default : .destructive, handler: handler)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,58 +10,67 @@ import XCTest
|
||||
@testable import Freetime
|
||||
|
||||
final class BookmarkStoreTests: XCTestCase {
|
||||
|
||||
var store: BookmarksStore!
|
||||
|
||||
override func setUp() {
|
||||
super.setUp()
|
||||
store = BookmarksStore("user_token")
|
||||
store.clear() // for a clean start
|
||||
}
|
||||
|
||||
override func tearDown() {
|
||||
super.tearDown()
|
||||
BookmarksStore.shared.clear()
|
||||
store.clear()
|
||||
}
|
||||
|
||||
func test_addBookMark() {
|
||||
let b1 = BookmarkModel(type: .repo, name: "GitHawk", owner: "rizwankce")
|
||||
|
||||
BookmarksStore.shared.add(bookmark: b1)
|
||||
store.add(bookmark: b1)
|
||||
|
||||
XCTAssert(BookmarksStore.shared.bookmarks.count == 1)
|
||||
XCTAssert(BookmarksStore.shared.bookmarks.first == b1)
|
||||
XCTAssert(store.bookmarks.count == 1)
|
||||
XCTAssert(store.bookmarks.first == b1)
|
||||
}
|
||||
|
||||
func test_duplicateBookmarks() {
|
||||
let b1 = BookmarkModel(type: .repo, name: "GitHawk", owner: "rizwankce")
|
||||
let b2 = BookmarkModel(type: .repo, name: "GitHawk", owner: "rizwankce")
|
||||
|
||||
BookmarksStore.shared.add(bookmark: b1)
|
||||
BookmarksStore.shared.add(bookmark: b2)
|
||||
store.add(bookmark: b1)
|
||||
store.add(bookmark: b2)
|
||||
|
||||
XCTAssert(BookmarksStore.shared.bookmarks.count == 1)
|
||||
XCTAssert(store.bookmarks.count == 1)
|
||||
}
|
||||
|
||||
func test_clearBookmarks() {
|
||||
let b1 = BookmarkModel(type: .repo, name: "GitHawk", owner: "rizwankce")
|
||||
|
||||
BookmarksStore.shared.add(bookmark: b1)
|
||||
BookmarksStore.shared.clear()
|
||||
store.add(bookmark: b1)
|
||||
store.clear()
|
||||
|
||||
XCTAssert(BookmarksStore.shared.bookmarks.count == 0)
|
||||
XCTAssert(store.bookmarks.isEmpty)
|
||||
}
|
||||
|
||||
func test_removeBookmark() {
|
||||
let b1 = BookmarkModel(type: .repo, name: "GitHawk", owner: "rizwankce")
|
||||
|
||||
BookmarksStore.shared.add(bookmark: b1)
|
||||
BookmarksStore.shared.remove(bookmark: b1)
|
||||
store.add(bookmark: b1)
|
||||
store.remove(bookmark: b1)
|
||||
|
||||
XCTAssert(BookmarksStore.shared.bookmarks.count == 0)
|
||||
XCTAssert(store.bookmarks.count == 0)
|
||||
}
|
||||
|
||||
func test_containsBookmark() {
|
||||
func test_bookmarksFromDifferentUser() {
|
||||
let b1 = BookmarkModel(type: .repo, name: "GitHawk", owner: "rizwankce")
|
||||
|
||||
BookmarksStore.shared.add(bookmark: b1)
|
||||
|
||||
XCTAssert(BookmarksStore.shared.contains(bookmark: b1))
|
||||
|
||||
let store1 = BookmarksStore("user_token1")
|
||||
let store2 = BookmarksStore("user_token2")
|
||||
|
||||
store1.add(bookmark: b1)
|
||||
store2.add(bookmark: b1)
|
||||
|
||||
XCTAssert(store1.bookmarks.count == 1)
|
||||
XCTAssert(store2.bookmarks.count == 1)
|
||||
XCTAssert(store1.bookmarkPath != store2.bookmarkPath)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user