Files
xiaoxia-saas/apps/web/src/pages/editing-planner/components/SubtitleStylePanel.tsx
T
xiaoxia a408ca6679
CI/CD Pipeline / Validate - Type Check (mypy) (push) Successful in 41s
CI/CD Pipeline / Validate - Migration (alembic) (push) Successful in 43s
CI/CD Pipeline / Validate - Code Quality (push) Has been cancelled
CI/CD Pipeline / Unit Tests (push) Has been cancelled
CI/CD Pipeline / Integration Tests (push) Has been cancelled
CI/CD Pipeline / Frontend Unit Tests (push) Has been cancelled
CI/CD Pipeline / Build Staging API Image (push) Has been cancelled
CI/CD Pipeline / Build Staging Web Image (push) Has been cancelled
CI/CD Pipeline / Build Staging Worker Image (push) Has been cancelled
CI/CD Pipeline / Deploy Staging (Watchtower auto-deploy) (push) Has been cancelled
CI/CD Pipeline / Staging E2E Tests (push) Has been cancelled
CI/CD Pipeline / Staging API Integration Tests (push) Has been cancelled
CI/CD Pipeline / Build Production API Image (push) Has been cancelled
CI/CD Pipeline / Build Production Web Image (push) Has been cancelled
CI/CD Pipeline / Build Production Worker Image (push) Has been cancelled
CI/CD Pipeline / Deploy Production (push) Has been cancelled
CI/CD Pipeline / Production Browser E2E (push) Has been cancelled
CI/CD Pipeline / ACR Image Cleanup (push) Has been cancelled
CI/CD Pipeline / Canary Release to Production (push) Has been cancelled
CI/CD Pipeline / CI Gate (push) Has been cancelled
CI/CD Pipeline / PR Build Worker Image (push) Failing after 903h17m31s
CI/CD Pipeline / PR Build API Image (push) Failing after 903h17m31s
CI/CD Pipeline / Frontend Lint (push) Failing after 903h17m32s
CI/CD Pipeline / Check if frontend-only change (push) Failing after 903h17m33s
CI/CD Pipeline / PR Build Web Image (push) Failing after 903h50m57s
fix: 5 个响应式/z-index 问题 (#1326)
2026-08-10 00:09:26 +08:00

148 lines
4.6 KiB
TypeScript
Executable File

import React from "react"
import { Drawer, Slider, ColorPicker, Select } from "antd"
import type { Color } from "antd/es/color-picker"
import type { SubtitleStyleConfig } from "@/pages/editing-planner/types/subtitle"
import {
FONT_OPTIONS,
ANIMATION_OPTIONS,
ASR_LANGUAGE_OPTIONS,
} from "@/pages/editing-planner/constants/subtitleStyle"
import SubtitlePreview from "./subtitle-style/SubtitlePreview"
import { SubtitleModeSwitch } from "./subtitle-style/SubtitleModeSwitch"
import { SubtitlePositionSelector } from "./subtitle-style/SubtitlePositionSelector"
import { SubtitleEffectButtons } from "./subtitle-style/SubtitleEffectButtons"
interface SubtitleStylePanelProps {
open: boolean
onClose: () => void
config: SubtitleStyleConfig
onChange: (config: SubtitleStyleConfig) => void
}
const SubtitleStylePanel: React.FC<SubtitleStylePanelProps> = ({
open,
onClose,
config,
onChange,
}) => {
const update = (partial: Partial<SubtitleStyleConfig>) => {
onChange({ ...config, ...partial })
}
return (
<Drawer
title="💬 字幕样式配置"
placement="right"
width={380}
styles={{ wrapper: { maxWidth: "100vw" } }}
open={open}
onClose={onClose}
className="subtitle-style-drawer"
>
<div className="sub-field">
<div className="sub-toggle-row">
<span className="sub-label">启用字幕</span>
<div
className={`ep-toggle${config.enabled ? " active" : ""}`}
onClick={() => update({ enabled: !config.enabled })}
>
<div className="ep-toggle-knob" />
</div>
</div>
</div>
{config.enabled && (
<>
<div className="sub-field">
<label className="sub-label">字幕来源</label>
<SubtitleModeSwitch mode={config.mode} onModeChange={(mode) => update({ mode })} />
</div>
{config.mode === "asr" && (
<div className="sub-field">
<label className="sub-label">识别语言</label>
<Select
className="sub-select"
value={config.asrLanguage}
onChange={(v) => update({ asrLanguage: v })}
options={ASR_LANGUAGE_OPTIONS}
popupMatchSelectWidth={false}
/>
</div>
)}
<div className="sub-field">
<label className="sub-label">
字体大小 <span className="sub-value">{config.fontSize}px</span>
</label>
<Slider
min={12}
max={48}
value={config.fontSize}
onChange={(v) => update({ fontSize: v })}
/>
</div>
<div className="sub-field">
<label className="sub-label">字体颜色</label>
<div className="sub-color-row">
<ColorPicker
value={config.fontColor}
onChange={(_color: Color, hex: string) => update({ fontColor: hex })}
showText
/>
</div>
</div>
<div className="sub-field">
<label className="sub-label">字体</label>
<Select
className="sub-select"
value={config.font}
onChange={(v) => update({ font: v })}
options={FONT_OPTIONS.map((f) => ({ value: f, label: f }))}
popupMatchSelectWidth={false}
/>
</div>
<div className="sub-field">
<label className="sub-label">位置</label>
<SubtitlePositionSelector
position={config.position}
onPositionChange={(position) => update({ position })}
/>
</div>
<div className="sub-field">
<label className="sub-label">效果</label>
<SubtitleEffectButtons
stroke={config.stroke}
shadow={config.shadow}
onStrokeChange={(stroke) => update({ stroke })}
onShadowChange={(shadow) => update({ shadow })}
/>
</div>
<div className="sub-field">
<label className="sub-label">动画效果</label>
<Select
className="sub-select"
value={config.animation}
onChange={(v) => update({ animation: v })}
options={ANIMATION_OPTIONS.map((o) => ({
value: o.value,
label: o.label,
}))}
popupMatchSelectWidth={false}
/>
</div>
<SubtitlePreview config={config} />
</>
)}
</Drawer>
)
}
export default SubtitleStylePanel