mirror of
https://github.com/simplex-chat/simplex-chat.git
synced 2026-05-08 02:27:07 +00:00
point based nearBottom
This commit is contained in:
@@ -897,21 +897,14 @@ final class ChatModel: ObservableObject {
|
||||
|
||||
func unreadChatItemCounts(itemsInView: Set<String>) -> UnreadChatItemCounts {
|
||||
var i = 0
|
||||
var totalBelow = 0
|
||||
var unreadBelow = 0
|
||||
while i < im.reversedChatItems.count - 1 && !itemsInView.contains(im.reversedChatItems[i].viewId) {
|
||||
totalBelow += 1
|
||||
if im.reversedChatItems[i].isRcvNew {
|
||||
unreadBelow += 1
|
||||
}
|
||||
i += 1
|
||||
}
|
||||
return UnreadChatItemCounts(
|
||||
// TODO these thresholds account for the fact that items are still "visible" while
|
||||
// covered by compose area, they should be replaced with the actual height in pixels below the screen.
|
||||
isNearBottom: totalBelow < 15,
|
||||
unreadBelow: unreadBelow
|
||||
)
|
||||
return UnreadChatItemCounts(unreadBelow: unreadBelow)
|
||||
}
|
||||
|
||||
func topItemInView(itemsInView: Set<String>) -> ChatItem? {
|
||||
@@ -935,7 +928,6 @@ struct NTFContactRequest {
|
||||
}
|
||||
|
||||
struct UnreadChatItemCounts: Equatable {
|
||||
var isNearBottom: Bool
|
||||
var unreadBelow: Int
|
||||
}
|
||||
|
||||
|
||||
@@ -395,7 +395,11 @@ struct ChatView: View {
|
||||
let cInfo = chat.chatInfo
|
||||
let mergedItems = filtered(im.reversedChatItems)
|
||||
return GeometryReader { g in
|
||||
ReverseList(items: mergedItems, scrollState: $scrollModel.state) { ci in
|
||||
ReverseList(
|
||||
items: mergedItems,
|
||||
scrollState: $scrollModel.state,
|
||||
isFarFromBottom: $scrollModel.isFarFromBottom
|
||||
) { ci in
|
||||
let voiceNoFrame = voiceWithoutFrame(ci)
|
||||
let maxWidth = cInfo.chatType == .group
|
||||
? voiceNoFrame
|
||||
@@ -470,10 +474,7 @@ struct ChatView: View {
|
||||
private var bag = Set<AnyCancellable>()
|
||||
|
||||
init() {
|
||||
unreadChatItemCounts = UnreadChatItemCounts(
|
||||
isNearBottom: true,
|
||||
unreadBelow: 0
|
||||
)
|
||||
unreadChatItemCounts = UnreadChatItemCounts(unreadBelow: 0)
|
||||
events
|
||||
.receive(on: DispatchQueue.global(qos: .background))
|
||||
.scan(Set<String>()) { itemsInView, event in
|
||||
@@ -537,7 +538,7 @@ struct ChatView: View {
|
||||
.onTapGesture {
|
||||
scrollModel.scrollToBottom()
|
||||
}
|
||||
} else if !counts.isNearBottom {
|
||||
} else if scrollModel.isFarFromBottom {
|
||||
circleButton {
|
||||
Image(systemName: "chevron.down")
|
||||
.foregroundColor(theme.colors.primary)
|
||||
|
||||
@@ -14,6 +14,7 @@ struct ReverseList<Item: Identifiable & Hashable & Sendable, Content: View>: UIV
|
||||
let items: Array<Item>
|
||||
|
||||
@Binding var scrollState: ReverseListScrollModel<Item>.State
|
||||
@Binding var isFarFromBottom: Bool
|
||||
|
||||
/// Closure, that returns user interface for a given item
|
||||
let content: (Item) -> Content
|
||||
@@ -175,16 +176,22 @@ struct ReverseList<Item: Identifiable & Hashable & Sendable, Content: View>: UIV
|
||||
)
|
||||
}
|
||||
|
||||
override func scrollViewDidScroll(_ scrollView: UIScrollView) {
|
||||
let adjustedOffset = tableView.contentOffset.y + InvertedTableView.inset
|
||||
if representer.isFarFromBottom {
|
||||
if adjustedOffset < 800 {
|
||||
DispatchQueue.main.async { self.representer.isFarFromBottom = false }
|
||||
}
|
||||
} else if adjustedOffset > 1000 {
|
||||
DispatchQueue.main.async { self.representer.isFarFromBottom = true }
|
||||
}
|
||||
}
|
||||
|
||||
private var isNearBottom: Bool {
|
||||
let adjustedOffset = tableView.contentOffset.y + InvertedTableView.inset
|
||||
return adjustedOffset > 0 && adjustedOffset < 500
|
||||
}
|
||||
|
||||
private var isFarFromBottom: Bool {
|
||||
let adjustedOffset = tableView.contentOffset.y + InvertedTableView.inset
|
||||
return adjustedOffset > 1000
|
||||
}
|
||||
|
||||
private var itemId: Item.ID?
|
||||
private var retainedItems: [Item]?
|
||||
private var updateInProgress = false
|
||||
@@ -217,7 +224,7 @@ struct ReverseList<Item: Identifiable & Hashable & Sendable, Content: View>: UIV
|
||||
itemCount = items.count
|
||||
}
|
||||
|
||||
func _update(items: Array<Item>, animated: Bool, completion: (() -> Void)? = nil) {
|
||||
private func _update(items: [Item], animated: Bool, completion: (() -> Void)? = nil) {
|
||||
var snapshot = NSDiffableDataSourceSnapshot<Section, Item>()
|
||||
snapshot.appendSections([.main])
|
||||
snapshot.appendItems(items)
|
||||
@@ -281,6 +288,7 @@ class ReverseListScrollModel<Item: Identifiable>: ObservableObject {
|
||||
}
|
||||
|
||||
@Published var state: State = .atDestination
|
||||
@Published var isFarFromBottom: Bool = false
|
||||
|
||||
func scrollToNextPage() {
|
||||
state = .scrollingTo(.nextPage)
|
||||
|
||||
Reference in New Issue
Block a user