2019-06-11 23:59:16 +02:00
//
// S e t t i n g s V i e w . s w i f t
// N e t N e w s W i r e - i O S
//
// C r e a t e d b y M a u r i c e P a r k e r o n 6 / 1 1 / 1 9 .
// C o p y r i g h t © 2 0 1 9 R a n c h e r o S o f t w a r e . A l l r i g h t s r e s e r v e d .
//
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 {
List {
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 ( " ABOUT " ) ) {
Text ( " About NetNewsWire " )
2019-06-16 01:23:32 +02:00
PresentationButton ( Text ( " Website " ) , destination : SafariView ( url : URL ( string : " https://ranchero.com/netnewswire/ " ) ! ) )
PresentationButton ( Text ( " Github Repository " ) , destination : SafariView ( url : URL ( string : " https://github.com/brentsimmons/NetNewsWire " ) ! ) )
PresentationButton ( Text ( " Bug Tracker " ) , destination : SafariView ( url : URL ( string : " https://github.com/brentsimmons/NetNewsWire/issues " ) ! ) )
PresentationButton ( Text ( " Technotes " ) , destination : SafariView ( url : URL ( string : " https://github.com/brentsimmons/NetNewsWire/tree/master/Technotes " ) ! ) )
PresentationButton ( Text ( " How to Support NetNewsWire " ) , destination : SafariView ( url : URL ( string : " https://github.com/brentsimmons/NetNewsWire/blob/master/Technotes/HowToSupportNetNewsWire.markdown " ) ! ) )
2019-06-11 23:59:16 +02:00
Text ( " Add NetNewsWire News Feed " )
}
. foregroundColor ( . primary )
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-11 23:59:16 +02:00
}
. listStyle ( . grouped )
. 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 ] ( )
for account in viewModel . accounts {
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
}
buttons . append ( button )
}
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 ] ( )
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-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-17 14:20:39 +02:00
// MARK: V i e w M o d e l
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 {
}
}
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