mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-11-03 06:55:59 +00:00
Use more Compound icons (part 2!) (#2082)
* Use Compound icons in ListRow. * Add CompoundIcon(asset:) convenience initialiser.
This commit is contained in:
@@ -33,6 +33,7 @@ internal enum Asset {
|
||||
internal enum Images {
|
||||
internal static let appLogo = ImageAsset(name: "images/app-logo")
|
||||
internal static let serverSelectionIcon = ImageAsset(name: "images/server-selection-icon")
|
||||
internal static let block = ImageAsset(name: "images/block")
|
||||
internal static let circle = ImageAsset(name: "images/circle")
|
||||
internal static let closeCircle = ImageAsset(name: "images/close-circle")
|
||||
internal static let addLocation = ImageAsset(name: "images/add-location")
|
||||
@@ -57,6 +58,7 @@ internal enum Asset {
|
||||
internal static let textFormat = ImageAsset(name: "images/text-format")
|
||||
internal static let underline = ImageAsset(name: "images/underline")
|
||||
internal static let unindent = ImageAsset(name: "images/unindent")
|
||||
internal static let devices = ImageAsset(name: "images/devices")
|
||||
internal static let document = ImageAsset(name: "images/document")
|
||||
internal static let decryptionError = ImageAsset(name: "images/decryption-error")
|
||||
internal static let endedPoll = ImageAsset(name: "images/ended-poll")
|
||||
@@ -67,6 +69,7 @@ internal enum Asset {
|
||||
internal static let locationPin = ImageAsset(name: "images/location-pin")
|
||||
internal static let locationPointerFull = ImageAsset(name: "images/location-pointer-full")
|
||||
internal static let locationPointer = ImageAsset(name: "images/location-pointer")
|
||||
internal static let lock = ImageAsset(name: "images/lock")
|
||||
internal static let mediaPause = ImageAsset(name: "images/media-pause")
|
||||
internal static let mediaPlay = ImageAsset(name: "images/media-play")
|
||||
internal static let secureBackupIcon = ImageAsset(name: "images/secure-backup-icon")
|
||||
@@ -82,6 +85,8 @@ internal enum Asset {
|
||||
internal static let timelineEndedPoll = ImageAsset(name: "images/timeline-ended-poll")
|
||||
internal static let timelinePollAttachment = ImageAsset(name: "images/timeline-poll-attachment")
|
||||
internal static let timelinePoll = ImageAsset(name: "images/timeline-poll")
|
||||
internal static let userAdd = ImageAsset(name: "images/user-add")
|
||||
internal static let user = ImageAsset(name: "images/user")
|
||||
internal static let waitingGradient = ImageAsset(name: "images/waiting-gradient")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -768,9 +768,9 @@ public enum L10n {
|
||||
public static var screenBugReportContactMeTitle: String { return L10n.tr("Localizable", "screen_bug_report_contact_me_title") }
|
||||
/// Edit screenshot
|
||||
public static var screenBugReportEditScreenshot: String { return L10n.tr("Localizable", "screen_bug_report_edit_screenshot") }
|
||||
/// Please describe the bug. What did you do? What did you expect to happen? What actually happened. Please go into as much detail as you can.
|
||||
/// Please describe the problem. What did you do? What did you expect to happen? What actually happened. Please go into as much detail as you can.
|
||||
public static var screenBugReportEditorDescription: String { return L10n.tr("Localizable", "screen_bug_report_editor_description") }
|
||||
/// Describe the bug…
|
||||
/// Describe the problem…
|
||||
public static var screenBugReportEditorPlaceholder: String { return L10n.tr("Localizable", "screen_bug_report_editor_placeholder") }
|
||||
/// If possible, please write the description in English.
|
||||
public static var screenBugReportEditorSupporting: String { return L10n.tr("Localizable", "screen_bug_report_editor_supporting") }
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
//
|
||||
// Copyright 2023 New Vector Ltd
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
import Compound
|
||||
import SwiftUI
|
||||
|
||||
extension CompoundIcon {
|
||||
init(asset: ImageAsset) {
|
||||
self.init(customImage: asset.swiftUIImage)
|
||||
}
|
||||
|
||||
init(asset: ImageAsset, size: CompoundIcon.Size, relativeTo font: Font) {
|
||||
self.init(customImage: asset.swiftUIImage, size: size, relativeTo: font)
|
||||
}
|
||||
}
|
||||
@@ -92,7 +92,7 @@ struct BugReportScreen: View {
|
||||
PhotosPicker(selection: $selectedScreenshot,
|
||||
matching: .screenshots,
|
||||
photoLibrary: .shared()) {
|
||||
ListLabel.default(title: photosPickerTitle, systemIcon: .camera)
|
||||
ListLabel.plain(title: photosPickerTitle)
|
||||
}
|
||||
})
|
||||
.accessibilityIdentifier(A11yIdentifiers.bugReportScreen.attachScreenshot)
|
||||
|
||||
@@ -45,7 +45,7 @@ struct VoiceMessageRecordingButton: View {
|
||||
.foregroundColor(.compound.iconSecondary)
|
||||
.scaledPadding(10, relativeTo: .title)
|
||||
case .recording:
|
||||
CompoundIcon(customImage: Asset.Images.stopRecording.swiftUIImage, size: .medium, relativeTo: .title)
|
||||
CompoundIcon(asset: Asset.Images.stopRecording, size: .medium, relativeTo: .title)
|
||||
.foregroundColor(.compound.iconOnSolidPrimary)
|
||||
.scaledPadding(6, relativeTo: .title)
|
||||
.background(
|
||||
|
||||
@@ -32,7 +32,7 @@ struct HomeScreenUserMenuButton: View {
|
||||
Text(L10n.commonSettings)
|
||||
} icon: {
|
||||
if context.viewState.showSettingsMenuOptionBadge {
|
||||
CompoundIcon(customImage: Asset.Images.settingsIconWithBadge.swiftUIImage)
|
||||
CompoundIcon(asset: Asset.Images.settingsIconWithBadge)
|
||||
} else {
|
||||
CompoundIcon(\.settings)
|
||||
}
|
||||
|
||||
@@ -122,7 +122,7 @@ struct RoomDetailsEditScreen: View {
|
||||
}
|
||||
|
||||
private var avatarOverlayIcon: some View {
|
||||
CompoundIcon(customImage: Asset.Images.editing.swiftUIImage, size: .xSmall, relativeTo: .compound.bodyLG)
|
||||
CompoundIcon(asset: Asset.Images.editing, size: .xSmall, relativeTo: .compound.bodyLG)
|
||||
.foregroundColor(.white)
|
||||
.padding(3)
|
||||
.background {
|
||||
|
||||
@@ -14,9 +14,8 @@
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import Compound
|
||||
import SwiftUI
|
||||
import UIKit
|
||||
|
||||
// MARK: - Coordinator
|
||||
|
||||
@@ -85,8 +84,8 @@ struct RoomDetailsScreenViewState: BindableState {
|
||||
areNotificationsMuted ? L10n.commonUnmute : L10n.commonMute
|
||||
}
|
||||
|
||||
var notificationShortcutButtonImage: Image {
|
||||
areNotificationsMuted ? Image(systemName: "bell.slash.fill") : Image(systemName: "bell")
|
||||
var notificationShortcutButtonIcon: KeyPath<CompoundIcons, Image> {
|
||||
areNotificationsMuted ? \.notificationsOff : \.notifications
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -110,7 +110,7 @@ struct RoomDetailsScreen: View {
|
||||
toggleMuteButton
|
||||
case .share(let permalink):
|
||||
ShareLink(item: permalink) {
|
||||
Image(systemName: "square.and.arrow.up")
|
||||
CompoundIcon(asset: Asset.Images.shareIos)
|
||||
}
|
||||
.buttonStyle(FormActionButtonStyle(title: L10n.actionShare))
|
||||
}
|
||||
@@ -141,7 +141,8 @@ struct RoomDetailsScreen: View {
|
||||
|
||||
private var aboutSection: some View {
|
||||
Section {
|
||||
ListRow(label: .default(title: L10n.commonPeople, systemIcon: .person),
|
||||
ListRow(label: .default(title: L10n.commonPeople,
|
||||
icon: CompoundIcon(asset: Asset.Images.user)),
|
||||
details: .title(String(context.viewState.joinedMembersCount)),
|
||||
kind: .navigationLink {
|
||||
context.send(viewAction: .processTapPeople)
|
||||
@@ -150,7 +151,7 @@ struct RoomDetailsScreen: View {
|
||||
|
||||
if context.viewState.canInviteUsers {
|
||||
ListRow(label: .default(title: L10n.screenRoomDetailsInvitePeopleTitle,
|
||||
systemIcon: .personBadgePlus),
|
||||
icon: CompoundIcon(asset: Asset.Images.userAdd)),
|
||||
kind: .navigationLink {
|
||||
context.send(viewAction: .processTapInvite)
|
||||
})
|
||||
@@ -159,11 +160,10 @@ struct RoomDetailsScreen: View {
|
||||
}
|
||||
}
|
||||
|
||||
@ViewBuilder
|
||||
private var notificationSection: some View {
|
||||
Section {
|
||||
ListRow(label: .default(title: L10n.screenRoomDetailsNotificationTitle,
|
||||
systemIcon: .bell),
|
||||
icon: \.notifications),
|
||||
details: context.viewState.notificationSettingsState.isLoading ? .isWaiting(true)
|
||||
: context.viewState.notificationSettingsState.isError ? .systemIcon(.exclamationmarkCircle)
|
||||
: .title(context.viewState.notificationSettingsState.label),
|
||||
@@ -176,7 +176,6 @@ struct RoomDetailsScreen: View {
|
||||
.disabled(context.viewState.notificationSettingsState.isLoading)
|
||||
}
|
||||
|
||||
@ViewBuilder
|
||||
private var toggleMuteButton: some View {
|
||||
Button {
|
||||
context.send(viewAction: .processToogleMuteNotifications)
|
||||
@@ -184,20 +183,20 @@ struct RoomDetailsScreen: View {
|
||||
if context.viewState.isProcessingMuteToggleAction {
|
||||
ProgressView()
|
||||
} else {
|
||||
context.viewState.notificationShortcutButtonImage
|
||||
CompoundIcon(context.viewState.notificationShortcutButtonIcon)
|
||||
}
|
||||
}
|
||||
.buttonStyle(FormActionButtonStyle(title: context.viewState.notificationShortcutButtonTitle))
|
||||
.disabled(context.viewState.isProcessingMuteToggleAction)
|
||||
}
|
||||
|
||||
|
||||
@ViewBuilder
|
||||
private var securitySection: some View {
|
||||
if context.viewState.isEncrypted {
|
||||
Section {
|
||||
ListRow(label: .default(title: L10n.screenRoomDetailsEncryptionEnabledTitle,
|
||||
description: L10n.screenRoomDetailsEncryptionEnabledSubtitle,
|
||||
systemIcon: .lockShield,
|
||||
icon: CompoundIcon(asset: Asset.Images.lock),
|
||||
iconAlignment: .top),
|
||||
kind: .label)
|
||||
} header: {
|
||||
@@ -209,9 +208,9 @@ struct RoomDetailsScreen: View {
|
||||
|
||||
private var leaveRoomSection: some View {
|
||||
Section {
|
||||
ListRow(label: .default(title: L10n.actionLeaveRoom,
|
||||
systemIcon: .doorRightHandOpen,
|
||||
role: .destructive),
|
||||
ListRow(label: .action(title: L10n.actionLeaveRoom,
|
||||
icon: \.leave,
|
||||
role: .destructive),
|
||||
kind: .button { context.send(viewAction: .processTapLeave) })
|
||||
}
|
||||
}
|
||||
@@ -219,7 +218,7 @@ struct RoomDetailsScreen: View {
|
||||
private func ignoreUserSection(user: RoomMemberDetails) -> some View {
|
||||
Section {
|
||||
ListRow(label: .default(title: user.isIgnored ? L10n.screenDmDetailsUnblockUser : L10n.screenDmDetailsBlockUser,
|
||||
systemIcon: .slashCircle,
|
||||
icon: CompoundIcon(asset: Asset.Images.block),
|
||||
role: user.isIgnored ? nil : .destructive),
|
||||
details: .isWaiting(context.viewState.isProcessingIgnoreRequest),
|
||||
kind: .button {
|
||||
|
||||
@@ -21,7 +21,7 @@ struct SwipeToReplyView: View {
|
||||
let timelineItem: RoomTimelineItemProtocol
|
||||
|
||||
var body: some View {
|
||||
CompoundIcon(customImage: Asset.Images.reply.swiftUIImage)
|
||||
CompoundIcon(asset: Asset.Images.reply)
|
||||
.foregroundColor(.compound.iconPrimary)
|
||||
.accessibilityHidden(true)
|
||||
}
|
||||
|
||||
+1
-1
@@ -28,7 +28,7 @@ struct TimelineDeliveryStatusView: View {
|
||||
private var icon: CompoundIcon {
|
||||
switch deliveryStatus {
|
||||
case .sending:
|
||||
return CompoundIcon(customImage: Asset.Images.circle.swiftUIImage, size: .xSmall, relativeTo: .compound.bodyMD)
|
||||
return CompoundIcon(asset: Asset.Images.circle, size: .xSmall, relativeTo: .compound.bodyMD)
|
||||
case .sent:
|
||||
return CompoundIcon(\.checkCircle, size: .xSmall, relativeTo: .compound.bodyMD)
|
||||
}
|
||||
|
||||
+1
-2
@@ -31,8 +31,7 @@ struct AnalyticsSettingsScreen: View {
|
||||
|
||||
var analyticsSection: some View {
|
||||
Section {
|
||||
ListRow(label: .default(title: L10n.screenAnalyticsSettingsShareData,
|
||||
systemIcon: .chartBar),
|
||||
ListRow(label: .plain(title: L10n.screenAnalyticsSettingsShareData),
|
||||
kind: .toggle($context.enableAnalytics))
|
||||
.onChange(of: context.enableAnalytics) { _ in
|
||||
context.send(viewAction: .toggleAnalytics)
|
||||
|
||||
+3
-4
@@ -23,15 +23,14 @@ struct AdvancedSettingsScreen: View {
|
||||
var body: some View {
|
||||
Form {
|
||||
Section {
|
||||
ListRow(label: .default(title: L10n.commonMessageLayout,
|
||||
systemIcon: .rectangleGrid1x2),
|
||||
ListRow(label: .plain(title: L10n.commonMessageLayout),
|
||||
kind: .picker(selection: $context.timelineStyle,
|
||||
items: TimelineStyle.allCases.map { (title: $0.name, tag: $0) }))
|
||||
|
||||
ListRow(label: .default(title: L10n.commonRichTextEditor, icon: Image(asset: Asset.Images.textFormat)),
|
||||
ListRow(label: .plain(title: L10n.commonRichTextEditor),
|
||||
kind: .toggle($context.richTextEditorEnabled))
|
||||
|
||||
ListRow(label: .default(title: L10n.actionViewSource, systemIcon: .mailAndTextMagnifyingglass),
|
||||
ListRow(label: .plain(title: L10n.actionViewSource),
|
||||
kind: .toggle($context.viewSourceEnabled))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -88,7 +88,7 @@ struct SettingsScreen: View {
|
||||
Section {
|
||||
if !context.viewState.isSessionVerified {
|
||||
ListRow(label: .default(title: L10n.actionCompleteVerification,
|
||||
systemIcon: .checkmarkShield),
|
||||
icon: \.checkCircle),
|
||||
kind: .button { context.send(viewAction: .sessionVerification) })
|
||||
} else if context.viewState.chatBackupEnabled {
|
||||
ListRow(label: .default(title: L10n.commonChatBackup,
|
||||
@@ -104,7 +104,8 @@ struct SettingsScreen: View {
|
||||
private var mainSection: some View {
|
||||
Section {
|
||||
if context.viewState.accountProfileURL != nil {
|
||||
ListRow(label: .default(title: L10n.actionManageAccount, systemIcon: .person),
|
||||
ListRow(label: .default(title: L10n.actionManageAccount,
|
||||
icon: \.userProfile),
|
||||
kind: .button {
|
||||
context.send(viewAction: .accountProfile)
|
||||
})
|
||||
@@ -112,35 +113,35 @@ struct SettingsScreen: View {
|
||||
}
|
||||
|
||||
ListRow(label: .default(title: L10n.screenNotificationSettingsTitle,
|
||||
systemIcon: .bell),
|
||||
icon: \.notifications),
|
||||
kind: .navigationLink {
|
||||
context.send(viewAction: .notifications)
|
||||
})
|
||||
.accessibilityIdentifier(A11yIdentifiers.settingsScreen.notifications)
|
||||
|
||||
ListRow(label: .default(title: L10n.commonAnalytics,
|
||||
systemIcon: .chartBar),
|
||||
icon: \.polls),
|
||||
kind: .navigationLink {
|
||||
context.send(viewAction: .analytics)
|
||||
})
|
||||
.accessibilityIdentifier(A11yIdentifiers.settingsScreen.analytics)
|
||||
|
||||
ListRow(label: .default(title: L10n.commonScreenLock,
|
||||
systemIcon: .lock),
|
||||
icon: CompoundIcon(asset: Asset.Images.lock)),
|
||||
kind: .navigationLink {
|
||||
context.send(viewAction: .appLock)
|
||||
})
|
||||
.accessibilityIdentifier(A11yIdentifiers.settingsScreen.screenLock)
|
||||
|
||||
ListRow(label: .default(title: L10n.commonReportAProblem,
|
||||
systemIcon: .ladybug),
|
||||
icon: \.chatProblem),
|
||||
kind: .navigationLink {
|
||||
context.send(viewAction: .reportBug)
|
||||
})
|
||||
.accessibilityIdentifier(A11yIdentifiers.settingsScreen.reportBug)
|
||||
|
||||
ListRow(label: .default(title: L10n.commonAbout,
|
||||
systemIcon: .questionmarkCircle),
|
||||
icon: \.info),
|
||||
kind: .navigationLink {
|
||||
context.send(viewAction: .about)
|
||||
})
|
||||
@@ -150,27 +151,18 @@ struct SettingsScreen: View {
|
||||
|
||||
private var manageSessionsSection: some View {
|
||||
Section {
|
||||
ListRow(label: .default(title: L10n.actionManageDevices, systemIcon: deviceIcon),
|
||||
ListRow(label: .default(title: L10n.actionManageDevices,
|
||||
icon: CompoundIcon(asset: Asset.Images.devices)),
|
||||
kind: .button {
|
||||
context.send(viewAction: .accountSessionsList)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
private var deviceIcon: SFSymbol {
|
||||
if ProcessInfo.processInfo.isiOSAppOnMac {
|
||||
return .macbookAndIphone
|
||||
} else if UIDevice.current.userInterfaceIdiom == .pad {
|
||||
return .ipad
|
||||
} else {
|
||||
return .iphone
|
||||
}
|
||||
}
|
||||
|
||||
private var advancedOptionsSection: some View {
|
||||
Section {
|
||||
ListRow(label: .default(title: L10n.commonAdvancedSettings,
|
||||
systemIcon: .gearshape2),
|
||||
icon: \.settings),
|
||||
kind: .navigationLink {
|
||||
context.send(viewAction: .advancedSettings)
|
||||
})
|
||||
@@ -178,7 +170,7 @@ struct SettingsScreen: View {
|
||||
|
||||
if context.viewState.showDeveloperOptions {
|
||||
ListRow(label: .default(title: L10n.commonDeveloperOptions,
|
||||
systemIcon: .hammerCircle),
|
||||
icon: CompoundIcon(asset: Asset.Images.codeBlock)),
|
||||
kind: .navigationLink {
|
||||
context.send(viewAction: .developerOptions)
|
||||
})
|
||||
@@ -189,8 +181,9 @@ struct SettingsScreen: View {
|
||||
|
||||
private var signOutSection: some View {
|
||||
Section {
|
||||
ListRow(label: .default(title: L10n.screenSignoutPreferenceItem,
|
||||
systemIcon: .rectanglePortraitAndArrowRight),
|
||||
ListRow(label: .action(title: L10n.screenSignoutPreferenceItem,
|
||||
icon: CompoundIcon(asset: Asset.Images.signOut),
|
||||
role: .destructive),
|
||||
kind: .button {
|
||||
context.send(viewAction: .logout)
|
||||
})
|
||||
|
||||
+1
-1
@@ -89,7 +89,7 @@ struct UserDetailsEditScreen: View {
|
||||
}
|
||||
|
||||
private var avatarOverlayIcon: some View {
|
||||
CompoundIcon(customImage: Asset.Images.editing.swiftUIImage, size: .xSmall, relativeTo: .compound.bodyLG)
|
||||
CompoundIcon(asset: Asset.Images.editing, size: .xSmall, relativeTo: .compound.bodyLG)
|
||||
.foregroundColor(.white)
|
||||
.padding(4)
|
||||
.background {
|
||||
|
||||
Reference in New Issue
Block a user