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

View File

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

View File

@@ -397,12 +397,13 @@ final class OpponentProfileViewController: UIViewController, UIGestureRecognizer
y = expandedH + 16 y = expandedH + 16
} else { } else {
// Collapsed: small avatar (SwiftUI: .padding(.top, 16)) // Collapsed: small avatar
headerImageView.alpha = 0 headerImageView.alpha = 0
scrimView.alpha = 0 scrimView.alpha = 0
avatarContainer.alpha = 1 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) avatarContainer.frame = CGRect(x: (w - avatarSize) / 2, y: y, width: avatarSize, height: avatarSize)
avatarHosting?.view.frame = avatarContainer.bounds avatarHosting?.view.frame = avatarContainer.bounds
y += avatarSize + 12 y += avatarSize + 12

View File

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