2023-12-29 11:17:37 +01:00
// M a d e b y L u m a a
import Foundation
import SwiftUI
@ Observable
2024-01-02 14:23:36 +01:00
public class Navigator : ObservableObject {
2023-12-29 11:17:37 +01:00
public var path : [ RouterDestination ] = [ ]
public var presentedSheet : SheetDestination ?
public var selectedTab : TabDestination = . timeline
public func navigate ( to : RouterDestination ) {
path . append ( to )
2024-01-02 14:23:36 +01:00
print ( " appended view " )
2023-12-29 11:17:37 +01:00
}
2024-01-28 17:51:50 +01:00
public func removeSettingsOfPath ( ) {
self . path = self . path . filter ( { ! RouterDestination . allSettings . contains ( $0 ) } )
}
2023-12-29 11:17:37 +01:00
}
public enum TabDestination : Identifiable {
case timeline
case search
case activity
case profile
public var id : String {
switch self {
case . timeline :
return " timeline "
case . search :
return " search "
case . activity :
return " activity "
case . profile :
return " profile "
}
}
}
public enum SheetDestination : Identifiable {
case welcome
2024-01-27 08:56:22 +01:00
case shop
2023-12-29 11:17:37 +01:00
case mastodonLogin ( logged : Binding < Bool > )
2024-01-26 14:10:17 +01:00
case post ( content : String = " " , replyId : String ? = nil , editId : String ? = nil )
2024-01-21 13:08:06 +01:00
case safari ( url : URL )
2024-01-26 14:10:17 +01:00
case shareImage ( image : UIImage , status : Status )
2023-12-29 11:17:37 +01:00
public var id : String {
switch self {
case . welcome :
return " welcome "
2024-01-27 08:56:22 +01:00
case . shop :
return " shop "
2023-12-29 11:17:37 +01:00
case . mastodonLogin :
return " login "
case . post :
return " post "
2024-01-21 13:08:06 +01:00
case . safari :
return " safari "
2024-01-21 16:34:26 +01:00
case . shareImage :
return " shareImage "
2023-12-29 11:17:37 +01:00
}
}
public var isCover : Bool {
switch self {
case . welcome :
return true
2024-01-27 08:56:22 +01:00
case . shop :
return true
2023-12-29 11:17:37 +01:00
case . mastodonLogin :
return false
case . post :
return false
2024-01-21 13:08:06 +01:00
case . safari :
return false
2024-01-21 16:34:26 +01:00
case . shareImage :
return false
2023-12-29 11:17:37 +01:00
}
}
}
public enum RouterDestination : Hashable {
case settings
case privacy
2024-01-04 22:19:35 +01:00
case appearence
2023-12-29 11:17:37 +01:00
case account ( acc : Account )
2024-01-10 17:45:41 +01:00
case post ( status : Status )
2023-12-30 20:59:09 +01:00
case about
2023-12-29 11:17:37 +01:00
}
2024-01-28 17:51:50 +01:00
extension RouterDestination {
static let allSettings : [ RouterDestination ] = [ . settings , . privacy , . about , . appearence ]
}
2023-12-29 11:17:37 +01:00
extension View {
2024-01-02 14:23:36 +01:00
func withAppRouter ( _ navigator : Navigator ) -> some View {
2023-12-29 11:17:37 +01:00
navigationDestination ( for : RouterDestination . self ) { destination in
switch destination {
case . settings :
2024-01-02 14:23:36 +01:00
SettingsView ( navigator : navigator )
2023-12-29 11:17:37 +01:00
case . privacy :
PrivacyView ( )
2024-01-04 22:19:35 +01:00
case . appearence :
AppearenceView ( )
2023-12-29 11:17:37 +01:00
case . account ( let acc ) :
2024-01-21 13:08:06 +01:00
AccountView ( account : acc )
2024-01-10 17:45:41 +01:00
case . post ( let status ) :
PostDetailsView ( status : status )
2023-12-30 20:59:09 +01:00
case . about :
AboutView ( )
2023-12-29 11:17:37 +01:00
}
}
}
func withSheets ( sheetDestination : Binding < SheetDestination ? > ) -> some View {
sheet ( item : sheetDestination ) { destination in
viewRepresentation ( destination : destination , isCover : false )
}
}
func withCovers ( sheetDestination : Binding < SheetDestination ? > ) -> some View {
fullScreenCover ( item : sheetDestination ) { destination in
viewRepresentation ( destination : destination , isCover : true )
}
}
private func viewRepresentation ( destination : SheetDestination , isCover : Bool ) -> some View {
Group {
if destination . isCover {
switch destination {
case . welcome :
ConnectView ( )
2024-01-27 08:56:22 +01:00
case . shop :
ShopView ( )
2023-12-29 11:17:37 +01:00
default :
2024-01-27 08:56:22 +01:00
EmptySheetView ( destId : destination . id )
2023-12-29 11:17:37 +01:00
}
} else {
switch destination {
2024-01-26 14:10:17 +01:00
case . post ( let content , let replyId , let editId ) :
2024-01-02 14:23:36 +01:00
NavigationStack {
2024-01-26 14:10:17 +01:00
PostingView ( initialString : content , replyId : replyId , editId : editId )
2024-01-02 14:23:36 +01:00
. tint ( Color ( uiColor : UIColor . label ) )
}
2023-12-29 11:17:37 +01:00
case let . mastodonLogin ( logged ) :
AddInstanceView ( logged : logged )
. tint ( Color . accentColor )
2024-01-21 13:08:06 +01:00
case let . safari ( url ) :
SfSafariView ( url : url )
2024-01-26 14:10:17 +01:00
. ignoresSafeArea ( )
case let . shareImage ( image , status ) :
ShareSheet ( image : image , status : status )
2023-12-29 11:17:37 +01:00
default :
2024-01-27 08:56:22 +01:00
EmptySheetView ( destId : destination . id )
2023-12-29 11:17:37 +01:00
}
}
}
}
}
2024-01-27 08:56:22 +01:00
private struct EmptySheetView : View {
var destId : String = " ??? "
2024-01-28 17:51:50 +01:00
let str : String = . init ( localized : " about.version- \( AppInfo . appVersion ) " )
2024-01-27 08:56:22 +01:00
var body : some View {
ZStack {
2024-01-28 17:51:50 +01:00
ContentUnavailableView ( String ( " Missing view for \" \( destId . isEmpty ? " [EMPTY_DEST_ID] " : destId ) \" " ) , systemImage : " exclamationmark.triangle.fill " , description : Text ( String ( " Please notify Lumaa as soon as possible! \n \n \( str ) " ) ) )
2024-01-27 08:56:22 +01:00
. ignoresSafeArea ( )
. background ( Color . red . gradient )
. foregroundStyle ( . white )
}
}
}