experiment

This commit is contained in:
Avently 2025-01-23 09:37:55 -08:00
parent 085ada470e
commit c952c9e623

View file

@ -78,7 +78,7 @@ struct ChatView: View {
} }
VStack(spacing: 0) { VStack(spacing: 0) {
ZStack(alignment: .bottomTrailing) { ZStack(alignment: .bottomTrailing) {
chatItemsList() ChatItemsList(chat: $chat, mergedItems: $mergedItems, revealedItems: $revealedItems, scrollModel: $scrollModel, loadingMoreItems: $loadingMoreItems, allowLoadMoreItems: $allowLoadMoreItems, ignoreLoadingRequests: $ignoreLoadingRequests, searchText: $searchText, theme: $theme)
FloatingButtons(theme: theme, scrollModel: scrollModel, chat: chat, loadingMoreItems: $loadingMoreItems) FloatingButtons(theme: theme, scrollModel: scrollModel, chat: chat, loadingMoreItems: $loadingMoreItems)
} }
connectingText() connectingText()
@ -441,105 +441,120 @@ struct ChatView: View {
} }
} }
struct ChatItemsList: View {
@Binding var chat: Chat
@Binding var mergedItems: MergedItems
@Binding var revealedItems: [Int64]
@Binding var scrollModel: ReverseListScrollModel
@Binding var loadingMoreItems: Bool
@Binding var allowLoadMoreItems: Bool
@Binding var ignoreLoadingRequests: Int64?
@Binding var searchText: String
@Binding var theme: AppTheme
private func chatItemsList() -> some View { var searchValueIsEmpty: Bool { get { searchText.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty } }
let cInfo = chat.chatInfo
return GeometryReader { g in var body: some View {
let _ = logger.debug("LALAL RELOAD \(im.reversedChatItems.count)") let im = ItemsModel.shared
// LALAL CAN I CHANGE BINDING LIKE THIS IN ignoreLoadingRequests? let cInfo = chat.chatInfo
ReverseList(mergedItems: $mergedItems, revealedItems: $revealedItems, unreadCount: Binding.constant(chat.chatStats.unreadCount), scrollState: $scrollModel.state, loadingMoreItems: $loadingMoreItems, allowLoadMoreItems: $allowLoadMoreItems, ignoreLoadingRequests: searchValueIsEmpty ? $ignoreLoadingRequests : Binding.constant(nil)) { index, mergedItem in return GeometryReader { g in
let ci = switch mergedItem { let _ = logger.debug("LALAL RELOAD \(im.reversedChatItems.count)")
case let .single(item, _, _): item.item // LALAL CAN I CHANGE BINDING LIKE THIS IN ignoreLoadingRequests?
case let .grouped(items, _, _, _, _, _, _, _): items.boxedValue.last!.item ReverseList(mergedItems: $mergedItems, revealedItems: $revealedItems, unreadCount: Binding.constant(chat.chatStats.unreadCount), scrollState: $scrollModel.state, loadingMoreItems: $loadingMoreItems, allowLoadMoreItems: $allowLoadMoreItems, ignoreLoadingRequests: searchValueIsEmpty ? $ignoreLoadingRequests : Binding.constant(nil)) { index, mergedItem in
} let ci = switch mergedItem {
let voiceNoFrame = voiceWithoutFrame(ci) case let .single(item, _, _): item.item
let maxWidth = cInfo.chatType == .group case let .grouped(items, _, _, _, _, _, _, _): items.boxedValue.last!.item
? voiceNoFrame }
? (g.size.width - 28) - 42 let voiceNoFrame = voiceWithoutFrame(ci)
: (g.size.width - 28) * 0.84 - 42 let maxWidth = cInfo.chatType == .group
: voiceNoFrame ? voiceNoFrame
? (g.size.width - 32) ? (g.size.width - 28) - 42
: (g.size.width - 32) * 0.84 : (g.size.width - 28) * 0.84 - 42
return ChatItemWithMenu( : voiceNoFrame
chat: $chat, ? (g.size.width - 32)
index: index, : (g.size.width - 32) * 0.84
isLastItem: index == mergedItems.items.count - 1, return ChatItemWithMenu(
chatItem: ci, chat: $chat,
merged: mergedItem, index: index,
maxWidth: maxWidth, isLastItem: index == mergedItems.items.count - 1,
composeState: $composeState, chatItem: ci,
selectedMember: $selectedMember, merged: mergedItem,
showChatInfoSheet: $showChatInfoSheet, maxWidth: maxWidth,
revealedItems: $revealedItems, composeState: $composeState,
selectedChatItems: $selectedChatItems, selectedMember: $selectedMember,
forwardedChatItems: $forwardedChatItems, showChatInfoSheet: $showChatInfoSheet,
reveal: { reveal in revealedItems: $revealedItems,
mergedItem.reveal(reveal, $revealedItems) selectedChatItems: $selectedChatItems,
updateMergedItemsTask?.cancel() forwardedChatItems: $forwardedChatItems,
mergedItems = MergedItems.create(ItemsModel.shared.reversedChatItems, chat.chatStats.unreadCount, revealedItems, ItemsModel.shared.chatState) reveal: { reveal in
mergedItem.reveal(reveal, $revealedItems)
updateMergedItemsTask?.cancel()
mergedItems = MergedItems.create(ItemsModel.shared.reversedChatItems, chat.chatStats.unreadCount, revealedItems, ItemsModel.shared.chatState)
}
)
.environmentObject(theme) // crashes without this line when scrolling to the first unread in ReverseList
.id(ci.id) // Required to trigger `onAppear` on iOS15
} loadItems: { unchecked, pagination, visibleItemIndexesNonReversed in
if unchecked {
await loadChatItemsUnchecked(cInfo, pagination, visibleItemIndexesNonReversed)
} else {
await loadChatItems(cInfo, pagination, visibleItemIndexesNonReversed)
} }
)
.environmentObject(theme) // crashes without this line when scrolling to the first unread in ReverseList
.id(ci.id) // Required to trigger `onAppear` on iOS15
} loadItems: { unchecked, pagination, visibleItemIndexesNonReversed in
if unchecked {
await loadChatItemsUnchecked(cInfo, pagination, visibleItemIndexesNonReversed)
} else {
await loadChatItems(cInfo, pagination, visibleItemIndexesNonReversed)
} }
} .onAppear {
.onAppear { mergedItems = MergedItems.create(im.reversedChatItems, chat.chatStats.unreadCount, revealedItems, ItemsModel.shared.chatState)
mergedItems = MergedItems.create(im.reversedChatItems, chat.chatStats.unreadCount, revealedItems, ItemsModel.shared.chatState) loadLastItems($loadingMoreItems, chat.chatInfo)
loadLastItems($loadingMoreItems, chat.chatInfo) allowLoadMoreItems = false
allowLoadMoreItems = false DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { allowLoadMoreItems = true
allowLoadMoreItems = true }
} }
} .onChange(of: im.reversedChatItems) { items in
.onChange(of: im.reversedChatItems) { items in updateMergedItemsTask?.cancel()
updateMergedItemsTask?.cancel() //updateMergedItemsTask = Task {
updateMergedItemsTask = Task {
let items = MergedItems.create(items, chat.chatStats.unreadCount, revealedItems, ItemsModel.shared.chatState) let items = MergedItems.create(items, chat.chatStats.unreadCount, revealedItems, ItemsModel.shared.chatState)
if Task.isCancelled { //if Task.isCancelled {
return // return
} //}
await MainActor.run { //await MainActor.run {
mergedItems = items mergedItems = items
//}
//}
}
.onChange(of: revealedItems) { revealed in
updateMergedItemsTask?.cancel()
mergedItems = MergedItems.create(im.reversedChatItems, chat.chatStats.unreadCount, revealed, ItemsModel.shared.chatState)
}
.onChange(of: chat.chatStats.unreadCount) { unreadCount in
updateMergedItemsTask?.cancel()
mergedItems = MergedItems.create(im.reversedChatItems, unreadCount, revealedItems, ItemsModel.shared.chatState)
}
.onChange(of: chat.id) { _ in
loadLastItems($loadingMoreItems, chat.chatInfo)
allowLoadMoreItems = false
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
allowLoadMoreItems = true
} }
} }
} .opacity(ItemsModel.shared.isLoading ? 0 : 1)
.onChange(of: revealedItems) { revealed in .padding(.vertical, -InvertedTableView.inset)
updateMergedItemsTask?.cancel() .onTapGesture { hideKeyboard() }
mergedItems = MergedItems.create(im.reversedChatItems, chat.chatStats.unreadCount, revealed, ItemsModel.shared.chatState) .onChange(of: searchText) { _ in
} Task { await loadChat(type: chat.chatInfo.chatType, id: chat.chatInfo.apiId, search: searchText) }
.onChange(of: chat.chatStats.unreadCount) { unreadCount in
updateMergedItemsTask?.cancel()
mergedItems = MergedItems.create(im.reversedChatItems, unreadCount, revealedItems, ItemsModel.shared.chatState)
}
.onChange(of: chat.id) { _ in
loadLastItems($loadingMoreItems, chat.chatInfo)
allowLoadMoreItems = false
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
allowLoadMoreItems = true
} }
} .onChange(of: im.itemAdded) { added in
.opacity(ItemsModel.shared.isLoading ? 0 : 1) if added {
.padding(.vertical, -InvertedTableView.inset) im.itemAdded = false
.onTapGesture { hideKeyboard() } if FloatingButtonModel.shared.isReallyNearBottom {
.onChange(of: searchText) { _ in scrollModel.scrollToBottom()
Task { await loadChat(type: chat.chatInfo.chatType, id: chat.chatInfo.apiId, search: searchText) } }
}
.onChange(of: im.itemAdded) { added in
if added {
im.itemAdded = false
if FloatingButtonModel.shared.isReallyNearBottom {
scrollModel.scrollToBottom()
} }
} }
} }
} }
} }
@ViewBuilder private func connectingText() -> some View { @ViewBuilder private func connectingText() -> some View {
if case let .direct(contact) = chat.chatInfo, if case let .direct(contact) = chat.chatInfo,
!contact.sndReady, !contact.sndReady,
@ -1112,7 +1127,7 @@ struct ChatView: View {
.onAppear { .onAppear {
// LALAL // LALAL
//return () //return ()
if markedRead { if markedRead {
return return
} else { } else {