Bin29's picture
Localize prompt defaults by locale
e610fb9
Raw
History Blame Contribute Delete
4.33 kB
import type {
GenerateRequest,
GenerateResponse,
JobResult,
ApiError,
PromptDefaults,
ModifyRequest,
UsageMetricsResponse,
PromptLocale
} from '../types/api';
import { loadSettings } from './settings';
import { localizeApiMessage, translate } from '../i18n';
const API_BASE = '/api';
function getAuthHeaders(contentType = 'application/json'): HeadersInit {
const headers: HeadersInit = {};
if (contentType) {
headers['Content-Type'] = contentType;
}
const apiKey = localStorage.getItem('manimcat_api_key');
if (apiKey) {
headers['Authorization'] = `Bearer ${apiKey}`;
}
return headers;
}
export async function modifyAnimation(request: ModifyRequest, signal?: AbortSignal): Promise<GenerateResponse> {
const videoConfig = request.videoConfig || loadSettings().video;
const payload = { ...request, videoConfig };
const response = await fetch(`${API_BASE}/modify`, {
method: 'POST',
headers: getAuthHeaders(),
body: JSON.stringify(payload),
signal,
});
if (!response.ok) {
const error: ApiError = await response.json();
throw new Error(error.error ? localizeApiMessage(error.error) : translate('api.modifyFailed'));
}
return response.json();
}
interface UploadReferenceImageResponse {
success: boolean;
url: string;
relativeUrl: string;
mimeType: string;
size: number;
}
export async function uploadReferenceImage(file: File, signal?: AbortSignal): Promise<UploadReferenceImageResponse> {
const response = await fetch(`${API_BASE}/reference-images`, {
method: 'POST',
headers: getAuthHeaders(file.type || 'application/octet-stream'),
body: file,
signal,
});
if (!response.ok) {
let message = translate('api.uploadFailed');
try {
const error: ApiError = await response.json();
message = error.error ? localizeApiMessage(error.error) : message;
} catch {
// ignore json parse errors and keep default message
}
throw new Error(message);
}
return response.json();
}
export async function generateAnimation(request: GenerateRequest, signal?: AbortSignal): Promise<GenerateResponse> {
const videoConfig = request.videoConfig || loadSettings().video;
const payload = { ...request, videoConfig };
const response = await fetch(`${API_BASE}/generate`, {
method: 'POST',
headers: getAuthHeaders(),
body: JSON.stringify(payload),
signal,
});
if (!response.ok) {
const error: ApiError = await response.json();
throw new Error(error.error ? localizeApiMessage(error.error) : translate('api.generateFailed'));
}
return response.json();
}
export async function getPromptDefaults(locale?: PromptLocale, signal?: AbortSignal): Promise<PromptDefaults> {
const query = locale ? `?locale=${encodeURIComponent(locale)}` : '';
const response = await fetch(`${API_BASE}/prompts/defaults${query}`, {
headers: getAuthHeaders(),
signal,
});
if (!response.ok) {
const error: ApiError = await response.json();
throw new Error(error.error || 'Failed to load prompt defaults');
}
return response.json();
}
export async function getJobStatus(jobId: string, signal?: AbortSignal): Promise<JobResult> {
const response = await fetch(`${API_BASE}/jobs/${jobId}`, {
headers: getAuthHeaders(),
signal,
});
if (!response.ok) {
const error: ApiError = await response.json();
throw new Error(error.error ? localizeApiMessage(error.error) : translate('api.jobStatusFailed'));
}
return response.json();
}
export async function cancelJob(jobId: string): Promise<void> {
const response = await fetch(`${API_BASE}/jobs/${jobId}/cancel`, {
method: 'POST',
headers: getAuthHeaders(),
});
if (!response.ok) {
const error: ApiError = await response.json();
throw new Error(error.error ? localizeApiMessage(error.error) : translate('api.cancelFailed'));
}
}
export async function getUsageMetrics(days = 7, signal?: AbortSignal): Promise<UsageMetricsResponse> {
const response = await fetch(`${API_BASE}/metrics/usage?days=${days}`, {
headers: getAuthHeaders(),
signal,
});
if (!response.ok) {
const error: ApiError = await response.json();
throw new Error(error.error ? localizeApiMessage(error.error) : translate('api.usageFailed'));
}
return response.json();
}