1.0.0-rc2 RC2
Deploy Docs to GitHub Pages / Build Documentation (push) Has been cancelled
Deploy Docs to GitHub Pages / Deploy to GitHub Pages (push) Has been cancelled

This commit is contained in:
2026-05-21 10:19:00 +02:00
parent 9b38d78042
commit eeef1fdb73
31 changed files with 4046 additions and 1449 deletions
+32 -1
View File
@@ -13,6 +13,7 @@ import DownloadsPage from './pages/DownloadsPage';
import ConverterPage from './pages/ConverterPage';
import AudiobooksPage from './pages/AudiobooksPage';
import TmdbMigrationPage from './pages/TmdbMigrationPage';
import HardwarePage from './pages/HardwarePage';
function normalizeJobId(value) {
const parsed = Number(value);
@@ -64,6 +65,35 @@ function isTerminalStage(value) {
return normalized === 'FINISHED' || normalized === 'ERROR' || normalized === 'CANCELLED';
}
function parseTimestamp(value) {
if (!value) {
return 0;
}
const ts = Date.parse(String(value));
return Number.isFinite(ts) ? ts : 0;
}
function mergePipelineStatePreservingNewestQueue(previousPipeline, incomingPipeline) {
const prev = previousPipeline && typeof previousPipeline === 'object' ? previousPipeline : {};
const incoming = incomingPipeline && typeof incomingPipeline === 'object' ? incomingPipeline : {};
const prevQueue = prev?.queue && typeof prev.queue === 'object' ? prev.queue : null;
const incomingQueue = incoming?.queue && typeof incoming.queue === 'object' ? incoming.queue : null;
if (!prevQueue || !incomingQueue) {
return {
...prev,
...incoming
};
}
const prevQueueTs = parseTimestamp(prevQueue.updatedAt);
const incomingQueueTs = parseTimestamp(incomingQueue.updatedAt);
const queue = incomingQueueTs >= prevQueueTs ? incomingQueue : prevQueue;
return {
...prev,
...incoming,
queue
};
}
function createInitialAudiobookUploadState() {
return {
phase: 'idle',
@@ -363,7 +393,7 @@ function App() {
}
if (message.type === 'PIPELINE_STATE_CHANGED') {
setPipeline(message.payload);
setPipeline((prev) => mergePipelineStatePreservingNewestQueue(prev, message.payload));
}
if (message.type === 'PIPELINE_PROGRESS') {
@@ -705,6 +735,7 @@ function App() {
<Route path="downloads" element={<DownloadsPage refreshToken={downloadsRefreshToken} />} />
<Route path="database" element={<DatabasePage />} />
<Route path="converter" element={<ConverterPage />} />
<Route path="hardware" element={<HardwarePage hardwareMonitoring={hardwareMonitoring} />} />
<Route
path="audiobooks"
element={