2020-06-28 21:21:43 +02:00
//
// S c e n e N a v i g a t i o n V i e w . s w i f t
// N e t N e w s W i r e
//
// 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 / 2 8 / 2 0 .
// C o p y r i g h t © 2 0 2 0 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
2020-07-16 03:09:11 +02:00
import Account
2020-06-28 21:21:43 +02:00
struct SceneNavigationView : View {
2020-07-07 23:05:26 +02:00
@ StateObject private var sceneModel = SceneModel ( )
2020-07-15 00:10:53 +02:00
@ State private var showSheet = false
@ State private var showShareSheet = false
2020-07-25 10:40:04 +02:00
@ State private var sheetToShow : SidebarSheets = . none
@ State private var showAccountSyncErrorAlert = false // m u l t i p l e s y n c e r r o r s
2020-07-07 23:05:26 +02:00
2020-06-29 16:06:00 +02:00
#if os ( iOS )
@ Environment ( \ . horizontalSizeClass ) private var horizontalSizeClass
#endif
var body : some View {
2020-06-28 21:21:43 +02:00
NavigationView {
#if os ( macOS )
2020-07-06 08:32:43 +02:00
SidebarContainerView ( )
2020-06-29 23:58:10 +02:00
. frame ( minWidth : 100 , idealWidth : 150 , maxHeight : . infinity )
2020-06-28 21:21:43 +02:00
#else
2020-07-06 08:32:43 +02:00
SidebarContainerView ( )
2020-06-28 21:21:43 +02:00
#endif
2020-06-29 16:06:00 +02:00
#if os ( iOS )
if horizontalSizeClass != . compact {
2020-07-18 11:35:44 +02:00
TimelineContainerView ( )
2020-06-29 16:06:00 +02:00
}
#else
2020-07-18 11:35:44 +02:00
TimelineContainerView ( )
2020-06-29 16:06:00 +02:00
#endif
2020-06-28 21:21:43 +02:00
2020-07-18 11:35:44 +02:00
ArticleContainerView ( )
2020-06-28 21:21:43 +02:00
}
2020-07-07 23:05:26 +02:00
. environmentObject ( sceneModel )
. onAppear {
sceneModel . startup ( )
}
2020-07-09 20:31:37 +02:00
. onChange ( of : sheetToShow ) { value in
value != . none ? ( showSheet = true ) : ( showSheet = false )
2020-07-07 23:05:26 +02:00
}
2020-07-25 10:40:04 +02:00
. onReceive ( sceneModel . $ accountSyncErrors ) { errors in
if errors . count = = 0 {
showAccountSyncErrorAlert = false
} else {
if errors . count > 1 {
showAccountSyncErrorAlert = true
} else {
sheetToShow = . fixCredentials
}
2020-07-16 03:06:29 +02:00
}
}
2020-07-25 10:40:04 +02:00
. sheet ( isPresented : $ showSheet ,
onDismiss : {
sheetToShow = . none
sceneModel . accountSyncErrors = [ ]
} ) {
if sheetToShow = = . web {
AddWebFeedView ( )
}
if sheetToShow = = . folder {
AddFolderView ( )
}
#if os ( iOS )
if sheetToShow = = . settings {
SettingsView ( )
}
#endif
if sheetToShow = = . fixCredentials {
FixAccountCredentialView ( accountSyncError : sceneModel . accountSyncErrors [ 0 ] )
}
2020-07-16 03:06:29 +02:00
}
2020-07-25 10:40:04 +02:00
. alert ( isPresented : $ showAccountSyncErrorAlert , content : {
#if os ( macOS )
return Alert ( title : Text ( " Account Sync Error " ) ,
message : Text ( " The following accounts failed to sync: " ) + Text ( sceneModel . accountSyncErrors . map ( { $0 . account . nameForDisplay } ) . joined ( separator : " , " ) ) + Text ( " . You can update credentials in Preferences " ) ,
dismissButton : . default ( Text ( " Dismiss " ) ) )
#else
return Alert ( title : Text ( " Account Sync Error " ) ,
message : Text ( " The following accounts failed to sync: " ) + Text ( sceneModel . accountSyncErrors . map ( { $0 . account . nameForDisplay } ) . joined ( separator : " , " ) ) + Text ( " . You can update credentials in Settings " ) ,
primaryButton : . default ( Text ( " Show Settings " ) , action : {
DispatchQueue . main . asyncAfter ( deadline : . now ( ) + 0.5 , execute : {
sheetToShow = . settings
} )
} ) ,
secondaryButton : . cancel ( Text ( " Dismiss " ) ) )
#endif
} )
2020-07-07 23:05:26 +02:00
. toolbar {
#if os ( macOS )
ToolbarItem ( ) {
Menu {
2020-07-09 20:31:37 +02:00
Button ( " Add Web Feed " , action : { sheetToShow = . web } )
2020-07-07 23:05:26 +02:00
Button ( " Add Reddit Feed " , action : { } )
Button ( " Add Twitter Feed " , action : { } )
2020-07-09 20:31:37 +02:00
Button ( " Add Folder " , action : { sheetToShow = . folder } )
2020-07-07 23:05:26 +02:00
} label : {
AppAssets . addMenuImage
}
}
ToolbarItem {
2020-07-14 00:24:40 +02:00
Button {
2020-07-25 10:40:04 +02:00
// A c c o u n t M a n a g e r . s h a r e d . r e f r e s h A l l ( e r r o r H a n d l e r : h a n d l e R e f r e s h E r r o r )
AccountManager . shared . refreshAll ( completion : nil )
2020-07-14 00:24:40 +02:00
} label : {
2020-07-07 23:05:26 +02:00
AppAssets . refreshImage
2020-07-14 00:24:40 +02:00
}
. help ( " Refresh " ) . padding ( . trailing , 40 )
2020-07-07 23:05:26 +02:00
}
ToolbarItem {
2020-07-14 00:24:40 +02:00
Button {
2020-07-18 11:58:46 +02:00
sceneModel . markAllAsRead ( )
2020-07-14 00:24:40 +02:00
} label : {
2020-07-20 00:44:41 +02:00
AppAssets . markAllAsReadImagePNG
. offset ( y : 7 )
2020-07-14 00:24:40 +02:00
}
. disabled ( sceneModel . markAllAsReadButtonState = = nil )
. help ( " Mark All as Read " )
2020-07-07 23:05:26 +02:00
}
ToolbarItem {
MacSearchField ( )
. frame ( width : 200 )
}
ToolbarItem {
2020-07-14 00:24:40 +02:00
Button {
2020-07-19 20:28:22 +02:00
sceneModel . goToNextUnread ( )
2020-07-14 00:24:40 +02:00
} label : {
2020-07-07 23:05:26 +02:00
AppAssets . nextUnreadArticleImage
2020-07-14 00:24:40 +02:00
}
. disabled ( sceneModel . nextUnreadButtonState = = nil )
. help ( " Go to Next Unread " ) . padding ( . trailing , 40 )
2020-07-07 23:05:26 +02:00
}
ToolbarItem {
2020-07-14 00:24:40 +02:00
Button {
sceneModel . toggleReadStatusForSelectedArticles ( )
} label : {
2020-07-13 23:26:53 +02:00
if sceneModel . readButtonState ? ? false {
2020-07-10 01:44:51 +02:00
AppAssets . readClosedImage
} else {
AppAssets . readOpenImage
}
2020-07-14 00:24:40 +02:00
}
. disabled ( sceneModel . readButtonState = = nil )
2020-07-13 23:26:53 +02:00
. help ( sceneModel . readButtonState ? ? false ? " Mark as Unread " : " Mark as Read " )
2020-07-07 23:05:26 +02:00
}
ToolbarItem {
2020-07-14 00:24:40 +02:00
Button {
sceneModel . toggleStarredStatusForSelectedArticles ( )
} label : {
2020-07-13 23:26:53 +02:00
if sceneModel . starButtonState ? ? false {
2020-07-10 01:44:51 +02:00
AppAssets . starClosedImage
} else {
AppAssets . starOpenImage
}
2020-07-14 00:24:40 +02:00
}
. disabled ( sceneModel . starButtonState = = nil )
2020-07-13 23:26:53 +02:00
. help ( sceneModel . starButtonState ? ? false ? " Mark as Unstarred " : " Mark as Starred " )
2020-07-07 23:05:26 +02:00
}
2020-07-09 00:34:35 +02:00
ToolbarItem {
2020-07-14 00:24:40 +02:00
Button {
} label : {
2020-07-09 00:34:35 +02:00
AppAssets . articleExtractorOff
2020-07-14 00:24:40 +02:00
}
. disabled ( sceneModel . extractorButtonState = = nil )
. help ( " Show Reader View " )
2020-07-09 00:34:35 +02:00
}
2020-07-07 23:05:26 +02:00
ToolbarItem {
2020-07-14 00:24:40 +02:00
Button {
2020-07-18 03:08:49 +02:00
sceneModel . openSelectedArticleInBrowser ( )
2020-07-14 00:24:40 +02:00
} label : {
2020-07-07 23:05:26 +02:00
AppAssets . openInBrowserImage
2020-07-14 00:24:40 +02:00
}
. disabled ( sceneModel . openInBrowserButtonState = = nil )
. help ( " Open in Browser " )
2020-07-07 23:05:26 +02:00
}
ToolbarItem {
2020-07-15 00:10:53 +02:00
ZStack {
if showShareSheet {
SharingServiceView ( articles : sceneModel . selectedArticles , showing : $ showShareSheet )
. frame ( width : 20 , height : 20 )
}
Button {
showShareSheet = true
} label : {
AppAssets . shareImage
}
2020-07-14 00:24:40 +02:00
}
. disabled ( sceneModel . shareButtonState = = nil )
. help ( " Share " )
2020-07-07 23:05:26 +02:00
}
#endif
}
2020-06-28 21:21:43 +02:00
}
2020-07-16 03:09:11 +02:00
2020-06-28 21:21:43 +02:00
}
struct NavigationView_Previews : PreviewProvider {
static var previews : some View {
2020-06-29 00:43:20 +02:00
SceneNavigationView ( )
2020-06-29 04:17:00 +02:00
. environmentObject ( SceneModel ( ) )
2020-06-28 21:21:43 +02:00
}
}