UX changes to require a selection for multiselect settings

This commit is contained in:
kdmukai
2026-01-20 06:34:59 -06:00
parent 01cb2cc796
commit 6e25e3f94b
3 changed files with 62 additions and 5 deletions
+38
View File
@@ -204,6 +204,13 @@ class SettingsEntryUpdateSelectionView(View):
)
if ret_value == RET_CODE__BACK_BUTTON:
if self.settings_entry.type == SettingsConstants.TYPE__MULTISELECT:
# After the user finishes toggling multiselect options, initial_value will
# have their final selections when they hit BACK to exit. All current
# multiselect settings require at least one option to be selected.
if not initial_value:
return Destination(SettingsSelectionRequiredWarningView, view_args={"attr_name": self.settings_entry.attr_name})
if self.blocking_view:
return Destination(self.blocking_view, clear_history=True)
return settings_menu_view_destination
@@ -261,6 +268,37 @@ class SettingsEntryUpdateSelectionView(View):
class SettingsSelectionRequiredWarningView(View):
def __init__(self, attr_name: str):
super().__init__()
self.settings_entry = SettingsDefinition.get_settings_entry(attr_name)
def run(self):
from seedsigner.gui.screens.screen import WarningScreen
# TRANSLATOR_NOTE: Title of a warning dialog when configuring a setting that requires at least one option to be selected.
title = _("Selection Required")
# TRANSLATOR_NOTE: The name of the setting being configured (e.g. "Script types") will be inserted.
text = _("At least one option must be selected for \"{}\".").format(self.settings_entry.display_name)
# TRANSLATOR_NOTE: Text for the button that returns the user to the setting configuration screen.
button_text = _("Return to setting")
self.run_screen(
WarningScreen,
title=title,
status_headline=None,
text=text,
button_data=[ButtonOption(button_text)],
show_back_button=False,
)
return Destination(SettingsEntryUpdateSelectionView, view_args=dict(attr_name=self.settings_entry.attr_name))
class SettingsIngestSettingsQRView(View):
def __init__(self, data: str):
from seedsigner.hardware.microsd import MicroSD
+1
View File
@@ -427,6 +427,7 @@ def generate_screenshots(locale):
ScreenshotConfig(settings_views.DonateView),
ScreenshotConfig(settings_views.SettingsIngestSettingsQRView, dict(data=settingsqr_data_persistent), screenshot_name="SettingsIngestSettingsQRView_persistent"),
ScreenshotConfig(settings_views.SettingsIngestSettingsQRView, dict(data=settingsqr_data_not_persistent), screenshot_name="SettingsIngestSettingsQRView_not_persistent"),
ScreenshotConfig(settings_views.SettingsSelectionRequiredWarningView, dict(attr_name=SettingsConstants.SETTING__SCRIPT_TYPES)),
],
"Misc Error Views": [
ScreenshotConfig(NotYetImplementedView),
+23 -5
View File
@@ -37,17 +37,35 @@ class TestSettingsFlows(FlowTest):
def test_multiselect(self):
""" Multiselect Settings options should stay in-place; requires BACK to exit. """
"""
Multiselect Settings options should stay in-place; requires BACK to exit. If no
selections are made, route to the warning screen and return the user to the
settings entry until at least one option is selected.
"""
# Which option are we testing?
settings_entry = SettingsDefinition.get_settings_entry(SettingsConstants.SETTING__XPUB_QR_FORMAT)
settings_entry = SettingsDefinition.get_settings_entry(SettingsConstants.SETTING__SIG_TYPES)
# Enable all options to start
self.settings.set_value(settings_entry.attr_name, [option[0] for option in settings_entry.selection_options])
# Sanity check, we only expect two options for this setting
assert len(settings_entry.selection_options) == 2
self.run_sequence([
FlowStep(MainMenuView, button_data_selection=MainMenuView.SETTINGS),
FlowStep(settings_views.SettingsMenuView, button_data_selection=settings_views.SettingsMenuView.ADVANCED),
FlowStep(settings_views.SettingsMenuView, button_data_selection=ButtonOption(settings_entry.display_name)),
FlowStep(settings_views.SettingsEntryUpdateSelectionView, screen_return_value=0), # select/deselect first option
FlowStep(settings_views.SettingsEntryUpdateSelectionView, screen_return_value=1), # select/deselect second option
FlowStep(settings_views.SettingsEntryUpdateSelectionView, screen_return_value=1), # select/deselect second option
FlowStep(settings_views.SettingsEntryUpdateSelectionView, screen_return_value=0), # deselect first option
FlowStep(settings_views.SettingsEntryUpdateSelectionView, screen_return_value=1), # deselect second option
FlowStep(settings_views.SettingsEntryUpdateSelectionView, screen_return_value=1), # select second option
FlowStep(settings_views.SettingsEntryUpdateSelectionView, screen_return_value=1), # deselect second option
FlowStep(settings_views.SettingsEntryUpdateSelectionView, screen_return_value=RET_CODE__BACK_BUTTON), # BACK to exit
# Both options were deselected, should route to the warning screen
FlowStep(settings_views.SettingsSelectionRequiredWarningView),
FlowStep(settings_views.SettingsEntryUpdateSelectionView, screen_return_value=0), # select first option
# Now we can exit
FlowStep(settings_views.SettingsEntryUpdateSelectionView, screen_return_value=RET_CODE__BACK_BUTTON), # BACK to exit
FlowStep(settings_views.SettingsMenuView),
])