Skip to content

Commit

Permalink
feat: add live preview
Browse files Browse the repository at this point in the history
  • Loading branch information
d0kur0 committed Jan 29, 2024
1 parent 4c66864 commit 9237940
Show file tree
Hide file tree
Showing 3 changed files with 100 additions and 11 deletions.
60 changes: 52 additions & 8 deletions src/components/FilePreview.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import { Box, Spinner } from "@hope-ui/solid";
import { createEffect, createMemo, createSignal } from "solid-js";
import { Match, Switch, createEffect, createMemo, createSignal } from "solid-js";
import { ExtendedFile, isFileImage } from "../utils/grabbing";
import { JSX } from "solid-js";
import { useStore } from "@nanostores/solid";
import { $hoverPreview } from "../stores/settings";

type FilePreviewProps = {
file: ExtendedFile;
Expand Down Expand Up @@ -35,6 +37,8 @@ const badgeStyles = {
};

export function FilePreview(props: FilePreviewProps) {
const hoverPreview = useStore($hoverPreview);

const [isInViewport, setIsInViewport] = createSignal(true);

const isImage = createMemo(() => isFileImage(props.file));
Expand All @@ -44,6 +48,7 @@ export function FilePreview(props: FilePreviewProps) {

const [isLoading, setIsLoading] = createSignal(true);
const [isLoadingFailed, setIsLoadingFailed] = createSignal(false);
const [isHovered, setIsHovered] = createSignal(false);

let rootRef: HTMLDivElement;

Expand All @@ -64,8 +69,20 @@ export function FilePreview(props: FilePreviewProps) {
return () => observer.disconnect();
});

const onMouseEnter = () => {
if (!hoverPreview()) return;
setIsHovered(true);
};

const onMouseLeave = () => {
if (!hoverPreview()) return;
setIsHovered(false);
};

return (
<Box
onMouseEnter={onMouseEnter}
onMouseLeave={onMouseLeave}
ref={rootRef!}
css={{ "aspect-ratio": `${width()}/${height()}`, padding: "10px" }}
onClick={props.onOpen}
Expand Down Expand Up @@ -116,13 +133,40 @@ export function FilePreview(props: FilePreviewProps) {
</Box>
</Box>

<img
src={props.file.previewUrl}
alt="preview image"
style={mediaElementStyles}
onLoad={() => setIsLoading(false)}
onError={() => setIsLoadingFailed(true)}
/>
<Switch>
<Match when={isHovered()}>
<Switch>
<Match when={isImage()}>
<img
src={props.file.url}
alt="preview image"
style={mediaElementStyles}
onLoad={() => setIsLoading(false)}
onError={() => setIsLoadingFailed(true)}
/>
</Match>
<Match when={!isImage()}>
<video
ref={(v) => (v.volume = 0)}
src={props.file.url}
autoplay
style={mediaElementStyles}
onLoad={() => setIsLoading(false)}
onError={() => setIsLoadingFailed(true)}
/>
</Match>
</Switch>
</Match>
<Match when={!isHovered()}>
<img
src={props.file.previewUrl}
alt="preview image"
style={mediaElementStyles}
onLoad={() => setIsLoading(false)}
onError={() => setIsLoadingFailed(true)}
/>
</Match>
</Switch>

{isLoading() && (
<Box css={centerPositionStyles}>
Expand Down
36 changes: 33 additions & 3 deletions src/pages/PageListFiles.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,13 @@
import { Box, Heading, Anchor, Tooltip, Button, ButtonGroup, notificationService } from "@hope-ui/solid";
import {
Box,
Heading,
Anchor,
Tooltip,
Button,
ButtonGroup,
notificationService,
Switch,
} from "@hope-ui/solid";
import { createMemo, createSignal } from "solid-js";
import { useStore } from "@nanostores/solid";
import { $filteredFiles, $threads } from "../stores/media";
Expand All @@ -9,11 +18,13 @@ import { createMasonryBreakpoints, Mason } from "solid-mason";
import { FilePreview } from "../components/FilePreview";
import { ImBlocked, ImEyeBlocked } from "solid-icons/im";
import { $excludeRulesMutations } from "../stores/excludeRules";
import { $hoverPreview, $hoverPreviewActions } from "../stores/settings";

const PAGE_LIMIT = 70;

export function PageListFiles() {
const { board, threadId } = useParams();
const hoverPreview = useStore($hoverPreview);

const files = useStore($filteredFiles);
const threads = useStore($threads);
Expand Down Expand Up @@ -100,8 +111,27 @@ export function PageListFiles() {
/>
)}

<Heading css={{ mb: 12, whiteSpace: "nowrap", textOverflow: "ellipsis", overflow: "hidden" }}>
{threadId ? thread()?.subject : "Список файлов"}
<Heading
css={{
mb: 12,
display: "flex",
overflow: "hidden",
alignItems: "top",
whiteSpace: "nowrap",
textOverflow: "ellipsis",
}}
>
<Box css={{ flex: "1 1 0" }}>{threadId ? thread()?.subject : "Список файлов"}</Box>
<Box css={{ mb: 12, display: "flex", alignItems: "center", gap: 6 }}>
<Switch
size="sm"
checked={hoverPreview()}
onChange={$hoverPreviewActions.toggle}
colorScheme="accent"
>
Live preview
</Switch>
</Box>
</Heading>

{threadId && (
Expand Down
15 changes: 15 additions & 0 deletions src/stores/settings.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { atom } from "nanostores";

export const $hoverPreview = atom(localStorage.disableHoverPreview === undefined ? true : false);

export const $hoverPreviewActions = {
toggle() {
const enabled = $hoverPreview.get();

enabled
? localStorage.setItem("disableHoverPreview", "true")
: localStorage.removeItem("disableHoverPreview");

$hoverPreview.set(!enabled);
},
};

0 comments on commit 9237940

Please sign in to comment.