Skip to content

Commit

Permalink
Merge pull request #536 from BPerlakiH/fix/518-open-link-in-new-tab-o…
Browse files Browse the repository at this point in the history
…n-macos

Fix opening new tabs on macos(#518)
  • Loading branch information
BPerlakiH authored Nov 21, 2023
2 parents 2e8c793 + d5ebdec commit accc2d2
Show file tree
Hide file tree
Showing 12 changed files with 355 additions and 174 deletions.
44 changes: 39 additions & 5 deletions App/App_macOS.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,15 @@

import SwiftUI
import UserNotifications
import Combine
import Defaults

#if os(macOS)
@main
struct Kiwix: App {
@StateObject private var libraryRefreshViewModel = LibraryViewModel()

private let notificationCenterDelegate = NotificationCenterDelegate()

init() {
UNUserNotificationCenter.current().delegate = notificationCenterDelegate
LibraryOperations.reopen()
Expand Down Expand Up @@ -63,7 +64,7 @@ struct Kiwix: App {
.environmentObject(libraryRefreshViewModel)
}
}

private class NotificationCenterDelegate: NSObject, UNUserNotificationCenterDelegate {
/// Handling file download complete notification
func userNotificationCenter(_ center: UNUserNotificationCenter,
Expand All @@ -86,7 +87,8 @@ struct RootView: View {
private let primaryItems: [NavigationItem] = [.reading, .bookmarks]
private let libraryItems: [NavigationItem] = [.opened, .categories, .downloads, .new]
private let openURL = NotificationCenter.default.publisher(for: .openURL)

private let appTerminates = NotificationCenter.default.publisher(for: NSApplication.willTerminateNotification)

var body: some View {
NavigationView {
List(selection: $navigation.currentItem) {
Expand All @@ -111,6 +113,12 @@ struct RootView: View {
switch navigation.currentItem {
case .reading:
BrowserTab().environmentObject(browser)
.withHostingWindow { window in
if let windowNumber = window?.windowNumber {
browser.restoreByWindowNumber(windowNumber: windowNumber,
urlToTabIdConverter: navigation.tabIDFor(url:))
}
}
case .bookmarks:
Bookmarks()
case .opened:
Expand Down Expand Up @@ -139,9 +147,35 @@ struct RootView: View {
}
.onReceive(openURL) { notification in
guard controlActiveState == .key, let url = notification.userInfo?["url"] as? URL else { return }
browser.load(url: url)
navigation.currentItem = .reading
browser.load(url: url)
}
.onReceive(appTerminates) { _ in
browser.persistAllTabIdsFromWindows()
}
}
}

// MARK: helpers to capture the window

extension View {
func withHostingWindow(_ callback: @escaping (NSWindow?) -> Void) -> some View {
self.background(HostingWindowFinder(callback: callback))
}
}

struct HostingWindowFinder: NSViewRepresentable {
typealias NSViewType = NSView
var callback: (NSWindow?) -> Void
func makeNSView(context: Context) -> NSView {
let view = NSView()
DispatchQueue.main.async { [weak view] in
self.callback(view?.window)
}
return view
}

func updateNSView(_ nsView: NSView, context: Context) {}
}

#endif
2 changes: 1 addition & 1 deletion App/CompactViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ private struct Content: View {
.focusedSceneValue(\.browserViewModel, browser)
.focusedSceneValue(\.canGoBack, browser.canGoBack)
.focusedSceneValue(\.canGoForward, browser.canGoForward)
.modifier(ExternalLinkHandler())
.modifier(ExternalLinkHandler(externalURL: $browser.externalURL))
.onAppear {
browser.updateLastOpened()
}
Expand Down
2 changes: 2 additions & 0 deletions Kiwix.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@
97E88F4D2AE407350037F0E5 /* CoreKiwix.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 97E88F4C2AE407320037F0E5 /* CoreKiwix.xcframework */; };
97F3333028AFC1A2007FF53C /* SearchResults.swift in Sources */ = {isa = PBXBuildFile; fileRef = 97F3332E28AFC1A2007FF53C /* SearchResults.swift */; };
97FB4ECE28B4E221003FB524 /* SwiftUIBackports in Frameworks */ = {isa = PBXBuildFile; productRef = 97FB4ECD28B4E221003FB524 /* SwiftUIBackports */; };
983ED7192B08AFE700409078 /* Kiwix-Bridging-Header.h in Sources */ = {isa = PBXBuildFile; fileRef = 9779A5D02456796A00F6F6FF /* Kiwix-Bridging-Header.h */; platformFilter = ios; };
/* End PBXBuildFile section */

/* Begin PBXContainerItemProxy section */
Expand Down Expand Up @@ -752,6 +753,7 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
983ED7192B08AFE700409078 /* Kiwix-Bridging-Header.h in Sources */,
972DE4BB2814A5A4004FD9B9 /* Errors.swift in Sources */,
9790CA5A28A05EBB00D39FC6 /* ZimFilesCategories.swift in Sources */,
97486D08284A42B90096E4DD /* SearchResultRow.swift in Sources */,
Expand Down
7 changes: 6 additions & 1 deletion Model/Utilities/URL.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
// Created by Chris Li on 11/6/21.
// Copyright © 2021 Chris Li. All rights reserved.
//
import Foundation

extension URL {
init?(zimFileID: String, contentPath: String) {
Expand All @@ -16,6 +17,10 @@ extension URL {
var isKiwixURL: Bool {
return scheme?.caseInsensitiveCompare("kiwix") == .orderedSame
}


var isExternal: Bool {
["http", "https"].contains(scheme)
}

static let documentDirectory = try! FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: false)
}
39 changes: 10 additions & 29 deletions Model/Utilities/WebKitHandler.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,13 @@
import os
import WebKit

/// Skipping handling for HTTP 206 Partial Content
/// For video playback, WebKit makes a large amount of requests with small byte range (e.g. 8 bytes)
/// to retrieve content of the video.
/// As a result of the large volume of small requests, CPU usage will be very high,
/// which can result in app or webpage frozen.
/// To mitigate, opting for the less "broken" behavior of ignoring Range header
/// until WebKit behavior is changed.
class KiwixURLSchemeHandler: NSObject, WKURLSchemeHandler {
private var urls = Set<URL>()
private var queue = DispatchQueue(label: "org.kiwix.webContent", qos: .userInitiated)
Expand All @@ -19,38 +26,12 @@ class KiwixURLSchemeHandler: NSObject, WKURLSchemeHandler {
urlSchemeTask.didFailWithError(URLError(.unsupportedURL))
return
}

objCTryBlock {
/// Skipping handling for HTTP 206 Partial Content
/// For video playback, WebKit makes a large amount of requests with small byte range (e.g. 8 bytes) to retrieve content of the video.
/// As a result of the large volume of small requests, CPU usage will be very high, which can result in app or webpage frozen.
/// To mitigate, opting for the less "broken" behavior of ignoring Range header until WebKit behavior is changed.
//if let range = urlSchemeTask.request.allHTTPHeaderFields?["Range"] as? String {
// let parts = range.components(separatedBy: ["=", "-"])
// guard parts.count >= 2, let start = UInt(parts[1]) else {
// self.sendHTTP400Response(urlSchemeTask, url: url)
// return
// }
// let end = parts.count == 3 ? UInt(parts[2]) ?? 0 : 0
// guard let content = ZimFileService.shared.getURLContent(
// url: url, start: start, end: end
// ) else {
// self.sendHTTP404Response(urlSchemeTask, url: url)
// return
// }
// self.sendHTTP206Response(urlSchemeTask, url: url, content: content)
//} else {
// guard let content = ZimFileService.shared.getURLContent(url: url) else {
// self.sendHTTP404Response(urlSchemeTask, url: url)
// return
// }
// self.sendHTTP200Response(urlSchemeTask, url: url, content: content)
//}
objCTryBlock { [weak self] in
guard let content = ZimFileService.shared.getURLContent(url: url) else {
self.sendHTTP404Response(urlSchemeTask, url: url)
self?.sendHTTP404Response(urlSchemeTask, url: url)
return
}
self.sendHTTP200Response(urlSchemeTask, url: url, content: content)
self?.sendHTTP200Response(urlSchemeTask, url: url, content: content)
}
}
}
Expand Down
8 changes: 6 additions & 2 deletions SwiftUI/Model/DefaultKeys.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,7 @@ extension Defaults.Keys {
//
// // search
static let recentSearchTexts = Key<[String]>("recentSearchTexts", default: [])



// library
static let libraryLanguageCodes = Key<Set<String>>("libraryLanguageCodes", default: Set())
static let libraryLanguageSortingMode = Key<LibraryLanguageSortingMode>(
Expand All @@ -37,6 +36,11 @@ extension Defaults.Keys {

static let downloadUsingCellular = Key<Bool>("downloadUsingCellular", default: false)
static let backupDocumentDirectory = Key<Bool>("backupDocumentDirectory", default: false)

#if os(macOS)
// window management:
static let windowURLs = Key<[URL]>("windowURLs", default: [])
#endif
}

extension Defaults.Serializable where Self: Codable {
Expand Down
2 changes: 1 addition & 1 deletion SwiftUI/Model/Enum.swift
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,7 @@ enum NavigationItem: Hashable, Identifiable {
}


enum SearchResultSnippetMode: String, CaseIterable, Identifiable, Defaults.Serializable {
enum SearchResultSnippetMode: String, CaseIterable, Identifiable, Defaults.Serializable {
case disabled, firstParagraph, firstSentence, matches

var id: String { rawValue }
Expand Down
Loading

0 comments on commit accc2d2

Please sign in to comment.