{# =================================================================== Start Page controls — used twice, with two different scopes: scope="user" what I see -> /api/user/preferences scope="global" what a new account sees by default -> PUT /api/settings (admin) Both render the same objects, so learning one teaches the other. The ids carry the scope so the settings page can show both at once, and static/start_page.js drives them from the same code path. Each scope is ONE card. Rows, cards-per-row and the filters are facets of a single decision ("what does this home page look like"), not three unrelated settings -- rendering them as three separate cards made the page read as six independent things and buried the fact that the whole lower half is just the same form again for a different audience. The row labels/hints are rendered here (through Flask-Babel) and read by the JS from window.__STARTPAGE_I18N -- the row list itself is built client-side from /api/home-feed/sources, because which sources exist depends on which modules are installed. =================================================================== #} {# NB: never put a Jinja comment INSIDE the dict expression below -- one inside a {{ ... }} expression is a syntax error that takes the whole page down (and Jinja comments do not nest, so this one cannot show you the token either). "column_n" carries the column number as %(n)s filled with a literal brace pair here, because Flask-Babel's newstyle gettext turns a bare "%s" into that same brace pair in the rendered catalogue string, and it is what static/start_page.js replaces at runtime. #} {% macro start_page_i18n() %} {% endmacro %} {# heading/intro are optional: the settings page passes them so the card carries its own title, the home page modal leaves them empty because the modal already has a title of its own. #} {% macro start_page_form(scope, show_new_home_toggle=False, heading='', intro='') %}
{% if heading %}

{{ heading }}

{% if intro %}
{{ intro }}
{% endif %} {% endif %} {# Layout comes first: it decides which home page the rows underneath are rendered into at all, so the card reads from the biggest decision to the smallest. #} {% if show_new_home_toggle %}

{{ _('Layout') }}

{{ _('Groups the discovery rows by question instead of by source: "New this week" and "Popular right now" mix every enabled source and each poster names where it came from. The classic layout keeps one block per source with its own rows. Reload the home page after changing this.') }}
{{ _('This is the default for accounts that have not picked a layout themselves — everyone can overrule it on their profile page.') }}
{# The instance-wide twin of the per-account "Home tabs" group further down (scope="user") -- what a fresh account, or one that never opened "Customise this page" itself, starts with. Same values, same select; only the storage differs (PUT /api/settings, not the per-account preferences endpoint), so it gets its own ids and its own handlers in static/settings.js rather than reusing static/start_page.js's per-scope bind()/load(), which is wired to window._USER_PREFS. #}

{{ _('Home tabs') }}

{{ _('The default arrangement for accounts that have not chosen one themselves. Everyone can still overrule it on their profile page.') }}

{{ _('Start on') }}

{# Instance-wide twin of the per-account "Recommendations" group further down (scope="user") -- what a fresh account, or one that never touched these two checkboxes, starts with. See db/ui_prefs.py's foryou_hero_hidden/foryou_hidden and static/home_foryou.js's heroHidden()/railHidden() for how the two are resolved together. #}

{{ _('Recommendations') }}

{{ _('The default for accounts that have not chosen for themselves. Everyone can still overrule it on their profile page.') }}
{% endif %} {# The same decision for THIS account. A select and not a checkbox, because "follow whatever the admin set" is a real third state and a checkbox cannot say it: switching to the new layout and switching back are two different things, and only one of them should keep following the instance default afterwards. #} {% if scope == 'user' %}

{{ _('Layout') }}

{{ _('Which home page you see. Only you — nobody else on this instance is affected.') }}
{# Only meaningful on the new (two-tab) layout, but shown regardless of which layout this account currently has -- switching to the new layout above does not reload this modal, and the choice should already be there once it does. Same reasoning as the Layout select above: per account, nobody else on the instance is affected. #}

{{ _('Home tabs') }}

{{ _('Tabs switch between the two; "All in one page" stacks the Dashboard above Discover instead, with no switching.') }}
{# Only worth asking while there are two SEPARATE tabs to pick a first one from -- "Discover only" has no Dashboard tab, "All in one page" has no tab switch either (both sections are simply stacked). This whole block hides itself for both (see syncStartTabRow() in static/start_page.js). #}

{{ _('Start on') }}

{# Hidden by syncOrderRows() in static/start_page.js whenever there is no Dashboard to arrange ("Discover only" / "All in one page"). Both rows are scope="user" only: this is a per-account arrangement, there is no instance default to arrange for a fresh account. #}

{{ _('Dashboard columns') }}

{{ _('How many columns the Dashboard is split into on a wide screen. A narrow window falls back to fewer on its own; on a phone the cards stack in one column, first column first. Reload the home page after changing this.') }}

{{ _('Card order') }}

{{ _('Which column each card sits in, and in which order. Dragging a card on the Dashboard itself writes the same setting.') }}
{# "Could be for you" -- the recommendation hero + rail on the Discover tab. Personal, same as every other Discover choice: one household member finding the guesses noisy must not turn them off for everyone else. static/home_foryou.js reads this pref before every load and static/start_page.js's spForyouHidden handler below applies a toggle immediately, without asking for a reload -- the row has no state of its own to lose by hiding and showing it again. #}

{{ _('Recommendations') }}

{% endif %}

{{ _('Rows') }}

{% if scope == 'user' %} {{ _('Which rows your home page shows, and in which order. Switch one off and MediaForge stops collecting its data as well.') }} {% else %} {{ _('The order and visibility a new account starts with. Every user can overrule this for themselves.') }} {% endif %}
{% if scope == 'user' %}
{% endif %}

{{ _('Cards per row') }}

{{ _('How many cards a discovery row holds at most. Fewer cards means less to fetch and a shorter page.') }}
{# The Jellyfin/Plex profile picker used to sit here, in the user scope. It moved to /profile (templates/profile.html), which is where the account's own settings belong -- it only landed in this modal because /settings is admin-only and there was nowhere else a normal account could reach. #} {% if scope == 'global' %}

{{ _('Default filters') }}

{{ _('Which chips are off when someone opens the home page for the first time. This is a starting point, not a restriction — every user can switch them back on. To take a source away entirely, disable it under Sources.') }}
{# One level below .settings-subtitle: these two only label the check grids inside the "Default filters" group, so they must not compete with the group headings themselves. #}
{{ _('Sources') }}
{{ _('Type') }}
{# Kids mode is armed HERE, not on the home page. Instance-wide because it is an instance decision: a per-account PIN would be set by the very account it is supposed to restrict. The button only appears on the home page once this is on AND a PIN exists -- both, because a mode nobody can leave would lock the account out of its own home page. #}

{{ _('Kids mode') }}

{{ _('Adds a “Kids” button to the home page that limits it to an age rating. The limit is applied on the server while the rows are built, so it cannot be bypassed from the browser. Leaving the mode asks for the PIN; entering it never does.') }}
{# .chb-main goes on the INPUT and .settings-checkbox-row on the label -- that is the pattern every other checkbox in this app uses. Putting chb-main on the
{% endif %}
{% endmacro %}