edit and compact mode, wip
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, watch, nextTick } from 'vue'
|
||||
import { ref, watch, nextTick, computed } from 'vue'
|
||||
import Panel from '@framework/components/Panel.vue'
|
||||
import { useStore } from '@/store'
|
||||
|
||||
@@ -7,6 +7,19 @@ const { state, activeFrameIndex, selectedFrames, seek, setSelectAll } = useStore
|
||||
|
||||
const cardEls = ref<Record<number, HTMLElement>>({})
|
||||
|
||||
// Thumbnail width (px), persisted. Height derives from a ~16:9 ratio.
|
||||
const MIN_W = 90
|
||||
const MAX_W = 360
|
||||
const STEP = 30
|
||||
const cardW = ref(clampW(Number(localStorage.getItem('meetus.frameW')) || 150))
|
||||
watch(cardW, (w) => localStorage.setItem('meetus.frameW', String(w)))
|
||||
|
||||
const thumbH = computed(() => Math.round(cardW.value * 0.56))
|
||||
|
||||
function clampW(w: number) { return Math.max(MIN_W, Math.min(MAX_W, w)) }
|
||||
function grow() { cardW.value = clampW(cardW.value + STEP) }
|
||||
function shrink() { cardW.value = clampW(cardW.value - STEP) }
|
||||
|
||||
function setCard(i: number, el: Element | null) {
|
||||
if (el) cardEls.value[i] = el as HTMLElement
|
||||
}
|
||||
@@ -29,6 +42,10 @@ watch(activeFrameIndex, async (i) => {
|
||||
<Panel title="Frames">
|
||||
<template #actions>
|
||||
<span class="count">{{ selectedFrames.length }}/{{ state.frames.length }} selected</span>
|
||||
<div class="sizer">
|
||||
<button title="Smaller" :disabled="cardW <= MIN_W" @click="shrink">−</button>
|
||||
<button title="Larger" :disabled="cardW >= MAX_W" @click="grow">+</button>
|
||||
</div>
|
||||
<button @click="setSelectAll(true)">All</button>
|
||||
<button @click="setSelectAll(false)">None</button>
|
||||
</template>
|
||||
@@ -40,8 +57,14 @@ watch(activeFrameIndex, async (i) => {
|
||||
:ref="(el) => setCard(i, el as Element | null)"
|
||||
class="card"
|
||||
:class="{ active: i === activeFrameIndex, off: !f.selected }"
|
||||
:style="{ width: cardW + 'px' }"
|
||||
>
|
||||
<div class="thumb" @click="f.time != null && seek(f.time)" :title="f.time != null ? 'Seek here' : 'No timestamp'">
|
||||
<div
|
||||
class="thumb"
|
||||
:style="{ height: thumbH + 'px' }"
|
||||
@click="f.time != null && seek(f.time)"
|
||||
:title="f.time != null ? 'Seek here' : 'No timestamp'"
|
||||
>
|
||||
<img :src="f.url" loading="lazy" :alt="f.file" />
|
||||
<span class="time">{{ fmt(f.time) }}</span>
|
||||
</div>
|
||||
@@ -69,7 +92,6 @@ watch(activeFrameIndex, async (i) => {
|
||||
padding: var(--space-4);
|
||||
}
|
||||
.card {
|
||||
width: 150px;
|
||||
border: 1px solid var(--border);
|
||||
border-radius: var(--panel-radius);
|
||||
overflow: hidden;
|
||||
@@ -89,7 +111,7 @@ watch(activeFrameIndex, async (i) => {
|
||||
}
|
||||
.thumb img {
|
||||
width: 100%;
|
||||
height: 84px;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
display: block;
|
||||
background: #000;
|
||||
@@ -118,4 +140,14 @@ watch(activeFrameIndex, async (i) => {
|
||||
color: var(--text-secondary);
|
||||
font-size: var(--font-size-sm);
|
||||
}
|
||||
.sizer {
|
||||
display: flex;
|
||||
gap: 2px;
|
||||
}
|
||||
.sizer button {
|
||||
width: 24px;
|
||||
padding: var(--space-1) 0;
|
||||
font-weight: 600;
|
||||
line-height: 1;
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user