calendar: keep zoom ladder inside month blocks on single scene
This commit is contained in:
@@ -5199,151 +5199,147 @@ async function decideFeedCard(card: FeedCard, decision: "accepted" | "rejected")
|
||||
:style="calendarSceneTransformStyle"
|
||||
@mouseleave="calendarHoveredMonthIndex = null; calendarHoveredWeekStartKey = ''; calendarHoveredDayKey = ''; clearCalendarZoomPrime()"
|
||||
>
|
||||
<div v-if="calendarView === 'month'" class="space-y-1">
|
||||
<div class="grid grid-cols-7 gap-1 text-center text-xs font-semibold text-base-content/60">
|
||||
<span>Sun</span>
|
||||
<span>Mon</span>
|
||||
<span>Tue</span>
|
||||
<span>Wed</span>
|
||||
<span>Thu</span>
|
||||
<span>Fri</span>
|
||||
<span>Sat</span>
|
||||
</div>
|
||||
|
||||
<div class="space-y-1">
|
||||
<div
|
||||
v-for="row in monthRows"
|
||||
:key="row.key"
|
||||
class="group relative calendar-hover-targetable"
|
||||
:class="[
|
||||
calendarHoveredWeekStartKey === row.startKey ? 'calendar-hover-target' : '',
|
||||
calendarZoomPrimeToken === calendarPrimeWeekToken(row.startKey) ? 'calendar-zoom-prime-active' : '',
|
||||
]"
|
||||
:style="calendarPrimeStyle(calendarPrimeWeekToken(row.startKey))"
|
||||
:data-calendar-week-start-key="row.startKey"
|
||||
@mouseenter="calendarHoveredWeekStartKey = row.startKey"
|
||||
>
|
||||
<div class="grid grid-cols-7 gap-1">
|
||||
<button
|
||||
v-for="cell in row.cells"
|
||||
:key="cell.key"
|
||||
class="group relative min-h-24 rounded-lg border p-1 text-left"
|
||||
:class="[
|
||||
cell.inMonth ? 'border-base-300 bg-base-100' : 'border-base-200 bg-base-200/40 text-base-content/40',
|
||||
selectedDateKey === cell.key ? 'border-primary bg-primary/5' : '',
|
||||
monthCellHasFocusedEvent(cell.events) ? 'border-success/60 bg-success/10' : '',
|
||||
]"
|
||||
:data-calendar-day-key="cell.key"
|
||||
@mouseenter="calendarHoveredDayKey = cell.key"
|
||||
@click="pickDate(cell.key)"
|
||||
>
|
||||
<p class="mb-1 text-xs font-semibold">{{ cell.day }}</p>
|
||||
<button
|
||||
v-for="event in monthCellEvents(cell.events)"
|
||||
:key="event.id"
|
||||
class="block w-full truncate rounded px-1 text-left text-[10px] text-base-content/70 transition hover:underline"
|
||||
:class="isReviewHighlightedEvent(event.id) ? 'bg-success/20 text-success-content ring-1 ring-success/40' : ''"
|
||||
@click.stop="openThreadFromCalendarItem(event)"
|
||||
>
|
||||
{{ formatTime(event.start) }} {{ event.title }}
|
||||
</button>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-else-if="calendarView === 'week'" class="calendar-week-scroll overflow-x-auto pb-1">
|
||||
<div class="calendar-week-grid">
|
||||
<article
|
||||
v-for="day in weekDays"
|
||||
:key="day.key"
|
||||
class="group relative flex min-h-[18rem] flex-col rounded-xl border border-base-300 bg-base-100 p-2.5 cursor-zoom-in calendar-hover-targetable"
|
||||
<div class="grid gap-2" :class="calendarView === 'year' ? 'sm:grid-cols-2 xl:grid-cols-3' : 'grid-cols-1'">
|
||||
<article
|
||||
v-for="item in yearMonths"
|
||||
:key="`year-month-${item.monthIndex}`"
|
||||
v-show="calendarView === 'year' || item.monthIndex === calendarCursor.getMonth()"
|
||||
class="group relative rounded-xl border border-base-300 p-3 text-left transition calendar-hover-targetable"
|
||||
:class="[
|
||||
selectedDateKey === day.key ? 'border-primary bg-primary/5' : '',
|
||||
calendarHoveredDayKey === day.key ? 'calendar-hover-target' : '',
|
||||
calendarZoomPrimeToken === calendarPrimeDayToken(day.key) ? 'calendar-zoom-prime-active' : '',
|
||||
]"
|
||||
:style="calendarPrimeStyle(calendarPrimeDayToken(day.key))"
|
||||
:data-calendar-day-key="day.key"
|
||||
@mouseenter="calendarHoveredDayKey = day.key"
|
||||
@click="pickDate(day.key)"
|
||||
>
|
||||
<div class="mb-2 flex items-start justify-between gap-2">
|
||||
<p class="text-sm font-semibold leading-tight">{{ day.label }} {{ day.day }}</p>
|
||||
</div>
|
||||
<div class="space-y-1.5">
|
||||
<button
|
||||
v-for="event in day.events"
|
||||
:key="event.id"
|
||||
class="block w-full rounded-md px-2 py-1.5 text-left text-xs"
|
||||
:class="isReviewHighlightedEvent(event.id) ? 'bg-success/20 ring-1 ring-success/45' : 'bg-base-200 hover:bg-base-300/80'"
|
||||
@click.stop="openThreadFromCalendarItem(event)"
|
||||
>
|
||||
{{ formatTime(event.start) }} - {{ event.title }} ({{ event.contact }})
|
||||
</button>
|
||||
<p v-if="day.events.length === 0" class="pt-1 text-xs text-base-content/50">No events</p>
|
||||
</div>
|
||||
</article>
|
||||
</div>
|
||||
</div>
|
||||
calendarView === 'year' ? 'hover:border-primary/50 hover:bg-primary/5 cursor-zoom-in' : 'cursor-default min-h-[26rem] bg-base-100',
|
||||
calendarHoveredMonthIndex === item.monthIndex ? 'calendar-hover-target' : '',
|
||||
calendarZoomPrimeToken === calendarPrimeMonthToken(item.monthIndex) ? 'calendar-zoom-prime-active' : '',
|
||||
]"
|
||||
:style="calendarPrimeStyle(calendarPrimeMonthToken(item.monthIndex))"
|
||||
:data-calendar-month-index="item.monthIndex"
|
||||
@mouseenter="calendarHoveredMonthIndex = item.monthIndex"
|
||||
@click="calendarView === 'year' ? zoomToMonth(item.monthIndex) : undefined"
|
||||
>
|
||||
<p class="font-medium">{{ item.label }}</p>
|
||||
<p class="text-xs text-base-content/60">{{ item.count }} events</p>
|
||||
<button
|
||||
v-if="calendarView === 'year' && item.first"
|
||||
class="mt-1 block w-full text-left text-xs text-base-content/70 hover:underline"
|
||||
@click.stop="openThreadFromCalendarItem(item.first)"
|
||||
>
|
||||
{{ formatDay(item.first.start) }} · {{ item.first.title }}
|
||||
</button>
|
||||
|
||||
<div v-else-if="calendarView === 'day'" class="space-y-2">
|
||||
<button
|
||||
v-for="event in selectedDayEvents"
|
||||
:key="event.id"
|
||||
class="block w-full rounded-xl border border-base-300 p-3 text-left transition hover:bg-base-200/60"
|
||||
:class="isReviewHighlightedEvent(event.id) ? 'border-success/60 bg-success/10' : ''"
|
||||
@click="openThreadFromCalendarItem(event)"
|
||||
>
|
||||
<p class="font-medium">{{ event.title }}</p>
|
||||
<p class="text-xs text-base-content/60">{{ event.contact }}</p>
|
||||
<p class="text-xs text-base-content/60">{{ formatTime(event.start) }} - {{ formatTime(event.end) }}</p>
|
||||
<p class="mt-1 text-sm text-base-content/80">{{ event.note }}</p>
|
||||
</button>
|
||||
<p v-if="selectedDayEvents.length === 0" class="text-sm text-base-content/60">No events on this day.</p>
|
||||
</div>
|
||||
<div
|
||||
v-if="item.monthIndex === calendarCursor.getMonth() && (calendarView === 'month' || calendarView === 'agenda')"
|
||||
class="mt-3 space-y-1"
|
||||
>
|
||||
<div class="grid grid-cols-7 gap-1 text-center text-xs font-semibold text-base-content/60">
|
||||
<span>Sun</span>
|
||||
<span>Mon</span>
|
||||
<span>Tue</span>
|
||||
<span>Wed</span>
|
||||
<span>Thu</span>
|
||||
<span>Fri</span>
|
||||
<span>Sat</span>
|
||||
</div>
|
||||
|
||||
<div v-else-if="calendarView === 'year'" class="grid gap-2 sm:grid-cols-2 xl:grid-cols-3">
|
||||
<button
|
||||
v-for="item in yearMonths"
|
||||
:key="`year-month-${item.monthIndex}`"
|
||||
class="group relative rounded-xl border border-base-300 p-3 text-left transition hover:border-primary/50 hover:bg-primary/5 cursor-zoom-in calendar-hover-targetable"
|
||||
:class="[
|
||||
calendarHoveredMonthIndex === item.monthIndex ? 'calendar-hover-target' : '',
|
||||
calendarZoomPrimeToken === calendarPrimeMonthToken(item.monthIndex) ? 'calendar-zoom-prime-active' : '',
|
||||
]"
|
||||
:style="calendarPrimeStyle(calendarPrimeMonthToken(item.monthIndex))"
|
||||
:data-calendar-month-index="item.monthIndex"
|
||||
@mouseenter="calendarHoveredMonthIndex = item.monthIndex"
|
||||
@click="zoomToMonth(item.monthIndex)"
|
||||
>
|
||||
<p class="font-medium">{{ item.label }}</p>
|
||||
<p class="text-xs text-base-content/60">{{ item.count }} events</p>
|
||||
<button
|
||||
v-if="item.first"
|
||||
class="mt-1 block w-full text-left text-xs text-base-content/70 hover:underline"
|
||||
@click.stop="openThreadFromCalendarItem(item.first)"
|
||||
>
|
||||
{{ formatDay(item.first.start) }} · {{ item.first.title }}
|
||||
</button>
|
||||
</button>
|
||||
</div>
|
||||
<div class="space-y-1">
|
||||
<div
|
||||
v-for="row in monthRows"
|
||||
:key="row.key"
|
||||
class="group relative calendar-hover-targetable"
|
||||
:class="[
|
||||
calendarHoveredWeekStartKey === row.startKey ? 'calendar-hover-target' : '',
|
||||
calendarZoomPrimeToken === calendarPrimeWeekToken(row.startKey) ? 'calendar-zoom-prime-active' : '',
|
||||
]"
|
||||
:style="calendarPrimeStyle(calendarPrimeWeekToken(row.startKey))"
|
||||
:data-calendar-week-start-key="row.startKey"
|
||||
@mouseenter="calendarHoveredWeekStartKey = row.startKey"
|
||||
>
|
||||
<div class="grid grid-cols-7 gap-1">
|
||||
<button
|
||||
v-for="cell in row.cells"
|
||||
:key="cell.key"
|
||||
class="group relative min-h-24 rounded-lg border p-1 text-left"
|
||||
:class="[
|
||||
cell.inMonth ? 'border-base-300 bg-base-100' : 'border-base-200 bg-base-200/40 text-base-content/40',
|
||||
selectedDateKey === cell.key ? 'border-primary bg-primary/5' : '',
|
||||
monthCellHasFocusedEvent(cell.events) ? 'border-success/60 bg-success/10' : '',
|
||||
]"
|
||||
:data-calendar-day-key="cell.key"
|
||||
@mouseenter="calendarHoveredDayKey = cell.key"
|
||||
@click="pickDate(cell.key)"
|
||||
>
|
||||
<p class="mb-1 text-xs font-semibold">{{ cell.day }}</p>
|
||||
<button
|
||||
v-for="event in monthCellEvents(cell.events)"
|
||||
:key="event.id"
|
||||
class="block w-full truncate rounded px-1 text-left text-[10px] text-base-content/70 transition hover:underline"
|
||||
:class="isReviewHighlightedEvent(event.id) ? 'bg-success/20 text-success-content ring-1 ring-success/40' : ''"
|
||||
@click.stop="openThreadFromCalendarItem(event)"
|
||||
>
|
||||
{{ formatTime(event.start) }} {{ event.title }}
|
||||
</button>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-else class="space-y-2">
|
||||
<button
|
||||
v-for="event in sortedEvents"
|
||||
:key="event.id"
|
||||
class="block w-full rounded-xl border border-base-300 p-3 text-left transition hover:bg-base-200/60"
|
||||
:class="isReviewHighlightedEvent(event.id) ? 'border-success/60 bg-success/10' : ''"
|
||||
@click="openThreadFromCalendarItem(event)"
|
||||
>
|
||||
<p class="font-medium">{{ event.title }}</p>
|
||||
<p class="text-xs text-base-content/60">{{ event.contact }}</p>
|
||||
<p class="text-xs text-base-content/60">{{ formatDay(event.start) }} · {{ formatTime(event.start) }} - {{ formatTime(event.end) }}</p>
|
||||
<p class="mt-1 text-sm text-base-content/80">{{ event.note }}</p>
|
||||
</button>
|
||||
</div>
|
||||
<div
|
||||
v-else-if="item.monthIndex === calendarCursor.getMonth() && calendarView === 'week'"
|
||||
class="mt-3 calendar-week-scroll overflow-x-auto pb-1"
|
||||
>
|
||||
<div class="calendar-week-grid">
|
||||
<article
|
||||
v-for="day in weekDays"
|
||||
:key="day.key"
|
||||
class="group relative flex min-h-[18rem] flex-col rounded-xl border border-base-300 bg-base-100 p-2.5 cursor-zoom-in calendar-hover-targetable"
|
||||
:class="[
|
||||
selectedDateKey === day.key ? 'border-primary bg-primary/5' : '',
|
||||
calendarHoveredDayKey === day.key ? 'calendar-hover-target' : '',
|
||||
calendarZoomPrimeToken === calendarPrimeDayToken(day.key) ? 'calendar-zoom-prime-active' : '',
|
||||
]"
|
||||
:style="calendarPrimeStyle(calendarPrimeDayToken(day.key))"
|
||||
:data-calendar-day-key="day.key"
|
||||
@mouseenter="calendarHoveredDayKey = day.key"
|
||||
@click="pickDate(day.key)"
|
||||
>
|
||||
<div class="mb-2 flex items-start justify-between gap-2">
|
||||
<p class="text-sm font-semibold leading-tight">{{ day.label }} {{ day.day }}</p>
|
||||
</div>
|
||||
<div class="space-y-1.5">
|
||||
<button
|
||||
v-for="event in day.events"
|
||||
:key="event.id"
|
||||
class="block w-full rounded-md px-2 py-1.5 text-left text-xs"
|
||||
:class="isReviewHighlightedEvent(event.id) ? 'bg-success/20 ring-1 ring-success/45' : 'bg-base-200 hover:bg-base-300/80'"
|
||||
@click.stop="openThreadFromCalendarItem(event)"
|
||||
>
|
||||
{{ formatTime(event.start) }} - {{ event.title }} ({{ event.contact }})
|
||||
</button>
|
||||
<p v-if="day.events.length === 0" class="pt-1 text-xs text-base-content/50">No events</p>
|
||||
</div>
|
||||
</article>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-else-if="item.monthIndex === calendarCursor.getMonth() && calendarView === 'day'"
|
||||
class="mt-3 space-y-2"
|
||||
>
|
||||
<button
|
||||
v-for="event in selectedDayEvents"
|
||||
:key="event.id"
|
||||
class="block w-full rounded-xl border border-base-300 p-3 text-left transition hover:bg-base-200/60"
|
||||
:class="isReviewHighlightedEvent(event.id) ? 'border-success/60 bg-success/10' : ''"
|
||||
@click="openThreadFromCalendarItem(event)"
|
||||
>
|
||||
<p class="font-medium">{{ event.title }}</p>
|
||||
<p class="text-xs text-base-content/60">{{ event.contact }}</p>
|
||||
<p class="text-xs text-base-content/60">{{ formatTime(event.start) }} - {{ formatTime(event.end) }}</p>
|
||||
<p class="mt-1 text-sm text-base-content/80">{{ event.note }}</p>
|
||||
</button>
|
||||
<p v-if="selectedDayEvents.length === 0" class="text-sm text-base-content/60">No events on this day.</p>
|
||||
</div>
|
||||
</article>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
@@ -5606,31 +5602,6 @@ async function decideFeedCard(card: FeedCard, decision: "accepted" | "rejected")
|
||||
|
||||
<div class="min-h-0 flex-1 overflow-y-auto p-0">
|
||||
<div
|
||||
v-if="peopleListMode === 'contacts' && hiddenContactInboxes.length"
|
||||
class="border-b border-base-300 px-3 py-2"
|
||||
>
|
||||
<p class="mb-1 text-[10px] font-semibold uppercase tracking-wide text-base-content/55">Hidden sources</p>
|
||||
<div class="space-y-1">
|
||||
<div
|
||||
v-for="inbox in hiddenContactInboxes.slice(0, 30)"
|
||||
:key="`hidden-inbox-${inbox.id}`"
|
||||
class="flex items-center justify-between gap-2 rounded-lg border border-base-300 bg-base-100 px-2 py-1"
|
||||
>
|
||||
<p class="min-w-0 flex-1 truncate text-[10px] text-base-content/75">
|
||||
{{ inbox.contactName }} · {{ formatInboxLabel(inbox) }}
|
||||
</p>
|
||||
<button
|
||||
class="btn btn-ghost btn-xs h-5 min-h-5 px-1"
|
||||
:disabled="isInboxToggleLoading(inbox.id)"
|
||||
@click="setInboxHidden(inbox.id, false)"
|
||||
>
|
||||
{{ isInboxToggleLoading(inbox.id) ? "..." : "Show" }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button
|
||||
v-if="peopleListMode === 'contacts'"
|
||||
v-for="thread in peopleContactList"
|
||||
:key="thread.id"
|
||||
@@ -5640,6 +5611,10 @@ async function decideFeedCard(card: FeedCard, decision: "accepted" | "rejected")
|
||||
isReviewHighlightedContact(thread.id) ? 'bg-primary/10 ring-1 ring-primary/45' : '',
|
||||
]"
|
||||
@click="openCommunicationThread(thread.contact)"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
@keydown.enter.prevent="openCommunicationThread(thread.contact)"
|
||||
@keydown.space.prevent="openCommunicationThread(thread.contact)"
|
||||
>
|
||||
<div class="flex items-start gap-2">
|
||||
<div class="avatar shrink-0">
|
||||
@@ -5661,24 +5636,46 @@ async function decideFeedCard(card: FeedCard, decision: "accepted" | "rejected")
|
||||
<p class="truncate text-xs font-semibold">{{ thread.contact }}</p>
|
||||
<span class="shrink-0 text-[10px] text-base-content/55">{{ formatThreadTime(thread.lastAt) }}</span>
|
||||
</div>
|
||||
<div class="mt-0.5 flex items-center gap-2">
|
||||
<p class="min-w-0 flex-1 truncate text-[11px] text-base-content/75">{{ thread.lastText }}</p>
|
||||
<span
|
||||
class="inline-block h-2 w-2 rounded-full"
|
||||
:class="
|
||||
threadTone(thread) === 'event'
|
||||
? 'bg-red-500'
|
||||
: threadTone(thread) === 'recommendation'
|
||||
? 'bg-violet-500'
|
||||
: threadTone(thread) === 'message'
|
||||
? 'bg-blue-500'
|
||||
: 'bg-base-300'
|
||||
"
|
||||
/>
|
||||
<div class="mt-0.5 flex items-center justify-between gap-2">
|
||||
<p class="min-w-0 flex-1 truncate text-[11px] text-base-content/75">{{ threadChannelLabel(thread) }}</p>
|
||||
<div class="dropdown dropdown-end" @click.stop>
|
||||
<button
|
||||
tabindex="0"
|
||||
class="btn btn-ghost btn-xs btn-square h-5 min-h-5"
|
||||
title="Source visibility settings"
|
||||
>
|
||||
<svg viewBox="0 0 24 24" class="h-3.5 w-3.5 fill-current">
|
||||
<path d="M19.14 12.94a7.43 7.43 0 0 0 .05-.94 7.43 7.43 0 0 0-.05-.94l2.03-1.58a.5.5 0 0 0 .12-.63l-1.92-3.32a.5.5 0 0 0-.6-.22l-2.39.96a7.2 7.2 0 0 0-1.62-.94l-.36-2.54A.5.5 0 0 0 13.9 2h-3.8a.5.5 0 0 0-.49.41L9.25 4.95a7.2 7.2 0 0 0-1.62.94l-2.39-.96a.5.5 0 0 0-.6.22L2.72 8.47a.5.5 0 0 0 .12.63l2.03 1.58a7.43 7.43 0 0 0-.05.94c0 .31.02.63.05.94l-2.03 1.58a.5.5 0 0 0-.12.63l1.92 3.32c.13.23.39.32.6.22l2.39-.96c.5.39 1.05.71 1.62.94l.36 2.54c.04.24.25.41.49.41h3.8c.24 0 .45-.17.49-.41l.36-2.54c.57-.23 1.12-.55 1.62-.94l2.39.96c.22.09.47 0 .6-.22l1.92-3.32a.5.5 0 0 0-.12-.63zM12 15.5A3.5 3.5 0 1 1 12 8a3.5 3.5 0 0 1 0 7.5Z" />
|
||||
</svg>
|
||||
</button>
|
||||
<div tabindex="0" class="dropdown-content z-20 mt-1 w-60 rounded-xl border border-base-300 bg-base-100 p-2 shadow-lg">
|
||||
<p class="px-1 pb-1 text-[10px] font-semibold uppercase tracking-wide text-base-content/55">Sources</p>
|
||||
<div v-if="threadInboxes(thread).length" class="space-y-1">
|
||||
<button
|
||||
v-for="inbox in threadInboxes(thread)"
|
||||
:key="`thread-inbox-setting-${inbox.id}`"
|
||||
class="btn btn-ghost btn-xs h-auto min-h-0 w-full justify-between px-2 py-1 text-left normal-case"
|
||||
@click.stop="setInboxHidden(inbox.id, !inbox.isHidden)"
|
||||
>
|
||||
<span class="min-w-0 truncate">{{ formatInboxLabel(inbox) }}</span>
|
||||
<span class="shrink-0 text-[10px] text-base-content/70">
|
||||
{{
|
||||
isInboxToggleLoading(inbox.id)
|
||||
? "..."
|
||||
: inbox.isHidden
|
||||
? "Hidden"
|
||||
: "Visible"
|
||||
}}
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
<p v-else class="px-1 py-1 text-[11px] text-base-content/60">No sources.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<button
|
||||
v-if="peopleListMode === 'deals'"
|
||||
@@ -5862,30 +5859,6 @@ async function decideFeedCard(card: FeedCard, decision: "accepted" | "rejected")
|
||||
<span class="shrink-0 text-xs text-base-content/75">{{ selectedCommPinnedStream.length }}</span>
|
||||
</button>
|
||||
|
||||
<div v-if="selectedThreadInboxes.length" class="mb-2 flex flex-wrap items-center gap-1.5">
|
||||
<div
|
||||
v-for="inbox in selectedThreadInboxes"
|
||||
:key="`inbox-chip-${inbox.id}`"
|
||||
class="inline-flex items-center gap-1 rounded-full border border-base-300 bg-base-100 px-2 py-1 text-[10px]"
|
||||
:class="inbox.isHidden ? 'opacity-60' : ''"
|
||||
>
|
||||
<span class="truncate max-w-[180px]">{{ formatInboxLabel(inbox) }}</span>
|
||||
<button
|
||||
class="btn btn-ghost btn-xs h-5 min-h-5 px-1"
|
||||
:disabled="isInboxToggleLoading(inbox.id)"
|
||||
@click="setInboxHidden(inbox.id, !inbox.isHidden)"
|
||||
>
|
||||
{{
|
||||
isInboxToggleLoading(inbox.id)
|
||||
? "..."
|
||||
: inbox.isHidden
|
||||
? "Show"
|
||||
: "Hide"
|
||||
}}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-for="entry in (commPinnedOnly ? selectedCommPinnedStream : threadStreamItems)"
|
||||
:key="entry.id"
|
||||
|
||||
Reference in New Issue
Block a user