Optimisations: Autoclosure for StatusRowViewModel

This commit is contained in:
Thomas Ricouard 2023-02-24 13:25:21 +01:00
parent 401bd7afb5
commit 29aaa7c5cb
9 changed files with 43 additions and 39 deletions

View file

@ -19,7 +19,7 @@ struct DisplaySettingsView: View {
var body: some View {
Form {
Section("settings.display.example-toot") {
StatusRowView(viewModel: previewStatusViewModel)
StatusRowView(viewModel: { previewStatusViewModel })
.allowsHitTesting(false)
}

View file

@ -275,7 +275,7 @@ public struct AccountDetailView: View {
.listRowSeparator(.hidden)
.listRowBackground(theme.primaryBackgroundColor)
ForEach(viewModel.pinned) { status in
StatusRowView(viewModel: .init(status: status, client: client, routerPath: routerPath))
StatusRowView(viewModel: { .init(status: status, client: client, routerPath: routerPath) })
}
Rectangle()
.fill(theme.secondaryBackgroundColor)

View file

@ -81,7 +81,7 @@ public struct ExploreView: View {
private var loadingView: some View {
ForEach(Status.placeholders()) { status in
StatusRowView(viewModel: .init(status: status, client: client, routerPath: routerPath))
StatusRowView(viewModel: { .init(status: status, client: client, routerPath: routerPath) })
.padding(.vertical, 8)
.redacted(reason: .placeholder)
.listRowBackground(theme.primaryBackgroundColor)
@ -112,7 +112,7 @@ public struct ExploreView: View {
if !results.statuses.isEmpty {
Section("explore.section.posts") {
ForEach(results.statuses) { status in
StatusRowView(viewModel: .init(status: status, client: client, routerPath: routerPath))
StatusRowView(viewModel: { .init(status: status, client: client, routerPath: routerPath) })
.listRowBackground(theme.primaryBackgroundColor)
.padding(.vertical, 8)
}
@ -184,7 +184,7 @@ public struct ExploreView: View {
Section("explore.section.trending.posts") {
ForEach(viewModel.trendingStatuses
.prefix(upTo: viewModel.trendingStatuses.count > 3 ? 3 : viewModel.trendingStatuses.count)) { status in
StatusRowView(viewModel: .init(status: status, client: client, routerPath: routerPath))
StatusRowView(viewModel: { .init(status: status, client: client, routerPath: routerPath) })
.listRowBackground(theme.primaryBackgroundColor)
.padding(.vertical, 8)
}
@ -192,7 +192,7 @@ public struct ExploreView: View {
NavigationLink {
List {
ForEach(viewModel.trendingStatuses) { status in
StatusRowView(viewModel: .init(status: status, client: client, routerPath: routerPath))
StatusRowView(viewModel: { .init(status: status, client: client, routerPath: routerPath) })
.listRowBackground(theme.primaryBackgroundColor)
.padding(.vertical, 8)
}

View file

@ -135,15 +135,15 @@ struct NotificationRowView: View {
if let status = notification.status {
HStack {
if type == .mention {
StatusRowView(viewModel: .init(status: status,
client: client,
routerPath: routerPath,
showActions: true))
StatusRowView(viewModel: { .init(status: status,
client: client,
routerPath: routerPath,
showActions: true) })
} else {
StatusRowView(viewModel: .init(status: status,
client: client,
routerPath: routerPath,
showActions: false))
StatusRowView(viewModel: { .init(status: status,
client: client,
routerPath: routerPath,
showActions: false) })
.lineLimit(4)
.foregroundColor(.gray)
}

View file

@ -124,7 +124,7 @@ public struct StatusDetailView: View {
makeCurrentStatusView(status: status)
.environment(\.extraLeadingInset, isReplyToPrevious ? 10 : 0)
} else {
StatusRowView(viewModel: viewModel)
StatusRowView(viewModel: { viewModel })
.environment(\.extraLeadingInset, isReplyToPrevious ? 10 : 0)
}
}
@ -137,10 +137,10 @@ public struct StatusDetailView: View {
}
private func makeCurrentStatusView(status: Status) -> some View {
StatusRowView(viewModel: .init(status: status,
client: client,
routerPath: routerPath,
isFocused: !viewModel.isLoadingContext))
StatusRowView(viewModel: { .init(status: status,
client: client,
routerPath: routerPath,
isFocused: !viewModel.isLoadingContext) })
.overlay {
GeometryReader { reader in
VStack {}
@ -166,7 +166,7 @@ public struct StatusDetailView: View {
private var loadingDetailView: some View {
ForEach(Status.placeholders()) { status in
StatusRowView(viewModel: .init(status: status, client: client, routerPath: routerPath))
StatusRowView(viewModel: { .init(status: status, client: client, routerPath: routerPath) })
.redacted(reason: .placeholder)
}
}

View file

@ -23,10 +23,10 @@ public struct StatusEmbeddedView: View {
HStack {
VStack(alignment: .leading) {
makeAccountView(account: status.reblog?.account ?? status.account)
StatusRowView(viewModel: .init(status: status,
client: client,
routerPath: routerPath,
showActions: false))
StatusRowView(viewModel: { .init(status: status,
client: client,
routerPath: routerPath,
showActions: false) })
.environment(\.isCompact, true)
}
Spacer()

View file

@ -24,7 +24,7 @@ public struct StatusesListView<Fetcher>: View where Fetcher: StatusesFetcher {
switch fetcher.statusesState {
case .loading:
ForEach(Status.placeholders()) { status in
StatusRowView(viewModel: .init(status: status, client: client, routerPath: routerPath))
StatusRowView(viewModel: { .init(status: status, client: client, routerPath: routerPath) })
.redacted(reason: .placeholder)
}
case .error:
@ -40,17 +40,19 @@ public struct StatusesListView<Fetcher>: View where Fetcher: StatusesFetcher {
case let .display(statuses, nextPageState):
ForEach(statuses, id: \.viewId) { status in
let viewModel = StatusRowViewModel(status: status, client: client, routerPath: routerPath, isRemote: isRemote)
if viewModel.filter?.filter.filterAction != .hide {
StatusRowView(viewModel: viewModel)
.id(status.id)
.onAppear {
fetcher.statusDidAppear(status: status)
}
.onDisappear {
fetcher.statusDidDisappear(status: status)
}
}
StatusRowView(viewModel: { StatusRowViewModel(status: status,
client: client,
routerPath: routerPath,
isRemote: isRemote)
})
.id(status.id)
.onAppear {
fetcher.statusDidAppear(status: status)
}
.onDisappear {
fetcher.statusDidDisappear(status: status)
}
}
switch nextPageState {
case .hasNextPage:

View file

@ -15,8 +15,9 @@ public struct StatusRowView: View {
@StateObject var viewModel: StatusRowViewModel
public init(viewModel: StatusRowViewModel) {
_viewModel = StateObject(wrappedValue: viewModel)
// StateObject accepts an @autoclosure which only allocates the view model once when the view gets on screen.
public init(viewModel: @escaping () -> StatusRowViewModel) {
_viewModel = StateObject(wrappedValue: viewModel())
}
var contextMenu: some View {
@ -32,6 +33,7 @@ public struct StatusRowView: View {
case .hide:
EmptyView()
.listRowSeparator(.hidden)
.listRowInsets(.init())
}
} else {
let status: AnyStatus = viewModel.status.reblog ?? viewModel.status

View file

@ -92,7 +92,7 @@ struct StatusRowContextMenu: View {
Button {
let view = HStack {
StatusRowView(viewModel: viewModel)
StatusRowView(viewModel: { viewModel })
.padding(16)
}
.environment(\.isInCaptureMode, true)