Replace Hero/Edit-source chrome with Photos role cards.
Inspector stills use plain-English roles and Mention phrases; Qwen Generate hides Photos entirely. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -1,24 +1,53 @@
|
||||
<template>
|
||||
<div class="slot-block">
|
||||
<span class="field-label">{{ label }}</span>
|
||||
<div class="photo-card">
|
||||
<button
|
||||
type="button"
|
||||
class="slot-thumb"
|
||||
:class="asset ? (size==='hero' ? 'slot-thumb--hero' : 'slot-thumb--slot') : 'slot-thumb--empty'"
|
||||
:class="asset ? 'slot-thumb--slot' : 'slot-thumb--empty'"
|
||||
:aria-label="asset ? 'Replace photo' : 'Select photo'"
|
||||
@click="$emit('pick')"
|
||||
>
|
||||
<span v-if="asset && hidden" class="p-2 text-center text-[var(--type-sm)] text-[var(--muted)]">Still loaded · preview hidden</span>
|
||||
<img v-else-if="asset" :src="asset.kind==='clip' ? `/api/library/clips/${asset.id}/thumb` : `/api/library/stills/${asset.id}`" :alt="label">
|
||||
<img v-else-if="asset" :src="thumbSrc" alt="">
|
||||
<span v-else class="inline-flex items-center gap-1">Select <span aria-hidden="true">▾</span></span>
|
||||
</button>
|
||||
<p v-if="asset" class="slot-caption" :title="assetLabel(asset)">{{ assetLabel(asset) }}</p>
|
||||
<label v-if="upload" class="slot-upload">Upload {{ label.toLowerCase() }}
|
||||
<input type="file" accept="image/*" class="sr-only" :disabled="disabled" @change="$emit('upload',$event)">
|
||||
</label>
|
||||
<div class="photo-card-body">
|
||||
<label class="photo-role-label">
|
||||
<span class="field-label">This photo is:</span>
|
||||
<select
|
||||
class="field-control photo-role-select"
|
||||
:value="role"
|
||||
:disabled="readonly"
|
||||
@change="$emit('update:role', ($event.target as HTMLSelectElement).value)"
|
||||
>
|
||||
<option v-for="opt in roleOptions" :key="opt.id" :value="opt.id">{{ opt.label }}</option>
|
||||
</select>
|
||||
</label>
|
||||
<div class="slot-actions">
|
||||
<button
|
||||
v-if="!readonly && asset"
|
||||
type="button"
|
||||
class="slot-token-btn"
|
||||
title="Mention this photo in the prompt"
|
||||
@click.stop="$emit('mention')"
|
||||
>Mention in prompt</button>
|
||||
<button v-if="!readonly" type="button" @click.stop="$emit('remove')">Remove</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import {assetLabel} from '~/shared/studio2/viewer.mjs'
|
||||
withDefaults(defineProps<{label:string;asset?:any;hidden?:boolean;upload?:boolean;disabled?:boolean;size?:'hero'|'slot'}>(),{size:'slot'})
|
||||
defineEmits(['pick','upload'])
|
||||
const props = withDefaults(defineProps<{
|
||||
asset?: any
|
||||
hidden?: boolean
|
||||
role: string
|
||||
roleOptions: { id: string; label: string }[]
|
||||
readonly?: boolean
|
||||
}>(), { readonly: false, hidden: false })
|
||||
defineEmits(['pick', 'remove', 'mention', 'update:role'])
|
||||
const thumbSrc = computed(() => {
|
||||
if (!props.asset) return ''
|
||||
if (props.asset.kind === 'clip') return `/api/library/clips/${props.asset.id}/thumb`
|
||||
return `/api/library/stills/${props.asset.id}`
|
||||
})
|
||||
</script>
|
||||
|
||||
Reference in New Issue
Block a user