mirror of
https://github.com/Dimillian/IceCubesApp.git
synced 2024-06-18 05:00:35 +00:00
* Enhance the message context menu A direct message can now directly be bookmarked, the author can be publicly mentioned and reported. Signed-off-by: Paul Schuetz <pa.schuetz@web.de> * Add options to the conversation list context menu Since the latest message is shown in the conversation list, the user can now interact with this message via the context menu similar to the messages in the conversation history. The "conversation" class had to be modified since bookmarking and liking a message would have led to a race condition (depending on the server) when fetching the conversations afterwards, so the only affected the message is now immediately updated. Signed-off-by: Paul Schuetz <pa.schuetz@web.de> * Remove child view models The child views models are removed, and the list row now only uses the conversation object managed by the list view model. Signed-off-by: Paul Schuetz <pa.schuetz@web.de> * Make unmodified var let The last state-var of a conversation isn't modified, instead, a new conversation is created. Therefore, the var is now a let. Signed-off-by: Paul Schuetz <pa.schuetz@web.de> --------- Signed-off-by: Paul Schuetz <pa.schuetz@web.de>
107 lines
3.3 KiB
Swift
107 lines
3.3 KiB
Swift
import DesignSystem
|
|
import Env
|
|
import Models
|
|
import Network
|
|
import Shimmer
|
|
import SwiftUI
|
|
|
|
public struct ConversationsListView: View {
|
|
@EnvironmentObject private var preferences: UserPreferences
|
|
@EnvironmentObject private var routerPath: RouterPath
|
|
@EnvironmentObject private var watcher: StreamWatcher
|
|
@EnvironmentObject private var client: Client
|
|
@EnvironmentObject private var theme: Theme
|
|
|
|
@StateObject private var viewModel = ConversationsListViewModel()
|
|
|
|
public init() {}
|
|
|
|
private var conversations: Binding<[Conversation]> {
|
|
if viewModel.isLoadingFirstPage {
|
|
return Binding.constant(Conversation.placeholders())
|
|
} else {
|
|
return $viewModel.conversations
|
|
}
|
|
}
|
|
|
|
public var body: some View {
|
|
ScrollView {
|
|
LazyVStack {
|
|
Group {
|
|
if !conversations.isEmpty || viewModel.isLoadingFirstPage {
|
|
ForEach(conversations) { $conversation in
|
|
if viewModel.isLoadingFirstPage {
|
|
ConversationsListRow(conversation: $conversation, viewModel: viewModel)
|
|
.padding(.horizontal, .layoutPadding)
|
|
.redacted(reason: .placeholder)
|
|
} else {
|
|
ConversationsListRow(conversation: $conversation, viewModel: viewModel)
|
|
.padding(.horizontal, .layoutPadding)
|
|
}
|
|
Divider()
|
|
}
|
|
} else if conversations.isEmpty && !viewModel.isLoadingFirstPage && !viewModel.isError {
|
|
EmptyView(iconName: "tray",
|
|
title: "conversations.empty.title",
|
|
message: "conversations.empty.message")
|
|
} else if viewModel.isError {
|
|
ErrorView(title: "conversations.error.title",
|
|
message: "conversations.error.message",
|
|
buttonTitle: "conversations.error.button") {
|
|
Task {
|
|
await viewModel.fetchConversations()
|
|
}
|
|
}
|
|
}
|
|
|
|
if viewModel.nextPage != nil {
|
|
HStack {
|
|
Spacer()
|
|
ProgressView()
|
|
Spacer()
|
|
}
|
|
.onAppear {
|
|
if !viewModel.isLoadingNextPage {
|
|
Task {
|
|
await viewModel.fetchNextPage()
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
.padding(.top, .layoutPadding)
|
|
}
|
|
.scrollContentBackground(.hidden)
|
|
.background(theme.primaryBackgroundColor)
|
|
.navigationTitle("conversations.navigation-title")
|
|
.navigationBarTitleDisplayMode(.inline)
|
|
.toolbar {
|
|
StatusEditorToolbarItem(visibility: .direct)
|
|
if UIDevice.current.userInterfaceIdiom == .pad && !preferences.showiPadSecondaryColumn {
|
|
SecondaryColumnToolbarItem()
|
|
}
|
|
}
|
|
.onChange(of: watcher.latestEvent?.id) { _ in
|
|
if let latestEvent = watcher.latestEvent {
|
|
viewModel.handleEvent(event: latestEvent)
|
|
}
|
|
}
|
|
.refreshable {
|
|
// note: this Task wrapper should not be necessary, but it reportedly crashes without it
|
|
// when refreshing on an empty list
|
|
Task {
|
|
await viewModel.fetchConversations()
|
|
}
|
|
}
|
|
.onAppear {
|
|
viewModel.client = client
|
|
if client.isAuth {
|
|
Task {
|
|
await viewModel.fetchConversations()
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|