This commit is contained in:
Shusui MOYATANI
2023-03-11 13:51:56 +09:00
parent fe3b1b6074
commit 0e62c4d167
20 changed files with 6378 additions and 902 deletions

94
src/components/Config.tsx Normal file
View File

@@ -0,0 +1,94 @@
import useConfig from '@/nostr/useConfig';
import { createSignal, For, type JSX } from 'solid-js';
type ConfigProps = {
onClose: () => void;
};
const RelayConfig = () => {
const { config, setConfig } = useConfig();
const [relayUrlInput, setRelayUrlInput] = createSignal<string>('');
const addRelay = (relayUrl: string) => {
setConfig((current) => ({
...current,
relayUrls: [...current.relayUrls, relayUrl],
}));
};
const removeRelay = (relayUrl: string) => {
setConfig((current) => ({
...current,
relayUrls: current.relayUrls.filter((e) => e !== relayUrl),
}));
};
const handleClickAddRelay: JSX.EventHandler<HTMLFormElement, Event> = (ev) => {
ev.preventDefault();
const relayUrl = ev.currentTarget?.relayUrl?.value as string | undefined;
if (relayUrl == null) return;
addRelay(relayUrlInput());
};
return (
<div>
<h3 class="font-bold"></h3>
<ul>
<For each={config().relayUrls}>
{(relayUrl: string) => {
return (
<li class="flex">
<div class="flex-1">{relayUrl}</div>
<button onClick={() => removeRelay(relayUrl)}>x</button>
</li>
);
}}
</For>
</ul>
<form class="flex gap-2" onSubmit={handleClickAddRelay}>
<input
class="flex-1"
type="text"
name="relayUrl"
value={relayUrlInput()}
onChange={(ev) => setRelayUrlInput(ev.currentTarget.value)}
/>
<button type="submit" class="rounded bg-rose-300 p-2 font-bold text-white">
</button>
</form>
</div>
);
};
const Config = (props: ConfigProps) => {
let containerRef: HTMLDivElement | undefined;
const handleClickContainer: JSX.EventHandler<HTMLDivElement, MouseEvent> = (ev) => {
if (ev.target === containerRef) {
props.onClose();
}
};
return (
<div
ref={containerRef}
class="absolute top-0 left-0 flex h-screen w-screen cursor-default place-content-center place-items-center bg-black/25"
role="button"
onClick={handleClickContainer}
>
<div class="w-[480px] max-w-[100vw] rounded bg-white p-4 shadow">
<div class="relative">
<h2 class="flex-1 text-center font-bold"></h2>
<button class="absolute top-1 right-0" onClick={() => props.onClose()}>
X
</button>
</div>
<RelayConfig />
</div>
</div>
);
};
export default Config;

View File

