Wrapper for Instant Update and Color Change

This commit is contained in:
CooperWang0912 2026-07-23 13:05:16 +08:00
parent c3649e2f88
commit 4d839631a4
1 changed files with 38 additions and 20 deletions

View File

@ -1,4 +1,5 @@
from typing import override
import inspect
from typing import Any, Callable, override
from archinstall.default_profiles.profile import GreeterType
from archinstall.lib.applications.application_menu import ApplicationMenu
@ -50,7 +51,7 @@ class GlobalMenu(AbstractMenu[None]):
self._skip_boot = skip_boot
self._advanced = advanced
self._uefi = SysInfo.has_uefi()
menu_options = self._get_menu_options()
menu_options = self._get_menu_options(wrap_actions=True)
self._item_group = MenuItemGroup(
menu_options,
@ -65,8 +66,8 @@ class GlobalMenu(AbstractMenu[None]):
"""
Returns a rich-formatted status prefix icon depending on item state:
- [] (Green) for configured items
- [!] (Yellow) for missing mandatory or required items
- [] (Dim) for unconfigured optional items
- [!] (Red) for missing mandatory or required items
- [] (Yellow) for unconfigured optional items
"""
if item.read_only or item.key in (SpecialMenuKey.SAVE.value, SpecialMenuKey.INSTALL.value, SpecialMenuKey.ABORT.value):
return ""
@ -79,20 +80,22 @@ class GlobalMenu(AbstractMenu[None]):
)
if is_auth_valid:
return "[bold green][✓][/bold green] "
return "[bold yellow][!][/bold yellow] "
return "[bold red][!][/bold red] "
# Standard mandatory or configured item check
if item.has_value():
return "[bold green][✓][/bold green] "
elif item.mandatory:
return "[bold yellow][!][/bold yellow] "
return "[bold red][!][/bold red] "
else:
return "[dim white][•][/dim white] "
return "[bold yellow][•][/bold yellow] "
def _update_item_labels(self) -> None:
"""
Re-applies translated titles and status prefixes to all active menu items.
"""
new_options = {o.key: o.text for o in self._get_menu_options() if o.key is not None}
raw_options = self._get_menu_options(wrap_actions=False)
new_options = {o.key: o.text for o in raw_options if o.key is not None}
for item in self._item_group.items:
if item.key in new_options:
@ -100,7 +103,26 @@ class GlobalMenu(AbstractMenu[None]):
prefix = self._get_status_prefix(item)
item.text = f"{prefix}{base_title}"
def _get_menu_options(self) -> list[MenuItem]:
def _wrap_action(self, key: str, action: Callable) -> Callable:
async def wrapper(*args, **kwargs) -> Any:
if inspect.iscoroutinefunction(action):
result = await action(*args, **kwargs)
else:
result = action(*args, **kwargs)
if inspect.isawaitable(result):
result = await result
item = self._item_group.find_by_key(key)
if item:
item.value = result
self._update_item_labels()
return result
return wrapper
def _get_menu_options(self, wrap_actions: bool = True) -> list[MenuItem]:
menu_options = [
MenuItem(
text=tr('Archinstall language'),
@ -231,6 +253,11 @@ class GlobalMenu(AbstractMenu[None]):
),
]
if wrap_actions:
for item in menu_options:
if item.key and item.action:
item.action = self._wrap_action(item.key, item.action)
return menu_options
async def _safe_config(self) -> None:
@ -305,12 +332,10 @@ class GlobalMenu(AbstractMenu[None]):
async def _select_applications(self, preset: ApplicationConfiguration | None) -> ApplicationConfiguration | None:
app_config = await ApplicationMenu(preset).show()
self._update_item_labels()
return app_config
async def _select_authentication(self, preset: AuthenticationConfiguration | None) -> AuthenticationConfiguration | None:
auth_config = await AuthenticationMenu(preset).show()
self._update_item_labels()
return auth_config
def _update_lang_text(self) -> None:
@ -322,7 +347,6 @@ class GlobalMenu(AbstractMenu[None]):
async def _locale_selection(self, preset: LocaleConfiguration) -> LocaleConfiguration | None:
locale_config = await LocaleMenu(preset).show()
self._update_item_labels()
return locale_config
def _prev_locale(self, item: MenuItem) -> str | None:
@ -457,9 +481,7 @@ class GlobalMenu(AbstractMenu[None]):
return None
async def _pacman_configuration(self, preset: PacmanConfiguration) -> PacmanConfiguration | None:
res = await PacmanMenu(preset, advanced=self._advanced).show()
self._update_item_labels()
return res
return await PacmanMenu(preset, advanced=self._advanced).show()
def _prev_pacman_config(self, item: MenuItem) -> str | None:
if not item.value:
@ -600,7 +622,6 @@ class GlobalMenu(AbstractMenu[None]):
preset: DiskLayoutConfiguration | None = None,
) -> DiskLayoutConfiguration | None:
disk_config = await DiskLayoutConfigurationMenu(preset).show()
self._update_item_labels()
return disk_config
async def _select_bootloader_config(
@ -611,14 +632,12 @@ class GlobalMenu(AbstractMenu[None]):
preset = BootloaderConfiguration.get_default(self._uefi, self._skip_boot)
bootloader_config = await BootloaderMenu(preset, self._uefi, self._skip_boot).show()
self._update_item_labels()
return bootloader_config
async def _select_profile(self, current_profile: ProfileConfiguration | None) -> ProfileConfiguration | None:
from archinstall.lib.profile.profile_menu import ProfileMenu
profile_config = await ProfileMenu(preset=current_profile).show()
self._update_item_labels()
return profile_config
async def _select_additional_packages(self, preset: list[str]) -> list[str]:
@ -632,7 +651,7 @@ class GlobalMenu(AbstractMenu[None]):
preset,
repositories=repositories,
)
self._update_item_labels()
return packages
async def _mirror_configuration(self, preset: MirrorConfiguration | None = None) -> MirrorConfiguration | None:
@ -650,7 +669,6 @@ class GlobalMenu(AbstractMenu[None]):
pacman_config.enable(mirror_configuration.optional_repositories)
pacman_config.apply()
self._update_item_labels()
return mirror_configuration
def _prev_mirror_config(self, item: MenuItem) -> str | None: