some work

This commit is contained in:
hzrd149
2023-09-07 11:27:01 -05:00
parent 9c93a3d9bf
commit bd50ab2ec7
3 changed files with 85 additions and 30 deletions

View File

@@ -48,6 +48,9 @@ export default function NavItems({ isInDrawer = false }: { isInDrawer?: boolean
<Button onClick={() => navigate("/streams")} leftIcon={<LiveStreamIcon />} justifyContent="flex-start">
Streams
</Button>
<Button onClick={() => navigate("/files")} leftIcon={<FileIcon />} justifyContent="flex-start">
Files
</Button>
<Button onClick={() => navigate("/lists")} leftIcon={<ListIcon />} justifyContent="flex-start">
Lists
</Button>
@@ -57,9 +60,6 @@ export default function NavItems({ isInDrawer = false }: { isInDrawer?: boolean
<Button onClick={() => navigate("/emojis")} leftIcon={<EmojiIcon />} justifyContent="flex-start">
Emojis
</Button>
<Button onClick={() => navigate("/files")} leftIcon={<FileIcon />} justifyContent="flex-start">
Files
</Button>
<Button onClick={() => navigate("/map")} leftIcon={<MapIcon />} justifyContent="flex-start">
Map
</Button>

View File

@@ -12,8 +12,14 @@ export type ParsedImageFile = {
blurhash?: string;
};
export function parseImageFile(event: NostrEvent): ParsedImageFile {
export function getFileUrl(event: NostrEvent) {
const url = event.tags.find((t) => t[0] === "url" && t[1])?.[1];
if (!url) throw new Error("Missing url");
return url;
}
export function parseImageFile(event: NostrEvent): ParsedImageFile {
const url = getFileUrl(event);
const mimeType = event.tags.find((t) => t[0] === "m" && t[1])?.[1];
const magnet = event.tags.find((t) => t[0] === "magnet" && t[1])?.[1];
const infoHash = event.tags.find((t) => t[0] === "i" && t[1])?.[1];
@@ -24,7 +30,6 @@ export function parseImageFile(event: NostrEvent): ParsedImageFile {
const dimensions = event.tags.find((t) => t[0] === "dim" && t[1])?.[1];
const [width, height] = dimensions?.split("x").map((v) => parseInt(v)) ?? [];
if (!url) throw new Error("missing url");
if (!mimeType) throw new Error("missing MIME Type");
if (width !== undefined && height !== undefined) {
if (!Number.isFinite(width) || !Number.isFinite(height)) throw new Error("bad dimensions");

View File

@@ -20,12 +20,19 @@ import useTimelineLoader from "../../hooks/use-timeline-loader";
import { useReadRelayUrls } from "../../hooks/use-client-relays";
import useSubject from "../../hooks/use-subject";
import { NostrEvent } from "../../types/nostr-event";
import { parseImageFile } from "../../helpers/nostr/files";
import { getFileUrl, parseImageFile } from "../../helpers/nostr/files";
import BlurhashImage from "../../components/blurhash-image";
import { ErrorBoundary } from "../../components/error-boundary";
import useAppSettings from "../../hooks/use-app-settings";
import { useTrusted } from "../../providers/trust";
import { TrustProvider, useTrusted } from "../../providers/trust";
import BlurredImage from "../../components/blured-image";
import PeopleListProvider, { usePeopleListContext } from "../../providers/people-list-provider";
import RelaySelectionProvider, { useRelaySelectionContext } from "../../providers/relay-selection-provider";
import PeopleListSelection from "../../components/people-list-selection/people-list-selection";
import RelaySelectionButton from "../../components/relay-selection/relay-selection-button";
import { UserAvatar } from "../../components/user-avatar";
import { UserAvatarLink } from "../../components/user-avatar-link";
import { UserLink } from "../../components/user-link";
const FILE_KIND = 1063;
const VIDEO_TYPES = ["video/mp4", "video/webm"];
@@ -40,23 +47,45 @@ function ImageFile({ event }: { event: NostrEvent }) {
const shouldBlur = settings.blurImages && !trust;
const showImage = useDisclosure();
if (shouldBlur && parsed.blurhash && parsed.width && parsed.height && !showImage.isOpen) {
const aspect = parsed.width / parsed.height;
return (
<BlurhashImage
blurhash={parsed.blurhash}
width={64 * aspect}
height={64}
onClick={showImage.onOpen}
cursor="pointer"
w="full"
/>
);
}
// const showImage = useDisclosure();
// if (shouldBlur && parsed.blurhash && parsed.width && parsed.height && !showImage.isOpen) {
// const aspect = parsed.width / parsed.height;
// return (
// <BlurhashImage
// blurhash={parsed.blurhash}
// width={64 * aspect}
// height={64}
// onClick={showImage.onOpen}
// cursor="pointer"
// w="full"
// />
// );
// }
const ImageComponent = shouldBlur ? BlurredImage : Image;
return <ImageComponent src={parsed.url} w="full" />;
return (
<Flex direction="column" gap="2">
<Flex gap="2" alignItems="center">
<UserAvatarLink pubkey={event.pubkey} size="sm" />
<UserLink pubkey={event.pubkey} fontWeight="bold" />
</Flex>
<ImageComponent src={parsed.url} w="full" />
</Flex>
);
}
function VideoFile({ event }: { event: NostrEvent }) {
const url = getFileUrl(event);
return (
<Flex direction="column" gap="2">
<Flex gap="2" alignItems="center">
<UserAvatarLink pubkey={event.pubkey} size="sm" />
<UserLink pubkey={event.pubkey} fontWeight="bold" />
</Flex>
<video src={url} controls />
</Flex>
);
}
function FileType({ event }: { event: NostrEvent }) {
@@ -65,12 +94,22 @@ function FileType({ event }: { event: NostrEvent }) {
if (!mimeType) throw new Error("missing MIME type");
if (IMAGE_TYPES.includes(mimeType)) {
return <ImageFile event={event} />;
return (
<TrustProvider trust>
<ImageFile event={event} />
</TrustProvider>
);
}
if (VIDEO_TYPES.includes(mimeType)) {
return <VideoFile event={event} />;
}
return <Text>Unknown mine type {mimeType}</Text>;
}
export default function FilesView() {
function FilesPage() {
const { listId, filter } = usePeopleListContext();
const { relays } = useRelaySelectionContext();
const [selectedTypes, setSelectedTypes] = useState<string[]>(IMAGE_TYPES);
const toggleType = useCallback(
(type: string) => {
@@ -80,22 +119,22 @@ export default function FilesView() {
} else return arr.concat(type);
});
},
[setSelectedTypes]
[setSelectedTypes],
);
const relays = useReadRelayUrls();
const timeline = useTimelineLoader(
"files",
`${listId}-files`,
relays,
{ kinds: [FILE_KIND], "#m": selectedTypes },
{ enabled: selectedTypes.length > 0 }
{ kinds: [FILE_KIND], "#m": selectedTypes, ...filter },
{ enabled: selectedTypes.length > 0 && !!filter },
);
const events = useSubject(timeline.timeline);
return (
<Flex direction="column" gap="2" p="2">
<Flex>
<Flex gap="2">
<PeopleListSelection />
<Popover>
<PopoverTrigger>
<Button>{selectedTypes.length} Selected types</Button>
@@ -145,6 +184,7 @@ export default function FilesView() {
</PopoverBody>
</PopoverContent>
</Popover>
<RelaySelectionButton ml="auto" />
</Flex>
<SimpleGrid minChildWidth="20rem" spacing="2">
@@ -158,3 +198,13 @@ export default function FilesView() {
</Flex>
);
}
export default function FilesView() {
return (
<PeopleListProvider>
<RelaySelectionProvider>
<FilesPage />
</RelaySelectionProvider>
</PeopleListProvider>
);
}