From 7dbddb27a6b745f81217616cb90e02ac7ca94b35 Mon Sep 17 00:00:00 2001 From: senseiGai Date: Fri, 13 Mar 2026 00:37:36 +0500 Subject: [PATCH] =?UTF-8?q?=D0=9F=D0=BE=D0=B4=D0=B0=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D0=B5=20=D1=83=D0=B2=D0=B5=D0=B4=D0=BE=D0=BC=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=D0=B8=D0=B9=20=D0=B2=20=D0=BE=D1=82=D0=BA=D1=80?= =?UTF-8?q?=D1=8B=D1=82=D0=BE=D0=BC=20=D1=87=D0=B0=D1=82=D0=B5,=20=D1=83?= =?UTF-8?q?=D1=81=D0=BA=D0=BE=D1=80=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=BF=D0=B5?= =?UTF-8?q?=D1=80=D0=B5=D1=85=D0=BE=D0=B4=D0=BE=D0=B2=20=D0=BC=D0=B5=D0=B6?= =?UTF-8?q?=D0=B4=D1=83=20=D1=8D=D0=BA=D1=80=D0=B0=D0=BD=D0=B0=D0=BC=D0=B8?= =?UTF-8?q?,=20=D0=B8=D0=BD=D0=B8=D1=86=D0=B8=D0=B0=D0=BB=D1=8B=20=D0=BD?= =?UTF-8?q?=D0=B0=20=D1=8D=D0=BA=D1=80=D0=B0=D0=BD=D0=B5=20=D1=80=D0=B0?= =?UTF-8?q?=D0=B7=D0=B1=D0=BB=D0=BE=D0=BA=D0=B8=D1=80=D0=BE=D0=B2=D0=BA?= =?UTF-8?q?=D0=B8,=20=D0=BF=D0=BB=D0=B0=D0=B2=D0=BD=D1=8B=D0=B9=20keyboard?= =?UTF-8?q?=20offset?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Rosetta.xcodeproj/project.pbxproj | 4 ++-- Rosetta/Features/Auth/AuthCoordinator.swift | 6 +++--- Rosetta/Features/Chats/ChatDetail/ChatDetailView.swift | 9 ++++++--- Rosetta/RosettaApp.swift | 6 +++--- 4 files changed, 14 insertions(+), 11 deletions(-) diff --git a/Rosetta.xcodeproj/project.pbxproj b/Rosetta.xcodeproj/project.pbxproj index db40619..906df3f 100644 --- a/Rosetta.xcodeproj/project.pbxproj +++ b/Rosetta.xcodeproj/project.pbxproj @@ -288,7 +288,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.0.10; + MARKETING_VERSION = 1.1.0; PRODUCT_BUNDLE_IDENTIFIER = com.rosetta.dev; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -327,7 +327,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.0.10; + MARKETING_VERSION = 1.1.0; PRODUCT_BUNDLE_IDENTIFIER = com.rosetta.dev; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; diff --git a/Rosetta/Features/Auth/AuthCoordinator.swift b/Rosetta/Features/Auth/AuthCoordinator.swift index b8477d2..5b275b3 100644 --- a/Rosetta/Features/Auth/AuthCoordinator.swift +++ b/Rosetta/Features/Auth/AuthCoordinator.swift @@ -68,7 +68,7 @@ struct AuthCoordinator: View { .ignoresSafeArea() .opacity(fadeOverlay ? 1 : 0) .allowsHitTesting(fadeOverlay) - .animation(.easeInOut(duration: 0.08), value: fadeOverlay) + .animation(.easeInOut(duration: 0.035), value: fadeOverlay) } .overlay(alignment: .leading) { if canSwipeBack { @@ -174,9 +174,9 @@ private extension AuthCoordinator { navigationDirection = .forward fadeOverlay = true Task { @MainActor in - try? await Task.sleep(nanoseconds: 80_000_000) + try? await Task.sleep(nanoseconds: 35_000_000) currentScreen = screen - try? await Task.sleep(nanoseconds: 20_000_000) + try? await Task.sleep(nanoseconds: 10_000_000) fadeOverlay = false } } diff --git a/Rosetta/Features/Chats/ChatDetail/ChatDetailView.swift b/Rosetta/Features/Chats/ChatDetail/ChatDetailView.swift index 9eda262..e1c52a4 100644 --- a/Rosetta/Features/Chats/ChatDetail/ChatDetailView.swift +++ b/Rosetta/Features/Chats/ChatDetail/ChatDetailView.swift @@ -119,19 +119,22 @@ struct ChatDetailView: View { .toolbar(.hidden, for: .tabBar) .task { isViewActive = true + // Suppress notifications & clear badge immediately (no 600ms delay). + // setDialogActive only touches MessageRepository.activeDialogs (Set), + // does NOT mutate DialogRepository, so ForEach won't rebuild. + MessageRepository.shared.setDialogActive(route.publicKey, isActive: true) + clearDeliveredNotifications(for: route.publicKey) // Reset idle timer — user is actively viewing a chat. SessionManager.shared.recordUserInteraction() // Request user info (non-mutating, won't trigger list rebuild) requestUserInfoIfNeeded() - // Delay ALL dialog mutations to let navigation transition complete. + // Delay DialogRepository mutations to let navigation transition complete. // Without this, DialogRepository update rebuilds ChatListView's ForEach // mid-navigation, recreating the NavigationLink and canceling the push. try? await Task.sleep(for: .milliseconds(600)) guard isViewActive else { return } activateDialog() markDialogAsRead() - // Clear delivered notifications from this sender - clearDeliveredNotifications(for: route.publicKey) // Subscribe to opponent's online status (Android parity) — only after settled SessionManager.shared.subscribeToOnlineStatus(publicKey: route.publicKey) // Desktop parity: force-refresh user info (incl. online status) on chat open. diff --git a/Rosetta/RosettaApp.swift b/Rosetta/RosettaApp.swift index fcb7a31..b85e223 100644 --- a/Rosetta/RosettaApp.swift +++ b/Rosetta/RosettaApp.swift @@ -164,7 +164,7 @@ struct RosettaApp: App { .ignoresSafeArea() .opacity(transitionOverlay ? 1 : 0) .allowsHitTesting(transitionOverlay) - .animation(.easeInOut(duration: 0.08), value: transitionOverlay) + .animation(.easeInOut(duration: 0.035), value: transitionOverlay) } .preferredColorScheme(.dark) .onAppear { @@ -228,9 +228,9 @@ struct RosettaApp: App { guard !transitionOverlay else { return } transitionOverlay = true Task { @MainActor in - try? await Task.sleep(nanoseconds: 80_000_000) // wait for overlay fade-in + try? await Task.sleep(nanoseconds: 35_000_000) // wait for overlay fade-in appState = newState - try? await Task.sleep(nanoseconds: 20_000_000) // brief settle + try? await Task.sleep(nanoseconds: 10_000_000) // brief settle transitionOverlay = false } }