From 2e3a06c8e44bff022cb787f7a7e1eda794db3f01 Mon Sep 17 00:00:00 2001 From: Valentin Perignon Date: Wed, 31 Jan 2024 14:30:39 +0100 Subject: [PATCH 1/2] refactor(ThreadCell): Move checkbox to a different view --- .../{ => ThreadCell}/ThreadCell.swift | 56 +++++++--------- .../ThreadCell/ThreadCellCheckboxView.swift | 66 +++++++++++++++++++ .../ThreadCellDetailsView.swift | 0 .../ThreadCellHeaderView.swift | 0 .../{ => ThreadCell}/ThreadCellInfoView.swift | 0 5 files changed, 88 insertions(+), 34 deletions(-) rename Mail/Components/{ => ThreadCell}/ThreadCell.swift (81%) create mode 100644 Mail/Components/ThreadCell/ThreadCellCheckboxView.swift rename Mail/Components/{ => ThreadCell}/ThreadCellDetailsView.swift (100%) rename Mail/Components/{ => ThreadCell}/ThreadCellHeaderView.swift (100%) rename Mail/Components/{ => ThreadCell}/ThreadCellInfoView.swift (100%) diff --git a/Mail/Components/ThreadCell.swift b/Mail/Components/ThreadCell/ThreadCell.swift similarity index 81% rename from Mail/Components/ThreadCell.swift rename to Mail/Components/ThreadCell/ThreadCell.swift index bc9854279..6a4b85e8e 100644 --- a/Mail/Components/ThreadCell.swift +++ b/Mail/Components/ThreadCell/ThreadCell.swift @@ -147,29 +147,15 @@ struct ThreadCell: View { .accessibilityLabel(additionalAccessibilityLabel) .accessibilityHidden(additionalAccessibilityLabel.isEmpty) - Group { - if density == .large { - ZStack { - AvatarView( - mailboxManager: mailboxManager, - contactConfiguration: dataHolder.contactConfiguration(contextMailboxManager: mailboxManager), - size: 40 - ) - .opacity(isSelected ? 0 : 1) - .onTapGesture { - avatarTapped?() - } - CheckboxView(isSelected: isSelected, density: density, accentColor: accentColor) - .opacity(isSelected ? 1 : 0) - } - .accessibility(hidden: true) - .animation(nil, value: isSelected) - } else if isMultipleSelectionEnabled { - CheckboxView(isSelected: isSelected, density: density, accentColor: accentColor) - .opacity(shouldDisplayCheckbox ? 1 : 0) - .animation(.default.speed(1.5), value: shouldDisplayCheckbox) - } - } + ThreadCellCheckboxView( + accentColor: accentColor, + density: density, + isSelected: isSelected, + isMultipleSelectionEnabled: isMultipleSelectionEnabled, + shouldDisplayCheckbox: shouldDisplayCheckbox, + contactConfiguration: dataHolder.contactConfiguration(contextMailboxManager: mailboxManager), + avatarTapped: avatarTapped + ) .padding(.trailing, value: .verySmall) VStack(alignment: .leading, spacing: UIPadding.verySmall) { @@ -198,18 +184,20 @@ struct ThreadCell: View { .padding(.vertical, density.cellVerticalPadding) .clipped() .accessibilityElement(children: .combine) - .onChange(of: isMultipleSelectionEnabled) { isEnabled in - guard density != .large else { return } - - withAnimation { - if isEnabled { - // We should wait a bit before showing the checkbox - DispatchQueue.main.asyncAfter(deadline: .now() + UIConstants.checkboxAppearDelay) { - shouldDisplayCheckbox = true - } - } else { - shouldDisplayCheckbox = false + .onChange(of: isMultipleSelectionEnabled, perform: animateCheckbox) + } + + private func animateCheckbox(_ isEnabled: Bool) { + guard density != .large else { return } + + withAnimation { + if isEnabled { + // We should wait a bit before showing the checkbox + DispatchQueue.main.asyncAfter(deadline: .now() + UIConstants.checkboxAppearDelay) { + shouldDisplayCheckbox = true } + } else { + shouldDisplayCheckbox = false } } } diff --git a/Mail/Components/ThreadCell/ThreadCellCheckboxView.swift b/Mail/Components/ThreadCell/ThreadCellCheckboxView.swift new file mode 100644 index 000000000..c3a19808f --- /dev/null +++ b/Mail/Components/ThreadCell/ThreadCellCheckboxView.swift @@ -0,0 +1,66 @@ +/* + Infomaniak Mail - iOS App + Copyright (C) 2022 Infomaniak Network SA + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + */ + +import MailCore +import SwiftUI + +struct ThreadCellCheckboxView: View { + @EnvironmentObject private var mailboxManager: MailboxManager + + let accentColor: AccentColor + let density: ThreadDensity + let isSelected: Bool + let isMultipleSelectionEnabled: Bool + let shouldDisplayCheckbox: Bool + let contactConfiguration: ContactConfiguration + let avatarTapped: (() -> Void)? + + var body: some View { + Group { + if density == .large { + ZStack { + AvatarView(mailboxManager: mailboxManager, contactConfiguration: contactConfiguration, size: 40) + .opacity(isSelected ? 0 : 1) + .onTapGesture { + avatarTapped?() + } + CheckboxView(isSelected: isSelected, density: density, accentColor: accentColor) + .opacity(isSelected ? 1 : 0) + } + .accessibility(hidden: true) + .animation(nil, value: isSelected) + } else if isMultipleSelectionEnabled { + CheckboxView(isSelected: isSelected, density: density, accentColor: accentColor) + .opacity(shouldDisplayCheckbox ? 1 : 0) + .animation(.default.speed(1.5), value: shouldDisplayCheckbox) + } + } + } +} + +#Preview { + ThreadCellCheckboxView( + accentColor: .pink, + density: .large, + isSelected: false, + isMultipleSelectionEnabled: false, + shouldDisplayCheckbox: true, + contactConfiguration: .emptyContact, + avatarTapped: nil + ) +} diff --git a/Mail/Components/ThreadCellDetailsView.swift b/Mail/Components/ThreadCell/ThreadCellDetailsView.swift similarity index 100% rename from Mail/Components/ThreadCellDetailsView.swift rename to Mail/Components/ThreadCell/ThreadCellDetailsView.swift diff --git a/Mail/Components/ThreadCellHeaderView.swift b/Mail/Components/ThreadCell/ThreadCellHeaderView.swift similarity index 100% rename from Mail/Components/ThreadCellHeaderView.swift rename to Mail/Components/ThreadCell/ThreadCellHeaderView.swift diff --git a/Mail/Components/ThreadCellInfoView.swift b/Mail/Components/ThreadCell/ThreadCellInfoView.swift similarity index 100% rename from Mail/Components/ThreadCellInfoView.swift rename to Mail/Components/ThreadCell/ThreadCellInfoView.swift From 4f6176aaf978336b202405bd4533c8d480139a90 Mon Sep 17 00:00:00 2001 From: Valentin Perignon Date: Wed, 31 Jan 2024 14:48:15 +0100 Subject: [PATCH 2/2] fix: Recipient names fill the available space --- Mail/Components/ThreadCell/ThreadCell.swift | 2 +- ...ift => ThreadCellAvatarCheckboxView.swift} | 4 +-- .../ThreadCell/ThreadCellHeaderView.swift | 29 ++++++++++--------- 3 files changed, 19 insertions(+), 16 deletions(-) rename Mail/Components/ThreadCell/{ThreadCellCheckboxView.swift => ThreadCellAvatarCheckboxView.swift} (96%) diff --git a/Mail/Components/ThreadCell/ThreadCell.swift b/Mail/Components/ThreadCell/ThreadCell.swift index 6a4b85e8e..30314bd9e 100644 --- a/Mail/Components/ThreadCell/ThreadCell.swift +++ b/Mail/Components/ThreadCell/ThreadCell.swift @@ -147,7 +147,7 @@ struct ThreadCell: View { .accessibilityLabel(additionalAccessibilityLabel) .accessibilityHidden(additionalAccessibilityLabel.isEmpty) - ThreadCellCheckboxView( + ThreadCellAvatarCheckboxView( accentColor: accentColor, density: density, isSelected: isSelected, diff --git a/Mail/Components/ThreadCell/ThreadCellCheckboxView.swift b/Mail/Components/ThreadCell/ThreadCellAvatarCheckboxView.swift similarity index 96% rename from Mail/Components/ThreadCell/ThreadCellCheckboxView.swift rename to Mail/Components/ThreadCell/ThreadCellAvatarCheckboxView.swift index c3a19808f..75ebc61d0 100644 --- a/Mail/Components/ThreadCell/ThreadCellCheckboxView.swift +++ b/Mail/Components/ThreadCell/ThreadCellAvatarCheckboxView.swift @@ -19,7 +19,7 @@ import MailCore import SwiftUI -struct ThreadCellCheckboxView: View { +struct ThreadCellAvatarCheckboxView: View { @EnvironmentObject private var mailboxManager: MailboxManager let accentColor: AccentColor @@ -54,7 +54,7 @@ struct ThreadCellCheckboxView: View { } #Preview { - ThreadCellCheckboxView( + ThreadCellAvatarCheckboxView( accentColor: .pink, density: .large, isSelected: false, diff --git a/Mail/Components/ThreadCell/ThreadCellHeaderView.swift b/Mail/Components/ThreadCell/ThreadCellHeaderView.swift index fc3925451..eb6dbe69b 100644 --- a/Mail/Components/ThreadCell/ThreadCellHeaderView.swift +++ b/Mail/Components/ThreadCell/ThreadCellHeaderView.swift @@ -29,26 +29,29 @@ struct ThreadCellHeaderView: View, Equatable { var body: some View { HStack(spacing: UIPadding.small) { - if showDraftPrefix { - Text("\(MailResourcesStrings.Localizable.draftPrefix)") - .textStyle(.bodyMediumError) + HStack(spacing: UIPadding.small) { + if showDraftPrefix { + Text("\(MailResourcesStrings.Localizable.draftPrefix)") + .textStyle(.bodyMediumError) + .lineLimit(1) + .layoutPriority(1) + } + + Text(recipientsTitle) + .textStyle(.bodyMedium) .lineLimit(1) - .layoutPriority(1) - } - - Text(recipientsTitle) - .textStyle(.bodyMedium) - .lineLimit(1) - if messageCount > 1 { - ThreadCountIndicatorView(messagesCount: messageCount, hasUnseenMessages: prominentMessageCount) - .accessibilityHidden(true) + if messageCount > 1 { + ThreadCountIndicatorView(messagesCount: messageCount, hasUnseenMessages: prominentMessageCount) + .accessibilityHidden(true) + } } + .frame(maxWidth: .infinity, alignment: .leading) Text(formattedDate) .textStyle(.bodySmallSecondary) .lineLimit(1) - .frame(maxWidth: .infinity, alignment: .trailing) + .layoutPriority(1) .accessibilityHidden(true) } }