This commit is contained in:
2023-10-24 13:11:10 +07:00
parent b1a44f2cbf
commit 854a47f266
52 changed files with 815 additions and 798 deletions

View File

@@ -1,10 +1,10 @@
import { NDKKind } from '@nostr-dev-kit/ndk';
import { NDKEvent, NDKKind } from '@nostr-dev-kit/ndk';
import * as Popover from '@radix-ui/react-popover';
import { useState } from 'react';
import { ReactionIcon } from '@shared/icons';
import { useNDK } from '@libs/ndk/provider';
import { useNostr } from '@utils/hooks/useNostr';
import { ReactionIcon } from '@shared/icons';
const REACTIONS = [
{
@@ -30,11 +30,11 @@ const REACTIONS = [
];
export function NoteReaction({ id, pubkey }: { id: string; pubkey: string }) {
const { ndk } = useNDK();
const [open, setOpen] = useState(false);
const [reaction, setReaction] = useState<string | null>(null);
const { publish } = useNostr();
const getReactionImage = (content: string) => {
const reaction: { img: string } = REACTIONS.find((el) => el.content === content);
return reaction.img;
@@ -43,16 +43,16 @@ export function NoteReaction({ id, pubkey }: { id: string; pubkey: string }) {
const react = async (content: string) => {
setReaction(content);
const event = await publish({
content: content,
kind: NDKKind.Reaction,
tags: [
['e', id],
['p', pubkey],
],
});
const event = new NDKEvent(ndk);
event.content = content;
event.kind = NDKKind.Reaction;
event.tags = [
['e', id],
['p', pubkey],
];
if (event) {
const publishedRelays = await event.publish();
if (publishedRelays) {
setOpen(false);
}
};

View File

@@ -1,9 +1,8 @@
import * as Tooltip from '@radix-ui/react-tooltip';
import { createSearchParams, useNavigate } from 'react-router-dom';
import { ReplyIcon } from '@shared/icons';
import { useComposer } from '@stores/composer';
export function NoteReply({
id,
pubkey,
@@ -13,14 +12,23 @@ export function NoteReply({
pubkey: string;
root?: string;
}) {
const setReply = useComposer((state) => state.setReply);
const navigate = useNavigate();
return (
<Tooltip.Root delayDuration={150}>
<Tooltip.Trigger asChild>
<button
type="button"
onClick={() => setReply(id, pubkey, root)}
onClick={() =>
navigate({
pathname: '/new/',
search: createSearchParams({
id,
pubkey,
root,
}).toString(),
})
}
className="group inline-flex h-7 w-7 items-center justify-center text-neutral-600 dark:text-neutral-400"
>
<ReplyIcon className="h-5 w-5 group-hover:text-blue-500" />

View File

@@ -1,20 +1,16 @@
import { NDKKind } from '@nostr-dev-kit/ndk';
import { NDKEvent, NDKKind } from '@nostr-dev-kit/ndk';
import * as AlertDialog from '@radix-ui/react-alert-dialog';
import * as Tooltip from '@radix-ui/react-tooltip';
import { message } from '@tauri-apps/plugin-dialog';
import { useState } from 'react';
import { toast } from 'sonner';
import { twMerge } from 'tailwind-merge';
import { useNDK } from '@libs/ndk/provider';
import { LoaderIcon, RepostIcon } from '@shared/icons';
import { useNostr } from '@utils/hooks/useNostr';
import { sendNativeNotification } from '@utils/notification';
export function NoteRepost({ id, pubkey }: { id: string; pubkey: string }) {
const { publish } = useNostr();
const { relayUrls } = useNDK();
const { ndk, relayUrls } = useNDK();
const [open, setOpen] = useState(false);
const [isLoading, setIsLoading] = useState(false);
@@ -22,18 +18,26 @@ export function NoteRepost({ id, pubkey }: { id: string; pubkey: string }) {
const submit = async () => {
setIsLoading(true);
const tags = [
['e', id, relayUrls[0], 'root'],
['p', pubkey],
];
const event = await publish({ content: '', kind: NDKKind.Repost, tags: tags });
if (event) {
const event = new NDKEvent(ndk);
event.content = '';
event.kind = NDKKind.Repost;
event.tags = tags;
const publishedRelays = await event.publish();
if (publishedRelays) {
setOpen(false);
setIsRepost(true);
await sendNativeNotification('Reposted successfully', 'Lume');
toast.success(`Broadcasted to ${publishedRelays.size} relays successfully.`);
} else {
setIsLoading(false);
await message('Repost failed, try again later', { title: 'Lume', type: 'error' });
toast.error('Repost failed, try again later');
}
};
@@ -63,11 +67,11 @@ export function NoteRepost({ id, pubkey }: { id: string; pubkey: string }) {
</Tooltip.Portal>
</Tooltip.Root>
<AlertDialog.Portal>
<AlertDialog.Overlay className="fixed inset-0 z-50 bg-black/80 backdrop-blur-2xl" />
<AlertDialog.Overlay className="fixed inset-0 z-50 bg-black/20 backdrop-blur-sm dark:bg-white/20" />
<AlertDialog.Content className="fixed inset-0 z-50 flex min-h-full items-center justify-center">
<div className="relative h-min w-full max-w-md rounded-xl bg-neutral-400 dark:bg-neutral-600">
<div className="flex flex-col gap-2 border-b border-white/5 px-5 py-4">
<AlertDialog.Title className="text-lg font-semibold leading-none text-white">
<div className="relative h-min w-full max-w-md rounded-xl bg-white dark:bg-black">
<div className="flex flex-col gap-2 border-b border-neutral-100 px-5 py-6 dark:border-neutral-900">
<AlertDialog.Title className="text-lg font-semibold leading-none text-neutral-900 dark:text-neutral-100">
Confirm repost this post?
</AlertDialog.Title>
<AlertDialog.Description className="text-sm leading-tight text-neutral-600 dark:text-neutral-400">
@@ -77,14 +81,14 @@ export function NoteRepost({ id, pubkey }: { id: string; pubkey: string }) {
</div>
<div className="flex justify-end gap-2 px-3 py-3">
<AlertDialog.Cancel asChild>
<button className="inline-flex h-9 w-20 items-center justify-center rounded-md text-sm font-medium leading-none text-white outline-none hover:bg-white/10 hover:backdrop-blur-xl">
<button className="inline-flex h-9 w-20 items-center justify-center rounded-md text-sm font-medium text-neutral-600 outline-none hover:bg-neutral-200 dark:bg-neutral-800 dark:text-neutral-400">
Cancel
</button>
</AlertDialog.Cancel>
<button
type="button"
onClick={() => submit()}
className="inline-flex h-9 w-28 items-center justify-center rounded-md bg-white/10 text-sm font-medium leading-none text-white outline-none hover:bg-blue-600"
className="inline-flex h-9 w-24 items-center justify-center rounded-md bg-blue-500 text-sm font-medium leading-none text-white outline-none hover:bg-blue-600"
>
{isLoading ? (
<LoaderIcon className="h-4 w-4 animate-spin text-white" />

View File

@@ -1,6 +1,5 @@
import { NDKEvent, NDKKind } from '@nostr-dev-kit/ndk';
import { nip19 } from 'nostr-tools';
import { Link } from 'react-router-dom';
import {
ArticleNote,
@@ -49,24 +48,17 @@ export function ChildNote({ id, root }: { id: string; root?: string }) {
<div className="absolute bottom-0 left-[18px] h-[calc(100%-3.4rem)] w-0.5 bg-gradient-to-t from-black/20 to-black/10 dark:from-white/20 dark:to-white/10" />
<div className="relative mb-5 flex flex-col">
<div className="relative z-10 flex items-start gap-3">
<div className="inline-flex h-10 w-10 items-end justify-center rounded-lg bg-black pb-1">
<img src="/lume.png" alt="lume" className="h-auto w-1/3" />
</div>
<h5 className="truncate font-semibold leading-none text-white">
Lume <span className="text-green-500">(System)</span>
<div className="inline-flex h-10 w-10 shrink-0 items-end justify-center rounded-lg bg-black"></div>
<h5 className="truncate font-semibold leading-none text-neutral-900 dark:text-neutral-100">
Lume <span className="text-teal-500">(System)</span>
</h5>
</div>
<div className="-mt-4 flex items-start gap-3">
<div className="w-10 shrink-0" />
<div>
<div className="relative z-20 mt-1 flex-1 select-text">
<div className="mb-1 select-text rounded-lg bg-white/5 p-1.5 text-sm">
Lume cannot find this post with your current relays, but you can view it
via njump.me.{' '}
<Link to={noteLink} className="text-blue-500">
Learn more
</Link>
</div>
<div className="flex-1">
<div className="prose prose-neutral max-w-none select-text whitespace-pre-line break-all leading-normal dark:prose-invert prose-headings:mb-1 prose-headings:mt-3 prose-p:mb-0 prose-p:mt-0 prose-p:last:mb-1 prose-a:font-normal prose-a:text-blue-500 prose-blockquote:mb-1 prose-blockquote:mt-1 prose-blockquote:border-l-[2px] prose-blockquote:border-blue-500 prose-blockquote:pl-2 prose-pre:whitespace-pre-wrap prose-pre:break-words prose-pre:break-all prose-pre:bg-white/10 prose-ol:m-0 prose-ol:mb-1 prose-ul:mb-1 prose-ul:mt-1 prose-img:mb-2 prose-img:mt-3 prose-hr:mx-0 prose-hr:my-2 hover:prose-a:text-blue-500">
Lume cannot find this post with your current relay set, but you can view
it via njump.me
</div>
<LinkPreview urls={[noteLink]} />
</div>

View File

@@ -41,7 +41,7 @@ export function FileNote(props: { event?: NDKEvent }) {
slot="media"
src={url}
poster={`https://thumbnail.video/api/get?url=${url}&seconds=1`}
preload="auto"
preload="none"
muted
crossOrigin=""
/>

View File

@@ -2,7 +2,6 @@ import { NDKEvent, NDKKind } from '@nostr-dev-kit/ndk';
import { useQuery } from '@tanstack/react-query';
import { nip19 } from 'nostr-tools';
import { memo, useCallback } from 'react';
import { Link } from 'react-router-dom';
import { twMerge } from 'tailwind-merge';
import { useNDK } from '@libs/ndk/provider';
@@ -113,24 +112,17 @@ export function Repost({
>
<div className="relative flex flex-col">
<div className="relative z-10 flex items-start gap-3">
<div className="inline-flex h-11 w-11 items-end justify-center rounded-lg bg-black pb-1">
<img src="/lume.png" alt="lume" className="h-auto w-1/3" />
</div>
<h5 className="truncate font-semibold leading-none text-white">
Lume <span className="text-green-500">(System)</span>
<div className="inline-flex h-10 w-10 shrink-0 items-end justify-center rounded-lg bg-black"></div>
<h5 className="truncate font-semibold leading-none text-neutral-900 dark:text-neutral-100">
Lume <span className="text-teal-500">(System)</span>
</h5>
</div>
<div className="-mt-4 flex items-start gap-3">
<div className="w-11 shrink-0" />
<div>
<div className="relative z-20 mt-1 flex-1 select-text">
<div className="mb-1 select-text rounded-lg bg-white/5 p-1.5 text-sm">
Lume cannot find this post with your current relays, but you can view
it via njump.me.{' '}
<Link to={noteLink} className="text-blue-500">
Learn more
</Link>
</div>
<div className="w-10 shrink-0" />
<div className="flex-1">
<div className="prose prose-neutral max-w-none select-text whitespace-pre-line break-all leading-normal dark:prose-invert prose-headings:mb-1 prose-headings:mt-3 prose-p:mb-0 prose-p:mt-0 prose-p:last:mb-1 prose-a:font-normal prose-a:text-blue-500 prose-blockquote:mb-1 prose-blockquote:mt-1 prose-blockquote:border-l-[2px] prose-blockquote:border-blue-500 prose-blockquote:pl-2 prose-pre:whitespace-pre-wrap prose-pre:break-words prose-pre:break-all prose-pre:bg-white/10 prose-ol:m-0 prose-ol:mb-1 prose-ul:mb-1 prose-ul:mt-1 prose-img:mb-2 prose-img:mt-3 prose-hr:mx-0 prose-hr:my-2 hover:prose-a:text-blue-500">
Lume cannot find this post with your current relay set, but you can view
it via njump.me
</div>
<LinkPreview urls={[noteLink]} />
</div>

View File

@@ -23,7 +23,7 @@ export function TextNote(props: { content?: string }) {
return (
<div>
<ReactMarkdown
className="prose prose-neutral max-w-none select-text whitespace-pre-line leading-normal dark:prose-invert prose-headings:mb-1 prose-headings:mt-3 prose-p:mb-0 prose-p:mt-0 prose-p:last:mb-1 prose-a:font-normal prose-a:text-blue-500 prose-blockquote:mb-1 prose-blockquote:mt-1 prose-blockquote:border-l-[2px] prose-blockquote:border-blue-500 prose-blockquote:pl-2 prose-pre:whitespace-pre-wrap prose-pre:break-words prose-pre:break-all prose-pre:bg-white/10 prose-ol:m-0 prose-ol:mb-1 prose-ul:mb-1 prose-ul:mt-1 prose-img:mb-2 prose-img:mt-3 prose-hr:mx-0 prose-hr:my-2 hover:prose-a:text-blue-500"
className="break-p prose prose-neutral max-w-none select-text whitespace-pre-line leading-normal dark:prose-invert prose-headings:mb-1 prose-headings:mt-3 prose-p:mb-0 prose-p:mt-0 prose-p:last:mb-1 prose-a:font-normal prose-a:text-blue-500 prose-blockquote:mb-1 prose-blockquote:mt-1 prose-blockquote:border-l-[2px] prose-blockquote:border-blue-500 prose-blockquote:pl-2 prose-pre:whitespace-pre-wrap prose-pre:bg-white/10 prose-ol:m-0 prose-ol:mb-1 prose-ul:mb-1 prose-ul:mt-1 prose-img:mb-2 prose-img:mt-3 prose-hr:mx-0 prose-hr:my-2 hover:prose-a:text-blue-500"
remarkPlugins={[remarkGfm]}
disallowedElements={['h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'pre', 'code']}
unwrapDisallowed={true}
@@ -38,7 +38,7 @@ export function TextNote(props: { content?: string }) {
return (
<div>
<ReactMarkdown
className="prose prose-neutral max-w-none select-text whitespace-pre-line leading-normal dark:prose-invert prose-headings:mb-1 prose-headings:mt-3 prose-p:mb-0 prose-p:mt-0 prose-p:last:mb-1 prose-a:font-normal prose-a:text-blue-500 prose-blockquote:mb-1 prose-blockquote:mt-1 prose-blockquote:border-l-[2px] prose-blockquote:border-blue-500 prose-blockquote:pl-2 prose-pre:whitespace-pre-wrap prose-pre:break-words prose-pre:break-all prose-pre:bg-white/10 prose-ol:m-0 prose-ol:mb-1 prose-ul:mb-1 prose-ul:mt-1 prose-img:mb-2 prose-img:mt-3 prose-hr:mx-0 prose-hr:my-2 hover:prose-a:text-blue-500"
className="break-p prose prose-neutral max-w-none select-text whitespace-pre-line leading-normal dark:prose-invert prose-headings:mb-1 prose-headings:mt-3 prose-p:mb-0 prose-p:mt-0 prose-p:last:mb-1 prose-a:font-normal prose-a:text-blue-500 prose-blockquote:mb-1 prose-blockquote:mt-1 prose-blockquote:border-l-[2px] prose-blockquote:border-blue-500 prose-blockquote:pl-2 prose-pre:whitespace-pre-wrap prose-pre:bg-white/10 prose-ol:m-0 prose-ol:mb-1 prose-ul:mb-1 prose-ul:mt-1 prose-img:mb-2 prose-img:mt-3 prose-hr:mx-0 prose-hr:my-2 hover:prose-a:text-blue-500"
remarkPlugins={[remarkGfm]}
components={{
a: ({ href }) => {

View File

@@ -52,7 +52,7 @@ export function LinkPreview({ urls }: { urls: string[] }) {
</h5>
)}
{data.description && (
<p className="mb-2.5 line-clamp-3 break-words text-sm text-neutral-700 dark:text-neutral-400">
<p className="mb-2.5 line-clamp-3 break-all text-sm text-neutral-700 dark:text-neutral-400">
{data.description}
</p>
)}

View File

@@ -18,7 +18,7 @@ export const VideoPreview = memo(function VideoPreview({ urls }: { urls: string[
slot="media"
src={url}
poster={`https://thumbnail.video/api/get?url=${url}&seconds=1`}
preload="auto"
preload="none"
muted
/>
<MediaControlBar>

View File

@@ -2,8 +2,10 @@ export function NoteSkeleton() {
return (
<div className="flex h-min flex-col">
<div className="flex items-start gap-3">
<div className="relative h-11 w-11 shrink overflow-hidden rounded-lg bg-neutral-400 dark:bg-neutral-600" />
<div className="h-3 w-20 rounded bg-neutral-400 dark:bg-neutral-600" />
<div className="relative h-10 w-10 shrink-0 overflow-hidden rounded-lg bg-neutral-400 dark:bg-neutral-600" />
<div className="h-6 w-full">
<div className="h-3 w-24 animate-pulse rounded bg-neutral-300 dark:bg-neutral-700" />
</div>
</div>
<div className="-mt-5 flex animate-pulse gap-3">
<div className="w-10 shrink-0" />

View File

@@ -38,7 +38,7 @@ export function NoteWrapper({
children,
event.kind === 1 ? { content: event.content } : { event: event }
)}
<NoteActions id={event.id} pubkey={event.pubkey} />
<NoteActions id={event.id} pubkey={event.pubkey} root={root} />
</div>
</div>
</div>