Use the new notification sound. (#4572)

* Use the new notification sound.

* Add a banner informing the user of the new notification sound.
This commit is contained in:
Doug
2025-10-03 21:09:50 +01:00
committed by GitHub
parent a226c99492
commit 7e7cf1587f
18 changed files with 133 additions and 2 deletions
@@ -39,6 +39,7 @@ enum HomeScreenViewAction {
case confirmRecoveryKey
case resetEncryption
case skipRecoveryKeyConfirmation
case dismissNewSoundBanner
case updateVisibleItemRange(Range<Int>)
case globalSearch
case markRoomAsUnread(roomIdentifier: String)
@@ -92,6 +93,7 @@ struct HomeScreenViewState: BindableState {
var userAvatarURL: URL?
var securityBannerMode = HomeScreenSecurityBannerMode.none
var shouldShowNewSoundBanner = false
var requiresExtraAccountSetup = false
@@ -134,6 +136,10 @@ struct HomeScreenViewState: BindableState {
var shouldShowFilters: Bool {
!bindings.isSearchFieldFocused && roomListMode == .rooms
}
var shouldShowBanner: Bool {
securityBannerMode.isShown || shouldShowNewSoundBanner
}
}
struct HomeScreenViewStateBindings {
@@ -105,6 +105,12 @@ class HomeScreenViewModel: HomeScreenViewModelType, HomeScreenViewModelProtocol
}
.store(in: &cancellables)
appSettings.$hasSeenNewSoundBanner
.sink { [weak self] hasSeenNewSoundBanner in
self?.state.shouldShowNewSoundBanner = !hasSeenNewSoundBanner
}
.store(in: &cancellables)
userSession.clientProxy.hideInviteAvatarsPublisher
.removeDuplicates()
.receive(on: DispatchQueue.main)
@@ -160,6 +166,8 @@ class HomeScreenViewModel: HomeScreenViewModelType, HomeScreenViewModelProtocol
actionsSubject.send(.presentEncryptionResetScreen)
case .skipRecoveryKeyConfirmation:
state.securityBannerMode = .dismissed
case .dismissNewSoundBanner:
appSettings.hasSeenNewSoundBanner = true
case .updateVisibleItemRange(let range):
roomSummaryProvider?.updateVisibleRange(range)
case .startChat:
@@ -122,14 +122,16 @@ struct HomeScreenContent: View {
@ViewBuilder
private var topSection: some View {
// An empty VStack causes glitches within the room list
if context.viewState.shouldShowFilters || context.viewState.securityBannerMode.isShown {
if context.viewState.shouldShowFilters || context.viewState.shouldShowBanner {
VStack(spacing: 0) {
if context.viewState.shouldShowFilters {
RoomListFiltersView(state: $context.filtersState)
}
if case let .show(state) = context.viewState.securityBannerMode {
HomeScreenRecoveryKeyConfirmationBanner(state: state, context: context)
} else if context.viewState.shouldShowNewSoundBanner {
HomeScreenNewSoundBanner { context.send(viewAction: .dismissNewSoundBanner) }
}
}
.background(Color.compound.bgCanvasDefault)
@@ -0,0 +1,59 @@
//
// Copyright 2025 New Vector Ltd.
//
// SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
// Please see LICENSE files in the repository root for full details.
//
import Compound
import SwiftUI
struct HomeScreenNewSoundBanner: View {
let dismissAction: () -> Void
var body: some View {
VStack(spacing: 16) {
content
buttons
}
.padding(16)
.background(Color.compound.bgSubtleSecondary)
.cornerRadius(14)
.padding(.horizontal, 16)
}
var content: some View {
VStack(alignment: .leading, spacing: 4) {
HStack(alignment: .firstTextBaseline, spacing: 16) {
Text(L10n.bannerNewSoundTitle)
.font(.compound.bodyLGSemibold)
.foregroundColor(.compound.textPrimary)
.frame(maxWidth: .infinity, alignment: .leading)
Button(action: dismissAction) {
Image(systemName: "xmark")
.foregroundColor(.compound.iconSecondary)
.frame(width: 12, height: 12)
}
}
Text(L10n.bannerNewSoundMessage)
.font(.compound.bodyMD)
.foregroundColor(.compound.textSecondary)
}
}
var buttons: some View {
Button(action: dismissAction) {
Text(L10n.actionOk)
.frame(maxWidth: .infinity)
}
.buttonStyle(.compound(.primary, size: .medium))
}
}
struct HomeScreenNewSoundBanner_Previews: PreviewProvider, TestablePreview {
static var previews: some View {
HomeScreenNewSoundBanner { }
}
}