mirror of
https://github.com/SeedSigner/seedsigner.git
synced 2026-10-05 15:08:25 +00:00
UX changes to require a selection for multiselect settings
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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),
|
||||
])
|
||||
|
||||
Reference in New Issue
Block a user