From 2f13093cc0cae0f7107d26095b61492808eef041 Mon Sep 17 00:00:00 2001 From: Daniel Chick Date: Mon, 23 Dec 2024 12:43:18 -0600 Subject: [PATCH] [iOS] Select all Users When Editing (#1373) --- Shared/Extensions/Set.swift | 6 + .../Views/SelectUserView/SelectUserView.swift | 107 +++++++++--------- 2 files changed, 61 insertions(+), 52 deletions(-) diff --git a/Shared/Extensions/Set.swift b/Shared/Extensions/Set.swift index bc6b9531a..a44224603 100644 --- a/Shared/Extensions/Set.swift +++ b/Shared/Extensions/Set.swift @@ -17,4 +17,10 @@ extension Set { insert(value) } } + + mutating func insert(contentsOf elements: [Element]) { + for element in elements { + insert(element) + } + } } diff --git a/Swiftfin/Views/SelectUserView/SelectUserView.swift b/Swiftfin/Views/SelectUserView/SelectUserView.swift index c36b2cc8f..798f6abcd 100644 --- a/Swiftfin/Views/SelectUserView/SelectUserView.swift +++ b/Swiftfin/Views/SelectUserView/SelectUserView.swift @@ -20,6 +20,9 @@ import SwiftUI // TODO: user ordering // - name // - last signed in date +// TODO: between the server selection menu and delete toolbar, +// figure out a way to make the grid/list and splash screen +// not jump when size is changed struct SelectUserView: View { @@ -85,6 +88,17 @@ struct SelectUserView: View { @State private var error: Error? = nil + private var users: [UserState] { + gridItems.compactMap { item in + switch item { + case let .user(user, _): + return user + default: + return nil + } + } + } + // MARK: - Select Server private var selectedServer: ServerState? { @@ -380,33 +394,6 @@ struct SelectUserView: View { } } - // MARK: - Delete Users Button - - @ViewBuilder - private var deleteUsersButton: some View { - Button { - isPresentingConfirmDeleteUsers = true - } label: { - ZStack { - Color.red - - Text(L10n.delete) - .font(.body.weight(.semibold)) - .foregroundStyle(selectedUsers.isNotEmpty ? .primary : .secondary) - - if selectedUsers.isEmpty { - Color.black - .opacity(0.5) - } - } - .clipShape(RoundedRectangle(cornerRadius: 10)) - .frame(height: 50) - .frame(maxWidth: 400) - } - .disabled(selectedUsers.isEmpty) - .buttonStyle(.plain) - } - // MARK: - User View @ViewBuilder @@ -453,11 +440,6 @@ struct SelectUserView: View { ) .edgePadding([.bottom, .horizontal]) } - - if isEditingUsers { - deleteUsersButton - .edgePadding([.bottom, .horizontal]) - } } .background { if selectUserUseSplashscreen, splashScreenImageSources.isNotEmpty { @@ -516,28 +498,49 @@ struct SelectUserView: View { .aspectRatio(contentMode: .fit) .frame(width: 30) } - } - .topBarTrailing { - if isEditingUsers { - Button { - isEditingUsers = false - } label: { - L10n.cancel.text - .font(.headline) - .padding(.vertical, 5) - .padding(.horizontal, 10) - .background { - if colorScheme == .light { - Color.secondarySystemFill - } else { - Color.tertiarySystemBackground - } + + ToolbarItem(placement: .topBarLeading) { + if isEditingUsers { + if selectedUsers.count == users.count { + Button(L10n.removeAll) { + selectedUsers.removeAll() + } + .buttonStyle(.toolbarPill) + } else { + Button(L10n.selectAll) { + selectedUsers.insert(contentsOf: users) } - .clipShape(RoundedRectangle(cornerRadius: 10)) + .buttonStyle(.toolbarPill) + } + } + } + + ToolbarItemGroup(placement: .topBarTrailing) { + if isEditingUsers { + Button(isEditingUsers ? L10n.cancel : L10n.edit) { + isEditingUsers.toggle() + + UIDevice.impact(.light) + + if !isEditingUsers { + selectedUsers.removeAll() + } + } + .buttonStyle(.toolbarPill) + } else { + advancedMenu + } + } + + ToolbarItem(placement: .bottomBar) { + if isEditingUsers { + Button(L10n.delete) { + isPresentingConfirmDeleteUsers = true + } + .buttonStyle(.toolbarPill(.red)) + .disabled(selectedUsers.isEmpty) + .frame(maxWidth: .infinity, alignment: .trailing) } - .buttonStyle(.plain) - } else { - advancedMenu } } .onAppear {