@@ -15,7 +15,7 @@ export type DeprecatedRepostProps = {
};
const DeprecatedRepost: Component<DeprecatedRepostProps> = (props) => {
const [config] = useConfig();
const { config } = useConfig();
const pubkey = () => props.event.pubkey;
const eventId = () => props.event.tags.find(([tagName]) => tagName === 'e')?.[1];

View File

@@ -1,8 +1,10 @@
import { createSignal, Show, type JSX, Component } from 'solid-js';
import MagnifyingGlass from 'heroicons/24/solid/magnifying-glass.svg';
import PencilSquare from 'heroicons/24/solid/pencil-square.svg';
import Cog6Tooth from 'heroicons/24/outline/cog-6-tooth.svg';
import NotePostForm from '@/components/NotePostForm';
import Config from '@/components/Config';
import useConfig from '@/nostr/useConfig';
import useCommands from '@/nostr/useCommands';
@@ -11,11 +13,12 @@ import { useHandleCommand } from '@/hooks/useCommandBus';
const SideBar: Component = () => {
let formTextAreaRef: HTMLTextAreaElement | undefined;
const [config] = useConfig();
const { config } = useConfig();
const getPubkey = usePubkey();
const commands = useCommands();
const [formOpened, setFormOpened] = createSignal(false);
const [configOpened, setConfigOpened] = createSignal(false);
const openForm = () => {
setFormOpened(true);
@@ -57,22 +60,36 @@ const SideBar: Component = () => {
return (
<div class="flex shrink-0 flex-row border-r bg-sidebar-bg">
<div class="flex w-14 flex-auto flex-col items-center gap-3 border-r border-rose-200 py-5">
<button
class={`h-9 w-9 rounded-full border border-primary bg-primary p-2 text-2xl font-bold text-white`}
onClick={() => setFormOpened((current) => !current)}
>
<PencilSquare />
</button>
<button class="h-9 w-9 rounded-full border border-primary p-2 text-2xl font-bold text-primary">
<MagnifyingGlass />
</button>
{/* <div>column 1</div> */}
{/* <div>column 2</div> */}
<div class="flex w-14 flex-auto flex-col items-center gap-3 border-r border-rose-200 pt-5">
<div class="flex flex-col items-center gap-3">
<button
class={`h-9 w-9 rounded-full border border-primary bg-primary p-2 text-2xl font-bold text-white`}
onClick={() => setFormOpened((current) => !current)}
>
<PencilSquare />
</button>
<button class="h-9 w-9 rounded-full border border-primary p-2 text-2xl font-bold text-primary">
<MagnifyingGlass />
</button>
{/* <div>column 1</div> */}
{/* <div>column 2</div> */}
</div>
<div class="grow" />
<div>
<button
class="h-12 w-12 p-3 text-primary"
onClick={() => setConfigOpened((current) => !current)}
>
<Cog6Tooth />
</button>
</div>
</div>
<Show when={formOpened()}>
<NotePostForm ref={formTextAreaRef} onPost={handlePost} onClose={closeForm} />
</Show>
<Show when={configOpened()}>
<Config onClose={() => setConfigOpened(false)} />
</Show>
</div>
);
};

View File

@@ -23,11 +23,15 @@ import ReplyPostForm from '@/components/ReplyPostForm';
export type TextNoteProps = {
event: NostrEvent;
//
// displayinlineContent: boolean = true;
// リアクションやリポスト等の
// actions: boolean = true;
};
const TextNote: Component<TextNoteProps> = (props) => {
const currentDate = useDatePulser();
const [config] = useConfig();
const { config } = useConfig();
const commands = useCommands();
const pubkey = usePubkey();
const [showReplyForm, setShowReplyForm] = createSignal(false);

View File

@@ -8,7 +8,7 @@ type UserNameDisplayProps = {
};
const UserNameDisplay: Component<UserNameDisplayProps> = (props) => {
const [config] = useConfig();
const { config } = useConfig();
const { profile } = useProfile(() => ({
relayUrls: config().relayUrls,
pubkey: props.pubkey,

View File

@@ -14,7 +14,7 @@ type ReactionProps = {
};
const Reaction: Component<ReactionProps> = (props) => {
const [config] = useConfig();
const { config } = useConfig();
const eventId = () => props.event.tags.find(([tagName]) => tagName === 'e')?.[1];
const { profile } = useProfile(() => ({
@@ -61,7 +61,10 @@ const Reaction: Component<ReactionProps> = (props) => {
</div>
</div>
<div class="notification-event">
<Show when={reactedEvent() != null} fallback={<>loading {eventId()}</>}>
<Show
when={reactedEvent() != null}
fallback={<div class="truncate">loading {eventId()}</div>}
>
<TextNote event={reactedEvent()} />
</Show>
</div>

View File

@@ -8,7 +8,7 @@ export type GeneralUserMentionDisplayProps = {
};
const GeneralUserMentionDisplay = (props: GeneralUserMentionDisplayProps) => {
const [config] = useConfig();
const { config } = useConfig();
const { profile } = useProfile(() => ({
relayUrls: config().relayUrls,
pubkey: props.pubkey,

View File

@@ -1,3 +1,10 @@
import { Switch, Match } from 'solid-js';
import TextNote from '@/components/TextNote';
import useConfig from '@/nostr/useConfig';
import useEvent from '@/nostr/useEvent';
import useProfile from '@/nostr/useProfile';
import type { MentionedEvent } from '@/core/parseTextNote';
export type MentionedEventDisplayProps = {
@@ -5,7 +12,28 @@ export type MentionedEventDisplayProps = {
};
const MentionedEventDisplay = (props: MentionedEventDisplayProps) => {
return <span class="text-blue-500 underline">#{props.mentionedEvent.eventId}</span>;
const { config } = useConfig();
const { event, query: eventQuery } = useEvent(() => ({
relayUrls: config().relayUrls,
eventId: props.mentionedEvent.eventId,
}));
// return <span class="text-blue-500 underline">#{props.mentionedEvent.eventId}</span>;
return (
<div class="rounded border py-2 px-1">
{/* TODO なんかこのあたりの処理は統一したい */}
<Switch fallback="failed to load">
<Match when={event() != null}>
<TextNote event={event()} />
</Match>
<Match when={eventQuery.isLoading}>
<div class="truncate">
{'loading '}
<span>{props.mentionedEvent.eventId}</span>
</div>
</Match>
</Switch>
</div>
);
};
export default MentionedEventDisplay;