From 390efc8be384674abda832c5f1e6ae3302525e5c Mon Sep 17 00:00:00 2001 From: Omar Albeik Date: Mon, 26 Mar 2018 14:47:22 +0300 Subject: [PATCH 1/3] Add bookmarks --- Example/Example.xcodeproj/project.pbxproj | 6 +- Source/FolioReaderBookmarkList.swift | 95 ++++ Source/FolioReaderCenter.swift | 506 ++++++++++-------- Source/FolioReaderConfig.swift | 6 + Source/Models/Bookmark+Helper.swift | 130 +++++ Source/Models/Bookmark.swift | 21 + Source/PageViewController.swift | 10 + .../Contents.json | 12 + .../icon-navbar-bookmark-selected.pdf | Bin 0 -> 4046 bytes .../Contents.json | 12 + .../icon-navbar-bookmark.pdf | Bin 0 -> 4153 bytes Source/UIBookmarkBarButtonItem.swift | 34 ++ 12 files changed, 592 insertions(+), 240 deletions(-) create mode 100644 Source/FolioReaderBookmarkList.swift create mode 100644 Source/Models/Bookmark+Helper.swift create mode 100644 Source/Models/Bookmark.swift create mode 100644 Source/Resources/Images.xcassets/icon-navbar-bookmark-selected.imageset/Contents.json create mode 100644 Source/Resources/Images.xcassets/icon-navbar-bookmark-selected.imageset/icon-navbar-bookmark-selected.pdf create mode 100644 Source/Resources/Images.xcassets/icon-navbar-bookmark.imageset/Contents.json create mode 100644 Source/Resources/Images.xcassets/icon-navbar-bookmark.imageset/icon-navbar-bookmark.pdf create mode 100644 Source/UIBookmarkBarButtonItem.swift diff --git a/Example/Example.xcodeproj/project.pbxproj b/Example/Example.xcodeproj/project.pbxproj index ee8f7712c..f068b2c60 100644 --- a/Example/Example.xcodeproj/project.pbxproj +++ b/Example/Example.xcodeproj/project.pbxproj @@ -380,7 +380,7 @@ TargetAttributes = { 1A42C2881C0E3882000F2137 = { CreatedOnToolsVersion = 7.1.1; - DevelopmentTeam = 32F2T8EJ6G; + DevelopmentTeam = C3VKVFB3SA; LastSwiftMigration = 0800; ProvisioningStyle = Automatic; SystemCapabilities = { @@ -1008,7 +1008,7 @@ ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = "$(inherited)"; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - DEVELOPMENT_TEAM = 32F2T8EJ6G; + DEVELOPMENT_TEAM = C3VKVFB3SA; INFOPLIST_FILE = Example/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.folioreader.Example; @@ -1025,7 +1025,7 @@ ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = "$(inherited)"; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - DEVELOPMENT_TEAM = 32F2T8EJ6G; + DEVELOPMENT_TEAM = C3VKVFB3SA; INFOPLIST_FILE = Example/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.folioreader.Example; diff --git a/Source/FolioReaderBookmarkList.swift b/Source/FolioReaderBookmarkList.swift new file mode 100644 index 000000000..e01e774ee --- /dev/null +++ b/Source/FolioReaderBookmarkList.swift @@ -0,0 +1,95 @@ +// +// FolioReaderBookmarkList.swift +// FolioReaderKit +// +// Created by Omar Albeik on 26.03.2018. +// + +import UIKit + +class FolioReaderBookmarkList: UITableViewController { + + fileprivate var bookmarks = [Bookmark]() + fileprivate var readerConfig: FolioReaderConfig + fileprivate var folioReader: FolioReader + + init(folioReader: FolioReader, readerConfig: FolioReaderConfig) { + self.readerConfig = readerConfig + self.folioReader = folioReader + + super.init(style: UITableViewStyle.plain) + } + + required init?(coder aDecoder: NSCoder) { + fatalError("init with coder not supported") + } + + override func viewDidLoad() { + super.viewDidLoad() + + self.tableView.register(UITableViewCell.self, forCellReuseIdentifier: kReuseCellIdentifier) + self.tableView.separatorInset = UIEdgeInsets.zero + self.tableView.backgroundColor = self.folioReader.isNight(self.readerConfig.nightModeMenuBackground, self.readerConfig.menuBackgroundColor) + self.tableView.separatorColor = self.folioReader.isNight(self.readerConfig.nightModeSeparatorColor, self.readerConfig.menuSeparatorColor) + + guard let bookId = (self.folioReader.readerContainer?.book.name as NSString?)?.deletingPathExtension else { + self.bookmarks = [] + return + } + + self.bookmarks = Bookmark.allByBookId(withConfiguration: self.readerConfig, bookId: bookId) + } + + // MARK: - Table view data source + + override func numberOfSections(in tableView: UITableView) -> Int { + return 1 + } + + override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + return bookmarks.count + } + + override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + let cell = tableView.dequeueReusableCell(withIdentifier: kReuseCellIdentifier, for: indexPath) + cell.backgroundColor = UIColor.clear + + let bookmark = bookmarks[(indexPath as NSIndexPath).row] + + // Format date + let dateFormatter = DateFormatter() + dateFormatter.dateFormat = self.readerConfig.localizedHighlightsDateFormat + let dateString = dateFormatter.string(from: bookmark.date) + + cell.textLabel?.text = "Page \(bookmark.page)" + cell.detailTextLabel?.text = dateString + + return cell + } + + // MARK: - Table view delegate + + override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { + guard let bookmark = bookmarks[safe: (indexPath as NSIndexPath).row] else { + return + } + + self.folioReader.readerCenter?.changePageWith(page: bookmark.page, andFragment: bookmark.bookmarkId) + self.dismiss() + } + + override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) { + if editingStyle == .delete { + let bookmark = bookmarks[(indexPath as NSIndexPath).row] + bookmark.remove(withConfiguration: self.readerConfig) // Remove from Database + bookmarks.remove(at: (indexPath as NSIndexPath).row) + tableView.deleteRows(at: [indexPath], with: .fade) + } + } + + // MARK: - Handle rotation transition + + override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) { + tableView.reloadData() + } +} diff --git a/Source/FolioReaderCenter.swift b/Source/FolioReaderCenter.swift index e32a177a8..0c8108269 100755 --- a/Source/FolioReaderCenter.swift +++ b/Source/FolioReaderCenter.swift @@ -11,12 +11,12 @@ import ZFDragableModalTransition /// Protocol which is used from `FolioReaderCenter`s. @objc public protocol FolioReaderCenterDelegate: class { - + /// Notifies that a page appeared. This is triggered when a page is chosen and displayed. /// /// - Parameter page: The appeared page @objc optional func pageDidAppear(_ page: FolioReaderPage) - + /// Passes and returns the HTML content as `String`. Implement this method if you want to modify the HTML content of a `FolioReaderPage`. /// /// - Parameters: @@ -29,24 +29,24 @@ import ZFDragableModalTransition /// /// - Parameter pageNumber: The appeared page item @objc optional func pageItemChanged(_ pageNumber: Int) - + } /// The base reader class open class FolioReaderCenter: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout { - + /// This delegate receives the events from the current `FolioReaderPage`s delegate. open weak var delegate: FolioReaderCenterDelegate? - + /// This delegate receives the events from current page open weak var pageDelegate: FolioReaderPageDelegate? - + /// The base reader container open weak var readerContainer: FolioReaderContainer? - + /// The current visible page on reader open fileprivate(set) var currentPage: FolioReaderPage? - + /// The collection view with pages open var collectionView: UICollectionView! @@ -70,7 +70,7 @@ open class FolioReaderCenter: UIViewController, UICollectionViewDelegate, UIColl var currentPageNumber: Int = 0 var pageWidth: CGFloat = 0.0 var pageHeight: CGFloat = 0.0 - + fileprivate var screenBounds: CGRect! fileprivate var pointNow = CGPoint.zero fileprivate var pageOffsetRate: CGFloat = 0 @@ -78,46 +78,46 @@ open class FolioReaderCenter: UIViewController, UICollectionViewDelegate, UIColl fileprivate var isFirstLoad = true fileprivate var currentWebViewScrollPositions = [Int: CGPoint]() fileprivate var currentOrientation: UIInterfaceOrientation? - + fileprivate var readerConfig: FolioReaderConfig { guard let readerContainer = readerContainer else { return FolioReaderConfig() } return readerContainer.readerConfig } - + fileprivate var book: FRBook { guard let readerContainer = readerContainer else { return FRBook() } return readerContainer.book } - + fileprivate var folioReader: FolioReader { guard let readerContainer = readerContainer else { return FolioReader() } return readerContainer.folioReader } - + // MARK: - Init - + init(withContainer readerContainer: FolioReaderContainer) { self.readerContainer = readerContainer super.init(nibName: nil, bundle: Bundle.frameworkBundle()) - + self.initialization() } - + required public init?(coder aDecoder: NSCoder) { fatalError("This class doesn't support NSCoding.") } - + /** Common Initialization */ fileprivate func initialization() { - + if (self.readerConfig.hideBars == true) { self.pageIndicatorHeight = 0 } self.totalPages = book.spine.spineReferences.count - + // Loading indicator let style: UIActivityIndicatorViewStyle = folioReader.isNight(.white, .gray) loadingView = UIActivityIndicatorView(activityIndicatorStyle: style) @@ -125,16 +125,16 @@ open class FolioReaderCenter: UIViewController, UICollectionViewDelegate, UIColl loadingView.startAnimating() self.view.addSubview(loadingView) } - + // MARK: - View life cicle - + override open func viewDidLoad() { super.viewDidLoad() - + screenBounds = self.getScreenBounds() setPageSize(UIApplication.shared.statusBarOrientation) - + // Layout collectionViewLayout.sectionInset = UIEdgeInsets.zero collectionViewLayout.minimumLineSpacing = 0 @@ -143,7 +143,7 @@ open class FolioReaderCenter: UIViewController, UICollectionViewDelegate, UIColl let background = folioReader.isNight(self.readerConfig.nightModeBackground, UIColor.white) view.backgroundColor = background - + // CollectionView collectionView = UICollectionView(frame: screenBounds, collectionViewLayout: collectionViewLayout) collectionView.autoresizingMask = [.flexibleWidth, .flexibleHeight] @@ -156,7 +156,7 @@ open class FolioReaderCenter: UIViewController, UICollectionViewDelegate, UIColl collectionView.decelerationRate = UIScrollViewDecelerationRateFast enableScrollBetweenChapters(scrollEnabled: true) view.addSubview(collectionView) - + // Activity Indicator self.activityIndicator.activityIndicatorViewStyle = .gray self.activityIndicator.hidesWhenStopped = true @@ -164,19 +164,19 @@ open class FolioReaderCenter: UIViewController, UICollectionViewDelegate, UIColl self.activityIndicator.backgroundColor = UIColor.gray self.view.addSubview(self.activityIndicator) self.view.bringSubview(toFront: self.activityIndicator) - + if #available(iOS 10.0, *) { collectionView.isPrefetchingEnabled = false } - + // Register cell classes collectionView?.register(FolioReaderPage.self, forCellWithReuseIdentifier: kReuseCellIdentifier) - + // Configure navigation bar and layout automaticallyAdjustsScrollViewInsets = false extendedLayoutIncludesOpaqueBars = true configureNavBar() - + // Page indicator view if (self.readerConfig.hidePageIndicator == false) { let frame = self.frameForPageIndicatorView() @@ -185,7 +185,7 @@ open class FolioReaderCenter: UIViewController, UICollectionViewDelegate, UIColl view.addSubview(pageIndicatorView) } } - + guard let readerContainer = readerContainer else { return } self.scrollScrubber = ScrollScrubber(frame: frameForScrollScrubber(), withReaderContainer: readerContainer) self.scrollScrubber?.delegate = self @@ -193,43 +193,43 @@ open class FolioReaderCenter: UIViewController, UICollectionViewDelegate, UIColl view.addSubview(scrollScrubber.slider) } } - + override open func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) - + configureNavBar() - + // Update pages pagesForCurrentPage(currentPage) pageIndicatorView?.reloadView(updateShadow: true) } - + override open func viewDidLayoutSubviews() { super.viewDidLayoutSubviews() - + screenBounds = self.getScreenBounds() loadingView.center = view.center - + setPageSize(UIApplication.shared.statusBarOrientation) updateSubviewFrames() } - + // MARK: Layout - + /** Enable or disable the scrolling between chapters (`FolioReaderPage`s). If this is enabled it's only possible to read the current chapter. If another chapter should be displayed is has to be triggered programmatically with `changePageWith`. - + - parameter scrollEnabled: `Bool` which enables or disables the scrolling between `FolioReaderPage`s. */ open func enableScrollBetweenChapters(scrollEnabled: Bool) { self.collectionView.isScrollEnabled = scrollEnabled } - + fileprivate func updateSubviewFrames() { self.pageIndicatorView?.frame = self.frameForPageIndicatorView() self.scrollScrubber?.frame = self.frameForScrollScrubber() } - + fileprivate func frameForPageIndicatorView() -> CGRect { var bounds = CGRect(x: 0, y: screenBounds.size.height-pageIndicatorHeight, width: screenBounds.size.width, height: pageIndicatorHeight) @@ -239,12 +239,12 @@ open class FolioReaderCenter: UIViewController, UICollectionViewDelegate, UIColl return bounds } - + fileprivate func frameForScrollScrubber() -> CGRect { let scrubberY: CGFloat = ((self.readerConfig.shouldHideNavigationOnTap == true || self.readerConfig.hideBars == true) ? 50 : 74) return CGRect(x: self.pageWidth + 10, y: scrubberY, width: 40, height: (self.pageHeight - 100)) } - + func configureNavBar() { let navBackground = folioReader.isNight(self.readerConfig.nightModeMenuBackground, UIColor.white) let tintColor = readerConfig.tintColor @@ -252,35 +252,41 @@ open class FolioReaderCenter: UIViewController, UICollectionViewDelegate, UIColl let font = UIFont(name: "Avenir-Light", size: 17)! setTranslucentNavigation(color: navBackground, tintColor: tintColor, titleColor: navText, andFont: font) } - + func configureNavBarButtons() { - + // Navbar buttons let shareIcon = UIImage(readerImageNamed: "icon-navbar-share")?.ignoreSystemTint(withConfiguration: self.readerConfig) let audioIcon = UIImage(readerImageNamed: "icon-navbar-tts")?.ignoreSystemTint(withConfiguration: self.readerConfig) //man-speech-icon let closeIcon = UIImage(readerImageNamed: "icon-navbar-close")?.ignoreSystemTint(withConfiguration: self.readerConfig) let tocIcon = UIImage(readerImageNamed: "icon-navbar-toc")?.ignoreSystemTint(withConfiguration: self.readerConfig) let fontIcon = UIImage(readerImageNamed: "icon-navbar-font")?.ignoreSystemTint(withConfiguration: self.readerConfig) + let space = 70 as CGFloat - + let menu = UIBarButtonItem(image: closeIcon, style: .plain, target: self, action:#selector(closeReader(_:))) let toc = UIBarButtonItem(image: tocIcon, style: .plain, target: self, action:#selector(presentChapterList(_:))) - + navigationItem.leftBarButtonItems = [menu, toc] - + var rightBarIcons = [UIBarButtonItem]() - + if (self.readerConfig.allowSharing == true) { rightBarIcons.append(UIBarButtonItem(image: shareIcon, style: .plain, target: self, action:#selector(shareChapter(_:)))) } - + + if readerConfig.allowBookmarking { + let bookmarkButton = UIBookmarkBarButtonItem(target: self, action: #selector(didTapBookmarkIcon(_:)), readerConfig: readerConfig) + rightBarIcons.append(bookmarkButton) + } + if self.book.hasAudio || self.readerConfig.enableTTS { rightBarIcons.append(UIBarButtonItem(image: audioIcon, style: .plain, target: self, action:#selector(presentPlayerMenu(_:)))) } - + let font = UIBarButtonItem(image: fontIcon, style: .plain, target: self, action: #selector(presentFontsMenu)) font.width = space - + rightBarIcons.append(contentsOf: [font]) navigationItem.rightBarButtonItems = rightBarIcons @@ -288,28 +294,28 @@ open class FolioReaderCenter: UIViewController, UICollectionViewDelegate, UIColl navigationItem.title = book.title } } - + func reloadData() { self.loadingView.stopAnimating() self.totalPages = book.spine.spineReferences.count - + self.collectionView.reloadData() self.configureNavBarButtons() self.setCollectionViewProgressiveDirection() - + if self.readerConfig.loadSavedPositionForCurrentBook { guard let position = folioReader.savedPositionForCurrentBook, let pageNumber = position["pageNumber"] as? Int, pageNumber > 0 else { self.currentPageNumber = 1 return } - + self.changePageWith(page: pageNumber) self.currentPageNumber = pageNumber } } - + // MARK: Change page progressive direction - + private func transformViewForRTL(_ view: UIView?) { if folioReader.needsRTLChange { view?.transform = CGAffineTransform(scaleX: -1, y: 1) @@ -317,36 +323,36 @@ open class FolioReaderCenter: UIViewController, UICollectionViewDelegate, UIColl view?.transform = CGAffineTransform.identity } } - + func setCollectionViewProgressiveDirection() { self.transformViewForRTL(self.collectionView) } - + func setPageProgressiveDirection(_ page: FolioReaderPage) { self.transformViewForRTL(page) } - + // MARK: Change layout orientation - + /// Get internal page offset before layout change private func updatePageOffsetRate() { guard let currentPage = self.currentPage, let webView = currentPage.webView else { return } - + let pageScrollView = webView.scrollView let contentSize = pageScrollView.contentSize.forDirection(withConfiguration: self.readerConfig) let contentOffset = pageScrollView.contentOffset.forDirection(withConfiguration: self.readerConfig) self.pageOffsetRate = (contentSize != 0 ? (contentOffset / contentSize) : 0) } - + func setScrollDirection(_ direction: FolioReaderScrollDirection) { guard let currentPage = self.currentPage, let webView = currentPage.webView else { return } - + let pageScrollView = webView.scrollView - + // Get internal page offset before layout change self.updatePageOffsetRate() // Change layout @@ -355,65 +361,65 @@ open class FolioReaderCenter: UIViewController, UICollectionViewDelegate, UIColl self.currentPage?.setNeedsLayout() self.collectionView.collectionViewLayout.invalidateLayout() self.collectionView.setContentOffset(frameForPage(self.currentPageNumber).origin, animated: false) - + // Page progressive direction self.setCollectionViewProgressiveDirection() delay(0.2) { self.setPageProgressiveDirection(currentPage) } - - + + /** * This delay is needed because the page will not be ready yet * so the delay wait until layout finished the changes. */ delay(0.1) { var pageOffset = (pageScrollView.contentSize.forDirection(withConfiguration: self.readerConfig) * self.pageOffsetRate) - + // Fix the offset for paged scroll if (self.readerConfig.scrollDirection == .horizontal && self.pageWidth != 0) { let page = round(pageOffset / self.pageWidth) pageOffset = (page * self.pageWidth) } - + let pageOffsetPoint = self.readerConfig.isDirection(CGPoint(x: 0, y: pageOffset), CGPoint(x: pageOffset, y: 0), CGPoint(x: 0, y: pageOffset)) pageScrollView.setContentOffset(pageOffsetPoint, animated: true) } } - + // MARK: Status bar and Navigation bar - + func hideBars() { guard self.readerConfig.shouldHideNavigationOnTap == true else { return } - + self.updateBarsStatus(true) } - + func showBars() { self.configureNavBar() self.updateBarsStatus(false) } - + func toggleBars() { guard self.readerConfig.shouldHideNavigationOnTap == true else { return } - + let shouldHide = !self.navigationController!.isNavigationBarHidden if shouldHide == false { self.configureNavBar() } - + self.updateBarsStatus(shouldHide) } - + private func updateBarsStatus(_ shouldHide: Bool, shouldShowIndicator: Bool = false) { guard let readerContainer = readerContainer else { return } readerContainer.shouldHideStatusBar = shouldHide - + UIView.animate(withDuration: 0.25, animations: { readerContainer.setNeedsStatusBarAppearanceUpdate() - + // Show minutes indicator if (shouldShowIndicator == true) { self.pageIndicatorView?.minutesLabel.alpha = shouldHide ? 0 : 1 @@ -421,27 +427,27 @@ open class FolioReaderCenter: UIViewController, UICollectionViewDelegate, UIColl }) self.navigationController?.setNavigationBarHidden(shouldHide, animated: true) } - + // MARK: UICollectionViewDataSource - + open func numberOfSections(in collectionView: UICollectionView) -> Int { return 1 } - + open func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { return totalPages } - + open func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { let reuseableCell = collectionView.dequeueReusableCell(withReuseIdentifier: kReuseCellIdentifier, for: indexPath) as? FolioReaderPage return self.configure(readerPageCell: reuseableCell, atIndexPath: indexPath) } - + private func configure(readerPageCell cell: FolioReaderPage?, atIndexPath indexPath: IndexPath) -> UICollectionViewCell { guard let cell = cell, let readerContainer = readerContainer else { return UICollectionViewCell() } - + cell.setup(withReaderContainer: readerContainer) cell.pageNumber = indexPath.row+1 cell.webView?.scrollView.delegate = self @@ -452,50 +458,50 @@ open class FolioReaderCenter: UIViewController, UICollectionViewDelegate, UIColl cell.webView?.frame = cell.webViewFrame() cell.delegate = self cell.backgroundColor = .clear - + setPageProgressiveDirection(cell) - + // Configure the cell let resource = self.book.spine.spineReferences[indexPath.row].resource guard var html = try? String(contentsOfFile: resource.fullHref, encoding: String.Encoding.utf8) else { return cell } - + let mediaOverlayStyleColors = "\"\(self.readerConfig.mediaOverlayColor.hexString(false))\", \"\(self.readerConfig.mediaOverlayColor.highlightColor().hexString(false))\"" - + // Inject CSS let jsFilePath = Bundle.frameworkBundle().path(forResource: "Bridge", ofType: "js") let cssFilePath = Bundle.frameworkBundle().path(forResource: "Style", ofType: "css") let cssTag = "" let jsTag = "" + "" - + let toInject = "\n\(cssTag)\n\(jsTag)\n" html = html.replacingOccurrences(of: "", with: toInject) - + // Font class name var classes = folioReader.currentFont.cssIdentifier classes += " " + folioReader.currentMediaOverlayStyle.className() - + // Night mode if folioReader.nightMode { classes += " nightMode" } - + // Font Size classes += " \(folioReader.currentFontSize.cssIdentifier)" - + html = html.replacingOccurrences(of: " CGSize { var size = CGSize(width: collectionView.frame.width, height: collectionView.frame.height) @@ -513,38 +519,38 @@ open class FolioReaderCenter: UIViewController, UICollectionViewDelegate, UIColl } // MARK: - Device rotation - + override open func willRotate(to toInterfaceOrientation: UIInterfaceOrientation, duration: TimeInterval) { guard folioReader.isReaderReady else { return } - + setPageSize(toInterfaceOrientation) updateCurrentPage() - + if self.currentOrientation == nil || (self.currentOrientation?.isPortrait != toInterfaceOrientation.isPortrait) { var pageIndicatorFrame = pageIndicatorView?.frame pageIndicatorFrame?.origin.y = ((screenBounds.size.height < screenBounds.size.width) ? (self.collectionView.frame.height - pageIndicatorHeight) : (self.collectionView.frame.width - pageIndicatorHeight)) pageIndicatorFrame?.origin.x = 0 pageIndicatorFrame?.size.width = ((screenBounds.size.height < screenBounds.size.width) ? (self.collectionView.frame.width) : (self.collectionView.frame.height)) pageIndicatorFrame?.size.height = pageIndicatorHeight - + var scrollScrubberFrame = scrollScrubber?.slider.frame; scrollScrubberFrame?.origin.x = ((screenBounds.size.height < screenBounds.size.width) ? (screenBounds.size.width - 100) : (screenBounds.size.height + 10)) scrollScrubberFrame?.size.height = ((screenBounds.size.height < screenBounds.size.width) ? (self.collectionView.frame.height - 100) : (self.collectionView.frame.width - 100)) - + self.collectionView.collectionViewLayout.invalidateLayout() - + UIView.animate(withDuration: duration, animations: { // Adjust page indicator view if let pageIndicatorFrame = pageIndicatorFrame { self.pageIndicatorView?.frame = pageIndicatorFrame self.pageIndicatorView?.reloadView(updateShadow: true) } - + // Adjust scroll scrubber slider if let scrollScrubberFrame = scrollScrubberFrame { self.scrollScrubber?.slider.frame = scrollScrubberFrame } - + // Adjust collectionView self.collectionView.contentSize = self.readerConfig.isDirection( CGSize(width: self.pageWidth, height: self.pageHeight * CGFloat(self.totalPages)), @@ -553,44 +559,44 @@ open class FolioReaderCenter: UIViewController, UICollectionViewDelegate, UIColl ) self.collectionView.setContentOffset(self.frameForPage(self.currentPageNumber).origin, animated: false) self.collectionView.collectionViewLayout.invalidateLayout() - + // Adjust internal page offset self.updatePageOffsetRate() }) } - + self.currentOrientation = toInterfaceOrientation } - + override open func didRotate(from fromInterfaceOrientation: UIInterfaceOrientation) { guard folioReader.isReaderReady == true, let currentPage = currentPage else { return } - + // Update pages pagesForCurrentPage(currentPage) currentPage.refreshPageMode() - + scrollScrubber?.setSliderVal() - + // After rotation fix internal page offset var pageOffset = (currentPage.webView?.scrollView.contentSize.forDirection(withConfiguration: self.readerConfig) ?? 0) * pageOffsetRate - + // Fix the offset for paged scroll if (self.readerConfig.scrollDirection == .horizontal && self.pageWidth != 0) { let page = round(pageOffset / self.pageWidth) pageOffset = page * self.pageWidth } - + let pageOffsetPoint = self.readerConfig.isDirection(CGPoint(x: 0, y: pageOffset), CGPoint(x: pageOffset, y: 0), CGPoint(x: 0, y: pageOffset)) currentPage.webView?.scrollView.setContentOffset(pageOffsetPoint, animated: true) } - + override open func willAnimateRotation(to toInterfaceOrientation: UIInterfaceOrientation, duration: TimeInterval) { guard folioReader.isReaderReady else { return } - + self.collectionView.scrollToItem(at: IndexPath(row: self.currentPageNumber - 1, section: 0), at: UICollectionViewScrollPosition(), animated: false) if (self.currentPageNumber + 1) >= totalPages { UIView.animate(withDuration: duration, animations: { @@ -598,9 +604,9 @@ open class FolioReaderCenter: UIViewController, UICollectionViewDelegate, UIColl }) } } - + // MARK: - Page - + func setPageSize(_ orientation: UIInterfaceOrientation) { guard orientation.isPortrait else { if screenBounds.size.width > screenBounds.size.height { @@ -612,7 +618,7 @@ open class FolioReaderCenter: UIViewController, UICollectionViewDelegate, UIColl } return } - + if screenBounds.size.width < screenBounds.size.height { self.pageWidth = screenBounds.size.width self.pageHeight = screenBounds.size.height @@ -621,7 +627,7 @@ open class FolioReaderCenter: UIViewController, UICollectionViewDelegate, UIColl self.pageHeight = screenBounds.size.width } } - + func updateCurrentPage(_ page: FolioReaderPage? = nil, completion: (() -> Void)? = nil) { if let page = page { currentPage = page @@ -630,64 +636,64 @@ open class FolioReaderCenter: UIViewController, UICollectionViewDelegate, UIColl } else { let currentIndexPath = getCurrentIndexPath() currentPage = collectionView.cellForItem(at: currentIndexPath) as? FolioReaderPage - + self.previousPageNumber = currentIndexPath.row self.currentPageNumber = currentIndexPath.row+1 } - + self.nextPageNumber = (((self.currentPageNumber + 1) <= totalPages) ? (self.currentPageNumber + 1) : self.currentPageNumber) - + // Set pages guard let currentPage = currentPage else { completion?() return } - + scrollScrubber?.setSliderVal() - + if let readingTime = currentPage.webView?.js("getReadingTime()") { pageIndicatorView?.totalMinutes = Int(readingTime)! } else { pageIndicatorView?.totalMinutes = 0 } pagesForCurrentPage(currentPage) - + delegate?.pageDidAppear?(currentPage) delegate?.pageItemChanged?(self.getCurrentPageItemNumber()) - + completion?() } - + func pagesForCurrentPage(_ page: FolioReaderPage?) { guard let page = page, let webView = page.webView else { return } - + let pageSize = self.readerConfig.isDirection(pageHeight, self.pageWidth, pageHeight) let contentSize = page.webView?.scrollView.contentSize.forDirection(withConfiguration: self.readerConfig) ?? 0 self.pageIndicatorView?.totalPages = ((pageSize != 0) ? Int(ceil(contentSize / pageSize)) : 0) - + let pageOffSet = self.readerConfig.isDirection(webView.scrollView.contentOffset.x, webView.scrollView.contentOffset.x, webView.scrollView.contentOffset.y) let webViewPage = pageForOffset(pageOffSet, pageHeight: pageSize) - + self.pageIndicatorView?.currentPage = webViewPage } - + func pageForOffset(_ offset: CGFloat, pageHeight height: CGFloat) -> Int { guard (height != 0) else { return 0 } - + let page = Int(ceil(offset / height))+1 return page } - + func getCurrentIndexPath() -> IndexPath { let indexPaths = collectionView.indexPathsForVisibleItems var indexPath = IndexPath() - + if indexPaths.count > 1 { let first = indexPaths.first! let last = indexPaths.last! - + switch self.pageScrollDirection { case .up, .left: if first.compare(last) == .orderedAscending { @@ -705,10 +711,10 @@ open class FolioReaderCenter: UIViewController, UICollectionViewDelegate, UIColl } else { indexPath = indexPaths.first ?? IndexPath(row: 0, section: 0) } - + return indexPath } - + func frameForPage(_ page: Int) -> CGRect { return self.readerConfig.isDirection( CGRect(x: 0, y: self.pageHeight * CGFloat(page-1), width: self.pageWidth, height: self.pageHeight), @@ -716,7 +722,7 @@ open class FolioReaderCenter: UIViewController, UICollectionViewDelegate, UIColl CGRect(x: 0, y: self.pageHeight * CGFloat(page-1), width: self.pageWidth, height: self.pageHeight) ) } - + open func changePageWith(page: Int, andFragment fragment: String, animated: Bool = false, completion: (() -> Void)? = nil) { if (self.currentPageNumber == page) { if let currentPage = currentPage , fragment != "" { @@ -732,7 +738,7 @@ open class FolioReaderCenter: UIViewController, UICollectionViewDelegate, UIColl }) } } - + open func changePageWith(href: String, animated: Bool = false, completion: (() -> Void)? = nil) { let item = findPageByHref(href) let indexPath = IndexPath(row: item, section: 0) @@ -742,11 +748,11 @@ open class FolioReaderCenter: UIViewController, UICollectionViewDelegate, UIColl } }) } - + open func changePageWith(href: String, andAudioMarkID markID: String) { if recentlyScrolled { return } // if user recently scrolled, do not change pages or scroll the webview guard let currentPage = currentPage else { return } - + let item = findPageByHref(href) let pageUpdateNeeded = item+1 != currentPage.pageNumber let indexPath = IndexPath(row: item, section: 0) @@ -760,14 +766,14 @@ open class FolioReaderCenter: UIViewController, UICollectionViewDelegate, UIColl } } } - + open func changePageWith(indexPath: IndexPath, animated: Bool = false, completion: (() -> Void)? = nil) { guard indexPathIsValid(indexPath) else { print("ERROR: Attempt to scroll to invalid index path") completion?() return } - + UIView.animate(withDuration: animated ? 0.3 : 0, delay: 0, options: UIViewAnimationOptions(), animations: { () -> Void in self.collectionView.scrollToItem(at: indexPath, at: .direction(withConfiguration: self.readerConfig), animated: false) }) { (finished: Bool) -> Void in @@ -780,31 +786,31 @@ open class FolioReaderCenter: UIViewController, UICollectionViewDelegate, UIColl self.changePageItem(to: pageItem) } } - + func indexPathIsValid(_ indexPath: IndexPath) -> Bool { let section = indexPath.section let row = indexPath.row let lastSectionIndex = numberOfSections(in: collectionView) - 1 - + //Make sure the specified section exists if section > lastSectionIndex { return false } - + let rowCount = self.collectionView(collectionView, numberOfItemsInSection: indexPath.section) - 1 return row <= rowCount } - + open func isLastPage() -> Bool{ return (currentPageNumber == self.nextPageNumber) } - + public func changePageToNext(_ completion: (() -> Void)? = nil) { changePageWith(page: self.nextPageNumber, animated: true) { () -> Void in completion?() } } - + public func changePageToPrevious(_ completion: (() -> Void)? = nil) { changePageWith(page: self.previousPageNumber, animated: true) { () -> Void in completion?() @@ -833,7 +839,7 @@ open class FolioReaderCenter: UIViewController, UICollectionViewDelegate, UIColl completion?() } - + public func getCurrentPageItemNumber() -> Int { guard let page = currentPage, let webView = page.webView else { return 0 } @@ -843,7 +849,7 @@ open class FolioReaderCenter: UIViewController, UICollectionViewDelegate, UIColl return webViewPage } - + public func changePageItemToPrevious(_ completion: (() -> Void)? = nil) { // TODO: It was implemented for horizontal orientation. // Need check page orientation (v/h) and make correct calc for vertical @@ -865,7 +871,7 @@ open class FolioReaderCenter: UIViewController, UICollectionViewDelegate, UIColl completion?() } - + public func changePageItemToLast(animated: Bool = true, _ completion: (() -> Void)? = nil) { // TODO: It was implemented for horizontal orientation. // Need check page orientation (v/h) and make correct calc for vertical @@ -891,7 +897,7 @@ open class FolioReaderCenter: UIViewController, UICollectionViewDelegate, UIColl completion?() } - + public func changePageItem(to: Int, animated: Bool = true, completion: (() -> Void)? = nil) { // TODO: It was implemented for horizontal orientation. // Need check page orientation (v/h) and make correct calc for vertical @@ -926,7 +932,7 @@ open class FolioReaderCenter: UIViewController, UICollectionViewDelegate, UIColl } } } - + /** Find a page by FRTocReference. */ @@ -940,7 +946,7 @@ open class FolioReaderCenter: UIViewController, UICollectionViewDelegate, UIColl } return count } - + /** Find a page by href. */ @@ -954,17 +960,17 @@ open class FolioReaderCenter: UIViewController, UICollectionViewDelegate, UIColl } return count } - + /** Find and return the current chapter resource. */ public func getCurrentChapter() -> FRResource? { var foundResource: FRResource? - + func search(_ items: [FRTocReference]) { for item in items { guard foundResource == nil else { break } - + if let reference = book.spine.spineReferences[safe: (currentPageNumber - 1)], let resource = item.resource, resource == reference.resource { foundResource = resource break @@ -974,10 +980,10 @@ open class FolioReaderCenter: UIViewController, UICollectionViewDelegate, UIColl } } search(book.flatTableOfContents) - + return foundResource } - + /** Return the current chapter progress based on current chapter and total of chapters. */ @@ -991,7 +997,7 @@ open class FolioReaderCenter: UIViewController, UICollectionViewDelegate, UIColl return CGFloat((100 * current) / total) } - + /** Find and return the current chapter name. */ @@ -1004,18 +1010,18 @@ open class FolioReaderCenter: UIViewController, UICollectionViewDelegate, UIColl let title = item.title else { continue } - + return title } - + return nil } - + // MARK: Public page methods - + /** Changes the current page of the reader. - + - parameter page: The target page index. Note: The page index starts at 1 (and not 0). - parameter animated: En-/Disables the animation of the page change. - parameter completion: A Closure which is called if the page change is completed. @@ -1030,21 +1036,21 @@ open class FolioReaderCenter: UIViewController, UICollectionViewDelegate, UIColl }) } } - + // MARK: - Audio Playing - + func audioMark(href: String, fragmentID: String) { changePageWith(href: href, andAudioMarkID: fragmentID) } - + // MARK: - Sharing - + /** Sharing chapter method. */ @objc func shareChapter(_ sender: UIBarButtonItem) { guard let currentPage = currentPage else { return } - + if let chapterText = currentPage.webView?.js("getBodyText()") { let htmlText = chapterText.replacingOccurrences(of: "[\\n\\r]+", with: "
", options: .regularExpression) var subject = readerConfig.localizedShareChapterSubject @@ -1054,53 +1060,73 @@ open class FolioReaderCenter: UIViewController, UICollectionViewDelegate, UIColl var chapterName = "" var authorName = "" var shareItems = [AnyObject]() - + // Get book title if let title = self.book.title { bookTitle = title subject += " “\(title)”" } - + // Get chapter name if let chapter = getCurrentChapterName() { chapterName = chapter } - + // Get author name if let author = self.book.metadata.creators.first { authorName = author.name } - + // Sharing html and text html = "" html += "

\(htmlText)



" html += "

"+readerConfig.localizedShareAllExcerptsFrom+"

" html += "\(bookTitle)
" html += readerConfig.localizedShareBy+" \(authorName)
" - + if let bookShareLink = readerConfig.localizedShareWebLink { html += "\(bookShareLink.absoluteString)" shareItems.append(bookShareLink as AnyObject) } - + html += "
" text = "\(chapterName)\n\n“\(chapterText)” \n\n\(bookTitle) \n\(readerConfig.localizedShareBy) \(authorName)" - + let act = FolioReaderSharingProvider(subject: subject, text: text, html: html) shareItems.insert(contentsOf: [act, "" as AnyObject], at: 0) - + let activityViewController = UIActivityViewController(activityItems: shareItems, applicationActivities: nil) activityViewController.excludedActivityTypes = [UIActivityType.print, UIActivityType.postToVimeo] - + // Pop style on iPad if let actv = activityViewController.popoverPresentationController { actv.barButtonItem = sender } - + present(activityViewController, animated: true, completion: nil) } } + + @objc func didTapBookmarkIcon(_ sender: UIBookmarkBarButtonItem) { +// guard let bookId = (self.book.name as NSString?)?.deletingPathExtension else { return } +// let pageNumber = folioReader.readerCenter?.currentPageNumber ?? 0 +// +// let match = Bookmark.MatchingBookmark(id: "", bookId: bookId, currentPage: pageNumber) +// let bookmark = Bookmark.matchBookmark(match, withConfiguration: readerConfig) + + let identifier = self + print(identifier) +// if sender.isHighlighed { +// sender.isHighlighed = false +// bookmark?.remove(withConfiguration: readerConfig) +// +// } else { +// sender.isHighlighed = true +// bookmark?.persist(withConfiguration: readerConfig) +// } + } + /** Sharing highlight method. */ @@ -1112,23 +1138,23 @@ open class FolioReaderCenter: UIViewController, UICollectionViewDelegate, UIColl var chapterName = "" var authorName = "" var shareItems = [AnyObject]() - + // Get book title if let title = self.book.title { bookTitle = title subject += " “\(title)”" } - + // Get chapter name if let chapter = getCurrentChapterName() { chapterName = chapter } - + // Get author name if let author = self.book.metadata.creators.first { authorName = author.name } - + // Sharing html and text html = "" html += "

\(chapterName)

" @@ -1136,70 +1162,70 @@ open class FolioReaderCenter: UIViewController, UICollectionViewDelegate, UIColl html += "

"+readerConfig.localizedShareAllExcerptsFrom+"

" html += "\(bookTitle)
" html += readerConfig.localizedShareBy+" \(authorName)
" - + if let bookShareLink = readerConfig.localizedShareWebLink { html += "\(bookShareLink.absoluteString)" shareItems.append(bookShareLink as AnyObject) } - + html += "
" text = "\(chapterName)\n\n“\(string)” \n\n\(bookTitle) \n\(readerConfig.localizedShareBy) \(authorName)" - + let act = FolioReaderSharingProvider(subject: subject, text: text, html: html) shareItems.insert(contentsOf: [act, "" as AnyObject], at: 0) - + let activityViewController = UIActivityViewController(activityItems: shareItems, applicationActivities: nil) activityViewController.excludedActivityTypes = [UIActivityType.print, UIActivityType.postToVimeo] - + // Pop style on iPad if let actv = activityViewController.popoverPresentationController { actv.sourceView = currentPage actv.sourceRect = rect } - + present(activityViewController, animated: true, completion: nil) } - + // MARK: - ScrollView Delegate - + open func scrollViewWillBeginDragging(_ scrollView: UIScrollView) { self.isScrolling = true clearRecentlyScrolled() recentlyScrolled = true pointNow = scrollView.contentOffset - + if let currentPage = currentPage { currentPage.webView?.createMenu(options: true) currentPage.webView?.setMenuVisible(false) } - + scrollScrubber?.scrollViewWillBeginDragging(scrollView) } - + open func scrollViewDidScroll(_ scrollView: UIScrollView) { - + if (navigationController?.isNavigationBarHidden == false) { self.toggleBars() } - + scrollScrubber?.scrollViewDidScroll(scrollView) - + let isCollectionScrollView = (scrollView is UICollectionView) let scrollType: ScrollType = ((isCollectionScrollView == true) ? .chapter : .page) - + // Update current reading page if (isCollectionScrollView == false), let page = currentPage, let webView = page.webView { - + let pageSize = self.readerConfig.isDirection(self.pageHeight, self.pageWidth, self.pageHeight) let contentOffset = webView.scrollView.contentOffset.forDirection(withConfiguration: self.readerConfig) let contentSize = webView.scrollView.contentSize.forDirection(withConfiguration: self.readerConfig) if (contentOffset + pageSize <= contentSize) { - + let webViewPage = pageForOffset(contentOffset, pageHeight: pageSize) - + if (readerConfig.scrollDirection == .horizontalWithVerticalContent) { let currentIndexPathRow = (page.pageNumber - 1) - + // if the cell reload doesn't save the top position offset if let oldOffSet = self.currentWebViewScrollPositions[currentIndexPathRow], (abs(oldOffSet.y - scrollView.contentOffset.y) > 100) { // Do nothing @@ -1207,7 +1233,7 @@ open class FolioReaderCenter: UIViewController, UICollectionViewDelegate, UIColl self.currentWebViewScrollPositions[currentIndexPathRow] = scrollView.contentOffset } } - + if (pageIndicatorView?.currentPage != webViewPage) { pageIndicatorView?.currentPage = webViewPage } @@ -1215,17 +1241,17 @@ open class FolioReaderCenter: UIViewController, UICollectionViewDelegate, UIColl self.delegate?.pageItemChanged?(webViewPage) } } - + self.updatePageScrollDirection(inScrollView: scrollView, forScrollType: scrollType) } - + private func updatePageScrollDirection(inScrollView scrollView: UIScrollView, forScrollType scrollType: ScrollType) { - + let scrollViewContentOffsetForDirection = scrollView.contentOffset.forDirection(withConfiguration: self.readerConfig, scrollType: scrollType) let pointNowForDirection = pointNow.forDirection(withConfiguration: self.readerConfig, scrollType: scrollType) // The movement is either positive or negative. This happens if the page change isn't completed. Toggle to the other scroll direction then. let isCurrentlyPositive = (self.pageScrollDirection == .left || self.pageScrollDirection == .up) - + if (scrollViewContentOffsetForDirection < pointNowForDirection) { self.pageScrollDirection = .negative(withConfiguration: self.readerConfig, scrollType: scrollType) } else if (scrollViewContentOffsetForDirection > pointNowForDirection) { @@ -1236,10 +1262,10 @@ open class FolioReaderCenter: UIViewController, UICollectionViewDelegate, UIColl self.pageScrollDirection = .positive(withConfiguration: self.readerConfig, scrollType: scrollType) } } - + open func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) { self.isScrolling = false - + // Perform the page after a short delay as the collection view hasn't completed it's transition if this method is called (the index paths aren't right during fast scrolls). delay(0.2, closure: { [weak self] in if (self?.readerConfig.scrollDirection == .horizontalWithVerticalContent), @@ -1247,7 +1273,7 @@ open class FolioReaderCenter: UIViewController, UICollectionViewDelegate, UIColl let currentIndexPathRow = cell.pageNumber - 1 self?.currentWebViewScrollPositions[currentIndexPathRow] = scrollView.contentOffset } - + if (scrollView is UICollectionView) { guard let instance = self else { return @@ -1262,12 +1288,12 @@ open class FolioReaderCenter: UIViewController, UICollectionViewDelegate, UIColl } }) } - + open func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) { recentlyScrolledTimer = Timer(timeInterval:recentlyScrolledDelay, target: self, selector: #selector(FolioReaderCenter.clearRecentlyScrolled), userInfo: nil, repeats: false) RunLoop.current.add(recentlyScrolledTimer, forMode: RunLoopMode.commonModes) } - + @objc func clearRecentlyScrolled() { if(recentlyScrolledTimer != nil) { recentlyScrolledTimer.invalidate() @@ -1275,46 +1301,52 @@ open class FolioReaderCenter: UIViewController, UICollectionViewDelegate, UIColl } recentlyScrolled = false } - + open func scrollViewDidEndScrollingAnimation(_ scrollView: UIScrollView) { scrollScrubber?.scrollViewDidEndScrollingAnimation(scrollView) } - + // MARK: NavigationBar Actions - + @objc func closeReader(_ sender: UIBarButtonItem) { dismiss() folioReader.close() } - + /** Present chapter list */ @objc func presentChapterList(_ sender: UIBarButtonItem) { folioReader.saveReaderState() - + let chapter = FolioReaderChapterList(folioReader: folioReader, readerConfig: readerConfig, book: book, delegate: self) let highlight = FolioReaderHighlightList(folioReader: folioReader, readerConfig: readerConfig) + let bookmark = FolioReaderBookmarkList(folioReader: folioReader, readerConfig: readerConfig) let pageController = PageViewController(folioReader: folioReader, readerConfig: readerConfig) - + pageController.viewControllerOne = chapter pageController.viewControllerTwo = highlight + pageController.viewControllerThree = bookmark pageController.segmentedControlItems = [readerConfig.localizedContentsTitle, readerConfig.localizedHighlightsTitle] - + + if readerConfig.allowBookmarking { + pageController.segmentedControlItems.append(readerConfig.localizedBookmarksTitle) + } + let nav = UINavigationController(rootViewController: pageController) present(nav, animated: true, completion: nil) } - + /** Present fonts and settings menu */ @objc func presentFontsMenu() { folioReader.saveReaderState() hideBars() - + let menu = FolioReaderFontsMenu(folioReader: folioReader, readerConfig: readerConfig) menu.modalPresentationStyle = .custom - + animator = ZFModalTransitionAnimator(modalViewController: menu) animator.isDragable = false animator.bounces = false @@ -1322,21 +1354,21 @@ open class FolioReaderCenter: UIViewController, UICollectionViewDelegate, UIColl animator.behindViewScale = 1 animator.transitionDuration = 0.6 animator.direction = ZFModalTransitonDirection.bottom - + menu.transitioningDelegate = animator self.present(menu, animated: true, completion: nil) } - + /** Present audio player menu */ @objc func presentPlayerMenu(_ sender: UIBarButtonItem) { folioReader.saveReaderState() hideBars() - + let menu = FolioReaderPlayerMenu(folioReader: folioReader, readerConfig: readerConfig) menu.modalPresentationStyle = .custom - + animator = ZFModalTransitionAnimator(modalViewController: menu) animator.isDragable = true animator.bounces = false @@ -1344,18 +1376,18 @@ open class FolioReaderCenter: UIViewController, UICollectionViewDelegate, UIColl animator.behindViewScale = 1 animator.transitionDuration = 0.6 animator.direction = ZFModalTransitonDirection.bottom - + menu.transitioningDelegate = animator present(menu, animated: true, completion: nil) } - + /** Present Quote Share */ func presentQuoteShare(_ string: String) { let quoteShare = FolioReaderQuoteShare(initWithText: string, readerConfig: readerConfig, folioReader: folioReader, book: book) let nav = UINavigationController(rootViewController: quoteShare) - + if UIDevice.current.userInterfaceIdiom == .pad { nav.modalPresentationStyle = .formSheet } @@ -1366,17 +1398,17 @@ open class FolioReaderCenter: UIViewController, UICollectionViewDelegate, UIColl // MARK: FolioPageDelegate extension FolioReaderCenter: FolioReaderPageDelegate { - + public func pageDidLoad(_ page: FolioReaderPage) { if self.readerConfig.loadSavedPositionForCurrentBook, let position = folioReader.savedPositionForCurrentBook { let pageNumber = position["pageNumber"] as? Int let offset = self.readerConfig.isDirection(position["pageOffsetY"], position["pageOffsetX"], position["pageOffsetY"]) as? CGFloat let pageOffset = offset - + if isFirstLoad { updateCurrentPage(page) isFirstLoad = false - + if (self.currentPageNumber == pageNumber && pageOffset > 0) { page.scrollPageToOffset(pageOffset!, animated: false) } @@ -1387,7 +1419,7 @@ extension FolioReaderCenter: FolioReaderPageDelegate { updateCurrentPage(page) isFirstLoad = false } - + // Go to fragment if needed if let fragmentID = tempFragment, let currentPage = currentPage , fragmentID != "" { currentPage.handleAnchor(fragmentID, avoidBeginningAnchors: true, animated: true) diff --git a/Source/FolioReaderConfig.swift b/Source/FolioReaderConfig.swift index 2f1be730b..991419784 100755 --- a/Source/FolioReaderConfig.swift +++ b/Source/FolioReaderConfig.swift @@ -138,6 +138,9 @@ open class FolioReaderConfig: NSObject { /// Allow sharing option, if `false` will hide all sharing icons and options open var allowSharing = true + /// Allow bookmarking option, if `false` will hide all bookmarking icons and options + open var allowBookmarking = true + /// Enable TTS (Text To Speech) open var enableTTS = true @@ -168,6 +171,9 @@ open class FolioReaderConfig: NSObject { // MARK: Localized strings + /// Localizes Bookmarks title + open var localizedBookmarksTitle = NSLocalizedString("Bookmarks", comment: "") + /// Localizes Highlight title open var localizedHighlightsTitle = NSLocalizedString("Highlights", comment: "") diff --git a/Source/Models/Bookmark+Helper.swift b/Source/Models/Bookmark+Helper.swift new file mode 100644 index 000000000..ecedee06c --- /dev/null +++ b/Source/Models/Bookmark+Helper.swift @@ -0,0 +1,130 @@ +// +// Bookmark+Helper.swift +// FolioReaderKit +// +// Created by Omar Albeik on 26.03.2018. +// + +import Foundation +import RealmSwift + +extension Bookmark { + + public struct MatchingBookmark { + var id: String + var bookId: String + var currentPage: Int + } + + /** + Match a bookmark on string. + */ + public static func matchBookmark(_ matchingBookmark: MatchingBookmark, withConfiguration readerConfig: FolioReaderConfig) -> Bookmark? { + + guard let bookmark = Bookmark.allByBookId(withConfiguration: readerConfig, bookId: matchingBookmark.bookId, andPage: matchingBookmark.currentPage as NSNumber).filter({ $0.bookmarkId == matchingBookmark.id }).first else { + + let bookmark = Bookmark() + bookmark.bookmarkId = matchingBookmark.id + bookmark.page = matchingBookmark.currentPage + bookmark.bookId = matchingBookmark.bookId + bookmark.date = Date() + + return bookmark + } + + return bookmark + } + + /// Save a Bookmark with completion block + /// + /// - Parameters: + /// - readerConfig: Current folio reader configuration. + /// - completion: Completion block. + public func persist(withConfiguration readerConfig: FolioReaderConfig, completion: Completion? = nil) { + do { + let realm = try Realm(configuration: readerConfig.realmConfiguration) + realm.beginWrite() + realm.add(self, update: true) + try realm.commitWrite() + completion?(nil) + } catch let error as NSError { + print("Error on persist bookmark: \(error)") + completion?(error) + } + } + + /// Remove a Bookmark + /// + /// - Parameter readerConfig: Current folio reader configuration. + public func remove(withConfiguration readerConfig: FolioReaderConfig) { + do { + guard let realm = try? Realm(configuration: readerConfig.realmConfiguration) else { + return + } + try realm.write { + realm.delete(self) + try realm.commitWrite() + } + } catch let error as NSError { + print("Error on remove bookmark: \(error)") + } + } + + /// Remove a Bookmark by ID + /// + /// - Parameters: + /// - readerConfig: Current folio reader configuration. + /// - bookmarkId: The ID to be removed + public static func removeById(withConfiguration readerConfig: FolioReaderConfig, bookmarkId: String) { + var bookmark: Bookmark? + let predicate = NSPredicate(format:"bookmarkId = %@", bookmarkId) + + do { + let realm = try Realm(configuration: readerConfig.realmConfiguration) + bookmark = realm.objects(Bookmark.self).filter(predicate).toArray(Bookmark.self).first + bookmark?.remove(withConfiguration: readerConfig) + } catch let error as NSError { + print("Error on remove bookmark by id: \(error)") + } + } + + /// Return a list of Bookmarks with a given ID + /// + /// - Parameters: + /// - readerConfig: Current folio reader configuration. + /// - bookId: Book ID + /// - page: Page number + /// - Returns: Return a list of Bookmarks + public static func allByBookId(withConfiguration readerConfig: FolioReaderConfig, bookId: String, andPage page: NSNumber? = nil) -> [Bookmark] { + var bookmarks: [Bookmark]? + var predicate = NSPredicate(format: "bookId = %@", bookId) + if let page = page { + predicate = NSPredicate(format: "bookId = %@ && page = %@", bookId, page) + } + + do { + let realm = try Realm(configuration: readerConfig.realmConfiguration) + bookmarks = realm.objects(Bookmark.self).filter(predicate).toArray(Bookmark.self) + return (bookmarks ?? []) + } catch let error as NSError { + print("Error on fetch all by book Id: \(error)") + return [] + } + } + + /// Return all Bookmarks + /// + /// - Parameter readerConfig: - readerConfig: Current folio reader configuration. + /// - Returns: Return all Bookmarks + public static func all(withConfiguration readerConfig: FolioReaderConfig) -> [Bookmark] { + var bookmarks: [Bookmark]? + do { + let realm = try Realm(configuration: readerConfig.realmConfiguration) + bookmarks = realm.objects(Bookmark.self).toArray(Bookmark.self) + return (bookmarks ?? []) + } catch let error as NSError { + print("Error on fetch all: \(error)") + return [] + } + } +} diff --git a/Source/Models/Bookmark.swift b/Source/Models/Bookmark.swift new file mode 100644 index 000000000..3701f63bb --- /dev/null +++ b/Source/Models/Bookmark.swift @@ -0,0 +1,21 @@ +// +// Bookmark.swift +// FolioReaderKit +// +// Created by Omar Albeik on 26.03.2018. +// + +import Foundation +import RealmSwift + +/// A Bookmark object +open class Bookmark: Object { + @objc open dynamic var bookId: String! + @objc open dynamic var date: Date! + @objc open dynamic var bookmarkId: String! + @objc open dynamic var page: Int = 0 + + override open class func primaryKey()-> String { + return "bookmarkId" + } +} diff --git a/Source/PageViewController.swift b/Source/PageViewController.swift index fcfaf6383..46fa5f29f 100644 --- a/Source/PageViewController.swift +++ b/Source/PageViewController.swift @@ -15,6 +15,7 @@ class PageViewController: UIPageViewController { var segmentedControlItems = [String]() var viewControllerOne: UIViewController! var viewControllerTwo: UIViewController! + var viewControllerThree: UIViewController! var index: Int fileprivate var readerConfig: FolioReaderConfig fileprivate var folioReader: FolioReader @@ -43,13 +44,22 @@ class PageViewController: UIPageViewController { segmentedControl.selectedSegmentIndex = index segmentedControl.setWidth(100, forSegmentAt: 0) segmentedControl.setWidth(100, forSegmentAt: 1) + segmentedControl.setWidth(100, forSegmentAt: 2) self.navigationItem.titleView = segmentedControl viewList = [viewControllerOne, viewControllerTwo] + if readerConfig.allowBookmarking { + viewList.append(viewControllerThree) + } + viewControllerOne.didMove(toParentViewController: self) viewControllerTwo.didMove(toParentViewController: self) + if readerConfig.allowBookmarking { + viewControllerThree.didMove(toParentViewController: self) + } + self.delegate = self self.dataSource = self diff --git a/Source/Resources/Images.xcassets/icon-navbar-bookmark-selected.imageset/Contents.json b/Source/Resources/Images.xcassets/icon-navbar-bookmark-selected.imageset/Contents.json new file mode 100644 index 000000000..54824e564 --- /dev/null +++ b/Source/Resources/Images.xcassets/icon-navbar-bookmark-selected.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "icon-navbar-bookmark-selected.pdf" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Source/Resources/Images.xcassets/icon-navbar-bookmark-selected.imageset/icon-navbar-bookmark-selected.pdf b/Source/Resources/Images.xcassets/icon-navbar-bookmark-selected.imageset/icon-navbar-bookmark-selected.pdf new file mode 100644 index 0000000000000000000000000000000000000000..c6a1faec91ee39b885c3d3978b1e6df25b7903ba GIT binary patch literal 4046 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 literal 0 HcmV?d00001 diff --git a/Source/UIBookmarkBarButtonItem.swift b/Source/UIBookmarkBarButtonItem.swift new file mode 100644 index 000000000..6fa8acb42 --- /dev/null +++ b/Source/UIBookmarkBarButtonItem.swift @@ -0,0 +1,34 @@ +// +// UIBookmarkBarButtonItem.swift +// AEXML +// +// Created by Omar Albeik on 26.03.2018. +// + +import UIKit + +class UIBookmarkBarButtonItem: UIBarButtonItem { + + var isHighlighed = false { + didSet { + image = UIImage(readerImageNamed: isHighlighed ? "icon-navbar-bookmark-selected" : "icon-navbar-bookmark") + } + } + + var readerConfig: FolioReaderConfig? { + didSet { + print("readerConfig") + guard let config = readerConfig else { return } + image = image?.ignoreSystemTint(withConfiguration: config) + } + } + + convenience init(target: Any?, action: Selector?, isHighlighed: Bool = false, readerConfig: FolioReaderConfig) { + + self.init(image: UIImage(readerImageNamed: "icon-navbar-bookmark"), style: .plain, target: target, action: action) + + self.isHighlighed = isHighlighed + self.readerConfig = readerConfig + } + +} From a92ae0271acd6a384303559b17dfacd41bebb117 Mon Sep 17 00:00:00 2001 From: Omar Albeik Date: Mon, 26 Mar 2018 14:52:23 +0300 Subject: [PATCH 2/3] Remove commented code --- Source/FolioReaderCenter.swift | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/Source/FolioReaderCenter.swift b/Source/FolioReaderCenter.swift index 0c8108269..cf897191b 100755 --- a/Source/FolioReaderCenter.swift +++ b/Source/FolioReaderCenter.swift @@ -1114,17 +1114,12 @@ open class FolioReaderCenter: UIViewController, UICollectionViewDelegate, UIColl // let match = Bookmark.MatchingBookmark(id: "", bookId: bookId, currentPage: pageNumber) // let bookmark = Bookmark.matchBookmark(match, withConfiguration: readerConfig) - let identifier = self - print(identifier) + if sender.isHighlighed { + sender.isHighlighed = false -// if sender.isHighlighed { -// sender.isHighlighed = false -// bookmark?.remove(withConfiguration: readerConfig) -// -// } else { -// sender.isHighlighed = true -// bookmark?.persist(withConfiguration: readerConfig) -// } + } else { + sender.isHighlighed = true + } } /** From a61b4bd9059c393323978b47583d502fb4ec9e9a Mon Sep 17 00:00:00 2001 From: Omar Albeik Date: Tue, 3 Apr 2018 09:58:16 +0300 Subject: [PATCH 3/3] Update Bookmarks --- .../xcshareddata/IDEWorkspaceChecks.plist | 8 ++++ Source/FolioReaderBookmarkList.swift | 37 +++++++++---------- Source/Models/Bookmark+Helper.swift | 5 ++- Source/Models/Bookmark.swift | 1 + 4 files changed, 29 insertions(+), 22 deletions(-) create mode 100644 Example/Example.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist diff --git a/Example/Example.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/Example/Example.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 000000000..18d981003 --- /dev/null +++ b/Example/Example.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/Source/FolioReaderBookmarkList.swift b/Source/FolioReaderBookmarkList.swift index e01e774ee..fff4da3bf 100644 --- a/Source/FolioReaderBookmarkList.swift +++ b/Source/FolioReaderBookmarkList.swift @@ -3,6 +3,7 @@ // FolioReaderKit // // Created by Omar Albeik on 26.03.2018. +// Copyright (c) 2015 Folio Reader. All rights reserved. // import UIKit @@ -27,38 +28,34 @@ class FolioReaderBookmarkList: UITableViewController { override func viewDidLoad() { super.viewDidLoad() - self.tableView.register(UITableViewCell.self, forCellReuseIdentifier: kReuseCellIdentifier) - self.tableView.separatorInset = UIEdgeInsets.zero - self.tableView.backgroundColor = self.folioReader.isNight(self.readerConfig.nightModeMenuBackground, self.readerConfig.menuBackgroundColor) - self.tableView.separatorColor = self.folioReader.isNight(self.readerConfig.nightModeSeparatorColor, self.readerConfig.menuSeparatorColor) + tableView.register(UITableViewCell.self, forCellReuseIdentifier: kReuseCellIdentifier) + tableView.separatorInset = UIEdgeInsets.zero + tableView.backgroundColor = folioReader.isNight(readerConfig.nightModeMenuBackground, readerConfig.menuBackgroundColor) + tableView.separatorColor = folioReader.isNight(readerConfig.nightModeSeparatorColor, readerConfig.menuSeparatorColor) - guard let bookId = (self.folioReader.readerContainer?.book.name as NSString?)?.deletingPathExtension else { - self.bookmarks = [] + guard let bookId = (folioReader.readerContainer?.book.name as NSString?)?.deletingPathExtension else { + bookmarks = [] return } - self.bookmarks = Bookmark.allByBookId(withConfiguration: self.readerConfig, bookId: bookId) + bookmarks = Bookmark.allByBookId(withConfiguration: readerConfig, bookId: bookId) } // MARK: - Table view data source - override func numberOfSections(in tableView: UITableView) -> Int { - return 1 - } - override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return bookmarks.count } override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: kReuseCellIdentifier, for: indexPath) - cell.backgroundColor = UIColor.clear + cell.backgroundColor = .clear - let bookmark = bookmarks[(indexPath as NSIndexPath).row] + let bookmark = bookmarks[indexPath.row] // Format date let dateFormatter = DateFormatter() - dateFormatter.dateFormat = self.readerConfig.localizedHighlightsDateFormat + dateFormatter.dateFormat = readerConfig.localizedHighlightsDateFormat let dateString = dateFormatter.string(from: bookmark.date) cell.textLabel?.text = "Page \(bookmark.page)" @@ -70,19 +67,19 @@ class FolioReaderBookmarkList: UITableViewController { // MARK: - Table view delegate override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { - guard let bookmark = bookmarks[safe: (indexPath as NSIndexPath).row] else { + guard let bookmark = bookmarks[safe: indexPath.row] else { return } - self.folioReader.readerCenter?.changePageWith(page: bookmark.page, andFragment: bookmark.bookmarkId) - self.dismiss() + folioReader.readerCenter?.changePageWith(page: bookmark.page, andFragment: bookmark.bookmarkId) + dismiss() } override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) { if editingStyle == .delete { - let bookmark = bookmarks[(indexPath as NSIndexPath).row] - bookmark.remove(withConfiguration: self.readerConfig) // Remove from Database - bookmarks.remove(at: (indexPath as NSIndexPath).row) + let bookmark = bookmarks[indexPath.row] + bookmark.remove(withConfiguration: readerConfig) // Remove from Database + bookmarks.remove(at: indexPath.row) tableView.deleteRows(at: [indexPath], with: .fade) } } diff --git a/Source/Models/Bookmark+Helper.swift b/Source/Models/Bookmark+Helper.swift index ecedee06c..935936735 100644 --- a/Source/Models/Bookmark+Helper.swift +++ b/Source/Models/Bookmark+Helper.swift @@ -3,6 +3,7 @@ // FolioReaderKit // // Created by Omar Albeik on 26.03.2018. +// Copyright (c) 2015 Folio Reader. All rights reserved. // import Foundation @@ -121,8 +122,8 @@ extension Bookmark { do { let realm = try Realm(configuration: readerConfig.realmConfiguration) bookmarks = realm.objects(Bookmark.self).toArray(Bookmark.self) - return (bookmarks ?? []) - } catch let error as NSError { + return bookmarks ?? [] + } catch let error { print("Error on fetch all: \(error)") return [] } diff --git a/Source/Models/Bookmark.swift b/Source/Models/Bookmark.swift index 3701f63bb..55e00cc7d 100644 --- a/Source/Models/Bookmark.swift +++ b/Source/Models/Bookmark.swift @@ -3,6 +3,7 @@ // FolioReaderKit // // Created by Omar Albeik on 26.03.2018. +// Copyright (c) 2015 Folio Reader. All rights reserved. // import Foundation