IceCubes/IceCubesApp/App/IceCubesApp.swift

182 lines
5.5 KiB
Swift
Raw Normal View History

2022-12-01 09:05:26 +01:00
import SwiftUI
import Timeline
import Network
import KeychainSwift
2022-12-22 10:53:36 +01:00
import Env
2022-12-24 14:55:04 +01:00
import DesignSystem
2023-01-07 13:44:13 +01:00
import QuickLook
import RevenueCat
2022-12-01 09:05:26 +01:00
@main
struct IceCubesApp: App {
2022-12-17 13:37:46 +01:00
public static let defaultServer = "mastodon.social"
2022-12-24 14:55:04 +01:00
2023-01-08 10:22:52 +01:00
@UIApplicationDelegateAdaptor private var appDelegate: AppDelegate
@Environment(\.scenePhase) private var scenePhase
2023-01-08 10:22:52 +01:00
@StateObject private var appAccountsManager = AppAccountsManager.shared
2023-01-01 18:31:23 +01:00
@StateObject private var currentInstance = CurrentInstance()
2022-12-22 11:19:56 +01:00
@StateObject private var currentAccount = CurrentAccount()
@StateObject private var userPreferences = UserPreferences()
@StateObject private var watcher = StreamWatcher()
2022-12-22 10:53:36 +01:00
@StateObject private var quickLook = QuickLook()
2022-12-24 14:55:04 +01:00
@StateObject private var theme = Theme()
2023-01-04 12:55:09 +01:00
@State private var selectedTab: Tab = .timeline
@State private var selectSidebarItem: Tab? = .timeline
2022-12-24 11:50:05 +01:00
@State private var popToRootTab: Tab = .other
private var availableTabs: [Tab] {
appAccountsManager.currentClient.isAuth ? Tab.loggedInTabs() : Tab.loggedOutTab()
}
2022-12-01 09:05:26 +01:00
var body: some Scene {
WindowGroup {
appView
2022-12-24 14:55:04 +01:00
.tint(theme.tintColor)
2022-12-22 11:19:56 +01:00
.onAppear {
2022-12-25 17:39:12 +01:00
setNewClientsInEnv(client: appAccountsManager.currentClient)
2022-12-29 10:39:34 +01:00
setBarsColor(color: theme.primaryBackgroundColor)
2023-01-07 13:44:13 +01:00
setupRevenueCat()
2023-01-08 10:22:52 +01:00
refreshPushSubs()
2022-12-22 11:19:56 +01:00
}
.preferredColorScheme(theme.selectedScheme == ColorScheme.dark ? .dark : .light)
2022-12-01 09:05:26 +01:00
.environmentObject(appAccountsManager)
.environmentObject(appAccountsManager.currentClient)
2022-12-22 10:53:36 +01:00
.environmentObject(quickLook)
2022-12-22 11:19:56 +01:00
.environmentObject(currentAccount)
2023-01-01 18:31:23 +01:00
.environmentObject(currentInstance)
.environmentObject(userPreferences)
2022-12-24 14:55:04 +01:00
.environmentObject(theme)
.environmentObject(watcher)
2023-01-08 10:22:52 +01:00
.environmentObject(PushNotifications.shared)
.quickLookPreview($quickLook.url, in: quickLook.urls)
2022-12-01 09:05:26 +01:00
}
.onChange(of: scenePhase, perform: { scenePhase in
2022-12-25 17:39:12 +01:00
handleScenePhase(scenePhase: scenePhase)
})
2022-12-29 10:39:34 +01:00
.onChange(of: appAccountsManager.currentClient) { newClient in
setNewClientsInEnv(client: newClient)
if newClient.isAuth {
watcher.watch(streams: [.user, .direct])
2022-12-29 10:39:34 +01:00
}
}
.onChange(of: theme.primaryBackgroundColor) { newValue in
setBarsColor(color: newValue)
}
2022-12-01 09:05:26 +01:00
}
2022-12-25 17:39:12 +01:00
@ViewBuilder
private var appView: some View {
if UIDevice.current.userInterfaceIdiom == .pad || UIDevice.current.userInterfaceIdiom == .mac {
splitView
} else {
tabBarView
}
}
private func badgeFor(tab: Tab) -> Int {
if tab == .notifications && selectedTab != tab {
return watcher.unreadNotificationsCount
} else if tab == .messages && selectedTab != tab {
return watcher.unreadMessagesCount
}
return 0
}
private var tabBarView: some View {
TabView(selection: .init(get: {
selectedTab
}, set: { newTab in
if newTab == selectedTab {
/// Stupid hack to trigger onChange binding in tab views.
popToRootTab = .other
DispatchQueue.main.asyncAfter(deadline: .now() + 0.01) {
2023-01-04 12:55:09 +01:00
popToRootTab = selectedTab
}
}
selectedTab = newTab
})) {
ForEach(availableTabs) { tab in
tab.makeContentView(popToRootTab: $popToRootTab)
.tabItem {
tab.label
}
.tag(tab)
.badge(badgeFor(tab: tab))
.toolbarBackground(theme.primaryBackgroundColor.opacity(0.50), for: .tabBar)
}
}
}
private var splitView: some View {
NavigationSplitView {
2023-01-04 12:55:09 +01:00
List(availableTabs, selection: $selectSidebarItem) { tab in
NavigationLink(value: tab) {
tab.label
}
}
.scrollContentBackground(.hidden)
.background(theme.secondaryBackgroundColor)
.navigationSplitViewColumnWidth(200)
} detail: {
2023-01-04 12:55:09 +01:00
selectSidebarItem?.makeContentView(popToRootTab: $popToRootTab)
}
}
2022-12-25 17:39:12 +01:00
private func setNewClientsInEnv(client: Client) {
currentAccount.setClient(client: client)
2023-01-01 18:31:23 +01:00
currentInstance.setClient(client: client)
2022-12-25 17:39:12 +01:00
watcher.setClient(client: client)
}
private func handleScenePhase(scenePhase: ScenePhase) {
switch scenePhase {
case .background:
watcher.stopWatching()
case .active:
watcher.watch(streams: [.user, .direct])
2022-12-25 17:39:12 +01:00
case .inactive:
break
default:
break
}
}
2022-12-29 10:39:34 +01:00
private func setBarsColor(color: Color) {
UINavigationBar.appearance().isTranslucent = true
UINavigationBar.appearance().barTintColor = UIColor(color)
}
2023-01-07 13:44:13 +01:00
private func setupRevenueCat() {
Purchases.logLevel = .error
Purchases.configure(withAPIKey: "appl_JXmiRckOzXXTsHKitQiicXCvMQi")
}
2023-01-08 10:22:52 +01:00
private func refreshPushSubs() {
PushNotifications.shared.requestPushNotifications()
Task {
await PushNotifications.shared.fetchSubscriptions(accounts: appAccountsManager.pushAccounts)
}
}
}
class AppDelegate: NSObject, UIApplicationDelegate {
func application(_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
return true
}
func application(_ application: UIApplication,
didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
PushNotifications.shared.pushToken = deviceToken
Task {
await PushNotifications.shared.updateSubscriptions(accounts: AppAccountsManager.shared.pushAccounts)
}
}
func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
print(error)
}
2022-12-01 09:05:26 +01:00
}