mirror of
https://github.com/kiwix/kiwix-apple.git
synced 2025-08-03 20:47:22 -04:00
Navigate to downloads via deeplink
This commit is contained in:
parent
d057f95ec0
commit
a98cc5cace
@ -73,7 +73,14 @@ struct Kiwix: App {
|
|||||||
if url.isFileURL {
|
if url.isFileURL {
|
||||||
NotificationCenter.openFiles([url], context: .file)
|
NotificationCenter.openFiles([url], context: .file)
|
||||||
} else if url.isZIMURL {
|
} else if url.isZIMURL {
|
||||||
NotificationCenter.openURL(url)
|
switch url {
|
||||||
|
case DownloadActivityAttributes.downloadsDeepLink:
|
||||||
|
if FeatureFlags.hasLibrary {
|
||||||
|
navigation.showDownloads.send()
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
NotificationCenter.openURL(url)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.task {
|
.task {
|
||||||
|
@ -137,11 +137,15 @@ private struct CompactView: View {
|
|||||||
@EnvironmentObject private var library: LibraryViewModel
|
@EnvironmentObject private var library: LibraryViewModel
|
||||||
@State private var presentedSheet: PresentedSheet?
|
@State private var presentedSheet: PresentedSheet?
|
||||||
|
|
||||||
private enum PresentedSheet: String, Identifiable {
|
private enum PresentedSheet: Identifiable {
|
||||||
case library
|
case library(downloads: Bool)
|
||||||
case settings
|
case settings
|
||||||
var id: String {
|
var id: String {
|
||||||
rawValue
|
switch self {
|
||||||
|
case .library(true): return "library-downloads"
|
||||||
|
case .library(false): return "library"
|
||||||
|
case .settings: return "settings"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -161,7 +165,7 @@ private struct CompactView: View {
|
|||||||
}
|
}
|
||||||
Content(tabID: tabID, showLibrary: {
|
Content(tabID: tabID, showLibrary: {
|
||||||
if presentedSheet == nil {
|
if presentedSheet == nil {
|
||||||
presentedSheet = .library
|
presentedSheet = .library(downloads: false)
|
||||||
} else {
|
} else {
|
||||||
// there's a sheet already presented by the user
|
// there's a sheet already presented by the user
|
||||||
// do nothing
|
// do nothing
|
||||||
@ -183,7 +187,7 @@ private struct CompactView: View {
|
|||||||
Spacer()
|
Spacer()
|
||||||
if FeatureFlags.hasLibrary {
|
if FeatureFlags.hasLibrary {
|
||||||
Button {
|
Button {
|
||||||
presentedSheet = .library
|
presentedSheet = .library(downloads: false)
|
||||||
} label: {
|
} label: {
|
||||||
Label(LocalString.common_tab_menu_library, systemImage: "folder")
|
Label(LocalString.common_tab_menu_library, systemImage: "folder")
|
||||||
}
|
}
|
||||||
@ -200,8 +204,10 @@ private struct CompactView: View {
|
|||||||
.environmentObject(browser)
|
.environmentObject(browser)
|
||||||
.sheet(item: $presentedSheet) { presentedSheet in
|
.sheet(item: $presentedSheet) { presentedSheet in
|
||||||
switch presentedSheet {
|
switch presentedSheet {
|
||||||
case .library:
|
case .library(downloads: false):
|
||||||
Library(dismiss: dismiss)
|
Library(dismiss: dismiss)
|
||||||
|
case .library(downloads: true):
|
||||||
|
Library(dismiss: dismiss, tabItem: .downloads)
|
||||||
case .settings:
|
case .settings:
|
||||||
NavigationStack {
|
NavigationStack {
|
||||||
Settings().toolbar {
|
Settings().toolbar {
|
||||||
@ -216,6 +222,16 @@ private struct CompactView: View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.onReceive(navigation.showDownloads) { _ in
|
||||||
|
switch presentedSheet {
|
||||||
|
case .library:
|
||||||
|
// switching to the downloads tab
|
||||||
|
// is done within Library
|
||||||
|
break
|
||||||
|
case .settings, nil:
|
||||||
|
presentedSheet = .library(downloads: true)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -21,6 +21,7 @@ import UIKit
|
|||||||
final class SplitViewController: UISplitViewController {
|
final class SplitViewController: UISplitViewController {
|
||||||
let navigationViewModel: NavigationViewModel
|
let navigationViewModel: NavigationViewModel
|
||||||
private var navigationItemObserver: AnyCancellable?
|
private var navigationItemObserver: AnyCancellable?
|
||||||
|
private var showDownloadsObserver: AnyCancellable?
|
||||||
private var openURLObserver: NSObjectProtocol?
|
private var openURLObserver: NSObjectProtocol?
|
||||||
private var hasZimFiles: Bool
|
private var hasZimFiles: Bool
|
||||||
|
|
||||||
@ -74,6 +75,16 @@ final class SplitViewController: UISplitViewController {
|
|||||||
self?.preferredDisplayMode = .automatic
|
self?.preferredDisplayMode = .automatic
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
showDownloadsObserver = navigationViewModel
|
||||||
|
.showDownloads
|
||||||
|
.receive(on: DispatchQueue.main)
|
||||||
|
.sink(receiveValue: { [weak self] _ in
|
||||||
|
if self?.traitCollection.horizontalSizeClass == .regular {
|
||||||
|
self?.navigationViewModel.currentItem = .downloads
|
||||||
|
}
|
||||||
|
// the compact one is triggered in CompactViewController
|
||||||
|
})
|
||||||
|
|
||||||
openURLObserver = NotificationCenter.default.addObserver(
|
openURLObserver = NotificationCenter.default.addObserver(
|
||||||
forName: .openURL, object: nil, queue: nil
|
forName: .openURL, object: nil, queue: nil
|
||||||
) { [weak self] notification in
|
) { [weak self] notification in
|
||||||
|
@ -18,6 +18,8 @@ import ActivityKit
|
|||||||
|
|
||||||
public struct DownloadActivityAttributes: ActivityAttributes {
|
public struct DownloadActivityAttributes: ActivityAttributes {
|
||||||
|
|
||||||
|
static let downloadsDeepLink = URL(string: "zim://downloads")
|
||||||
|
|
||||||
private static func progressFor(items: [DownloadItem]) -> Progress {
|
private static func progressFor(items: [DownloadItem]) -> Progress {
|
||||||
let sumOfTotal = items.reduce(0) { result, item in
|
let sumOfTotal = items.reduce(0) { result, item in
|
||||||
result + item.total
|
result + item.total
|
||||||
|
@ -15,12 +15,15 @@
|
|||||||
|
|
||||||
import CoreData
|
import CoreData
|
||||||
import WebKit
|
import WebKit
|
||||||
|
import Combine
|
||||||
|
|
||||||
@MainActor
|
@MainActor
|
||||||
final class NavigationViewModel: ObservableObject {
|
final class NavigationViewModel: ObservableObject {
|
||||||
let uuid = UUID()
|
let uuid = UUID()
|
||||||
// remained optional due to focusedSceneValue conformance
|
// remained optional due to focusedSceneValue conformance
|
||||||
@Published var currentItem: NavigationItem? = .loading
|
@Published var currentItem: NavigationItem? = .loading
|
||||||
|
private(set) var showDownloads = PassthroughSubject<Void, Never>()
|
||||||
|
|
||||||
#if os(macOS)
|
#if os(macOS)
|
||||||
var isTerminating: Bool = false
|
var isTerminating: Bool = false
|
||||||
|
|
||||||
|
@ -21,16 +21,19 @@ import Defaults
|
|||||||
/// Tabbed library view on iOS & iPadOS
|
/// Tabbed library view on iOS & iPadOS
|
||||||
struct Library: View {
|
struct Library: View {
|
||||||
@EnvironmentObject private var viewModel: LibraryViewModel
|
@EnvironmentObject private var viewModel: LibraryViewModel
|
||||||
@SceneStorage("LibraryTabItem") private var tabItem: LibraryTabItem = .categories
|
@EnvironmentObject private var navigation: NavigationViewModel
|
||||||
|
@State private var tabItem: LibraryTabItem
|
||||||
@Default(.hasSeenCategories) private var hasSeenCategories
|
@Default(.hasSeenCategories) private var hasSeenCategories
|
||||||
private let categories: [Category]
|
private let categories: [Category]
|
||||||
let dismiss: (() -> Void)?
|
let dismiss: (() -> Void)?
|
||||||
|
|
||||||
init(
|
init(
|
||||||
dismiss: (() -> Void)?,
|
dismiss: (() -> Void)?,
|
||||||
|
tabItem: LibraryTabItem = .categories,
|
||||||
categories: [Category] = CategoriesToLanguages().allCategories()
|
categories: [Category] = CategoriesToLanguages().allCategories()
|
||||||
) {
|
) {
|
||||||
self.dismiss = dismiss
|
self.dismiss = dismiss
|
||||||
|
self.tabItem = tabItem
|
||||||
self.categories = categories
|
self.categories = categories
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -70,6 +73,8 @@ struct Library: View {
|
|||||||
viewModel.start(isUserInitiated: false)
|
viewModel.start(isUserInitiated: false)
|
||||||
}.onDisappear {
|
}.onDisappear {
|
||||||
hasSeenCategories = true
|
hasSeenCategories = true
|
||||||
|
}.onReceive(navigation.showDownloads) { _ in
|
||||||
|
tabItem = .downloads
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -66,7 +66,7 @@ struct DownloadsLiveActivity: Widget {
|
|||||||
.progressViewStyle(CircularProgressGaugeStyle(lineWidth: 5.7))
|
.progressViewStyle(CircularProgressGaugeStyle(lineWidth: 5.7))
|
||||||
.frame(width: 24, height: 24)
|
.frame(width: 24, height: 24)
|
||||||
}
|
}
|
||||||
.widgetURL(URL(string: "zim://downloads"))
|
.widgetURL(DownloadActivityAttributes.downloadsDeepLink)
|
||||||
.keylineTint(Color.red)
|
.keylineTint(Color.red)
|
||||||
}.containerBackgroundRemovable()
|
}.containerBackgroundRemovable()
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user