This commit is contained in:
Shusui MOYATANI
2023-05-14 15:06:40 +09:00
parent 88cc1c9bc8
commit 9ed589dcd2
2 changed files with 38 additions and 13 deletions

View File

@@ -112,6 +112,7 @@ const TextNoteDisplay: Component<TextNoteDisplayProps> = (props) => {
reactions, reactions,
reactionsGroupedByContent, reactionsGroupedByContent,
isReactedBy, isReactedBy,
isReactedByWithEmoji,
invalidateReactions, invalidateReactions,
query: reactionsQuery, query: reactionsQuery,
} = useReactions(() => ({ } = useReactions(() => ({
@@ -220,6 +221,10 @@ const TextNoteDisplay: Component<TextNoteDisplayProps> = (props) => {
const p = pubkey(); const p = pubkey();
return (p != null && isReactedBy(p)) || reacted(); return (p != null && isReactedBy(p)) || reacted();
}); });
const isReactedByMeWithEmoji = createMemo(() => {
const p = pubkey();
return p != null && isReactedByWithEmoji(p);
});
const isRepostedByMe = createMemo(() => { const isRepostedByMe = createMemo(() => {
const p = pubkey(); const p = pubkey();
return (p != null && isRepostedBy(p)) || reposted(); return (p != null && isRepostedBy(p)) || reposted();
@@ -429,8 +434,10 @@ const TextNoteDisplay: Component<TextNoteDisplayProps> = (props) => {
<div <div
class="flex shrink-0 items-center gap-1" class="flex shrink-0 items-center gap-1"
classList={{ classList={{
'text-zinc-400': !isReactedByMe(), 'text-zinc-400': !isReactedByMe() || isReactedByMeWithEmoji(),
'text-rose-400': isReactedByMe() || publishReactionMutation.isLoading, 'text-rose-400':
(isReactedByMe() && !isReactedByMeWithEmoji()) ||
publishReactionMutation.isLoading,
}} }}
> >
<button <button
@@ -438,7 +445,10 @@ const TextNoteDisplay: Component<TextNoteDisplayProps> = (props) => {
onClick={handleReaction} onClick={handleReaction}
disabled={publishReactionMutation.isLoading} disabled={publishReactionMutation.isLoading}
> >
<Show when={isReactedByMe()} fallback={<HeartOutlined />}> <Show
when={isReactedByMe() && !isReactedByMeWithEmoji()}
fallback={<HeartOutlined />}
>
<HeartSolid /> <HeartSolid />
</Show> </Show>
</button> </button>
@@ -451,7 +461,15 @@ const TextNoteDisplay: Component<TextNoteDisplayProps> = (props) => {
</Show> </Show>
</div> </div>
<Show when={config().useEmojiReaction}> <Show when={config().useEmojiReaction}>
<div class="shrink-0"> <div
class="flex shrink-0 items-center gap-1"
classList={{
'text-zinc-400': !isReactedByMe() || !isReactedByMeWithEmoji(),
'text-rose-400':
(isReactedByMe() && isReactedByMeWithEmoji()) ||
publishReactionMutation.isLoading,
}}
>
<EmojiPicker onEmojiSelect={(emoji) => doReaction(emoji)}> <EmojiPicker onEmojiSelect={(emoji) => doReaction(emoji)}>
<span class="inline-block h-4 w-4"> <span class="inline-block h-4 w-4">
<Plus /> <Plus />

View File

@@ -1,11 +1,4 @@
import { import { createSignal, createMemo, observable, type Accessor, type Signal } from 'solid-js';
createSignal,
createMemo,
createRoot,
observable,
type Accessor,
type Signal,
} from 'solid-js';
import { createQuery, useQueryClient, type CreateQueryResult } from '@tanstack/solid-query'; import { createQuery, useQueryClient, type CreateQueryResult } from '@tanstack/solid-query';
import { type Event as NostrEvent, type Filter, Kind } from 'nostr-tools'; import { type Event as NostrEvent, type Filter, Kind } from 'nostr-tools';
@@ -82,6 +75,7 @@ export type UseReactions = {
reactions: () => NostrEvent[]; reactions: () => NostrEvent[];
reactionsGroupedByContent: () => Map<string, NostrEvent[]>; reactionsGroupedByContent: () => Map<string, NostrEvent[]>;
isReactedBy: (pubkey: string) => boolean; isReactedBy: (pubkey: string) => boolean;
isReactedByWithEmoji: (pubkey: string) => boolean;
invalidateReactions: () => Promise<void>; invalidateReactions: () => Promise<void>;
query: CreateQueryResult<NostrEvent[]>; query: CreateQueryResult<NostrEvent[]>;
}; };
@@ -116,6 +110,8 @@ export type UseFollowings = {
query: CreateQueryResult<NostrEvent | null>; query: CreateQueryResult<NostrEvent | null>;
}; };
const EmojiRegex = /\p{Emoji_Presentation}/u;
let count = 0; let count = 0;
const { setActiveBatchSubscriptions } = useStats(); const { setActiveBatchSubscriptions } = useStats();
@@ -408,9 +404,20 @@ export const useReactions = (propsProvider: () => UseReactionsProps | null): Use
const isReactedBy = (pubkey: string): boolean => const isReactedBy = (pubkey: string): boolean =>
reactions().findIndex((event) => event.pubkey === pubkey) !== -1; reactions().findIndex((event) => event.pubkey === pubkey) !== -1;
const isReactedByWithEmoji = (pubkey: string): boolean =>
reactions().findIndex((event) => event.pubkey === pubkey && EmojiRegex.test(event.content)) !==
-1;
const invalidateReactions = (): Promise<void> => queryClient.invalidateQueries(genQueryKey()); const invalidateReactions = (): Promise<void> => queryClient.invalidateQueries(genQueryKey());
return { reactions, reactionsGroupedByContent, isReactedBy, invalidateReactions, query }; return {
reactions,
reactionsGroupedByContent,
isReactedBy,
isReactedByWithEmoji,
invalidateReactions,
query,
};
}; };
export const useReposts = (propsProvider: () => UseRepostsProps): UseReposts => { export const useReposts = (propsProvider: () => UseRepostsProps): UseReposts => {