新增移除任务
This commit is contained in:
parent
d8759d56c6
commit
508f28d092
@ -50,6 +50,14 @@ fn update_segment_text(
|
|||||||
task::update_segment_text(state, segment).map_err(error_to_string)
|
task::update_segment_text(state, segment).map_err(error_to_string)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tauri::command]
|
||||||
|
fn delete_task(
|
||||||
|
state: tauri::State<'_, AppState>,
|
||||||
|
task_id: String,
|
||||||
|
) -> std::result::Result<(), String> {
|
||||||
|
task::delete_task(state, task_id).map_err(error_to_string)
|
||||||
|
}
|
||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
fn export_subtitles(
|
fn export_subtitles(
|
||||||
state: tauri::State<'_, AppState>,
|
state: tauri::State<'_, AppState>,
|
||||||
@ -83,6 +91,7 @@ pub fn run() {
|
|||||||
start_subtitle_task,
|
start_subtitle_task,
|
||||||
list_tasks,
|
list_tasks,
|
||||||
update_segment_text,
|
update_segment_text,
|
||||||
|
delete_task,
|
||||||
export_subtitles,
|
export_subtitles,
|
||||||
get_default_model_paths
|
get_default_model_paths
|
||||||
])
|
])
|
||||||
|
|||||||
@ -31,6 +31,12 @@ impl AppState {
|
|||||||
Ok(tasks)
|
Ok(tasks)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn delete_task(&self, task_id: &str) -> Result<()> {
|
||||||
|
let mut guard = self.tasks.lock().map_err(|_| anyhow!("task store poisoned"))?;
|
||||||
|
guard.remove(task_id);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
pub fn update_segment(&self, segment: SubtitleSegment) -> Result<SubtitleTask> {
|
pub fn update_segment(&self, segment: SubtitleSegment) -> Result<SubtitleTask> {
|
||||||
let mut guard = self.tasks.lock().map_err(|_| anyhow!("task store poisoned"))?;
|
let mut guard = self.tasks.lock().map_err(|_| anyhow!("task store poisoned"))?;
|
||||||
let task = guard
|
let task = guard
|
||||||
|
|||||||
@ -357,6 +357,10 @@ pub fn list_tasks(state: tauri::State<'_, AppState>) -> Result<Vec<SubtitleTask>
|
|||||||
state.list_tasks()
|
state.list_tasks()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn delete_task(state: tauri::State<'_, AppState>, task_id: String) -> Result<()> {
|
||||||
|
state.delete_task(&task_id)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn export_task(state: tauri::State<'_, AppState>, task_id: String, format: String) -> Result<String> {
|
pub fn export_task(state: tauri::State<'_, AppState>, task_id: String, format: String) -> Result<String> {
|
||||||
let task = state.get_task(&task_id)?;
|
let task = state.get_task(&task_id)?;
|
||||||
let format = SubtitleFormat::try_from(format.as_str())?;
|
let format = SubtitleFormat::try_from(format.as_str())?;
|
||||||
|
|||||||
@ -352,6 +352,7 @@ async function handleExport(format: 'srt' | 'vtt' | 'ass') {
|
|||||||
:selected-task-id="taskStore.selectedTaskId"
|
:selected-task-id="taskStore.selectedTaskId"
|
||||||
@select="taskStore.selectTask"
|
@select="taskStore.selectTask"
|
||||||
@retry="taskStore.retryTask"
|
@retry="taskStore.retryTask"
|
||||||
|
@delete="taskStore.deleteTask"
|
||||||
/>
|
/>
|
||||||
<SubtitleEditor
|
<SubtitleEditor
|
||||||
:task="selectedTask"
|
:task="selectedTask"
|
||||||
|
|||||||
@ -9,6 +9,7 @@ defineProps<{
|
|||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
select: [taskId: string]
|
select: [taskId: string]
|
||||||
retry: [taskId: string]
|
retry: [taskId: string]
|
||||||
|
delete: [taskId: string]
|
||||||
}>()
|
}>()
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@ -52,6 +53,17 @@ const emit = defineEmits<{
|
|||||||
<p class="error-text">{{ task.error }}</p>
|
<p class="error-text">{{ task.error }}</p>
|
||||||
<button class="retry-button" type="button" @click.stop="emit('retry', task.id)">{{ $t('taskQueue.retry') }}</button>
|
<button class="retry-button" type="button" @click.stop="emit('retry', task.id)">{{ $t('taskQueue.retry') }}</button>
|
||||||
</div>
|
</div>
|
||||||
|
<button
|
||||||
|
class="delete-button"
|
||||||
|
type="button"
|
||||||
|
:title="$t('taskQueue.delete')"
|
||||||
|
@click.stop="emit('delete', task.id)"
|
||||||
|
>
|
||||||
|
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||||||
|
<polyline points="3 6 5 6 21 6" />
|
||||||
|
<path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2" />
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</aside>
|
</aside>
|
||||||
|
|||||||
@ -49,6 +49,7 @@ export default {
|
|||||||
subtitle: 'Select a task to view subtitles',
|
subtitle: 'Select a task to view subtitles',
|
||||||
empty: 'No tasks',
|
empty: 'No tasks',
|
||||||
retry: 'Retry',
|
retry: 'Retry',
|
||||||
|
delete: 'Delete',
|
||||||
status: {
|
status: {
|
||||||
queued: 'Queued',
|
queued: 'Queued',
|
||||||
extracting: 'Extracting',
|
extracting: 'Extracting',
|
||||||
|
|||||||
@ -49,6 +49,7 @@ export default {
|
|||||||
subtitle: '选择任务查看字幕',
|
subtitle: '选择任务查看字幕',
|
||||||
empty: '暂无任务',
|
empty: '暂无任务',
|
||||||
retry: '重试',
|
retry: '重试',
|
||||||
|
delete: '移除',
|
||||||
status: {
|
status: {
|
||||||
queued: '排队中',
|
queued: '排队中',
|
||||||
extracting: '抽取',
|
extracting: '抽取',
|
||||||
|
|||||||
@ -140,6 +140,18 @@ export const useTaskStore = defineStore('tasks', {
|
|||||||
if (index >= 0) this.tasks[index] = updated
|
if (index >= 0) this.tasks[index] = updated
|
||||||
},
|
},
|
||||||
|
|
||||||
|
async deleteTask(taskId: string) {
|
||||||
|
await invoke('delete_task', { taskId })
|
||||||
|
const index = this.tasks.findIndex((t) => t.id === taskId)
|
||||||
|
if (index >= 0) {
|
||||||
|
this.tasks.splice(index, 1)
|
||||||
|
}
|
||||||
|
delete this.logsByTaskId[taskId]
|
||||||
|
if (this.selectedTaskId === taskId) {
|
||||||
|
this.selectedTaskId = ''
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
async exportTask(taskId: string, format: ExportFormat) {
|
async exportTask(taskId: string, format: ExportFormat) {
|
||||||
return invoke<string>('export_subtitles', { taskId, format })
|
return invoke<string>('export_subtitles', { taskId, format })
|
||||||
},
|
},
|
||||||
|
|||||||
@ -488,6 +488,36 @@ textarea {
|
|||||||
border-left: 3px solid transparent;
|
border-left: 3px solid transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.task-item:hover .delete-button {
|
||||||
|
opacity: 1;
|
||||||
|
pointer-events: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.delete-button {
|
||||||
|
position: absolute;
|
||||||
|
top: 8px;
|
||||||
|
right: 8px;
|
||||||
|
width: 26px;
|
||||||
|
height: 26px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
border: 1px solid var(--c-border);
|
||||||
|
border-radius: var(--radius-sm);
|
||||||
|
background: var(--c-surface);
|
||||||
|
color: var(--c-text-tertiary);
|
||||||
|
cursor: pointer;
|
||||||
|
opacity: 0;
|
||||||
|
pointer-events: none;
|
||||||
|
transition: opacity var(--transition), color var(--transition), border-color var(--transition), background var(--transition);
|
||||||
|
}
|
||||||
|
|
||||||
|
.delete-button:hover {
|
||||||
|
color: var(--c-error);
|
||||||
|
border-color: var(--c-error);
|
||||||
|
background: rgba(220, 38, 38, 0.06);
|
||||||
|
}
|
||||||
|
|
||||||
.truncate {
|
.truncate {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user