mirror of
https://github.com/aljazceru/rabbit.git
synced 2025-12-17 14:04:21 +01:00
update
This commit is contained in:
@@ -106,6 +106,53 @@ const DateFormatConfig = () => {
|
||||
);
|
||||
};
|
||||
|
||||
const ToggleButton = (props: {
|
||||
value: boolean;
|
||||
onClick: JSX.EventHandler<HTMLButtonElement, MouseEvent>;
|
||||
}) => {
|
||||
return (
|
||||
<button
|
||||
class="flex h-[24px] w-[48px] items-center rounded-full border border-primary px-1"
|
||||
classList={{
|
||||
'bg-white': !props.value,
|
||||
'justify-start': !props.value,
|
||||
'bg-rose-300': props.value,
|
||||
'justify-end': props.value,
|
||||
}}
|
||||
area-label={props.value}
|
||||
onClick={props.onClick}
|
||||
>
|
||||
<span class="m-[-2px] inline-block h-5 w-5 rounded-full border border-primary bg-white shadow" />
|
||||
</button>
|
||||
);
|
||||
};
|
||||
|
||||
const OtherConfig = () => {
|
||||
const { config, setConfig } = useConfig();
|
||||
|
||||
const toggleKeepOpenPostForm = () => {
|
||||
setConfig((current) => ({
|
||||
...current,
|
||||
keepOpenPostForm: !(current.keepOpenPostForm ?? false),
|
||||
}));
|
||||
};
|
||||
|
||||
return (
|
||||
<div>
|
||||
<h3 class="font-bold">その他</h3>
|
||||
<div class="flex flex-col justify-evenly gap-2 sm:flex-row">
|
||||
<div class="flex w-full">
|
||||
<div class="flex-1">投稿欄を開いたままにする</div>
|
||||
<ToggleButton
|
||||
value={config().keepOpenPostForm}
|
||||
onClick={() => toggleKeepOpenPostForm()}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const ConfigUI = (props: ConfigProps) => {
|
||||
let containerRef: HTMLDivElement | undefined;
|
||||
|
||||
@@ -131,6 +178,7 @@ const ConfigUI = (props: ConfigProps) => {
|
||||
</div>
|
||||
<RelayConfig />
|
||||
<DateFormatConfig />
|
||||
<OtherConfig />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -22,19 +22,21 @@ import eventWrapper from '@/core/event';
|
||||
import useConfig from '@/nostr/useConfig';
|
||||
import useCommands from '@/nostr/useCommands';
|
||||
import usePubkey from '@/nostr/usePubkey';
|
||||
import { useHandleCommand } from '@/hooks/useCommandBus';
|
||||
|
||||
type NotePostFormProps = {
|
||||
replyTo?: NostrEvent;
|
||||
mode?: 'normal' | 'reply';
|
||||
onClose: () => void;
|
||||
onPost?: () => void;
|
||||
textAreaRef?: (textAreaRef: HTMLTextAreaElement) => void;
|
||||
};
|
||||
|
||||
const placeholder = (mode: NotePostFormProps['mode']) => {
|
||||
switch (mode) {
|
||||
case 'normal':
|
||||
return 'いまどうしてる?';
|
||||
case 'reply':
|
||||
return '返信を投稿';
|
||||
case 'normal':
|
||||
default:
|
||||
return 'いまどうしてる?';
|
||||
}
|
||||
@@ -59,7 +61,7 @@ const NotePostForm: Component<NotePostFormProps> = (props) => {
|
||||
onSuccess: () => {
|
||||
console.log('succeeded to post');
|
||||
clearText();
|
||||
props?.onClose();
|
||||
props.onPost?.();
|
||||
},
|
||||
onError: (err) => {
|
||||
console.error('error', err);
|
||||
@@ -99,6 +101,7 @@ const NotePostForm: Component<NotePostFormProps> = (props) => {
|
||||
if (ev.key === 'Enter' && (ev.ctrlKey || ev.metaKey)) {
|
||||
submit();
|
||||
} else if (ev.key === 'Escape') {
|
||||
textAreaRef?.blur();
|
||||
props.onClose();
|
||||
}
|
||||
};
|
||||
@@ -129,7 +132,10 @@ const NotePostForm: Component<NotePostFormProps> = (props) => {
|
||||
</Show>
|
||||
<form class="flex flex-col gap-1" onSubmit={handleSubmit}>
|
||||
<textarea
|
||||
ref={textAreaRef}
|
||||
ref={(el) => {
|
||||
textAreaRef = el;
|
||||
props.textAreaRef?.(el);
|
||||
}}
|
||||
name="text"
|
||||
class="rounded border-none"
|
||||
rows={4}
|
||||
|
||||
@@ -7,8 +7,12 @@ import NotePostForm from '@/components/NotePostForm';
|
||||
import Config from '@/components/Config';
|
||||
|
||||
import { useHandleCommand } from '@/hooks/useCommandBus';
|
||||
import useConfig from '@/nostr/useConfig';
|
||||
|
||||
const SideBar: Component = () => {
|
||||
let textAreaRef: HTMLTextAreaElement | undefined;
|
||||
|
||||
const { config } = useConfig();
|
||||
const [formOpened, setFormOpened] = createSignal(false);
|
||||
const [configOpened, setConfigOpened] = createSignal(false);
|
||||
|
||||
@@ -17,7 +21,10 @@ const SideBar: Component = () => {
|
||||
|
||||
useHandleCommand(() => ({
|
||||
commandType: 'openPostForm',
|
||||
handler: (cmd) => openForm(),
|
||||
handler: () => {
|
||||
openForm();
|
||||
setTimeout(() => textAreaRef?.focus?.(), 100);
|
||||
},
|
||||
}));
|
||||
|
||||
return (
|
||||
@@ -48,8 +55,13 @@ const SideBar: Component = () => {
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<Show when={formOpened()}>
|
||||
<NotePostForm onClose={closeForm} />
|
||||
<Show when={formOpened() || config().keepOpenPostForm}>
|
||||
<NotePostForm
|
||||
textAreaRef={(el) => {
|
||||
textAreaRef = el;
|
||||
}}
|
||||
onClose={closeForm}
|
||||
/>
|
||||
</Show>
|
||||
<Show when={configOpened()}>
|
||||
<Config onClose={() => setConfigOpened(false)} />
|
||||
|
||||
@@ -42,6 +42,7 @@ const TextNoteDisplay: Component<TextNoteDisplayProps> = (props) => {
|
||||
const pubkey = usePubkey();
|
||||
|
||||
const [showReplyForm, setShowReplyForm] = createSignal(false);
|
||||
const closeReplyForm = () => setShowReplyForm(false);
|
||||
const [showMenu, setShowMenu] = createSignal(false);
|
||||
|
||||
const event = createMemo(() => eventWrapper(props.event));
|
||||
@@ -255,7 +256,12 @@ const TextNoteDisplay: Component<TextNoteDisplayProps> = (props) => {
|
||||
</div>
|
||||
</div>
|
||||
<Show when={showReplyForm()}>
|
||||
<NotePostForm mode="reply" replyTo={props.event} onClose={() => setShowReplyForm(false)} />
|
||||
<NotePostForm
|
||||
mode="reply"
|
||||
replyTo={props.event}
|
||||
onClose={closeReplyForm}
|
||||
onPost={closeReplyForm}
|
||||
/>
|
||||
</Show>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -112,7 +112,7 @@ export const parseTextNote = (event: NostrEvent): ParsedTextNote => {
|
||||
}
|
||||
} else if (match.groups?.nip19 && match.index >= pos) {
|
||||
try {
|
||||
const decoded = decode(match[0].toLowerCase());
|
||||
const decoded = decode(match[0]);
|
||||
const bech32Entity: Bech32Entity = {
|
||||
type: 'Bech32Entity',
|
||||
content: match[0],
|
||||
|
||||
@@ -7,6 +7,7 @@ import {
|
||||
export type Config = {
|
||||
relayUrls: string[];
|
||||
dateFormat: 'relative' | 'absolute-long' | 'absolute-short';
|
||||
keepOpenPostForm: boolean;
|
||||
};
|
||||
|
||||
type UseConfig = {
|
||||
@@ -29,6 +30,7 @@ const InitialConfig: Config = {
|
||||
'wss://nostr.holybea.com',
|
||||
],
|
||||
dateFormat: 'relative',
|
||||
keepOpenPostForm: false,
|
||||
};
|
||||
|
||||
const serializer = (config: Config): string => JSON.stringify(config);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { createSignal, createEffect, onMount, type Component, onCleanup } from 'solid-js';
|
||||
import { useNavigate } from '@solidjs/router';
|
||||
import uniq from 'lodash/uniq';
|
||||
|
||||
import Column from '@/components/Column';
|
||||
import SideBar from '@/components/SideBar';
|
||||
@@ -48,7 +49,7 @@ const Home: Component = () => {
|
||||
filters: [
|
||||
{
|
||||
kinds: [1, 6],
|
||||
authors: followingPubkeys(),
|
||||
authors: uniq([...followingPubkeys(), pubkeyNonNull]),
|
||||
limit: 25,
|
||||
since: Math.floor(Date.now() / 1000) - 12 * 60 * 60,
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user