mirror of
https://github.com/karatektus/pl_mail.git
synced 2026-10-25 10:04:18 +00:00
* feat(mail): replace the history entry when switching category tabs on a phone Below md, a category tab navigates the inbox list frame with Turbo's replace action, so the browser's Back leaves the inbox instead of stepping back through every tab. At md and up the link keeps advance, so desktop behaviour is unchanged. The choice is made on click by the ui--tab-history controller, not on connect: the tab strip is morphed on every list refresh, and a morph removes attributes the server did not render. Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com> * feat(mail): category tabs replace the history entry at every width #150 asked for this on a phone only; the maintainer wants it everywhere, as Gmail does. With no breakpoint to ask about, the tab links render data-turbo-action="replace" from the server, so the click-time controller goes: a server-rendered attribute survives the strip's morph on its own. The account page's tab strip, added on main since, gets the same. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(changelog): credit the tab history entry to #161, which took over #113 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Flouss <15911342+Flouss@users.noreply.github.com> Co-authored-by: Claude Haiku 5.5 <noreply@anthropic.com>
90 lines
5.0 KiB
Twig
90 lines
5.0 KiB
Twig
{#
|
|
mail/account.html.twig — one account's INBOX.
|
|
|
|
Reached by clicking the account itself in the sidebar. It used to be every
|
|
thread in the account whatever it was labelled, which meant your own sent mail
|
|
interleaved through what had arrived, with drafts and spam among it — an
|
|
archive, where a person clicking their address means "show me what came in".
|
|
Everything else in the account is a folder row one click below it.
|
|
|
|
The heading names the account AND says Inbox, because those two facts together
|
|
are the only thing that distinguishes this screen from the unified inbox above
|
|
it and from the account's other folders beside it.
|
|
#}
|
|
{% extends '_layout/_mailbox.html.twig' %}
|
|
|
|
{% block title %}{{ account.displayAddress }} — {{ 'app.name'|trans }}{% endblock %}
|
|
|
|
{% block inbox_tabs %}
|
|
{% import '_partials/_category_tab_glyphs.html.twig' as glyphs %}
|
|
|
|
<div class="px-4 py-2.5 border-b border-line flex items-center gap-2">
|
|
<h2 class="text-sm font-semibold text-ink-soft">{{ 'sidebar.nav.inbox'|trans }}</h2>
|
|
<span class="text-xs text-ink-faint truncate">{{ account.displayAddress }}</span>
|
|
</div>
|
|
|
|
{# The category tabs, for this account's mail.
|
|
|
|
The same tabs as the unified inbox — the five and the reader's own — and
|
|
chosen by the same rule (MailController::visibleTabs()): one exists while
|
|
it holds mail in THIS account, the one you are on stays. But deliberately
|
|
plainer: an icon and a name. What the unified strip adds is a set of
|
|
counters ("3 new", the sender hint, the unread tint) that are summed
|
|
across EVERY account and rewritten by the sidebar controller from that
|
|
same payload. Drawn here they would describe the wrong mailbox, and be
|
|
overwritten with the wrong numbers after the next sync, so they are not
|
|
drawn; the keys they are patched by are not emitted either. Dragging a
|
|
conversation onto a tab is the unified inbox's, for the same reason: its
|
|
targets are built from that page's counts.
|
|
|
|
Links go to THIS page with `?tab=`, carrying whatever else narrows the
|
|
list and dropping `page`, because page four of Primary is not page four
|
|
of Social. The strip scrolls inside itself rather than squeezing, since
|
|
five tabs are wider than a phone, and ui--scroll-active brings the open
|
|
tab into view the way it does on the unified strip (#53). #}
|
|
{% set tabQuery = app.request.query.all|filter((v, k) => k not in ['tab', 'page']) %}
|
|
|
|
{% if tabs|length > 1 %}
|
|
<div class="border-b border-line px-1">
|
|
<nav class="relative flex text-sm overflow-x-auto overflow-y-hidden pb-px -mb-px [scrollbar-width:none] [&::-webkit-scrollbar]:hidden"
|
|
data-controller="ui--scroll-active">
|
|
{% for tabCase in tabs %}
|
|
{% set isActive = tab is not null and tabCase.value == tab.value %}
|
|
<a
|
|
href="{{ path('app_mail_account', {account: account.id}|merge(tabQuery)|merge({tab: tabCase.value})) }}"
|
|
data-turbo-frame="inbox-list-frame"
|
|
{# `replace`, as on the Inbox's strip: see the note there. #}
|
|
data-turbo-action="replace"
|
|
{% if isActive %}aria-current="page" data-ui--scroll-active-target="current"{% endif %}
|
|
class="flex items-center gap-2.5 px-3 @xl:px-5 py-1.5 min-h-14 font-medium border-b-2 -mb-px transition-colors shrink-0 whitespace-nowrap {{ isActive ? 'text-accent border-accent' : 'text-ink-muted hover:text-gray-700 border-transparent hover:border-gray-300' }}"
|
|
>
|
|
{% if isActive %}
|
|
<svg class="w-5 h-5 shrink-0" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true">
|
|
<path fill-rule="evenodd" clip-rule="evenodd" d="{{ glyphs.solid(tabCase.isCustom ? 'custom' : tabCase.value) }}"/>
|
|
</svg>
|
|
{% else %}
|
|
<svg class="w-5 h-5 shrink-0" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" aria-hidden="true">
|
|
<path stroke-linecap="round" stroke-linejoin="round" d="{{ glyphs.outline(tabCase.isCustom ? 'custom' : tabCase.value) }}"/>
|
|
</svg>
|
|
{% endif %}
|
|
{{ tabCase.isCustom ? tabCase.name : ('tabs.' ~ tabCase.value)|trans }}
|
|
</a>
|
|
{% endfor %}
|
|
</nav>
|
|
</div>
|
|
{% endif %}
|
|
{% endblock %}
|
|
|
|
{% block message_list %}
|
|
{% if threads is empty %}
|
|
<li class="px-4 py-8 text-center text-sm text-ink-faint">
|
|
{{ 'inbox.empty_account'|trans }}
|
|
</li>
|
|
{% else %}
|
|
{% for thread in threads %}
|
|
{# Every row here is the same account, so the dot would say nothing. #}
|
|
{% include '_partials/_thread_row.html.twig' with { thread: thread, unified: false } %}
|
|
{% endfor %}
|
|
{% endif %}
|
|
{% endblock %}
|