ios: open chat on first unread, "scroll" to quoted items that were not loaded (#5392)

* ios: open chat on first unread, "scroll" to quoted items that were not loaded

* more changes

* changes

* unused

* fix reveal logic

* debug

* changes

* test

* Revert "test"

This reverts commit 553be124d5.

* change

* change

* changes

* changes

* changes

* commented deceleration logic

* changes

* fixes

* optimized item identifiers to use merged item directly

* fixed counters

* encreased initial and preload counters

* fix initial loading and trimming items

* optimize

* allow marking read

* 10 instead of 5

* performance

* one more parameter in hash

* disable trimming

* performance

* performance - in background

* optimization

* next/prev

* changes

* markread

* finally

* less logs

* read

* change after merge

* trimming, edge cases

* wait until items loaded

* Revert "wait until items loaded"

This reverts commit 895218b978.

* progress indicator

* optimization

* disable scroll helper

* experiment

* Revert "experiment"

This reverts commit c952c9e623.

* jump

* no read

* layoutIfNeeded

* changes

* EndlessScrollView

* read

* changes

* changes

* changes

* reduce time to open a chat (by ~300ms)

* open from the first unread when clicking member chat

* refactored and removed unused code

* handling search emptiness to scroll to correct position

* changes

* read state maintain

* remove protocol

* avoid parsing chatId

* pass chat

* changes

* remove reveal

* refactor spaghetti

* remove ItemsScrollModel

* rename

* remove setUpdateListener

* unused

* optimization

* scrollToTop

* fix

* scrollbar working again

* scrollToBottom

* fix

* scrollBar hiding when not many items on screen

* small safer change

---------

Co-authored-by: Evgeny Poberezkin <evgeny@poberezkin.com>
This commit is contained in:
Stanislav Dmitrenko
2025-02-17 18:21:40 +00:00
committed by GitHub
co-authored by Evgeny Poberezkin
parent 704bab171d
commit 9d1329498b
24 changed files with 2177 additions and 711 deletions
+16 -27
View File
@@ -328,38 +328,27 @@ func apiGetChatTagsAsync() async throws -> [ChatTag] {
let loadItemsPerPage = 50
func apiGetChat(type: ChatType, id: Int64, search: String = "") async throws -> Chat {
let r = await chatSendCmd(.apiGetChat(type: type, id: id, pagination: .last(count: loadItemsPerPage), search: search))
if case let .apiChat(_, chat) = r { return Chat.init(chat) }
func apiGetChat(chatId: ChatId, pagination: ChatPagination, search: String = "") async throws -> (Chat, NavigationInfo) {
let r = await chatSendCmd(.apiGetChat(chatId: chatId, pagination: pagination, search: search))
if case let .apiChat(_, chat, navInfo) = r { return (Chat.init(chat), navInfo ?? NavigationInfo()) }
throw r
}
func apiGetChatItems(type: ChatType, id: Int64, pagination: ChatPagination, search: String = "") async throws -> [ChatItem] {
let r = await chatSendCmd(.apiGetChat(type: type, id: id, pagination: pagination, search: search))
if case let .apiChat(_, chat) = r { return chat.chatItems }
throw r
func loadChat(chat: Chat, search: String = "", clearItems: Bool = true) async {
await loadChat(chatId: chat.chatInfo.id)
}
func loadChat(chat: Chat, search: String = "", clearItems: Bool = true, replaceChat: Bool = false) async {
do {
let cInfo = chat.chatInfo
let m = ChatModel.shared
let im = ItemsModel.shared
m.chatItemStatuses = [:]
if clearItems {
await MainActor.run { im.reversedChatItems = [] }
func loadChat(chatId: ChatId, search: String = "", clearItems: Bool = true) async {
let m = ChatModel.shared
let im = ItemsModel.shared
m.chatItemStatuses = [:]
if clearItems {
await MainActor.run {
im.reversedChatItems = []
ItemsModel.shared.chatItemsChangesListener.cleared()
}
let chat = try await apiGetChat(type: cInfo.chatType, id: cInfo.apiId, search: search)
await MainActor.run {
im.reversedChatItems = chat.chatItems.reversed()
m.updateChatInfo(chat.chatInfo)
if (replaceChat) {
m.replaceChat(chat.chatInfo.id, chat)
}
}
} catch let error {
logger.error("loadChat error: \(responseError(error))")
}
await apiLoadMessages(chatId, search == "" ? .initial(count: loadItemsPerPage) : .last(count: loadItemsPerPage), im.chatState, search, { 0...0 })
}
func apiGetChatItemInfo(type: ChatType, id: Int64, itemId: Int64) async throws -> ChatItemInfo {
@@ -869,7 +858,7 @@ func apiSetConnectionIncognito(connId: Int64, incognito: Bool) async throws -> P
func apiChangeConnectionUser(connId: Int64, userId: Int64) async throws -> PendingContactConnection? {
let r = await chatSendCmd(.apiChangeConnectionUser(connId: connId, userId: userId))
if case let .connectionUserChanged(_, _, toConnection, _) = r {return toConnection}
throw r
}
@@ -2172,7 +2161,7 @@ func processReceivedMsg(_ res: ChatResponse) async {
}
case let .groupLinkConnecting(user, groupInfo, hostMember):
if !active(user) { return }
await MainActor.run {
m.updateGroup(groupInfo)
if let hostConn = hostMember.activeConn {