Files
rabbit/src/pages/Home.tsx
2023-04-21 23:42:41 +09:00

171 lines
4.6 KiB
TypeScript

import {
createSignal,
createEffect,
onMount,
onCleanup,
Show,
Switch,
Match,
type Component,
} from 'solid-js';
import { useNavigate } from '@solidjs/router';
import { createVirtualizer } from '@tanstack/solid-virtual';
import uniq from 'lodash/uniq';
import Column from '@/components/Column';
import SideBar from '@/components/SideBar';
import Timeline from '@/components/Timeline';
import Notification from '@/components/Notification';
import ProfileDisplay from '@/components/ProfileDisplay';
import usePool from '@/nostr/usePool';
import useConfig from '@/nostr/useConfig';
import useSubscription from '@/nostr/useSubscription';
import useFollowings from '@/nostr/useFollowings';
import usePubkey from '@/nostr/usePubkey';
import { useMountShortcutKeys } from '@/hooks/useShortcutKeys';
import usePersistStatus from '@/hooks/usePersistStatus';
import useModalState from '@/hooks/useModalState';
import ensureNonNull from '@/utils/ensureNonNull';
import epoch from '@/utils/epoch';
const Home: Component = () => {
useMountShortcutKeys();
const navigate = useNavigate();
const { persistStatus } = usePersistStatus();
const { modalState, closeModal } = useModalState();
const pool = usePool();
const { config } = useConfig();
const pubkey = usePubkey();
createEffect(() => {
config().relayUrls.map(async (relayUrl) => {
const relay = await pool().ensureRelay(relayUrl);
relay.on('notice', (msg: string) => {
console.error(`NOTICE: ${relayUrl}: ${msg}`);
});
});
});
const { followingPubkeys } = useFollowings(() =>
ensureNonNull([pubkey()] as const)(([pubkeyNonNull]) => ({
relayUrls: config().relayUrls,
pubkey: pubkeyNonNull,
})),
);
const { events: followingsPosts } = useSubscription(() => {
const authors = uniq([...followingPubkeys()]);
if (authors.length === 0) return null;
return {
relayUrls: config().relayUrls,
filters: [
{
kinds: [1, 6],
authors,
limit: 25,
},
],
};
});
const { events: myPosts } = useSubscription(() =>
ensureNonNull([pubkey()] as const)(([pubkeyNonNull]) => ({
relayUrls: config().relayUrls,
filters: [
{
kinds: [1, 6],
authors: [pubkeyNonNull],
limit: 25,
},
],
})),
);
const { events: myReactions } = useSubscription(() =>
ensureNonNull([pubkey()] as const)(([pubkeyNonNull]) => ({
relayUrls: config().relayUrls,
filters: [
{
kinds: [7],
authors: [pubkeyNonNull],
limit: 25,
},
],
})),
);
const { events: notifications } = useSubscription(() =>
ensureNonNull([pubkey()] as const)(([pubkeyNonNull]) => ({
relayUrls: config().relayUrls,
filters: [
{
kinds: [1, 6, 7],
'#p': [pubkeyNonNull],
limit: 25,
},
],
})),
);
const { events: localTimeline } = useSubscription(() => ({
relayUrls: [
'wss://relay-jp.nostr.wirednet.jp',
'wss://nostr.h3z.jp',
'wss://nostr.holybea.com',
],
filters: [
{
kinds: [1, 6],
limit: 25,
since: epoch() - 12 * 60 * 60,
},
],
}));
onMount(() => {
if (!persistStatus().loggedIn) {
navigate('/hello');
}
});
return (
<div class="absolute inset-0 flex w-screen touch-manipulation flex-row overflow-hidden">
<SideBar />
<div class="flex h-full snap-x snap-mandatory flex-row overflow-y-hidden overflow-x-scroll">
<Column name="ホーム" columnIndex={1} width="widest">
<Timeline events={followingsPosts()} />
</Column>
<Column name="通知" columnIndex={2} width="medium">
<Notification events={notifications()} />
</Column>
<Column name="日本リレー" columnIndex={3} width="medium">
<Timeline events={localTimeline()} />
</Column>
<Column name="自分の投稿" columnIndex={4} width="medium">
<Timeline events={myPosts()} />
</Column>
<Column name="自分のいいね" columnIndex={5} lastColumn width="medium">
<Notification events={myReactions()} />
</Column>
</div>
<Show when={modalState()} keyed>
{(state) => (
<Switch>
<Match when={state.type === 'Profile' && state.pubkey} keyed>
{(pubkeyNonNull: string) => (
<ProfileDisplay pubkey={pubkeyNonNull} onClose={closeModal} />
)}
</Match>
</Switch>
)}
</Show>
</div>
);
};
export default Home;