mirror of
https://github.com/spacedriveapp/spacedrive.git
synced 2026-04-21 23:18:06 -04:00
* init * changes * Now updating statistics once a minute * More robust statistics updater * Concurrency is hard * improvements to stats * refactor * adjust setting back/forward padding so it matches top bar * refactor sidebar * rename * setting up screens * some changes * Co-authored-by: Brendan Allan <Brendonovich@users.noreply.github.com> * yes * yes2 * refactored explorerItem.ts * important explorer code shouldn't be thrown away in a util moment * support for multiple thumbnails in ExplorerItem * clippy * move debug * yes * label filters * ts * comment out unconnected stuff * added .mid for midi files --------- Co-authored-by: Ericson Fogo Soares <ericson.ds999@gmail.com> Co-authored-by: Brendan Allan <brendonovich@outlook.com>
96 lines
2.2 KiB
TypeScript
96 lines
2.2 KiB
TypeScript
import clsx from 'clsx';
|
|
import { motion } from 'framer-motion';
|
|
import { useRef } from 'react';
|
|
import { Link, useLocation } from 'react-router-dom';
|
|
import { formatNumber, SearchFilterArgs, useLibraryQuery } from '@sd/client';
|
|
import { Icon } from '~/components';
|
|
|
|
export default () => {
|
|
const ref = useRef<HTMLDivElement>(null);
|
|
|
|
const kinds = useLibraryQuery(['library.kindStatistics']);
|
|
|
|
return (
|
|
<>
|
|
{/* This is awful, will replace icons accordingly and memo etc */}
|
|
{kinds.data?.statistics
|
|
?.sort((a, b) => b.count - a.count)
|
|
.filter((i) => i.kind !== 0)
|
|
.map(({ kind, name, count }) => {
|
|
let icon = name;
|
|
switch (name) {
|
|
case 'Code':
|
|
icon = 'Terminal';
|
|
break;
|
|
case 'Unknown':
|
|
icon = 'Undefined';
|
|
break;
|
|
}
|
|
return (
|
|
<motion.div
|
|
viewport={{
|
|
root: ref,
|
|
// WARNING: Edge breaks if the values are not postfixed with px or %
|
|
margin: '0% -120px 0% 0%'
|
|
}}
|
|
className={clsx('min-w-fit')}
|
|
key={kind}
|
|
>
|
|
<KindItem
|
|
kind={kind}
|
|
name={name}
|
|
icon={icon}
|
|
items={count}
|
|
onClick={() => {}}
|
|
/>
|
|
</motion.div>
|
|
);
|
|
})}
|
|
</>
|
|
);
|
|
};
|
|
|
|
interface KindItemProps {
|
|
kind: number;
|
|
name: string;
|
|
items: number;
|
|
icon: string;
|
|
selected?: boolean;
|
|
onClick?: () => void;
|
|
disabled?: boolean;
|
|
}
|
|
|
|
const KindItem = ({ kind, name, icon, items, selected, onClick, disabled }: KindItemProps) => {
|
|
return (
|
|
<Link
|
|
to={{
|
|
pathname: '../search',
|
|
search: new URLSearchParams({
|
|
filters: JSON.stringify([
|
|
{ object: { kind: { in: [kind] } } }
|
|
] as SearchFilterArgs[])
|
|
}).toString()
|
|
}}
|
|
>
|
|
<div
|
|
onClick={onClick}
|
|
className={clsx(
|
|
'flex shrink-0 items-center rounded-lg py-1 text-sm outline-none focus:bg-app-selectedItem/50',
|
|
selected && 'bg-app-selectedItem',
|
|
disabled && 'cursor-not-allowed opacity-30'
|
|
)}
|
|
>
|
|
<Icon name={icon as any} className="mr-3 h-12 w-12" />
|
|
<div className="pr-5">
|
|
<h2 className="text-sm font-medium">{name}</h2>
|
|
{items !== undefined && (
|
|
<p className="text-xs text-ink-faint">
|
|
{formatNumber(items)} Item{(items > 1 || items === 0) && 's'}
|
|
</p>
|
|
)}
|
|
</div>
|
|
</div>
|
|
</Link>
|
|
);
|
|
};
|