mirror of
https://github.com/BrenBroZAYT/gameyfin.git
synced 2026-06-16 16:20:04 +00:00
Minor layout fixes for ScanProgressPopover
This commit is contained in:
@@ -10,25 +10,42 @@ import {
|
|||||||
Spinner
|
Spinner
|
||||||
} from "@heroui/react";
|
} from "@heroui/react";
|
||||||
import {useSnapshot} from "valtio/react";
|
import {useSnapshot} from "valtio/react";
|
||||||
import {clear, scanState} from "Frontend/state/ScanState";
|
import {scanState} from "Frontend/state/ScanState";
|
||||||
import LibraryScanProgress from "Frontend/generated/de/grimsi/gameyfin/libraries/dto/LibraryScanProgress";
|
import LibraryScanProgress from "Frontend/generated/de/grimsi/gameyfin/libraries/dto/LibraryScanProgress";
|
||||||
import {libraryState} from "Frontend/state/LibraryState";
|
import {libraryState} from "Frontend/state/LibraryState";
|
||||||
import {Target} from "@phosphor-icons/react";
|
import {Target} from "@phosphor-icons/react";
|
||||||
import {timeUntil} from "Frontend/util/utils";
|
import {timeBetween, timeUntil} from "Frontend/util/utils";
|
||||||
import LibraryScanStatus from "Frontend/generated/de/grimsi/gameyfin/libraries/dto/LibraryScanStatus";
|
import LibraryScanStatus from "Frontend/generated/de/grimsi/gameyfin/libraries/dto/LibraryScanStatus";
|
||||||
|
import {useEffect, useState} from "react";
|
||||||
|
|
||||||
export default function ScanProgressPopover() {
|
export default function ScanProgressPopover() {
|
||||||
const libraries = useSnapshot(libraryState).state;
|
const libraries = useSnapshot(libraryState).state;
|
||||||
const scans = useSnapshot(scanState).sortedByStartTime as LibraryScanProgress[];
|
const scans = useSnapshot(scanState).sortedByStartTime as LibraryScanProgress[];
|
||||||
const scanInProgress = useSnapshot(scanState).isScanning;
|
const scanInProgress = useSnapshot(scanState).isScanning;
|
||||||
|
|
||||||
|
// Add state to track current time and force re-renders
|
||||||
|
const [currentTime, setCurrentTime] = useState(Date.now());
|
||||||
|
|
||||||
|
// Set up an interval to update the time every second
|
||||||
|
useEffect(() => {
|
||||||
|
const intervalId = setInterval(() => {
|
||||||
|
setCurrentTime(Date.now());
|
||||||
|
}, 1000);
|
||||||
|
|
||||||
|
// Clean up the interval when component unmounts
|
||||||
|
return () => clearInterval(intervalId);
|
||||||
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Popover placement="bottom-end" showArrow={true}>
|
<Popover placement="bottom-end" showArrow={true}>
|
||||||
<PopoverTrigger>
|
<PopoverTrigger>
|
||||||
<Button isIconOnly variant="light">
|
<Button isIconOnly variant="light">
|
||||||
{scanInProgress ?
|
{scanInProgress ?
|
||||||
<Spinner size="sm" color="default" variant="simple"/> :
|
<Spinner size="sm" color="default" variant="spinner"
|
||||||
<Target/>
|
classNames={{
|
||||||
|
spinnerBars: "bg-foreground-500",
|
||||||
|
}}/> :
|
||||||
|
<Target className="fill-foreground-500"/>
|
||||||
}
|
}
|
||||||
</Button>
|
</Button>
|
||||||
</PopoverTrigger>
|
</PopoverTrigger>
|
||||||
@@ -36,56 +53,56 @@ export default function ScanProgressPopover() {
|
|||||||
<div className="flex flex-col gap-2 m-2 w-96">
|
<div className="flex flex-col gap-2 m-2 w-96">
|
||||||
{scans.length === 0 ?
|
{scans.length === 0 ?
|
||||||
<p className="flex h-12 items-center justify-center text-sm text-default-500">
|
<p className="flex h-12 items-center justify-center text-sm text-default-500">
|
||||||
No scans in progress.
|
No scans in progress or in history.
|
||||||
</p> :
|
</p> :
|
||||||
<div className="flex flex-col gap-4">
|
<ScrollShadow hideScrollBar className="max-h-96">
|
||||||
<Link underline="always" size="sm" href="#" onPress={clear} className="justify-end">
|
{scans.map((scan, index) =>
|
||||||
Clear
|
<div className="flex flex-col">
|
||||||
</Link>
|
<div
|
||||||
<ScrollShadow hideScrollBar className="max-h-96">
|
className="flex flex-row justify-between items-center text-default-500 mb-1">
|
||||||
{scans.map((scan, index) =>
|
<p>Scan for library
|
||||||
<div className="flex flex-col">
|
<Link underline="always"
|
||||||
<div
|
color="foreground"
|
||||||
className="flex flex-row justify-between items-center text-default-500 mb-1">
|
size="sm"
|
||||||
<p>Scan for library
|
href={`/administration/libraries/library/${scan.libraryId}`}>
|
||||||
<Link underline="always"
|
{libraries[scan.libraryId].name}
|
||||||
color="foreground"
|
</Link>
|
||||||
size="sm"
|
</p>
|
||||||
href={`/administration/libraries/library/${scan.libraryId}`}>
|
{scan.finishedAt ?
|
||||||
{libraries[scan.libraryId].name}
|
<p className="text-default-500">
|
||||||
</Link>
|
Finished {timeUntil(scan.finishedAt)}
|
||||||
</p>
|
</p> :
|
||||||
{scan.finishedAt ?
|
<p className="text-default-500">
|
||||||
<p className="text-default-500">Finished {timeUntil(scan.finishedAt)}</p> :
|
Started {timeUntil(scan.startedAt)}
|
||||||
<p className="text-default-500">Started {timeUntil(scan.startedAt)}</p>
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
{scan.status === LibraryScanStatus.IN_PROGRESS ?
|
|
||||||
scan.currentStep.current && scan.currentStep.total ?
|
|
||||||
<div>
|
|
||||||
<p className="text-default-500">
|
|
||||||
{`${scan.currentStep.description} (${scan.currentStep.current} / ${scan.currentStep.total})`}
|
|
||||||
</p>
|
|
||||||
<Progress
|
|
||||||
value={scan.currentStep.current / scan.currentStep.total * 100}
|
|
||||||
size="sm"/>
|
|
||||||
</div> :
|
|
||||||
<div>
|
|
||||||
<p className="text-default-500">{scan.currentStep.description}</p>
|
|
||||||
<Progress isIndeterminate size="sm"/>
|
|
||||||
</div>
|
|
||||||
:
|
|
||||||
<p>
|
|
||||||
{scan.result?.new} new /
|
|
||||||
{scan.result?.removed} removed /
|
|
||||||
{scan.result?.unmatched} unmatched
|
|
||||||
</p>
|
</p>
|
||||||
}
|
}
|
||||||
{scans.length > 1 && index < (scans.length - 1) && <Divider className="my-2"/>}
|
|
||||||
</div>
|
</div>
|
||||||
)}
|
{scan.status === LibraryScanStatus.IN_PROGRESS ?
|
||||||
</ScrollShadow>
|
scan.currentStep.current && scan.currentStep.total ?
|
||||||
</div>
|
<div className="flex flex-col gap-1">
|
||||||
|
<p className="text-default-500">
|
||||||
|
{`${scan.currentStep.description} (${scan.currentStep.current}/${scan.currentStep.total})`}
|
||||||
|
</p>
|
||||||
|
<Progress
|
||||||
|
value={scan.currentStep.current / scan.currentStep.total * 100}
|
||||||
|
size="sm"/>
|
||||||
|
</div> :
|
||||||
|
<div className="flex flex-col gap-1">
|
||||||
|
<p className="text-default-500">{scan.currentStep.description}</p>
|
||||||
|
<Progress isIndeterminate size="sm"/>
|
||||||
|
</div>
|
||||||
|
:
|
||||||
|
<p>
|
||||||
|
{scan.result?.new} new /
|
||||||
|
{scan.result?.removed} removed /
|
||||||
|
{scan.result?.unmatched} unmatched
|
||||||
|
(in {timeBetween(scan.startedAt, scan.finishedAt!)})
|
||||||
|
</p>
|
||||||
|
}
|
||||||
|
{scans.length > 1 && index < (scans.length - 1) && <Divider className="my-2"/>}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</ScrollShadow>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
</PopoverContent>
|
</PopoverContent>
|
||||||
|
|||||||
@@ -44,10 +44,6 @@ export function initializeScanState() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export function clear() {
|
|
||||||
scanState.state = {};
|
|
||||||
}
|
|
||||||
|
|
||||||
export function handleLibraryDeletion(libraryId: number) {
|
export function handleLibraryDeletion(libraryId: number) {
|
||||||
for (const scanId in scanState.state) {
|
for (const scanId in scanState.state) {
|
||||||
if (scanState.state[scanId].libraryId === libraryId) {
|
if (scanState.state[scanId].libraryId === libraryId) {
|
||||||
|
|||||||
Reference in New Issue
Block a user