Tweak the design of various Forms to match Figma (#573)

Add formBackground and formRowBackground colours and adopt them.

* Include topic in UI tests.
This commit is contained in:
Doug
2023-02-14 10:14:13 +00:00
committed by GitHub
parent 7ab64d4cb4
commit b2d99e27a5
21 changed files with 156 additions and 143 deletions
@@ -81,6 +81,26 @@ public struct ElementColors {
collection.userInterfaceStyle == .light ? .element.systemGray6 : .element.system
})
}
/// The colour to use on the background of a Form or grouped List.
///
/// This colour is a special case as it uses `system` in light mode and `background` in dark mode.
public var formBackground: Color {
Color(UIColor { collection in
// Note: Light colour doesn't currently match Figma.
collection.userInterfaceStyle == .light ? .element.system : .element.background
})
}
/// The background colour of a row in a Form or grouped List.
///
/// This colour is a special case as it uses `background` in light mode and `system` in dark mode.
public var formRowBackground: Color {
Color(UIColor { collection in
// Note: Light colour doesn't currently match Figma.
collection.userInterfaceStyle == .light ? .element.background : .element.system
})
}
}
// MARK: UIKit
@@ -21,7 +21,7 @@ struct FormSectionHeaderStyle: ViewModifier {
func body(content: Content) -> some View {
content
.foregroundColor(.element.secondaryContent)
.font(.element.footnoteBold)
.font(.element.caption1)
}
}
@@ -30,7 +30,7 @@ struct SettingsActionButtonStyle: ButtonStyle {
.frame(width: menuIconSize, height: menuIconSize)
.background {
RoundedRectangle(cornerRadius: 16)
.fill(Color.element.background.opacity(configuration.isPressed ? 0.5 : 1))
.fill(Color.element.formRowBackground.opacity(configuration.isPressed ? 0.5 : 1))
}
Text(title)
@@ -32,7 +32,7 @@ struct BugReportScreen: View {
.padding(.horizontal, horizontalPadding)
}
.scrollDismissesKeyboard(.immediately)
.background(Color.element.system)
.background(Color.element.formBackground.ignoresSafeArea())
.navigationTitle(ElementL10n.bugReportScreenTitle)
.navigationBarTitleDisplayMode(.inline)
.toolbar { toolbar }
@@ -52,18 +52,15 @@ struct BugReportScreen: View {
private var descriptionTextEditor: some View {
ZStack(alignment: .topLeading) {
RoundedRectangle(cornerRadius: 14, style: .continuous)
.fill(Color.element.background)
.fill(Color.element.formRowBackground)
TextEditor(text: $context.reportText)
.tint(.element.brand)
.padding(.horizontal, 10)
.padding(.vertical, 4)
.background(Color.clear)
.cornerRadius(14)
.accessibilityIdentifier("reportTextView")
.introspectTextView { textView in
textView.backgroundColor = .clear
}
.scrollContentBackground(.hidden)
if context.reportText.isEmpty {
Text(ElementL10n.bugReportScreenDescription)
@@ -90,7 +87,7 @@ struct BugReportScreen: View {
.accessibilityIdentifier("sendLogsToggle")
.padding(.horizontal, 16)
.padding(.vertical, 11)
.background(RoundedRectangle(cornerRadius: 14).fill(Color.element.background))
.background(RoundedRectangle(cornerRadius: 14).fill(Color.element.formRowBackground))
Text(ElementL10n.bugReportScreenLogsDescription)
.font(.element.caption1)
@@ -142,9 +139,11 @@ struct BugReportScreen: View {
// MARK: - Previews
struct BugReport_Previews: PreviewProvider {
static let viewModel = BugReportViewModel(bugReportService: MockBugReportService(),
screenshot: Asset.Images.appLogo.image,
isModallyPresented: false)
static var previews: some View {
let viewModel = BugReportViewModel(bugReportService: MockBugReportService(), screenshot: Asset.Images.appLogo.image, isModallyPresented: false)
BugReportScreen(context: viewModel.context)
.previewInterfaceOrientation(.portrait)
}
}
@@ -28,14 +28,19 @@ struct RoomDetailsScreen: View {
if let topic = context.viewState.topic {
topicSection(with: topic)
.listRowBackground(Color.element.formRowBackground)
}
aboutSection
.listRowBackground(Color.element.formRowBackground)
if context.viewState.isEncrypted {
securitySection
.listRowBackground(Color.element.formRowBackground)
}
}
.scrollContentBackground(.hidden)
.background(Color.element.formBackground.ignoresSafeArea())
.alert(item: $context.alertInfo) { $0.alert }
}
@@ -82,103 +87,111 @@ struct RoomDetailsScreen: View {
}
private func topicSection(with topic: String) -> some View {
Section(header: Text(ElementL10n.roomSettingsTopic)
.formSectionHeader()) {
Text(topic)
.foregroundColor(.element.secondaryContent)
.font(.element.footnote)
}
Section {
Text(topic)
.foregroundColor(.element.secondaryContent)
.font(.element.footnote)
} header: {
Text(ElementL10n.roomSettingsTopic)
.formSectionHeader()
}
}
private var aboutSection: some View {
Section(header: Text(ElementL10n.roomDetailsAboutSectionTitle)
.formSectionHeader()) {
Button {
context.send(viewAction: .processTapPeople)
} label: {
HStack {
Image(systemName: "person")
Section {
Button {
context.send(viewAction: .processTapPeople)
} label: {
HStack {
Image(systemName: "person")
.foregroundColor(.element.secondaryContent)
.padding(4)
.background(Color.element.formBackground)
.cornerRadius(8)
.frame(width: menuIconSize, height: menuIconSize)
Text(ElementL10n.bottomActionPeople)
.foregroundColor(.element.primaryContent)
.font(.body)
Spacer()
if context.viewState.isLoadingMembers {
ProgressView()
} else {
Text(String(context.viewState.members.count))
.foregroundColor(.element.secondaryContent)
.padding(4)
.background(Color.element.system)
.clipShape(RoundedCornerShape(radius: 8, corners: .allCorners))
.frame(width: menuIconSize, height: menuIconSize)
Text(ElementL10n.bottomActionPeople)
.foregroundColor(.element.primaryContent)
.font(.body)
Spacer()
if context.viewState.isLoadingMembers {
ProgressView()
} else {
Text(String(context.viewState.members.count))
.foregroundColor(.element.secondaryContent)
.font(.element.body)
Image(systemName: "chevron.forward")
.foregroundColor(.element.quaternaryContent)
}
.font(.element.body)
Image(systemName: "chevron.forward")
.foregroundColor(.element.quaternaryContent)
}
}
.listRowInsets(listRowInsets)
.foregroundColor(.element.primaryContent)
.accessibilityIdentifier("peopleButton")
.disabled(context.viewState.isLoadingMembers)
}
.listRowInsets(listRowInsets)
.foregroundColor(.element.primaryContent)
.accessibilityIdentifier("peopleButton")
.disabled(context.viewState.isLoadingMembers)
} header: {
Text(ElementL10n.roomDetailsAboutSectionTitle)
.formSectionHeader()
}
}
private var securitySection: some View {
Section(header: Text(ElementL10n.roomProfileSectionSecurity)
.formSectionHeader()) {
HStack(alignment: .top) {
Image(systemName: "lock.shield")
Section {
HStack(alignment: .top) {
Image(systemName: "lock.shield")
.foregroundColor(.element.secondaryContent)
.padding(4)
.background(Color.element.formBackground)
.cornerRadius(8)
.frame(width: menuIconSize, height: menuIconSize)
VStack(alignment: .leading, spacing: 2) {
Text(ElementL10n.encryptionEnabled)
.foregroundColor(.element.primaryContent)
.font(.element.body)
Text(ElementL10n.encryptionEnabledTileDescription)
.foregroundColor(.element.secondaryContent)
.padding(4)
.background(Color.element.system)
.clipShape(RoundedCornerShape(radius: 8, corners: .allCorners))
.frame(width: menuIconSize, height: menuIconSize)
VStack(alignment: .leading, spacing: 2) {
Text(ElementL10n.encryptionEnabled)
.foregroundColor(.element.primaryContent)
.font(.element.body)
Text(ElementL10n.encryptionEnabledTileDescription)
.foregroundColor(.element.secondaryContent)
.font(.element.footnote)
}
Spacer()
Image(systemName: "checkmark")
.foregroundColor(.element.quaternaryContent)
.font(.element.footnote)
}
.padding(.horizontal, -3)
Spacer()
Image(systemName: "checkmark")
.foregroundColor(.element.quaternaryContent)
}
.padding(.horizontal, -3)
} header: {
Text(ElementL10n.roomProfileSectionSecurity)
.formSectionHeader()
}
}
}
// MARK: - Previews
struct RoomDetails_Previews: PreviewProvider {
static let viewModel = {
let members: [RoomMemberProxy] = [
.mockAlice,
.mockBob,
.mockCharlie
]
let roomProxy = MockRoomProxy(displayName: "Room A",
topic: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
isDirect: false,
isEncrypted: true,
canonicalAlias: "#alias:domain.com",
members: members)
return RoomDetailsViewModel(roomProxy: roomProxy,
mediaProvider: MockMediaProvider())
}()
static var previews: some View {
Group {
let members: [RoomMemberProxy] = [
.mockAlice,
.mockBob,
.mockCharlie
]
let roomProxy = MockRoomProxy(displayName: "Room A",
topic: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
isDirect: false,
isEncrypted: true,
canonicalAlias: "#alias:domain.com",
members: members)
let viewModel = RoomDetailsViewModel(roomProxy: roomProxy,
mediaProvider: MockMediaProvider())
RoomDetailsScreen(context: viewModel.context)
}
.tint(.element.accent)
RoomDetailsScreen(context: viewModel.context)
.tint(.element.accent)
}
}
@@ -22,6 +22,7 @@ struct SettingsScreen: View {
@ScaledMetric private var avatarSize = AvatarSize.user(on: .settings).value
@ScaledMetric private var menuIconSize = 30.0
private let listRowInsets = EdgeInsets(top: 8, leading: 16, bottom: 8, trailing: 16)
@ObservedObject var context: SettingsScreenViewModel.Context
@@ -29,25 +30,23 @@ struct SettingsScreen: View {
var body: some View {
Form {
userSection
.listRowBackground(rowBackgroundColor)
.listRowBackground(Color.element.formRowBackground)
if context.viewState.showSessionVerificationSection {
sessionVerificationSection
.listRowBackground(rowBackgroundColor)
.listRowBackground(Color.element.formRowBackground)
}
simplifiedSection
.listRowBackground(rowBackgroundColor)
.listRowBackground(Color.element.formRowBackground)
signOutSection
.listRowBackground(rowBackgroundColor)
}
.introspectTableView { tableView in
tableView.backgroundColor = .clear
.listRowBackground(Color.element.formRowBackground)
}
.scrollContentBackground(.hidden)
.background(Color.element.formBackground.ignoresSafeArea())
.navigationTitle(ElementL10n.settings)
.navigationBarTitleDisplayMode(.inline)
.background(backgroundColor.ignoresSafeArea())
.toolbar {
ToolbarItem(placement: .confirmationAction) {
doneButton
@@ -59,14 +58,6 @@ struct SettingsScreen: View {
Text(ElementL10n.settingsVersion + ": " + InfoPlistReader.main.bundleShortVersionString + " (" + InfoPlistReader.main.bundleVersion + ")")
}
private var backgroundColor: Color {
.element.system
}
private var rowBackgroundColor: Color {
colorScheme == .light ? .element.background : .element.system
}
private var userSection: some View {
Section {
HStack(spacing: 13) {
@@ -189,7 +180,7 @@ struct SettingsScreen_Previews: PreviewProvider {
NavigationView {
SettingsScreen(context: viewModel.context)
.previewInterfaceOrientation(.portrait)
.tint(.element.accent)
}
}
}
@@ -287,8 +287,10 @@ class MockScreen: Identifiable {
let navigationStackCoordinator = NavigationStackCoordinator()
let roomProxy = MockRoomProxy(id: "MockRoomIdentifier",
displayName: "Room",
topic: "Bacon ipsum dolor amet commodo incididunt ribeye dolore cupidatat short ribs.",
avatarURL: URL.picturesDirectory,
isEncrypted: true,
canonicalAlias: "#mock:room.org",
members: [.mockAlice, .mockBob, .mockCharlie])
let coordinator = RoomDetailsCoordinator(parameters: .init(navigationStackCoordinator: navigationStackCoordinator,
roomProxy: roomProxy,
@@ -21,19 +21,6 @@ class SettingsUITests: XCTestCase {
func testInitialStateComponents() {
let app = Application.launch()
app.goToScreenWithIdentifier(.settings)
XCTAssert(app.navigationBars[ElementL10n.settings].exists)
let reportBugButton = app.buttons["reportBugButton"]
XCTAssert(reportBugButton.exists)
XCTAssertEqual(reportBugButton.label, ElementL10n.sendBugReport)
XCTAssertTrue(app.buttons["timelineStylePicker"].exists)
XCTAssertTrue(app.staticTexts[ElementL10n.settingsTimelineStyle].exists)
let logoutButton = app.buttons["logoutButton"]
XCTAssert(logoutButton.exists)
XCTAssertEqual(logoutButton.label, ElementL10n.logout)
app.assertScreenshot(.settings)
}
}
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:970c9b01387e5cd16dfda9a4da49d0bebaaa06dfba5bcf9e48ff575ba635a471
size 90791
oid sha256:9c1a4f312dabc8e0f7ca1f4555cc0fb9212845c40d54b104aaa8e6df0a1b1a1e
size 90593
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:77a207072518aa4a87f67628ccc12a70613cfc953f7636589f9a58e30aadbdb9
size 91154
oid sha256:0677000cc125bb1c3aaaf02b0236939085c4ad2d1f34e653f2b81dfaafb98ab7
size 115608
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:911e3f878cf2fb58f4618326b0efeaa9fc69b5b750ab2f9898516f01c068e404
size 100993
oid sha256:929b6e0abf913cc4598dedd2faef6845b73697d163480dab3339f88d90e43970
size 101082
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:3d36ef0d09153dc39c5f4b4f5b14f3e71f70e0f157d45a8ef1c451c6622716b3
size 106670
oid sha256:08ec2c9755ee86d41b9825cfb4ad031e480ac8aacc3591e1a145e27344c831ee
size 106500
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:b13acb165866118942b42f3defdbd9f049f4ad3f113416a5ff92684ff6ab54df
size 107173
oid sha256:feb2d3126893d206fe486e22b0277f8cdf3e69fc1e748c1386f0f733189595b6
size 142603
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:7356f84c44761fc41f98fc4fca6cc9146eeb55a3130f76f6bea025543fb5b730
size 123373
oid sha256:f39c68000391860a8260c6faeb29954456d3f10f8cacef51ed1f5850ec7b85e1
size 126031
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:50081a6f1d88492cee859e6948f528ed1400509fa6b829f4ac30f9594d0905df
size 86961
oid sha256:999309a2b2227b3b5bc2c471fc60b7de0ff060bbffc60e18493651d31ccc2e2e
size 86938
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:a191f7365d3968ae8eecabd03e9518c80850ddd2e4f5d2e2882a67b5c4e2d0dc
size 87266
oid sha256:9892c8a4cb57e9d678204a0995f048cc9810c03bece188ee69504f0b81478e23
size 112193
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:15c84b0229148507bfbf15711a28f2ab205fbda27ad363ac6328034454287d71
size 101889
oid sha256:b84b32cd357de819895541fb6ed10c562649e9f3596108151cd93e4d815977d5
size 101777
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:ff9c2153c054fe02e85266a8e428996a3c12f908d3f303ed4b93a94d96d2e157
size 103803
oid sha256:0065cc98273a41f0782f6f556187f8f3519db3063e0dc147edcdd37cad38dc6f
size 103310
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:bcbbe7544478c8a1086ed546da661e83666a7c748f51b5e552254652cbb4b5d7
size 104328
oid sha256:f9a7db7bb77d8d87d185e8ed22b4f12be4a066678b0fa0f95200eb55111c0ab9
size 139278
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:cb6a7654c6184115f0feed9cce2b78a8c464a864a69eda2fc93e2c68a68f5602
size 123302
oid sha256:63a0ed106d7a0cbe662657f8e55e9a8b3635e847d3c48e00fc8bb1bedb7f675d
size 123587
+1
View File
@@ -0,0 +1 @@
Update appearance of forms in the app. Add formBackground and formRowBackground colours.