Skip to content

Commit

Permalink
Add some slightly nicer loading UI
Browse files Browse the repository at this point in the history
  • Loading branch information
Vafilor committed Dec 21, 2023
1 parent 4bb27dd commit f5e9e59
Show file tree
Hide file tree
Showing 8 changed files with 69 additions and 13 deletions.
2 changes: 1 addition & 1 deletion src/components/file-browser/file-browser.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ export function FileBrowser({ path: initialPath, config, className }: Props) {

export default function PathFileBrowser() {
// These values provide the initial state for the application
// It is not necessary for them to be up-to-date
// It is not necessary for them to update the FileBrowser on change, so we only get them once.
const { value: homeDirectory, loading: homeDirectoryLoading } = useAwaitValue(() => FileSystemClient.instance.getUserHomeDirectory());
const { value: config, loading: configLoading } = useAwaitValue(() => Configuration.instance.getOptions());

Expand Down
4 changes: 2 additions & 2 deletions src/components/file-list/icon-image.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import useAwaitValue from "app/hooks/useAwaitValue";
import FileSystemClient from "app/services/filesystem-client";
import ImageFile from "../file-view/image-file";
import Rectangle from "../loading/rectangle";

type Props = Omit<
React.DetailedHTMLProps<React.ImgHTMLAttributes<HTMLImageElement>, HTMLImageElement>,
Expand All @@ -9,9 +10,8 @@ type Props = Omit<
export default function IconImage({ src, width, height, ...otherProps }: Props) {
const { value: cachedImagePath, loading, error } = useAwaitValue(() => FileSystemClient.instance.getImageIconPath(src, width, height));

// TODO loading UI
if (loading) {
return <div>loading</div>;
return <Rectangle width={width} height={height} />
}

if (error) {
Expand Down
9 changes: 6 additions & 3 deletions src/components/file-view/file-view.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ import useAwaitValue from "app/hooks/useAwaitValue";
import FileSystemClient from "app/services/filesystem-client";
import VideoFile from "./video-file";
import Layout from "./layout";
import PathClient from "app/services/path";
import HeicImageFile from "./heic-image-file";
import Rectangle from "../loading/rectangle";

interface Props {
file: AppFile;
Expand Down Expand Up @@ -64,9 +64,12 @@ export default function FileView({ file: partialFile }: Props) {
);
}

// TODO better loading UI
if (loading || !file) {
return <div>Loading</div>;
return (
<Layout>
<Rectangle />
</Layout>
);
}

if (!viewLargeFile && isTooBig(file.size)) {
Expand Down
23 changes: 18 additions & 5 deletions src/components/file-view/text-file.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,32 @@
import FileSystemClient from "app/services/filesystem-client";
import useAwaitValue from "app/hooks/useAwaitValue";
import { AppFile } from "app/types/filesystem";
import { RectangleList } from "../loading/rectangle-list";
import { useWindowSize } from "@uidotdev/usehooks";
import { useMemo } from "react";

interface Props {
file: AppFile;
}

const HEIGHT = 12;
const GAP = 10;

export default function TextFile({ file }: Props) {
const { value: content, loading } = useAwaitValue(
() => FileSystemClient.instance.getTextFileContext(file.path)
);
const { value: content, loading } = useAwaitValue(() => FileSystemClient.instance.getTextFileContext(file.path));

const { height: windowHeight } = useWindowSize();
const count = useMemo(() => {
if (windowHeight === null) {
return 10;
}

// Rough calculation to make sure we have nough bars to cover the ui
return Math.max(10, Math.floor((windowHeight - 40) / (HEIGHT + GAP)));
}, [windowHeight]);

// TODO better loading ui
if (loading) {
return <div>Loading</div>;
return <RectangleList width="100%" height={HEIGHT} count={count} gap={GAP} />
}

return (
Expand Down
19 changes: 19 additions & 0 deletions src/components/loading/rectangle-list.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import Rectangle from "./rectangle";

interface Props {
width?: number | string;
height?: number | string;
count: number;
gap: number;
className?: string;
}

export function RectangleList({ width, height, count, gap, className }: Props) {
return (
<div className={"flex flex-col" + (className || "")} style={{ gap, width }}>
{(new Array(count).fill(0)).map((_, index) => (
<Rectangle key={index} width={width} height={height} />
))}
</div>
);
}
11 changes: 11 additions & 0 deletions src/components/loading/rectangle.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
interface Props {
width?: number | string;
height?: number | string;
}

export default function Rectangle({ width, height }: Props) {
return (
<div className="animate-pulse rounded bg-slate-200" style={{ width, height }}>
</div>
);
}
9 changes: 7 additions & 2 deletions src/server/image.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,13 @@ export async function createIcon(inputPath: string, outputPath: string, width: n
const inputBuffer = await readFile(inputPath);
const { data, width: imageWidth, height: imageHeight } = await decode({ buffer: inputBuffer });

// TODO 4 is a guess - need to validate
await sharp(data, { raw: { width: imageWidth, height: imageHeight, channels: 4 } }).resize(width, height).jpeg().toFile(outputPath);
// data is returned as type ImageData, which has 4 channels RGBA
// https://github.com/catdad-experiments/heic-decode
// "When the images are decoded, the return value is a plain object in the format of ImageData"
// https://developer.mozilla.org/en-US/docs/Web/API/ImageData/data
await sharp(data, {
raw: { width: imageWidth, height: imageHeight, channels: 4 }
}).resize(width, height).jpeg().toFile(outputPath);
} else {
await sharp(inputPath).resize(width, height).jpeg().toFile(outputPath);
}
Expand Down
5 changes: 5 additions & 0 deletions src/utils/sleep.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export default function sleep(milliseconds: number): Promise<void> {
return new Promise<void>((resolve) => {
setTimeout(() => resolve(), milliseconds);
});
}

0 comments on commit f5e9e59

Please sign in to comment.