This commit is contained in:
Shusui MOYATANI
2023-03-01 00:31:04 +09:00
parent 57bc321436
commit 471b03eb1d
20 changed files with 279 additions and 118 deletions

View File

@@ -1,23 +1,17 @@
import {
Show,
For,
createSignal,
createMemo,
onMount,
onCleanup,
type JSX,
Component,
} from 'solid-js';
import { Show, For, createMemo, type JSX, type Component } from 'solid-js';
import type { Event as NostrEvent } from 'nostr-tools/event';
import HeartOutlined from 'heroicons/24/outline/heart.svg';
import HeartSolid from 'heroicons/24/solid/heart.svg';
import ArrowPathRoundedSquare from 'heroicons/24/outline/arrow-path-rounded-square.svg';
import ChatBubbleLeft from 'heroicons/24/outline/chat-bubble-left.svg';
import EllipsisHorizontal from 'heroicons/24/outline/ellipsis-horizontal.svg';
import useProfile from '@/clients/useProfile';
import useConfig from '@/clients/useConfig';
import usePubkey from '@/clients/usePubkey';
import useCommands from '@/clients/useCommands';
import useReactions from '@/clients/useReactions';
import useDatePulser from '@/hooks/useDatePulser';
import { formatRelative } from '@/utils/formatDate';
import ColumnItem from '@/components/ColumnItem';
@@ -32,11 +26,24 @@ const TextNote: Component<TextNoteProps> = (props) => {
const currentDate = useDatePulser();
const [config] = useConfig();
const commands = useCommands();
const pubkey = usePubkey();
const { profile: author } = useProfile(() => ({
relayUrls: config().relayUrls,
pubkey: props.event.pubkey,
}));
const {
reactions,
isReactedBy,
query: reactionsQuery,
} = useReactions(() => ({
relayUrls: config().relayUrls,
eventId: props.event.id,
}));
const isReactedByMe = createMemo(() => isReactedBy(pubkey()));
const replyingToPubKeys = createMemo(() =>
props.event.tags.filter((tag) => tag[0] === 'p').map((e) => e[1]),
);
@@ -45,16 +52,31 @@ const TextNote: Component<TextNoteProps> = (props) => {
const handleRepost: JSX.EventHandler<HTMLButtonElement, MouseEvent> = (ev) => {
ev.preventDefault();
commands.publishDeprecatedRepost({});
commands.publishDeprecatedRepost({
relayUrls: config().relayUrls,
pubkey: pubkey(),
eventId: props.event.id,
notifyPubkey: props.event.pubkey,
});
};
const handleReaction: JSX.EventHandler<HTMLButtonElement, MouseEvent> = (ev) => {
if (isReactedByMe()) {
// TODO remove reaction
return;
}
ev.preventDefault();
commands.publishReaction({
relayUrls: config().relayUrls,
pubkey: pubkeyHex,
eventId: props.event.id,
});
commands
.publishReaction({
relayUrls: config().relayUrls,
pubkey: pubkey(),
content: '+',
eventId: props.event.id,
notifyPubkey: props.event.pubkey,
})
.then(() => {
reactionsQuery.refetch();
});
};
return (
@@ -74,8 +96,8 @@ const TextNote: Component<TextNoteProps> = (props) => {
<div class="flex justify-between gap-1 text-xs">
<div class="author flex min-w-0 truncate">
{/* TODO link to author */}
<Show when={author()?.display_name != null && author()?.display_name.length > 0}>
<div class="author-name pr-1 font-bold">{author()?.display_name}</div>
<Show when={(author()?.display_name?.length ?? 0) > 0}>
<div class="author-name truncate pr-1 font-bold">{author()?.display_name}</div>
</Show>
<div class="author-username truncate text-zinc-600">
<Show when={author()?.name} fallback={props.event.pubkey}>
@@ -89,9 +111,9 @@ const TextNote: Component<TextNoteProps> = (props) => {
<div class="text-xs">
{'Replying to '}
<For each={replyingToPubKeys()}>
{(pubkey: string) => (
{(replyToPubkey: string) => (
<span class="pr-1 text-blue-500 underline">
<GeneralUserMentionDisplay pubkey={pubkey} />
<GeneralUserMentionDisplay pubkey={replyToPubkey} />
</span>
)}
</For>
@@ -100,16 +122,27 @@ const TextNote: Component<TextNoteProps> = (props) => {
<div class="content whitespace-pre-wrap break-all">
<TextNoteContentDisplay event={props.event} embedding={true} />
</div>
<div class="flex justify-end gap-16">
<div class="flex w-48 items-center justify-between gap-8 pt-1">
<button class="h-4 w-4 text-zinc-400">
<ChatBubbleLeft />
</button>
<button class="h-4 w-4 text-zinc-400" onClick={handleRepost}>
<ArrowPathRoundedSquare />
</button>
<button class="h-4 w-4 text-zinc-400" onClick={handleReaction}>
<HeartOutlined />
</button>
<div
class="flex items-center gap-1"
classList={{
'text-zinc-400': !isReactedByMe(),
'text-rose-400': isReactedByMe(),
}}
>
<button class="h-4 w-4" onClick={handleReaction}>
<Show when={isReactedByMe()} fallback={<HeartOutlined />}>
<HeartSolid />
</Show>
</button>
<div class="text-sm text-zinc-400">{reactions().length}</div>
</div>
<button class="h-4 w-4 text-zinc-400">
<EllipsisHorizontal />
</button>