2020-07-18 11:34:04 +02:00
|
|
|
//
|
|
|
|
// InspectorView.swift
|
|
|
|
// NetNewsWire
|
|
|
|
//
|
|
|
|
// Created by Stuart Breckenridge on 18/7/20.
|
|
|
|
// Copyright © 2020 Ranchero Software. All rights reserved.
|
|
|
|
//
|
|
|
|
|
|
|
|
import SwiftUI
|
|
|
|
import RSCore
|
|
|
|
import Account
|
|
|
|
|
|
|
|
struct InspectorView: View {
|
|
|
|
|
|
|
|
@Environment(\.presentationMode) var presentationMode
|
|
|
|
@StateObject private var feedIconImageLoader = FeedIconImageLoader()
|
2020-07-18 15:21:59 +02:00
|
|
|
@StateObject private var inspectorModel = InspectorModel()
|
2020-07-18 11:34:04 +02:00
|
|
|
var sidebarItem: SidebarItem
|
|
|
|
|
|
|
|
var body: some View {
|
|
|
|
switch sidebarItem.representedType {
|
|
|
|
case .webFeed:
|
|
|
|
WebFeedInspectorView
|
2020-07-18 15:21:59 +02:00
|
|
|
.modifier(InspectorPlatformModifier(shouldUpdate: $inspectorModel.shouldUpdate))
|
2020-07-18 11:34:04 +02:00
|
|
|
case .folder:
|
|
|
|
FolderInspectorView
|
2020-07-18 15:21:59 +02:00
|
|
|
.modifier(InspectorPlatformModifier(shouldUpdate: $inspectorModel.shouldUpdate))
|
2020-07-18 11:34:04 +02:00
|
|
|
case .account:
|
|
|
|
AccountInspectorView
|
2020-07-18 15:21:59 +02:00
|
|
|
.modifier(InspectorPlatformModifier(shouldUpdate: $inspectorModel.shouldUpdate))
|
2020-07-18 11:34:04 +02:00
|
|
|
default:
|
|
|
|
EmptyView()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-07-19 01:57:25 +02:00
|
|
|
// MARK: WebFeed Inspector
|
|
|
|
|
2020-08-13 16:21:31 +02:00
|
|
|
|
2020-07-18 11:34:04 +02:00
|
|
|
var WebFeedInspectorView: some View {
|
2020-08-13 16:21:31 +02:00
|
|
|
Form {
|
2020-07-19 01:57:25 +02:00
|
|
|
Section(header: webFeedHeader) {
|
|
|
|
TextField("", text: $inspectorModel.editedName)
|
2020-07-18 11:34:04 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
#if os(macOS)
|
|
|
|
Divider()
|
|
|
|
#endif
|
|
|
|
|
2020-07-18 15:21:59 +02:00
|
|
|
Section(content: {
|
|
|
|
Toggle("Notify About New Articles", isOn: $inspectorModel.notifyAboutNewArticles)
|
|
|
|
Toggle("Always Show Reader View", isOn: $inspectorModel.alwaysShowReaderView)
|
|
|
|
})
|
|
|
|
|
2020-07-19 03:18:57 +02:00
|
|
|
if let homePageURL = (sidebarItem.feed as? WebFeed)?.homePageURL {
|
|
|
|
#if os(macOS)
|
|
|
|
Divider()
|
|
|
|
#endif
|
|
|
|
|
|
|
|
Section(header: Text("Home Page URL")) {
|
|
|
|
HStack {
|
|
|
|
Text(verbatim: homePageURL)
|
|
|
|
.fixedSize(horizontal: false, vertical: true)
|
|
|
|
Spacer()
|
|
|
|
AppAssets.openInBrowserImage
|
|
|
|
.foregroundColor(.accentColor)
|
2020-07-19 01:57:25 +02:00
|
|
|
}
|
2020-07-19 03:18:57 +02:00
|
|
|
.onTapGesture {
|
|
|
|
if let url = URL(string: homePageURL) {
|
2020-07-19 01:57:25 +02:00
|
|
|
#if os(macOS)
|
2020-07-19 03:18:57 +02:00
|
|
|
NSWorkspace.shared.open(url)
|
2020-07-19 01:57:25 +02:00
|
|
|
#else
|
2020-07-19 03:18:57 +02:00
|
|
|
inspectorModel.showHomePage = true
|
2020-07-19 01:57:25 +02:00
|
|
|
#endif
|
|
|
|
}
|
2020-07-19 03:18:57 +02:00
|
|
|
}
|
|
|
|
.contextMenu(ContextMenu(menuItems: {
|
|
|
|
Button(action: {
|
|
|
|
#if os(macOS)
|
|
|
|
URLPasteboardWriter.write(urlString: homePageURL, to: NSPasteboard.general)
|
|
|
|
#else
|
|
|
|
UIPasteboard.general.string = homePageURL
|
|
|
|
#endif
|
|
|
|
}, label: {
|
|
|
|
Text("Copy Home Page URL")
|
|
|
|
})
|
|
|
|
}))
|
2020-08-13 16:21:31 +02:00
|
|
|
.sheet(isPresented: $inspectorModel.showHomePage, onDismiss: { inspectorModel.showHomePage = false }) {
|
|
|
|
#if os(macOS)
|
|
|
|
EmptyView()
|
|
|
|
#else
|
|
|
|
SafariView(url: URL(string: (sidebarItem.feed as! WebFeed).homePageURL!)!)
|
|
|
|
#endif
|
|
|
|
}
|
2020-07-19 03:18:57 +02:00
|
|
|
}
|
2020-07-18 11:34:04 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
#if os(macOS)
|
|
|
|
Divider()
|
|
|
|
#endif
|
|
|
|
|
2020-07-19 01:57:25 +02:00
|
|
|
Section(header: Text("Feed URL")) {
|
2020-07-19 03:22:41 +02:00
|
|
|
VStack {
|
2020-08-13 16:21:31 +02:00
|
|
|
// #if os(macOS)
|
|
|
|
// Spacer() // This shouldn't be necessary, but for some reason macOS doesn't put the space in itself
|
|
|
|
// #endif
|
2020-07-19 03:22:41 +02:00
|
|
|
Text(verbatim: (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")
|
|
|
|
})
|
|
|
|
}))
|
|
|
|
}
|
2020-07-18 11:34:04 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
#if os(macOS)
|
|
|
|
HStack {
|
|
|
|
Spacer()
|
|
|
|
Button("Cancel", action: {
|
|
|
|
presentationMode.wrappedValue.dismiss()
|
2020-08-13 13:16:17 +02:00
|
|
|
})
|
2020-07-18 13:31:56 +02:00
|
|
|
Button("Done", action: {
|
2020-07-18 15:21:59 +02:00
|
|
|
inspectorModel.shouldUpdate = true
|
2020-08-13 13:16:17 +02:00
|
|
|
})
|
2020-08-13 16:21:31 +02:00
|
|
|
}.padding([.top, .bottom], 20)
|
2020-07-18 11:34:04 +02:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
.onAppear {
|
2020-07-18 15:21:59 +02:00
|
|
|
inspectorModel.configure(with: sidebarItem.feed as! WebFeed)
|
2020-07-18 11:34:04 +02:00
|
|
|
feedIconImageLoader.loadImage(for: sidebarItem.feed!)
|
2020-07-19 01:57:25 +02:00
|
|
|
}.onReceive(inspectorModel.$shouldUpdate) { value in
|
2020-07-18 11:34:04 +02:00
|
|
|
if value == true {
|
2020-07-18 15:21:59 +02:00
|
|
|
if inspectorModel.editedName.trimmingWhitespace.count > 0 {
|
2020-07-20 00:07:09 +02:00
|
|
|
(sidebarItem.feed as? WebFeed)?.rename(to: inspectorModel.editedName.trimmingWhitespace) { _ in }
|
2020-07-18 11:34:04 +02:00
|
|
|
}
|
|
|
|
presentationMode.wrappedValue.dismiss()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-07-19 01:57:25 +02:00
|
|
|
var webFeedHeader: some View {
|
|
|
|
HStack(alignment: .center) {
|
|
|
|
Spacer()
|
|
|
|
if let image = feedIconImageLoader.image {
|
|
|
|
IconImageView(iconImage: image)
|
|
|
|
.frame(width: 50, height: 50)
|
|
|
|
}
|
|
|
|
Spacer()
|
2020-08-13 16:21:31 +02:00
|
|
|
}.padding(.top, 20)
|
2020-07-19 01:57:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// MARK: Folder Inspector
|
|
|
|
|
2020-07-18 11:34:04 +02:00
|
|
|
var FolderInspectorView: some View {
|
2020-08-13 16:21:31 +02:00
|
|
|
Form {
|
2020-07-19 01:57:25 +02:00
|
|
|
Section(header: folderHeader) {
|
|
|
|
TextField("", text: $inspectorModel.editedName)
|
2020-07-18 11:34:04 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
#if os(macOS)
|
|
|
|
HStack {
|
|
|
|
Spacer()
|
|
|
|
Button("Cancel", action: {
|
|
|
|
presentationMode.wrappedValue.dismiss()
|
2020-08-13 16:21:31 +02:00
|
|
|
})
|
2020-07-18 13:31:56 +02:00
|
|
|
Button("Done", action: {
|
2020-07-18 15:21:59 +02:00
|
|
|
inspectorModel.shouldUpdate = true
|
2020-08-13 16:21:31 +02:00
|
|
|
})
|
|
|
|
}.padding([.top, .bottom])
|
2020-07-18 11:34:04 +02:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
.onAppear {
|
2020-07-18 15:21:59 +02:00
|
|
|
inspectorModel.configure(with: sidebarItem.represented as! Folder)
|
2020-07-18 11:34:04 +02:00
|
|
|
feedIconImageLoader.loadImage(for: sidebarItem.feed!)
|
|
|
|
}
|
2020-07-19 01:57:25 +02:00
|
|
|
.onReceive(inspectorModel.$shouldUpdate) { value in
|
2020-07-18 11:34:04 +02:00
|
|
|
if value == true {
|
2020-07-18 15:21:59 +02:00
|
|
|
if inspectorModel.editedName.trimmingWhitespace.count > 0 {
|
2020-07-20 00:07:09 +02:00
|
|
|
(sidebarItem.feed as? Folder)?.rename(to: inspectorModel.editedName.trimmingWhitespace) { _ in }
|
2020-07-18 11:34:04 +02:00
|
|
|
}
|
|
|
|
presentationMode.wrappedValue.dismiss()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-07-19 01:57:25 +02:00
|
|
|
var folderHeader: some View {
|
|
|
|
HStack(alignment: .center) {
|
|
|
|
Spacer()
|
|
|
|
if let image = feedIconImageLoader.image {
|
|
|
|
IconImageView(iconImage: image)
|
|
|
|
.frame(width: 50, height: 50)
|
|
|
|
}
|
|
|
|
Spacer()
|
2020-08-13 16:21:31 +02:00
|
|
|
}.padding(.top, 20)
|
2020-07-19 01:57:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// MARK: Account Inspector
|
|
|
|
|
2020-07-18 11:34:04 +02:00
|
|
|
var AccountInspectorView: some View {
|
2020-08-13 16:21:31 +02:00
|
|
|
Form {
|
2020-07-19 01:57:25 +02:00
|
|
|
Section(header: accountHeader) {
|
|
|
|
TextField("", text: $inspectorModel.editedName)
|
|
|
|
Toggle("Active", isOn: $inspectorModel.accountIsActive)
|
2020-07-18 11:34:04 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
#if os(macOS)
|
|
|
|
HStack {
|
|
|
|
Spacer()
|
|
|
|
Button("Cancel", action: {
|
|
|
|
presentationMode.wrappedValue.dismiss()
|
2020-07-19 02:25:26 +02:00
|
|
|
}).keyboardShortcut(.cancelAction)
|
2020-07-18 13:31:56 +02:00
|
|
|
Button("Done", action: {
|
2020-07-18 15:21:59 +02:00
|
|
|
inspectorModel.shouldUpdate = true
|
|
|
|
}).keyboardShortcut(.defaultAction)
|
2020-07-18 11:34:04 +02:00
|
|
|
}.padding(.top)
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
.onAppear {
|
2020-07-18 15:21:59 +02:00
|
|
|
inspectorModel.configure(with: sidebarItem.represented as! Account)
|
|
|
|
}
|
2020-07-19 01:57:25 +02:00
|
|
|
.onReceive(inspectorModel.$shouldUpdate) { value in
|
2020-07-18 11:34:04 +02:00
|
|
|
if value == true {
|
2020-07-18 15:21:59 +02:00
|
|
|
if inspectorModel.editedName.trimmingWhitespace.count > 0 {
|
|
|
|
(sidebarItem.represented as? Account)?.name = inspectorModel.editedName
|
2020-07-18 11:34:04 +02:00
|
|
|
} else {
|
|
|
|
(sidebarItem.represented as? Account)?.name = nil
|
|
|
|
}
|
|
|
|
presentationMode.wrappedValue.dismiss()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-07-19 01:57:25 +02:00
|
|
|
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()
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2020-07-18 11:34:04 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|