- Recherche : le watcher débouncé du singleton useWorktreeView est créé dans un effectScope détaché → ne gèle plus après une navigation ; recherche aussi par label de dépôt ; accès à la palette depuis le MoreSheet mobile (sidebar/⌘K indisponibles sur mobile). - Sessions : sessionsForCwd exclut désormais toujours les sessions masquées ; les sessions externes (discovered) sont masquées par défaut côté UI, avec puce de révélation par carte et case globale dans le dashboard. - Terminal : ACK découplé du callback de rendu (armé à la réception + flush au retour de visibilité) → plus de pause PTY quand l'onglet passe en arrière-plan ; repaint forcé sur perte de contexte WebGL / resize / retour en avant-plan. Historique élargi : REPLAY_TAIL_BYTES 1 Mo, RING_CAPACITY 4 Mo, scrollback xterm 20k. - Grille de groupe : bouton « plein écran » sur chaque cellule ouvrant /sessions/:id.
60 lines
2.2 KiB
Vue
60 lines
2.2 KiB
Vue
<template>
|
|
<Teleport to="body">
|
|
<div class="fixed inset-0 z-50 md:hidden" role="dialog" aria-modal="true">
|
|
<div class="absolute inset-0 bg-black/60" @click="emit('close')" />
|
|
<div
|
|
class="absolute inset-x-0 bottom-0 rounded-t-2xl border-t border-zinc-800 bg-zinc-900 p-4 shadow-pop"
|
|
style="padding-bottom: calc(1rem + env(safe-area-inset-bottom))"
|
|
>
|
|
<div class="mx-auto mb-3 h-1 w-10 rounded-full bg-zinc-700" />
|
|
<!-- accès recherche/palette : sur mobile la sidebar (et ⌘K) est indisponible → seul point d'entrée -->
|
|
<button
|
|
type="button"
|
|
class="mb-3 flex w-full items-center gap-2 rounded-lg border border-zinc-800 bg-zinc-950/40 px-3 py-2 text-sm text-zinc-400 transition-colors hover:border-zinc-700 hover:text-zinc-200 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-emerald-500/50"
|
|
@click="openSearch"
|
|
>
|
|
<Search :size="16" />
|
|
<span>{{ t('common.search') }}</span>
|
|
</button>
|
|
<nav class="mb-3 flex flex-col gap-1">
|
|
<NavItem
|
|
v-for="item in secondary"
|
|
:key="item.key"
|
|
:to="item.to"
|
|
:href="item.href"
|
|
:icon="item.icon"
|
|
:label="item.label"
|
|
:active="isActive(item.match)"
|
|
orientation="row"
|
|
@click="emit('close')"
|
|
/>
|
|
</nav>
|
|
<div class="border-t border-zinc-800/80 pt-3">
|
|
<AppShellFooter />
|
|
</div>
|
|
<BaseButton class="mt-3 w-full" @click="emit('close')">{{ t('common.close') }}</BaseButton>
|
|
</div>
|
|
</div>
|
|
</Teleport>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import { useI18n } from 'vue-i18n';
|
|
import { Search } from '@lucide/vue';
|
|
import { useNav } from '../../composables/useNav';
|
|
import { useCommandPalette } from '../../composables/useCommandPalette';
|
|
import NavItem from './NavItem.vue';
|
|
import AppShellFooter from './AppShellFooter.vue';
|
|
import BaseButton from '../ui/BaseButton.vue';
|
|
|
|
const { t } = useI18n();
|
|
const { secondary, isActive } = useNav();
|
|
const palette = useCommandPalette();
|
|
const emit = defineEmits<{ close: [] }>();
|
|
|
|
function openSearch(): void {
|
|
emit('close');
|
|
palette.show();
|
|
}
|
|
</script>
|