mirror of
https://github.com/aljazceru/rabbit.git
synced 2025-12-18 22:44:26 +01:00
update
This commit is contained in:
94
src/components/Config.tsx
Normal file
94
src/components/Config.tsx
Normal 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;
|
||||
@@ -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];
|
||||
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user