mirror of
https://github.com/omnivore-app/omnivore.git
synced 2026-03-11 08:54:26 +00:00
use @StateObject when the view owns the observable object
This commit is contained in:
parent
de07e9ad92
commit
1073c63476
9 changed files with 55 additions and 44 deletions
|
|
@ -95,10 +95,10 @@ final class ShareExtensionViewModel: ObservableObject {
|
|||
}
|
||||
|
||||
struct ShareExtensionView: View {
|
||||
@ObservedObject private var viewModel: ShareExtensionViewModel
|
||||
@StateObject private var viewModel: ShareExtensionViewModel
|
||||
|
||||
init(extensionContext: NSExtensionContext?) {
|
||||
self.viewModel = ShareExtensionViewModel(extensionContext: extensionContext)
|
||||
self._viewModel = StateObject(wrappedValue: ShareExtensionViewModel(extensionContext: extensionContext))
|
||||
}
|
||||
|
||||
var body: some View {
|
||||
|
|
|
|||
|
|
@ -22,8 +22,18 @@ public final class RootViewModel: ObservableObject {
|
|||
|
||||
public var subscriptions = Set<AnyCancellable>()
|
||||
|
||||
public init() {
|
||||
public init(pdfViewerProvider: ((URL, PDFViewerViewModel) -> AnyView)?) {
|
||||
registerFonts()
|
||||
|
||||
if let pdfViewerProvider = pdfViewerProvider {
|
||||
configurePDFProvider(pdfViewerProvider: pdfViewerProvider)
|
||||
}
|
||||
|
||||
#if DEBUG
|
||||
if CommandLine.arguments.contains("--uitesting") {
|
||||
services.authenticator.logout()
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
func configurePDFProvider(pdfViewerProvider: @escaping (URL, PDFViewerViewModel) -> AnyView) {
|
||||
|
|
@ -112,26 +122,13 @@ private struct SafariWebLinkPath: Identifiable {
|
|||
}
|
||||
|
||||
public struct RootView: View {
|
||||
@ObservedObject private var viewModel: RootViewModel
|
||||
@ObservedObject private var authenticator: Authenticator
|
||||
@StateObject private var viewModel: RootViewModel
|
||||
|
||||
public init(
|
||||
pdfViewerProvider: ((URL, PDFViewerViewModel) -> AnyView)?,
|
||||
intercomProvider: IntercomProvider?
|
||||
) {
|
||||
let rootViewModel = RootViewModel()
|
||||
self.viewModel = rootViewModel
|
||||
self.authenticator = rootViewModel.services.authenticator
|
||||
|
||||
#if DEBUG
|
||||
if CommandLine.arguments.contains("--uitesting") {
|
||||
authenticator.logout()
|
||||
}
|
||||
#endif
|
||||
|
||||
if let pdfViewerProvider = pdfViewerProvider {
|
||||
viewModel.configurePDFProvider(pdfViewerProvider: pdfViewerProvider)
|
||||
}
|
||||
self._viewModel = StateObject(wrappedValue: RootViewModel(pdfViewerProvider: pdfViewerProvider))
|
||||
|
||||
if let intercomProvider = intercomProvider {
|
||||
DataService.showIntercomMessenger = intercomProvider.showIntercomMessenger
|
||||
|
|
@ -141,7 +138,7 @@ public struct RootView: View {
|
|||
}
|
||||
|
||||
@ViewBuilder private var innerBody: some View {
|
||||
if authenticator.isLoggedIn {
|
||||
if viewModel.services.authenticator.isLoggedIn {
|
||||
PrimaryContentView()
|
||||
.onAppear {
|
||||
viewModel.triggerPushNotificationRequestIfNeeded()
|
||||
|
|
|
|||
|
|
@ -101,13 +101,15 @@ final class CreateProfileViewModel: ObservableObject {
|
|||
struct CreateProfileContainerView: View {
|
||||
@EnvironmentObject var authenticator: Authenticator
|
||||
@EnvironmentObject var dataService: DataService
|
||||
@ObservedObject private var viewModel: CreateProfileViewModel
|
||||
@StateObject private var viewModel: CreateProfileViewModel
|
||||
|
||||
@State private var name: String
|
||||
@State private var bio = ""
|
||||
|
||||
init(userProfile: UserProfile, dataService: DataService) {
|
||||
self.viewModel = CreateProfileViewModel(initialUserProfile: userProfile, dataService: dataService)
|
||||
self._viewModel = StateObject(
|
||||
wrappedValue: CreateProfileViewModel(initialUserProfile: userProfile, dataService: dataService)
|
||||
)
|
||||
self._name = State(initialValue: userProfile.name)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -179,7 +179,7 @@ final class HomeFeedViewModel: ObservableObject {
|
|||
struct HomeFeedView: View {
|
||||
@EnvironmentObject var dataService: DataService
|
||||
|
||||
@ObservedObject private var viewModel = HomeFeedViewModel()
|
||||
@StateObject private var viewModel = HomeFeedViewModel()
|
||||
@State private var selectedLinkItem: FeedItem?
|
||||
@State private var searchQuery = ""
|
||||
@State private var itemToRemove: FeedItem?
|
||||
|
|
|
|||
|
|
@ -30,12 +30,12 @@ final class NewAppleSignupViewModel: ObservableObject {
|
|||
|
||||
struct NewAppleSignupView: View {
|
||||
@EnvironmentObject var authenticator: Authenticator
|
||||
@ObservedObject private var viewModel: NewAppleSignupViewModel
|
||||
@StateObject private var viewModel: NewAppleSignupViewModel
|
||||
let showProfileEditView: () -> Void
|
||||
|
||||
init(userProfile: UserProfile, showProfileEditView: @escaping () -> Void) {
|
||||
self.showProfileEditView = showProfileEditView
|
||||
self.viewModel = NewAppleSignupViewModel(userProfile: userProfile)
|
||||
self._viewModel = StateObject(wrappedValue: NewAppleSignupViewModel(userProfile: userProfile))
|
||||
}
|
||||
|
||||
var body: some View {
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ final class NewsletterEmailsViewModel: ObservableObject {
|
|||
|
||||
struct NewsletterEmailsView: View {
|
||||
@EnvironmentObject var dataService: DataService
|
||||
@ObservedObject var viewModel = NewsletterEmailsViewModel()
|
||||
@StateObject var viewModel = NewsletterEmailsViewModel()
|
||||
let footerText = "Add PDFs to your library, or subscribe to emails using an Omnivore email address."
|
||||
|
||||
var body: some View {
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ struct ProfileView: View {
|
|||
@EnvironmentObject var authenticator: Authenticator
|
||||
@EnvironmentObject var dataService: DataService
|
||||
|
||||
@ObservedObject private var viewModel = ProfileContainerViewModel()
|
||||
@StateObject private var viewModel = ProfileContainerViewModel()
|
||||
|
||||
@State private var showLogoutConfirmation = false
|
||||
|
||||
|
|
|
|||
|
|
@ -88,7 +88,7 @@ struct RegistrationView: View {
|
|||
@EnvironmentObject var authenticator: Authenticator
|
||||
@EnvironmentObject var dataService: DataService
|
||||
@Environment(\.horizontalSizeClass) var horizontalSizeClass
|
||||
@ObservedObject private var viewModel = RegistrationViewModel()
|
||||
@StateObject private var viewModel = RegistrationViewModel()
|
||||
|
||||
var authenticationView: some View {
|
||||
VStack(spacing: 0) {
|
||||
|
|
|
|||
|
|
@ -5,31 +5,43 @@ import Utils
|
|||
|
||||
struct AsyncImage: View {
|
||||
let isResizable: Bool
|
||||
@ObservedObject private var imageLoader = ImageLoader()
|
||||
let url: URL?
|
||||
@State private var isLoaded = false
|
||||
@StateObject private var imageLoader = ImageLoader()
|
||||
|
||||
init(url: URL?, isResizable: Bool = true) {
|
||||
self.isResizable = isResizable
|
||||
if let url = url {
|
||||
self.url = url
|
||||
}
|
||||
|
||||
func load() {
|
||||
if let url = url, !isLoaded {
|
||||
imageLoader.load(fromUrl: url)
|
||||
isLoaded = true
|
||||
}
|
||||
}
|
||||
|
||||
var body: some View {
|
||||
#if os(iOS)
|
||||
if isResizable {
|
||||
Image(uiImage: imageLoader.image ?? imageLoader.placeholder)
|
||||
.resizable()
|
||||
} else {
|
||||
Image(uiImage: imageLoader.image ?? imageLoader.placeholder)
|
||||
}
|
||||
#elseif os(macOS)
|
||||
if isResizable {
|
||||
Image(nsImage: imageLoader.image ?? imageLoader.placeholder)
|
||||
.resizable()
|
||||
} else {
|
||||
Image(nsImage: imageLoader.image ?? imageLoader.placeholder)
|
||||
}
|
||||
#endif
|
||||
Group {
|
||||
#if os(iOS)
|
||||
if isResizable {
|
||||
Image(uiImage: imageLoader.image ?? imageLoader.placeholder)
|
||||
.resizable()
|
||||
} else {
|
||||
Image(uiImage: imageLoader.image ?? imageLoader.placeholder)
|
||||
}
|
||||
#elseif os(macOS)
|
||||
if isResizable {
|
||||
Image(nsImage: imageLoader.image ?? imageLoader.placeholder)
|
||||
.resizable()
|
||||
} else {
|
||||
Image(nsImage: imageLoader.image ?? imageLoader.placeholder)
|
||||
}
|
||||
#endif
|
||||
}
|
||||
.onAppear {
|
||||
load()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue