Use more Compound icons (part 2!) (#2082)

* Use Compound icons in ListRow.

* Add CompoundIcon(asset:) convenience initialiser.
This commit is contained in:
Doug
2023-11-15 09:54:43 +00:00
committed by GitHub
parent 2c1e61a1bc
commit 4b3a373782
82 changed files with 287 additions and 165 deletions
+5
View File
@@ -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")
}
}
+2 -2
View File
@@ -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)
}
@@ -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)
}
@@ -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)
@@ -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)
})
@@ -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 {