feat(export): split default media options

This commit is contained in:
aits2026
2026-03-06 14:41:02 +08:00
parent d735ed19cb
commit 39e59a4077
4 changed files with 185 additions and 30 deletions

View File

@@ -220,6 +220,29 @@
background: var(--bg-primary);
}
.media-default-grid {
width: 100%;
display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr));
gap: 8px 12px;
margin-bottom: 10px;
label {
display: inline-flex;
align-items: center;
gap: 6px;
margin-bottom: 0;
font-size: 13px;
font-weight: 500;
color: var(--text-primary);
cursor: pointer;
}
input {
margin: 0;
}
}
.log-status {
font-size: 13px;
color: var(--text-secondary);
@@ -354,6 +377,11 @@
margin-bottom: 0;
}
.media-default-grid {
max-width: 360px;
margin-bottom: 0;
}
.concurrency-inline-options {
max-width: 360px;
margin-bottom: 0;
@@ -391,6 +419,7 @@
.select-field,
.settings-time-range-field,
.log-toggle-line,
.media-default-grid,
.concurrency-inline-options,
.format-grid {
max-width: none;

View File

@@ -15,7 +15,7 @@ export interface ExportDefaultsSettingsPatch {
format?: string
avatars?: boolean
dateRange?: ExportDateRangeSelection
media?: boolean
media?: configService.ExportDefaultMediaConfig
voiceAsText?: boolean
excelCompactColumns?: boolean
concurrency?: number
@@ -62,7 +62,12 @@ export function ExportDefaultsSettingsForm({
const [exportDefaultFormat, setExportDefaultFormat] = useState('excel')
const [exportDefaultAvatars, setExportDefaultAvatars] = useState(true)
const [exportDefaultDateRange, setExportDefaultDateRange] = useState<ExportDateRangeSelection>(() => createDefaultExportDateRangeSelection())
const [exportDefaultMedia, setExportDefaultMedia] = useState(false)
const [exportDefaultMedia, setExportDefaultMedia] = useState<configService.ExportDefaultMediaConfig>({
images: true,
videos: true,
voices: true,
emojis: true
})
const [exportDefaultVoiceAsText, setExportDefaultVoiceAsText] = useState(false)
const [exportDefaultExcelCompactColumns, setExportDefaultExcelCompactColumns] = useState(true)
const [exportDefaultConcurrency, setExportDefaultConcurrency] = useState(2)
@@ -85,7 +90,12 @@ export function ExportDefaultsSettingsForm({
setExportDefaultFormat(savedFormat || 'excel')
setExportDefaultAvatars(savedAvatars ?? true)
setExportDefaultDateRange(resolveExportDateRangeConfig(savedDateRange))
setExportDefaultMedia(savedMedia ?? false)
setExportDefaultMedia(savedMedia ?? {
images: true,
videos: true,
voices: true,
emojis: true
})
setExportDefaultVoiceAsText(savedVoiceAsText ?? false)
setExportDefaultExcelCompactColumns(savedExcelCompactColumns ?? true)
setExportDefaultConcurrency(savedConcurrency ?? 2)
@@ -237,27 +247,66 @@ export function ExportDefaultsSettingsForm({
<div className="form-group">
<div className="form-copy">
<label></label>
<span className="form-hint">//</span>
<label></label>
<span className="form-hint"></span>
</div>
<div className="form-control">
<div className="log-toggle-line">
<span className="log-status">{exportDefaultMedia ? '已开启' : '已关闭'}</span>
<label className="switch" htmlFor="shared-export-default-media">
<div className="media-default-grid">
<label>
<input
id="shared-export-default-media"
className="switch-input"
type="checkbox"
checked={exportDefaultMedia}
checked={exportDefaultMedia.images}
onChange={async (e) => {
const enabled = e.target.checked
setExportDefaultMedia(enabled)
await configService.setExportDefaultMedia(enabled)
onDefaultsChanged?.({ media: enabled })
notify(enabled ? '开启默认媒体导出' : '关闭默认媒体导出', true)
const next = { ...exportDefaultMedia, images: e.target.checked }
setExportDefaultMedia(next)
await configService.setExportDefaultMedia(next)
onDefaultsChanged?.({ media: next })
notify(`${e.target.checked ? '开启' : '关闭'}默认导出图片`, true)
}}
/>
<span className="switch-slider" />
</label>
<label>
<input
type="checkbox"
checked={exportDefaultMedia.voices}
onChange={async (e) => {
const next = { ...exportDefaultMedia, voices: e.target.checked }
setExportDefaultMedia(next)
await configService.setExportDefaultMedia(next)
onDefaultsChanged?.({ media: next })
notify(`${e.target.checked ? '开启' : '关闭'}默认导出语音`, true)
}}
/>
</label>
<label>
<input
type="checkbox"
checked={exportDefaultMedia.videos}
onChange={async (e) => {
const next = { ...exportDefaultMedia, videos: e.target.checked }
setExportDefaultMedia(next)
await configService.setExportDefaultMedia(next)
onDefaultsChanged?.({ media: next })
notify(`${e.target.checked ? '开启' : '关闭'}默认导出视频`, true)
}}
/>
</label>
<label>
<input
type="checkbox"
checked={exportDefaultMedia.emojis}
onChange={async (e) => {
const next = { ...exportDefaultMedia, emojis: e.target.checked }
setExportDefaultMedia(next)
await configService.setExportDefaultMedia(next)
onDefaultsChanged?.({ media: next })
notify(`${e.target.checked ? '开启' : '关闭'}默认导出表情包`, true)
}}
/>
</label>
</div>
</div>