feat: enhance emotion handling in audiobook segments and UI for multi-emotion selection
This commit is contained in:
@@ -1381,9 +1381,7 @@ function CharactersPanel({
|
||||
}
|
||||
|
||||
const EMOTION_OPTIONS = ['开心', '愤怒', '悲伤', '恐惧', '厌恶', '低沉', '惊讶', '中性']
|
||||
const EMOTION_ALPHA_DEFAULTS: Record<string, number> = {
|
||||
开心: 0.6, 愤怒: 0.15, 悲伤: 0.4, 恐惧: 0.4, 厌恶: 0.6, 低沉: 0.6, 惊讶: 0.3, 中性: 0.5,
|
||||
}
|
||||
|
||||
|
||||
function ChaptersPanel({
|
||||
project,
|
||||
@@ -1674,8 +1672,10 @@ function ChaptersPanel({
|
||||
{seg.character_name || t('projectCard.segments.unknownCharacter')}
|
||||
</Badge>
|
||||
{!isEditing && seg.emo_text && (
|
||||
<span className="text-[11px] text-muted-foreground shrink-0">
|
||||
{seg.emo_text}
|
||||
<span className="text-[11px] text-muted-foreground shrink-0 flex items-center gap-0.5 flex-wrap">
|
||||
{seg.emo_text.split('+').map(e => (
|
||||
<span key={e} className="bg-muted rounded px-1">{e.trim()}</span>
|
||||
))}
|
||||
{seg.emo_alpha != null && (
|
||||
<span className="opacity-60 ml-0.5">{seg.emo_alpha.toFixed(2)}</span>
|
||||
)}
|
||||
@@ -1718,22 +1718,32 @@ function ChaptersPanel({
|
||||
className="text-sm min-h-[60px] resize-y"
|
||||
rows={3}
|
||||
/>
|
||||
<div className="flex items-center gap-2 flex-wrap">
|
||||
<span className="text-xs text-muted-foreground shrink-0">{t('projectCard.segments.emotion')}:</span>
|
||||
<select
|
||||
value={editEmoText}
|
||||
onChange={e => {
|
||||
const v = e.target.value
|
||||
setEditEmoText(v)
|
||||
if (v && EMOTION_ALPHA_DEFAULTS[v]) setEditEmoAlpha(EMOTION_ALPHA_DEFAULTS[v])
|
||||
}}
|
||||
className="text-xs h-6 rounded border border-input bg-background px-1 focus:outline-none"
|
||||
>
|
||||
<option value="">{t('projectCard.segments.noEmotion')}</option>
|
||||
{EMOTION_OPTIONS.map(e => <option key={e} value={e}>{e}</option>)}
|
||||
</select>
|
||||
<div className="space-y-1.5">
|
||||
<div className="flex items-center gap-1 flex-wrap">
|
||||
<span className="text-xs text-muted-foreground shrink-0">{t('projectCard.segments.emotion')}:</span>
|
||||
{EMOTION_OPTIONS.map(emo => {
|
||||
const selectedEmos = editEmoText.split('+').filter(Boolean)
|
||||
const isSelected = selectedEmos.includes(emo)
|
||||
return (
|
||||
<button
|
||||
key={emo}
|
||||
type="button"
|
||||
className={`px-2 py-0.5 rounded text-xs border transition-colors ${isSelected ? "bg-primary text-primary-foreground border-primary" : "bg-muted text-muted-foreground border-transparent"}`}
|
||||
onClick={() => {
|
||||
const current = editEmoText.split('+').filter(Boolean)
|
||||
const next = isSelected
|
||||
? current.filter(e => e !== emo)
|
||||
: [...current, emo]
|
||||
setEditEmoText(next.join('+'))
|
||||
}}
|
||||
>
|
||||
{emo}
|
||||
</button>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
{editEmoText && (
|
||||
<div className="flex items-center gap-1.5 flex-1 min-w-[120px]">
|
||||
<div className="flex items-center gap-1.5">
|
||||
<span className="text-xs text-muted-foreground shrink-0">{t('projectCard.segments.intensity')}:</span>
|
||||
<input
|
||||
type="range"
|
||||
|
||||
Reference in New Issue
Block a user