mirror of
https://github.com/kiwix/kiwix-apple.git
synced 2025-09-11 05:06:30 -04:00
207 lines
7.7 KiB
Swift
207 lines
7.7 KiB
Swift
// This file is part of Kiwix for iOS & macOS.
|
|
//
|
|
// Kiwix is free software; you can redistribute it and/or modify it
|
|
// under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation; either version 3 of the License, or
|
|
// any later version.
|
|
//
|
|
// Kiwix is distributed in the hope that it will be useful, but
|
|
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
// General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with Kiwix; If not, see https://www.gnu.org/licenses/.
|
|
|
|
import SwiftUI
|
|
import UserNotifications
|
|
import Combine
|
|
import Defaults
|
|
import CoreKiwix
|
|
|
|
#if os(macOS)
|
|
final class AppDelegate: NSObject, NSApplicationDelegate {
|
|
func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool {
|
|
true
|
|
}
|
|
}
|
|
|
|
enum SettingsTab: Int {
|
|
case reading
|
|
case catalog
|
|
case hotspot
|
|
case about
|
|
}
|
|
|
|
@main
|
|
struct Kiwix: App {
|
|
@NSApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
|
|
@Environment(\.openWindow) var openWindow
|
|
@StateObject private var libraryRefreshViewModel = LibraryViewModel()
|
|
private let notificationCenterDelegate = NotificationCenterDelegate()
|
|
private var amountSelected = PassthroughSubject<SelectedAmount?, Never>()
|
|
@State private var selectedAmount: SelectedAmount?
|
|
@StateObject var formReset = FormReset()
|
|
@FocusState private var isSearchFocused: Bool
|
|
@FocusedValue(\.browserURL) var browserURL
|
|
@StateObject private var colorSchemeStore = UserColorSchemeStore()
|
|
@State private var settingsTab: Int = SettingsTab.reading.rawValue
|
|
|
|
init() {
|
|
UNUserNotificationCenter.current().delegate = notificationCenterDelegate
|
|
if FeatureFlags.hasLibrary {
|
|
LibraryViewModel().start(isUserInitiated: false)
|
|
}
|
|
}
|
|
|
|
private func selectHotspotTab() {
|
|
settingsTab = SettingsTab.hotspot.rawValue
|
|
}
|
|
|
|
var body: some Scene {
|
|
WindowGroup {
|
|
let root = RootView(isSearchFocused: $isSearchFocused)
|
|
.environment(\.managedObjectContext, Database.shared.viewContext)
|
|
.environmentObject(libraryRefreshViewModel)
|
|
.task { colorSchemeStore.update() }
|
|
if #available(macOS 14, *) {
|
|
root.modifier(OpeningSettingsModifier(updateTabSelection: selectHotspotTab))
|
|
} else {
|
|
root.modifier(OpeningSettingsModifier_macOS_13(updateTabSelection: selectHotspotTab))
|
|
}
|
|
}.commands {
|
|
SidebarCommands()
|
|
CommandGroup(replacing: .importExport) {
|
|
OpenFileButton(context: .command) { Text(LocalString.app_macos_commands_open_file) }
|
|
}
|
|
CommandGroup(replacing: .newItem) {
|
|
Button(LocalString.app_macos_commands_new) {
|
|
guard let currentWindow = NSApp.keyWindow,
|
|
let controller = currentWindow.windowController else { return }
|
|
controller.newWindowForTab(nil)
|
|
guard let newWindow = NSApp.keyWindow, currentWindow != newWindow else { return }
|
|
currentWindow.addTabbedWindow(newWindow, ordered: .above)
|
|
}.keyboardShortcut("t")
|
|
Divider()
|
|
}
|
|
CommandGroup(after: .toolbar) {
|
|
NavigationCommands(goBack: {
|
|
NotificationCenter.default.post(name: .goBack, object: nil)
|
|
}, goForward: {
|
|
NotificationCenter.default.post(name: .goForward, object: nil)
|
|
})
|
|
Divider()
|
|
PageZoomCommands()
|
|
Divider()
|
|
SidebarNavigationCommands()
|
|
Divider()
|
|
}
|
|
CommandGroup(after: .pasteboard) {
|
|
Button(LocalString.library_zim_file_context_copy_url) {
|
|
if let browserURL {
|
|
CopyPaste.copyToPasteBoard(url: browserURL)
|
|
}
|
|
}
|
|
.disabled(browserURL == nil)
|
|
.keyboardShortcut("c", modifiers: [.command, .shift])
|
|
|
|
}
|
|
CommandGroup(after: .textEditing) {
|
|
Button(LocalString.common_search) {
|
|
isSearchFocused = true
|
|
}
|
|
.keyboardShortcut("f", modifiers: [.command])
|
|
}
|
|
CommandGroup(replacing: .help) {}
|
|
}
|
|
|
|
Settings {
|
|
TabView(selection: $settingsTab) {
|
|
ReadingSettings()
|
|
.environmentObject(colorSchemeStore)
|
|
.tag(SettingsTab.reading.rawValue)
|
|
if FeatureFlags.hasLibrary {
|
|
LibrarySettings()
|
|
.environmentObject(libraryRefreshViewModel)
|
|
.tag(SettingsTab.catalog.rawValue)
|
|
HotspotSettings()
|
|
.tag(SettingsTab.hotspot.rawValue)
|
|
}
|
|
About()
|
|
.tag(SettingsTab.about.rawValue)
|
|
}
|
|
.frame(width: 550, height: 400)
|
|
}
|
|
.handlesExternalEvents(matching: [])
|
|
|
|
Window(LocalString.payment_donate_title, id: "donation") {
|
|
Group {
|
|
if let selectedAmount {
|
|
PaymentSummary(selectedAmount: selectedAmount, onComplete: {
|
|
closeDonation()
|
|
switch Payment.showResult() {
|
|
case .none: break
|
|
case .thankYou:
|
|
openWindow(id: "donation-thank-you")
|
|
case .error:
|
|
openWindow(id: "donation-error")
|
|
}
|
|
})
|
|
} else {
|
|
PaymentForm(amountSelected: amountSelected)
|
|
.frame(width: 320, height: 320)
|
|
}
|
|
}
|
|
.onReceive(amountSelected) { amount in
|
|
selectedAmount = amount
|
|
}
|
|
.onReceive(NotificationCenter.default.publisher(for: NSWindow.willCloseNotification)) { notification in
|
|
if let window = notification.object as? NSWindow,
|
|
window.identifier?.rawValue == "donation" {
|
|
formReset.reset()
|
|
selectedAmount = nil
|
|
}
|
|
}
|
|
.environmentObject(formReset)
|
|
}
|
|
.windowResizability(.contentMinSize)
|
|
.windowStyle(.titleBar)
|
|
.commandsRemoved()
|
|
.defaultSize(width: 320, height: 400)
|
|
.restorationBehaviourDisabled()
|
|
.handlesExternalEvents(matching: [])
|
|
|
|
Window("", id: "donation-thank-you") {
|
|
PaymentResultPopUp(state: .thankYou)
|
|
.padding()
|
|
}
|
|
.windowResizability(.contentMinSize)
|
|
.commandsRemoved()
|
|
.defaultSize(width: 320, height: 198)
|
|
.restorationBehaviourDisabled()
|
|
.handlesExternalEvents(matching: [])
|
|
|
|
Window("", id: "donation-error") {
|
|
PaymentResultPopUp(state: .error)
|
|
.padding()
|
|
}
|
|
.windowResizability(.contentMinSize)
|
|
.commandsRemoved()
|
|
.defaultSize(width: 320, height: 198)
|
|
.restorationBehaviourDisabled()
|
|
.handlesExternalEvents(matching: [])
|
|
}
|
|
|
|
private func closeDonation() {
|
|
// after upgrading to macOS 14, use:
|
|
// @Environment(\.dismissWindow) var dismissWindow
|
|
// and call:
|
|
// dismissWindow(id: "donation")
|
|
NSApplication.shared.windows.first { window in
|
|
window.identifier?.rawValue == "donation"
|
|
}?.close()
|
|
}
|
|
}
|
|
|
|
#endif
|