mirror of
https://github.com/element-hq/element-x-ios.git
synced 2025-03-10 21:39:12 +00:00
Update the layout of HomeScreenRoomCell for Dynamic Type (#695)
* Update the layout of HomeScreenRoomCell. - Make sure the separator always aligns to the text when dynamic type changes. - Use vertical padding for the minimum height to display more cells at smaller dynamic type sizes. --------- Co-authored-by: Mauro <34335419+Velin92@users.noreply.github.com>
This commit is contained in:
parent
1fbeec6182
commit
7eef86970a
@ -17,9 +17,14 @@
|
|||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
|
||||||
struct HomeScreenRoomCell: View {
|
struct HomeScreenRoomCell: View {
|
||||||
|
@Environment(\.redactionReasons) private var redactionReasons
|
||||||
|
|
||||||
let room: HomeScreenRoom
|
let room: HomeScreenRoom
|
||||||
let context: HomeScreenViewModel.Context
|
let context: HomeScreenViewModel.Context
|
||||||
|
|
||||||
|
private let verticalInsets = 12.0
|
||||||
|
private let horizontalInsets = 16.0
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
Button {
|
Button {
|
||||||
if let roomId = room.roomId {
|
if let roomId = room.roomId {
|
||||||
@ -29,22 +34,20 @@ struct HomeScreenRoomCell: View {
|
|||||||
HStack(spacing: 16.0) {
|
HStack(spacing: 16.0) {
|
||||||
avatar
|
avatar
|
||||||
|
|
||||||
VStack(alignment: .leading, spacing: 2) {
|
content
|
||||||
header
|
.padding(.vertical, verticalInsets)
|
||||||
footer
|
.overlay(alignment: .bottom) {
|
||||||
}
|
Rectangle()
|
||||||
|
.fill(Color.element.quinaryContent)
|
||||||
|
.frame(height: 1 / UIScreen.main.scale)
|
||||||
|
.padding(.trailing, -horizontalInsets)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.frame(minHeight: 84.0)
|
.padding(.horizontal, horizontalInsets)
|
||||||
.accessibilityElement(children: .combine)
|
.accessibilityElement(children: .combine)
|
||||||
}
|
}
|
||||||
.buttonStyle(HomeScreenRoomCellButtonStyle())
|
.buttonStyle(HomeScreenRoomCellButtonStyle(isSelected: false))
|
||||||
.accessibilityIdentifier(A11yIdentifiers.homeScreen.roomName(room.name))
|
.accessibilityIdentifier(A11yIdentifiers.homeScreen.roomName(room.name))
|
||||||
.overlay(alignment: .bottom) {
|
|
||||||
Divider()
|
|
||||||
.frame(height: 0.5)
|
|
||||||
.background(Color.element.quinaryContent)
|
|
||||||
.padding(.leading, 84)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ViewBuilder
|
@ViewBuilder
|
||||||
@ -57,6 +60,23 @@ struct HomeScreenRoomCell: View {
|
|||||||
.accessibilityHidden(true)
|
.accessibilityHidden(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var content: some View {
|
||||||
|
VStack(alignment: .leading, spacing: 2) {
|
||||||
|
header
|
||||||
|
footer
|
||||||
|
}
|
||||||
|
// Hide the normal content for Skeletons and overlay centre aligned placeholders.
|
||||||
|
.opacity(redactionReasons.contains(.placeholder) ? 0 : 1)
|
||||||
|
.overlay {
|
||||||
|
if redactionReasons.contains(.placeholder) {
|
||||||
|
VStack(alignment: .leading, spacing: 2) {
|
||||||
|
header
|
||||||
|
lastMessage
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@ViewBuilder
|
@ViewBuilder
|
||||||
var header: some View {
|
var header: some View {
|
||||||
HStack(alignment: .top, spacing: 16) {
|
HStack(alignment: .top, spacing: 16) {
|
||||||
@ -79,44 +99,53 @@ struct HomeScreenRoomCell: View {
|
|||||||
HStack(alignment: .firstTextBaseline) {
|
HStack(alignment: .firstTextBaseline) {
|
||||||
ZStack(alignment: .topLeading) {
|
ZStack(alignment: .topLeading) {
|
||||||
// Hidden text with 2 lines to maintain consistent height, scaling with dynamic text.
|
// Hidden text with 2 lines to maintain consistent height, scaling with dynamic text.
|
||||||
Text(" \n ").lastMessageFormatting().hidden()
|
Text(" \n ")
|
||||||
|
.lastMessageFormatting()
|
||||||
|
.hidden()
|
||||||
|
.environment(\.redactionReasons, []) // Always maintain consistent height
|
||||||
|
|
||||||
switch room.lastMessage {
|
lastMessage
|
||||||
case .loaded(let lastMessage):
|
|
||||||
Text(lastMessage)
|
|
||||||
.lastMessageFormatting()
|
|
||||||
case .loading:
|
|
||||||
Text(HomeScreenRoom.placeholderLastMessage)
|
|
||||||
.lastMessageFormatting()
|
|
||||||
.redacted(reason: .placeholder)
|
|
||||||
case .unknown:
|
|
||||||
Text(ElementL10n.message)
|
|
||||||
.lastMessageFormatting()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Spacer()
|
Spacer()
|
||||||
|
|
||||||
if room.hasUnreads {
|
if room.hasUnreads {
|
||||||
Rectangle()
|
Circle()
|
||||||
.frame(width: 12, height: 12)
|
.frame(width: 12, height: 12)
|
||||||
.foregroundColor(.element.brand)
|
.foregroundColor(.element.brand)
|
||||||
.clipShape(Circle())
|
|
||||||
.padding(.leading, 12)
|
.padding(.leading, 12)
|
||||||
} else {
|
} else {
|
||||||
// Force extra padding between last message text and the right border of the screen if there is no unread dot
|
// Force extra padding between last message text and the right border of the screen if there is no unread dot
|
||||||
Rectangle()
|
Circle()
|
||||||
.fill(Color.clear)
|
|
||||||
.frame(width: 12, height: 12)
|
.frame(width: 12, height: 12)
|
||||||
|
.hidden()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ViewBuilder
|
||||||
|
var lastMessage: some View {
|
||||||
|
switch room.lastMessage {
|
||||||
|
case .loaded(let lastMessage):
|
||||||
|
Text(lastMessage)
|
||||||
|
.lastMessageFormatting()
|
||||||
|
case .loading:
|
||||||
|
Text(HomeScreenRoom.placeholderLastMessage)
|
||||||
|
.lastMessageFormatting()
|
||||||
|
.redacted(reason: .placeholder)
|
||||||
|
case .unknown:
|
||||||
|
Text(ElementL10n.message)
|
||||||
|
.lastMessageFormatting()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct HomeScreenRoomCellButtonStyle: ButtonStyle {
|
struct HomeScreenRoomCellButtonStyle: ButtonStyle {
|
||||||
|
let isSelected: Bool
|
||||||
|
|
||||||
func makeBody(configuration: Configuration) -> some View {
|
func makeBody(configuration: Configuration) -> some View {
|
||||||
configuration.label
|
configuration.label
|
||||||
.roomCellBackground(configuration.isPressed ? .element.system : .clear)
|
.background(configuration.isPressed || isSelected ? Color.element.system : .clear)
|
||||||
.contentShape(Rectangle())
|
.contentShape(Rectangle())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -128,13 +157,6 @@ private extension View {
|
|||||||
.lineLimit(2)
|
.lineLimit(2)
|
||||||
.multilineTextAlignment(.leading)
|
.multilineTextAlignment(.leading)
|
||||||
}
|
}
|
||||||
|
|
||||||
// To be used to indicate the selected room too
|
|
||||||
func roomCellBackground(_ background: Color) -> some View {
|
|
||||||
padding(.horizontal, 8)
|
|
||||||
.padding(.horizontal, 8)
|
|
||||||
.background { background }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct HomeScreenRoomCell_Previews: PreviewProvider {
|
struct HomeScreenRoomCell_Previews: PreviewProvider {
|
||||||
@ -170,6 +192,13 @@ struct HomeScreenRoomCell_Previews: PreviewProvider {
|
|||||||
ForEach(rooms) { room in
|
ForEach(rooms) { room in
|
||||||
HomeScreenRoomCell(room: room, context: viewModel.context)
|
HomeScreenRoomCell(room: room, context: viewModel.context)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
HomeScreenRoomCell(room: .placeholder(), context: viewModel.context)
|
||||||
|
.redacted(reason: .placeholder)
|
||||||
|
HomeScreenRoomCell(room: .placeholder(), context: viewModel.context)
|
||||||
|
.redacted(reason: .placeholder)
|
||||||
|
HomeScreenRoomCell(room: .placeholder(), context: viewModel.context)
|
||||||
|
.redacted(reason: .placeholder)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
BIN
UITests/Sources/__Snapshots__/Application/de-DE-iPad-9th-generation.home.png
(Stored with Git LFS)
BIN
UITests/Sources/__Snapshots__/Application/de-DE-iPad-9th-generation.home.png
(Stored with Git LFS)
Binary file not shown.
BIN
UITests/Sources/__Snapshots__/Application/de-DE-iPad-9th-generation.userSessionScreen-1.png
(Stored with Git LFS)
BIN
UITests/Sources/__Snapshots__/Application/de-DE-iPad-9th-generation.userSessionScreen-1.png
(Stored with Git LFS)
Binary file not shown.
BIN
UITests/Sources/__Snapshots__/Application/de-DE-iPhone-14.home.png
(Stored with Git LFS)
BIN
UITests/Sources/__Snapshots__/Application/de-DE-iPhone-14.home.png
(Stored with Git LFS)
Binary file not shown.
BIN
UITests/Sources/__Snapshots__/Application/de-DE-iPhone-14.userSessionScreen-1.png
(Stored with Git LFS)
BIN
UITests/Sources/__Snapshots__/Application/de-DE-iPhone-14.userSessionScreen-1.png
(Stored with Git LFS)
Binary file not shown.
BIN
UITests/Sources/__Snapshots__/Application/en-GB-iPad-9th-generation.home.png
(Stored with Git LFS)
BIN
UITests/Sources/__Snapshots__/Application/en-GB-iPad-9th-generation.home.png
(Stored with Git LFS)
Binary file not shown.
BIN
UITests/Sources/__Snapshots__/Application/en-GB-iPad-9th-generation.userSessionScreen-1.png
(Stored with Git LFS)
BIN
UITests/Sources/__Snapshots__/Application/en-GB-iPad-9th-generation.userSessionScreen-1.png
(Stored with Git LFS)
Binary file not shown.
BIN
UITests/Sources/__Snapshots__/Application/en-GB-iPhone-14.home.png
(Stored with Git LFS)
BIN
UITests/Sources/__Snapshots__/Application/en-GB-iPhone-14.home.png
(Stored with Git LFS)
Binary file not shown.
BIN
UITests/Sources/__Snapshots__/Application/en-GB-iPhone-14.userSessionScreen-1.png
(Stored with Git LFS)
BIN
UITests/Sources/__Snapshots__/Application/en-GB-iPhone-14.userSessionScreen-1.png
(Stored with Git LFS)
Binary file not shown.
1
changelog.d/pr-670.bugfix
Normal file
1
changelog.d/pr-670.bugfix
Normal file
@ -0,0 +1 @@
|
|||||||
|
Hides the scroll down button for VoiceOver users if it is hidden for visual users by Sem Pruijs
|
1
changelog.d/pr-695.bugfix
Normal file
1
changelog.d/pr-695.bugfix
Normal file
@ -0,0 +1 @@
|
|||||||
|
Hide the message composer textfield placeholder for VoiceOver users by Sem Pruijs
|
Loading…
x
Reference in New Issue
Block a user