refact (core): split large code blocks, remove useless files/code #12
@@ -18,6 +18,8 @@ import { useUploadStore } from '../stores/uploadStore'
|
||||
import { useValidationStore } from '../stores/validationStore'
|
||||
import { getFormats } from '../api/client'
|
||||
import { SplitOptions } from '../types'
|
||||
import { useFilterCodecs } from '../hooks/useFilterCodecs'
|
||||
import { useFormatValidation } from '../hooks/useFormatValidation'
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// Section component (collapsible)
|
||||
@@ -91,64 +93,12 @@ export const OptionsPanel: React.FC = () => {
|
||||
// --------------------------------------------------------------
|
||||
// Filter codec options based on selected container
|
||||
// --------------------------------------------------------------
|
||||
const filteredAudioCodecs = useMemo(() => {
|
||||
const entry = compatibility?.[options.container || '']
|
||||
if (!entry) return codecs.filter(c => c.supports_transcoding)
|
||||
const audioList = entry.audio
|
||||
if (audioList === null) return codecs.filter(c => c.supports_transcoding)
|
||||
return codecs.filter(c => c.supports_transcoding && audioList.includes(c.name))
|
||||
}, [compatibility, options.container, codecs])
|
||||
|
||||
const filteredVideoCodecs = useMemo(() => {
|
||||
const entry = compatibility?.[options.container || '']
|
||||
if (!entry) return codecs.filter(c => c.supports_video)
|
||||
const videoList = entry.video
|
||||
if (videoList === null) return codecs.filter(c => c.supports_video)
|
||||
return codecs.filter(c => c.supports_video && videoList.includes(c.name))
|
||||
}, [compatibility, options.container, codecs])
|
||||
const { filteredAudioCodecs, filteredVideoCodecs } = useFilterCodecs(compatibility, options.container, codecs)
|
||||
|
||||
// --------------------------------------------------------------
|
||||
// Validate compatibility
|
||||
// --------------------------------------------------------------
|
||||
useEffect(() => {
|
||||
const selectedContainer = containers.find(c => c.name === options.container)
|
||||
if (selectedContainer?.audio_only && hasVideo && !options.drop_video) {
|
||||
setFormatError(
|
||||
`Container '${options.container}' does not support video streams. Please enable "Drop video" or choose a container that supports video.`
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
// Check audio codec compatibility
|
||||
if (options.audio_codec && options.audio_codec !== 'copy' && options.container) {
|
||||
const entry = compatibility?.[options.container]
|
||||
if (entry) {
|
||||
const audioList = entry.audio
|
||||
if (audioList !== null && !audioList.includes(options.audio_codec)) {
|
||||
setFormatError(
|
||||
`Audio codec '${options.audio_codec}' is not supported by container '${options.container}'.`
|
||||
)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check video codec compatibility
|
||||
if (options.video_codec && options.video_codec !== 'copy' && options.container && hasVideo && !options.drop_video) {
|
||||
const entry = compatibility?.[options.container]
|
||||
if (entry) {
|
||||
const videoList = entry.video
|
||||
if (videoList !== null && !videoList.includes(options.video_codec)) {
|
||||
setFormatError(
|
||||
`Video codec '${options.video_codec}' is not supported by container '${options.container}'.`
|
||||
)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
setFormatError(null)
|
||||
}, [options.container, options.audio_codec, options.video_codec, options.drop_video, hasVideo, compatibility, containers, setFormatError])
|
||||
useFormatValidation(options, hasVideo, compatibility, containers, setFormatError)
|
||||
|
||||
// --------------------------------------------------------------
|
||||
// Handlers
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
import { useMemo } from 'react'
|
||||
import { CodecInfo } from '../types'
|
||||
|
||||
export interface CompatibilityEntry {
|
||||
audio: string[] | null
|
||||
video: string[] | null
|
||||
}
|
||||
|
||||
export function useFilterCodecs(
|
||||
compatibility: Record<string, CompatibilityEntry>,
|
||||
container: string | null,
|
||||
codecs: CodecInfo[]
|
||||
) {
|
||||
const filteredAudioCodecs = useMemo(() => {
|
||||
const entry = compatibility?.[container || '']
|
||||
if (!entry) return codecs.filter(c => c.supports_transcoding)
|
||||
const audioList = entry.audio
|
||||
if (audioList === null) return codecs.filter(c => c.supports_transcoding)
|
||||
return codecs.filter(c => c.supports_transcoding && audioList.includes(c.name))
|
||||
}, [compatibility, container, codecs])
|
||||
|
||||
const filteredVideoCodecs = useMemo(() => {
|
||||
const entry = compatibility?.[container || '']
|
||||
if (!entry) return codecs.filter(c => c.supports_video)
|
||||
const videoList = entry.video
|
||||
if (videoList === null) return codecs.filter(c => c.supports_video)
|
||||
return codecs.filter(c => c.supports_video && videoList.includes(c.name))
|
||||
}, [compatibility, container, codecs])
|
||||
|
||||
return { filteredAudioCodecs, filteredVideoCodecs }
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
import { useEffect } from 'react'
|
||||
import { ContainerInfo } from '../types'
|
||||
import { CompatibilityEntry } from './useFilterCodecs'
|
||||
|
||||
export function useFormatValidation(
|
||||
options: {
|
||||
container: string | null
|
||||
audio_codec: string
|
||||
video_codec: string
|
||||
drop_video: boolean
|
||||
},
|
||||
hasVideo: boolean,
|
||||
compatibility: Record<string, CompatibilityEntry>,
|
||||
containers: ContainerInfo[],
|
||||
setFormatError: (error: string | null) => void
|
||||
) {
|
||||
useEffect(() => {
|
||||
const selectedContainer = containers.find(c => c.name === options.container)
|
||||
if (selectedContainer?.audio_only && hasVideo && !options.drop_video) {
|
||||
setFormatError(
|
||||
`Container '${options.container}' does not support video streams. Please enable "Drop video" or choose a container that supports video.`
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
// Check audio codec compatibility
|
||||
if (options.audio_codec && options.audio_codec !== 'copy' && options.container) {
|
||||
const entry = compatibility?.[options.container]
|
||||
if (entry) {
|
||||
const audioList = entry.audio
|
||||
if (audioList !== null && !audioList.includes(options.audio_codec)) {
|
||||
setFormatError(
|
||||
`Audio codec '${options.audio_codec}' is not supported by container '${options.container}'.`
|
||||
)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check video codec compatibility
|
||||
if (options.video_codec && options.video_codec !== 'copy' && options.container && hasVideo && !options.drop_video) {
|
||||
const entry = compatibility?.[options.container]
|
||||
if (entry) {
|
||||
const videoList = entry.video
|
||||
if (videoList !== null && !videoList.includes(options.video_codec)) {
|
||||
setFormatError(
|
||||
`Video codec '${options.video_codec}' is not supported by container '${options.container}'.`
|
||||
)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
setFormatError(null)
|
||||
}, [options.container, options.audio_codec, options.video_codec, options.drop_video, hasVideo, compatibility, containers, setFormatError])
|
||||
}
|
||||
Reference in New Issue
Block a user