mirror of
https://github.com/simplex-chat/simplex-chat.git
synced 2026-10-23 12:53:18 +00:00
debug
This commit is contained in:
1 parent
449f15ea0e
commit
a4a268310b
4 files changed
+120
-11
No files matched your search
@@ -0,0 +1,27 @@
|
||||
//
|
||||
// ChatScrollHelpers.swift
|
||||
// SimpleX (iOS)
|
||||
//
|
||||
// Created by me on 20.12.2024.
|
||||
// Copyright © 2024 SimpleX Chat. All rights reserved.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
import SimpleXChat
|
||||
|
||||
func loadLastItems(_ loadingMoreItems: Binding<Bool>, _ chatInfo: ChatInfo) {
|
||||
//return ()
|
||||
Task {
|
||||
try? await Task.sleep(nanoseconds: 2500_000000)
|
||||
if ItemsModel.shared.chatState.totalAfter == 0 || ChatModel.shared.chatId != chatInfo.id {
|
||||
return
|
||||
}
|
||||
await MainActor.run {
|
||||
loadingMoreItems.wrappedValue = true
|
||||
}
|
||||
await apiLoadMessages(chatInfo.chatType, chatInfo.apiId, ChatPagination.last(count: 50), ItemsModel.shared.chatState)
|
||||
await MainActor.run {
|
||||
loadingMoreItems.wrappedValue = false
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -465,12 +465,14 @@ struct ChatView: View {
|
||||
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: { pagination, visibleItemIndexesNonReversed in
|
||||
loadChatItems(cInfo, pagination, visibleItemIndexesNonReversed)
|
||||
}
|
||||
.onAppear {
|
||||
mergedItems = MergedItems.create(im.reversedChatItems, chat.chatStats.unreadCount, revealedItems, ItemsModel.shared.chatState)
|
||||
loadLastItems($loadingItems, chat.chatInfo)
|
||||
}
|
||||
.onChange(of: im.reversedChatItems) { items in
|
||||
mergedItems = MergedItems.create(items, chat.chatStats.unreadCount, revealedItems, ItemsModel.shared.chatState)
|
||||
@@ -481,6 +483,9 @@ struct ChatView: View {
|
||||
.onChange(of: chat.chatStats.unreadCount) { unreadCount in
|
||||
mergedItems = MergedItems.create(im.reversedChatItems, unreadCount, revealedItems, ItemsModel.shared.chatState)
|
||||
}
|
||||
.onChange(of: chat.id) { _ in
|
||||
loadLastItems($loadingItems, chat.chatInfo)
|
||||
}
|
||||
.opacity(ItemsModel.shared.isLoading ? 0 : 1)
|
||||
.padding(.vertical, -InvertedTableView.inset)
|
||||
.onTapGesture { hideKeyboard() }
|
||||
@@ -1032,6 +1037,8 @@ struct ChatView: View {
|
||||
}
|
||||
}
|
||||
.onAppear {
|
||||
// LALAL
|
||||
return ()
|
||||
if markedRead {
|
||||
return
|
||||
} else {
|
||||
|
||||
@@ -60,6 +60,8 @@ struct ReverseList<Content: View>: UIViewControllerRepresentable {
|
||||
private let updateFloatingButtons = PassthroughSubject<Void, Never>()
|
||||
private var bag = Set<AnyCancellable>()
|
||||
|
||||
private var scrollToRowOnAppear = 0
|
||||
|
||||
init(representer: ReverseList) {
|
||||
self.representer = representer
|
||||
super.init(style: .plain)
|
||||
@@ -156,6 +158,31 @@ struct ReverseList<Content: View>: UIViewControllerRepresentable {
|
||||
NotificationCenter.default.post(name: .chatViewWillBeginScrolling, object: nil)
|
||||
}
|
||||
|
||||
/// depending on tableView layout phase conditions, it can already have known size or not. Not possible to correctly scroll to required
|
||||
/// item if the size is unknown
|
||||
func scrollToRowWhenKnowSize(_ row: Int) {
|
||||
// logger.debug("LALAL WILL SCROLL TO \(self.scrollToRowOnAppear)")
|
||||
if row > 0 && tableView.visibleSize.height > 0 {
|
||||
// logger.debug("LALAL OFFSET before \(self.tableView.contentOffset.y), visible \(self.tableView.visibleSize.height) \(self.tableView.frame.height) \(self.view.frame.height) \(self.tableView.indexPathsForVisibleRows!)")
|
||||
//tableView.setContentOffset(CGPointMake(0, tableView.contentOffset.y - tableView.visibleSize.height), animated: false)
|
||||
tableView.scrollToRow(at: IndexPath(item: min(tableView.numberOfRows(inSection: 0) - 1, row), section: 0), at: .bottom, animated: false)
|
||||
// Without this small scroll position is not correct pixel-to-pixel.
|
||||
// Only needed when viewDidAppear has not been called yet because in there clipsToBounds is applied
|
||||
if tableView.clipsToBounds {
|
||||
tableView.setContentOffset(CGPointMake(0, tableView.contentOffset.y - 5), animated: false)
|
||||
}
|
||||
// logger.debug("LALAL OFFSET after \(self.tableView.contentOffset.y) \(self.tableView.indexPathsForVisibleRows!)")
|
||||
scrollToRowOnAppear = 0
|
||||
} else {
|
||||
scrollToRowOnAppear = row
|
||||
}
|
||||
}
|
||||
|
||||
override public func viewIsAppearing(_ animated: Bool) {
|
||||
super.viewIsAppearing(animated)
|
||||
scrollToRowWhenKnowSize(scrollToRowOnAppear)
|
||||
}
|
||||
|
||||
override func viewDidAppear(_ animated: Bool) {
|
||||
tableView.clipsToBounds = false
|
||||
parent?.viewIfLoaded?.clipsToBounds = false
|
||||
@@ -196,23 +223,67 @@ struct ReverseList<Content: View>: UIViewControllerRepresentable {
|
||||
}
|
||||
|
||||
func update(items: [ChatItem]) {
|
||||
let wasCount = dataSource.snapshot().numberOfItems
|
||||
var prevSnapshot = dataSource.snapshot()
|
||||
let wasCount = prevSnapshot.numberOfItems
|
||||
let insertedOneNewestItem = wasCount != 0 && representer.mergedItems.items.count - wasCount == 1 && prevSnapshot.itemIdentifiers.first! == self.representer.mergedItems.items[1]
|
||||
logger.debug("LALAL WAS \(wasCount) will be \(self.representer.mergedItems.items.count)")
|
||||
//self.representer.mergedItems = MergedItems.create(items, representer.unreadCount, representer.revealedItems, ItemsModel.shared.chatState)
|
||||
var snapshot = NSDiffableDataSourceSnapshot<Section, MergedItem>()
|
||||
snapshot.appendSections([.main])
|
||||
snapshot.appendItems(representer.mergedItems.items)
|
||||
let snapshot: NSDiffableDataSourceSnapshot<Section, MergedItem>
|
||||
if insertedOneNewestItem {
|
||||
prevSnapshot.insertItems([representer.mergedItems.items.first!], beforeItem: prevSnapshot.itemIdentifiers.first!)
|
||||
snapshot = prevSnapshot
|
||||
} else {
|
||||
var snap = NSDiffableDataSourceSnapshot<Section, MergedItem>()
|
||||
snap.appendSections([.main])
|
||||
snap.appendItems(representer.mergedItems.items)
|
||||
|
||||
if snap.itemIdentifiers == prevSnapshot.itemIdentifiers {
|
||||
logger.debug("LALAL SAME ITEMS, not rebuilding the tableview")
|
||||
return
|
||||
}
|
||||
|
||||
snapshot = snap
|
||||
}
|
||||
dataSource.defaultRowAnimation = .none
|
||||
dataSource.apply(
|
||||
snapshot,
|
||||
animatingDifferences: wasCount != 0 && abs(representer.mergedItems.items.count - wasCount) == 1
|
||||
)
|
||||
let wasContentHeight = tableView.contentSize.height
|
||||
let wasOffset = tableView.contentOffset.y
|
||||
let countDiff = max(0, snapshot.numberOfItems - prevSnapshot.numberOfItems)
|
||||
// Sets content offset on initial load
|
||||
if wasCount == 0 {
|
||||
tableView.setContentOffset(
|
||||
CGPoint(x: 0, y: -InvertedTableView.inset),
|
||||
animated: false
|
||||
dataSource.apply(
|
||||
snapshot,
|
||||
animatingDifferences: insertedOneNewestItem
|
||||
)
|
||||
if let firstUnreadItem = snapshot.itemIdentifiers.lastIndex(where: { merged in merged.hasUnread() }) {
|
||||
scrollToRowWhenKnowSize(firstUnreadItem)
|
||||
} else {
|
||||
tableView.setContentOffset(
|
||||
CGPoint(x: 0, y: -InvertedTableView.inset),
|
||||
animated: false
|
||||
)
|
||||
}
|
||||
} else if wasCount != snapshot.numberOfItems {
|
||||
tableView.beginUpdates()
|
||||
dataSource.apply(
|
||||
snapshot,
|
||||
animatingDifferences: false
|
||||
)
|
||||
// tableView.scrollToRow(
|
||||
// at: IndexPath(row: countDiff, section: 0),
|
||||
// at: .top,
|
||||
// animated: false
|
||||
// )
|
||||
tableView.endUpdates()
|
||||
// if snapshot.itemIdentifiers[0].newest().item.id == prevSnapshot.itemIdentifiers[0].newest().item.id {
|
||||
// // added new items to top
|
||||
// } else {
|
||||
// // added new items to bottom
|
||||
// logger.debug("LALAL WAS HEIGHT \(wasContentHeight) now \(self.tableView.contentSize.height), offset was \(wasOffset), now \(self.tableView.contentOffset.y), will be \(self.tableView.contentOffset.y + (self.tableView.contentSize.height - wasContentHeight))")
|
||||
// DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
|
||||
// self.tableView.setContentOffset(CGPointMake(0, self.tableView.contentOffset.y + (self.tableView.contentSize.height - wasContentHeight)), animated: false)
|
||||
// }
|
||||
// }
|
||||
|
||||
}
|
||||
updateFloatingButtons.send()
|
||||
}
|
||||
|
||||
@@ -198,6 +198,7 @@
|
||||
8C8118722C220B5B00E6FC94 /* Yams in Frameworks */ = {isa = PBXBuildFile; productRef = 8C8118712C220B5B00E6FC94 /* Yams */; };
|
||||
8C81482C2BD91CD4002CBEC3 /* AudioDevicePicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8C81482B2BD91CD4002CBEC3 /* AudioDevicePicker.swift */; };
|
||||
8C9BC2652C240D5200875A27 /* ThemeModeEditor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8C9BC2642C240D5100875A27 /* ThemeModeEditor.swift */; };
|
||||
8CAD466F2D15A8100078D18F /* ChatScrollHelpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8CAD466E2D15A8100078D18F /* ChatScrollHelpers.swift */; };
|
||||
8CAEF1502D11A6A000240F00 /* ChatItemsLoader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8CAEF14F2D11A6A000240F00 /* ChatItemsLoader.swift */; };
|
||||
8CB15EA02CFDA30600C28209 /* ChatItemsMerger.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8CB15E9F2CFDA30600C28209 /* ChatItemsMerger.swift */; };
|
||||
8CB3476C2CF5CFFA006787A5 /* Ink in Frameworks */ = {isa = PBXBuildFile; productRef = 8CB3476B2CF5CFFA006787A5 /* Ink */; };
|
||||
@@ -549,6 +550,7 @@
|
||||
8C852B072C1086D100BA61E8 /* Color.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Color.swift; sourceTree = "<group>"; };
|
||||
8C86EBE42C0DAE4F00E12243 /* ThemeManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThemeManager.swift; sourceTree = "<group>"; };
|
||||
8C9BC2642C240D5100875A27 /* ThemeModeEditor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThemeModeEditor.swift; sourceTree = "<group>"; };
|
||||
8CAD466E2D15A8100078D18F /* ChatScrollHelpers.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatScrollHelpers.swift; sourceTree = "<group>"; };
|
||||
8CAEF14F2D11A6A000240F00 /* ChatItemsLoader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatItemsLoader.swift; sourceTree = "<group>"; };
|
||||
8CB15E9F2CFDA30600C28209 /* ChatItemsMerger.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatItemsMerger.swift; sourceTree = "<group>"; };
|
||||
8CB3476D2CF5F58B006787A5 /* ConditionsWebView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConditionsWebView.swift; sourceTree = "<group>"; };
|
||||
@@ -750,6 +752,7 @@
|
||||
8CE848A22C5A0FA000D5C7C8 /* SelectableChatItemToolbars.swift */,
|
||||
8CB15E9F2CFDA30600C28209 /* ChatItemsMerger.swift */,
|
||||
8CAEF14F2D11A6A000240F00 /* ChatItemsLoader.swift */,
|
||||
8CAD466E2D15A8100078D18F /* ChatScrollHelpers.swift */,
|
||||
);
|
||||
path = Chat;
|
||||
sourceTree = "<group>";
|
||||
@@ -1507,6 +1510,7 @@
|
||||
5C6BA667289BD954009B8ECC /* DismissSheets.swift in Sources */,
|
||||
5C577F7D27C83AA10006112D /* MarkdownHelp.swift in Sources */,
|
||||
6407BA83295DA85D0082BA18 /* CIInvalidJSONView.swift in Sources */,
|
||||
8CAD466F2D15A8100078D18F /* ChatScrollHelpers.swift in Sources */,
|
||||
644EFFDE292BCD9D00525D5B /* ComposeVoiceView.swift in Sources */,
|
||||
5CA059EB279559F40002BEB4 /* SimpleXApp.swift in Sources */,
|
||||
64D0C2C029F9688300B38D5F /* UserAddressView.swift in Sources */,
|
||||
|
||||
Reference in new issue
Block a user