mirror of
https://github.com/kiwix/kiwix-apple.git
synced 2025-09-27 13:59:04 -04:00
Book detail bookmark
This commit is contained in:
parent
b39774f521
commit
8ab153b0e8
@ -8,8 +8,10 @@
|
|||||||
|
|
||||||
import UIKit
|
import UIKit
|
||||||
import CoreData
|
import CoreData
|
||||||
|
import Operations
|
||||||
|
import DZNEmptyDataSet
|
||||||
|
|
||||||
class BookmarkController: UITableViewController, NSFetchedResultsControllerDelegate {
|
class BookmarkController: UITableViewController, NSFetchedResultsControllerDelegate, DZNEmptyDataSetSource, DZNEmptyDataSetDelegate {
|
||||||
|
|
||||||
var book: Book?
|
var book: Book?
|
||||||
|
|
||||||
@ -17,6 +19,75 @@ class BookmarkController: UITableViewController, NSFetchedResultsControllerDeleg
|
|||||||
|
|
||||||
override func viewDidLoad() {
|
override func viewDidLoad() {
|
||||||
super.viewDidLoad()
|
super.viewDidLoad()
|
||||||
|
title = LocalizedStrings.bookmarks
|
||||||
|
clearsSelectionOnViewWillAppear = true
|
||||||
|
tableView.estimatedRowHeight = 66.0
|
||||||
|
tableView.rowHeight = UITableViewAutomaticDimension
|
||||||
|
tableView.allowsMultipleSelectionDuringEditing = true
|
||||||
|
tableView.emptyDataSetSource = self
|
||||||
|
tableView.emptyDataSetDelegate = self
|
||||||
|
}
|
||||||
|
|
||||||
|
override func setEditing(editing: Bool, animated: Bool) {
|
||||||
|
super.setEditing(editing, animated: animated)
|
||||||
|
navigationItem.leftBarButtonItem = editing ? UIBarButtonItem(barButtonSystemItem: .Trash) : nil
|
||||||
|
navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: editing ? .Done : .Edit)
|
||||||
|
navigationItem.leftBarButtonItem?.target = self
|
||||||
|
navigationItem.leftBarButtonItem?.action = #selector(BookmarkController.trashButtonTapped(_:))
|
||||||
|
navigationItem.rightBarButtonItem?.target = self
|
||||||
|
navigationItem.rightBarButtonItem?.action = #selector(BookmarkController.editButtonTapped(_:))
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - Action
|
||||||
|
|
||||||
|
func trash(articles articles: [Article]) {
|
||||||
|
let operation = BookmarkTrashOperation(articles: articles)
|
||||||
|
operation.addObserver(DidFinishObserver { _ in
|
||||||
|
NSOperationQueue.mainQueue().addOperationWithBlock({
|
||||||
|
guard self.fetchedResultController.fetchedObjects?.count == 0 else {return}
|
||||||
|
self.navigationController?.popViewControllerAnimated(true)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
GlobalQueue.shared.addOperation(operation)
|
||||||
|
}
|
||||||
|
|
||||||
|
func trashButtonTapped(sender: UIBarButtonItem) {
|
||||||
|
guard editing else {return}
|
||||||
|
guard let selectedIndexPathes = tableView.indexPathsForSelectedRows else {return}
|
||||||
|
let articles = selectedIndexPathes.flatMap() {fetchedResultController.objectAtIndexPath($0) as? Article}
|
||||||
|
trash(articles: articles)
|
||||||
|
}
|
||||||
|
|
||||||
|
@IBAction func editButtonTapped(sender: UIBarButtonItem) {
|
||||||
|
setEditing(!editing, animated: true)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - Empty table datasource & delegate
|
||||||
|
|
||||||
|
func imageForEmptyDataSet(scrollView: UIScrollView!) -> UIImage! {
|
||||||
|
return UIImage(named: "BookmarkColor")
|
||||||
|
}
|
||||||
|
|
||||||
|
func titleForEmptyDataSet(scrollView: UIScrollView!) -> NSAttributedString! {
|
||||||
|
let text = NSLocalizedString("Bookmarks", comment: "Bookmarks view title")
|
||||||
|
let attributes = [NSFontAttributeName: UIFont.boldSystemFontOfSize(18.0),
|
||||||
|
NSForegroundColorAttributeName: UIColor.darkGrayColor()]
|
||||||
|
return NSAttributedString(string: text, attributes: attributes)
|
||||||
|
}
|
||||||
|
|
||||||
|
func descriptionForEmptyDataSet(scrollView: UIScrollView!) -> NSAttributedString! {
|
||||||
|
let text = NSLocalizedString("To add a bookmark, long press the star button when reading an article", comment: "Bookmarks view message")
|
||||||
|
let style = NSMutableParagraphStyle()
|
||||||
|
style.lineBreakMode = .ByWordWrapping
|
||||||
|
style.alignment = .Center
|
||||||
|
let attributes = [NSFontAttributeName: UIFont.boldSystemFontOfSize(14.0),
|
||||||
|
NSForegroundColorAttributeName: UIColor.lightGrayColor(),
|
||||||
|
NSParagraphStyleAttributeName: style]
|
||||||
|
return NSAttributedString(string: text, attributes: attributes)
|
||||||
|
}
|
||||||
|
|
||||||
|
func spaceHeightForEmptyDataSet(scrollView: UIScrollView!) -> CGFloat {
|
||||||
|
return 30.0
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - Table view data source
|
// MARK: - Table view data source
|
||||||
@ -32,9 +103,15 @@ class BookmarkController: UITableViewController, NSFetchedResultsControllerDeleg
|
|||||||
|
|
||||||
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
|
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
|
||||||
let article = fetchedResultController.objectAtIndexPath(indexPath) as? Article
|
let article = fetchedResultController.objectAtIndexPath(indexPath) as? Article
|
||||||
let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath)
|
if let _ = article?.snippet {
|
||||||
cell.textLabel?.text = article?.title
|
let cell = tableView.dequeueReusableCellWithIdentifier("BookmarkSnippetCell", forIndexPath: indexPath)
|
||||||
return cell
|
configureSnippetCell(cell, atIndexPath: indexPath)
|
||||||
|
return cell
|
||||||
|
} else {
|
||||||
|
let cell = tableView.dequeueReusableCellWithIdentifier("BookmarkCell", forIndexPath: indexPath)
|
||||||
|
configureCell(cell, atIndexPath: indexPath)
|
||||||
|
return cell
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func configureCell(cell: UITableViewCell, atIndexPath indexPath: NSIndexPath) {
|
func configureCell(cell: UITableViewCell, atIndexPath indexPath: NSIndexPath) {
|
||||||
@ -49,6 +126,49 @@ class BookmarkController: UITableViewController, NSFetchedResultsControllerDeleg
|
|||||||
cell.subtitleLabel.text = article.book?.title
|
cell.subtitleLabel.text = article.book?.title
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func configureSnippetCell(cell: UITableViewCell, atIndexPath indexPath: NSIndexPath) {
|
||||||
|
configureCell(cell, atIndexPath: indexPath)
|
||||||
|
|
||||||
|
guard let cell = cell as? BookmarkSnippetCell else {return}
|
||||||
|
guard let article = fetchedResultController.objectAtIndexPath(indexPath) as? Article else {return}
|
||||||
|
cell.snippetLabel.text = article.snippet
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - Table view delegate
|
||||||
|
|
||||||
|
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
|
||||||
|
guard !tableView.editing else {return}
|
||||||
|
defer {dismissViewControllerAnimated(true, completion: nil)}
|
||||||
|
guard let article = fetchedResultController.objectAtIndexPath(indexPath) as? Article,
|
||||||
|
let url = article.url else {return}
|
||||||
|
trash(articles: [article])
|
||||||
|
|
||||||
|
let operation = ArticleLoadOperation(url: url)
|
||||||
|
GlobalQueue.shared.add(load: operation)
|
||||||
|
}
|
||||||
|
|
||||||
|
override func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
override func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {}
|
||||||
|
|
||||||
|
override func tableView(tableView: UITableView, editActionsForRowAtIndexPath indexPath: NSIndexPath) -> [UITableViewRowAction]? {
|
||||||
|
let remove = UITableViewRowAction(style: .Destructive, title: LocalizedStrings.remove) { (action, indexPath) -> Void in
|
||||||
|
guard let article = self.fetchedResultController.objectAtIndexPath(indexPath) as? Article else {return}
|
||||||
|
let context = NSManagedObjectContext.mainQueueContext
|
||||||
|
context.performBlockAndWait({ () -> Void in
|
||||||
|
article.isBookmarked = false
|
||||||
|
})
|
||||||
|
self.trash(articles: [article])
|
||||||
|
}
|
||||||
|
return [remove]
|
||||||
|
}
|
||||||
|
|
||||||
|
override func tableView(tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
|
||||||
|
return CGFloat.min
|
||||||
|
}
|
||||||
|
|
||||||
// MARK: - Fetched Result Controller Delegate
|
// MARK: - Fetched Result Controller Delegate
|
||||||
|
|
||||||
let managedObjectContext = NSManagedObjectContext.mainQueueContext
|
let managedObjectContext = NSManagedObjectContext.mainQueueContext
|
||||||
@ -93,17 +213,17 @@ class BookmarkController: UITableViewController, NSFetchedResultsControllerDeleg
|
|||||||
switch type {
|
switch type {
|
||||||
case .Insert:
|
case .Insert:
|
||||||
guard let newIndexPath = newIndexPath else {return}
|
guard let newIndexPath = newIndexPath else {return}
|
||||||
tableView.insertRowsAtIndexPaths([newIndexPath], withRowAnimation: .Fade)
|
tableView.insertRowsAtIndexPaths([newIndexPath], withRowAnimation: .Left)
|
||||||
case .Delete:
|
case .Delete:
|
||||||
guard let indexPath = indexPath else {return}
|
guard let indexPath = indexPath else {return}
|
||||||
tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)
|
tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Right)
|
||||||
case .Update:
|
case .Update:
|
||||||
guard let indexPath = indexPath, let cell = tableView.cellForRowAtIndexPath(indexPath) else {return}
|
guard let indexPath = indexPath, let cell = tableView.cellForRowAtIndexPath(indexPath) else {return}
|
||||||
configureCell(cell, atIndexPath: indexPath)
|
configureCell(cell, atIndexPath: indexPath)
|
||||||
case .Move:
|
case .Move:
|
||||||
guard let indexPath = indexPath, let newIndexPath = newIndexPath else {return}
|
guard let indexPath = indexPath, let newIndexPath = newIndexPath else {return}
|
||||||
tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)
|
tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Right)
|
||||||
tableView.insertRowsAtIndexPaths([newIndexPath], withRowAnimation: .Fade)
|
tableView.insertRowsAtIndexPaths([newIndexPath], withRowAnimation: .Left)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,7 +24,10 @@ class BookDetailController: UITableViewController, DZNEmptyDataSetSource, DZNEmp
|
|||||||
private(set) var sectionHeaders = [String?]()
|
private(set) var sectionHeaders = [String?]()
|
||||||
private(set) var sectionFooters = [String?]()
|
private(set) var sectionFooters = [String?]()
|
||||||
private(set) var cellTitles = [[String]]()
|
private(set) var cellTitles = [[String]]()
|
||||||
private(set) var bookmarkCount = 0
|
var bookmarkCount: Int? {
|
||||||
|
guard let book = book else {return nil}
|
||||||
|
return Article.fetchBookmarked(in: book, with: NSManagedObjectContext.mainQueueContext).count
|
||||||
|
}
|
||||||
|
|
||||||
override func viewDidLoad() {
|
override func viewDidLoad() {
|
||||||
super.viewDidLoad()
|
super.viewDidLoad()
|
||||||
@ -41,8 +44,10 @@ class BookDetailController: UITableViewController, DZNEmptyDataSetSource, DZNEmp
|
|||||||
|
|
||||||
override func viewWillAppear(animated: Bool) {
|
override func viewWillAppear(animated: Bool) {
|
||||||
super.viewWillAppear(animated)
|
super.viewWillAppear(animated)
|
||||||
configureViews()
|
|
||||||
book?.addObserver(self, forKeyPath: "stateRaw", options: .New, context: context)
|
book?.addObserver(self, forKeyPath: "stateRaw", options: .New, context: context)
|
||||||
|
configureViews()
|
||||||
|
tableView.reloadEmptyDataSet()
|
||||||
|
tableView.reloadData()
|
||||||
}
|
}
|
||||||
|
|
||||||
override func viewWillDisappear(animated: Bool) {
|
override func viewWillDisappear(animated: Bool) {
|
||||||
@ -104,7 +109,6 @@ class BookDetailController: UITableViewController, DZNEmptyDataSetSource, DZNEmp
|
|||||||
}
|
}
|
||||||
|
|
||||||
func configureBookmarkSection(with book: Book) {
|
func configureBookmarkSection(with book: Book) {
|
||||||
bookmarkCount = Article.fetchBookmarked(in: book, with: NSManagedObjectContext.mainQueueContext).count
|
|
||||||
guard bookmarkCount > 0 else {return}
|
guard bookmarkCount > 0 else {return}
|
||||||
sectionHeaders.append(nil)
|
sectionHeaders.append(nil)
|
||||||
sectionFooters.append(nil)
|
sectionFooters.append(nil)
|
||||||
@ -143,6 +147,10 @@ class BookDetailController: UITableViewController, DZNEmptyDataSetSource, DZNEmp
|
|||||||
}
|
}
|
||||||
|
|
||||||
func configureViews() {
|
func configureViews() {
|
||||||
|
sectionHeaders.removeAll()
|
||||||
|
sectionFooters.removeAll()
|
||||||
|
cellTitles.removeAll()
|
||||||
|
|
||||||
guard let book = book else {return}
|
guard let book = book else {return}
|
||||||
configureStaticHeader(with: book)
|
configureStaticHeader(with: book)
|
||||||
configureIndicators(with: book)
|
configureIndicators(with: book)
|
||||||
@ -152,7 +160,6 @@ class BookDetailController: UITableViewController, DZNEmptyDataSetSource, DZNEmp
|
|||||||
configureBookInfoSection(with: book)
|
configureBookInfoSection(with: book)
|
||||||
configurePIDSection(with: book)
|
configurePIDSection(with: book)
|
||||||
configureURLSection(with: book)
|
configureURLSection(with: book)
|
||||||
tableView.reloadEmptyDataSet()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - Table view data source
|
// MARK: - Table view data source
|
||||||
@ -194,7 +201,7 @@ class BookDetailController: UITableViewController, DZNEmptyDataSetSource, DZNEmp
|
|||||||
case LocalizedStrings.bookmarks:
|
case LocalizedStrings.bookmarks:
|
||||||
let cell = tableView.dequeueReusableCellWithIdentifier("DetailSegueCell", forIndexPath: indexPath)
|
let cell = tableView.dequeueReusableCellWithIdentifier("DetailSegueCell", forIndexPath: indexPath)
|
||||||
cell.textLabel?.text = title
|
cell.textLabel?.text = title
|
||||||
cell.detailTextLabel?.text = "\(bookmarkCount)"
|
cell.detailTextLabel?.text = String(bookmarkCount ?? 0)
|
||||||
return cell
|
return cell
|
||||||
default:
|
default:
|
||||||
let cell = tableView.dequeueReusableCellWithIdentifier("RightDetailCell", forIndexPath: indexPath)
|
let cell = tableView.dequeueReusableCellWithIdentifier("RightDetailCell", forIndexPath: indexPath)
|
||||||
|
@ -54,6 +54,6 @@ class JSInjection {
|
|||||||
let path = NSBundle.mainBundle().pathForResource("getSnippet", ofType: "js"),
|
let path = NSBundle.mainBundle().pathForResource("getSnippet", ofType: "js"),
|
||||||
let jString = try? String(contentsOfFile: path),
|
let jString = try? String(contentsOfFile: path),
|
||||||
let snippet = context.evaluateScript(jString).toString() else {return nil}
|
let snippet = context.evaluateScript(jString).toString() else {return nil}
|
||||||
return snippet
|
return snippet == "null" ? nil : snippet
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -49,7 +49,7 @@
|
|||||||
</dict>
|
</dict>
|
||||||
</array>
|
</array>
|
||||||
<key>CFBundleVersion</key>
|
<key>CFBundleVersion</key>
|
||||||
<string>1.8.1369</string>
|
<string>1.8.1454</string>
|
||||||
<key>ITSAppUsesNonExemptEncryption</key>
|
<key>ITSAppUsesNonExemptEncryption</key>
|
||||||
<false/>
|
<false/>
|
||||||
<key>LSRequiresIPhoneOS</key>
|
<key>LSRequiresIPhoneOS</key>
|
||||||
|
@ -13,7 +13,7 @@ function getSnippet() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
getSnippet();
|
getSnippet();
|
@ -19,10 +19,10 @@
|
|||||||
<color key="sectionIndexBackgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
<color key="sectionIndexBackgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
<prototypes>
|
<prototypes>
|
||||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" reuseIdentifier="BookmarkCell" rowHeight="66" id="HDv-lO-b6r" customClass="BookmarkCell" customModule="Kiwix" customModuleProvider="target">
|
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" reuseIdentifier="BookmarkCell" rowHeight="66" id="HDv-lO-b6r" customClass="BookmarkCell" customModule="Kiwix" customModuleProvider="target">
|
||||||
<rect key="frame" x="0.0" y="120" width="375" height="66"/>
|
<rect key="frame" x="0.0" y="119.5" width="375" height="66"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="HDv-lO-b6r" id="OAl-D1-ec7">
|
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="HDv-lO-b6r" id="OAl-D1-ec7">
|
||||||
<frame key="frameInset" width="375" height="65"/>
|
<frame key="frameInset" width="375" height="65.5"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="U1x-fn-tr7">
|
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="U1x-fn-tr7">
|
||||||
@ -64,10 +64,10 @@
|
|||||||
</connections>
|
</connections>
|
||||||
</tableViewCell>
|
</tableViewCell>
|
||||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" reuseIdentifier="BookmarkSnippetCell" rowHeight="149" id="o5A-Xv-pf5" customClass="BookmarkSnippetCell" customModule="Kiwix" customModuleProvider="target">
|
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" reuseIdentifier="BookmarkSnippetCell" rowHeight="149" id="o5A-Xv-pf5" customClass="BookmarkSnippetCell" customModule="Kiwix" customModuleProvider="target">
|
||||||
<rect key="frame" x="0.0" y="186" width="375" height="149"/>
|
<rect key="frame" x="0.0" y="185.5" width="375" height="149"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="o5A-Xv-pf5" id="KOC-sh-r2Q">
|
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="o5A-Xv-pf5" id="KOC-sh-r2Q">
|
||||||
<frame key="frameInset" width="375" height="148"/>
|
<frame key="frameInset" width="375" height="148.5"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Iw0-U5-FqV">
|
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Iw0-U5-FqV">
|
||||||
@ -155,7 +155,7 @@
|
|||||||
</tableViewController>
|
</tableViewController>
|
||||||
<placeholder placeholderIdentifier="IBFirstResponder" id="b4G-fm-Sda" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
<placeholder placeholderIdentifier="IBFirstResponder" id="b4G-fm-Sda" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||||
</objects>
|
</objects>
|
||||||
<point key="canvasLocation" x="1853" y="1137"/>
|
<point key="canvasLocation" x="2791.1999999999998" y="1136.5817091454273"/>
|
||||||
</scene>
|
</scene>
|
||||||
<!--Navigation Controller-->
|
<!--Navigation Controller-->
|
||||||
<scene sceneID="QEZ-t8-ULC">
|
<scene sceneID="QEZ-t8-ULC">
|
||||||
@ -183,18 +183,118 @@
|
|||||||
<scene sceneID="SVz-ni-k6U">
|
<scene sceneID="SVz-ni-k6U">
|
||||||
<objects>
|
<objects>
|
||||||
<tableViewController storyboardIdentifier="BookmarkController" id="uLf-Kw-kC4" customClass="BookmarkController" customModule="Kiwix" customModuleProvider="target" sceneMemberID="viewController">
|
<tableViewController storyboardIdentifier="BookmarkController" id="uLf-Kw-kC4" customClass="BookmarkController" customModule="Kiwix" customModuleProvider="target" sceneMemberID="viewController">
|
||||||
<tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" separatorStyle="default" rowHeight="44" sectionHeaderHeight="28" sectionFooterHeight="28" id="e97-aT-3rg">
|
<tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="grouped" separatorStyle="default" rowHeight="44" sectionHeaderHeight="18" sectionFooterHeight="18" id="e97-aT-3rg">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
|
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
<color key="backgroundColor" cocoaTouchSystemColor="groupTableViewBackgroundColor"/>
|
||||||
<prototypes>
|
<prototypes>
|
||||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" reuseIdentifier="Cell" id="jws-Kz-Krn">
|
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" reuseIdentifier="BookmarkCell" rowHeight="66" id="5PG-FL-cxF" customClass="BookmarkCell" customModule="Kiwix" customModuleProvider="target">
|
||||||
<rect key="frame" x="0.0" y="28" width="375" height="44"/>
|
<rect key="frame" x="0.0" y="119.5" width="375" height="66"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="jws-Kz-Krn" id="l4Q-UL-tNB">
|
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="5PG-FL-cxF" id="xaN-IW-A8Q">
|
||||||
<frame key="frameInset" width="375" height="43"/>
|
<frame key="frameInset" width="375" height="65.5"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
|
<subviews>
|
||||||
|
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="8C5-aP-W5f">
|
||||||
|
<constraints>
|
||||||
|
<constraint firstAttribute="height" constant="22" id="8Wa-GZ-Fdn"/>
|
||||||
|
</constraints>
|
||||||
|
<fontDescription key="fontDescription" type="system" pointSize="16"/>
|
||||||
|
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
|
<nil key="highlightedColor"/>
|
||||||
|
</label>
|
||||||
|
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="kTX-Se-1Tr">
|
||||||
|
<fontDescription key="fontDescription" style="UICTFontTextStyleFootnote"/>
|
||||||
|
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
|
<nil key="highlightedColor"/>
|
||||||
|
</label>
|
||||||
|
<imageView userInteractionEnabled="NO" contentMode="scaleAspectFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="MLn-gx-0vX">
|
||||||
|
<constraints>
|
||||||
|
<constraint firstAttribute="width" constant="50" id="HZd-Cl-V3K"/>
|
||||||
|
<constraint firstAttribute="height" constant="50" id="uiV-Hq-hDX"/>
|
||||||
|
</constraints>
|
||||||
|
</imageView>
|
||||||
|
</subviews>
|
||||||
|
<constraints>
|
||||||
|
<constraint firstItem="8C5-aP-W5f" firstAttribute="leading" secondItem="MLn-gx-0vX" secondAttribute="trailing" constant="8" id="20T-Gb-4xa"/>
|
||||||
|
<constraint firstItem="8C5-aP-W5f" firstAttribute="leading" secondItem="xaN-IW-A8Q" secondAttribute="leadingMargin" constant="58" id="7x4-8l-TKY"/>
|
||||||
|
<constraint firstItem="kTX-Se-1Tr" firstAttribute="trailing" secondItem="xaN-IW-A8Q" secondAttribute="trailingMargin" id="CXv-MZ-OHC"/>
|
||||||
|
<constraint firstItem="8C5-aP-W5f" firstAttribute="top" secondItem="xaN-IW-A8Q" secondAttribute="topMargin" constant="2" id="JnU-bN-UVz"/>
|
||||||
|
<constraint firstItem="8C5-aP-W5f" firstAttribute="trailing" secondItem="xaN-IW-A8Q" secondAttribute="trailingMargin" id="LKT-j4-l4Q"/>
|
||||||
|
<constraint firstItem="MLn-gx-0vX" firstAttribute="centerY" secondItem="xaN-IW-A8Q" secondAttribute="centerY" id="W6U-dK-Zdl"/>
|
||||||
|
<constraint firstItem="kTX-Se-1Tr" firstAttribute="top" secondItem="8C5-aP-W5f" secondAttribute="bottom" constant="4" id="eQC-OL-FVO"/>
|
||||||
|
<constraint firstItem="kTX-Se-1Tr" firstAttribute="leading" secondItem="xaN-IW-A8Q" secondAttribute="leadingMargin" constant="58" id="vEP-KN-deT"/>
|
||||||
|
<constraint firstAttribute="bottomMargin" secondItem="kTX-Se-1Tr" secondAttribute="bottom" constant="2" id="vZz-lW-ir3"/>
|
||||||
|
</constraints>
|
||||||
</tableViewCellContentView>
|
</tableViewCellContentView>
|
||||||
|
<connections>
|
||||||
|
<outlet property="subtitleLabel" destination="kTX-Se-1Tr" id="t7e-sO-Zlg"/>
|
||||||
|
<outlet property="thumbImageView" destination="MLn-gx-0vX" id="ZqQ-DD-eY6"/>
|
||||||
|
<outlet property="titleLabel" destination="8C5-aP-W5f" id="PLm-CK-x4Q"/>
|
||||||
|
</connections>
|
||||||
|
</tableViewCell>
|
||||||
|
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" reuseIdentifier="BookmarkSnippetCell" rowHeight="149" id="63j-xA-eDr" customClass="BookmarkSnippetCell" customModule="Kiwix" customModuleProvider="target">
|
||||||
|
<rect key="frame" x="0.0" y="185.5" width="375" height="149"/>
|
||||||
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
|
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="63j-xA-eDr" id="vOo-g4-SUY">
|
||||||
|
<frame key="frameInset" width="375" height="148.5"/>
|
||||||
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
|
<subviews>
|
||||||
|
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Ucm-1R-oq2">
|
||||||
|
<constraints>
|
||||||
|
<constraint firstAttribute="height" constant="22" id="kPD-8s-fMo"/>
|
||||||
|
</constraints>
|
||||||
|
<fontDescription key="fontDescription" type="system" pointSize="16"/>
|
||||||
|
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
|
<nil key="highlightedColor"/>
|
||||||
|
</label>
|
||||||
|
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="ZiC-LW-CAz">
|
||||||
|
<constraints>
|
||||||
|
<constraint firstAttribute="height" constant="19.5" id="Z3G-7m-zmO"/>
|
||||||
|
</constraints>
|
||||||
|
<fontDescription key="fontDescription" style="UICTFontTextStyleFootnote"/>
|
||||||
|
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
|
<nil key="highlightedColor"/>
|
||||||
|
</label>
|
||||||
|
<imageView userInteractionEnabled="NO" contentMode="scaleAspectFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="fb7-cw-RPA">
|
||||||
|
<constraints>
|
||||||
|
<constraint firstAttribute="height" constant="50" id="BXW-1c-V8W"/>
|
||||||
|
<constraint firstAttribute="width" constant="50" id="Ur8-fD-YFg"/>
|
||||||
|
</constraints>
|
||||||
|
</imageView>
|
||||||
|
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="justified" lineBreakMode="tailTruncation" numberOfLines="4" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="z7h-P0-nCy">
|
||||||
|
<fontDescription key="fontDescription" style="UICTFontTextStyleCaption2"/>
|
||||||
|
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
|
<nil key="highlightedColor"/>
|
||||||
|
</label>
|
||||||
|
</subviews>
|
||||||
|
<constraints>
|
||||||
|
<constraint firstItem="Ucm-1R-oq2" firstAttribute="leading" secondItem="vOo-g4-SUY" secondAttribute="leadingMargin" constant="58" id="3T4-1H-XTZ"/>
|
||||||
|
<constraint firstItem="ZiC-LW-CAz" firstAttribute="trailing" secondItem="vOo-g4-SUY" secondAttribute="trailingMargin" id="7OF-sG-pOp"/>
|
||||||
|
<constraint firstAttribute="topMargin" secondItem="fb7-cw-RPA" secondAttribute="top" id="I19-z3-SCp"/>
|
||||||
|
<constraint firstItem="Ucm-1R-oq2" firstAttribute="top" secondItem="vOo-g4-SUY" secondAttribute="topMargin" constant="2" id="Ipo-0d-gf4"/>
|
||||||
|
<constraint firstItem="Ucm-1R-oq2" firstAttribute="leading" secondItem="fb7-cw-RPA" secondAttribute="trailing" constant="8" id="JYn-IL-cun"/>
|
||||||
|
<constraint firstItem="z7h-P0-nCy" firstAttribute="bottom" secondItem="vOo-g4-SUY" secondAttribute="bottomMargin" id="JgH-Vt-DP2"/>
|
||||||
|
<constraint firstItem="z7h-P0-nCy" firstAttribute="trailing" secondItem="vOo-g4-SUY" secondAttribute="trailingMargin" id="Omn-e2-gEG"/>
|
||||||
|
<constraint firstItem="Ucm-1R-oq2" firstAttribute="trailing" secondItem="vOo-g4-SUY" secondAttribute="trailingMargin" id="Qra-DT-kjm"/>
|
||||||
|
<constraint firstItem="ZiC-LW-CAz" firstAttribute="top" secondItem="Ucm-1R-oq2" secondAttribute="bottom" constant="4" id="Wlg-pC-5Nu"/>
|
||||||
|
<constraint firstItem="z7h-P0-nCy" firstAttribute="top" secondItem="ZiC-LW-CAz" secondAttribute="bottom" constant="10.5" id="Y78-ff-8Lx"/>
|
||||||
|
<constraint firstItem="fb7-cw-RPA" firstAttribute="centerY" secondItem="vOo-g4-SUY" secondAttribute="centerY" id="fWN-qd-SxN"/>
|
||||||
|
<constraint firstAttribute="leadingMargin" secondItem="z7h-P0-nCy" secondAttribute="leading" id="gsJ-BE-Vvk"/>
|
||||||
|
<constraint firstItem="ZiC-LW-CAz" firstAttribute="leading" secondItem="vOo-g4-SUY" secondAttribute="leadingMargin" constant="58" id="sKe-A0-zxB"/>
|
||||||
|
</constraints>
|
||||||
|
<variation key="default">
|
||||||
|
<mask key="constraints">
|
||||||
|
<exclude reference="fWN-qd-SxN"/>
|
||||||
|
</mask>
|
||||||
|
</variation>
|
||||||
|
</tableViewCellContentView>
|
||||||
|
<connections>
|
||||||
|
<outlet property="snippetLabel" destination="z7h-P0-nCy" id="S6G-Ol-b0B"/>
|
||||||
|
<outlet property="subtitleLabel" destination="ZiC-LW-CAz" id="Q1y-pr-E0m"/>
|
||||||
|
<outlet property="thumbImageView" destination="fb7-cw-RPA" id="1WQ-SQ-QDN"/>
|
||||||
|
<outlet property="titleLabel" destination="Ucm-1R-oq2" id="uil-XC-kpb"/>
|
||||||
|
</connections>
|
||||||
</tableViewCell>
|
</tableViewCell>
|
||||||
</prototypes>
|
</prototypes>
|
||||||
<connections>
|
<connections>
|
||||||
@ -202,10 +302,20 @@
|
|||||||
<outlet property="delegate" destination="uLf-Kw-kC4" id="eAm-IZ-3SL"/>
|
<outlet property="delegate" destination="uLf-Kw-kC4" id="eAm-IZ-3SL"/>
|
||||||
</connections>
|
</connections>
|
||||||
</tableView>
|
</tableView>
|
||||||
|
<toolbarItems/>
|
||||||
|
<navigationItem key="navigationItem" id="uvo-qe-heC">
|
||||||
|
<barButtonItem key="rightBarButtonItem" systemItem="edit" id="Vy8-bG-jxx">
|
||||||
|
<connections>
|
||||||
|
<action selector="editButtonTapped:" destination="uLf-Kw-kC4" id="WYd-PY-qFx"/>
|
||||||
|
</connections>
|
||||||
|
</barButtonItem>
|
||||||
|
</navigationItem>
|
||||||
|
<simulatedNavigationBarMetrics key="simulatedTopBarMetrics" prompted="NO"/>
|
||||||
|
<simulatedToolbarMetrics key="simulatedBottomBarMetrics"/>
|
||||||
</tableViewController>
|
</tableViewController>
|
||||||
<placeholder placeholderIdentifier="IBFirstResponder" id="kQh-IS-Ttn" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
<placeholder placeholderIdentifier="IBFirstResponder" id="kQh-IS-Ttn" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||||
</objects>
|
</objects>
|
||||||
<point key="canvasLocation" x="1455" y="1720"/>
|
<point key="canvasLocation" x="2676" y="1787"/>
|
||||||
</scene>
|
</scene>
|
||||||
<!--BookmarkHUD-->
|
<!--BookmarkHUD-->
|
||||||
<scene sceneID="eMu-pk-jX5">
|
<scene sceneID="eMu-pk-jX5">
|
||||||
@ -315,7 +425,25 @@
|
|||||||
</connections>
|
</connections>
|
||||||
</tapGestureRecognizer>
|
</tapGestureRecognizer>
|
||||||
</objects>
|
</objects>
|
||||||
<point key="canvasLocation" x="2604" y="1137"/>
|
<point key="canvasLocation" x="3543.1999999999998" y="1136.5817091454273"/>
|
||||||
|
</scene>
|
||||||
|
<!--Navigation Controller-->
|
||||||
|
<scene sceneID="pBB-bl-wh0">
|
||||||
|
<objects>
|
||||||
|
<navigationController automaticallyAdjustsScrollViewInsets="NO" id="epu-ol-vd5" sceneMemberID="viewController">
|
||||||
|
<toolbarItems/>
|
||||||
|
<navigationBar key="navigationBar" contentMode="scaleToFill" id="7Ri-xB-OG0">
|
||||||
|
<rect key="frame" x="0.0" y="0.0" width="375" height="44"/>
|
||||||
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
|
</navigationBar>
|
||||||
|
<nil name="viewControllers"/>
|
||||||
|
<connections>
|
||||||
|
<segue destination="uLf-Kw-kC4" kind="relationship" relationship="rootViewController" id="oTY-iv-avG"/>
|
||||||
|
</connections>
|
||||||
|
</navigationController>
|
||||||
|
<placeholder placeholderIdentifier="IBFirstResponder" id="qOY-S3-xOp" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||||
|
</objects>
|
||||||
|
<point key="canvasLocation" x="1560.8" y="1764.4677661169417"/>
|
||||||
</scene>
|
</scene>
|
||||||
</scenes>
|
</scenes>
|
||||||
<resources>
|
<resources>
|
||||||
|
@ -34,18 +34,23 @@ class BasicBookCell: UITableViewCell {
|
|||||||
|
|
||||||
override func setHighlighted(highlighted: Bool, animated: Bool) {
|
override func setHighlighted(highlighted: Bool, animated: Bool) {
|
||||||
super.setHighlighted(highlighted, animated: animated)
|
super.setHighlighted(highlighted, animated: animated)
|
||||||
setHasPicIndicatorColor()
|
setIndicatorColor()
|
||||||
|
}
|
||||||
|
|
||||||
|
override func setSelected(selected: Bool, animated: Bool) {
|
||||||
|
super.setSelected(selected, animated: animated)
|
||||||
|
setIndicatorColor()
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: Shorthand properties
|
// MARK: Shorthand properties
|
||||||
|
|
||||||
var hasPic: Bool = false {
|
var hasPic: Bool = false {
|
||||||
didSet {
|
didSet {
|
||||||
setHasPicIndicatorColor()
|
setIndicatorColor()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private func setHasPicIndicatorColor() {
|
private func setIndicatorColor() {
|
||||||
hasPicIndicator.backgroundColor = hasPic ? AppColors.hasPicTintColor : UIColor.lightGrayColor()
|
hasPicIndicator.backgroundColor = hasPic ? AppColors.hasPicTintColor : UIColor.lightGrayColor()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -21,7 +21,7 @@
|
|||||||
<key>CFBundleSignature</key>
|
<key>CFBundleSignature</key>
|
||||||
<string>????</string>
|
<string>????</string>
|
||||||
<key>CFBundleVersion</key>
|
<key>CFBundleVersion</key>
|
||||||
<string>1.8.1373</string>
|
<string>1.8.1458</string>
|
||||||
<key>NSExtension</key>
|
<key>NSExtension</key>
|
||||||
<dict>
|
<dict>
|
||||||
<key>NSExtensionMainStoryboard</key>
|
<key>NSExtensionMainStoryboard</key>
|
||||||
|
@ -62,7 +62,7 @@
|
|||||||
973DD4191D343F2F009D45DB /* libzim.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 973DD40E1D343F2F009D45DB /* libzim.a */; };
|
973DD4191D343F2F009D45DB /* libzim.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 973DD40E1D343F2F009D45DB /* libzim.a */; };
|
||||||
973DD4281D36E3E4009D45DB /* SettingSingleSwitchTBVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 973DD4271D36E3E4009D45DB /* SettingSingleSwitchTBVC.swift */; };
|
973DD4281D36E3E4009D45DB /* SettingSingleSwitchTBVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 973DD4271D36E3E4009D45DB /* SettingSingleSwitchTBVC.swift */; };
|
||||||
974F33C41D99BBEB00879D35 /* 1.8.xcmappingmodel in Sources */ = {isa = PBXBuildFile; fileRef = 974F33C31D99BBEB00879D35 /* 1.8.xcmappingmodel */; };
|
974F33C41D99BBEB00879D35 /* 1.8.xcmappingmodel in Sources */ = {isa = PBXBuildFile; fileRef = 974F33C31D99BBEB00879D35 /* 1.8.xcmappingmodel */; };
|
||||||
974F33C61D99CAD700879D35 /* BookmarkMigrationOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 974F33C51D99CAD700879D35 /* BookmarkMigrationOperation.swift */; };
|
974F33C61D99CAD700879D35 /* BookmarkOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 974F33C51D99CAD700879D35 /* BookmarkOperation.swift */; };
|
||||||
974F42821D47E19A00F8074C /* SettingWidgetBookmarksTBVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 974F42811D47E19A00F8074C /* SettingWidgetBookmarksTBVC.swift */; };
|
974F42821D47E19A00F8074C /* SettingWidgetBookmarksTBVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 974F42811D47E19A00F8074C /* SettingWidgetBookmarksTBVC.swift */; };
|
||||||
975227821D020560001D1DDE /* Indexer.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 975227811D020560001D1DDE /* Indexer.storyboard */; };
|
975227821D020560001D1DDE /* Indexer.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 975227811D020560001D1DDE /* Indexer.storyboard */; };
|
||||||
975227B01D021539001D1DDE /* IndexerController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 975227AF1D021539001D1DDE /* IndexerController.swift */; };
|
975227B01D021539001D1DDE /* IndexerController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 975227AF1D021539001D1DDE /* IndexerController.swift */; };
|
||||||
@ -283,7 +283,7 @@
|
|||||||
973DD40E1D343F2F009D45DB /* libzim.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libzim.a; path = Kiwix/libkiwix/iOS/libzim.a; sourceTree = "<group>"; };
|
973DD40E1D343F2F009D45DB /* libzim.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libzim.a; path = Kiwix/libkiwix/iOS/libzim.a; sourceTree = "<group>"; };
|
||||||
973DD4271D36E3E4009D45DB /* SettingSingleSwitchTBVC.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = SettingSingleSwitchTBVC.swift; path = "Kiwix-iOS/Controller/Setting/SettingSingleSwitchTBVC.swift"; sourceTree = SOURCE_ROOT; };
|
973DD4271D36E3E4009D45DB /* SettingSingleSwitchTBVC.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = SettingSingleSwitchTBVC.swift; path = "Kiwix-iOS/Controller/Setting/SettingSingleSwitchTBVC.swift"; sourceTree = SOURCE_ROOT; };
|
||||||
974F33C31D99BBEB00879D35 /* 1.8.xcmappingmodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcmappingmodel; name = 1.8.xcmappingmodel; path = Kiwix/CoreData/Migration/1.8.xcmappingmodel; sourceTree = SOURCE_ROOT; };
|
974F33C31D99BBEB00879D35 /* 1.8.xcmappingmodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcmappingmodel; name = 1.8.xcmappingmodel; path = Kiwix/CoreData/Migration/1.8.xcmappingmodel; sourceTree = SOURCE_ROOT; };
|
||||||
974F33C51D99CAD700879D35 /* BookmarkMigrationOperation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BookmarkMigrationOperation.swift; sourceTree = "<group>"; };
|
974F33C51D99CAD700879D35 /* BookmarkOperation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BookmarkOperation.swift; sourceTree = "<group>"; };
|
||||||
974F42811D47E19A00F8074C /* SettingWidgetBookmarksTBVC.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = SettingWidgetBookmarksTBVC.swift; path = "Kiwix-iOS/Controller/Setting/SettingWidgetBookmarksTBVC.swift"; sourceTree = SOURCE_ROOT; };
|
974F42811D47E19A00F8074C /* SettingWidgetBookmarksTBVC.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = SettingWidgetBookmarksTBVC.swift; path = "Kiwix-iOS/Controller/Setting/SettingWidgetBookmarksTBVC.swift"; sourceTree = SOURCE_ROOT; };
|
||||||
975227811D020560001D1DDE /* Indexer.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; name = Indexer.storyboard; path = "Kiwix-OSX/StoryBoards/Indexer.storyboard"; sourceTree = SOURCE_ROOT; };
|
975227811D020560001D1DDE /* Indexer.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; name = Indexer.storyboard; path = "Kiwix-OSX/StoryBoards/Indexer.storyboard"; sourceTree = SOURCE_ROOT; };
|
||||||
975227AF1D021539001D1DDE /* IndexerController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = IndexerController.swift; path = "Kiwix-OSX/Controllers/IndexerController.swift"; sourceTree = SOURCE_ROOT; };
|
975227AF1D021539001D1DDE /* IndexerController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = IndexerController.swift; path = "Kiwix-OSX/Controllers/IndexerController.swift"; sourceTree = SOURCE_ROOT; };
|
||||||
@ -984,7 +984,7 @@
|
|||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
9764CBD21D8083AA00072D6A /* ArticleOperation.swift */,
|
9764CBD21D8083AA00072D6A /* ArticleOperation.swift */,
|
||||||
974F33C51D99CAD700879D35 /* BookmarkMigrationOperation.swift */,
|
974F33C51D99CAD700879D35 /* BookmarkOperation.swift */,
|
||||||
97DF259B1D6F7612001648A3 /* BookOperation.swift */,
|
97DF259B1D6F7612001648A3 /* BookOperation.swift */,
|
||||||
97D6811C1D6F70AC00E5FA99 /* GlobalQueue.swift */,
|
97D6811C1D6F70AC00E5FA99 /* GlobalQueue.swift */,
|
||||||
97D6811D1D6F70AC00E5FA99 /* RefreshLibraryOperation.swift */,
|
97D6811D1D6F70AC00E5FA99 /* RefreshLibraryOperation.swift */,
|
||||||
@ -1514,7 +1514,7 @@
|
|||||||
970E68B61D37E224001E8514 /* SettingSearchHistoryTBVC.swift in Sources */,
|
970E68B61D37E224001E8514 /* SettingSearchHistoryTBVC.swift in Sources */,
|
||||||
97C005D81D64B99E004352E8 /* LibrarySplitViewController.swift in Sources */,
|
97C005D81D64B99E004352E8 /* LibrarySplitViewController.swift in Sources */,
|
||||||
97FDACC41D85A3B300DEDACB /* Language+CoreDataProperties.swift in Sources */,
|
97FDACC41D85A3B300DEDACB /* Language+CoreDataProperties.swift in Sources */,
|
||||||
974F33C61D99CAD700879D35 /* BookmarkMigrationOperation.swift in Sources */,
|
974F33C61D99CAD700879D35 /* BookmarkOperation.swift in Sources */,
|
||||||
97A8AD871D6CF38000584ED1 /* EmptyTableConfigExtension.swift in Sources */,
|
97A8AD871D6CF38000584ED1 /* EmptyTableConfigExtension.swift in Sources */,
|
||||||
971A102E1D022AD5007FC62C /* TableViewCells.swift in Sources */,
|
971A102E1D022AD5007FC62C /* TableViewCells.swift in Sources */,
|
||||||
97DF259D1D6F9053001648A3 /* URLSessionDownloadTaskOperation.swift in Sources */,
|
97DF259D1D6F9053001648A3 /* URLSessionDownloadTaskOperation.swift in Sources */,
|
||||||
|
@ -33,53 +33,5 @@
|
|||||||
endingLineNumber = "37">
|
endingLineNumber = "37">
|
||||||
</BreakpointContent>
|
</BreakpointContent>
|
||||||
</BreakpointProxy>
|
</BreakpointProxy>
|
||||||
<BreakpointProxy
|
|
||||||
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
|
|
||||||
<BreakpointContent
|
|
||||||
shouldBeEnabled = "Yes"
|
|
||||||
ignoreCount = "0"
|
|
||||||
continueAfterRunningActions = "No"
|
|
||||||
filePath = "Kiwix/Operations/BookmarkMigrationOperation.swift"
|
|
||||||
timestampString = "496692057.397729"
|
|
||||||
startingColumnNumber = "9223372036854775807"
|
|
||||||
endingColumnNumber = "9223372036854775807"
|
|
||||||
startingLineNumber = "27"
|
|
||||||
endingLineNumber = "27"
|
|
||||||
landmarkName = "execute()"
|
|
||||||
landmarkType = "7">
|
|
||||||
<Locations>
|
|
||||||
<Location
|
|
||||||
shouldBeEnabled = "Yes"
|
|
||||||
ignoreCount = "0"
|
|
||||||
continueAfterRunningActions = "No"
|
|
||||||
symbolName = "Kiwix.BookmarkMigrationOperation.(execute () -> ()).(closure #1)"
|
|
||||||
moduleName = "Kiwix"
|
|
||||||
usesParentBreakpointCondition = "Yes"
|
|
||||||
urlString = "file:///Volumes/Data/Developer/Kiwix/Kiwix/Operations/BookmarkMigrationOperation.swift"
|
|
||||||
timestampString = "496794457.332421"
|
|
||||||
startingColumnNumber = "9223372036854775807"
|
|
||||||
endingColumnNumber = "9223372036854775807"
|
|
||||||
startingLineNumber = "27"
|
|
||||||
endingLineNumber = "27"
|
|
||||||
offsetFromSymbolStart = "28">
|
|
||||||
</Location>
|
|
||||||
<Location
|
|
||||||
shouldBeEnabled = "Yes"
|
|
||||||
ignoreCount = "0"
|
|
||||||
continueAfterRunningActions = "No"
|
|
||||||
symbolName = "Kiwix.BookmarkMigrationOperation.(execute () -> ()).(closure #1).(closure #1)"
|
|
||||||
moduleName = "Kiwix"
|
|
||||||
usesParentBreakpointCondition = "Yes"
|
|
||||||
urlString = "file:///Volumes/Data/Developer/Kiwix/Kiwix/Operations/BookmarkMigrationOperation.swift"
|
|
||||||
timestampString = "496794457.333823"
|
|
||||||
startingColumnNumber = "9223372036854775807"
|
|
||||||
endingColumnNumber = "9223372036854775807"
|
|
||||||
startingLineNumber = "27"
|
|
||||||
endingLineNumber = "27"
|
|
||||||
offsetFromSymbolStart = "36">
|
|
||||||
</Location>
|
|
||||||
</Locations>
|
|
||||||
</BreakpointContent>
|
|
||||||
</BreakpointProxy>
|
|
||||||
</Breakpoints>
|
</Breakpoints>
|
||||||
</Bucket>
|
</Bucket>
|
||||||
|
@ -1,38 +0,0 @@
|
|||||||
//
|
|
||||||
// BookmarkMigrationOperation.swift
|
|
||||||
// Kiwix
|
|
||||||
//
|
|
||||||
// Created by Chris Li on 9/26/16.
|
|
||||||
// Copyright © 2016 Chris. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
import CoreData
|
|
||||||
import Operations
|
|
||||||
|
|
||||||
class BookmarkMigrationOperation: Operation {
|
|
||||||
private let context: NSManagedObjectContext
|
|
||||||
|
|
||||||
override init() {
|
|
||||||
self.context = NSManagedObjectContext(concurrencyType: .PrivateQueueConcurrencyType)
|
|
||||||
context.parentContext = NSManagedObjectContext.mainQueueContext
|
|
||||||
context.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy
|
|
||||||
|
|
||||||
super.init()
|
|
||||||
addCondition(MutuallyExclusive<GlobalQueue>())
|
|
||||||
name = String(self)
|
|
||||||
}
|
|
||||||
|
|
||||||
override func execute() {
|
|
||||||
context.performBlockAndWait {
|
|
||||||
let pids = Book.fetchLocal(self.context).flatMap({$1.pid})
|
|
||||||
for pid in pids {
|
|
||||||
var books = Book.fetch(pid: pid, context: self.context)
|
|
||||||
let latestBook = books.removeFirst()
|
|
||||||
for book in books {
|
|
||||||
book.articles.forEach({$0.book = latestBook})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if self.context.hasChanges {_ = try? self.context.save()}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
81
Kiwix/Operations/BookmarkOperation.swift
Normal file
81
Kiwix/Operations/BookmarkOperation.swift
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
//
|
||||||
|
// BookmarkMigrationOperation.swift
|
||||||
|
// Kiwix
|
||||||
|
//
|
||||||
|
// Created by Chris Li on 9/26/16.
|
||||||
|
// Copyright © 2016 Chris. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import CoreData
|
||||||
|
import Operations
|
||||||
|
|
||||||
|
class BookmarkMigrationOperation: Operation {
|
||||||
|
private let context: NSManagedObjectContext
|
||||||
|
|
||||||
|
override init() {
|
||||||
|
self.context = NSManagedObjectContext(concurrencyType: .PrivateQueueConcurrencyType)
|
||||||
|
context.parentContext = NSManagedObjectContext.mainQueueContext
|
||||||
|
context.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy
|
||||||
|
|
||||||
|
super.init()
|
||||||
|
addCondition(MutuallyExclusive<GlobalQueue>())
|
||||||
|
name = String(self)
|
||||||
|
}
|
||||||
|
|
||||||
|
override func execute() {
|
||||||
|
context.performBlockAndWait {
|
||||||
|
let pids = Book.fetchLocal(self.context).flatMap({$1.pid})
|
||||||
|
for pid in pids {
|
||||||
|
var books = Book.fetch(pid: pid, context: self.context)
|
||||||
|
let latestBook = books.removeFirst()
|
||||||
|
for book in books {
|
||||||
|
book.articles.forEach({$0.book = latestBook})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if self.context.hasChanges {_ = try? self.context.save()}
|
||||||
|
}
|
||||||
|
finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class BookmarkTrashOperation: Operation {
|
||||||
|
private let context: NSManagedObjectContext
|
||||||
|
private let articles: [Article]
|
||||||
|
|
||||||
|
init(articles: [Article]) {
|
||||||
|
self.context = NSManagedObjectContext.mainQueueContext
|
||||||
|
self.articles = articles
|
||||||
|
|
||||||
|
super.init()
|
||||||
|
addCondition(MutuallyExclusive<BookmarkController>())
|
||||||
|
name = String(self)
|
||||||
|
}
|
||||||
|
|
||||||
|
override func execute() {
|
||||||
|
context.performBlock {
|
||||||
|
self.articles.forEach() {
|
||||||
|
$0.isBookmarked = false
|
||||||
|
$0.bookmarkDate = nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get books whose zim file removed, but are retain by bookmarks, and whose bookmarks are all removed
|
||||||
|
let books = Set(self.articles.flatMap({$0.book}))
|
||||||
|
.filter({Article.fetchBookmarked(in: $0, with: self.context).count == 0 && $0.state == .Retained})
|
||||||
|
books.forEach({ (book) in
|
||||||
|
if let _ = book.meta4URL {
|
||||||
|
book.state = .Cloud
|
||||||
|
} else {
|
||||||
|
self.context.deleteObject(book)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
if self.context.hasChanges {_ = try? self.context.save()}
|
||||||
|
}
|
||||||
|
|
||||||
|
if articles.count > 0 {
|
||||||
|
produceOperation(UpdateWidgetDataSourceOperation())
|
||||||
|
}
|
||||||
|
|
||||||
|
finish()
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user