Use Compound icons within the user indicators.

This commit is contained in:
Stefan Ceriu
2026-05-25 20:35:48 +03:00
parent c9317547f8
commit da9eda80cd
25 changed files with 39 additions and 37 deletions
@@ -885,6 +885,6 @@ class ChatsTabFlowCoordinator: FlowCoordinatorProtocol {
flowParameters.userIndicatorController.submitIndicator(UserIndicator(id: Self.failureIndicatorIdentifier, flowParameters.userIndicatorController.submitIndicator(UserIndicator(id: Self.failureIndicatorIdentifier,
type: .toast, type: .toast,
title: L10n.errorUnknown, title: L10n.errorUnknown,
iconName: "xmark")) icon: \.close))
} }
} }
@@ -1067,7 +1067,7 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
case .cancel: case .cancel:
break break
case .finish: case .finish:
flowParameters.userIndicatorController.submitIndicator(UserIndicator(title: L10n.commonReportSubmitted, iconName: "checkmark")) flowParameters.userIndicatorController.submitIndicator(UserIndicator(title: L10n.commonReportSubmitted, icon: \.check))
} }
} }
.store(in: &cancellables) .store(in: &cancellables)
@@ -7,7 +7,9 @@
// //
import Combine import Combine
import Compound
import Foundation import Foundation
import SwiftUI
enum UserIndicatorType: Equatable { enum UserIndicatorType: Equatable {
case toast(progress: UserIndicator.Progress?) case toast(progress: UserIndicator.Progress?)
@@ -40,7 +42,7 @@ struct UserIndicator: Equatable, Identifiable {
var type: UserIndicatorType = .toast var type: UserIndicatorType = .toast
var title: String var title: String
var message: String? var message: String?
var iconName: String? var icon: KeyPath<CompoundIcons, Image>?
var persistent = false var persistent = false
// MARK: - Associated values from the type // MARK: - Associated values from the type
@@ -7,6 +7,7 @@
// //
import Combine import Combine
import Compound
import SwiftUI import SwiftUI
struct UserIndicatorModalView: View { struct UserIndicatorModalView: View {
@@ -23,9 +24,8 @@ struct UserIndicatorModalView: View {
} }
HStack(spacing: 8) { HStack(spacing: 8) {
if let iconName = indicator.iconName { if let icon = indicator.icon {
Image(systemName: iconName) CompoundIcon(icon, size: .medium, relativeTo: .compound.headingMDBold)
.font(titleFont)
.foregroundColor(.compound.iconPrimary) .foregroundColor(.compound.iconPrimary)
} }
@@ -76,24 +76,24 @@ struct UserIndicatorModalView_Previews: PreviewProvider, TestablePreview {
VStack(spacing: 0) { VStack(spacing: 0) {
UserIndicatorModalView(indicator: UserIndicator(type: .modal, UserIndicatorModalView(indicator: UserIndicator(type: .modal,
title: "Successfully logged in", title: "Successfully logged in",
iconName: "checkmark")) icon: \.check))
UserIndicatorModalView(indicator: UserIndicator(type: .modal(progress: .published(CurrentValueSubject<Double, Never>(0.5).asCurrentValuePublisher()), UserIndicatorModalView(indicator: UserIndicator(type: .modal(progress: .published(CurrentValueSubject<Double, Never>(0.5).asCurrentValuePublisher()),
interactiveDismissDisabled: false, interactiveDismissDisabled: false,
allowsInteraction: false), allowsInteraction: false),
title: "Successfully logged in", title: "Successfully logged in",
iconName: "checkmark")) icon: \.check))
UserIndicatorModalView(indicator: UserIndicator(type: .modal(progress: .none, UserIndicatorModalView(indicator: UserIndicator(type: .modal(progress: .none,
interactiveDismissDisabled: false, interactiveDismissDisabled: false,
allowsInteraction: false), allowsInteraction: false),
title: "Successfully logged in", title: "Successfully logged in",
iconName: "checkmark")) icon: \.check))
UserIndicatorModalView(indicator: UserIndicator(type: .modal, UserIndicatorModalView(indicator: UserIndicator(type: .modal,
title: "Successfully logged in", title: "Successfully logged in",
message: "You can now be happy.", message: "You can now be happy.",
iconName: "checkmark")) icon: \.check))
} }
} }
} }
@@ -6,6 +6,7 @@
// Please see LICENSE files in the repository root for full details. // Please see LICENSE files in the repository root for full details.
// //
import Compound
import SwiftUI import SwiftUI
struct UserIndicatorToastView: View { struct UserIndicatorToastView: View {
@@ -18,9 +19,8 @@ struct UserIndicatorToastView: View {
.controlSize(.small) .controlSize(.small)
.tint(.compound.iconPrimary) .tint(.compound.iconPrimary)
} }
if let iconName = indicator.iconName { if let icon = indicator.icon {
Image(systemName: iconName) CompoundIcon(icon, size: .small, relativeTo: .compound.bodyMD)
.font(.compound.bodyMD)
.foregroundColor(.compound.iconPrimary) .foregroundColor(.compound.iconPrimary)
} }
Text(indicator.title) Text(indicator.title)
@@ -48,7 +48,7 @@ struct UserIndicatorToastView_Previews: PreviewProvider, TestablePreview {
static var previews: some View { static var previews: some View {
VStack(spacing: 30) { VStack(spacing: 30) {
UserIndicatorToastView(indicator: UserIndicator(title: "Successfully logged in", UserIndicatorToastView(indicator: UserIndicator(title: "Successfully logged in",
iconName: "checkmark")) icon: \.check))
UserIndicatorToastView(indicator: UserIndicator(title: "Toast without icon")) UserIndicatorToastView(indicator: UserIndicator(title: "Toast without icon"))
@@ -160,7 +160,7 @@ class OAuthAuthenticationPresenter: NSObject {
userIndicatorController.submitIndicator(UserIndicator(id: failureIndicatorID, userIndicatorController.submitIndicator(UserIndicator(id: failureIndicatorID,
type: .toast, type: .toast,
title: L10n.errorUnknown, title: L10n.errorUnknown,
iconName: "xmark")) icon: \.close))
} }
} }
@@ -94,6 +94,6 @@ final class BugReportScreenCoordinator: CoordinatorProtocol {
} }
private func showError(label: String) { private func showError(label: String) {
parameters.userIndicatorController?.submitIndicator(UserIndicator(title: label, iconName: "xmark")) parameters.userIndicatorController?.submitIndicator(UserIndicator(title: label, icon: \.close))
} }
} }
@@ -107,6 +107,6 @@ class DeclineAndBlockScreenViewModel: DeclineAndBlockScreenViewModelType, Declin
} }
private func showSuccess() { private func showSuccess() {
userIndicatorController.submitIndicator(.init(title: L10n.commonSuccess, iconName: "checkmark")) userIndicatorController.submitIndicator(.init(title: L10n.commonSuccess, icon: \.check))
} }
} }
@@ -213,21 +213,21 @@ class TimelineMediaPreviewViewModel: TimelineMediaPreviewViewModelType {
userIndicatorController.submitIndicator(UserIndicator(id: statusIndicatorID, userIndicatorController.submitIndicator(UserIndicator(id: statusIndicatorID,
type: .toast, type: .toast,
title: L10n.commonFileDeleted, title: L10n.commonFileDeleted,
iconName: "checkmark")) icon: \.check))
} }
private func showSavedIndicator() { private func showSavedIndicator() {
userIndicatorController.submitIndicator(UserIndicator(id: statusIndicatorID, userIndicatorController.submitIndicator(UserIndicator(id: statusIndicatorID,
type: .toast, type: .toast,
title: L10n.commonFileSaved, title: L10n.commonFileSaved,
iconName: "checkmark")) icon: \.check))
} }
private func showErrorIndicator() { private func showErrorIndicator() {
userIndicatorController.submitIndicator(UserIndicator(id: statusIndicatorID, userIndicatorController.submitIndicator(UserIndicator(id: statusIndicatorID,
type: .toast, type: .toast,
title: L10n.errorUnknown, title: L10n.errorUnknown,
iconName: "xmark")) icon: \.close))
} }
private func showTimelineEndIndicator() { private func showTimelineEndIndicator() {
@@ -453,7 +453,7 @@ class HomeScreenViewModel: HomeScreenViewModelType, HomeScreenViewModelProtocol
userIndicatorController.submitIndicator(UserIndicator(id: UUID().uuidString, userIndicatorController.submitIndicator(UserIndicator(id: UUID().uuidString,
type: .toast, type: .toast,
title: L10n.commonCurrentUserLeftRoom, title: L10n.commonCurrentUserLeftRoom,
iconName: "checkmark")) icon: \.check))
actionsSubject.send(.roomLeft(roomIdentifier: roomID)) actionsSubject.send(.roomLeft(roomIdentifier: roomID))
} }
@@ -308,7 +308,7 @@ class LocationSharingScreenViewModel: LocationSharingScreenViewModelType, Locati
userIndicatorController.submitIndicator(UserIndicator(id: Self.statusIndicatorID, userIndicatorController.submitIndicator(UserIndicator(id: Self.statusIndicatorID,
type: .toast, type: .toast,
title: L10n.errorUnknown, title: L10n.errorUnknown,
iconName: "xmark")) icon: \.close))
} }
private func showLoader() { private func showLoader() {
@@ -140,7 +140,7 @@ class ManageRoomMemberSheetViewModel: ManageRoomMemberSheetViewModelType, Manage
private func showManageMemberFailure(title: String) { private func showManageMemberFailure(title: String) {
userIndicatorController.retractIndicatorWithId(title) userIndicatorController.retractIndicatorWithId(title)
userIndicatorController.submitIndicator(UserIndicator(title: L10n.commonFailed, iconName: "xmark")) userIndicatorController.submitIndicator(UserIndicator(title: L10n.commonFailed, icon: \.close))
} }
} }
@@ -47,7 +47,7 @@ class ReportRoomScreenViewModel: ReportRoomScreenViewModelType, ReportRoomScreen
await leaveRoom(showLoading: false) await leaveRoom(showLoading: false)
} else { } else {
hideLoadingIndicator() hideLoadingIndicator()
userIndicatorController.submitIndicator(.init(title: L10n.dialogRoomReported, iconName: "checkmark")) userIndicatorController.submitIndicator(.init(title: L10n.dialogRoomReported, icon: \.check))
actionsSubject.send(.dismiss(shouldLeaveRoom: false)) actionsSubject.send(.dismiss(shouldLeaveRoom: false))
} }
case .failure: case .failure:
@@ -70,7 +70,7 @@ class ReportRoomScreenViewModel: ReportRoomScreenViewModelType, ReportRoomScreen
switch result { switch result {
case .success: case .success:
userIndicatorController.submitIndicator(.init(title: L10n.dialogRoomReportedAndLeft, iconName: "checkmark")) userIndicatorController.submitIndicator(.init(title: L10n.dialogRoomReportedAndLeft, icon: \.check))
actionsSubject.send(.dismiss(shouldLeaveRoom: true)) actionsSubject.send(.dismiss(shouldLeaveRoom: true))
case .failure: case .failure:
state.bindings.alert = .init(id: .leaveRoomFailed, state.bindings.alert = .init(id: .leaveRoomFailed,
@@ -105,7 +105,7 @@ class ResolveVerifiedUserSendFailureScreenViewModel: ResolveVerifiedUserSendFail
userIndicatorController.submitIndicator(UserIndicator(id: Self.failureIndicatorIdentifier, userIndicatorController.submitIndicator(UserIndicator(id: Self.failureIndicatorIdentifier,
type: .toast, type: .toast,
title: L10n.errorUnknown, title: L10n.errorUnknown,
iconName: "xmark")) icon: \.close))
} }
} }
@@ -84,7 +84,7 @@ class RoomDirectorySearchScreenViewModel: RoomDirectorySearchScreenViewModelType
userIndicatorController.submitIndicator(UserIndicator(id: Self.errorID, userIndicatorController.submitIndicator(UserIndicator(id: Self.errorID,
type: .toast, type: .toast,
title: L10n.screenRoomDirectorySearchLoadingError, title: L10n.screenRoomDirectorySearchLoadingError,
iconName: "xmark")) icon: \.close))
} }
// Add a small delay to allow the rooms to be published, // Add a small delay to allow the rooms to be published,
@@ -273,6 +273,6 @@ class RoomMemberDetailsScreenViewModel: RoomMemberDetailsScreenViewModelType, Ro
userIndicatorController.submitIndicator(UserIndicator(id: statusIndicatorIdentifier, userIndicatorController.submitIndicator(UserIndicator(id: statusIndicatorIdentifier,
type: .toast, type: .toast,
title: L10n.errorUnknown, title: L10n.errorUnknown,
iconName: "xmark")) icon: \.close))
} }
} }
@@ -222,7 +222,7 @@ class RoomMembersListScreenViewModel: RoomMembersListScreenViewModelType, RoomMe
private func showManageMemberFailure(title: String) { private func showManageMemberFailure(title: String) {
userIndicatorController.retractIndicatorWithId(title) userIndicatorController.retractIndicatorWithId(title)
userIndicatorController.submitIndicator(UserIndicator(title: L10n.commonFailed, iconName: "xmark")) userIndicatorController.submitIndicator(UserIndicator(title: L10n.commonFailed, icon: \.close))
} }
} }
@@ -169,6 +169,6 @@ class RoomRolesAndPermissionsScreenViewModel: RoomRolesAndPermissionsScreenViewM
userIndicatorController.submitIndicator(UserIndicator(id: Self.successIndicatorID, userIndicatorController.submitIndicator(UserIndicator(id: Self.successIndicatorID,
type: .toast, type: .toast,
title: L10n.commonSuccess, title: L10n.commonSuccess,
iconName: "checkmark")) icon: \.check))
} }
} }
@@ -72,7 +72,7 @@ final class SecureBackupRecoveryKeyScreenCoordinator: CoordinatorProtocol {
parameters.userIndicatorController.submitIndicator(.init(id: .init(), parameters.userIndicatorController.submitIndicator(.init(id: .init(),
type: .toast(progress: nil), type: .toast(progress: nil),
title: title, title: title,
iconName: "checkmark", icon: \.check,
persistent: false)) persistent: false))
} }
} }
@@ -80,7 +80,7 @@ class LeaveSpaceViewModel: LeaveSpaceViewModelType {
userIndicatorController.submitIndicator(UserIndicator(id: Self.failureIndicatorID, userIndicatorController.submitIndicator(UserIndicator(id: Self.failureIndicatorID,
type: .toast, type: .toast,
title: L10n.errorUnknown, title: L10n.errorUnknown,
iconName: "xmark")) icon: \.close))
} }
} }
@@ -187,6 +187,6 @@ class SpaceAddRoomsScreenViewModel: SpaceAddRoomsScreenViewModelType, SpaceAddRo
userIndicatorController.submitIndicator(UserIndicator(id: failureIndicatorID, userIndicatorController.submitIndicator(UserIndicator(id: failureIndicatorID,
type: .toast, type: .toast,
title: L10n.errorUnknown, title: L10n.errorUnknown,
iconName: "xmark")) icon: \.close))
} }
} }
@@ -295,6 +295,6 @@ class SpaceScreenViewModel: SpaceScreenViewModelType, SpaceScreenViewModelProtoc
userIndicatorController.submitIndicator(UserIndicator(id: Self.failureIndicatorID, userIndicatorController.submitIndicator(UserIndicator(id: Self.failureIndicatorID,
type: .toast, type: .toast,
title: L10n.errorUnknown, title: L10n.errorUnknown,
iconName: "xmark")) icon: \.close))
} }
} }
@@ -92,6 +92,6 @@ class SpacesScreenViewModel: SpacesScreenViewModelType, SpacesScreenViewModelPro
userIndicatorController.submitIndicator(UserIndicator(id: Self.failureIndicatorID, userIndicatorController.submitIndicator(UserIndicator(id: Self.failureIndicatorID,
type: .toast, type: .toast,
title: L10n.errorUnknown, title: L10n.errorUnknown,
iconName: "xmark")) icon: \.close))
} }
} }
@@ -1106,7 +1106,7 @@ class TimelineViewModel: TimelineViewModelType, TimelineViewModelProtocol {
userIndicatorController.submitIndicator(UserIndicator(id: Constants.toastErrorID, userIndicatorController.submitIndicator(UserIndicator(id: Constants.toastErrorID,
type: .toast, type: .toast,
title: title, title: title,
iconName: "xmark")) icon: \.close))
} }
} }
@@ -190,6 +190,6 @@ class UserProfileScreenViewModel: UserProfileScreenViewModelType, UserProfileScr
userIndicatorController.submitIndicator(UserIndicator(id: statusIndicatorIdentifier, userIndicatorController.submitIndicator(UserIndicator(id: statusIndicatorIdentifier,
type: .toast, type: .toast,
title: L10n.errorUnknown, title: L10n.errorUnknown,
iconName: "xmark")) icon: \.close))
} }
} }