mirror of
https://github.com/hzrd149/nostrudel.git
synced 2025-09-25 11:13:30 +02:00
some work
This commit is contained in:
@@ -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>
|
||||
|
@@ -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");
|
||||
|
@@ -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>
|
||||
);
|
||||
}
|
||||
|
Reference in New Issue
Block a user