diff --git a/Kiwix.xcodeproj/project.pbxproj b/Kiwix.xcodeproj/project.pbxproj index 256ce75d..efd1d822 100644 --- a/Kiwix.xcodeproj/project.pbxproj +++ b/Kiwix.xcodeproj/project.pbxproj @@ -47,6 +47,7 @@ 97533B461F4C723900F6651A /* MainWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 97533B451F4C723900F6651A /* MainWindowController.swift */; }; 97598E09202B60E0005A9055 /* BackupManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 97598E08202B60E0005A9055 /* BackupManager.swift */; }; 97598E0A202B60E0005A9055 /* BackupManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 97598E08202B60E0005A9055 /* BackupManager.swift */; }; + 975F97A820D00EAE0005D642 /* SettingSearchController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 975F97A720D00EAE0005D642 /* SettingSearchController.swift */; }; 975FDADA1F6082DA00A10E8C /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 975FDAD91F6082DA00A10E8C /* AppDelegate.swift */; }; 975FDAE41F6082DA00A10E8C /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 975FDAE21F6082DA00A10E8C /* LaunchScreen.storyboard */; }; 975FDAF51F608A2200A10E8C /* URLProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9767717D1F437BB9007ED0C2 /* URLProtocol.swift */; }; @@ -67,6 +68,7 @@ 977D7BB91F9E6A43009A8703 /* ZimMultiReader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 977D7BB31F9E6A43009A8703 /* ZimMultiReader.swift */; }; 977D7BBE1F9FC618009A8703 /* Queue.swift in Sources */ = {isa = PBXBuildFile; fileRef = 977D7BBD1F9FC618009A8703 /* Queue.swift */; }; 977D7BBF1F9FC618009A8703 /* Queue.swift in Sources */ = {isa = PBXBuildFile; fileRef = 977D7BBD1F9FC618009A8703 /* Queue.swift */; }; + 977ED8C820BD9BCB009A2FB2 /* MapController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 977ED8C720BD9BCB009A2FB2 /* MapController.swift */; }; 977F983E1F9E43EC002ABFCE /* ScanProcedure.swift in Sources */ = {isa = PBXBuildFile; fileRef = 977F983D1F9E43EC002ABFCE /* ScanProcedure.swift */; }; 977F983F1F9E43EC002ABFCE /* ScanProcedure.swift in Sources */ = {isa = PBXBuildFile; fileRef = 977F983D1F9E43EC002ABFCE /* ScanProcedure.swift */; }; 979D6E0C20B34FD700B08DE7 /* BookmarkController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 979D6E0B20B34FD700B08DE7 /* BookmarkController.swift */; }; @@ -168,6 +170,7 @@ 97F4D10620AB80740038FC87 /* LibraryZimFileDetailController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 97F4D10520AB80740038FC87 /* LibraryZimFileDetailController.swift */; }; 97F4D10A20ADD0F00038FC87 /* DownloadManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 97F4D10920ADD0F00038FC87 /* DownloadManager.swift */; }; 97F4D10C20ADFE370038FC87 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97F4D10B20ADFE370038FC87 /* Assets.xcassets */; }; + 97F6CC5120BD960F005CDBD2 /* MapKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 97F6CC5020BD960F005CDBD2 /* MapKit.framework */; }; DFD371610877B5817E9C9FEB /* Pods_macOS.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 81DF90AB14037E242E284CA8 /* Pods_macOS.framework */; }; FA1E975E797443400EBF3EE8 /* Pods_WikiMed.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 14995D226EC82CFFBBB5B159 /* Pods_WikiMed.framework */; }; /* End PBXBuildFile section */ @@ -266,6 +269,7 @@ 975415D31F54C1870007EA6C /* SearchProcedure.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchProcedure.swift; sourceTree = ""; }; 97598E08202B60E0005A9055 /* BackupManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BackupManager.swift; sourceTree = ""; }; 9759D4211F4F278800705779 /* Kiwix.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Kiwix.entitlements; sourceTree = ""; }; + 975F97A720D00EAE0005D642 /* SettingSearchController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingSearchController.swift; sourceTree = ""; }; 975FDAD91F6082DA00A10E8C /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 975FDAE31F6082DA00A10E8C /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 975FDAE51F6082DA00A10E8C /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; @@ -285,6 +289,7 @@ 977D7BB21F9E6A43009A8703 /* ZimMultiReader.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ZimMultiReader.mm; sourceTree = ""; }; 977D7BB31F9E6A43009A8703 /* ZimMultiReader.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ZimMultiReader.swift; sourceTree = ""; }; 977D7BBD1F9FC618009A8703 /* Queue.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Queue.swift; sourceTree = ""; }; + 977ED8C720BD9BCB009A2FB2 /* MapController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapController.swift; sourceTree = ""; }; 977F983D1F9E43EC002ABFCE /* ScanProcedure.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScanProcedure.swift; sourceTree = ""; }; 9780DE051E43BFF5009B6945 /* NetworkActivityIndicatorController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NetworkActivityIndicatorController.swift; sourceTree = ""; }; 979315811E5127930093D3BA /* Kiwix.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Kiwix.app; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -624,6 +629,7 @@ 97F4D10520AB80740038FC87 /* LibraryZimFileDetailController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LibraryZimFileDetailController.swift; sourceTree = ""; }; 97F4D10920ADD0F00038FC87 /* DownloadManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DownloadManager.swift; sourceTree = ""; }; 97F4D10B20ADFE370038FC87 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 97F6CC5020BD960F005CDBD2 /* MapKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MapKit.framework; path = System/Library/Frameworks/MapKit.framework; sourceTree = SDKROOT; }; C6EB8B17B86590EA06112D8C /* Pods-macOS.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-macOS.debug.xcconfig"; path = "Pods/Target Support Files/Pods-macOS/Pods-macOS.debug.xcconfig"; sourceTree = ""; }; C93DC28B91BE9E73AFC06E16 /* Pods-iOS.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-iOS.release.xcconfig"; path = "Pods/Target Support Files/Pods-iOS/Pods-iOS.release.xcconfig"; sourceTree = ""; }; DB2AE49B95B84C6AAA4C6A80 /* Pods-macOS.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-macOS.release.xcconfig"; path = "Pods/Target Support Files/Pods-macOS/Pods-macOS.release.xcconfig"; sourceTree = ""; }; @@ -685,6 +691,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 97F6CC5120BD960F005CDBD2 /* MapKit.framework in Frameworks */, 97C575F4202CB0E800E37502 /* NotificationCenter.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; @@ -695,6 +702,7 @@ 3B93EAF9B5C5AA23046BDEAC /* Frameworks */ = { isa = PBXGroup; children = ( + 97F6CC5020BD960F005CDBD2 /* MapKit.framework */, 97A6882F207D40F500DBBE0D /* Pods_iOS.framework */, 975FDB061F608F4100A10E8C /* WebKit.framework */, 2E854211810A39173DD6A5BD /* Pods_iOS.framework */, @@ -736,6 +744,7 @@ 9763EDC8201FCA6900F3A6D5 /* SettingWebController.swift */, 97A2180B2024EC3800D1E67B /* SettingFontSizeViewController.swift */, 97BAA541202B4C5E00500644 /* SettingBackupController.swift */, + 975F97A720D00EAE0005D642 /* SettingSearchController.swift */, 97DBCF9C203CA254004EE274 /* SettingExternalLinkControllerTableViewController.swift */, ); path = Setting; @@ -823,7 +832,8 @@ 97028C4E20192F65001259CB /* TableOfContentController.swift */, 97252102200D3C4B00B60A80 /* HUDController.swift */, 972B6661200808D6003F5365 /* WelcomeController.swift */, - 97C99B45205AF58D00439C77 /* Main */, + 977ED8C720BD9BCB009A2FB2 /* MapController.swift */, + 97C99B47205AF58D00439C77 /* MainController.swift */, 97050CFF1F6730010021DE78 /* Tab */, 972E6F651FA2872A00F5C927 /* Search */, 97B1046D1F8FC61400488444 /* Library */, @@ -1012,14 +1022,6 @@ path = Migration; sourceTree = ""; }; - 97C99B45205AF58D00439C77 /* Main */ = { - isa = PBXGroup; - children = ( - 97C99B47205AF58D00439C77 /* MainController.swift */, - ); - path = Main; - sourceTree = ""; - }; 97CA45D3209BB247008CEA6D /* ZimFileProcessing */ = { isa = PBXGroup; children = ( @@ -1844,6 +1846,7 @@ 97CA45D2209BB23F008CEA6D /* ZimFileProcessingProcedure.swift in Sources */, 97A6882E207D3DE300DBBE0D /* ZimFile.swift in Sources */, 971B8E58202246ED00C5C939 /* RecentSearchCells.swift in Sources */, + 975F97A820D00EAE0005D642 /* SettingSearchController.swift in Sources */, 97242E162093A9AC00AA4436 /* Bookmark.swift in Sources */, 97D00A7F1FBB92D400165629 /* TableOfContentItem.swift in Sources */, 97A5C1412089115D009CA5F9 /* SearchResultContainerController.swift in Sources */, @@ -1861,6 +1864,7 @@ 97A36C321F8C21210079B452 /* AppDelegate.swift in Sources */, 979FD159201679C5007B5290 /* SearchResultsListController.swift in Sources */, 972B66602007F9F7003F5365 /* WebKitWebController.swift in Sources */, + 977ED8C820BD9BCB009A2FB2 /* MapController.swift in Sources */, 97C57638202CB86800E37502 /* Article.swift in Sources */, 9763EDC9201FCA6900F3A6D5 /* SettingWebController.swift in Sources */, 97AC121320878F8B004779D1 /* SearchResultController.swift in Sources */, diff --git a/Kiwix.xcodeproj/xcuserdata/Chrisli.xcuserdatad/xcschemes/Bookmarks.xcscheme b/Kiwix.xcodeproj/xcuserdata/Chrisli.xcuserdatad/xcschemes/Bookmarks.xcscheme index b7e6abe6..68392420 100644 --- a/Kiwix.xcodeproj/xcuserdata/Chrisli.xcuserdatad/xcschemes/Bookmarks.xcscheme +++ b/Kiwix.xcodeproj/xcuserdata/Chrisli.xcuserdatad/xcschemes/Bookmarks.xcscheme @@ -1,6 +1,6 @@ ("langFilterSortByAlphabeticalAsc") static let langFilterNameDisplayInOriginalLocale = DefaultsKey("langFilterNameDisplayInOriginalLocale") - static let resumeData = DefaultsKey<[String: Any]>("resumeData") + } // MARK: - Rate diff --git a/Shared/Procedure/SearchProcedure.swift b/Shared/Procedure/SearchProcedure.swift index 6ea8bda4..c890c471 100644 --- a/Shared/Procedure/SearchProcedure.swift +++ b/Shared/Procedure/SearchProcedure.swift @@ -11,13 +11,15 @@ import ProcedureKit class SearchProcedure: Procedure { let searchText: String let ids: Set + let extractSnippet: Bool private var results = Set() private(set) var sortedResults: [SearchResult] = [] - init(term: String, ids: Set = Set()) { + init(term: String, ids: Set = Set(), extractSnippet: Bool) { self.searchText = term self.ids = ids.count == 0 ? Set(ZimMultiReader.shared.ids) : ids + self.extractSnippet = extractSnippet super.init() name = "Search Procedure" } @@ -33,7 +35,7 @@ class SearchProcedure: Procedure { private func addIndexedSearchResults() { guard !isCancelled else { ZimMultiReader.shared.stopIndexSearch(); return } ZimMultiReader.shared.startIndexSearch(searchText: searchText, zimFileIDs: ids) - while let result = ZimMultiReader.shared.getNextIndexSearchResult() { + while let result = ZimMultiReader.shared.getNextIndexSearchResult(extractSnippet: extractSnippet) { guard !isCancelled else { ZimMultiReader.shared.stopIndexSearch(); return } results.insert(result) } diff --git a/Shared/Procedure/SearchQueue.swift b/Shared/Procedure/SearchQueue.swift index 05967e4b..f23a5196 100644 --- a/Shared/Procedure/SearchQueue.swift +++ b/Shared/Procedure/SearchQueue.swift @@ -7,6 +7,7 @@ // import ProcedureKit +import SwiftyUserDefaults class SearchQueue: ProcedureQueue, ProcedureQueueDelegate { weak var eventDelegate: SearchQueueEvents? @@ -18,7 +19,7 @@ class SearchQueue: ProcedureQueue, ProcedureQueueDelegate { } func enqueue(searchText: String, zimFileIDs: Set) { - let procedure = SearchProcedure(term: searchText, ids: zimFileIDs) + let procedure = SearchProcedure(term: searchText, ids: zimFileIDs, extractSnippet: !Defaults[.searchResultExcludeSnippet]) add(operation: procedure) } diff --git a/Shared/ZimMultiReader/ZimMultiReader.h b/Shared/ZimMultiReader/ZimMultiReader.h index 883a438b..6d101912 100644 --- a/Shared/ZimMultiReader/ZimMultiReader.h +++ b/Shared/ZimMultiReader/ZimMultiReader.h @@ -30,7 +30,7 @@ - (NSString *_Nullable)getMainPagePath:(NSString *_Nonnull)bookID NS_REFINED_FOR_SWIFT; - (void)startIndexSearch:(NSString *_Nonnull)searchText zimFileIDs:(NSSet *_Nonnull)zimFileIDs NS_REFINED_FOR_SWIFT; -- (NSDictionary *_Nullable)getNextIndexSearchResult NS_REFINED_FOR_SWIFT; +- (NSDictionary *_Nullable)getNextIndexSearchResultWithSnippet:(BOOL)extractSnippet NS_REFINED_FOR_SWIFT; - (void)stopIndexSearch; - (NSArray *_Nonnull)getTitleSearchResults:(NSString *_Nonnull)searchText zimFileID:(NSString *_Nullable)zimFileID count:(unsigned int)count NS_REFINED_FOR_SWIFT; diff --git a/Shared/ZimMultiReader/ZimMultiReader.mm b/Shared/ZimMultiReader/ZimMultiReader.mm index b3c67261..99536a65 100644 --- a/Shared/ZimMultiReader/ZimMultiReader.mm +++ b/Shared/ZimMultiReader/ZimMultiReader.mm @@ -217,7 +217,7 @@ NSMutableDictionary *fileURLs = [[NSMutableDictionary alloc] init]; // [ID: File } } -# pragma mark - Search +# pragma mark - Text Search - (void)startIndexSearch:(NSString *)searchText zimFileIDs:(NSSet *)zimFileIDs { std::string searchTextC = [searchText cStringUsingEncoding:NSUTF8StringEncoding]; @@ -250,26 +250,31 @@ NSMutableDictionary *fileURLs = [[NSMutableDictionary alloc] init]; // [ID: File searcher->search(searchTextC, 0, 20); } -- (NSDictionary *)convertSearchResultWithIndentifier:(NSString *)identifier result:(kiwix::Result *)result { +- (NSDictionary *)convertSearchResultWithIndentifier:(NSString *)identifier result:(kiwix::Result *)result extractSnippet:(BOOL)extractSnippet { NSString *title = [NSString stringWithCString:result->get_title().c_str() encoding:NSUTF8StringEncoding]; NSString *path = [NSString stringWithCString:result->get_url().c_str() encoding:NSUTF8StringEncoding]; NSNumber *probability = [[NSNumber alloc] initWithDouble:(double)result->get_score() / double(100)]; - NSString *snippet = [NSString stringWithCString:result->get_snippet().c_str() encoding:NSUTF8StringEncoding]; + NSString *snippet = @""; + + if (extractSnippet) { + snippet = [NSString stringWithCString:result->get_snippet().c_str() encoding:NSUTF8StringEncoding]; + } + delete result; return @{@"id": identifier, @"title": title, @"path": path, @"probability": probability, @"snippet": snippet}; } -- (NSDictionary *)getNextIndexSearchResult { +- (NSDictionary *)getNextIndexSearchResultWithSnippet:(BOOL)extractSnippet { kiwix::Result *result = searcher->getNextResult(); if (result != NULL) { NSString *identifier = searcherZimIDs[result->get_readerIndex()]; - return [self convertSearchResultWithIndentifier:identifier result:result]; + return [self convertSearchResultWithIndentifier:identifier result:result extractSnippet:extractSnippet]; } else { for(auto iter: externalSearchers) { NSString *identifier = [NSString stringWithCString:iter.first.c_str() encoding:NSUTF8StringEncoding]; result = iter.second->getNextResult(); if (result != NULL) { - return [self convertSearchResultWithIndentifier:identifier result:result]; + return [self convertSearchResultWithIndentifier:identifier result:result extractSnippet:extractSnippet]; } } return nil; @@ -308,4 +313,7 @@ NSMutableDictionary *fileURLs = [[NSMutableDictionary alloc] init]; // [ID: File } } +# pragma mark - Geo Search + + @end diff --git a/Shared/ZimMultiReader/ZimMultiReader.swift b/Shared/ZimMultiReader/ZimMultiReader.swift index 17a308b9..1f1fd353 100644 --- a/Shared/ZimMultiReader/ZimMultiReader.swift +++ b/Shared/ZimMultiReader/ZimMultiReader.swift @@ -45,8 +45,8 @@ extension ZimMultiReader { __startIndexSearch(searchText, zimFileIDs: zimFileIDs) } - func getNextIndexSearchResult() -> SearchResult? { - guard let result = __getNextIndexSearchResult() as? Dictionary, + func getNextIndexSearchResult(extractSnippet: Bool) -> SearchResult? { + guard let result = __getNextIndexSearchResult(withSnippet: extractSnippet) as? Dictionary, let id = result["id"] as? String, let path = result["path"] as? String, let title = result["title"] as? String else {return nil} diff --git a/iOS/BookmarksWidget/Info.plist b/iOS/BookmarksWidget/Info.plist index d719b59b..eb775721 100644 --- a/iOS/BookmarksWidget/Info.plist +++ b/iOS/BookmarksWidget/Info.plist @@ -17,9 +17,9 @@ CFBundlePackageType XPC! CFBundleShortVersionString - 1.9.1 + 1.9.2 CFBundleVersion - 18 + 21 NSExtension NSExtensionMainStoryboard diff --git a/iOS/BookmarksWidget/TodayViewController.swift b/iOS/BookmarksWidget/TodayViewController.swift index 28c5b2fd..024022a4 100644 --- a/iOS/BookmarksWidget/TodayViewController.swift +++ b/iOS/BookmarksWidget/TodayViewController.swift @@ -33,7 +33,7 @@ class TodayViewController: UIViewController, NCWidgetProviding, UICollectionView func getBookmarks() -> [(title: String, url: String, thumbImageData: Data)] { return UserDefaults(suiteName: "group.kiwix")?.array(forKey: "bookmarks")? - .flatMap({ $0 as? [String: Any] }).flatMap({ (bookmark) -> (title: String, url: String, thumbImageData: Data)? in + .compactMap({ $0 as? [String: Any] }).compactMap({ (bookmark) -> (title: String, url: String, thumbImageData: Data)? in guard let title = bookmark["title"] as? String, let url = bookmark["url"] as? String, let thumbImageData = bookmark["thumbImageData"] as? Data else {return nil} diff --git a/iOS/Controller/Main/MainController.swift b/iOS/Controller/MainController.swift similarity index 97% rename from iOS/Controller/Main/MainController.swift rename to iOS/Controller/MainController.swift index d0476a38..46e27e16 100644 --- a/iOS/Controller/Main/MainController.swift +++ b/iOS/Controller/MainController.swift @@ -7,6 +7,7 @@ // import UIKit +import MapKit import NotificationCenter import RealmSwift import SwiftyUserDefaults @@ -143,6 +144,17 @@ extension MainController: WebViewControllerDelegate { } } + func webViewDidTapOnGeoLocation(controller: WebViewController, url: URL) { +// guard let components = URLComponents(string: url.absoluteString) else {return} +// let parts = components.path.split(separator: ",") +// guard parts.count == 2, let latitude = CLLocationDegrees(parts[0]), let longitude = CLLocationDegrees(parts[1]) else {return} +// let coordinate = CLLocationCoordinate2D(latitude: latitude, longitude: longitude) +// +// let mapController = MapController(coordinate: coordinate, title: controller.currentTitle) +// let navigationController = UINavigationController(rootViewController: mapController) +// self.navigationController?.present(navigationController, animated: true) + } + func webViewDidFinishLoading(controller: WebViewController) { navigationBackButtonItem.button.isEnabled = controller.canGoBack navigationForwardButtonItem.button.isEnabled = controller.canGoForward diff --git a/iOS/Controller/MapController.swift b/iOS/Controller/MapController.swift new file mode 100644 index 00000000..679bec77 --- /dev/null +++ b/iOS/Controller/MapController.swift @@ -0,0 +1,45 @@ +// +// MapController.swift +// iOS +// +// Created by Chris Li on 5/29/18. +// Copyright © 2018 Chris Li. All rights reserved. +// + +import UIKit +import MapKit + +class MapController: UIViewController { + let coordinate: CLLocationCoordinate2D + private let mapView = MKMapView() + + init(coordinate: CLLocationCoordinate2D, title: String?) { + self.coordinate = coordinate + super.init(nibName: nil, bundle: nil) + self.title = title + } + + required init?(coder aDecoder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + override func loadView() { + view = mapView + } + + override func viewDidLoad() { + super.viewDidLoad() + navigationItem.leftBarButtonItem = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(dismissController)) + + let region = MKCoordinateRegion(center: self.coordinate, span: MKCoordinateSpan(latitudeDelta: 0.01, longitudeDelta: 0.01)) + mapView.setRegion(region, animated: false) + let annotation = MKPointAnnotation() + annotation.coordinate = self.coordinate + annotation.title = title + mapView.addAnnotation(annotation) + } + + @objc func dismissController() { + dismiss(animated: true, completion: nil) + } +} diff --git a/iOS/Controller/Setting/SettingController.swift b/iOS/Controller/Setting/SettingController.swift index fe3bb30a..d017da26 100644 --- a/iOS/Controller/Setting/SettingController.swift +++ b/iOS/Controller/Setting/SettingController.swift @@ -22,19 +22,9 @@ class SettingNavigationController: UINavigationController { class SettingController: UIViewController, UITableViewDataSource, UITableViewDelegate { let tableView = UITableView(frame: .zero, style: .grouped) - let titles: [SettingMenuItem: String] = { - var titles = [SettingMenuItem: String]() - titles[.fontSize] = NSLocalizedString("Font Size", comment: "Setting Item Title") - titles[.backup] = NSLocalizedString("Backup", comment: "Setting Item Title") - titles[.externalLink] = NSLocalizedString("External Link", comment: "Setting Item Title") - titles[.feedback] = NSLocalizedString("Email us your suggestions", comment: "Setting Item Title") - titles[.rateApp] = NSLocalizedString("Give Kiwix a rate", comment: "Setting Item Title") - titles[.about] = NSLocalizedString("About", comment: "Setting Item Title") - return titles - }() - private let items: [[SettingMenuItem]] = { - var items: [[SettingMenuItem]] = [ - [.fontSize, .backup, .externalLink], + private let items: [[MenuItem]] = { + var items: [[MenuItem]] = [ + [.fontSize, .backup, .search, .externalLink], [.rateApp], [.about] ] @@ -79,7 +69,7 @@ class SettingController: UIViewController, UITableViewDataSource, UITableViewDel func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) let item = items[indexPath.section][indexPath.row] - cell.textLabel?.text = titles[item] + cell.textLabel?.text = item.description cell.accessoryType = .disclosureIndicator return cell } @@ -105,21 +95,23 @@ class SettingController: UIViewController, UITableViewDataSource, UITableViewDel switch item { case .fontSize: let controller = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "SettingFontSizeViewController") - controller.title = titles[item] + controller.title = item.description navigationController?.pushViewController(controller, animated: true) case.backup: - navigationController?.pushViewController(SettingBackupController(title: titles[item]), animated: true) + navigationController?.pushViewController(SettingBackupController(title: item.description), animated: true) case .externalLink: - navigationController?.pushViewController(SettingExternalLinkController(title: titles[item]), animated: true) + navigationController?.pushViewController(SettingExternalLinkController(title: item.description), animated: true) + case .search: + navigationController?.pushViewController(SettingSearchController(title: item.description), animated: true) case .feedback: presentFeedbackEmailComposer() case .rateApp: - presentRateAppAlert(title: titles[item]!) + presentRateAppAlert(title: item.description) case .about: guard let path = Bundle.main.path(forResource: "About", ofType: "html") else {return} let url = URL(fileURLWithPath: path) let controller = SettingWebController(fileURL: url) - controller.title = titles[item] + controller.title = item.description navigationController?.pushViewController(controller, animated: true) } } @@ -139,6 +131,33 @@ class SettingController: UIViewController, UITableViewDataSource, UITableViewDel present(alert, animated: true) } + + // MARK: - Type Definition + + enum MenuItem: CustomStringConvertible { + case fontSize, backup, externalLink, search + case feedback, rateApp + case about + + var description: String { + switch self { + case .fontSize: + return NSLocalizedString("Font Size", comment: "Setting Item Title") + case .backup: + return NSLocalizedString("Backup", comment: "Setting Item Title") + case .externalLink: + return NSLocalizedString("External Link", comment: "Setting Item Title") + case .search: + return NSLocalizedString("Search", comment: "Setting Item Title") + case .feedback: + return NSLocalizedString("Email us your suggestions", comment: "Setting Item Title") + case .rateApp: + return NSLocalizedString("Give Kiwix a rate", comment: "Setting Item Title") + case .about: + return NSLocalizedString("About", comment: "Setting Item Title") + } + } + } } extension SettingController: MFMailComposeViewControllerDelegate { @@ -172,9 +191,3 @@ extension SettingController: MFMailComposeViewControllerDelegate { } } } - -enum SettingMenuItem { - case fontSize, backup, externalLink - case feedback, rateApp - case about -} diff --git a/iOS/Controller/Setting/SettingSearchController.swift b/iOS/Controller/Setting/SettingSearchController.swift new file mode 100644 index 00000000..292071b4 --- /dev/null +++ b/iOS/Controller/Setting/SettingSearchController.swift @@ -0,0 +1,68 @@ +// +// SettingSearchController.swift +// iOS +// +// Created by Chris Li on 6/12/18. +// Copyright © 2018 Chris Li. All rights reserved. +// + +import UIKit +import SwiftyUserDefaults + +class SettingSearchController: UIViewController, UITableViewDataSource, UITableViewDelegate { + let tableView = UITableView(frame: .zero, style: .grouped) + + init(title: String) { + super.init(nibName: nil, bundle: nil) + self.title = title + } + + required init?(coder aDecoder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + override func loadView() { + view = tableView + tableView.dataSource = self + tableView.delegate = self + tableView.register(UITableViewCell.self, forCellReuseIdentifier: "Cell") + } + + @objc func switchValueChanged(switchControl: UISwitch) { + Defaults[.searchResultExcludeSnippet] = !switchControl.isOn + } + + // MARK: - UITableViewDataSource & Delegate + + func numberOfSections(in tableView: UITableView) -> Int { + return 1 + } + + func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + return 1 + } + + func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) + cell.textLabel?.text = NSLocalizedString("Snippet", comment: "Setting: Search") + cell.selectionStyle = .none + let switchControl = UISwitch() + switchControl.addTarget(self, action: #selector(switchValueChanged(switchControl:)), for: .valueChanged) + switchControl.isOn = !Defaults[.searchResultExcludeSnippet] + cell.accessoryView = switchControl + return cell + } + + func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? { + return NSLocalizedString("Search Result", comment: "Setting: Search") + } + + func tableView(_ tableView: UITableView, titleForFooterInSection section: Int) -> String? { + return NSLocalizedString("If search performance issue is encountered, disable snippets to improve the situation.", comment: "Setting: Search") + } + +} + +extension DefaultsKeys { + static let searchResultExcludeSnippet = DefaultsKey("searchResultExcludeSnippet") +} diff --git a/iOS/Controller/Tab/LegacyWebController.swift b/iOS/Controller/Tab/LegacyWebController.swift index 3cf7831a..786d9756 100644 --- a/iOS/Controller/Tab/LegacyWebController.swift +++ b/iOS/Controller/Tab/LegacyWebController.swift @@ -125,6 +125,7 @@ class LegacyWebController: UIViewController, UIWebViewDelegate, WebViewControlle } return false } else if url.scheme == "geo" { + delegate?.webViewDidTapOnGeoLocation(controller: self, url: url) return false } else { return false diff --git a/iOS/Controller/Tab/WebKitWebController.swift b/iOS/Controller/Tab/WebKitWebController.swift index 9b503aab..e016263d 100644 --- a/iOS/Controller/Tab/WebKitWebController.swift +++ b/iOS/Controller/Tab/WebKitWebController.swift @@ -131,7 +131,7 @@ class WebKitWebController: UIViewController, WKUIDelegate, WKNavigationDelegate, } decisionHandler(.cancel) } else if url.scheme == "geo" { - // show map + delegate?.webViewDidTapOnGeoLocation(controller: self, url: url) decisionHandler(.cancel) } else { decisionHandler(.cancel) diff --git a/iOS/Controller/Tab/WebViewControllerProtocols.swift b/iOS/Controller/Tab/WebViewControllerProtocols.swift index bb86c655..ff70843e 100644 --- a/iOS/Controller/Tab/WebViewControllerProtocols.swift +++ b/iOS/Controller/Tab/WebViewControllerProtocols.swift @@ -27,6 +27,7 @@ protocol WebViewController { } protocol WebViewControllerDelegate: class { + func webViewDidTapOnGeoLocation(controller: WebViewController, url: URL) func webViewDidFinishLoading(controller: WebViewController) } diff --git a/iOS/Support/Info.plist b/iOS/Support/Info.plist index 66540e02..df64918a 100644 --- a/iOS/Support/Info.plist +++ b/iOS/Support/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType APPL CFBundleShortVersionString - 1.9.1 + 1.9.2 CFBundleURLTypes @@ -30,7 +30,7 @@ CFBundleVersion - 18 + 21 LSRequiresIPhoneOS NSAppTransportSecurity