refactor: Implement trailing content management for schedule options and bottom sheets - #2990
refactor: Implement trailing content management for schedule options and bottom sheets#2990Elouan1411 wants to merge 6 commits into
Conversation
90ceb0e to
b20f175
Compare
There was a problem hiding this comment.
Pull request overview
Refactors trailing-content handling across schedule options, settings rows, and bottom sheets.
Changes:
- Extracts shared KSuite chip and trailing-content management.
- Adds plan-specific chips to custom scheduling and reminder options.
- Updates last-schedule-option visibility handling.
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
DraftSendOptionsFragment.kt |
Integrates trailing content and custom reminder handling. |
MailActionsBottomSheetDialog.kt |
Updates the extracted trailing-content import. |
KSuiteChipManager.kt |
Adds reusable chip management and trailing-content types. |
ActionItemView.kt |
Delegates chip rendering to the shared manager. |
ItemSettingView.kt |
Supports chips and chevrons as trailing content. |
SimpleSchedulePickerBottomSheet.kt |
Configures plan-specific custom-option content. |
ScheduleOptionsHelper.kt |
Coordinates trailing content and option visibility. |
Comments suppressed due to low confidence (1)
app/src/main/java/com/infomaniak/mail/ui/newMessage/sendOptions/DraftSendOptionsFragment.kt:271
onViewCreated()calls this withfalseimmediately afterScheduleOptionsHelpercomputes whether the last option is eligible. That sets the child toGONE; a later call withtruethen evaluatestrue && false, so the last schedule option can never reappear. Hide only the wrapper and preserve the child's helper-computed visibility.
lastScheduleOption.isVisible = isVisible && lastScheduleOption.isVisible
b20f175 to
10a817b
Compare
d7c3db2 to
6083e12
Compare
| (firstItem as? ActionItemView)?.setDividerVisibility(shouldDisplayDivider) | ||
| } | ||
|
|
||
| protected open fun setupCustomScheduleOptionTrailing(kSuite: KSuite?) { |
There was a problem hiding this comment.
Why did you put that as protected open?
There was a problem hiding this comment.
Also you don't need the kSuite parameter as you can directly use currentKSuite
There was a problem hiding this comment.
Why did you put that as
protected open?
I forgot to remove it, it's no longer useful
| chevron.isGone = mustBlock | ||
| } | ||
|
|
||
| fun setMyKSuiteChipVisibility(isVisible: Boolean) { |
|
|
||
| private fun setTrailingContentUi(trailingContent: TrailingContent) = with(binding) { | ||
| val hasChip = kSuiteChipManager.displayChipFor(trailingContent) | ||
| trailingChipContainer.isVisible = hasChip |
There was a problem hiding this comment.
No need to create a hasCip variable here as you only use it here.
| import com.infomaniak.core.ksuite.ksuitepro.views.EvolveChipView | ||
| import com.infomaniak.core.ksuite.myksuite.ui.views.MyKSuitePlusChipView | ||
|
|
||
| class KSuiteChipManager(private val container: ViewGroup) { |
There was a problem hiding this comment.
Don't pass a view like that as a val. It could leak. If you want the context, you could just pass it as a parameter:
class KSuiteChipManager(context: Context) {
private val kSuitePersoChipView : BaseMyKSuiteChipView = MyKSuitePlusChipView(context)
private val kSuiteProChipView : EvolveChipView = EvolveChipView(context)
fun displayChipFor(container: ViewGroup, trailingContent: TrailingContent): Boolean {
...and the by lazy is not necessary as you always use those variables.
| (firstItem as? ActionItemView)?.setDividerVisibility(shouldDisplayDivider) | ||
| } | ||
|
|
||
| protected open fun setupCustomScheduleOptionTrailing(kSuite: KSuite?) { |
There was a problem hiding this comment.
Also you don't need the kSuite parameter as you can directly use currentKSuite
| binding.customScheduleOption.trailingContent = when (kSuite) { | ||
| KSuite.Perso.Free -> TrailingContent.KSuitePersoChip | ||
| KSuite.Pro.Free, KSuite.StarterPack -> TrailingContent.KSuiteProChip | ||
| else -> TrailingContent.Chevron | ||
| } | ||
| } |
There was a problem hiding this comment.
This could probably by factorized by a View extension function
| fun displayChipFor(trailingContent: TrailingContent): Boolean { | ||
| container.removeView(kSuitePersoChipView) | ||
| container.removeView(kSuiteProChipView) | ||
|
|
||
| return when (trailingContent) { | ||
| // ComposeView are not compatible with view without lifecycles (ex: PopupWindow in RecipientFieldView). | ||
| // This is causing a crash so to avoid that, we have to programmatically | ||
| // add the Compose view only where it's needed. | ||
| TrailingContent.KSuitePersoChip -> container.addView(kSuitePersoChipView).let { true } | ||
| TrailingContent.KSuiteProChip -> container.addView(kSuiteProChipView).let { true } | ||
| else -> false | ||
| } | ||
| } | ||
| } |
There was a problem hiding this comment.
Here's my suggestion :
| fun displayChipFor(trailingContent: TrailingContent): Boolean { | |
| container.removeView(kSuitePersoChipView) | |
| container.removeView(kSuiteProChipView) | |
| return when (trailingContent) { | |
| // ComposeView are not compatible with view without lifecycles (ex: PopupWindow in RecipientFieldView). | |
| // This is causing a crash so to avoid that, we have to programmatically | |
| // add the Compose view only where it's needed. | |
| TrailingContent.KSuitePersoChip -> container.addView(kSuitePersoChipView).let { true } | |
| TrailingContent.KSuiteProChip -> container.addView(kSuiteProChipView).let { true } | |
| else -> false | |
| } | |
| } | |
| } | |
| fun displayChipFor(trailingContent: TrailingContent): Boolean { | |
| container.removeView(kSuitePersoChipView) | |
| container.removeView(kSuiteProChipView) | |
| val chipView = when (trailingContent) { | |
| // ComposeView are not compatible with view without lifecycles (ex: PopupWindow in RecipientFieldView). | |
| // This is causing a crash so to avoid that, we have to programmatically | |
| // add the Compose view only where it's needed. | |
| TrailingContent.KSuitePersoChip -> kSuitePersoChipView | |
| TrailingContent.KSuiteProChip -> kSuiteProChipView | |
| else -> null | |
| } | |
| return chipView?.also(container::addView) != null | |
| } |
| } | ||
|
|
||
| /** Keep the entries order, it's used by the attribute (or change also the attributes order in attrs.xml) */ | ||
| enum class TrailingContent { |
There was a problem hiding this comment.
I'm don't think this should be kept in this class because it's not only related to kSuite chips
Or the class should be renamed and used more generally
| private fun onCustomDelayReminderClicked() = | ||
| executeIfAuthorized(MatomoName.ReminderCustomDelta.value) { showCustomDelayReminderDatePicker() } |
There was a problem hiding this comment.
| private fun onCustomDelayReminderClicked() = | |
| executeIfAuthorized(MatomoName.ReminderCustomDelta.value) { showCustomDelayReminderDatePicker() } | |
| private fun onCustomDelayReminderClicked() { | |
| executeIfAuthorized(MatomoName.ReminderCustomDelta.value) { showCustomDelayReminderDatePicker() } | |
| } |
| ScheduleOptionUtils.getAvailableScheduleOptions(currentlyScheduledEpochMillis).forEach { scheduleOption -> | ||
| scheduleOptions.addView(createScheduleOptionItem(scheduleOption)) | ||
| } | ||
|
|
6083e12 to
d73f3f2
Compare
478c028 to
c5058ec
Compare
c5058ec to
b363fbe
Compare
b363fbe to
0e2b679
Compare
0e2b679 to
9e6918b
Compare
41a8670 to
784c3f3
Compare
784c3f3 to
6957590
Compare
…and bottom sheets
6957590 to
78269d4
Compare
|



No description provided.