Фикс: unread badge не сбрасывался markIncomingAsRead теперь вызывается до markAsRead

This commit is contained in:
2026-04-17 03:24:03 +05:00
parent c3c708b5b3
commit 00414a8991
4 changed files with 10 additions and 5 deletions

View File

@@ -1413,11 +1413,11 @@ final class SessionManager {
if context.fromMe {
// Android parity: read sync from another own device means
// incoming messages in this dialog should become read locally.
DialogRepository.shared.markAsRead(opponentKey: opponentKey)
MessageRepository.shared.markIncomingAsRead(
opponentKey: opponentKey,
myPublicKey: ownKey
)
DialogRepository.shared.markAsRead(opponentKey: opponentKey)
// Desktop-active suppression: prevent in-app banner for 30s.
self.desktopActiveDialogs[opponentKey] = Date()
@@ -2043,11 +2043,11 @@ final class SessionManager {
let shouldMarkRead = dialogIsActive && dialogIsReadEligible && fg && !isSystem && !idle
if shouldMarkRead {
DialogRepository.shared.markAsRead(opponentKey: opponentKey)
MessageRepository.shared.markIncomingAsRead(
opponentKey: opponentKey,
myPublicKey: myKey
)
DialogRepository.shared.markAsRead(opponentKey: opponentKey)
if !fromMe && !wasKnownBefore {
// Android/Desktop parity: send read receipt immediately,
// even during sync. 400ms debounce prevents flooding.

View File

@@ -1573,8 +1573,8 @@ private extension ChatDetailView {
func markDialogAsRead() {
guard MessageRepository.shared.isDialogReadEligible(route.publicKey) else { return }
DialogRepository.shared.markAsRead(opponentKey: route.publicKey)
MessageRepository.shared.markIncomingAsRead(opponentKey: route.publicKey, myPublicKey: currentPublicKey)
DialogRepository.shared.markAsRead(opponentKey: route.publicKey)
// Desktop parity: don't send read receipts for system accounts
if !route.isSystemAccount {
SessionManager.shared.sendReadReceipt(toPublicKey: route.publicKey)

View File

@@ -397,12 +397,13 @@ final class OpponentProfileViewController: UIViewController, UIGestureRecognizer
y = expandedH + 16
} else {
// Collapsed: small avatar (SwiftUI: .padding(.top, 16))
// Collapsed: small avatar
headerImageView.alpha = 0
scrimView.alpha = 0
avatarContainer.alpha = 1
y = safeTop + 16
// Avatar starts at same Y as back button side by side, no gap
y = safeTop
avatarContainer.frame = CGRect(x: (w - avatarSize) / 2, y: y, width: avatarSize, height: avatarSize)
avatarHosting?.view.frame = avatarContainer.bounds
y += avatarSize + 12

View File

@@ -127,6 +127,10 @@ final class ChatListViewModel: ObservableObject {
}
func markAsRead(_ dialog: Dialog) {
MessageRepository.shared.markIncomingAsRead(
opponentKey: dialog.opponentKey,
myPublicKey: SessionManager.shared.currentPublicKey
)
DialogRepository.shared.markAsRead(opponentKey: dialog.opponentKey)
}