2019-06-11 23:59:16 +02:00
|
|
|
//
|
|
|
|
// SettingsView.swift
|
|
|
|
// NetNewsWire-iOS
|
|
|
|
//
|
|
|
|
// Created by Maurice Parker on 6/11/19.
|
|
|
|
// Copyright © 2019 Ranchero Software. All rights reserved.
|
|
|
|
//
|
|
|
|
|
|
|
|
import SwiftUI
|
2019-06-13 21:30:56 +02:00
|
|
|
import Combine
|
2019-06-11 23:59:16 +02:00
|
|
|
import Account
|
|
|
|
|
|
|
|
struct SettingsView : View {
|
2019-06-13 21:30:56 +02:00
|
|
|
@ObjectBinding var viewModel: ViewModel
|
2019-06-16 18:19:15 +02:00
|
|
|
@State var subscriptionsImportAccounts: ActionSheet? = nil
|
|
|
|
@State var subscriptionsImportDocumentPicker: Modal? = nil
|
|
|
|
@State var subscriptionsExportAccounts: ActionSheet? = nil
|
|
|
|
@State var subscriptionsExportDocumentPicker: Modal? = nil
|
2019-06-16 01:19:20 +02:00
|
|
|
|
2019-06-11 23:59:16 +02:00
|
|
|
var body: some View {
|
|
|
|
NavigationView {
|
2019-06-18 23:54:51 +02:00
|
|
|
Form {
|
2019-06-11 23:59:16 +02:00
|
|
|
|
|
|
|
Section(header: Text("ACCOUNTS")) {
|
|
|
|
ForEach(viewModel.accounts.identified(by: \.self)) { account in
|
2019-06-13 21:30:56 +02:00
|
|
|
NavigationButton(destination: SettingsDetailAccountView(viewModel: SettingsDetailAccountView.ViewModel(account)), isDetail: false) {
|
|
|
|
Text(verbatim: account.nameForDisplay)
|
|
|
|
}
|
2019-06-11 23:59:16 +02:00
|
|
|
}
|
|
|
|
NavigationButton(destination: SettingsAddAccountView(), isDetail: false) {
|
|
|
|
Text("Add Account")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Section(header: Text("TIMELINE")) {
|
|
|
|
Toggle(isOn: $viewModel.sortOldestToNewest) {
|
|
|
|
Text("Sort Oldest to Newest")
|
|
|
|
}
|
|
|
|
Stepper(value: $viewModel.timelineNumberOfLines, in: 2...6) {
|
|
|
|
Text("Number of Text Lines: \(viewModel.timelineNumberOfLines)")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Section(header: Text("DATABASE")) {
|
|
|
|
Picker(selection: $viewModel.refreshInterval, label: Text("Refresh Interval")) {
|
|
|
|
ForEach(RefreshInterval.allCases.identified(by: \.self)) { interval in
|
|
|
|
Text(interval.description()).tag(interval)
|
|
|
|
}
|
|
|
|
}
|
2019-06-16 01:19:20 +02:00
|
|
|
Button(action: {
|
2019-06-16 18:19:15 +02:00
|
|
|
self.subscriptionsImportAccounts = self.createSubscriptionsImportAccounts
|
2019-06-16 01:19:20 +02:00
|
|
|
}) {
|
|
|
|
Text("Import Subscriptions...")
|
|
|
|
}
|
2019-06-16 18:19:15 +02:00
|
|
|
.presentation(subscriptionsImportAccounts)
|
|
|
|
.presentation(subscriptionsImportDocumentPicker)
|
2019-06-16 01:19:20 +02:00
|
|
|
Button(action: {
|
2019-06-16 18:19:15 +02:00
|
|
|
self.subscriptionsExportAccounts = self.createSubscriptionsExportAccounts
|
2019-06-16 01:19:20 +02:00
|
|
|
}) {
|
|
|
|
Text("Export Subscriptions...")
|
|
|
|
}
|
2019-06-16 18:19:15 +02:00
|
|
|
.presentation(subscriptionsExportAccounts)
|
|
|
|
.presentation(subscriptionsExportDocumentPicker)
|
2019-06-11 23:59:16 +02:00
|
|
|
}
|
2019-06-16 01:19:20 +02:00
|
|
|
.foregroundColor(.primary)
|
|
|
|
|
2019-06-19 00:38:20 +02:00
|
|
|
Section(header: Text("ABOUT"), footer: buildFooter) {
|
|
|
|
Text("About NetNewsWire")
|
|
|
|
PresentationButton(destination: SafariView(url: URL(string: "https://ranchero.com/netnewswire/")!)) {
|
|
|
|
Text("Website")
|
|
|
|
}
|
|
|
|
PresentationButton(destination: SafariView(url: URL(string: "https://github.com/brentsimmons/NetNewsWire")!)) {
|
|
|
|
Text("Github Repository")
|
|
|
|
}
|
|
|
|
PresentationButton(destination: SafariView(url: URL(string: "https://github.com/brentsimmons/NetNewsWire/issues")!)) {
|
|
|
|
Text("Bug Tracker")
|
|
|
|
}
|
|
|
|
PresentationButton(destination: SafariView(url: URL(string: "https://github.com/brentsimmons/NetNewsWire/tree/master/Technotes")!)) {
|
|
|
|
Text("Technotes")
|
|
|
|
}
|
|
|
|
PresentationButton(destination: SafariView(url: URL(string: "https://github.com/brentsimmons/NetNewsWire/blob/master/Technotes/HowToSupportNetNewsWire.markdown")!)) {
|
|
|
|
Text("How to Support NetNewsWire")
|
|
|
|
}
|
|
|
|
Text("Add NetNewsWire News Feed")
|
|
|
|
}
|
|
|
|
.foregroundColor(.primary)
|
|
|
|
|
2019-06-11 23:59:16 +02:00
|
|
|
}
|
|
|
|
.navigationBarTitle(Text("Settings"), displayMode: .inline)
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
2019-06-13 21:30:56 +02:00
|
|
|
|
2019-06-16 18:19:15 +02:00
|
|
|
var createSubscriptionsImportAccounts: ActionSheet {
|
2019-06-16 01:19:20 +02:00
|
|
|
var buttons = [ActionSheet.Button]()
|
2019-06-20 00:50:32 +02:00
|
|
|
|
2019-06-17 22:50:17 +02:00
|
|
|
for account in viewModel.activeAccounts {
|
2019-06-20 00:50:32 +02:00
|
|
|
if !account.isOPMLImportSupported {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
2019-06-16 01:19:20 +02:00
|
|
|
let button = ActionSheet.Button.default(Text(verbatim: account.nameForDisplay)) {
|
2019-06-16 18:19:15 +02:00
|
|
|
self.subscriptionsImportAccounts = nil
|
|
|
|
self.subscriptionsImportDocumentPicker = Modal(SettingsSubscriptionsImportDocumentPickerView(account: account))
|
2019-06-16 01:19:20 +02:00
|
|
|
}
|
2019-06-20 00:50:32 +02:00
|
|
|
|
2019-06-16 01:19:20 +02:00
|
|
|
buttons.append(button)
|
|
|
|
}
|
2019-06-20 00:50:32 +02:00
|
|
|
|
2019-06-16 18:19:15 +02:00
|
|
|
buttons.append(.cancel { self.subscriptionsImportAccounts = nil })
|
2019-06-16 01:19:20 +02:00
|
|
|
return ActionSheet(title: Text("Import Subscriptions..."), message: Text("Select the account to import your OPML file into."), buttons: buttons)
|
|
|
|
}
|
|
|
|
|
2019-06-16 18:19:15 +02:00
|
|
|
var createSubscriptionsExportAccounts: ActionSheet {
|
2019-06-16 01:19:20 +02:00
|
|
|
var buttons = [ActionSheet.Button]()
|
2019-06-20 00:50:32 +02:00
|
|
|
|
2019-06-16 01:19:20 +02:00
|
|
|
for account in viewModel.accounts {
|
|
|
|
let button = ActionSheet.Button.default(Text(verbatim: account.nameForDisplay)) {
|
2019-06-16 18:19:15 +02:00
|
|
|
self.subscriptionsExportAccounts = nil
|
|
|
|
self.subscriptionsExportDocumentPicker = Modal(SettingsSubscriptionsExportDocumentPickerView(account: account))
|
2019-06-16 01:19:20 +02:00
|
|
|
}
|
|
|
|
buttons.append(button)
|
|
|
|
}
|
2019-06-20 00:50:32 +02:00
|
|
|
|
2019-06-16 18:19:15 +02:00
|
|
|
buttons.append(.cancel { self.subscriptionsExportAccounts = nil })
|
2019-06-16 01:19:20 +02:00
|
|
|
return ActionSheet(title: Text("Export Subscriptions..."), message: Text("Select the account to export out of."), buttons: buttons)
|
|
|
|
}
|
|
|
|
|
2019-06-19 00:38:20 +02:00
|
|
|
var buildFooter: some View {
|
|
|
|
return Text(verbatim: "\(Bundle.main.appName) v \(Bundle.main.versionNumber) (Build \(Bundle.main.buildNumber))")
|
|
|
|
.font(.footnote)
|
|
|
|
.foregroundColor(.secondary)
|
|
|
|
}
|
|
|
|
|
2019-06-17 14:20:39 +02:00
|
|
|
// MARK: ViewModel
|
|
|
|
|
2019-06-13 21:30:56 +02:00
|
|
|
class ViewModel: BindableObject {
|
|
|
|
|
|
|
|
let didChange = PassthroughSubject<ViewModel, Never>()
|
|
|
|
|
|
|
|
init() {
|
|
|
|
NotificationCenter.default.addObserver(self, selector: #selector(accountsDidChange(_:)), name: .AccountsDidChange, object: nil)
|
|
|
|
NotificationCenter.default.addObserver(self, selector: #selector(displayNameDidChange(_:)), name: .DisplayNameDidChange, object: nil)
|
|
|
|
}
|
|
|
|
|
|
|
|
var accounts: [Account] {
|
|
|
|
get {
|
|
|
|
return AccountManager.shared.sortedAccounts
|
|
|
|
}
|
|
|
|
set {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-06-17 22:50:17 +02:00
|
|
|
var activeAccounts: [Account] {
|
|
|
|
get {
|
|
|
|
return AccountManager.shared.sortedActiveAccounts
|
|
|
|
}
|
|
|
|
set {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-06-13 21:30:56 +02:00
|
|
|
var sortOldestToNewest: Bool {
|
|
|
|
get {
|
|
|
|
return AppDefaults.timelineSortDirection == .orderedDescending
|
|
|
|
}
|
|
|
|
set {
|
|
|
|
if newValue == true {
|
|
|
|
AppDefaults.timelineSortDirection = .orderedDescending
|
|
|
|
} else {
|
|
|
|
AppDefaults.timelineSortDirection = .orderedAscending
|
|
|
|
}
|
|
|
|
didChange.send(self)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
var timelineNumberOfLines: Int {
|
|
|
|
get {
|
|
|
|
return AppDefaults.timelineNumberOfLines
|
|
|
|
}
|
|
|
|
set {
|
|
|
|
AppDefaults.timelineNumberOfLines = newValue
|
|
|
|
didChange.send(self)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
var refreshInterval: RefreshInterval {
|
|
|
|
get {
|
|
|
|
return AppDefaults.refreshInterval
|
|
|
|
}
|
|
|
|
set {
|
|
|
|
AppDefaults.refreshInterval = newValue
|
|
|
|
didChange.send(self)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@objc func accountsDidChange(_ notification: Notification) {
|
|
|
|
didChange.send(self)
|
|
|
|
}
|
|
|
|
|
|
|
|
@objc func displayNameDidChange(_ notification: Notification) {
|
|
|
|
didChange.send(self)
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2019-06-11 23:59:16 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
#if DEBUG
|
|
|
|
struct SettingsView_Previews : PreviewProvider {
|
|
|
|
static var previews: some View {
|
2019-06-13 21:30:56 +02:00
|
|
|
SettingsView(viewModel: SettingsView.ViewModel())
|
2019-06-11 23:59:16 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|