diff --git a/Kiwix-iOS/Controller/Main/Buttons.swift b/Kiwix-iOS/Controller/Main/Buttons.swift index 0bd8f52f..3e857c49 100644 --- a/Kiwix-iOS/Controller/Main/Buttons.swift +++ b/Kiwix-iOS/Controller/Main/Buttons.swift @@ -32,6 +32,8 @@ class Buttons: LPTBarButtonItemDelegate { delegate?.didTapBackButton() case forward: delegate?.didTapForwardButton() + case toc: + delegate?.didTapTOCButton() default: return } diff --git a/Kiwix-iOS/Controller/Main/Controllers.swift b/Kiwix-iOS/Controller/Main/Controllers.swift index af7663cf..741dba30 100644 --- a/Kiwix-iOS/Controller/Main/Controllers.swift +++ b/Kiwix-iOS/Controller/Main/Controllers.swift @@ -10,26 +10,12 @@ import UIKit class Controllers { - public func cleanUp() { - //_bookmark = nil - //bookmarkHUD = nil - _library = nil - _search = nil - //setting = nil - _welcome = nil - } - // MARK: - Main class var main: MainController { return (UIApplication.appDelegate.window?.rootViewController as! UINavigationController).topViewController as! MainController } - - // MARK: - NavigationList - - private(set) lazy var navigationList = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "NavigationListController") as! NavigationListController - // MARK: - Bookmark // // private var bookmark: UINavigationController? diff --git a/Kiwix-iOS/Controller/Main/MainController.swift b/Kiwix-iOS/Controller/Main/MainController.swift index 1c79f9f6..8891eb9e 100644 --- a/Kiwix-iOS/Controller/Main/MainController.swift +++ b/Kiwix-iOS/Controller/Main/MainController.swift @@ -12,10 +12,21 @@ import WebKit class MainController: UIViewController { @IBOutlet weak var webView: UIWebView! + @IBOutlet weak var dimView: UIView! + @IBOutlet weak var tocVisiualEffectView: UIVisualEffectView! + @IBOutlet weak var tocTopToSuperViewBottomSpacing: NSLayoutConstraint! + @IBOutlet weak var tocHeightConstraint: NSLayoutConstraint! + @IBOutlet weak var tocLeadSpacing: NSLayoutConstraint! + + let searchBar = SearchBar() lazy var controllers = Controllers() lazy var buttons = Buttons() + + var isShowingTableOfContents = false + private(set) var tableOfContentsController: TableOfContentsController? + override func viewDidLoad() { super.viewDidLoad() @@ -31,6 +42,7 @@ class MainController: UIViewController { super.traitCollectionDidChange(previousTraitCollection) guard traitCollection.horizontalSizeClass != previousTraitCollection?.horizontalSizeClass || traitCollection.verticalSizeClass != previousTraitCollection?.verticalSizeClass else {return} + // buttons switch traitCollection.horizontalSizeClass { case .compact: navigationController?.setToolbarHidden(false, animated: false) @@ -48,5 +60,16 @@ class MainController: UIViewController { default: return } + configureTOCConstraints() } + + override func prepare(for segue: UIStoryboardSegue, sender: Any?) { + if segue.identifier == "EmbeddedTOCController" { + guard let controller = segue.destination as? TableOfContentsController else {return} + tableOfContentsController = controller + tableOfContentsController?.delegate = self + } + } + + } diff --git a/Kiwix-iOS/Controller/Main/MainDelegates.swift b/Kiwix-iOS/Controller/Main/MainDelegates.swift index 36561057..399be9fb 100644 --- a/Kiwix-iOS/Controller/Main/MainDelegates.swift +++ b/Kiwix-iOS/Controller/Main/MainDelegates.swift @@ -9,9 +9,40 @@ import UIKit import SafariServices +// MARK: - Web + +extension MainController: UIWebViewDelegate, SFSafariViewControllerDelegate { + func webView(_ webView: UIWebView, shouldStartLoadWith request: URLRequest, navigationType: UIWebViewNavigationType) -> Bool { + guard let url = request.url else {return false} + guard url.isKiwixURL else { + let controller = SFSafariViewController(url: url) + controller.delegate = self + present(controller, animated: true, completion: nil) + return false + } + return true + } + + func webViewDidStartLoad(_ webView: UIWebView) { + } + + func webViewDidFinishLoad(_ webView: UIWebView) { + JS.preventDefaultLongTap(webView: webView) + guard let title = JS.getTitle(from: webView) else {return} + searchBar.title = title + + buttons.back.tintColor = webView.canGoBack ? nil : UIColor.gray + buttons.forward.tintColor = webView.canGoForward ? nil : UIColor.gray + } + + func webView(_ webView: UIWebView, didFailLoadWithError error: Error) { + + } +} + // MARK: - Search -extension MainController: SearchBarDelegate { +extension MainController: SearchBarDelegate, SearchContainerDelegate { func didBecomeFirstResponder(searchBar: SearchBar) { showSearch(animated: true) @@ -82,50 +113,15 @@ extension MainController: SearchBarDelegate { completion(true) } } -} - -// MARK: - Web - -extension MainController: UIWebViewDelegate, SFSafariViewControllerDelegate { - func webView(_ webView: UIWebView, shouldStartLoadWith request: URLRequest, navigationType: UIWebViewNavigationType) -> Bool { - guard let url = request.url else {return false} - guard url.isKiwixURL else { - let controller = SFSafariViewController(url: url) - controller.delegate = self - present(controller, animated: true, completion: nil) - return false - } - return true - } - func webViewDidStartLoad(_ webView: UIWebView) { - } - - func webViewDidFinishLoad(_ webView: UIWebView) { - JS.preventDefaultLongTap(webView: webView) - guard let title = JS.getTitle(from: webView) else {return} - searchBar.title = title - - buttons.back.tintColor = webView.canGoBack ? nil : UIColor.gray - buttons.forward.tintColor = webView.canGoForward ? nil : UIColor.gray - } - - func webView(_ webView: UIWebView, didFailLoadWithError error: Error) { - - } -} - -// MARK: - SFSafariViewControllerDelegate - -extension MainController { - func safariViewControllerDidFinish(_ controller: SFSafariViewController) { - controller.dismiss(animated: true, completion: nil) + func didTapSearchDimView() { + _ = searchBar.resignFirstResponder() } } // MARK: - Button Delegates -extension MainController: ButtonDelegates, SearchContainerDelegate { +extension MainController: ButtonDelegates { func didTapBackButton() { webView.goBack() } @@ -135,7 +131,7 @@ extension MainController: ButtonDelegates, SearchContainerDelegate { } func didTapTOCButton() { - + isShowingTableOfContents ? hideTableOfContents(animated: true) : showTableOfContents(animated: true) } func didTapBookmarkButton() { @@ -161,20 +157,81 @@ extension MainController: ButtonDelegates, SearchContainerDelegate { } } -// MARK: - NavigationListControllerDelegate +// MARK: - Table Of Content -//extension MainController: NavigationListControllerDelegate { -// func load(url: URL) { -// let request = URLRequest(url: url) -// webView.loadRequest(request) -// } -//} - -// MARK: - SearchContainerDelegate - -extension MainController { - func didTapDimView() { - _ = searchBar.resignFirstResponder() +extension MainController: TableOfContentsDelegate { + func showTableOfContents(animated: Bool) { + guard welcomeController == nil else {return} + isShowingTableOfContents = true + tocVisiualEffectView.isHidden = false + dimView.isHidden = false + dimView.alpha = 0.0 + view.layoutIfNeeded() + + //configureTableOfContents() + configureTOCConstraints() + + if animated { + UIView.animate(withDuration: 0.3, delay: 0.0, usingSpringWithDamping: 0.8, initialSpringVelocity: 0.0, options: .curveEaseOut, animations: { + self.view.layoutIfNeeded() + self.dimView.alpha = 0.5 + }) { (completed) in } + } else { + view.layoutIfNeeded() + dimView.alpha = 0.5 + } + + JS.startTOCCallBack(webView) + } + + func hideTableOfContents(animated: Bool) { + isShowingTableOfContents = false + view.layoutIfNeeded() + + configureTOCConstraints() + if animated { + UIView.animate(withDuration: 0.2, delay: 0.0, options: .curveEaseIn, animations: { + self.view.layoutIfNeeded() + self.dimView.alpha = 0.0 + }) { (completed) in + self.dimView.isHidden = true + self.tocVisiualEffectView.isHidden = true + } + } else { + view.layoutIfNeeded() + dimView.alpha = 0.0 + dimView.isHidden = true + tocVisiualEffectView.isHidden = true + } + + JS.stopTOCCallBack(webView) + } + + func configureTOCConstraints() { + switch traitCollection.horizontalSizeClass { + case .compact: + let tocHeight: CGFloat = { + guard let controller = tableOfContentsController else {return floor(view.frame.height * 0.4)} + let tocContentHeight = controller.tableView.contentSize.height + guard controller.headings.count != 0 else {return floor(view.frame.height * 0.4)} + let toolBarHeight: CGFloat = traitCollection.horizontalSizeClass == .regular ? 0.0 : (traitCollection.verticalSizeClass == .compact ? 32.0 : 44.0) + return min(tocContentHeight + toolBarHeight, floor(view.frame.height * 0.65)) + }() + tocHeightConstraint.constant = tocHeight + tocTopToSuperViewBottomSpacing.constant = isShowingTableOfContents ? tocHeight : 0.0 + case .regular: + tocLeadSpacing.constant = isShowingTableOfContents ? 0.0 : 270 + default: + break + } + } + + func didSelectTOCItem(heading: HTMLHeading) { + + } + + @IBAction func didTapTOCDimView(_ sender: UITapGestureRecognizer) { + hideTableOfContents(animated: true) } } @@ -193,10 +250,14 @@ extension MainController { } func hideWelcome() { - guard let controller = childViewControllers.flatMap({$0 as? WelcomeController}).first else {return} + guard let controller = welcomeController else {return} controller.removeFromParentViewController() controller.view.removeFromSuperview() } + + var welcomeController: WelcomeController? { + return childViewControllers.flatMap({$0 as? WelcomeController}).first + } } // MARK: - Bookmark @@ -224,3 +285,11 @@ extension MainController: UIViewControllerTransitioningDelegate { return BookmarkHUDAnimator(animateIn: false) } } + +// MARK: - SFSafariViewControllerDelegate + +extension MainController { + func safariViewControllerDidFinish(_ controller: SFSafariViewController) { + controller.dismiss(animated: true, completion: nil) + } +} diff --git a/Kiwix-iOS/Controller/Main/NavigationListController.swift b/Kiwix-iOS/Controller/Main/NavigationListController.swift deleted file mode 100644 index 378003c3..00000000 --- a/Kiwix-iOS/Controller/Main/NavigationListController.swift +++ /dev/null @@ -1,95 +0,0 @@ -// -// NavigationListController.swift -// Kiwix -// -// Created by Chris Li on 11/25/16. -// Copyright © 2016 Chris Li. All rights reserved. -// - -import UIKit - -class NavigationListController: UITableViewController { - - override func viewDidLoad() { - super.viewDidLoad() - - // Uncomment the following line to preserve selection between presentations - // self.clearsSelectionOnViewWillAppear = false - - // Uncomment the following line to display an Edit button in the navigation bar for this view controller. - // self.navigationItem.rightBarButtonItem = self.editButtonItem() - } - - override func didReceiveMemoryWarning() { - super.didReceiveMemoryWarning() - // Dispose of any resources that can be recreated. - } - - // MARK: - Table view data source - - override func numberOfSections(in tableView: UITableView) -> Int { - // #warning Incomplete implementation, return the number of sections - return 0 - } - - override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { - // #warning Incomplete implementation, return the number of rows - return 0 - } - - /* - override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { - let cell = tableView.dequeueReusableCell(withIdentifier: "reuseIdentifier", for: indexPath) - - // Configure the cell... - - return cell - } - */ - - /* - // Override to support conditional editing of the table view. - override func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool { - // Return false if you do not want the specified item to be editable. - return true - } - */ - - /* - // Override to support editing the table view. - override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) { - if editingStyle == .delete { - // Delete the row from the data source - tableView.deleteRows(at: [indexPath], with: .fade) - } else if editingStyle == .insert { - // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view - } - } - */ - - /* - // Override to support rearranging the table view. - override func tableView(_ tableView: UITableView, moveRowAt fromIndexPath: IndexPath, to: IndexPath) { - - } - */ - - /* - // Override to support conditional rearranging of the table view. - override func tableView(_ tableView: UITableView, canMoveRowAt indexPath: IndexPath) -> Bool { - // Return false if you do not want the item to be re-orderable. - return true - } - */ - - /* - // MARK: - Navigation - - // In a storyboard-based application, you will often want to do a little preparation before navigation - override func prepare(for segue: UIStoryboardSegue, sender: Any?) { - // Get the new view controller using segue.destinationViewController. - // Pass the selected object to the new view controller. - } - */ - -} diff --git a/Kiwix-iOS/Controller/Others/TableOfContentsController.swift b/Kiwix-iOS/Controller/Others/TableOfContentsController.swift index 95dc2911..11603830 100644 --- a/Kiwix-iOS/Controller/Others/TableOfContentsController.swift +++ b/Kiwix-iOS/Controller/Others/TableOfContentsController.swift @@ -122,7 +122,7 @@ class TableOfContentsController: UIViewController, UITableViewDelegate, UITableV // MARK: - Table view delegate func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { - delegate?.scrollTo(headings[indexPath.row]) + delegate?.didSelectTOCItem(heading: headings[indexPath.row]) tableView.deselectRow(at: indexPath, animated: true) } @@ -150,5 +150,5 @@ class TableOfContentsController: UIViewController, UITableViewDelegate, UITableV } protocol TableOfContentsDelegate: class { - func scrollTo(_ heading: HTMLHeading) + func didSelectTOCItem(heading: HTMLHeading) } diff --git a/Kiwix-iOS/Controller/Search/SearchContainer.swift b/Kiwix-iOS/Controller/Search/SearchContainer.swift index aa634704..1ca3f3a0 100644 --- a/Kiwix-iOS/Controller/Search/SearchContainer.swift +++ b/Kiwix-iOS/Controller/Search/SearchContainer.swift @@ -58,10 +58,10 @@ class SearchContainer: UIViewController { } @IBAction func handleDimViewTap(_ sender: UITapGestureRecognizer) { - delegate?.didTapDimView() + delegate?.didTapSearchDimView() } } protocol SearchContainerDelegate: class { - func didTapDimView() + func didTapSearchDimView() } diff --git a/Kiwix-iOS/Info.plist b/Kiwix-iOS/Info.plist index 22d76dbe..614abc07 100644 --- a/Kiwix-iOS/Info.plist +++ b/Kiwix-iOS/Info.plist @@ -49,7 +49,7 @@ CFBundleVersion - 1.8.3277 + 1.8.3308 ITSAppUsesNonExemptEncryption LSRequiresIPhoneOS diff --git a/Kiwix-iOS/Storyboard/Main.storyboard b/Kiwix-iOS/Storyboard/Main.storyboard index 308d0e37..a945f668 100644 --- a/Kiwix-iOS/Storyboard/Main.storyboard +++ b/Kiwix-iOS/Storyboard/Main.storyboard @@ -1,5 +1,5 @@ - + @@ -23,7 +23,7 @@ - + @@ -38,51 +38,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -103,11 +58,11 @@ - + diff --git a/Kiwix-iOSWidgets/Bookmarks/Info.plist b/Kiwix-iOSWidgets/Bookmarks/Info.plist index 0bdcb429..5a481b75 100644 --- a/Kiwix-iOSWidgets/Bookmarks/Info.plist +++ b/Kiwix-iOSWidgets/Bookmarks/Info.plist @@ -21,7 +21,7 @@ CFBundleSignature ???? CFBundleVersion - 1.8.3277 + 1.8.3308 NSExtension NSExtensionMainStoryboard diff --git a/Kiwix.xcodeproj/project.pbxproj b/Kiwix.xcodeproj/project.pbxproj index 627fba17..1b3e8de2 100644 --- a/Kiwix.xcodeproj/project.pbxproj +++ b/Kiwix.xcodeproj/project.pbxproj @@ -68,7 +68,6 @@ 9764F5991D833F2B00E0B1C4 /* KiwixURL.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9764F5981D833F2B00E0B1C4 /* KiwixURL.swift */; }; 976B86D81DDA0C7E00FA7FD1 /* SearchContainer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 976B86D71DDA0C7E00FA7FD1 /* SearchContainer.swift */; }; 9771A5BD1DD269BD005F1795 /* Book+CoreDataProperties.swift in Sources */ = {isa = PBXBuildFile; fileRef = 97D6813C1D6F712800E5FA99 /* Book+CoreDataProperties.swift */; }; - 977319841DE8998200111474 /* NavigationListController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 977319831DE8998200111474 /* NavigationListController.swift */; }; 9779C3141D4575AD0064CC8E /* NotificationCenter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 97E609F01D103DED00EBCB9D /* NotificationCenter.framework */; }; 9779C3171D4575AE0064CC8E /* TodayViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9779C3161D4575AE0064CC8E /* TodayViewController.swift */; }; 9779C31E1D4575AE0064CC8E /* Bookmarks.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = 9779C3131D4575AD0064CC8E /* Bookmarks.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; @@ -225,7 +224,6 @@ 9764F5981D833F2B00E0B1C4 /* KiwixURL.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KiwixURL.swift; sourceTree = ""; }; 976A0C801D41619C0006A742 /* DZNEmptyDataSet.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = DZNEmptyDataSet.framework; path = "../../../../Users/chrisli/Library/Developer/Xcode/DerivedData/Kiwix-ayxrfhaqnfxzendihdolvkklkmhk/Build/Products/Debug-iphoneos/DZNEmptyDataSet/DZNEmptyDataSet.framework"; sourceTree = ""; }; 976B86D71DDA0C7E00FA7FD1 /* SearchContainer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SearchContainer.swift; sourceTree = ""; }; - 977319831DE8998200111474 /* NavigationListController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NavigationListController.swift; sourceTree = ""; }; 9779C3131D4575AD0064CC8E /* Bookmarks.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = Bookmarks.appex; sourceTree = BUILT_PRODUCTS_DIR; }; 9779C3161D4575AE0064CC8E /* TodayViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TodayViewController.swift; sourceTree = ""; }; 9779C31B1D4575AE0064CC8E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; @@ -480,7 +478,6 @@ 97BC0FBA1DD90A34004BBAD1 /* old */, 97BC0FBE1DD90A65004BBAD1 /* MainController.swift */, 97D0E98E1DDA12B30029530E /* MainDelegates.swift */, - 977319831DE8998200111474 /* NavigationListController.swift */, 97BC0FC11DD92B62004BBAD1 /* Buttons.swift */, 97BC0FBD1DD90A65004BBAD1 /* JSInjection.swift */, 972F81581DDC1B71008D7289 /* Controllers.swift */, @@ -1185,7 +1182,6 @@ 97D6813F1D6F712800E5FA99 /* Article+CoreDataProperties.swift in Sources */, 97A1FD1D1D6F71D800A80EE2 /* URLResponseCache.swift in Sources */, 97A1FD441D6F728200A80EE2 /* Preference.swift in Sources */, - 977319841DE8998200111474 /* NavigationListController.swift in Sources */, 97D681311D6F70EC00E5FA99 /* 1.5.xcmappingmodel in Sources */, 9732075C1DD136BB00EDD3DC /* CoreDataExtension.swift in Sources */, 973208271DD2238B00EDD3DC /* GlobalQueue.swift in Sources */, diff --git a/Kiwix.xcworkspace/xcuserdata/chrisli.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist b/Kiwix.xcworkspace/xcuserdata/chrisli.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist index 5bbee8dd..e2573a59 100644 --- a/Kiwix.xcworkspace/xcuserdata/chrisli.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist +++ b/Kiwix.xcworkspace/xcuserdata/chrisli.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist @@ -3,36 +3,6 @@ type = "0" version = "2.0"> - - - - - - - -