From 671e02edcbf0e766fa64300d636830739df2a4ba Mon Sep 17 00:00:00 2001 From: Brandon Thomas Date: Wed, 15 Oct 2025 01:00:28 -0400 Subject: [PATCH] refactor fields --- .../task_queue/get_task_queue_command.rs | 27 +++++++++--- .../components/signaled/TopBar/TaskQueue.tsx | 42 ++++++++----------- .../lib/artcraft/task_queue/GetTaskQueue.ts | 18 ++++++-- 3 files changed, 54 insertions(+), 33 deletions(-) diff --git a/crates/desktop/artcraft/src/core/commands/task_queue/get_task_queue_command.rs b/crates/desktop/artcraft/src/core/commands/task_queue/get_task_queue_command.rs index d706bd3285..be0cb8cec9 100644 --- a/crates/desktop/artcraft/src/core/commands/task_queue/get_task_queue_command.rs +++ b/crates/desktop/artcraft/src/core/commands/task_queue/get_task_queue_command.rs @@ -18,6 +18,7 @@ use serde_derive::{Deserialize, Serialize}; use sqlite_tasks::queries::list_tasks_for_frontend::list_tasks_for_frontend; use storyteller_client::endpoints::media_files::delete_media_file::delete_media_file; use tauri::{AppHandle, State}; +use tokens::tokens::batch_generations::BatchGenerationToken; use tokens::tokens::media_files::MediaFileToken; use tokens::tokens::sqlite::tasks::TaskId; @@ -42,9 +43,20 @@ pub struct TaskQueueItem { #[derive(Serialize)] pub struct CompletedItemData { - pub primary_media_file_token: MediaFileToken, + pub primary_media_file: MediaFileData, + + /// If generated in a batch, we probably have a batch token we can query. + pub maybe_batch_token: Option, +} + +#[derive(Serialize)] +pub struct MediaFileData { + pub token: MediaFileToken, pub cdn_url: String, - pub thumbnail_url_template: Option, + pub maybe_thumbnail_url_template: Option, + + // NB: The frontend wants this. + pub created_at: DateTime, } impl SerializeMarker for GetTaskQueueCommandResponse {} @@ -93,9 +105,14 @@ pub async fn handle_request( if let Some((primary_media_file_token, media_file_url)) = token_and_url{ completed_item = Some(CompletedItemData { - primary_media_file_token, - cdn_url: media_file_url, - thumbnail_url_template: task.on_complete_primary_media_file_thumbnail_url_template, + primary_media_file: MediaFileData { + token: primary_media_file_token, + cdn_url: media_file_url.clone(), + maybe_thumbnail_url_template: task.on_complete_primary_media_file_thumbnail_url_template.clone(), + // NB: This isn't the exact completion date. Also, fallback to now if missing. + created_at: task.completed_at.unwrap_or_else(Utc::now), + }, + maybe_batch_token: task.on_complete_batch_token, }); } else { warn!("Task {} is marked complete but has no primary media file token or URL.", task.id); diff --git a/frontend/apps/editor3d/app/src/components/signaled/TopBar/TaskQueue.tsx b/frontend/apps/editor3d/app/src/components/signaled/TopBar/TaskQueue.tsx index 71ab23bf1f..080ea69aae 100644 --- a/frontend/apps/editor3d/app/src/components/signaled/TopBar/TaskQueue.tsx +++ b/frontend/apps/editor3d/app/src/components/signaled/TopBar/TaskQueue.tsx @@ -29,7 +29,6 @@ import { getProviderDisplayName, getModelDisplayName, } from "@storyteller/model-list"; -import { MediaFilesApi } from "@storyteller/api"; import { CloseButton } from "@storyteller/ui-close-button"; import { ActionReminderModal } from "@storyteller/ui-action-reminder-modal"; @@ -38,7 +37,7 @@ type InProgressTask = { title: string; subtitle?: string; progress: number; - updatedAt?: string; + updatedAt?: Date; canDismiss?: boolean; }; @@ -47,8 +46,8 @@ type CompletedTask = { title: string; subtitle?: string; thumbnailUrl?: string; - completedAt?: string; - updatedAt?: string; + completedAt?: Date; + updatedAt?: Date; imageUrls?: string[]; mediaTokens?: string[]; }; @@ -225,19 +224,6 @@ export const TaskQueue = () => { const { tasks } = result; - //let mediaTokens: string[] = []; - //let imageUrls: string[] = []; - //let thumbnailUrls : string[] = []; - //for (const task of tasks) { - // if (!!task.completed_item) { - // mediaTokens.push(task.completed_item.primary_media_file_token); - // imageUrls.push(task.completed_item.cdn_url) - // if (!!task.completed_item.thumbnail_url_template) { - // thumbnailUrls.push(task.completed_item.thumbnail_url_template.replace("{WIDTH}", "250")); - // } - // } - //} - const now = Date.now(); const inProg = tasks .filter( @@ -267,7 +253,7 @@ export const TaskQueue = () => { title: `Generating ${parts.kind || "Task"}...`, subtitle: parts.subtitle, progress, - updatedAt: t.updated_at?.toISOString(), + updatedAt: t.updated_at, canDismiss, }; }); @@ -290,11 +276,17 @@ export const TaskQueue = () => { .map((t: TaskQueueItem) => ({ id: t.id, ...formatTitleParts(t), - thumbnailUrl: t.completed_item?.thumbnail_url_template ? t.completed_item?.thumbnail_url_template.replace("{WIDTH}", "250") : undefined, - completedAt: t.completed_at?.toISOString(), - updatedAt: t.updated_at?.toISOString(), - imageUrls: t.completed_item?.cdn_url ? [t.completed_item?.cdn_url] : [], - mediaTokens: t.completed_item?.primary_media_file_token ? [t.completed_item?.primary_media_file_token] : [], + thumbnailUrl: t.completed_item?.primary_media_file?.maybe_thumbnail_url_template ? + t.completed_item?.primary_media_file?.maybe_thumbnail_url_template.replace("{WIDTH}", "250") : + undefined, + imageUrls: t.completed_item?.primary_media_file?.cdn_url ? + [t.completed_item?.primary_media_file?.cdn_url] : + [], + mediaTokens: t.completed_item?.primary_media_file?.token ? + [t.completed_item?.primary_media_file?.token] : + [], + completedAt: t.completed_at, + updatedAt: t.updated_at, })); setInProgress(inProg); @@ -460,7 +452,7 @@ export const TaskQueue = () => { label: t.title, thumbnail: t.thumbnailUrl || null, fullImage: t.imageUrls?.[0] || null, - createdAt: new Date().toISOString(), + createdAt: (t.completedAt || new Date()).toISOString(), mediaClass: "image", } as GalleryItem; galleryModalLightboxMediaId.value = item.id; @@ -582,7 +574,7 @@ export const TaskQueue = () => { label: t.title, thumbnail: t.thumbnailUrl || null, fullImage: t.imageUrls?.[0] || null, - createdAt: new Date().toISOString(), + createdAt: (t.completedAt || new Date()).toISOString(), mediaClass: "image", } as GalleryItem; galleryModalLightboxMediaId.value = item.id; diff --git a/frontend/libs/tauri-api/src/lib/artcraft/task_queue/GetTaskQueue.ts b/frontend/libs/tauri-api/src/lib/artcraft/task_queue/GetTaskQueue.ts index fa63453031..99582ac98a 100644 --- a/frontend/libs/tauri-api/src/lib/artcraft/task_queue/GetTaskQueue.ts +++ b/frontend/libs/tauri-api/src/lib/artcraft/task_queue/GetTaskQueue.ts @@ -26,9 +26,15 @@ export interface TaskQueueItem { } export interface TaskQueueCompletedItem { - primary_media_file_token: string, + primary_media_file: MediaFileData, + maybe_batch_token?: string, +} + +export interface MediaFileData { + token: string, cdn_url: string, - thumbnail_url_template?: string, + maybe_thumbnail_url_template?: string, + created_at: Date, } interface GetTaskQueueSuccess extends CommandResult { @@ -44,6 +50,12 @@ export const GetTaskQueue = async (): Promise => { // Convert timestamps to Date objects const newTasks: TaskQueueItem[] = tasks.map((task) => { + let completed_item = task.completed_item; + + if (!!completed_item) { + completed_item.primary_media_file.created_at = new Date(completed_item.primary_media_file.created_at); + } + return { id: task.id, task_status: task.task_status, @@ -51,7 +63,7 @@ export const GetTaskQueue = async (): Promise => { model_type: task.model_type, provider: task.provider, provider_job_id: task.provider_job_id, - completed_item: task.completed_item, + completed_item: completed_item, created_at: new Date(task.created_at), updated_at: new Date(task.updated_at), completed_at: task.completed_at ? new Date(task.completed_at) : undefined,