mirror of
https://github.com/kiwix/kiwix-apple.git
synced 2025-09-27 13:59:04 -04:00
Commit
This commit is contained in:
parent
463810d2ef
commit
2a2009ec92
@ -22,6 +22,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
|
|||||||
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey : Any]? = nil) -> Bool {
|
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey : Any]? = nil) -> Bool {
|
||||||
URLProtocol.registerClass(KiwixURLProtocol.self)
|
URLProtocol.registerClass(KiwixURLProtocol.self)
|
||||||
_ = Network.shared
|
_ = Network.shared
|
||||||
|
_ = AppNotification.shared
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -147,7 +147,7 @@ class BookmarkCollectionController: CoreDataCollectionBaseController, UICollecti
|
|||||||
collectionView.deselectItem(at: indexPath, animated: true)
|
collectionView.deselectItem(at: indexPath, animated: true)
|
||||||
let article = fetchedResultController.object(at: indexPath)
|
let article = fetchedResultController.object(at: indexPath)
|
||||||
guard let url = article.url else {return}
|
guard let url = article.url else {return}
|
||||||
GlobalQueue.shared.add(articleLoadOperation: ArticleLoadOperation(url: url))
|
GlobalQueue.shared.add(articleLoad: ArticleLoadOperation(url: url))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,6 +23,6 @@ class LibraryTabController: UITabBarController {
|
|||||||
|
|
||||||
override func viewDidAppear(_ animated: Bool) {
|
override func viewDidAppear(_ animated: Bool) {
|
||||||
super.viewDidAppear(animated)
|
super.viewDidAppear(animated)
|
||||||
AppNotification.shared.register()
|
AppNotification.shared.requestAuth()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -98,8 +98,7 @@ class SearchResultController: SearchBaseTableController, UITableViewDataSource,
|
|||||||
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
|
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
|
||||||
tableView.deselectRow(at: indexPath, animated: true)
|
tableView.deselectRow(at: indexPath, animated: true)
|
||||||
let result = searchResults[indexPath.row]
|
let result = searchResults[indexPath.row]
|
||||||
let operation = ArticleLoadOperation(bookID: result.bookID, articleTitle: result.title)
|
GlobalQueue.shared.add(articleLoad: ArticleLoadOperation(bookID: result.bookID, articleTitle: result.title))
|
||||||
GlobalQueue.shared.add(articleLoadOperation: operation)
|
|
||||||
Preference.RecentSearch.add(term: searchText)
|
Preference.RecentSearch.add(term: searchText)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -100,8 +100,7 @@ class SearchScopeAndHistoryController: SearchBaseTableController, UITableViewDel
|
|||||||
tableView.deselectRow(at: indexPath, animated: true)
|
tableView.deselectRow(at: indexPath, animated: true)
|
||||||
|
|
||||||
let book = fetchedResultController.object(at: indexPath)
|
let book = fetchedResultController.object(at: indexPath)
|
||||||
let operation = ArticleLoadOperation(bookID: book.id)
|
GlobalQueue.shared.add(articleLoad: ArticleLoadOperation(bookID: book.id))
|
||||||
GlobalQueue.shared.add(articleLoadOperation: operation)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - DZNEmptyDataSet
|
// MARK: - DZNEmptyDataSet
|
||||||
|
@ -10,12 +10,25 @@ import UserNotifications
|
|||||||
|
|
||||||
class AppNotification: NSObject, UNUserNotificationCenterDelegate {
|
class AppNotification: NSObject, UNUserNotificationCenterDelegate {
|
||||||
static let shared = AppNotification()
|
static let shared = AppNotification()
|
||||||
private override init() {}
|
private override init() {
|
||||||
|
super.init()
|
||||||
|
UNUserNotificationCenter.current().delegate = self
|
||||||
|
registerActions()
|
||||||
|
}
|
||||||
|
|
||||||
func register() {
|
let downloadFinishIdentifier = "org.kiwix.download-finished"
|
||||||
|
|
||||||
|
func requestAuth() {
|
||||||
UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound]) { _ in }
|
UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound]) { _ in }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func registerActions() {
|
||||||
|
let downloadFinish = UNNotificationCategory(identifier: downloadFinishIdentifier, actions: [
|
||||||
|
UNNotificationAction(identifier: "loadMain", title: "Open Main Page", options: .foreground)
|
||||||
|
], intentIdentifiers: [])
|
||||||
|
UNUserNotificationCenter.current().setNotificationCategories([downloadFinish])
|
||||||
|
}
|
||||||
|
|
||||||
func downloadFinished(bookID: String, bookTitle: String, fileSizeDescription: String) {
|
func downloadFinished(bookID: String, bookTitle: String, fileSizeDescription: String) {
|
||||||
UNUserNotificationCenter.current().getNotificationSettings(completionHandler: { (settings) in
|
UNUserNotificationCenter.current().getNotificationSettings(completionHandler: { (settings) in
|
||||||
guard settings.alertSetting == .enabled else {return}
|
guard settings.alertSetting == .enabled else {return}
|
||||||
@ -23,7 +36,8 @@ class AppNotification: NSObject, UNUserNotificationCenterDelegate {
|
|||||||
content.categoryIdentifier = "org.kiwix.download-finished"
|
content.categoryIdentifier = "org.kiwix.download-finished"
|
||||||
content.title = bookTitle + " is downloaded!"
|
content.title = bookTitle + " is downloaded!"
|
||||||
content.body = fileSizeDescription + " has been transferred."
|
content.body = fileSizeDescription + " has been transferred."
|
||||||
let request = UNNotificationRequest(identifier: "org.kiwix.download-finished." + bookID, content: content, trigger: nil)
|
content.categoryIdentifier = self.downloadFinishIdentifier
|
||||||
|
let request = UNNotificationRequest(identifier: [self.downloadFinishIdentifier, bookID].joined(separator: "."), content: content, trigger: nil)
|
||||||
UNUserNotificationCenter.current().add(request, withCompletionHandler: nil)
|
UNUserNotificationCenter.current().add(request, withCompletionHandler: nil)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -34,5 +48,13 @@ class AppNotification: NSObject, UNUserNotificationCenterDelegate {
|
|||||||
completionHandler([.alert, .sound])
|
completionHandler([.alert, .sound])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
|
||||||
|
let requestIdentifier = response.notification.request.identifier
|
||||||
|
if requestIdentifier.hasPrefix(downloadFinishIdentifier) {
|
||||||
|
let bookID = requestIdentifier.replacingOccurrences(of: downloadFinishIdentifier + ".", with: "")
|
||||||
|
if response.actionIdentifier == UNNotificationDefaultActionIdentifier || response.actionIdentifier == "loadMain" {
|
||||||
|
GlobalQueue.shared.add(articleLoad: ArticleLoadOperation(bookID: bookID))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,4 +2,38 @@
|
|||||||
<Bucket
|
<Bucket
|
||||||
type = "0"
|
type = "0"
|
||||||
version = "2.0">
|
version = "2.0">
|
||||||
|
<Breakpoints>
|
||||||
|
<BreakpointProxy
|
||||||
|
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
|
||||||
|
<BreakpointContent
|
||||||
|
shouldBeEnabled = "Yes"
|
||||||
|
ignoreCount = "0"
|
||||||
|
continueAfterRunningActions = "No"
|
||||||
|
filePath = "Kiwix-iOS/Notification.swift"
|
||||||
|
timestampString = "507657369.862229"
|
||||||
|
startingColumnNumber = "9223372036854775807"
|
||||||
|
endingColumnNumber = "9223372036854775807"
|
||||||
|
startingLineNumber = "56"
|
||||||
|
endingLineNumber = "56"
|
||||||
|
landmarkName = "userNotificationCenter(_:didReceive:withCompletionHandler:)"
|
||||||
|
landmarkType = "7">
|
||||||
|
</BreakpointContent>
|
||||||
|
</BreakpointProxy>
|
||||||
|
<BreakpointProxy
|
||||||
|
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
|
||||||
|
<BreakpointContent
|
||||||
|
shouldBeEnabled = "Yes"
|
||||||
|
ignoreCount = "0"
|
||||||
|
continueAfterRunningActions = "No"
|
||||||
|
filePath = "Kiwix/Operations/ArticleOperation.swift"
|
||||||
|
timestampString = "507657555.465639"
|
||||||
|
startingColumnNumber = "9223372036854775807"
|
||||||
|
endingColumnNumber = "9223372036854775807"
|
||||||
|
startingLineNumber = "73"
|
||||||
|
endingLineNumber = "73"
|
||||||
|
landmarkName = "execute()"
|
||||||
|
landmarkType = "7">
|
||||||
|
</BreakpointContent>
|
||||||
|
</BreakpointProxy>
|
||||||
|
</Breakpoints>
|
||||||
</Bucket>
|
</Bucket>
|
||||||
|
@ -78,7 +78,10 @@ class ArticleLoadOperation: Procedure {
|
|||||||
|
|
||||||
OperationQueue.main.addOperation {
|
OperationQueue.main.addOperation {
|
||||||
_ = main.searchBar.resignFirstResponder()
|
_ = main.searchBar.resignFirstResponder()
|
||||||
main.presentedViewController?.dismiss(animated: self.animated, completion: nil)
|
|
||||||
|
main.presentedViewController?.dismiss(animated: true, completion: {
|
||||||
|
main.presentedViewController?.dismiss(animated: true, completion: nil)
|
||||||
|
})
|
||||||
main.hideWelcome()
|
main.hideWelcome()
|
||||||
|
|
||||||
if main.traitCollection.horizontalSizeClass == .compact {
|
if main.traitCollection.horizontalSizeClass == .compact {
|
||||||
|
@ -32,17 +32,17 @@ class GlobalQueue: ProcedureQueue {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private weak var articleLoadOperation: ArticleLoadOperation?
|
private weak var articleLoadOperation: ArticleLoadOperation?
|
||||||
func add(articleLoadOperation: ArticleLoadOperation) {
|
func add(articleLoad operation: ArticleLoadOperation) {
|
||||||
if let scanOperation = scanOperation {
|
if let scanOperation = scanOperation {
|
||||||
articleLoadOperation.addDependency(scanOperation)
|
operation.addDependency(scanOperation)
|
||||||
}
|
}
|
||||||
|
|
||||||
if let articleLoadOperation = self.articleLoadOperation {
|
if let articleLoadOperation = self.articleLoadOperation {
|
||||||
articleLoadOperation.addDependency(articleLoadOperation)
|
articleLoadOperation.addDependency(articleLoadOperation)
|
||||||
}
|
}
|
||||||
|
|
||||||
add(operation: articleLoadOperation)
|
add(operation: operation)
|
||||||
self.articleLoadOperation = articleLoadOperation
|
self.articleLoadOperation = operation
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -106,7 +106,7 @@ extension AlertProcedure {
|
|||||||
} else if book.state == .local {
|
} else if book.state == .local {
|
||||||
alert.add(actionWithTitle: "set back to cloud", style: .default) { _ in
|
alert.add(actionWithTitle: "set back to cloud", style: .default) { _ in
|
||||||
let context = AppDelegate.persistentContainer.viewContext
|
let context = AppDelegate.persistentContainer.viewContext
|
||||||
context.perform({
|
context.perform({
|
||||||
book.state = .cloud
|
book.state = .cloud
|
||||||
})
|
})
|
||||||
alert.finish()
|
alert.finish()
|
||||||
@ -122,31 +122,12 @@ extension AlertProcedure {
|
|||||||
|
|
||||||
extension AlertProcedure {
|
extension AlertProcedure {
|
||||||
class Library {
|
class Library {
|
||||||
static func refreshError(context: UIViewController) -> AlertProcedure {
|
static func refreshError(context: UIViewController, message: String) -> AlertProcedure {
|
||||||
assert(Thread.isMainThread, "Library refresh error alert has to be initialized in the main thread")
|
assert(Thread.isMainThread, "Library refresh error alert has to be initialized in the main thread")
|
||||||
let alert = AlertProcedure(presentAlertFrom: context, withPreferredStyle: .actionSheet, waitForDismissal: true)
|
let alert = AlertProcedure(presentAlertFrom: context, withPreferredStyle: .actionSheet, waitForDismissal: true)
|
||||||
alert.title = "There was an error"
|
alert.title = Localized.Library.RefreshError.title
|
||||||
if book.state == .cloud {
|
alert.message = message
|
||||||
alert.add(actionWithTitle: Localized.Library.download, style: .default) { _ in
|
alert.add(actionWithTitle: Localized.Common.ok, style: .cancel) { _ in alert.finish() }
|
||||||
Network.shared.start(bookID: book.id)
|
|
||||||
alert.finish()
|
|
||||||
}
|
|
||||||
alert.add(actionWithTitle: Localized.Library.copyURL, style: .default) { _ in
|
|
||||||
guard let url = book.url else {return}
|
|
||||||
UIPasteboard.general.string = url.absoluteString
|
|
||||||
alert.finish()
|
|
||||||
}
|
|
||||||
} else if book.state == .local {
|
|
||||||
alert.add(actionWithTitle: "set back to cloud", style: .default) { _ in
|
|
||||||
let context = AppDelegate.persistentContainer.viewContext
|
|
||||||
context.perform({
|
|
||||||
book.state = .cloud
|
|
||||||
})
|
|
||||||
alert.finish()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
alert.add(actionWithTitle: Localized.Common.cancel, style: .cancel) { _ in alert.finish() }
|
|
||||||
return alert
|
return alert
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -94,6 +94,11 @@ class Localized {
|
|||||||
static let hiding = NSLocalizedString("HIDING", comment: "Library, Language Filter")
|
static let hiding = NSLocalizedString("HIDING", comment: "Library, Language Filter")
|
||||||
static let original = NSLocalizedString("Original", comment: "Library, Language Filter")
|
static let original = NSLocalizedString("Original", comment: "Library, Language Filter")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class RefreshError {
|
||||||
|
static let title = NSLocalizedString("Unable to refresh library", comment: "Library, Refresh Error")
|
||||||
|
static let subtitle = NSLocalizedString("Please try again later", comment: "Library, Refresh Error")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - Setting
|
// MARK: - Setting
|
||||||
|
Loading…
x
Reference in New Issue
Block a user