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-08-10 02:01:16 +02:00
#if os ( macOS )
import AppKit
#endif
2020-06-28 21:21:43 +02:00
2020-08-13 18:04:39 +02:00
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-08-13 18:04:39 +02:00
@ StateObject private var sceneNavigationModel = SceneNavigationModel ( )
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-08-12 15:44:46 +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-25 10:40:04 +02:00
. onReceive ( sceneModel . $ accountSyncErrors ) { errors in
if errors . count = = 0 {
2020-08-13 18:04:39 +02:00
sceneNavigationModel . showAccountSyncErrorAlert = false
2020-07-25 10:40:04 +02:00
} else {
if errors . count > 1 {
2020-08-13 18:04:39 +02:00
sceneNavigationModel . showAccountSyncErrorAlert = true
2020-07-25 10:40:04 +02:00
} else {
2020-08-13 18:04:39 +02:00
sceneNavigationModel . sheetToShow = . fixCredentials
2020-07-25 10:40:04 +02:00
}
2020-07-16 03:06:29 +02:00
}
}
2020-08-13 18:04:39 +02:00
. sheet ( isPresented : $ sceneNavigationModel . showSheet ,
2020-07-25 10:40:04 +02:00
onDismiss : {
2020-08-13 18:04:39 +02:00
sceneNavigationModel . sheetToShow = . none
2020-07-25 10:40:04 +02:00
sceneModel . accountSyncErrors = [ ]
} ) {
2020-08-13 18:04:39 +02:00
if sceneNavigationModel . sheetToShow = = . web {
AddWebFeedView ( isPresented : $ sceneNavigationModel . showSheet )
2020-07-25 10:40:04 +02:00
}
2020-08-13 18:04:39 +02:00
if sceneNavigationModel . sheetToShow = = . folder {
AddFolderView ( isPresented : $ sceneNavigationModel . showSheet )
2020-07-25 10:40:04 +02:00
}
#if os ( iOS )
2020-08-13 18:04:39 +02:00
if sceneNavigationModel . sheetToShow = = . settings {
2020-07-25 10:40:04 +02:00
SettingsView ( )
}
#endif
2020-08-13 18:04:39 +02:00
if sceneNavigationModel . sheetToShow = = . fixCredentials {
2020-07-25 10:40:04 +02:00
FixAccountCredentialView ( accountSyncError : sceneModel . accountSyncErrors [ 0 ] )
}
2020-07-16 03:06:29 +02:00
}
2020-08-13 18:04:39 +02:00
. alert ( isPresented : $ sceneNavigationModel . showAccountSyncErrorAlert , content : {
2020-07-25 10:40:04 +02:00
#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 : {
2020-08-13 18:04:39 +02:00
sceneNavigationModel . sheetToShow = . settings
2020-07-25 10:40:04 +02:00
} )
} ) ,
secondaryButton : . cancel ( Text ( " Dismiss " ) ) )
#endif
} )
2020-07-07 23:05:26 +02:00
. toolbar {
#if os ( macOS )
2020-08-10 02:01:16 +02:00
ToolbarItem ( placement : . navigation ) {
Button {
NSApp . keyWindow ? . firstResponder ? . tryToPerform ( #selector ( NSSplitViewController . toggleSidebar ( _ : ) ) , with : nil )
} label : {
2020-08-10 02:36:31 +02:00
AppAssets . sidebarToggleImage
2020-08-10 02:01:16 +02:00
}
2020-08-10 02:31:10 +02:00
. help ( " Toggle Sidebar " )
2020-08-10 02:01:16 +02:00
}
2020-07-07 23:05:26 +02:00
ToolbarItem ( ) {
Menu {
2020-08-13 18:04:39 +02:00
Button ( " Add Web Feed " , action : { sceneNavigationModel . sheetToShow = . web } )
2020-07-07 23:05:26 +02:00
Button ( " Add Reddit Feed " , action : { } )
Button ( " Add Twitter Feed " , action : { } )
2020-08-13 18:04:39 +02:00
Button ( " Add Folder " , action : { sceneNavigationModel . 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
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
}
2020-08-10 02:01:16 +02:00
// T o o l b a r I t e m {
// M a c S e a r c h F i e l d ( )
// . f r a m e ( w i d t h : 2 0 0 )
// }
2020-07-07 23:05:26 +02:00
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 {
2020-08-13 18:04:39 +02:00
if sceneNavigationModel . showShareSheet {
SharingServiceView ( articles : sceneModel . selectedArticles , showing : $ sceneNavigationModel . showShareSheet )
2020-07-15 00:10:53 +02:00
. frame ( width : 20 , height : 20 )
}
Button {
2020-08-13 18:04:39 +02:00
sceneNavigationModel . showShareSheet = true
2020-07-15 00:10:53 +02:00
} 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
}
}