mirror of
https://github.com/hzrd149/nostrudel.git
synced 2025-04-09 20:29:17 +02:00
Blur videos from strangers
Use nevent instead of note1 in urls
This commit is contained in:
parent
ead0d512df
commit
a714a2c621
5
.changeset/poor-dogs-look.md
Normal file
5
.changeset/poor-dogs-look.md
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
"nostrudel": minor
|
||||||
|
---
|
||||||
|
|
||||||
|
Use nevent instead of note1 in urls
|
5
.changeset/stupid-trees-tan.md
Normal file
5
.changeset/stupid-trees-tan.md
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
"nostrudel": minor
|
||||||
|
---
|
||||||
|
|
||||||
|
Blur videos from strangers
|
@ -1,21 +1,8 @@
|
|||||||
import { Link } from "@chakra-ui/react";
|
import { Link } from "@chakra-ui/react";
|
||||||
|
|
||||||
import OpenGraphCard from "../open-graph-card";
|
import OpenGraphCard from "../open-graph-card";
|
||||||
import { isVideoURL } from "../../helpers/url";
|
|
||||||
import OpenGraphLink from "../open-graph-link";
|
import OpenGraphLink from "../open-graph-link";
|
||||||
|
|
||||||
export function renderVideoUrl(match: URL) {
|
|
||||||
if (!isVideoURL(match)) return null;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<video
|
|
||||||
src={match.toString()}
|
|
||||||
controls
|
|
||||||
style={{ maxWidth: "30rem", maxHeight: "20rem", width: "100%", position: "relative", zIndex: 1 }}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function renderGenericUrl(match: URL) {
|
export function renderGenericUrl(match: URL) {
|
||||||
return (
|
return (
|
||||||
<Link href={match.toString()} isExternal color="blue.500">
|
<Link href={match.toString()} isExternal color="blue.500">
|
||||||
|
@ -1,12 +1,10 @@
|
|||||||
import {
|
import {
|
||||||
CSSProperties,
|
|
||||||
MouseEventHandler,
|
MouseEventHandler,
|
||||||
MutableRefObject,
|
MutableRefObject,
|
||||||
forwardRef,
|
forwardRef,
|
||||||
useCallback,
|
useCallback,
|
||||||
useMemo,
|
useMemo,
|
||||||
useRef,
|
useRef,
|
||||||
useState,
|
|
||||||
} from "react";
|
} from "react";
|
||||||
import { Image, ImageProps, Link, LinkProps } from "@chakra-ui/react";
|
import { Image, ImageProps, Link, LinkProps } from "@chakra-ui/react";
|
||||||
|
|
||||||
@ -20,25 +18,7 @@ import PhotoGallery, { PhotoWithoutSize } from "../photo-gallery";
|
|||||||
import { NostrEvent } from "../../types/nostr-event";
|
import { NostrEvent } from "../../types/nostr-event";
|
||||||
import useAppSettings from "../../hooks/use-app-settings";
|
import useAppSettings from "../../hooks/use-app-settings";
|
||||||
import { useBreakpointValue } from "../../providers/breakpoint-provider";
|
import { useBreakpointValue } from "../../providers/breakpoint-provider";
|
||||||
|
import useElementBlur from "../../hooks/use-element-blur";
|
||||||
function useElementBlur(initBlur = false): { style: CSSProperties; onClick: MouseEventHandler } {
|
|
||||||
const [blur, setBlur] = useState(initBlur);
|
|
||||||
|
|
||||||
const onClick = useCallback<MouseEventHandler>(
|
|
||||||
(e) => {
|
|
||||||
if (blur) {
|
|
||||||
e.stopPropagation();
|
|
||||||
e.preventDefault();
|
|
||||||
setBlur(false);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
[blur],
|
|
||||||
);
|
|
||||||
|
|
||||||
const style: CSSProperties = blur ? { filter: "blur(1.5rem)", cursor: "pointer" } : {};
|
|
||||||
|
|
||||||
return { onClick, style };
|
|
||||||
}
|
|
||||||
|
|
||||||
export type TrustImageProps = ImageProps;
|
export type TrustImageProps = ImageProps;
|
||||||
|
|
||||||
|
@ -7,3 +7,4 @@ export * from "./nostr";
|
|||||||
export * from "./emoji";
|
export * from "./emoji";
|
||||||
export * from "./image";
|
export * from "./image";
|
||||||
export * from "./cashu";
|
export * from "./cashu";
|
||||||
|
export * from "./video";
|
||||||
|
35
src/components/embed-types/video.tsx
Normal file
35
src/components/embed-types/video.tsx
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
import styled from "@emotion/styled";
|
||||||
|
import { isVideoURL } from "../../helpers/url";
|
||||||
|
import useAppSettings from "../../hooks/use-app-settings";
|
||||||
|
import useElementBlur from "../../hooks/use-element-blur";
|
||||||
|
import { useTrusted } from "../../providers/trust";
|
||||||
|
|
||||||
|
const StyledVideo = styled.video`
|
||||||
|
max-width: 30rem;
|
||||||
|
max-height: 20rem;
|
||||||
|
width: 100%;
|
||||||
|
position: relative;
|
||||||
|
z-index: 1;
|
||||||
|
`;
|
||||||
|
|
||||||
|
function TrustVideo({ src }: { src: string }) {
|
||||||
|
const { blurImages } = useAppSettings();
|
||||||
|
const trusted = useTrusted();
|
||||||
|
const { onClick, handleEvent, style } = useElementBlur(!trusted);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<StyledVideo
|
||||||
|
src={src}
|
||||||
|
controls
|
||||||
|
style={blurImages ? style : undefined}
|
||||||
|
onClick={blurImages ? onClick : undefined}
|
||||||
|
onPlay={blurImages ? handleEvent : undefined}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function renderVideoUrl(match: URL) {
|
||||||
|
if (!isVideoURL(match)) return null;
|
||||||
|
|
||||||
|
return <TrustVideo src={match.toString()} />;
|
||||||
|
}
|
34
src/hooks/use-element-blur.ts
Normal file
34
src/hooks/use-element-blur.ts
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
import { CSSProperties, EventHandler, MouseEventHandler, ReactEventHandler, useCallback, useState } from "react";
|
||||||
|
|
||||||
|
export default function useElementBlur(initBlur = false): {
|
||||||
|
style: CSSProperties;
|
||||||
|
onClick: MouseEventHandler;
|
||||||
|
handleEvent: ReactEventHandler<HTMLElement>;
|
||||||
|
} {
|
||||||
|
const [blur, setBlur] = useState(initBlur);
|
||||||
|
|
||||||
|
const onClick = useCallback<MouseEventHandler>(
|
||||||
|
(e) => {
|
||||||
|
if (blur) {
|
||||||
|
e.stopPropagation();
|
||||||
|
e.preventDefault();
|
||||||
|
setBlur(false);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[blur],
|
||||||
|
);
|
||||||
|
const handleEvent = useCallback<ReactEventHandler<HTMLElement>>(
|
||||||
|
(e) => {
|
||||||
|
if (blur) {
|
||||||
|
e.stopPropagation();
|
||||||
|
e.preventDefault();
|
||||||
|
setBlur(false);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[blur],
|
||||||
|
);
|
||||||
|
|
||||||
|
const style: CSSProperties = blur ? { filter: "blur(1.5rem)", cursor: "pointer" } : {};
|
||||||
|
|
||||||
|
return { onClick, handleEvent, style };
|
||||||
|
}
|
@ -11,7 +11,6 @@ import {
|
|||||||
useColorMode,
|
useColorMode,
|
||||||
useDisclosure,
|
useDisclosure,
|
||||||
} from "@chakra-ui/react";
|
} from "@chakra-ui/react";
|
||||||
import { nip19 } from "nostr-tools";
|
|
||||||
import { Link as RouterLink } from "react-router-dom";
|
import { Link as RouterLink } from "react-router-dom";
|
||||||
|
|
||||||
import { ReplyIcon } from "../../../components/icons";
|
import { ReplyIcon } from "../../../components/icons";
|
||||||
@ -39,6 +38,7 @@ import { UserDnsIdentityIcon } from "../../../components/user-dns-identity-icon"
|
|||||||
import NoteProxyLink from "../../../components/note/components/note-proxy-link";
|
import NoteProxyLink from "../../../components/note/components/note-proxy-link";
|
||||||
import { NoteDetailsButton } from "../../../components/note/components/note-details-button";
|
import { NoteDetailsButton } from "../../../components/note/components/note-details-button";
|
||||||
import EventInteractionDetailsModal from "../../../components/event-interactions-modal";
|
import EventInteractionDetailsModal from "../../../components/event-interactions-modal";
|
||||||
|
import { getNeventCodeWithRelays } from "../../../helpers/nip19";
|
||||||
|
|
||||||
const LEVEL_COLORS = ["green", "blue", "red", "purple", "yellow", "cyan", "pink"];
|
const LEVEL_COLORS = ["green", "blue", "red", "purple", "yellow", "cyan", "pink"];
|
||||||
|
|
||||||
@ -85,7 +85,7 @@ export const ThreadPost = memo(({ post, initShowReplies, focusId, level = -1 }:
|
|||||||
<UserAvatarLink pubkey={post.event.pubkey} size="sm" />
|
<UserAvatarLink pubkey={post.event.pubkey} size="sm" />
|
||||||
<UserLink pubkey={post.event.pubkey} fontWeight="bold" isTruncated />
|
<UserLink pubkey={post.event.pubkey} fontWeight="bold" isTruncated />
|
||||||
<UserDnsIdentityIcon pubkey={post.event.pubkey} onlyIcon />
|
<UserDnsIdentityIcon pubkey={post.event.pubkey} onlyIcon />
|
||||||
<Link as={RouterLink} whiteSpace="nowrap" color="current" to={`/n/${nip19.noteEncode(post.event.id)}`}>
|
<Link as={RouterLink} whiteSpace="nowrap" color="current" to={`/n/${getNeventCodeWithRelays(post.event.id)}`}>
|
||||||
<Timestamp timestamp={post.event.created_at} />
|
<Timestamp timestamp={post.event.created_at} />
|
||||||
</Link>
|
</Link>
|
||||||
{replies.length > 0 ? (
|
{replies.length > 0 ? (
|
||||||
|
@ -165,12 +165,12 @@ export default function DisplaySettings() {
|
|||||||
<FormControl>
|
<FormControl>
|
||||||
<Flex alignItems="center">
|
<Flex alignItems="center">
|
||||||
<FormLabel htmlFor="blurImages" mb="0">
|
<FormLabel htmlFor="blurImages" mb="0">
|
||||||
Blur images from strangers
|
Blur media from strangers
|
||||||
</FormLabel>
|
</FormLabel>
|
||||||
<Switch id="blurImages" {...register("blurImages")} />
|
<Switch id="blurImages" {...register("blurImages")} />
|
||||||
</Flex>
|
</Flex>
|
||||||
<FormHelperText>
|
<FormHelperText>
|
||||||
<span>Enabled: blur images for people you aren't following</span>
|
<span>Enabled: blur media from people you aren't following</span>
|
||||||
</FormHelperText>
|
</FormHelperText>
|
||||||
</FormControl>
|
</FormControl>
|
||||||
<FormControl>
|
<FormControl>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user