mirror of
https://github.com/simplex-chat/simplex-chat.git
synced 2024-12-17 17:20:21 +01:00
cleanup
This commit is contained in:
@@ -322,15 +322,15 @@ let loadItemsPerPage = 100
|
||||
let preloadItem = 25
|
||||
let idealChatListSize = 300
|
||||
|
||||
func apiGetChat(type: ChatType, id: Int64, search: String = "") async throws -> (Chat, Int?) {
|
||||
func apiGetChat(type: ChatType, id: Int64, search: String = "") async throws -> Chat {
|
||||
let r = await chatSendCmd(.apiGetChat(type: type, id: id, pagination: .initial(count: loadItemsPerPage), search: search))
|
||||
if case let .apiChat(_, chat, gap) = r { return (Chat.init(chat), gap) }
|
||||
if case let .apiChat(_, chat, _) = r { return Chat.init(chat) }
|
||||
throw r
|
||||
}
|
||||
|
||||
func apiGetChatItems(type: ChatType, id: Int64, pagination: ChatPagination, search: String = "") async throws -> ([ChatItem], Int?) {
|
||||
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, gap) = r { return (chat.chatItems, gap) }
|
||||
if case let .apiChat(_, chat, _) = r { return chat.chatItems }
|
||||
if case .chatCmdError(_, _) = r {
|
||||
if case .chatError(_, let chatError) = r {
|
||||
if case .errorStore(let storeError) = chatError {
|
||||
@@ -355,14 +355,9 @@ func loadChat(chat: Chat, search: String = "", clearItems: Bool = true) async {
|
||||
im.gap = nil
|
||||
}
|
||||
}
|
||||
let (chat, gap) = try await apiGetChat(type: cInfo.chatType, id: cInfo.apiId, search: search)
|
||||
let chat = try await apiGetChat(type: cInfo.chatType, id: cInfo.apiId, search: search)
|
||||
await MainActor.run {
|
||||
im.reversedChatItems = chat.chatItems.reversed()
|
||||
if let gap = gap {
|
||||
im.gap = ChatGap(index: loadItemsPerPage, size: gap)
|
||||
} else {
|
||||
im.gap = nil
|
||||
}
|
||||
m.updateChatInfo(chat.chatInfo)
|
||||
}
|
||||
} catch let error {
|
||||
|
||||
@@ -349,7 +349,7 @@ struct FramedItemView: View {
|
||||
let im = ItemsModel.shared
|
||||
var reversedPage = Array<ChatItem>()
|
||||
let pagination: ChatPagination = .around(chatItemId: chatItemId, count: loadItemsPerPage * 2)
|
||||
let (chatItems, gap) = try await apiGetChatItems(
|
||||
let chatItems = try await apiGetChatItems(
|
||||
type: cInfo.chatType,
|
||||
id: cInfo.apiId,
|
||||
pagination: pagination,
|
||||
@@ -366,18 +366,12 @@ struct FramedItemView: View {
|
||||
}
|
||||
|
||||
let itemCount = im.reversedChatItems.count
|
||||
if let size = gap, size - itemCount > 0 {
|
||||
im.gap = ChatGap(index: itemCount, size: size - itemCount)
|
||||
}
|
||||
im.reversedChatItems.append(contentsOf: reversedPage)
|
||||
}
|
||||
|
||||
if (itemsToDrop.count > 0) {
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
|
||||
Task {
|
||||
if let g = im.gap {
|
||||
im.gap = ChatGap(index: g.index - itemsToDrop.count, size: g.size + itemsToDrop.count)
|
||||
}
|
||||
im.reversedChatItems.removeAll(where: { itemsToDrop.contains($0.id) })
|
||||
}
|
||||
}
|
||||
|
||||
@@ -427,7 +427,7 @@ struct ChatView: View {
|
||||
let cInfo = chat.chatInfo
|
||||
let mergedItems = filtered(im.reversedChatItems)
|
||||
return GeometryReader { g in
|
||||
ReverseList(items: mergedItems, gap: im.gap, scrollState: $scrollModel.state, initialChatItem: $initialChatItem) { ci in
|
||||
ReverseList(items: mergedItems, scrollState: $scrollModel.state, initialChatItem: $initialChatItem) { ci in
|
||||
let voiceNoFrame = voiceWithoutFrame(ci)
|
||||
let maxWidth = cInfo.chatType == .group
|
||||
? voiceNoFrame
|
||||
@@ -485,7 +485,6 @@ struct ChatView: View {
|
||||
scrollModel.scrollToBottom()
|
||||
if let g = im.gap {
|
||||
let sliceSize = min(g.index, idealChatListSize)
|
||||
im.gap = nil
|
||||
im.reversedChatItems = Array(im.reversedChatItems[..<sliceSize])
|
||||
}
|
||||
}
|
||||
@@ -893,7 +892,6 @@ struct ChatView: View {
|
||||
loadingItems = true
|
||||
do {
|
||||
var reversedPage = Array<ChatItem>()
|
||||
var apiGap: Int? = nil
|
||||
var chatItemsAvailable = true
|
||||
// Load additional items until the page is +50 large after merging
|
||||
while chatItemsAvailable && filtered(reversedPage).count < loadItemsPerPage {
|
||||
@@ -906,13 +904,12 @@ struct ChatView: View {
|
||||
case .around(_, _): throw RuntimeError("Unsupported pagination type for loading chat items: \(pagination)")
|
||||
}
|
||||
|
||||
let (chatItems, gap) = try await apiGetChatItems(
|
||||
let chatItems = try await apiGetChatItems(
|
||||
type: cInfo.chatType,
|
||||
id: cInfo.apiId,
|
||||
pagination: chatPagination,
|
||||
search: searchText
|
||||
)
|
||||
apiGap = gap
|
||||
chatItemsAvailable = !chatItems.isEmpty
|
||||
reversedPage.append(contentsOf: chatItems.reversed())
|
||||
}
|
||||
@@ -928,28 +925,12 @@ struct ChatView: View {
|
||||
case .before(_, _):
|
||||
if im.reversedChatItems.count + dedupedreversePage.count > idealChatListSize,
|
||||
dedupedreversePage.count <= loadItemsPerPage {
|
||||
if let gap = im.gap {
|
||||
im.gap = ChatGap(index: gap.index, size: gap.size + dedupedreversePage.count)
|
||||
} else {
|
||||
im.gap = ChatGap(index: loadItemsPerPage, size: dedupedreversePage.count)
|
||||
}
|
||||
im.reversedChatItems.removeSubrange(loadItemsPerPage..<loadItemsPerPage + dedupedreversePage.count)
|
||||
}
|
||||
im.reversedChatItems.append(contentsOf: dedupedreversePage)
|
||||
case let .after(chatItemId, _):
|
||||
let index = im.reversedChatItems.firstIndex { $0.id == chatItemId }
|
||||
if let index {
|
||||
if let gap = im.gap {
|
||||
let size = max(0, (apiGap ?? 0) - index)
|
||||
if size > 0 {
|
||||
im.gap = ChatGap(index: gap.index, size: size)
|
||||
if im.reversedChatItems.count + dedupedreversePage.count - gap.index > idealChatListSize {
|
||||
im.reversedChatItems.removeLast(dedupedreversePage.count)
|
||||
}
|
||||
} else {
|
||||
im.gap = nil
|
||||
}
|
||||
}
|
||||
im.reversedChatItems.insert(contentsOf: dedupedreversePage, at: index)
|
||||
}
|
||||
case .around(_, _): break
|
||||
|
||||
@@ -340,7 +340,7 @@ struct GroupMemberInfoView: View {
|
||||
InfoViewButton(image: "message.fill", title: "message", width: width) {
|
||||
Task {
|
||||
do {
|
||||
let (chat, _) = try await apiGetChat(type: .direct, id: contactId)
|
||||
let chat = try await apiGetChat(type: .direct, id: contactId)
|
||||
chatModel.addChat(chat)
|
||||
ItemsModel.shared.loadOpenChat(chat.id) {
|
||||
dismissAllSheets(animated: true)
|
||||
|
||||
@@ -13,7 +13,6 @@ import SimpleXChat
|
||||
/// A List, which displays it's items in reverse order - from bottom to top
|
||||
struct ReverseList<Content: View>: UIViewControllerRepresentable {
|
||||
let items: Array<ChatItem>
|
||||
let gap: ChatGap?
|
||||
|
||||
@Binding var scrollState: ReverseListScrollModel.State
|
||||
@Binding var initialChatItem: ChatItem?
|
||||
@@ -40,7 +39,7 @@ struct ReverseList<Content: View>: UIViewControllerRepresentable {
|
||||
controller.scroll(to: 0, position: .top)
|
||||
}
|
||||
} else {
|
||||
controller.update(items: items, gap: gap)
|
||||
controller.update(items: items)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,7 +51,6 @@ struct ReverseList<Content: View>: UIViewControllerRepresentable {
|
||||
private var itemCount: Int = 0
|
||||
private let updateFloatingButtons = PassthroughSubject<Void, Never>()
|
||||
private var bag = Set<AnyCancellable>()
|
||||
private var renderedItems = Array<ChatItem>()
|
||||
|
||||
init(representer: ReverseList) {
|
||||
self.representer = representer
|
||||
@@ -222,27 +220,15 @@ struct ReverseList<Content: View>: UIViewControllerRepresentable {
|
||||
}
|
||||
}
|
||||
|
||||
func update(items: [ChatItem], gap: ChatGap?) {
|
||||
func update(items: [ChatItem]) {
|
||||
var snapshot = NSDiffableDataSourceSnapshot<Section, ChatItem>()
|
||||
let originalSize = renderedItems.count
|
||||
if let gap = gap {
|
||||
var itemsCopy = items
|
||||
let blanks = (0..<20).map { index in
|
||||
// Using existing text instead of random rumble or empty text does make long scroll look natural.
|
||||
let sourceItem = items[index % items.count]
|
||||
return ChatItem.placeholder(idx: index + 1, text: sourceItem.text, chatDir: sourceItem.chatDir)
|
||||
}
|
||||
itemsCopy.insert(contentsOf: blanks, at: gap.index)
|
||||
renderedItems = itemsCopy
|
||||
} else {
|
||||
renderedItems = items
|
||||
}
|
||||
let originalSize = tableView.numberOfRows(inSection: 0)
|
||||
snapshot.appendSections([.main])
|
||||
snapshot.appendItems(renderedItems)
|
||||
snapshot.appendItems(items)
|
||||
dataSource.defaultRowAnimation = .none
|
||||
|
||||
let countDiff = max(0, renderedItems.count - originalSize)
|
||||
if tableView.contentOffset.y == 0, originalSize > countDiff {
|
||||
let countDiff = max(0, items.count - originalSize)
|
||||
if tableView.contentOffset.y == 100, originalSize < items.count, originalSize > 0 {
|
||||
dataSource.apply(
|
||||
snapshot,
|
||||
animatingDifferences: false
|
||||
@@ -269,7 +255,7 @@ struct ReverseList<Content: View>: UIViewControllerRepresentable {
|
||||
animated: false
|
||||
)
|
||||
}
|
||||
itemCount = renderedItems.count
|
||||
itemCount = items.count
|
||||
updateFloatingButtons.send()
|
||||
}
|
||||
|
||||
@@ -279,18 +265,18 @@ struct ReverseList<Content: View>: UIViewControllerRepresentable {
|
||||
|
||||
func getListState() -> ListState? {
|
||||
if let visibleRows = tableView.indexPathsForVisibleRows,
|
||||
visibleRows.last?.item ?? 0 < renderedItems.count {
|
||||
visibleRows.last?.item ?? 0 < representer.items.count {
|
||||
let scrollOffset: Double = tableView.contentOffset.y + InvertedTableView.inset
|
||||
|
||||
let topItemDate: Date? =
|
||||
if let lastVisible = visibleRows.last(where: { isVisible(indexPath: $0) }) {
|
||||
renderedItems[lastVisible.item].meta.itemTs
|
||||
representer.items[lastVisible.item].meta.itemTs
|
||||
} else {
|
||||
nil
|
||||
}
|
||||
let bottomItemId: ChatItem.ID? =
|
||||
if let firstVisible = visibleRows.first(where: { isVisible(indexPath: $0) }) {
|
||||
renderedItems[firstVisible.item].id
|
||||
representer.items[firstVisible.item].id
|
||||
} else {
|
||||
nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user