mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-11-05 20:09:04 +00:00
room members list redesign
This commit is contained in:
@@ -629,6 +629,8 @@
|
|||||||
"screen_room_details_requests_to_join_title" = "Requests to join";
|
"screen_room_details_requests_to_join_title" = "Requests to join";
|
||||||
"screen_room_grouped_state_events_expand" = "Expand";
|
"screen_room_grouped_state_events_expand" = "Expand";
|
||||||
"screen_room_grouped_state_events_reduce" = "Reduce";
|
"screen_room_grouped_state_events_reduce" = "Reduce";
|
||||||
|
"screen_room_member_list_banned_header_title" = "%1$d Banned";
|
||||||
|
"screen_room_member_list_pending_status" = "Pending";
|
||||||
"screen_room_roles_and_permissions_space_details" = "Space details";
|
"screen_room_roles_and_permissions_space_details" = "Space details";
|
||||||
"screen_room_timeline_tombstoned_room_action" = "Jump to new room";
|
"screen_room_timeline_tombstoned_room_action" = "Jump to new room";
|
||||||
"screen_room_timeline_tombstoned_room_message" = "This room has been replaced and is no longer active";
|
"screen_room_timeline_tombstoned_room_message" = "This room has been replaced and is no longer active";
|
||||||
@@ -1069,7 +1071,7 @@
|
|||||||
"screen_room_member_list_manage_member_unban_message" = "They will be able to join this room again if invited.";
|
"screen_room_member_list_manage_member_unban_message" = "They will be able to join this room again if invited.";
|
||||||
"screen_room_member_list_mode_banned" = "Banned";
|
"screen_room_member_list_mode_banned" = "Banned";
|
||||||
"screen_room_member_list_mode_members" = "Members";
|
"screen_room_member_list_mode_members" = "Members";
|
||||||
"screen_room_member_list_pending_header_title" = "Pending";
|
"screen_room_member_list_pending_header_title" = "%1$d Invited";
|
||||||
"screen_room_member_list_role_owner" = "Owner";
|
"screen_room_member_list_role_owner" = "Owner";
|
||||||
"screen_room_member_list_room_members_header_title" = "Room members";
|
"screen_room_member_list_room_members_header_title" = "Room members";
|
||||||
"screen_room_member_list_unbanning_user" = "Unbanning %1$@";
|
"screen_room_member_list_unbanning_user" = "Unbanning %1$@";
|
||||||
|
|||||||
@@ -629,6 +629,8 @@
|
|||||||
"screen_room_details_requests_to_join_title" = "Requests to join";
|
"screen_room_details_requests_to_join_title" = "Requests to join";
|
||||||
"screen_room_grouped_state_events_expand" = "Expand";
|
"screen_room_grouped_state_events_expand" = "Expand";
|
||||||
"screen_room_grouped_state_events_reduce" = "Reduce";
|
"screen_room_grouped_state_events_reduce" = "Reduce";
|
||||||
|
"screen_room_member_list_banned_header_title" = "%1$d Banned";
|
||||||
|
"screen_room_member_list_pending_status" = "Pending";
|
||||||
"screen_room_roles_and_permissions_space_details" = "Space details";
|
"screen_room_roles_and_permissions_space_details" = "Space details";
|
||||||
"screen_room_timeline_tombstoned_room_action" = "Jump to new room";
|
"screen_room_timeline_tombstoned_room_action" = "Jump to new room";
|
||||||
"screen_room_timeline_tombstoned_room_message" = "This room has been replaced and is no longer active";
|
"screen_room_timeline_tombstoned_room_message" = "This room has been replaced and is no longer active";
|
||||||
@@ -1069,7 +1071,7 @@
|
|||||||
"screen_room_member_list_manage_member_unban_message" = "They will be able to join this room again if invited.";
|
"screen_room_member_list_manage_member_unban_message" = "They will be able to join this room again if invited.";
|
||||||
"screen_room_member_list_mode_banned" = "Banned";
|
"screen_room_member_list_mode_banned" = "Banned";
|
||||||
"screen_room_member_list_mode_members" = "Members";
|
"screen_room_member_list_mode_members" = "Members";
|
||||||
"screen_room_member_list_pending_header_title" = "Pending";
|
"screen_room_member_list_pending_header_title" = "%1$d Invited";
|
||||||
"screen_room_member_list_role_owner" = "Owner";
|
"screen_room_member_list_role_owner" = "Owner";
|
||||||
"screen_room_member_list_room_members_header_title" = "Room members";
|
"screen_room_member_list_room_members_header_title" = "Room members";
|
||||||
"screen_room_member_list_unbanning_user" = "Unbanning %1$@";
|
"screen_room_member_list_unbanning_user" = "Unbanning %1$@";
|
||||||
|
|||||||
@@ -317,9 +317,9 @@
|
|||||||
<key>NSStringFormatValueTypeKey</key>
|
<key>NSStringFormatValueTypeKey</key>
|
||||||
<string>d</string>
|
<string>d</string>
|
||||||
<key>one</key>
|
<key>one</key>
|
||||||
<string>%1$d person</string>
|
<string>%1$d Person</string>
|
||||||
<key>other</key>
|
<key>other</key>
|
||||||
<string>%1$d people</string>
|
<string>%1$d People</string>
|
||||||
</dict>
|
</dict>
|
||||||
</dict>
|
</dict>
|
||||||
<key>screen_room_multiple_knock_requests_title</key>
|
<key>screen_room_multiple_knock_requests_title</key>
|
||||||
|
|||||||
@@ -2478,6 +2478,10 @@ internal enum L10n {
|
|||||||
}
|
}
|
||||||
/// There are no banned users.
|
/// There are no banned users.
|
||||||
internal static var screenRoomMemberListBannedEmpty: String { return L10n.tr("Localizable", "screen_room_member_list_banned_empty") }
|
internal static var screenRoomMemberListBannedEmpty: String { return L10n.tr("Localizable", "screen_room_member_list_banned_empty") }
|
||||||
|
/// %1$d Banned
|
||||||
|
internal static func screenRoomMemberListBannedHeaderTitle(_ p1: Int) -> String {
|
||||||
|
return L10n.tr("Localizable", "screen_room_member_list_banned_header_title", p1)
|
||||||
|
}
|
||||||
/// Plural format key: "%#@COUNT@"
|
/// Plural format key: "%#@COUNT@"
|
||||||
internal static func screenRoomMemberListHeaderTitle(_ p1: Int) -> String {
|
internal static func screenRoomMemberListHeaderTitle(_ p1: Int) -> String {
|
||||||
return L10n.tr("Localizable", "screen_room_member_list_header_title", p1)
|
return L10n.tr("Localizable", "screen_room_member_list_header_title", p1)
|
||||||
@@ -2496,8 +2500,12 @@ internal enum L10n {
|
|||||||
internal static var screenRoomMemberListModeBanned: String { return L10n.tr("Localizable", "screen_room_member_list_mode_banned") }
|
internal static var screenRoomMemberListModeBanned: String { return L10n.tr("Localizable", "screen_room_member_list_mode_banned") }
|
||||||
/// Members
|
/// Members
|
||||||
internal static var screenRoomMemberListModeMembers: String { return L10n.tr("Localizable", "screen_room_member_list_mode_members") }
|
internal static var screenRoomMemberListModeMembers: String { return L10n.tr("Localizable", "screen_room_member_list_mode_members") }
|
||||||
|
/// %1$d Invited
|
||||||
|
internal static func screenRoomMemberListPendingHeaderTitle(_ p1: Int) -> String {
|
||||||
|
return L10n.tr("Localizable", "screen_room_member_list_pending_header_title", p1)
|
||||||
|
}
|
||||||
/// Pending
|
/// Pending
|
||||||
internal static var screenRoomMemberListPendingHeaderTitle: String { return L10n.tr("Localizable", "screen_room_member_list_pending_header_title") }
|
internal static var screenRoomMemberListPendingStatus: String { return L10n.tr("Localizable", "screen_room_member_list_pending_status") }
|
||||||
/// Admin
|
/// Admin
|
||||||
internal static var screenRoomMemberListRoleAdministrator: String { return L10n.tr("Localizable", "screen_room_member_list_role_administrator") }
|
internal static var screenRoomMemberListRoleAdministrator: String { return L10n.tr("Localizable", "screen_room_member_list_role_administrator") }
|
||||||
/// Moderator
|
/// Moderator
|
||||||
|
|||||||
@@ -65,6 +65,7 @@ enum UserAvatarSizeOnScreen {
|
|||||||
case timeline
|
case timeline
|
||||||
case settings
|
case settings
|
||||||
case roomDetails
|
case roomDetails
|
||||||
|
case roomMembersList
|
||||||
case dmDetails
|
case dmDetails
|
||||||
case startChat
|
case startChat
|
||||||
case memberDetails
|
case memberDetails
|
||||||
@@ -103,6 +104,8 @@ enum UserAvatarSizeOnScreen {
|
|||||||
return 52
|
return 52
|
||||||
case .roomDetails:
|
case .roomDetails:
|
||||||
return 44
|
return 44
|
||||||
|
case .roomMembersList:
|
||||||
|
return 32
|
||||||
case .startChat:
|
case .startChat:
|
||||||
return 36
|
return 36
|
||||||
case .memberDetails:
|
case .memberDetails:
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ struct RoomChangeRolesScreenRow: View {
|
|||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
ListRow(label: .avatar(title: member.name ?? member.id,
|
ListRow(label: .avatar(title: member.name ?? member.id,
|
||||||
status: member.isInvited ? L10n.screenRoomMemberListPendingHeaderTitle : nil,
|
status: member.isInvited ? L10n.screenRoomMemberListPendingStatus : nil,
|
||||||
description: member.name == nil ? nil : member.id,
|
description: member.name == nil ? nil : member.id,
|
||||||
icon: avatar),
|
icon: avatar),
|
||||||
kind: .multiSelection(isSelected: isSelected, action: action))
|
kind: .multiSelection(isSelected: isSelected, action: action))
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ struct RoomMembersListScreen: View {
|
|||||||
.tag(RoomMembersListScreenMode.banned)
|
.tag(RoomMembersListScreenMode.banned)
|
||||||
}
|
}
|
||||||
.pickerStyle(.segmented)
|
.pickerStyle(.segmented)
|
||||||
.padding(.horizontal, 16)
|
.padding(ListRowPadding.insets)
|
||||||
}
|
}
|
||||||
|
|
||||||
if context.mode == .members {
|
if context.mode == .members {
|
||||||
@@ -38,15 +38,14 @@ struct RoomMembersListScreen: View {
|
|||||||
.foregroundStyle(.secondary)
|
.foregroundStyle(.secondary)
|
||||||
.multilineTextAlignment(.center)
|
.multilineTextAlignment(.center)
|
||||||
.frame(maxWidth: .infinity)
|
.frame(maxWidth: .infinity)
|
||||||
.background(.compound.bgCanvasDefault)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.compoundList()
|
||||||
.searchable(text: $context.searchQuery,
|
.searchable(text: $context.searchQuery,
|
||||||
placement: .navigationBarDrawer(displayMode: .always),
|
placement: .navigationBarDrawer(displayMode: .always),
|
||||||
prompt: L10n.commonSearchForSomeone)
|
prompt: L10n.commonSearchForSomeone)
|
||||||
.compoundSearchField()
|
.compoundSearchField()
|
||||||
.autocorrectionDisabled()
|
.autocorrectionDisabled()
|
||||||
.background(Color.compound.bgCanvasDefault.ignoresSafeArea())
|
|
||||||
.navigationTitle(L10n.commonPeople)
|
.navigationTitle(L10n.commonPeople)
|
||||||
.navigationBarTitleDisplayMode(.inline)
|
.navigationBarTitleDisplayMode(.inline)
|
||||||
.sheet(item: $context.manageMemeberViewModel) {
|
.sheet(item: $context.manageMemeberViewModel) {
|
||||||
@@ -59,41 +58,44 @@ struct RoomMembersListScreen: View {
|
|||||||
|
|
||||||
// MARK: - Private
|
// MARK: - Private
|
||||||
|
|
||||||
|
@ViewBuilder
|
||||||
var roomMembers: some View {
|
var roomMembers: some View {
|
||||||
LazyVStack(alignment: .leading, spacing: 12) {
|
membersSection(entries: context.viewState.visibleInvitedMembers, section: .invited)
|
||||||
membersSection(entries: context.viewState.visibleInvitedMembers, sectionTitle: L10n.screenRoomMemberListPendingHeaderTitle)
|
membersSection(entries: context.viewState.visibleJoinedMembers, section: .joined)
|
||||||
membersSection(entries: context.viewState.visibleJoinedMembers, sectionTitle: L10n.screenRoomMemberListHeaderTitle(Int(context.viewState.joinedMembersCount)))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var bannedUsers: some View {
|
var bannedUsers: some View {
|
||||||
LazyVStack(alignment: .leading, spacing: 12) {
|
membersSection(entries: context.viewState.visibleBannedMembers, section: .banned)
|
||||||
membersSection(entries: context.viewState.visibleBannedMembers)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ViewBuilder
|
@ViewBuilder
|
||||||
private func membersSection(entries: [RoomMemberListScreenEntry], sectionTitle: String? = nil) -> some View {
|
private func membersSection(entries: [RoomMemberListScreenEntry], section: MembersSection) -> some View {
|
||||||
if !entries.isEmpty {
|
if !entries.isEmpty {
|
||||||
Section {
|
Section {
|
||||||
ForEach(entries, id: \.member.id) { entry in
|
LazyVStack(alignment: .leading, spacing: 0) {
|
||||||
RoomMembersListScreenMemberCell(listEntry: entry, context: context)
|
ForEach(entries, id: \.member.id) { entry in
|
||||||
|
ListRow(kind: .custom {
|
||||||
|
RoomMembersListScreenMemberCell(listEntry: entry, isLast: entries.last == entry, context: context)
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
.background(.compound.bgCanvasDefault)
|
||||||
|
.clipShape(sectionShape)
|
||||||
} header: {
|
} header: {
|
||||||
if let sectionTitle {
|
section.header(count: entries.count)
|
||||||
Text(sectionTitle)
|
|
||||||
.foregroundColor(.compound.textSecondary)
|
|
||||||
.font(.compound.bodyLG)
|
|
||||||
.padding(.top, 12)
|
|
||||||
} else {
|
|
||||||
// Put something in here to maintain constant top padding.
|
|
||||||
Spacer().frame(height: 0)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
.padding(.horizontal, 16)
|
.padding(.horizontal, 16)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private var sectionShape: AnyShape {
|
||||||
|
if #available(iOS 26, *) {
|
||||||
|
AnyShape(ConcentricRectangle(corners: .concentric(minimum: 26)))
|
||||||
|
} else {
|
||||||
|
AnyShape(RoundedRectangle(cornerRadius: 8))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@ToolbarContentBuilder
|
@ToolbarContentBuilder
|
||||||
private var toolbar: some ToolbarContent {
|
private var toolbar: some ToolbarContent {
|
||||||
ToolbarItem(placement: .confirmationAction) {
|
ToolbarItem(placement: .confirmationAction) {
|
||||||
@@ -106,6 +108,40 @@ struct RoomMembersListScreen: View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private enum MembersSection {
|
||||||
|
case joined
|
||||||
|
case invited
|
||||||
|
case banned
|
||||||
|
|
||||||
|
private func sectionTitle(count: Int) -> String {
|
||||||
|
switch self {
|
||||||
|
case .banned:
|
||||||
|
L10n.screenRoomMemberListBannedHeaderTitle(count)
|
||||||
|
case .invited:
|
||||||
|
L10n.screenRoomMemberListHeaderTitle(count)
|
||||||
|
case .joined:
|
||||||
|
L10n.screenRoomMemberListPendingHeaderTitle(count)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ViewBuilder
|
||||||
|
private func text(count: Int) -> some View {
|
||||||
|
switch self {
|
||||||
|
case .invited, .joined:
|
||||||
|
Text(sectionTitle(count: count))
|
||||||
|
case .banned:
|
||||||
|
Text(sectionTitle(count: count))
|
||||||
|
.foregroundStyle(.compound.bgCriticalPrimary)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func header(count: Int) -> some View {
|
||||||
|
text(count: count)
|
||||||
|
.compoundListSectionHeader()
|
||||||
|
.frame(maxWidth: .infinity, alignment: .leading)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// MARK: - Previews
|
// MARK: - Previews
|
||||||
|
|
||||||
struct RoomMembersListScreen_Previews: PreviewProvider, TestablePreview {
|
struct RoomMembersListScreen_Previews: PreviewProvider, TestablePreview {
|
||||||
|
|||||||
+18
-8
@@ -6,28 +6,30 @@
|
|||||||
// 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 RoomMembersListScreenMemberCell: View {
|
struct RoomMembersListScreenMemberCell: View {
|
||||||
let listEntry: RoomMemberListScreenEntry
|
let listEntry: RoomMemberListScreenEntry
|
||||||
|
let isLast: Bool
|
||||||
let context: RoomMembersListScreenViewModel.Context
|
let context: RoomMembersListScreenViewModel.Context
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
Button {
|
Button {
|
||||||
context.send(viewAction: .selectMember(listEntry.member))
|
context.send(viewAction: .selectMember(listEntry.member))
|
||||||
} label: {
|
} label: {
|
||||||
HStack(spacing: 8) {
|
HStack(spacing: 16) {
|
||||||
LoadableAvatarImage(url: avatarURL,
|
LoadableAvatarImage(url: avatarURL,
|
||||||
name: avatarName,
|
name: avatarName,
|
||||||
contentID: listEntry.member.id,
|
contentID: listEntry.member.id,
|
||||||
avatarSize: .user(on: .roomDetails),
|
avatarSize: .user(on: .roomMembersList),
|
||||||
mediaProvider: context.mediaProvider)
|
mediaProvider: context.mediaProvider)
|
||||||
.accessibilityHidden(true)
|
.accessibilityHidden(true)
|
||||||
|
|
||||||
HStack(alignment: .center, spacing: 4) {
|
HStack(alignment: .center, spacing: 4) {
|
||||||
VStack(alignment: .leading, spacing: 0) {
|
VStack(alignment: .leading, spacing: 2) {
|
||||||
Text(title)
|
Text(title)
|
||||||
.font(.compound.bodyMDSemibold)
|
.font(.compound.bodyLG)
|
||||||
.foregroundColor(.compound.textPrimary)
|
.foregroundColor(.compound.textPrimary)
|
||||||
.lineLimit(1)
|
.lineLimit(1)
|
||||||
|
|
||||||
@@ -44,11 +46,19 @@ struct RoomMembersListScreenMemberCell: View {
|
|||||||
|
|
||||||
if let role {
|
if let role {
|
||||||
Text(role)
|
Text(role)
|
||||||
.font(.compound.bodyXS)
|
.font(.compound.bodyLG)
|
||||||
.foregroundStyle(.compound.textSecondary)
|
.foregroundStyle(.compound.textSecondary)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.overlay(alignment: .bottom) {
|
||||||
|
if !isLast {
|
||||||
|
ListRowColor.separatorTint
|
||||||
|
.frame(height: 1)
|
||||||
|
.offset(x: 0, y: ListRowPadding.vertical)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
.padding(ListRowPadding.insets)
|
||||||
.frame(maxWidth: .infinity, alignment: .leading)
|
.frame(maxWidth: .infinity, alignment: .leading)
|
||||||
.accessibilityElement(children: .combine)
|
.accessibilityElement(children: .combine)
|
||||||
}
|
}
|
||||||
@@ -124,17 +134,17 @@ struct RoomMembersListMemberCell_Previews: PreviewProvider, TestablePreview {
|
|||||||
userIndicatorController: ServiceLocator.shared.userIndicatorController,
|
userIndicatorController: ServiceLocator.shared.userIndicatorController,
|
||||||
analytics: ServiceLocator.shared.analytics)
|
analytics: ServiceLocator.shared.analytics)
|
||||||
static var previews: some View {
|
static var previews: some View {
|
||||||
VStack(spacing: 12) {
|
VStack(spacing: 0) {
|
||||||
Section("Invited/Joined") {
|
Section("Invited/Joined") {
|
||||||
ForEach(members, id: \.member.id) { entry in
|
ForEach(members, id: \.member.id) { entry in
|
||||||
RoomMembersListScreenMemberCell(listEntry: entry, context: viewModel.context)
|
RoomMembersListScreenMemberCell(listEntry: entry, isLast: members.last == entry, context: viewModel.context)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Banned members should have their profiles hidden and the avatar should use the first letter from their user ID.
|
// Banned members should have their profiles hidden and the avatar should use the first letter from their user ID.
|
||||||
Section("Banned") {
|
Section("Banned") {
|
||||||
ForEach(bannedMembers, id: \.member.id) { entry in
|
ForEach(bannedMembers, id: \.member.id) { entry in
|
||||||
RoomMembersListScreenMemberCell(listEntry: entry, context: viewModel.context)
|
RoomMembersListScreenMemberCell(listEntry: entry, isLast: bannedMembers.last == entry, context: viewModel.context)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:c05a6866924c1dc6ed46c7c42439dd7edb47b39caa41ed3ea99ee4514aebbd9b
|
oid sha256:626953fe5279cddc37886a61d6628430e943cf0e9bda8ec47bbc0b97c2c5213c
|
||||||
size 172188
|
size 162660
|
||||||
|
|||||||
+2
-2
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:6ddfa14daa481bf9b3fd5a84a0cada55486d626313c3049c338f640ecc7210f7
|
oid sha256:b62b1cc3a8ceba8dc8f09d85e600a2371ad5a40c30063b60a27fef90e79513b7
|
||||||
size 175875
|
size 164686
|
||||||
|
|||||||
+2
-2
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:5d7c756030fcec306f1708cbb1b1275661840c3649736590b4a777f0aaf28bf7
|
oid sha256:f81d4dd8fa0c0e584233dc1469a79a060ca264d51976914745428d4d55047653
|
||||||
size 115487
|
size 108340
|
||||||
|
|||||||
+2
-2
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:6658c53066412084efb6c2f9615c8d0519ba6e993ed88d8f1935dca8afbd894d
|
oid sha256:617978565a9716a9217398e284505ec9d993ede2b1fcfe5d6b847a64ca8eca67
|
||||||
size 119683
|
size 113531
|
||||||
|
|||||||
+2
-2
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:6fc900a55aea1573a2d544b88aff8ecbb890a3ec6d61af00d081374f35907368
|
oid sha256:cbcfb604471fe40dd146fe4d8e0a956c0d301781ed5a0c3159734fcd58491406
|
||||||
size 108132
|
size 121371
|
||||||
|
|||||||
+2
-2
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:b104bd91c956e166d92b98e95d3abd82d6403dae85f31019c1ec3d4a17070257
|
oid sha256:781c81df49e21c06d9fdff9b75433f8f5f503f6e204365288b1f6d6cdca45390
|
||||||
size 111815
|
size 127670
|
||||||
|
|||||||
+2
-2
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:2a49cf8fb6c4684125678d52bee5a04bef44d5db5b5f41e3626043b808ee5990
|
oid sha256:71d7553d6d3f0e2abc63993724b98f14019b4b1a33141d5f3d19912c78ef852c
|
||||||
size 61196
|
size 72866
|
||||||
|
|||||||
+2
-2
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:8106c194e4f97f9ed6972c11aea4f78e5a948e9e461646e4dd20e3aca175013a
|
oid sha256:e6231f0e6186964a242496dc1e4a6cf3305eb07441ef563f8b69b9a37d2aae19
|
||||||
size 65510
|
size 78832
|
||||||
|
|||||||
+2
-2
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:f9bdeaa4425619052c7e7eab2b5f4405ad4c5047ed57cba13f31f1a2f1f2436d
|
oid sha256:fc17e0a24d8cc64bbbe65a7f676bf09256175accad59c20b259ae669502bbbfb
|
||||||
size 83436
|
size 93333
|
||||||
|
|||||||
+2
-2
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:d433ff05d79d924e76e47ea61bab505e34e0591203960a28fa43c7e1c7a17994
|
oid sha256:6064da92e7315269aa38bc2ed679cff391b9da78db19673b06c8aa5a0aac11e1
|
||||||
size 88184
|
size 97330
|
||||||
|
|||||||
+2
-2
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:f57ed7cafac354d0309851aa21a3885032549ab5447d78f1c469e18353856399
|
oid sha256:dce1a408d4ec5ae9962edc09bc01b0477fe16e510af431006469d48d6e4a29bf
|
||||||
size 41120
|
size 47487
|
||||||
|
|||||||
+2
-2
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:dc5dfbe50f2f344599a3ae8fc8fef8906ca665bc3f11a66b646315cdf5aea3a0
|
oid sha256:941e55f24c7a3fbedc55f075fbff6c61469347c1a40f9dc124f5c3c66e596a32
|
||||||
size 47374
|
size 53536
|
||||||
|
|||||||
+2
-2
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:d8e8b9718e40cecfcc94ebb04d2c1e41fc80c9ca00189d3c20200e99dd5f3a79
|
oid sha256:26487be725ada6101341c7d2c763e2f951a5ed0c78a21728d8e8133f00f919a7
|
||||||
size 147670
|
size 158766
|
||||||
|
|||||||
+2
-2
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:06afe8ae860805c6c5b96ef8f3dec4a282b81efc1792d9fa346d6c330132a85b
|
oid sha256:4dc4ba4368f4a62de3e3ff56f0d7ad9db560850076f6df06a4fd2add88f388ba
|
||||||
size 158881
|
size 164680
|
||||||
|
|||||||
+2
-2
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:f0738dc64c667fc44298ab817c2eadbc46dd6969941b6a4cdef75bb9ec35399d
|
oid sha256:7add08193316c3e604894d4168fbe1f8a2ccec3bcb1ee75748c8a21948f90b73
|
||||||
size 95115
|
size 104760
|
||||||
|
|||||||
+2
-2
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:d768e7fe7686374632a0448b8d71e9394fc86186b700eb505140470779ea2782
|
oid sha256:4376b92a41308856c4d072033614d1fd23b80eaabbf61341efb3f7c456304aef
|
||||||
size 105486
|
size 115048
|
||||||
|
|||||||
+2
-2
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:b7f1f3a735682ef5d36cbfe87fecfe0233ded73a14ab02eebc336a8b1792099a
|
oid sha256:f2185e01f3bc1aad1691fecc6f37151b54b4d9407fe081d23a1c518249bd8a08
|
||||||
size 151862
|
size 163295
|
||||||
|
|||||||
+2
-2
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:0ff46c798eaac998442ccf3179442425a41f790cb7c5a3cb9aa98dec5553ca3d
|
oid sha256:58cc3e279f005c41b2ca490a7761ebaf348ed76b9b38251203a7e655c1bbed08
|
||||||
size 161568
|
size 172300
|
||||||
|
|||||||
+2
-2
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:c1840368e7afd7efe36ddceb78003bba9ead25bd2c7b408f7af778cd3a146ccb
|
oid sha256:12eed8cec6dbd7f95f3caa6c855e2945ad9038d8692c6441af2291811c1b3ddf
|
||||||
size 99336
|
size 108805
|
||||||
|
|||||||
+2
-2
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:9a0a9f0b949250ca39c3b1698f28c32bc5dcb9cc184f55ee13b285b837234c02
|
oid sha256:ae20b89c56b784e58cd12a8703fc5a1fba2645c144d9dd0ec35623fbb64d0721
|
||||||
size 110635
|
size 121582
|
||||||
|
|||||||
+2
-2
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:cf4d509b9a4e3628c86c9362ab9acbf145520785774b136b7f55aa21e0d8d5ec
|
oid sha256:200ac76b32fc16f4f27da59c265fe538102ba463409d4ce1c97aff7ab0a04e02
|
||||||
size 141288
|
size 152142
|
||||||
|
|||||||
+2
-2
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:ccdc87a92e6c749b1de8a496f48f87c78b34fc99fec918afadd1d2323cdc6d8c
|
oid sha256:552257279e96d8ec4841194e1f4dee4fa2ae4f2b337994bd03a1be08f09ffe24
|
||||||
size 150793
|
size 156878
|
||||||
|
|||||||
+2
-2
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:1e09aa40dccea285ce9285cae8e27ca074af7928ec78f2b4f29906a6c5a02761
|
oid sha256:bc454b71beceefe553e13085e35e2ff6fe473f622e4532bbb0d8f98cef7b6b50
|
||||||
size 89977
|
size 98405
|
||||||
|
|||||||
+2
-2
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:21cdb1184fccb5c74647d45a12ccbf46efa6e87775b364f286c7fd7dde3b73fe
|
oid sha256:62d46a736487e5c851e1c5c17cb08e6d7475018b97702af394c78c80b7acd8bf
|
||||||
size 99479
|
size 108150
|
||||||
|
|||||||
@@ -8,6 +8,16 @@
|
|||||||
|
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
|
||||||
|
public enum ListRowColor {
|
||||||
|
public static var separatorTint: Color {
|
||||||
|
if #available(iOS 26, *) {
|
||||||
|
.compound.bgSubtleSecondary
|
||||||
|
} else {
|
||||||
|
.compound._borderInteractiveSecondaryAlpha
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public enum ListRowPadding {
|
public enum ListRowPadding {
|
||||||
public static let horizontal: CGFloat = 16
|
public static let horizontal: CGFloat = 16
|
||||||
public static let vertical: CGFloat = 13
|
public static let vertical: CGFloat = 13
|
||||||
@@ -49,20 +59,12 @@ public struct ListRow<Icon: View, DetailsIcon: View, CustomContent: View, Select
|
|||||||
|
|
||||||
let kind: Kind<CustomContent, SelectionValue>
|
let kind: Kind<CustomContent, SelectionValue>
|
||||||
|
|
||||||
private var separatorTint: Color {
|
|
||||||
if #available(iOS 26, *) {
|
|
||||||
.compound.bgSubtleSecondary
|
|
||||||
} else {
|
|
||||||
.compound._borderInteractiveSecondaryAlpha
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public var body: some View {
|
public var body: some View {
|
||||||
rowContent
|
rowContent
|
||||||
.buttonStyle(ListRowButtonStyle())
|
.buttonStyle(ListRowButtonStyle())
|
||||||
.listRowInsets(EdgeInsets())
|
.listRowInsets(EdgeInsets())
|
||||||
.listRowBackground(Color.compound.bgCanvasDefaultLevel1)
|
.listRowBackground(Color.compound.bgCanvasDefaultLevel1)
|
||||||
.listRowSeparatorTint(separatorTint)
|
.listRowSeparatorTint(ListRowColor.separatorTint)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ViewBuilder
|
@ViewBuilder
|
||||||
|
|||||||
Reference in New Issue
Block a user