storage bar changes/file kinds loader

This commit is contained in:
myung03 2024-06-26 16:28:20 -07:00
parent 4735adcb66
commit 45e54f33ee
5 changed files with 118 additions and 97 deletions

View file

@ -5,7 +5,7 @@ import { motion } from 'framer-motion';
import React, { MouseEventHandler, useCallback, useEffect, useRef, useState } from 'react';
import { useNavigate } from 'react-router';
import { KindStatistic, uint32ArrayToBigInt, useLibraryQuery } from '@sd/client';
import { Card, Tooltip } from '@sd/ui';
import { Card, Loader, Tooltip } from '@sd/ui';
import { useIsDark, useLocale } from '~/hooks';
const INFO_ICON_CLASSLIST =
@ -71,7 +71,7 @@ const FileKindStats: React.FC<FileKindStatsProps> = () => {
const isDark = useIsDark();
const navigate = useNavigate();
const { t } = useLocale();
const { data } = useLibraryQuery(['library.kindStatistics']);
const { data, isLoading } = useLibraryQuery(['library.kindStatistics']);
const [fileKinds, setFileKinds] = useState<FileKind[]>([]);
const [cardWidth, setCardWidth] = useState<number>(0);
const containerRef = useRef<HTMLDivElement>(null);
@ -182,90 +182,110 @@ const FileKindStats: React.FC<FileKindStatsProps> = () => {
ref={containerRef}
className="max-w-1/2 group mx-1 flex h-[220px] w-full min-w-[400px] shrink-0 flex-col gap-2 bg-app-box/50"
>
<div className={TOTAL_FILES_CLASSLIST}>
<Tooltip className="flex items-center" label={t('bar_graph_info')}>
<div className="flex items-center gap-2">
<span
className={clsx(
'text-xl font-black',
isDark ? 'text-white' : 'text-black'
)}
>
{data?.total_identified_files
? formatNumberWithCommas(data.total_identified_files)
: '0'}{' '}
</span>
<div className="flex items-center">
{t('total_files')}
<Info weight="fill" className={INFO_ICON_CLASSLIST} />
{isLoading ? (
<>
<div className="m-auto flex flex-col items-center justify-center gap-5">
<Loader />
<p className="text-m font-medium text-ink-faint">
Calculating file kinds...
</p>
</div>
</>
) : (
<>
<div className={TOTAL_FILES_CLASSLIST}>
<Tooltip className="flex items-center" label={t('bar_graph_info')}>
<div className="flex items-center gap-2">
<span
className={clsx(
'text-xl font-black',
isDark ? 'text-white' : 'text-black'
)}
>
{data?.total_identified_files
? formatNumberWithCommas(data.total_identified_files)
: '0'}{' '}
</span>
<div className="flex items-center">
{t('total_files')}
<Info weight="fill" className={INFO_ICON_CLASSLIST} />
</div>
</div>
</Tooltip>
<div className={UNIDENTIFIED_FILES_CLASSLIST}>
<Tooltip label={t('unidentified_files_info')}>
<span>
{data?.total_unidentified_files
? formatNumberWithCommas(data.total_unidentified_files)
: '0'}{' '}
unidentified files
</span>
</Tooltip>
</div>
</div>
</Tooltip>
<div className={UNIDENTIFIED_FILES_CLASSLIST}>
<Tooltip label={t('unidentified_files_info')}>
<span>
{data?.total_unidentified_files
? formatNumberWithCommas(data.total_unidentified_files)
: '0'}{' '}
unidentified files
</span>
</Tooltip>
</div>
</div>
<div className={BARS_CONTAINER_CLASSLIST}>
{sortedFileKinds.map((fileKind, index) => {
const iconImage = iconsRef.current[fileKind.kind];
const barColor = interpolateHexColor(
BAR_COLOR_START,
BAR_COLOR_END,
index / (barCount - 1)
);
<div className={BARS_CONTAINER_CLASSLIST}>
{sortedFileKinds.map((fileKind, index) => {
const iconImage = iconsRef.current[fileKind.kind];
const barColor = interpolateHexColor(
BAR_COLOR_START,
BAR_COLOR_END,
index / (barCount - 1)
);
const barHeight =
mapFractionalValue(fileKind.count, maxFileCount, BAR_MAX_HEIGHT) + 'px';
return (
<>
<Tooltip
asChild
key={fileKind.kind}
label={
formatNumberWithCommas(fileKind.count) +
' ' +
fileKind.kind +
's'
}
position="left"
>
<div
className="relative flex w-full min-w-8 max-w-10 grow cursor-pointer flex-col items-center"
onDoubleClick={makeBarClickHandler(fileKind)}
>
{iconImage && (
<img
src={iconImage.src}
alt={fileKind.kind}
className="relative mb-1 size-4 duration-500"
/>
)}
<motion.div
className="flex w-full flex-col items-center rounded transition-all duration-500"
initial={{ height: 0 }}
animate={{ height: barHeight }}
transition={{ duration: 0.4, ease: [0.42, 0, 0.58, 1] }}
style={{
height: barHeight,
backgroundColor: barColor
}}
></motion.div>
</div>
</Tooltip>
<div className="sm col-span-1 row-start-2 row-end-auto text-center text-[10px] font-medium text-ink-faint">
{formatCount(fileKind.count)}
</div>
</>
);
})}
</div>
const barHeight =
mapFractionalValue(
fileKind.count,
maxFileCount,
BAR_MAX_HEIGHT
) + 'px';
return (
<>
<Tooltip
asChild
key={fileKind.kind}
label={
formatNumberWithCommas(fileKind.count) +
' ' +
fileKind.kind +
's'
}
position="left"
>
<div
className="relative flex w-full min-w-8 max-w-10 grow cursor-pointer flex-col items-center"
onDoubleClick={makeBarClickHandler(fileKind)}
>
{iconImage && (
<img
src={iconImage.src}
alt={fileKind.kind}
className="relative mb-1 size-4 duration-500"
/>
)}
<motion.div
className="flex w-full flex-col items-center rounded transition-all duration-500"
initial={{ height: 0 }}
animate={{ height: barHeight }}
transition={{
duration: 0.4,
ease: [0.42, 0, 0.58, 1]
}}
style={{
height: barHeight,
backgroundColor: barColor
}}
></motion.div>
</div>
</Tooltip>
<div className="sm col-span-1 row-start-2 row-end-auto text-center text-[10px] font-medium text-ink-faint">
{formatCount(fileKind.count)}
</div>
</>
);
})}
</div>
</>
)}
</Card>
</div>
);

View file

@ -86,18 +86,18 @@ const LibraryStats = () => {
const StatItemNames: Partial<Record<keyof Statistics, string>> = {
total_library_bytes: t('library_bytes'),
total_local_bytes_capacity: t('total_bytes_capacity'),
total_local_bytes_free: t('total_bytes_free'),
library_db_size: t('library_db_size'),
total_library_preview_media_bytes: t('preview_media_bytes')
total_library_preview_media_bytes: t('preview_media_bytes'),
total_local_bytes_capacity: t('total_bytes_capacity'),
total_local_bytes_free: t('total_bytes_free')
};
const StatDescriptions: Partial<Record<keyof Statistics, string>> = {
total_library_bytes: t('library_bytes_description'),
total_local_bytes_capacity: t('total_bytes_capacity_description'),
total_local_bytes_free: t('total_bytes_free_description'),
library_db_size: t('library_db_size_description'),
total_library_preview_media_bytes: t('preview_media_bytes_description')
total_library_preview_media_bytes: t('preview_media_bytes_description'),
total_local_bytes_capacity: t('total_bytes_capacity_description'),
total_local_bytes_free: t('total_bytes_free_description')
};
const displayableStatItems = Object.keys(
@ -113,6 +113,7 @@ const LibraryStats = () => {
const totalUsedSpace = Number(statistics.total_local_bytes_used);
// Define the major categories and aggregate the "Other" category
// TODO: edit to use library size as total capacity and split bar into major categories without system data
const majorCategories = ['Document', 'Text', 'Image', 'Video'];
const aggregatedData = (storageBarData ?? []).reduce(
(acc, curr) => {
@ -165,7 +166,7 @@ const LibraryStats = () => {
return (
<Card className="flex h-[220px] w-[750px] shrink-0 flex-col bg-app-box/50">
<div className="mb-1 flex overflow-hidden p-4">
<div className="flex overflow-hidden p-4">
{Object.entries(statistics)
.sort(
([a], [b]) =>

View file

@ -3,7 +3,7 @@ import { humanizeSize } from '@sd/client';
import { Tooltip } from '@sd/ui';
import { useIsDark } from '~/hooks';
const BARWIDTH = 700;
const BARWIDTH = 750;
const lightenColor = (color: string, percent: number) => {
const num = parseInt(color.replace('#', ''), 16);
@ -109,7 +109,7 @@ const StorageBar: React.FC<StorageBarProps> = ({ sections, totalSpace }) => {
{sections.map((section, index) => (
<Tooltip key={index} label={section.tooltip} position="top">
<div
className="mb-2 mr-6 flex items-center"
className="mb-2 mr-8 flex items-center"
onMouseEnter={() => setHoveredSectionIndex(index)}
onMouseLeave={() => setHoveredSectionIndex(null)}
>

View file

@ -715,7 +715,7 @@
"toggle_sidebar": "تبديل الشريط الجانبي",
"tools": "أدوات",
"total_bytes_capacity": "Total capacity",
"total_bytes_capacity_description": "The total capacity of all nodes connected to the library. May show incorrect values during alpha.",
"total_bytes_capacity_description": "The total capacity of the current nodes connected to the library. May show incorrect values during alpha.",
"total_bytes_free": "Free space",
"total_bytes_free_description": "Free space available on all nodes connected to the library.",
"total_bytes_used": "Total used space",

View file

@ -707,10 +707,10 @@
"toggle_quick_preview": "Toggle quick preview",
"toggle_sidebar": "Toggle sidebar",
"tools": "Tools",
"total_bytes_capacity": "Total capacity",
"total_bytes_capacity_description": "The total capacity of all nodes connected to the library. May show incorrect values during alpha.",
"total_bytes_free": "Free space",
"total_bytes_free_description": "Free space available on all nodes connected to the library.",
"total_bytes_capacity": "Total local capacity",
"total_bytes_capacity_description": "The total capacity the current node. May show incorrect values during alpha.",
"total_bytes_free": "Free local space",
"total_bytes_free_description": "Free space available on the current node.",
"total_bytes_used": "Total used space",
"total_bytes_used_description": "Total space used on all nodes connected to the library.",
"total_files": "Total files",