mirror of
https://github.com/Dimillian/IceCubesApp.git
synced 2024-06-02 10:11:31 +00:00
More Observation
This commit is contained in:
parent
54839953cd
commit
fa38511e2f
|
@ -20,10 +20,10 @@ struct IceCubesApp: App {
|
|||
@StateObject private var currentAccount = CurrentAccount.shared
|
||||
@StateObject private var userPreferences = UserPreferences.shared
|
||||
@StateObject private var pushNotificationsService = PushNotificationsService.shared
|
||||
@StateObject private var watcher = StreamWatcher()
|
||||
@State private var watcher = StreamWatcher()
|
||||
@StateObject private var quickLook = QuickLook()
|
||||
@StateObject private var theme = Theme.shared
|
||||
@StateObject private var sidebarRouterPath = RouterPath()
|
||||
@State private var sidebarRouterPath = RouterPath()
|
||||
|
||||
@State private var selectedTab: Tab = .timeline
|
||||
@State private var popToRootTab: Tab = .other
|
||||
|
@ -50,7 +50,7 @@ struct IceCubesApp: App {
|
|||
.environmentObject(currentInstance)
|
||||
.environmentObject(userPreferences)
|
||||
.environmentObject(theme)
|
||||
.environmentObject(watcher)
|
||||
.environment(watcher)
|
||||
.environmentObject(pushNotificationsService)
|
||||
.environment(\.isSupporter, isSupporter)
|
||||
.fullScreenCover(item: $quickLook.url, content: { url in
|
||||
|
|
|
@ -14,7 +14,7 @@ extension View {
|
|||
private struct SafariRouter: ViewModifier {
|
||||
@EnvironmentObject private var theme: Theme
|
||||
@EnvironmentObject private var preferences: UserPreferences
|
||||
@EnvironmentObject private var routerPath: RouterPath
|
||||
@Environment(RouterPath.self) private var routerPath
|
||||
|
||||
@State private var safariManager = InAppSafariManager()
|
||||
|
||||
|
|
|
@ -9,13 +9,13 @@ struct SideBarView<Content: View>: View {
|
|||
@Environment(AppAccountsManager.self) private var appAccounts
|
||||
@EnvironmentObject private var currentAccount: CurrentAccount
|
||||
@EnvironmentObject private var theme: Theme
|
||||
@EnvironmentObject private var watcher: StreamWatcher
|
||||
@Environment(StreamWatcher.self) private var watcher
|
||||
@EnvironmentObject private var userPreferences: UserPreferences
|
||||
|
||||
@Binding var selectedTab: Tab
|
||||
@Binding var popToRootTab: Tab
|
||||
var tabs: [Tab]
|
||||
@ObservedObject var routerPath = RouterPath()
|
||||
@State var routerPath = RouterPath()
|
||||
@ViewBuilder var content: () -> Content
|
||||
|
||||
private func badgeFor(tab: Tab) -> Int {
|
||||
|
|
|
@ -12,7 +12,7 @@ struct ExploreTab: View {
|
|||
@EnvironmentObject private var preferences: UserPreferences
|
||||
@EnvironmentObject private var currentAccount: CurrentAccount
|
||||
@Environment(Client.self) private var client
|
||||
@StateObject private var routerPath = RouterPath()
|
||||
@State private var routerPath = RouterPath()
|
||||
@Binding var popToRootTab: Tab
|
||||
|
||||
var body: some View {
|
||||
|
@ -35,7 +35,7 @@ struct ExploreTab: View {
|
|||
}
|
||||
}
|
||||
.withSafariRouter()
|
||||
.environmentObject(routerPath)
|
||||
.environment(routerPath)
|
||||
.onChange(of: $popToRootTab.wrappedValue) { oldValue, newValue in
|
||||
if newValue == .explore {
|
||||
routerPath.path = []
|
||||
|
|
|
@ -10,11 +10,11 @@ import SwiftUI
|
|||
|
||||
struct MessagesTab: View {
|
||||
@EnvironmentObject private var theme: Theme
|
||||
@EnvironmentObject private var watcher: StreamWatcher
|
||||
@Environment(StreamWatcher.self) private var watcher
|
||||
@Environment(Client.self) private var client
|
||||
@EnvironmentObject private var currentAccount: CurrentAccount
|
||||
@Environment(AppAccountsManager.self) private var appAccount
|
||||
@StateObject private var routerPath = RouterPath()
|
||||
@State private var routerPath = RouterPath()
|
||||
@Binding var popToRootTab: Tab
|
||||
|
||||
var body: some View {
|
||||
|
@ -44,6 +44,6 @@ struct MessagesTab: View {
|
|||
routerPath.client = client
|
||||
}
|
||||
.withSafariRouter()
|
||||
.environmentObject(routerPath)
|
||||
.environment(routerPath)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,12 +13,12 @@ struct NotificationsTab: View {
|
|||
|
||||
@EnvironmentObject private var theme: Theme
|
||||
@Environment(Client.self) private var client
|
||||
@EnvironmentObject private var watcher: StreamWatcher
|
||||
@Environment(StreamWatcher.self) private var watcher
|
||||
@Environment(AppAccountsManager.self) private var appAccount
|
||||
@EnvironmentObject private var currentAccount: CurrentAccount
|
||||
@EnvironmentObject private var userPreferences: UserPreferences
|
||||
@EnvironmentObject private var pushNotificationsService: PushNotificationsService
|
||||
@StateObject private var routerPath = RouterPath()
|
||||
@State private var routerPath = RouterPath()
|
||||
@Binding var popToRootTab: Tab
|
||||
|
||||
let lockedType: Models.Notification.NotificationType?
|
||||
|
@ -54,7 +54,7 @@ struct NotificationsTab: View {
|
|||
}
|
||||
}
|
||||
.withSafariRouter()
|
||||
.environmentObject(routerPath)
|
||||
.environment(routerPath)
|
||||
.onChange(of: $popToRootTab.wrappedValue) { oldValue, newValue in
|
||||
if newValue == .notifications {
|
||||
routerPath.path = []
|
||||
|
|
|
@ -13,7 +13,7 @@ struct ProfileTab: View {
|
|||
@EnvironmentObject private var theme: Theme
|
||||
@Environment(Client.self) private var client
|
||||
@EnvironmentObject private var currentAccount: CurrentAccount
|
||||
@StateObject private var routerPath = RouterPath()
|
||||
@State private var routerPath = RouterPath()
|
||||
@Binding var popToRootTab: Tab
|
||||
|
||||
var body: some View {
|
||||
|
@ -41,6 +41,6 @@ struct ProfileTab: View {
|
|||
routerPath.client = client
|
||||
}
|
||||
.withSafariRouter()
|
||||
.environmentObject(routerPath)
|
||||
.environment(routerPath)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@ import Env
|
|||
import SwiftUI
|
||||
|
||||
struct AboutView: View {
|
||||
@EnvironmentObject private var routerPath: RouterPath
|
||||
@Environment(RouterPath.self) private var routerPath
|
||||
@EnvironmentObject private var theme: Theme
|
||||
|
||||
let versionNumber: String
|
||||
|
|
|
@ -19,8 +19,7 @@ struct SettingsTabs: View {
|
|||
@Environment(AppAccountsManager.self) private var appAccountsManager
|
||||
@EnvironmentObject private var theme: Theme
|
||||
|
||||
@StateObject private var routerPath = RouterPath()
|
||||
|
||||
@State private var routerPath = RouterPath()
|
||||
@State private var addAccountSheetPresented = false
|
||||
@State private var isEditingAccount = false
|
||||
@State private var cachedRemoved = false
|
||||
|
@ -67,7 +66,7 @@ struct SettingsTabs: View {
|
|||
}
|
||||
}
|
||||
.withSafariRouter()
|
||||
.environmentObject(routerPath)
|
||||
.environment(routerPath)
|
||||
.onChange(of: $popToRootTab.wrappedValue) { oldValue, newValue in
|
||||
if newValue == .notifications {
|
||||
routerPath.path = []
|
||||
|
|
|
@ -13,7 +13,7 @@ struct TimelineTab: View {
|
|||
@EnvironmentObject private var currentAccount: CurrentAccount
|
||||
@EnvironmentObject private var preferences: UserPreferences
|
||||
@Environment(Client.self) private var client
|
||||
@StateObject private var routerPath = RouterPath()
|
||||
@State private var routerPath = RouterPath()
|
||||
@Binding var popToRootTab: Tab
|
||||
|
||||
@State private var didAppear: Bool = false
|
||||
|
@ -90,7 +90,7 @@ struct TimelineTab: View {
|
|||
}
|
||||
}
|
||||
.withSafariRouter()
|
||||
.environmentObject(routerPath)
|
||||
.environment(routerPath)
|
||||
}
|
||||
|
||||
@ViewBuilder
|
||||
|
|
|
@ -4,7 +4,7 @@ import SwiftUI
|
|||
|
||||
public struct AccountDetailContextMenu: View {
|
||||
@Environment(Client.self) private var client
|
||||
@EnvironmentObject private var routerPath: RouterPath
|
||||
@Environment(RouterPath.self) private var routerPath
|
||||
@EnvironmentObject private var currentInstance: CurrentInstance
|
||||
@EnvironmentObject private var preferences: UserPreferences
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@ struct AccountDetailHeaderView: View {
|
|||
|
||||
@EnvironmentObject private var theme: Theme
|
||||
@EnvironmentObject private var quickLook: QuickLook
|
||||
@EnvironmentObject private var routerPath: RouterPath
|
||||
@Environment(RouterPath.self) private var routerPath
|
||||
@EnvironmentObject private var currentAccount: CurrentAccount
|
||||
@Environment(\.redactionReasons) private var reasons
|
||||
@Environment(\.isSupporter) private var isSupporter: Bool
|
||||
|
|
|
@ -11,13 +11,13 @@ public struct AccountDetailView: View {
|
|||
@Environment(\.openURL) private var openURL
|
||||
@Environment(\.redactionReasons) private var reasons
|
||||
|
||||
@EnvironmentObject private var watcher: StreamWatcher
|
||||
@Environment(StreamWatcher.self) private var watcher
|
||||
@EnvironmentObject private var currentAccount: CurrentAccount
|
||||
@EnvironmentObject private var currentInstance: CurrentInstance
|
||||
@EnvironmentObject private var preferences: UserPreferences
|
||||
@EnvironmentObject private var theme: Theme
|
||||
@Environment(Client.self) private var client
|
||||
@EnvironmentObject private var routerPath: RouterPath
|
||||
@Environment(RouterPath.self) private var routerPath
|
||||
|
||||
@State private var viewModel: AccountDetailViewModel
|
||||
@State private var isCurrentUser: Bool = false
|
||||
|
|
|
@ -23,7 +23,7 @@ import Observation
|
|||
public struct AccountsListRow: View {
|
||||
@EnvironmentObject private var theme: Theme
|
||||
@EnvironmentObject private var currentAccount: CurrentAccount
|
||||
@EnvironmentObject private var routerPath: RouterPath
|
||||
@Environment(RouterPath.self) private var routerPath
|
||||
@Environment(Client.self) private var client
|
||||
|
||||
@State var viewModel: AccountsListRowViewModel
|
||||
|
|
|
@ -5,7 +5,7 @@ import SwiftUI
|
|||
|
||||
public struct AppAccountView: View {
|
||||
@EnvironmentObject private var theme: Theme
|
||||
@EnvironmentObject private var routerPath: RouterPath
|
||||
@Environment(RouterPath.self) private var routerPath
|
||||
@Environment(AppAccountsManager.self) private var appAccounts
|
||||
@EnvironmentObject private var preferences: UserPreferences
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ public struct AppAccountsSelectorView: View {
|
|||
@Environment(AppAccountsManager.self) private var appAccounts
|
||||
@EnvironmentObject private var theme: Theme
|
||||
|
||||
@ObservedObject var routerPath: RouterPath
|
||||
var routerPath: RouterPath
|
||||
|
||||
@State private var accountsViewModel: [AppAccountViewModel] = []
|
||||
@State private var isPresented: Bool = false
|
||||
|
|
|
@ -11,11 +11,11 @@ public struct ConversationDetailView: View {
|
|||
}
|
||||
|
||||
@EnvironmentObject private var quickLook: QuickLook
|
||||
@EnvironmentObject private var routerPath: RouterPath
|
||||
@Environment(RouterPath.self) private var routerPath
|
||||
@EnvironmentObject private var currentAccount: CurrentAccount
|
||||
@Environment(Client.self) private var client
|
||||
@EnvironmentObject private var theme: Theme
|
||||
@EnvironmentObject private var watcher: StreamWatcher
|
||||
@Environment(StreamWatcher.self) private var watcher
|
||||
|
||||
@StateObject private var viewModel: ConversationDetailViewModel
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ import SwiftUI
|
|||
|
||||
struct ConversationMessageView: View {
|
||||
@EnvironmentObject private var quickLook: QuickLook
|
||||
@EnvironmentObject private var routerPath: RouterPath
|
||||
@Environment(RouterPath.self) private var routerPath
|
||||
@EnvironmentObject private var currentAccount: CurrentAccount
|
||||
@Environment(Client.self) private var client
|
||||
@EnvironmentObject private var theme: Theme
|
||||
|
|
|
@ -7,7 +7,7 @@ import SwiftUI
|
|||
|
||||
struct ConversationsListRow: View {
|
||||
@Environment(Client.self) private var client
|
||||
@EnvironmentObject private var routerPath: RouterPath
|
||||
@Environment(RouterPath.self) private var routerPath
|
||||
@EnvironmentObject private var theme: Theme
|
||||
@EnvironmentObject private var currentAccount: CurrentAccount
|
||||
|
||||
|
|
|
@ -7,8 +7,8 @@ import SwiftUI
|
|||
|
||||
public struct ConversationsListView: View {
|
||||
@EnvironmentObject private var preferences: UserPreferences
|
||||
@EnvironmentObject private var routerPath: RouterPath
|
||||
@EnvironmentObject private var watcher: StreamWatcher
|
||||
@Environment(RouterPath.self) private var routerPath
|
||||
@Environment(StreamWatcher.self) private var watcher
|
||||
@Environment(Client.self) private var client
|
||||
@EnvironmentObject private var theme: Theme
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@ public extension View {
|
|||
|
||||
@MainActor
|
||||
public struct StatusEditorToolbarItem: ToolbarContent {
|
||||
@EnvironmentObject private var routerPath: RouterPath
|
||||
@Environment(RouterPath.self) private var routerPath
|
||||
|
||||
let visibility: Models.Visibility
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@ import Models
|
|||
import SwiftUI
|
||||
|
||||
public struct TagRowView: View {
|
||||
@EnvironmentObject private var routerPath: RouterPath
|
||||
@Environment(RouterPath.self) private var routerPath
|
||||
|
||||
let tag: Tag
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@ import Foundation
|
|||
import Models
|
||||
import Network
|
||||
import SwiftUI
|
||||
import Observation
|
||||
|
||||
public enum RouterDestination: Hashable {
|
||||
case accountDetail(id: String)
|
||||
|
@ -69,12 +70,12 @@ public enum SheetDestination: Identifiable {
|
|||
}
|
||||
|
||||
@MainActor
|
||||
public class RouterPath: ObservableObject {
|
||||
@Observable public class RouterPath {
|
||||
public var client: Client?
|
||||
public var urlHandler: ((URL) -> OpenURLAction.Result)?
|
||||
|
||||
@Published public var path: [RouterDestination] = []
|
||||
@Published public var presentedSheet: SheetDestination?
|
||||
public var path: [RouterDestination] = []
|
||||
public var presentedSheet: SheetDestination?
|
||||
|
||||
public init() {}
|
||||
|
||||
|
|
|
@ -2,9 +2,10 @@ import Combine
|
|||
import Foundation
|
||||
import Models
|
||||
import Network
|
||||
import Observation
|
||||
|
||||
@MainActor
|
||||
public class StreamWatcher: ObservableObject {
|
||||
@Observable public class StreamWatcher {
|
||||
private var client: Client?
|
||||
private var task: URLSessionWebSocketTask?
|
||||
private var watchedStreams: [Stream] = []
|
||||
|
@ -21,9 +22,9 @@ public class StreamWatcher: ObservableObject {
|
|||
case direct
|
||||
}
|
||||
|
||||
@Published public var events: [any StreamEvent] = []
|
||||
@Published public var unreadNotificationsCount: Int = 0
|
||||
@Published public var latestEvent: (any StreamEvent)?
|
||||
public var events: [any StreamEvent] = []
|
||||
public var unreadNotificationsCount: Int = 0
|
||||
public var latestEvent: (any StreamEvent)?
|
||||
|
||||
public init() {
|
||||
decoder.keyDecodingStrategy = .convertFromSnakeCase
|
||||
|
|
|
@ -10,7 +10,7 @@ import SwiftUI
|
|||
public struct ExploreView: View {
|
||||
@EnvironmentObject private var theme: Theme
|
||||
@Environment(Client.self) private var client
|
||||
@EnvironmentObject private var routerPath: RouterPath
|
||||
@Environment(RouterPath.self) private var routerPath
|
||||
|
||||
@StateObject private var viewModel = ExploreViewModel()
|
||||
|
||||
|
|
|
@ -8,9 +8,9 @@ import SwiftUI
|
|||
public struct NotificationsListView: View {
|
||||
@Environment(\.scenePhase) private var scenePhase
|
||||
@EnvironmentObject private var theme: Theme
|
||||
@EnvironmentObject private var watcher: StreamWatcher
|
||||
@Environment(StreamWatcher.self) private var watcher
|
||||
@Environment(Client.self) private var client
|
||||
@EnvironmentObject private var routerPath: RouterPath
|
||||
@Environment(RouterPath.self) private var routerPath
|
||||
@EnvironmentObject private var account: CurrentAccount
|
||||
@StateObject private var viewModel = NotificationsViewModel()
|
||||
|
||||
|
|
|
@ -8,9 +8,9 @@ import SwiftUI
|
|||
public struct StatusDetailView: View {
|
||||
@EnvironmentObject private var theme: Theme
|
||||
@EnvironmentObject private var currentAccount: CurrentAccount
|
||||
@EnvironmentObject private var watcher: StreamWatcher
|
||||
@Environment(StreamWatcher.self) private var watcher
|
||||
@Environment(Client.self) private var client
|
||||
@EnvironmentObject private var routerPath: RouterPath
|
||||
@Environment(RouterPath.self) private var routerPath
|
||||
|
||||
@StateObject private var viewModel: StatusDetailViewModel
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@ public struct StatusEditorView: View {
|
|||
@EnvironmentObject private var theme: Theme
|
||||
@Environment(Client.self) private var client
|
||||
@EnvironmentObject private var currentAccount: CurrentAccount
|
||||
@EnvironmentObject private var routerPath: RouterPath
|
||||
@Environment(RouterPath.self) private var routerPath
|
||||
@Environment(\.dismiss) private var dismiss
|
||||
|
||||
@StateObject private var viewModel: StatusEditorViewModel
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import Combine
|
||||
import Models
|
||||
import SwiftUI
|
||||
import Observation
|
||||
|
||||
public enum StatusesState {
|
||||
public enum PagingState {
|
||||
|
@ -13,7 +14,7 @@ public enum StatusesState {
|
|||
}
|
||||
|
||||
@MainActor
|
||||
public protocol StatusesFetcher: ObservableObject {
|
||||
public protocol StatusesFetcher {
|
||||
var statusesState: StatusesState { get }
|
||||
func fetchNewestStatuses() async
|
||||
func fetchNextPage() async
|
||||
|
|
|
@ -8,7 +8,7 @@ import SwiftUI
|
|||
public struct StatusesListView<Fetcher>: View where Fetcher: StatusesFetcher {
|
||||
@EnvironmentObject private var theme: Theme
|
||||
|
||||
@ObservedObject private var fetcher: Fetcher
|
||||
@State private var fetcher: Fetcher
|
||||
// Whether this status is on a remote local timeline (many actions are unavailable if so)
|
||||
private let isRemote: Bool
|
||||
private let routerPath: RouterPath
|
||||
|
@ -19,7 +19,7 @@ public struct StatusesListView<Fetcher>: View where Fetcher: StatusesFetcher {
|
|||
routerPath: RouterPath,
|
||||
isRemote: Bool = false)
|
||||
{
|
||||
self.fetcher = fetcher
|
||||
_fetcher = .init(initialValue: fetcher)
|
||||
self.isRemote = isRemote
|
||||
self.client = client
|
||||
self.routerPath = routerPath
|
||||
|
|
|
@ -2,8 +2,9 @@ import Models
|
|||
import Nuke
|
||||
import SwiftUI
|
||||
import UIKit
|
||||
import Observation
|
||||
|
||||
final class TimelinePrefetcher: NSObject, ObservableObject, UICollectionViewDataSourcePrefetching {
|
||||
@Observable final class TimelinePrefetcher: NSObject, UICollectionViewDataSourcePrefetching {
|
||||
private let prefetcher = ImagePrefetcher()
|
||||
|
||||
weak var viewModel: TimelineViewModel?
|
||||
|
|
|
@ -15,12 +15,12 @@ public struct TimelineView: View {
|
|||
@Environment(\.scenePhase) private var scenePhase
|
||||
@EnvironmentObject private var theme: Theme
|
||||
@EnvironmentObject private var account: CurrentAccount
|
||||
@EnvironmentObject private var watcher: StreamWatcher
|
||||
@Environment(StreamWatcher.self) private var watcher
|
||||
@Environment(Client.self) private var client
|
||||
@EnvironmentObject private var routerPath: RouterPath
|
||||
@Environment(RouterPath.self) private var routerPath
|
||||
|
||||
@StateObject private var viewModel = TimelineViewModel()
|
||||
@StateObject private var prefetcher = TimelinePrefetcher()
|
||||
@State private var viewModel = TimelineViewModel()
|
||||
@State private var prefetcher = TimelinePrefetcher()
|
||||
|
||||
@State private var wasBackgrounded: Bool = false
|
||||
@State private var collectionView: UICollectionView?
|
||||
|
|
|
@ -3,12 +3,13 @@ import Models
|
|||
import Network
|
||||
import Status
|
||||
import SwiftUI
|
||||
import Observation
|
||||
|
||||
@MainActor
|
||||
class TimelineViewModel: ObservableObject {
|
||||
@Published var scrollToIndex: Int?
|
||||
@Published var statusesState: StatusesState = .loading
|
||||
@Published var timeline: TimelineFilter = .federated {
|
||||
@Observable class TimelineViewModel {
|
||||
var scrollToIndex: Int?
|
||||
var statusesState: StatusesState = .loading
|
||||
var timeline: TimelineFilter = .federated {
|
||||
didSet {
|
||||
timelineTask?.cancel()
|
||||
timelineTask = Task {
|
||||
|
@ -39,7 +40,7 @@ class TimelineViewModel: ObservableObject {
|
|||
|
||||
private var timelineTask: Task<Void, Never>?
|
||||
|
||||
@Published var tag: Tag?
|
||||
var tag: Tag?
|
||||
|
||||
var tagGroup: TagGroup? {
|
||||
if case let .tagGroup(group) = timeline {
|
||||
|
|
Loading…
Reference in a new issue