diff --git a/ReaderTranslator.xcodeproj/project.pbxproj b/ReaderTranslator.xcodeproj/project.pbxproj index 0358bcb..9131be7 100644 --- a/ReaderTranslator.xcodeproj/project.pbxproj +++ b/ReaderTranslator.xcodeproj/project.pbxproj @@ -86,6 +86,8 @@ F0BB43832344846C00ADBEF1 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F0AA69A4232E9710007CC07B /* ContentView.swift */; }; F0EE0A1023478C86004A5EAD /* DOMEvent.swift in Sources */ = {isa = PBXBuildFile; fileRef = F0EE0A0F23478C86004A5EAD /* DOMEvent.swift */; }; F0EE0A122347AA0E004A5EAD /* DOMEvent.swift in Sources */ = {isa = PBXBuildFile; fileRef = F0EE0A0F23478C86004A5EAD /* DOMEvent.swift */; }; + F0EE0A162347BF09004A5EAD /* PageWebView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F0EE0A152347BF09004A5EAD /* PageWebView.swift */; }; + F0EE0A172347BF09004A5EAD /* PageWebView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F0EE0A152347BF09004A5EAD /* PageWebView.swift */; }; F0F256BD233D309F00C9D719 /* String.swift in Sources */ = {isa = PBXBuildFile; fileRef = F0F256BC233D309F00C9D719 /* String.swift */; }; F0F256C2233E6C4C00C9D719 /* FavoriteVoiceName.swift in Sources */ = {isa = PBXBuildFile; fileRef = F0F256C1233E6C4C00C9D719 /* FavoriteVoiceName.swift */; }; /* End PBXBuildFile section */ @@ -192,6 +194,7 @@ F0AB12B3233F599C005B9F2A /* StatusBarView_Voice_Favorite.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatusBarView_Voice_Favorite.swift; sourceTree = ""; }; F0AB12B5233F59B4005B9F2A /* StatusBarView_Voice_Volume.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatusBarView_Voice_Volume.swift; sourceTree = ""; }; F0EE0A0F23478C86004A5EAD /* DOMEvent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DOMEvent.swift; sourceTree = ""; }; + F0EE0A152347BF09004A5EAD /* PageWebView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PageWebView.swift; sourceTree = ""; }; F0F256BC233D309F00C9D719 /* String.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = String.swift; sourceTree = ""; }; F0F256C1233E6C4C00C9D719 /* FavoriteVoiceName.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FavoriteVoiceName.swift; sourceTree = ""; }; /* End PBXFileReference section */ @@ -409,7 +412,7 @@ F0AA69DD232E97B0007CC07B /* PDFKitView.swift */, F0AA69DA232E97AF007CC07B /* SpeechSynthesizer.swift */, F0AA69DB232E97AF007CC07B /* TranslatorView.swift */, - F0AA69DC232E97B0007CC07B /* WebView.swift */, + F0EE0A142347BEDB004A5EAD /* WebView */, F06DB1032344975E00C2DE90 /* Stack.swift */, F06DB109234504FD00C2DE90 /* EditorNSTextView.swift */, F06DB10C23450B6000C2DE90 /* View.swift */, @@ -450,6 +453,15 @@ path = StatusBarView; sourceTree = ""; }; + F0EE0A142347BEDB004A5EAD /* WebView */ = { + isa = PBXGroup; + children = ( + F0AA69DC232E97B0007CC07B /* WebView.swift */, + F0EE0A152347BF09004A5EAD /* PageWebView.swift */, + ); + path = WebView; + sourceTree = ""; + }; F0F256BB233D307C00C9D719 /* Extentions */ = { isa = PBXGroup; children = ( @@ -666,6 +678,7 @@ buildActionMask = 2147483647; files = ( F0BB43792344845000ADBEF1 /* StatusBarView_Tabs.swift in Sources */, + F0EE0A172347BF09004A5EAD /* PageWebView.swift in Sources */, F06DB10B234504FD00C2DE90 /* EditorNSTextView.swift in Sources */, F06DB10E23450B6000C2DE90 /* View.swift in Sources */, F0BB437F2344845000ADBEF1 /* StatusBarView_Voice_Favorite.swift in Sources */, @@ -727,6 +740,7 @@ F0AA69D4232E9762007CC07B /* ReaderView.swift in Sources */, F0AB12B0233F5968005B9F2A /* StatusBarView_Voice.swift in Sources */, F0AB12B2233F597B005B9F2A /* StatusBarView_Voice_Select.swift in Sources */, + F0EE0A162347BF09004A5EAD /* PageWebView.swift in Sources */, F0F256C2233E6C4C00C9D719 /* FavoriteVoiceName.swift in Sources */, F06DB10D23450B6000C2DE90 /* View.swift in Sources */, F0AA69DF232E97B0007CC07B /* TranslatorView.swift in Sources */, diff --git a/ReaderTranslator/Components/WebView.swift b/ReaderTranslator/Components/WebView/PageWebView.swift similarity index 79% rename from ReaderTranslator/Components/WebView.swift rename to ReaderTranslator/Components/WebView/PageWebView.swift index 30f862a..c6570df 100644 --- a/ReaderTranslator/Components/WebView.swift +++ b/ReaderTranslator/Components/WebView/PageWebView.swift @@ -1,70 +1,14 @@ // -// WebView.swift -// PdfTranslator +// PageWebView.swift +// ReaderTranslator // -// Created by Viktor Kushnerov on 9/14/19. +// Created by Viktor Kushnerov on 10/4/19. // Copyright © 2019 Viktor Kushnerov. All rights reserved. // -import SwiftUI import Combine import WebKit -#if os(macOS) - -struct WebView: NSViewRepresentable { - @Binding var lastWebPage: String - - static var pageView: PageWebView { views[Store.shared.currentTab]! } - - @ObservedObject private var store = Store.shared - static private var views = [Int: PageWebView]() - private var view: PageWebView { - if let view = WebView.views[store.currentTab] { return view } - let view = PageWebView() - - WebView.views[self.store.currentTab] = view - store.canGoBack = view.canGoBack - - return view - } - - func makeNSView(context: Context) -> PageWebView { view } - - func updateNSView(_ view: PageWebView, context: Context) { - #if os(macOS) - //TODO: view.scrollView.zoomScale = store.zoom - view.setNeedsDisplay(view.bounds) - #else - view.scrollView.zoomScale = store.zoom - #endif - if view.newUrl != lastWebPage { view.newUrl = lastWebPage } - } -} -#else -struct WebView: UIViewRepresentable { - @Binding var lastWebPage: String - - @ObservedObject private var store = Store.shared - static private var views = [Int: PageWebView]() - private var view: PageWebView { WebView.views[store.currentTab] ?? PageWebView() } - - static var pageView: PageWebView { views[Store.shared.currentTab]! } - - func makeUIView(context: Context) -> PageWebView { - WebView.views[self.store.currentTab] = view - store.canGoBack = view.canGoBack - - return view - } - - func updateUIView(_ uiView: PageWebView, context: Context) { - uiView.setZoom(zoomLevel: store.zoom) - if uiView.newUrl != lastWebPage { uiView.newUrl = lastWebPage } - } -} -#endif - //This hack to make PageWebView the first responder but the selection won't work //extension UIView { @@ -101,7 +45,7 @@ private let script = """ class PageWebView: WKWebView { @Published var newUrl = "" - @Published private var selectedText = "" + @Published private var selectedText = "" private var cancellableSet: Set = [] private var store = Store.shared @@ -195,7 +139,7 @@ extension PageWebView { override public var keyCommands: [UIKeyCommand]? { //Voice selected text with any key since performCommand isn't fired because PageWebView isn't the first responder. SpeechSynthesizer.speak(stopSpeaking: true, isVoiceEnabled: true) - return [.init(input: "1", modifierFlags: .command, eventName: #selector(performCommand))] + return [.init(input: "1", modifierFlags: .command, action: #selector(performCommand))] } @objc func performCommand(sender: UIKeyCommand) { @@ -291,4 +235,3 @@ extension PageWebView: WKNavigationDelegate { } } - diff --git a/ReaderTranslator/Components/WebView/WebView.swift b/ReaderTranslator/Components/WebView/WebView.swift new file mode 100644 index 0000000..cc03614 --- /dev/null +++ b/ReaderTranslator/Components/WebView/WebView.swift @@ -0,0 +1,66 @@ +// +// WebView.swift +// PdfTranslator +// +// Created by Viktor Kushnerov on 9/14/19. +// Copyright © 2019 Viktor Kushnerov. All rights reserved. +// + +import SwiftUI + +#if os(macOS) + +struct WebView: NSViewRepresentable { + @Binding var lastWebPage: String + + static var pageView: PageWebView { views[Store.shared.currentTab]! } + + @ObservedObject private var store = Store.shared + static private var views = [Int: PageWebView]() + private var view: PageWebView { + if let view = WebView.views[store.currentTab] { return view } + let view = PageWebView() + + WebView.views[self.store.currentTab] = view + store.canGoBack = view.canGoBack + + return view + } + + func makeNSView(context: Context) -> PageWebView { view } + + func updateNSView(_ view: PageWebView, context: Context) { + #if os(macOS) + //TODO: view.scrollView.zoomScale = store.zoom + view.setNeedsDisplay(view.bounds) + #else + view.scrollView.zoomScale = store.zoom + #endif + if view.newUrl != lastWebPage { view.newUrl = lastWebPage } + } +} +#else +struct WebView: UIViewRepresentable { + @Binding var lastWebPage: String + + @ObservedObject private var store = Store.shared + static private var views = [Int: PageWebView]() + private var view: PageWebView { WebView.views[store.currentTab] ?? PageWebView() } + + static var pageView: PageWebView { views[Store.shared.currentTab]! } + + func makeUIView(context: Context) -> PageWebView { + WebView.views[self.store.currentTab] = view + store.canGoBack = view.canGoBack + + return view + } + + func updateUIView(_ uiView: PageWebView, context: Context) { + uiView.setZoom(zoomLevel: store.zoom) + if uiView.newUrl != lastWebPage { uiView.newUrl = lastWebPage } + } +} +#endif + + diff --git a/ReaderTranslator/Views/ReaderView/ReaderView.swift b/ReaderTranslator/Views/ReaderView/ReaderView.swift index 98da7e0..3041681 100644 --- a/ReaderTranslator/Views/ReaderView/ReaderView.swift +++ b/ReaderTranslator/Views/ReaderView/ReaderView.swift @@ -15,8 +15,10 @@ struct ReaderView: View { var body: some View { Stack(arrange: store.viewMode == .safari ? .vertical : .horizontal) { ReaderView_PDF() - ReaderView_Web() + ReaderView_Web() + #if os(macOS) ReaderView_Safari() + #endif TranslatorView(text: .constant(URLQueryItem(name: "text", value: self.store.selectedText))) } .onAppear { diff --git a/ReaderTranslator/Views/ReaderView/ReaderView_Safari.swift b/ReaderTranslator/Views/ReaderView/ReaderView_Safari.swift index 2affafc..3a6b7e6 100644 --- a/ReaderTranslator/Views/ReaderView/ReaderView_Safari.swift +++ b/ReaderTranslator/Views/ReaderView/ReaderView_Safari.swift @@ -14,11 +14,9 @@ struct ReaderView_Safari: View { var body: some View { Group { - #if os(macOS) if store.viewMode == .safari { Text(store.selectedText) } - #endif } .onAppear { SafariExtensionManager().start(onMessageChanged: self.onMessageChanged(notificationName:)) diff --git a/ReaderTranslator/Views/StatusBarView/StatusBarView.swift b/ReaderTranslator/Views/StatusBarView/StatusBarView.swift index f672b32..a380b2e 100644 --- a/ReaderTranslator/Views/StatusBarView/StatusBarView.swift +++ b/ReaderTranslator/Views/StatusBarView/StatusBarView.swift @@ -17,11 +17,12 @@ struct StatusBarView: View { StatusBarView_ViewMode().padding(5) StatusBarView_PdfPage() StatusBarView_Tabs(viewMode: $store.viewMode, currentTab: $store.currentTab) - #if os(macOS) - #else StatusBarView_Zoom() - #endif StatusBarView_Voice().padding([.top,.bottom], 5) + #if os(macOS) + Text("Safari plugin: \(store.canSafariSendSelectedText ? "on" : "off")") + .foregroundColor(store.canSafariSendSelectedText ? .green : .red) + #endif }.padding(.trailing, 20) } } diff --git a/ReaderTranslator/Views/StatusBarView/StatusBarView_Zoom.swift b/ReaderTranslator/Views/StatusBarView/StatusBarView_Zoom.swift index e61194f..085bed9 100644 --- a/ReaderTranslator/Views/StatusBarView/StatusBarView_Zoom.swift +++ b/ReaderTranslator/Views/StatusBarView/StatusBarView_Zoom.swift @@ -10,18 +10,21 @@ import SwiftUI struct StatusBarView_Zoom: View { @EnvironmentObject var store: Store - - var body: some View { - let zoom = Binding( - get: { String(format: "%.02f", CGFloat(self.store.zoom)) }, - set: { - if let value = NumberFormatter().number(from: $0) { - self.store.zoom = CGFloat(truncating: value) - } + #if !os(macOS) + let zoom = Binding( + get: { String(format: "%.02f", CGFloat(Store.shared.zoom)) }, + set: { + if let value = NumberFormatter().number(from: $0) { + Store.shared.zoom = CGFloat(truncating: value) + } } - ) + ) + #endif + + var body: some View { return Group { + #if !os(macOS) if store.viewMode == .web { Divider().fixedSize() TextField("zoom", text: zoom) @@ -35,6 +38,7 @@ struct StatusBarView_Zoom: View { Image(systemName: "plus.magnifyingglass") } } + #endif } } }