Webhost: Allow Option Groups to specify whether they start collapsed (#3370)

* allow option groups to specify whether they should be hidden or not

* allow worlds to override whether game options starts collapsed

* remove Game Options assert so the visibility of that group can be changed

* if "Game Options" or "Item & Location Options" groups are specified, fix casing

* don't allow item & location options to have duplicates of the auto added options

* use a generator instead of a comprehension

* use consistent naming
This commit is contained in:
Aaron Wagener 2024-05-24 00:18:21 -05:00 committed by GitHub
parent 613e76689e
commit 8045c8717c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 18 additions and 4 deletions

View File

@ -1130,6 +1130,8 @@ class OptionGroup(typing.NamedTuple):
"""Name of the group to categorize these options in for display on the WebHost and in generated YAMLS.""" """Name of the group to categorize these options in for display on the WebHost and in generated YAMLS."""
options: typing.List[typing.Type[Option[typing.Any]]] options: typing.List[typing.Type[Option[typing.Any]]]
"""Options to be in the defined group.""" """Options to be in the defined group."""
start_collapsed: bool = False
"""Whether the group will start collapsed on the WebHost options pages."""
item_and_loc_options = [LocalItems, NonLocalItems, StartInventory, StartInventoryPool, StartHints, item_and_loc_options = [LocalItems, NonLocalItems, StartInventory, StartInventoryPool, StartHints,

View File

@ -32,11 +32,16 @@ def render_options_page(template: str, world_name: str, is_complex: bool = False
return redirect("games") return redirect("games")
visibility_flag = Options.Visibility.complex_ui if is_complex else Options.Visibility.simple_ui visibility_flag = Options.Visibility.complex_ui if is_complex else Options.Visibility.simple_ui
start_collapsed = {"Game Options": False}
for group in world.web.option_groups:
start_collapsed[group.name] = group.start_collapsed
return render_template( return render_template(
template, template,
world_name=world_name, world_name=world_name,
world=world, world=world,
option_groups=Options.get_option_groups(world, visibility_level=visibility_flag), option_groups=Options.get_option_groups(world, visibility_level=visibility_flag),
start_collapsed=start_collapsed,
issubclass=issubclass, issubclass=issubclass,
Options=Options, Options=Options,
theme=get_world_theme(world_name), theme=get_world_theme(world_name),

View File

@ -69,7 +69,7 @@
<div id="option-groups"> <div id="option-groups">
{% for group_name, group_options in option_groups.items() %} {% for group_name, group_options in option_groups.items() %}
<details class="group-container" {% if loop.index == 1 %}open{% endif %}> <details class="group-container" {% if not start_collapsed[group_name] %}open{% endif %}>
<summary class="h2">{{ group_name }}</summary> <summary class="h2">{{ group_name }}</summary>
<div class="game-options"> <div class="game-options">
<div class="left"> <div class="left">

View File

@ -51,7 +51,7 @@
<div id="{{ world_name }}-container"> <div id="{{ world_name }}-container">
{% for group_name, group_options in option_groups.items() %} {% for group_name, group_options in option_groups.items() %}
<details {% if loop.index == 1 %}open{% endif %}> <details {% if not start_collapsed[group_name] %}open{% endif %}>
<summary class="h2">{{ group_name }}</summary> <summary class="h2">{{ group_name }}</summary>
{% for option_name, option in group_options.items() %} {% for option_name, option in group_options.items() %}
<div class="option-wrapper"> <div class="option-wrapper">

View File

@ -116,12 +116,19 @@ class WebWorldRegister(type):
# don't allow an option to appear in multiple groups, allow "Item & Location Options" to appear anywhere by the # don't allow an option to appear in multiple groups, allow "Item & Location Options" to appear anywhere by the
# dev, putting it at the end if they don't define options in it # dev, putting it at the end if they don't define options in it
option_groups: List[OptionGroup] = dct.get("option_groups", []) option_groups: List[OptionGroup] = dct.get("option_groups", [])
prebuilt_options = ["Game Options", "Item & Location Options"]
seen_options = [] seen_options = []
item_group_in_list = False item_group_in_list = False
for group in option_groups: for group in option_groups:
assert group.name != "Game Options", "Game Options is a pre-determined group and can not be defined."
assert group.options, "A custom defined Option Group must contain at least one Option." assert group.options, "A custom defined Option Group must contain at least one Option."
# catch incorrectly titled versions of the prebuilt groups so they don't create extra groups
title_name = group.name.title()
if title_name in prebuilt_options:
group.name = title_name
if group.name == "Item & Location Options": if group.name == "Item & Location Options":
assert not any(option in item_and_loc_options for option in group.options), \
f"Item and Location Options cannot be specified multiple times"
group.options.extend(item_and_loc_options) group.options.extend(item_and_loc_options)
item_group_in_list = True item_group_in_list = True
else: else:
@ -133,7 +140,7 @@ class WebWorldRegister(type):
assert option not in seen_options, f"{option} found in two option groups" assert option not in seen_options, f"{option} found in two option groups"
seen_options.append(option) seen_options.append(option)
if not item_group_in_list: if not item_group_in_list:
option_groups.append(OptionGroup("Item & Location Options", item_and_loc_options)) option_groups.append(OptionGroup("Item & Location Options", item_and_loc_options, True))
return super().__new__(mcs, name, bases, dct) return super().__new__(mcs, name, bases, dct)