Rename input stills from the picker and reveal all hidden library thumbs.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -149,8 +149,34 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-center justify-between gap-2 px-3 py-2">
|
||||
<span class="truncate text-xs text-zinc-400">{{ still.name || still.filename }}</span>
|
||||
<button type="button" class="text-[10px] text-red-300 hover:text-red-200" @click.stop="removeStill(still)">Delete</button>
|
||||
<input
|
||||
v-if="renamingId === still.id"
|
||||
ref="renameInput"
|
||||
v-model="renameDraft"
|
||||
class="min-w-0 flex-1 rounded-md border border-amber-300/40 bg-zinc-950 px-2 py-1 text-xs outline-none ring-amber-300/40 focus:ring-2"
|
||||
maxlength="80"
|
||||
aria-label="Still name"
|
||||
@click.stop
|
||||
@keydown.enter.prevent="saveRename(still)"
|
||||
@keydown.escape.prevent="cancelRename"
|
||||
@blur="saveRename(still)"
|
||||
>
|
||||
<span v-else class="min-w-0 flex-1 truncate text-xs text-zinc-400">{{ stillLabel(still) }}</span>
|
||||
<div class="flex shrink-0 items-center gap-1">
|
||||
<button
|
||||
v-if="renamingId !== still.id"
|
||||
type="button"
|
||||
class="rounded-full p-1 text-amber-200 hover:bg-white/5 hover:text-amber-100"
|
||||
title="Rename"
|
||||
@click.stop="startRename(still)"
|
||||
>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" class="h-3.5 w-3.5">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M16.862 4.487l1.687-1.688a1.875 1.875 0 112.652 2.652L10.582 16.07a4.5 4.5 0 01-1.897 1.13L6 18l.8-2.685a4.5 4.5 0 011.13-1.897l8.932-8.931z" />
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M19.5 7.125L16.862 4.487" />
|
||||
</svg>
|
||||
</button>
|
||||
<button type="button" class="text-[10px] text-red-300 hover:text-red-200" @click.stop="removeStill(still)">Delete</button>
|
||||
</div>
|
||||
</div>
|
||||
</article>
|
||||
</div>
|
||||
@@ -210,6 +236,10 @@ const revealAll = ref(false)
|
||||
const revealedIds = ref<string[]>([])
|
||||
const picking = ref(false)
|
||||
const keepingId = ref('')
|
||||
const renamingId = ref('')
|
||||
const renameDraft = ref('')
|
||||
const renameInput = ref<HTMLInputElement | null>(null)
|
||||
const renameSaving = ref(false)
|
||||
|
||||
function onKey(event: KeyboardEvent) {
|
||||
if (!props.open) return
|
||||
@@ -316,6 +346,45 @@ function onDrop(event: DragEvent) {
|
||||
if (next) void ingest(next)
|
||||
}
|
||||
|
||||
function stillLabel(still: PickerStill) {
|
||||
return (still.name || still.filename.replace(/\.[a-z0-9]+$/i, '') || 'Untitled still').trim()
|
||||
}
|
||||
|
||||
function startRename(still: PickerStill) {
|
||||
renamingId.value = still.id
|
||||
renameDraft.value = stillLabel(still)
|
||||
nextTick(() => {
|
||||
renameInput.value?.focus()
|
||||
renameInput.value?.select()
|
||||
})
|
||||
}
|
||||
|
||||
function cancelRename() {
|
||||
renamingId.value = ''
|
||||
}
|
||||
|
||||
async function saveRename(still: PickerStill) {
|
||||
if (renamingId.value !== still.id || renameSaving.value) return
|
||||
const name = renameDraft.value.trim().slice(0, 80)
|
||||
if (!name) {
|
||||
emit('error', 'A name is required')
|
||||
return
|
||||
}
|
||||
if (name === stillLabel(still)) {
|
||||
cancelRename()
|
||||
return
|
||||
}
|
||||
renameSaving.value = true
|
||||
try {
|
||||
emit('updated', await $fetch(`/api/library/stills/${still.id}`, { method: 'PATCH', body: { name } }))
|
||||
cancelRename()
|
||||
} catch (error: any) {
|
||||
emit('error', error?.data?.statusMessage || 'Could not rename still')
|
||||
} finally {
|
||||
renameSaving.value = false
|
||||
}
|
||||
}
|
||||
|
||||
async function keepAsInput(still: PickerStill) {
|
||||
if (keepingId.value) return
|
||||
keepingId.value = still.id
|
||||
|
||||
Reference in New Issue
Block a user