IceCubesApp/IceCubesApp/App/IceCubesApp.swift

190 lines
5.8 KiB
Swift
Raw Normal View History

2023-01-17 10:36:01 +00:00
import Account
import AppAccount
2023-01-09 17:52:53 +00:00
import AVFoundation
2022-12-24 13:55:04 +00:00
import DesignSystem
2023-01-17 10:36:01 +00:00
import Env
import KeychainSwift
import Network
2023-01-07 12:44:13 +00:00
import RevenueCat
2023-01-17 10:36:01 +00:00
import SwiftUI
import Timeline
2022-12-01 08:05:26 +00:00
@main
2023-01-17 10:36:01 +00:00
struct IceCubesApp: App {
2023-01-08 09:22:52 +00:00
@UIApplicationDelegateAdaptor private var appDelegate: AppDelegate
2023-01-17 10:36:01 +00:00
@Environment(\.scenePhase) private var scenePhase
2023-01-08 09:22:52 +00:00
@StateObject private var appAccountsManager = AppAccountsManager.shared
@StateObject private var currentInstance = CurrentInstance.shared
@StateObject private var currentAccount = CurrentAccount.shared
@StateObject private var userPreferences = UserPreferences.shared
@StateObject private var watcher = StreamWatcher()
2022-12-22 09:53:36 +00:00
@StateObject private var quickLook = QuickLook()
@StateObject private var theme = Theme.shared
2023-01-17 10:36:01 +00:00
2023-01-04 11:55:09 +00:00
@State private var selectedTab: Tab = .timeline
@State private var selectSidebarItem: Tab? = .timeline
2022-12-24 10:50:05 +00:00
@State private var popToRootTab: Tab = .other
2023-01-16 18:51:05 +00:00
@State private var sideBarLoadedTabs: [Tab] = []
2023-01-17 10:36:01 +00:00
private var availableTabs: [Tab] {
appAccountsManager.currentClient.isAuth ? Tab.loggedInTabs() : Tab.loggedOutTab()
}
2023-01-17 10:36:01 +00:00
2022-12-01 08:05:26 +00:00
var body: some Scene {
WindowGroup {
appView
2023-01-17 10:36:01 +00:00
.applyTheme(theme)
.onAppear {
setNewClientsInEnv(client: appAccountsManager.currentClient)
setupRevenueCat()
refreshPushSubs()
}
.environmentObject(appAccountsManager)
.environmentObject(appAccountsManager.currentClient)
.environmentObject(quickLook)
.environmentObject(currentAccount)
.environmentObject(currentInstance)
.environmentObject(userPreferences)
.environmentObject(theme)
.environmentObject(watcher)
.environmentObject(PushNotificationsService.shared)
.sheet(item: $quickLook.url, content: { url in
QuickLookPreview(selectedURL: url, urls: quickLook.urls)
.edgesIgnoringSafeArea(.bottom)
})
2022-12-01 08:05:26 +00:00
}
.onChange(of: scenePhase) { scenePhase in
2022-12-25 16:39:12 +00:00
handleScenePhase(scenePhase: scenePhase)
}
2022-12-29 09:39:34 +00:00
.onChange(of: appAccountsManager.currentClient) { newClient in
setNewClientsInEnv(client: newClient)
if newClient.isAuth {
watcher.watch(streams: [.user, .direct])
2022-12-29 09:39:34 +00:00
}
}
2022-12-01 08:05:26 +00:00
}
2023-01-17 10:36:01 +00:00
@ViewBuilder
private var appView: some View {
if UIDevice.current.userInterfaceIdiom == .pad || UIDevice.current.userInterfaceIdiom == .mac {
2023-01-16 13:40:23 +00:00
sidebarView
} else {
tabBarView
}
}
2023-01-17 10:36:01 +00:00
private func badgeFor(tab: Tab) -> Int {
if tab == .notifications && selectedTab != tab {
2023-01-09 17:52:53 +00:00
return watcher.unreadNotificationsCount + userPreferences.pushNotificationsCount
}
return 0
}
2023-01-17 10:36:01 +00:00
2023-01-16 13:40:23 +00:00
private var sidebarView: some View {
2023-01-16 18:51:05 +00:00
SideBarView(selectedTab: $selectedTab,
popToRootTab: $popToRootTab,
2023-01-16 20:15:33 +00:00
tabs: availableTabs) {
2023-01-16 18:51:05 +00:00
ZStack {
2023-01-16 20:15:33 +00:00
if let account = currentAccount.account, selectedTab == .profile {
AccountDetailView(account: account)
}
2023-01-16 13:40:23 +00:00
ForEach(availableTabs) { tab in
2023-01-16 18:51:05 +00:00
if tab == selectedTab || sideBarLoadedTabs.contains(tab) {
tab
.makeContentView(popToRootTab: $popToRootTab)
.opacity(tab == selectedTab ? 1 : 0)
.id(tab)
.onAppear {
if !sideBarLoadedTabs.contains(tab) {
sideBarLoadedTabs.append(tab)
}
2023-01-16 13:40:23 +00:00
}
2023-01-16 18:51:05 +00:00
} else {
EmptyView()
2023-01-16 13:40:23 +00:00
}
}
}
}
}
2023-01-17 10:36:01 +00:00
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 11:55:09 +00: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)
}
}
}
2023-01-17 10:36:01 +00:00
2022-12-25 16:39:12 +00:00
private func setNewClientsInEnv(client: Client) {
currentAccount.setClient(client: client)
2023-01-01 17:31:23 +00:00
currentInstance.setClient(client: client)
2023-01-09 18:47:54 +00:00
userPreferences.setClient(client: client)
2022-12-25 16:39:12 +00:00
watcher.setClient(client: client)
}
2023-01-17 10:36:01 +00:00
2022-12-25 16:39:12 +00:00
private func handleScenePhase(scenePhase: ScenePhase) {
switch scenePhase {
case .background:
watcher.stopWatching()
case .active:
watcher.watch(streams: [.user, .direct])
2023-01-09 17:52:53 +00:00
UIApplication.shared.applicationIconBadgeNumber = 0
2023-01-09 18:47:54 +00:00
Task {
await userPreferences.refreshServerPreferences()
}
2022-12-25 16:39:12 +00:00
case .inactive:
break
default:
break
}
}
2023-01-17 10:36:01 +00:00
2023-01-07 12:44:13 +00:00
private func setupRevenueCat() {
Purchases.logLevel = .error
Purchases.configure(withAPIKey: "appl_JXmiRckOzXXTsHKitQiicXCvMQi")
}
2023-01-17 10:36:01 +00:00
2023-01-08 09:22:52 +00:00
private func refreshPushSubs() {
2023-01-08 13:16:43 +00:00
PushNotificationsService.shared.requestPushNotifications()
2023-01-08 09:22:52 +00:00
}
}
class AppDelegate: NSObject, UIApplicationDelegate {
2023-01-17 10:36:01 +00:00
func application(_: UIApplication,
didFinishLaunchingWithOptions _: [UIApplication.LaunchOptionsKey: Any]? = nil) -> Bool
{
2023-01-09 17:52:53 +00:00
try? AVAudioSession.sharedInstance().setCategory(.ambient, options: .mixWithOthers)
2023-01-08 09:22:52 +00:00
return true
}
2023-01-17 10:36:01 +00:00
func application(_: UIApplication,
didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data)
{
2023-01-08 13:16:43 +00:00
PushNotificationsService.shared.pushToken = deviceToken
2023-01-08 09:22:52 +00:00
Task {
2023-01-08 13:16:43 +00:00
await PushNotificationsService.shared.fetchSubscriptions(accounts: AppAccountsManager.shared.pushAccounts)
await PushNotificationsService.shared.updateSubscriptions(accounts: AppAccountsManager.shared.pushAccounts)
2023-01-08 09:22:52 +00:00
}
}
2023-01-17 10:36:01 +00:00
func application(_: UIApplication, didFailToRegisterForRemoteNotificationsWithError _: Error) {}
2022-12-01 08:05:26 +00:00
}