From 4d227e7e2c5ba6921442922b4e7b61ad9e4cc91d Mon Sep 17 00:00:00 2001 From: Stuart Breckenridge Date: Sun, 19 Jul 2020 07:57:25 +0800 Subject: [PATCH 1/3] Inspector tweaks - [x] Account Inspector should have an Active toggle (see iOS) - [x] Feed Inspector Home Page should open the link in browser when tapped - [x] Feed Inspector Home Page should have a browser icon (see iOS) - [x] Feed Inspector Home Page URL should line wrap - [x] Feed Inspector Feed URL should be copiable (currently this is a long press on iOS) - [x] Feed Inspector Feed URL should line wrap - [x] Inspector should use inset style on iOS --- .../Shared/Inspector/InspectorModel.swift | 14 +- .../Inspector/InspectorPlatformModifier.swift | 37 +++-- .../Shared/Inspector/InspectorView.swift | 148 +++++++++++++----- 3 files changed, 145 insertions(+), 54 deletions(-) diff --git a/Multiplatform/Shared/Inspector/InspectorModel.swift b/Multiplatform/Shared/Inspector/InspectorModel.swift index ff9ede619..63d774cef 100644 --- a/Multiplatform/Shared/Inspector/InspectorModel.swift +++ b/Multiplatform/Shared/Inspector/InspectorModel.swift @@ -19,9 +19,12 @@ import UIKit class InspectorModel: ObservableObject { - @Published var notificationSettings: UNNotificationSettings? + // Global Inspector Variables @Published var editedName: String = "" @Published var shouldUpdate: Bool = false + + // Account Inspector Variables + @Published var notificationSettings: UNNotificationSettings? @Published var notifyAboutNewArticles: Bool = false { didSet { updateNotificationSettings() @@ -32,6 +35,14 @@ class InspectorModel: ObservableObject { selectedWebFeed?.isArticleExtractorAlwaysOn = alwaysShowReaderView } } + @Published var accountIsActive: Bool = false { + didSet { + selectedAccount?.isActive = accountIsActive + } + } + @Published var showHomePage: Bool = false // iOS only + + // Private Variables private let centre = UNUserNotificationCenter.current() private var selectedWebFeed: WebFeed? private var selectedFolder: Folder? @@ -71,6 +82,7 @@ class InspectorModel: ObservableObject { func configure(with account: Account) { selectedAccount = account editedName = account.nameForDisplay + accountIsActive = account.isActive } func updateNotificationSettings() { diff --git a/Multiplatform/Shared/Inspector/InspectorPlatformModifier.swift b/Multiplatform/Shared/Inspector/InspectorPlatformModifier.swift index 9ee8d96ad..c287fd91d 100644 --- a/Multiplatform/Shared/Inspector/InspectorPlatformModifier.swift +++ b/Multiplatform/Shared/Inspector/InspectorPlatformModifier.swift @@ -16,24 +16,29 @@ struct InspectorPlatformModifier: ViewModifier { @ViewBuilder func body(content: Content) -> some View { #if os(macOS) - content - .textFieldStyle(RoundedBorderTextFieldStyle()) - .frame(width: 300) - .padding() + Form { + content + } + .textFieldStyle(RoundedBorderTextFieldStyle()) + .frame(width: 300) + .padding() #else NavigationView { - content - .navigationBarTitle("Inspector", displayMode: .inline) - .navigationBarItems( - leading: - Button("Cancel", action: { - presentationMode.wrappedValue.dismiss() - }), - trailing: - Button("Done", action: { - shouldUpdate = true - }) - ) + List { + content + } + .listStyle(InsetGroupedListStyle()) + .navigationBarTitle("Inspector", displayMode: .inline) + .navigationBarItems( + leading: + Button("Cancel", action: { + presentationMode.wrappedValue.dismiss() + }), + trailing: + Button("Done", action: { + shouldUpdate = true + }) + ) } #endif } diff --git a/Multiplatform/Shared/Inspector/InspectorView.swift b/Multiplatform/Shared/Inspector/InspectorView.swift index f93ddd9d6..bedb9cf2c 100644 --- a/Multiplatform/Shared/Inspector/InspectorView.swift +++ b/Multiplatform/Shared/Inspector/InspectorView.swift @@ -34,17 +34,13 @@ struct InspectorView: View { } } + // MARK: WebFeed Inspector + @ViewBuilder var WebFeedInspectorView: some View { - Form { - Section(header: Text("Name").bold()) { - HStack(alignment: .center) { - if let image = feedIconImageLoader.image { - IconImageView(iconImage: image) - .frame(width: 30, height: 30) - } - TextField("", text: $inspectorModel.editedName) - } + Group { + Section(header: webFeedHeader) { + TextField("", text: $inspectorModel.editedName) } #if os(macOS) @@ -60,16 +56,67 @@ struct InspectorView: View { Divider() #endif - Section(header: Text("Home Page URL").bold()) { - Text((sidebarItem.feed as? WebFeed)?.homePageURL ?? "") + Section(header: Text("Home Page URL")) { + HStack { + Text((sidebarItem.feed as? WebFeed)?.homePageURL ?? "") + .fixedSize(horizontal: false, vertical: true) + Spacer() + Image(systemName: "safari") + .foregroundColor(.accentColor) + } + .onTapGesture { + if let url = URL(string: (sidebarItem.feed as? WebFeed)?.homePageURL ?? "") { + #if os(macOS) + NSWorkspace.shared.open(url) + #else + inspectorModel.showHomePage = true + #endif + } + } + .contextMenu(ContextMenu(menuItems: { + Button(action: { + if let urlString = (sidebarItem.feed as? WebFeed)?.homePageURL { + #if os(macOS) + URLPasteboardWriter.write(urlString: urlString, to: NSPasteboard.general) + #else + UIPasteboard.general.string = urlString + #endif + } + + + }, label: { + Text("Copy Home Page URL") + }) + })) + } + .sheet(isPresented: $inspectorModel.showHomePage, onDismiss: { inspectorModel.showHomePage = false }) { + #if os(macOS) + EmptyView() + #else + SafariView(url: URL(string: (sidebarItem.feed as! WebFeed).homePageURL!)!) + #endif } #if os(macOS) Divider() #endif - Section(header: Text("Feed URL").bold()) { + Section(header: Text("Feed URL")) { Text((sidebarItem.feed as? WebFeed)?.url ?? "") + .fixedSize(horizontal: false, vertical: true) + .contextMenu(ContextMenu(menuItems: { + Button(action: { + if let urlString = (sidebarItem.feed as? WebFeed)?.url { + #if os(macOS) + URLPasteboardWriter.write(urlString: urlString, to: NSPasteboard.general) + #else + UIPasteboard.general.string = urlString + #endif + } + }, label: { + Text("Copy Feed URL") + }) + })) } #if os(macOS) @@ -87,7 +134,7 @@ struct InspectorView: View { .onAppear { inspectorModel.configure(with: sidebarItem.feed as! WebFeed) feedIconImageLoader.loadImage(for: sidebarItem.feed!) - }.onChange(of: inspectorModel.shouldUpdate) { value in + }.onReceive(inspectorModel.$shouldUpdate) { value in if value == true { if inspectorModel.editedName.trimmingWhitespace.count > 0 { (sidebarItem.feed as? WebFeed)?.editedName = inspectorModel.editedName @@ -97,21 +144,27 @@ struct InspectorView: View { presentationMode.wrappedValue.dismiss() } } - } + var webFeedHeader: some View { + HStack(alignment: .center) { + Spacer() + if let image = feedIconImageLoader.image { + IconImageView(iconImage: image) + .frame(width: 50, height: 50) + } + Spacer() + }.padding() + } + + + // MARK: Folder Inspector + @ViewBuilder var FolderInspectorView: some View { - - Form { - Section(header: Text("Name").bold()) { - HStack(alignment: .center) { - if let image = feedIconImageLoader.image { - IconImageView(iconImage: image) - .frame(width: 30, height: 30) - } - TextField("", text: $inspectorModel.editedName) - } + Group { + Section(header: folderHeader) { + TextField("", text: $inspectorModel.editedName) } #if os(macOS) @@ -131,7 +184,7 @@ struct InspectorView: View { inspectorModel.configure(with: sidebarItem.represented as! Folder) feedIconImageLoader.loadImage(for: sidebarItem.feed!) } - .onChange(of: inspectorModel.shouldUpdate) { value in + .onReceive(inspectorModel.$shouldUpdate) { value in if value == true { if inspectorModel.editedName.trimmingWhitespace.count > 0 { (sidebarItem.feed as? Folder)?.name = inspectorModel.editedName @@ -143,19 +196,26 @@ struct InspectorView: View { } } + var folderHeader: some View { + HStack(alignment: .center) { + Spacer() + if let image = feedIconImageLoader.image { + IconImageView(iconImage: image) + .frame(width: 50, height: 50) + } + Spacer() + }.padding() + } + + + // MARK: Account Inspector + @ViewBuilder var AccountInspectorView: some View { - Form { - Section(header: Text("Name").bold()) { - HStack(alignment: .center) { - if let image = (sidebarItem.represented as? Account)?.smallIcon?.image { - Image(rsImage: image) - .resizable() - .aspectRatio(contentMode: .fit) - .frame(width: 30, height: 30) - } - TextField("", text: $inspectorModel.editedName) - } + Group { + Section(header: accountHeader) { + TextField("", text: $inspectorModel.editedName) + Toggle("Active", isOn: $inspectorModel.accountIsActive) } #if os(macOS) @@ -173,7 +233,7 @@ struct InspectorView: View { .onAppear { inspectorModel.configure(with: sidebarItem.represented as! Account) } - .onChange(of: inspectorModel.shouldUpdate) { value in + .onReceive(inspectorModel.$shouldUpdate) { value in if value == true { if inspectorModel.editedName.trimmingWhitespace.count > 0 { (sidebarItem.represented as? Account)?.name = inspectorModel.editedName @@ -185,6 +245,20 @@ struct InspectorView: View { } } + var accountHeader: some View { + HStack(alignment: .center) { + Spacer() + if let image = (sidebarItem.represented as? Account)?.smallIcon?.image { + Image(rsImage: image) + .resizable() + .aspectRatio(contentMode: .fit) + .frame(width: 50, height: 50) + } + Spacer() + }.padding() + } + + } From 526a98f326c30d8827b8fcd57b8e94c0ad051638 Mon Sep 17 00:00:00 2001 From: Stuart Breckenridge Date: Sun, 19 Jul 2020 08:12:20 +0800 Subject: [PATCH 2/3] Switches to AppAssets --- Multiplatform/Shared/Inspector/InspectorView.swift | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Multiplatform/Shared/Inspector/InspectorView.swift b/Multiplatform/Shared/Inspector/InspectorView.swift index bedb9cf2c..25975ad3c 100644 --- a/Multiplatform/Shared/Inspector/InspectorView.swift +++ b/Multiplatform/Shared/Inspector/InspectorView.swift @@ -61,7 +61,7 @@ struct InspectorView: View { Text((sidebarItem.feed as? WebFeed)?.homePageURL ?? "") .fixedSize(horizontal: false, vertical: true) Spacer() - Image(systemName: "safari") + AppAssets.openInBrowserImage .foregroundColor(.accentColor) } .onTapGesture { @@ -82,8 +82,6 @@ struct InspectorView: View { UIPasteboard.general.string = urlString #endif } - - }, label: { Text("Copy Home Page URL") }) From 03c60a2979e44aa091f08be4d8a7853f37a2cd21 Mon Sep 17 00:00:00 2001 From: Stuart Breckenridge Date: Sun, 19 Jul 2020 08:25:26 +0800 Subject: [PATCH 3/3] Adds default cancel keyboard shortcut --- Multiplatform/Shared/Inspector/InspectorView.swift | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Multiplatform/Shared/Inspector/InspectorView.swift b/Multiplatform/Shared/Inspector/InspectorView.swift index 25975ad3c..b70b00bb0 100644 --- a/Multiplatform/Shared/Inspector/InspectorView.swift +++ b/Multiplatform/Shared/Inspector/InspectorView.swift @@ -122,7 +122,7 @@ struct InspectorView: View { Spacer() Button("Cancel", action: { presentationMode.wrappedValue.dismiss() - }) + }).keyboardShortcut(.cancelAction) Button("Done", action: { inspectorModel.shouldUpdate = true }).keyboardShortcut(.defaultAction) @@ -170,7 +170,7 @@ struct InspectorView: View { Spacer() Button("Cancel", action: { presentationMode.wrappedValue.dismiss() - }) + }).keyboardShortcut(.cancelAction) Button("Done", action: { inspectorModel.shouldUpdate = true }).keyboardShortcut(.defaultAction) @@ -221,7 +221,7 @@ struct InspectorView: View { Spacer() Button("Cancel", action: { presentationMode.wrappedValue.dismiss() - }) + }).keyboardShortcut(.cancelAction) Button("Done", action: { inspectorModel.shouldUpdate = true }).keyboardShortcut(.defaultAction)