Add support for Lottie stickers and enhance disk space API endpoint

- Introduced Lottie sticker component with placeholder handling in DiscordLogs.
- Expanded Discord message types in DiscordLogs component.
- Implemented disk space fetching in MediaRequestForm with visual indicator.
- Enhanced API for fetching Discord messages to include Lottie data for stickers.
- Added disk space API endpoint with authentication and authorization checks.
This commit is contained in:
2025-12-19 10:26:22 -05:00
parent 2cc07b6cc2
commit 95a59e9395
7 changed files with 509 additions and 55 deletions

View File

@@ -34,6 +34,7 @@ export default function MediaRequestForm() {
const [albumPlaybackLoadingId, setAlbumPlaybackLoadingId] = useState(null);
const [shuffleAlbums, setShuffleAlbums] = useState({});
const [audioProgress, setAudioProgress] = useState({ current: 0, duration: 0 });
const [diskSpace, setDiskSpace] = useState(null);
const debounceTimeout = useRef(null);
const autoCompleteRef = useRef(null);
@@ -64,6 +65,22 @@ export default function MediaRequestForm() {
lastUrlRef.current = window.location.pathname + window.location.search + window.location.hash;
}, []);
// Fetch disk space on mount
useEffect(() => {
const fetchDiskSpace = async () => {
try {
const res = await fetch('/api/disk-space');
if (res.ok) {
const data = await res.json();
setDiskSpace(data);
}
} catch (err) {
console.error('Failed to fetch disk space:', err);
}
};
fetchDiskSpace();
}, []);
useEffect(() => {
if (typeof window === "undefined") return undefined;
@@ -999,6 +1016,32 @@ export default function MediaRequestForm() {
}
`}</style>
<BreadcrumbNav currentPage="request" />
{/* Disk Space Indicator - always visible */}
{diskSpace && (
<div className="mb-4 flex items-center gap-2 text-xs text-neutral-500 dark:text-neutral-400">
<svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M4 7v10c0 2 1 3 3 3h10c2 0 3-1 3-3V7c0-2-1-3-3-3H7c-2 0-3 1-3 3z" />
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M8 7V5c0-1 .5-2 2-2h4c1.5 0 2 1 2 2v2" />
</svg>
<span>
<span className={`font-medium ${
diskSpace.usedPercent > 90 ? 'text-red-500' :
diskSpace.usedPercent > 75 ? 'text-yellow-500' : 'text-green-600 dark:text-green-400'
}`}>{diskSpace.availableFormatted}</span> available
</span>
<div className="w-20 h-1.5 bg-neutral-200 dark:bg-neutral-700 rounded-full overflow-hidden">
<div
className={`h-full rounded-full ${diskSpace.usedPercent > 90 ? 'bg-red-500' :
diskSpace.usedPercent > 75 ? 'bg-yellow-500' : 'bg-green-500'
}`}
style={{ width: `${diskSpace.usedPercent}%` }}
/>
</div>
<span className="text-neutral-400">({diskSpace.usedPercent}% used)</span>
</div>
)}
<h2 className="text-2xl sm:text-3xl font-bold tracking-tight mb-2">New Request</h2>
<p className="text-neutral-500 dark:text-neutral-400 text-sm mb-6">Search for an artist to browse and select tracks for download.</p>
<div className="flex flex-col gap-6">
@@ -1283,8 +1326,8 @@ export default function MediaRequestForm() {
);
})}
</Accordion>
<div className="flex justify-end">
<Button onClick={handleSubmitRequest} color="primary" className="mt-4" disabled={isSubmitting}>
<div className="flex justify-end mt-4">
<Button onClick={handleSubmitRequest} color="primary" disabled={isSubmitting}>
{isSubmitting ? (
<span className="flex items-center gap-2">
<span className="animate-spin h-4 w-4 border-2 border-t-2 border-gray-200 border-t-primary rounded-full"></span>