mirror of
https://github.com/luminous-devs/lume.git
synced 2024-09-18 11:13:30 +00:00
add topic widget
This commit is contained in:
parent
108ecafab7
commit
cb9006abb2
@ -6,7 +6,7 @@ import { useStorage } from '@libs/storage/provider';
|
||||
|
||||
import { ArrowLeftIcon, CheckCircleIcon, LoaderIcon } from '@shared/icons';
|
||||
|
||||
import { HASHTAGS, WidgetKinds } from '@stores/constants';
|
||||
import { HASHTAGS, WIDGET_KIND } from '@stores/constants';
|
||||
import { useOnboarding } from '@stores/onboarding';
|
||||
|
||||
export function OnboardHashtagScreen() {
|
||||
@ -35,7 +35,7 @@ export function OnboardHashtagScreen() {
|
||||
setLoading(true);
|
||||
|
||||
for (const tag of tags) {
|
||||
await db.createWidget(WidgetKinds.global.hashtag, tag, tag.replace('#', ''));
|
||||
await db.createWidget(WIDGET_KIND.global.hashtag, tag, tag.replace('#', ''));
|
||||
}
|
||||
|
||||
setHashtag();
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { PlusIcon } from '@shared/icons';
|
||||
import { WidgetWrapper } from '@shared/widgets';
|
||||
|
||||
import { WidgetKinds } from '@stores/constants';
|
||||
import { WIDGET_KIND } from '@stores/constants';
|
||||
|
||||
import { useWidget } from '@utils/hooks/useWidget';
|
||||
|
||||
@ -14,7 +14,7 @@ export function ToggleWidgetList() {
|
||||
<button
|
||||
type="button"
|
||||
onClick={() =>
|
||||
addWidget.mutate({ kind: WidgetKinds.tmp.list, title: '', content: '' })
|
||||
addWidget.mutate({ kind: WIDGET_KIND.tmp.list, title: '', content: '' })
|
||||
}
|
||||
className="inline-flex h-9 items-center gap-2 rounded-full bg-neutral-200 px-3 text-neutral-900 hover:bg-neutral-300 dark:bg-neutral-800 dark:text-neutral-100 dark:hover:bg-neutral-700"
|
||||
>
|
||||
|
@ -13,7 +13,7 @@ import {
|
||||
import { TitleBar } from '@shared/titleBar';
|
||||
import { WidgetWrapper } from '@shared/widgets';
|
||||
|
||||
import { DefaultWidgets, WidgetKinds } from '@stores/constants';
|
||||
import { DEFAULT_WIDGETS, WIDGET_KIND } from '@stores/constants';
|
||||
|
||||
import { useWidget } from '@utils/hooks/useWidget';
|
||||
import { Widget, WidgetGroup, WidgetGroupItem } from '@utils/types';
|
||||
@ -22,55 +22,48 @@ export function WidgetList({ params }: { params: Widget }) {
|
||||
const { addWidget, removeWidget } = useWidget();
|
||||
|
||||
const open = (item: WidgetGroupItem) => {
|
||||
addWidget.mutate({ kind: item.kind, title: item.title, content: '' });
|
||||
addWidget.mutate({
|
||||
kind: item.kind,
|
||||
title: item.title,
|
||||
content: JSON.stringify(item.content),
|
||||
});
|
||||
removeWidget.mutate(params.id);
|
||||
};
|
||||
|
||||
const renderIcon = useCallback(
|
||||
(kind: number) => {
|
||||
const renderIcon = useCallback((kind: number) => {
|
||||
switch (kind) {
|
||||
case WidgetKinds.tmp.xfeed:
|
||||
case WIDGET_KIND.tmp.xfeed:
|
||||
return (
|
||||
<GroupFeedsIcon className="h-5 w-5 text-neutral-900 dark:text-neutral-100" />
|
||||
);
|
||||
case WidgetKinds.local.follows:
|
||||
return (
|
||||
<FollowsIcon className="h-5 w-5 text-neutral-900 dark:text-neutral-100" />
|
||||
);
|
||||
case WidgetKinds.local.files:
|
||||
case WidgetKinds.global.files:
|
||||
case WIDGET_KIND.local.follows:
|
||||
return <FollowsIcon className="h-5 w-5 text-neutral-900 dark:text-neutral-100" />;
|
||||
case WIDGET_KIND.local.files:
|
||||
case WIDGET_KIND.global.files:
|
||||
return <FileIcon className="h-5 w-5 text-neutral-900 dark:text-neutral-100" />;
|
||||
case WidgetKinds.local.articles:
|
||||
case WidgetKinds.global.articles:
|
||||
return (
|
||||
<ArticleIcon className="h-5 w-5 text-neutral-900 dark:text-neutral-100" />
|
||||
);
|
||||
case WidgetKinds.tmp.xhashtag:
|
||||
return (
|
||||
<HashtagIcon className="h-5 w-5 text-neutral-900 dark:text-neutral-100" />
|
||||
);
|
||||
case WidgetKinds.nostrBand.trendingAccounts:
|
||||
case WidgetKinds.nostrBand.trendingNotes:
|
||||
case WIDGET_KIND.local.articles:
|
||||
case WIDGET_KIND.global.articles:
|
||||
return <ArticleIcon className="h-5 w-5 text-neutral-900 dark:text-neutral-100" />;
|
||||
case WIDGET_KIND.tmp.xhashtag:
|
||||
return <HashtagIcon className="h-5 w-5 text-neutral-900 dark:text-neutral-100" />;
|
||||
case WIDGET_KIND.nostrBand.trendingAccounts:
|
||||
case WIDGET_KIND.nostrBand.trendingNotes:
|
||||
return (
|
||||
<TrendingIcon className="h-5 w-5 text-neutral-900 dark:text-neutral-100" />
|
||||
);
|
||||
case WidgetKinds.local.notification:
|
||||
case WIDGET_KIND.local.notification:
|
||||
return <BellIcon className="h-5 w-5 text-neutral-900 dark:text-neutral-100" />;
|
||||
case WidgetKinds.other.learnNostr:
|
||||
return (
|
||||
<ThreadsIcon className="h-5 w-5 text-neutral-900 dark:text-neutral-100" />
|
||||
);
|
||||
case WIDGET_KIND.other.learnNostr:
|
||||
return <ThreadsIcon className="h-5 w-5 text-neutral-900 dark:text-neutral-100" />;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
},
|
||||
[DefaultWidgets]
|
||||
);
|
||||
}, []);
|
||||
|
||||
const renderItem = useCallback((row: WidgetGroup, index: number) => {
|
||||
return (
|
||||
<div key={index} className="flex flex-col gap-2">
|
||||
<h3 className="text-sm font-semibold">{row.title}</h3>
|
||||
<h3 className="font-semibold">{row.title}</h3>
|
||||
<div className="flex flex-col divide-y divide-neutral-200 overflow-hidden rounded-xl bg-neutral-100 dark:divide-neutral-800 dark:bg-neutral-900">
|
||||
{row.data.map((item, index) => (
|
||||
<button
|
||||
@ -111,7 +104,7 @@ export function WidgetList({ params }: { params: Widget }) {
|
||||
<TitleBar id={params.id} title="Add widget" />
|
||||
<div className="flex-1 overflow-y-auto pb-10 scrollbar-none">
|
||||
<div className="flex flex-col gap-6 px-3">
|
||||
{DefaultWidgets.map((row: WidgetGroup, index: number) =>
|
||||
{DEFAULT_WIDGETS.map((row: WidgetGroup, index: number) =>
|
||||
renderItem(row, index)
|
||||
)}
|
||||
<div className="border-t border-neutral-200 pt-6 dark:border-neutral-800">
|
||||
|
@ -25,7 +25,7 @@ import {
|
||||
XhashtagWidget,
|
||||
} from '@shared/widgets';
|
||||
|
||||
import { WidgetKinds } from '@stores/constants';
|
||||
import { WIDGET_KIND } from '@stores/constants';
|
||||
|
||||
import { Widget } from '@utils/types';
|
||||
|
||||
@ -43,13 +43,13 @@ export function SpaceScreen() {
|
||||
id: '9998',
|
||||
title: 'Notification',
|
||||
content: '',
|
||||
kind: WidgetKinds.local.notification,
|
||||
kind: WIDGET_KIND.local.notification,
|
||||
},
|
||||
{
|
||||
id: '9999',
|
||||
title: 'Newsfeed',
|
||||
content: '',
|
||||
kind: WidgetKinds.local.network,
|
||||
kind: WIDGET_KIND.local.network,
|
||||
},
|
||||
];
|
||||
|
||||
@ -63,35 +63,35 @@ export function SpaceScreen() {
|
||||
|
||||
const renderItem = useCallback((widget: Widget) => {
|
||||
switch (widget.kind) {
|
||||
case WidgetKinds.local.feeds:
|
||||
case WIDGET_KIND.local.feeds:
|
||||
return <LocalFeedsWidget key={widget.id} params={widget} />;
|
||||
case WidgetKinds.local.files:
|
||||
case WIDGET_KIND.local.files:
|
||||
return <LocalFilesWidget key={widget.id} params={widget} />;
|
||||
case WidgetKinds.local.articles:
|
||||
case WIDGET_KIND.local.articles:
|
||||
return <LocalArticlesWidget key={widget.id} params={widget} />;
|
||||
case WidgetKinds.local.user:
|
||||
case WIDGET_KIND.local.user:
|
||||
return <LocalUserWidget key={widget.id} params={widget} />;
|
||||
case WidgetKinds.local.thread:
|
||||
case WIDGET_KIND.local.thread:
|
||||
return <LocalThreadWidget key={widget.id} params={widget} />;
|
||||
case WidgetKinds.global.hashtag:
|
||||
case WIDGET_KIND.global.hashtag:
|
||||
return <GlobalHashtagWidget key={widget.id} params={widget} />;
|
||||
case WidgetKinds.global.articles:
|
||||
case WIDGET_KIND.global.articles:
|
||||
return <GlobalArticlesWidget key={widget.id} params={widget} />;
|
||||
case WidgetKinds.global.files:
|
||||
case WIDGET_KIND.global.files:
|
||||
return <GlobalFilesWidget key={widget.id} params={widget} />;
|
||||
case WidgetKinds.nostrBand.trendingAccounts:
|
||||
case WIDGET_KIND.nostrBand.trendingAccounts:
|
||||
return <TrendingAccountsWidget key={widget.id} params={widget} />;
|
||||
case WidgetKinds.nostrBand.trendingNotes:
|
||||
case WIDGET_KIND.nostrBand.trendingNotes:
|
||||
return <TrendingNotesWidget key={widget.id} params={widget} />;
|
||||
case WidgetKinds.tmp.xfeed:
|
||||
case WIDGET_KIND.tmp.xfeed:
|
||||
return <XfeedsWidget key={widget.id} params={widget} />;
|
||||
case WidgetKinds.tmp.xhashtag:
|
||||
case WIDGET_KIND.tmp.xhashtag:
|
||||
return <XhashtagWidget key={widget.id} params={widget} />;
|
||||
case WidgetKinds.tmp.list:
|
||||
case WIDGET_KIND.tmp.list:
|
||||
return <WidgetList key={widget.id} params={widget} />;
|
||||
case WidgetKinds.local.notification:
|
||||
case WIDGET_KIND.local.notification:
|
||||
return <NotificationWidget key={widget.id} />;
|
||||
case WidgetKinds.local.network:
|
||||
case WIDGET_KIND.local.network:
|
||||
return <NewsfeedWidget key={widget.id} />;
|
||||
default:
|
||||
return null;
|
||||
|
@ -6,7 +6,7 @@ import { NoteReply } from '@shared/notes/actions/reply';
|
||||
import { NoteRepost } from '@shared/notes/actions/repost';
|
||||
import { NoteZap } from '@shared/notes/actions/zap';
|
||||
|
||||
import { WidgetKinds } from '@stores/constants';
|
||||
import { WIDGET_KIND } from '@stores/constants';
|
||||
|
||||
import { useWidget } from '@utils/hooks/useWidget';
|
||||
|
||||
@ -34,7 +34,7 @@ export function NoteActions({
|
||||
type="button"
|
||||
onClick={() =>
|
||||
addWidget.mutate({
|
||||
kind: WidgetKinds.local.thread,
|
||||
kind: WIDGET_KIND.local.thread,
|
||||
title: 'Thread',
|
||||
content: id,
|
||||
})
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { WidgetKinds } from '@stores/constants';
|
||||
import { WIDGET_KIND } from '@stores/constants';
|
||||
|
||||
import { useWidget } from '@utils/hooks/useWidget';
|
||||
|
||||
@ -10,7 +10,7 @@ export function Hashtag({ tag }: { tag: string }) {
|
||||
type="button"
|
||||
onClick={() =>
|
||||
addWidget.mutate({
|
||||
kind: WidgetKinds.global.hashtag,
|
||||
kind: WIDGET_KIND.global.hashtag,
|
||||
title: tag,
|
||||
content: tag.replace('#', ''),
|
||||
})
|
||||
|
@ -9,7 +9,7 @@ import {
|
||||
} from '@shared/notes';
|
||||
import { User } from '@shared/user';
|
||||
|
||||
import { WidgetKinds } from '@stores/constants';
|
||||
import { WIDGET_KIND } from '@stores/constants';
|
||||
|
||||
import { useEvent } from '@utils/hooks/useEvent';
|
||||
import { useWidget } from '@utils/hooks/useWidget';
|
||||
@ -50,7 +50,7 @@ export const MentionNote = memo(function MentionNote({ id }: { id: string }) {
|
||||
type="button"
|
||||
onClick={() =>
|
||||
addWidget.mutate({
|
||||
kind: WidgetKinds.local.thread,
|
||||
kind: WIDGET_KIND.local.thread,
|
||||
title: 'Thread',
|
||||
content: data.id,
|
||||
})
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { memo } from 'react';
|
||||
|
||||
import { WidgetKinds } from '@stores/constants';
|
||||
import { WIDGET_KIND } from '@stores/constants';
|
||||
|
||||
import { useProfile } from '@utils/hooks/useProfile';
|
||||
import { useWidget } from '@utils/hooks/useWidget';
|
||||
@ -14,14 +14,14 @@ export const MentionUser = memo(function MentionUser({ pubkey }: { pubkey: strin
|
||||
type="button"
|
||||
onClick={() =>
|
||||
addWidget.mutate({
|
||||
kind: WidgetKinds.local.user,
|
||||
kind: WIDGET_KIND.local.user,
|
||||
title: user?.name || user?.display_name || user?.displayName,
|
||||
content: pubkey,
|
||||
})
|
||||
}
|
||||
onKeyDown={() =>
|
||||
addWidget.mutate({
|
||||
kind: WidgetKinds.local.user,
|
||||
kind: WIDGET_KIND.local.user,
|
||||
title: user?.name || user?.display_name || user?.displayName,
|
||||
content: pubkey,
|
||||
})
|
||||
|
@ -10,7 +10,7 @@ import {
|
||||
} from '@shared/notes';
|
||||
import { User } from '@shared/user';
|
||||
|
||||
import { WidgetKinds } from '@stores/constants';
|
||||
import { WIDGET_KIND } from '@stores/constants';
|
||||
|
||||
import { formatCreatedAt } from '@utils/createdAt';
|
||||
import { useEvent } from '@utils/hooks/useEvent';
|
||||
@ -91,7 +91,7 @@ export function NotifyNote({ event }: { event: NDKEvent }) {
|
||||
type="button"
|
||||
onClick={() =>
|
||||
addWidget.mutate({
|
||||
kind: WidgetKinds.local.thread,
|
||||
kind: WIDGET_KIND.local.thread,
|
||||
title: 'Thread',
|
||||
content: data.id,
|
||||
})
|
||||
|
@ -4,7 +4,7 @@ import { memo } from 'react';
|
||||
import { ChildNote, NoteActions } from '@shared/notes';
|
||||
import { User } from '@shared/user';
|
||||
|
||||
import { WidgetKinds } from '@stores/constants';
|
||||
import { WIDGET_KIND } from '@stores/constants';
|
||||
|
||||
import { useNostr } from '@utils/hooks/useNostr';
|
||||
import { useRichContent } from '@utils/hooks/useRichContent';
|
||||
@ -30,7 +30,7 @@ export function TextNote({ event }: { event: NDKEvent }) {
|
||||
type="button"
|
||||
onClick={() =>
|
||||
addWidget.mutate({
|
||||
kind: WidgetKinds.local.thread,
|
||||
kind: WIDGET_KIND.local.thread,
|
||||
title: 'Thread',
|
||||
content: thread.rootEventId,
|
||||
})
|
||||
|
@ -14,3 +14,4 @@ export * from './tmp/hashtag';
|
||||
export * from './newsfeed';
|
||||
export * from './notification';
|
||||
export * from './liveUpdater';
|
||||
export * from './topic';
|
||||
|
@ -6,7 +6,7 @@ import { ArrowRightCircleIcon, CancelIcon, CheckCircleIcon } from '@shared/icons
|
||||
import { User } from '@shared/user';
|
||||
import { WidgetWrapper } from '@shared/widgets';
|
||||
|
||||
import { WidgetKinds } from '@stores/constants';
|
||||
import { WIDGET_KIND } from '@stores/constants';
|
||||
|
||||
import { useWidget } from '@utils/hooks/useWidget';
|
||||
import { Widget } from '@utils/types';
|
||||
@ -28,7 +28,7 @@ export function XfeedsWidget({ params }: { params: Widget }) {
|
||||
|
||||
const submit = async () => {
|
||||
addWidget.mutate({
|
||||
kind: WidgetKinds.local.feeds,
|
||||
kind: WIDGET_KIND.local.feeds,
|
||||
title: title || 'Group',
|
||||
content: JSON.stringify(groups),
|
||||
});
|
||||
|
@ -3,7 +3,7 @@ import { Resolver, useForm } from 'react-hook-form';
|
||||
import { ArrowRightCircleIcon, CancelIcon } from '@shared/icons';
|
||||
import { WidgetWrapper } from '@shared/widgets';
|
||||
|
||||
import { HASHTAGS, WidgetKinds } from '@stores/constants';
|
||||
import { HASHTAGS, WIDGET_KIND } from '@stores/constants';
|
||||
|
||||
import { useWidget } from '@utils/hooks/useWidget';
|
||||
import { Widget } from '@utils/types';
|
||||
@ -39,7 +39,7 @@ export function XhashtagWidget({ params }: { params: Widget }) {
|
||||
const onSubmit = async (data: FormValues) => {
|
||||
try {
|
||||
addWidget.mutate({
|
||||
kind: WidgetKinds.global.hashtag,
|
||||
kind: WIDGET_KIND.global.hashtag,
|
||||
title: data.hashtag,
|
||||
content: data.hashtag.replace('#', ''),
|
||||
});
|
||||
|
128
src/shared/widgets/topic.tsx
Normal file
128
src/shared/widgets/topic.tsx
Normal file
@ -0,0 +1,128 @@
|
||||
import { NDKEvent, NDKKind } from '@nostr-dev-kit/ndk';
|
||||
import { useInfiniteQuery } from '@tanstack/react-query';
|
||||
import { useCallback, useMemo } from 'react';
|
||||
import { VList } from 'virtua';
|
||||
|
||||
import { useNDK } from '@libs/ndk/provider';
|
||||
|
||||
import { ArrowRightCircleIcon, LoaderIcon } from '@shared/icons';
|
||||
import {
|
||||
MemoizedRepost,
|
||||
MemoizedTextNote,
|
||||
NoteSkeleton,
|
||||
UnknownNote,
|
||||
} from '@shared/notes';
|
||||
import { TitleBar } from '@shared/titleBar';
|
||||
import { WidgetWrapper } from '@shared/widgets';
|
||||
|
||||
import { FETCH_LIMIT } from '@stores/constants';
|
||||
|
||||
import { Widget } from '@utils/types';
|
||||
|
||||
export function TopicWidget({ widget }: { widget: Widget }) {
|
||||
const { relayUrls, ndk, fetcher } = useNDK();
|
||||
const { status, data, hasNextPage, isFetchingNextPage, fetchNextPage } =
|
||||
useInfiniteQuery({
|
||||
queryKey: [widget.title],
|
||||
initialPageParam: 0,
|
||||
queryFn: async ({
|
||||
signal,
|
||||
pageParam,
|
||||
}: {
|
||||
signal: AbortSignal;
|
||||
pageParam: number;
|
||||
}) => {
|
||||
const hashtags: string[] = JSON.parse(widget.content as string);
|
||||
const rootIds = new Set();
|
||||
const dedupQueue = new Set();
|
||||
|
||||
const events = await fetcher.fetchLatestEvents(
|
||||
relayUrls,
|
||||
{
|
||||
kinds: [NDKKind.Text, NDKKind.Repost],
|
||||
'#t': hashtags,
|
||||
},
|
||||
FETCH_LIMIT,
|
||||
{ asOf: pageParam === 0 ? undefined : pageParam, abortSignal: signal }
|
||||
);
|
||||
|
||||
const ndkEvents = events.map((event) => {
|
||||
return new NDKEvent(ndk, event);
|
||||
});
|
||||
|
||||
ndkEvents.forEach((event) => {
|
||||
const tags = event.tags.filter((el) => el[0] === 'e');
|
||||
if (tags && tags.length > 0) {
|
||||
const rootId = tags.filter((el) => el[3] === 'root')[1] ?? tags[0][1];
|
||||
if (rootIds.has(rootId)) return dedupQueue.add(event.id);
|
||||
rootIds.add(rootId);
|
||||
}
|
||||
});
|
||||
|
||||
return ndkEvents
|
||||
.filter((event) => !dedupQueue.has(event.id))
|
||||
.sort((a, b) => b.created_at - a.created_at);
|
||||
},
|
||||
getNextPageParam: (lastPage) => {
|
||||
const lastEvent = lastPage.at(-1);
|
||||
if (!lastEvent) return;
|
||||
return lastEvent.created_at - 1;
|
||||
},
|
||||
refetchOnWindowFocus: false,
|
||||
});
|
||||
|
||||
const allEvents = useMemo(
|
||||
() => (data ? data.pages.flatMap((page) => page) : []),
|
||||
[data]
|
||||
);
|
||||
|
||||
const renderItem = useCallback(
|
||||
(event: NDKEvent) => {
|
||||
switch (event.kind) {
|
||||
case NDKKind.Text:
|
||||
return <MemoizedTextNote key={event.id} event={event} />;
|
||||
case NDKKind.Repost:
|
||||
return <MemoizedRepost key={event.id} event={event} />;
|
||||
default:
|
||||
return <UnknownNote key={event.id} event={event} />;
|
||||
}
|
||||
},
|
||||
[data]
|
||||
);
|
||||
|
||||
return (
|
||||
<WidgetWrapper>
|
||||
<TitleBar id={widget.id} title={widget.title} />
|
||||
<VList className="flex-1" overscan={2}>
|
||||
{status === 'pending' ? (
|
||||
<div className="px-3 py-1.5">
|
||||
<div className="rounded-xl bg-neutral-100 px-3 py-3 dark:bg-neutral-900">
|
||||
<NoteSkeleton />
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
allEvents.map((item) => renderItem(item))
|
||||
)}
|
||||
<div className="flex h-16 items-center justify-center px-3 pb-3">
|
||||
{hasNextPage ? (
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => fetchNextPage()}
|
||||
disabled={!hasNextPage || isFetchingNextPage}
|
||||
className="inline-flex h-10 w-max items-center justify-center gap-2 rounded-full bg-blue-500 px-6 font-medium text-white hover:bg-blue-600 focus:outline-none"
|
||||
>
|
||||
{isFetchingNextPage ? (
|
||||
<LoaderIcon className="h-4 w-4 animate-spin" />
|
||||
) : (
|
||||
<>
|
||||
<ArrowRightCircleIcon className="h-5 w-5" />
|
||||
Load more
|
||||
</>
|
||||
)}
|
||||
</button>
|
||||
) : null}
|
||||
</div>
|
||||
</VList>
|
||||
</WidgetWrapper>
|
||||
);
|
||||
}
|
@ -41,7 +41,7 @@ export const HASHTAGS = [
|
||||
{ hashtag: '#primal' },
|
||||
];
|
||||
|
||||
export const WidgetKinds = {
|
||||
export const WIDGET_KIND = {
|
||||
local: {
|
||||
network: 100,
|
||||
feeds: 101,
|
||||
@ -57,6 +57,7 @@ export const WidgetKinds = {
|
||||
files: 1001,
|
||||
articles: 1002,
|
||||
hashtag: 1003,
|
||||
topic: 108,
|
||||
},
|
||||
nostrBand: {
|
||||
trendingAccounts: 1,
|
||||
@ -72,24 +73,293 @@ export const WidgetKinds = {
|
||||
},
|
||||
};
|
||||
|
||||
export const DefaultWidgets: Array<WidgetGroup> = [
|
||||
export const TOPICS = [
|
||||
{
|
||||
title: 'Gaming',
|
||||
description: '',
|
||||
kind: WIDGET_KIND.global.topic,
|
||||
content: [
|
||||
'#gamestr',
|
||||
'#gaming',
|
||||
'#gamer',
|
||||
'#ps',
|
||||
'#playstation',
|
||||
'#videogames',
|
||||
'#game',
|
||||
'#xbox',
|
||||
'#games',
|
||||
'#twitch',
|
||||
'#fortnite',
|
||||
'#pc',
|
||||
'#memes',
|
||||
'#pcgaming',
|
||||
'#gamers',
|
||||
'#gamingcommunity',
|
||||
'#youtube',
|
||||
'#switch',
|
||||
'#gamergirl',
|
||||
'#nintendo',
|
||||
'#gta',
|
||||
'#callofduty',
|
||||
'#streamer',
|
||||
'#follow',
|
||||
'#pubg',
|
||||
'#videogame',
|
||||
'#esports',
|
||||
'#bhfyp',
|
||||
'#meme',
|
||||
'#twitchstreamer',
|
||||
'#art',
|
||||
'#genshinimpact',
|
||||
'#honkaiimpact',
|
||||
'#warthunder',
|
||||
'#hovoverse',
|
||||
'#arknights',
|
||||
'#soul',
|
||||
'#eldenring',
|
||||
'#steam',
|
||||
'#pubg',
|
||||
'#cs2',
|
||||
'#apexlegends',
|
||||
'#baldurgate3',
|
||||
'#starfield',
|
||||
'#gta6',
|
||||
'#gameoftheyear',
|
||||
],
|
||||
},
|
||||
{
|
||||
title: 'Music',
|
||||
description: '',
|
||||
kind: WIDGET_KIND.global.topic,
|
||||
content: [
|
||||
'#audiostr',
|
||||
'#musicstr',
|
||||
'#music',
|
||||
'#love',
|
||||
'#hiphop',
|
||||
'#rap',
|
||||
'#art',
|
||||
'#musician',
|
||||
'#artist',
|
||||
'#musica',
|
||||
'#instagood',
|
||||
'#singer',
|
||||
'#dj',
|
||||
'#follow',
|
||||
'#rock',
|
||||
'#like',
|
||||
'#dance',
|
||||
'#guitar',
|
||||
'#s',
|
||||
'#photography',
|
||||
'#song',
|
||||
'#bhfyp',
|
||||
'#newmusic',
|
||||
'#producer',
|
||||
'#life',
|
||||
'#rapper',
|
||||
'#party',
|
||||
'#fashion',
|
||||
'#explorepage',
|
||||
'#viral',
|
||||
'#beats',
|
||||
],
|
||||
},
|
||||
{
|
||||
title: 'Photography',
|
||||
description: '',
|
||||
kind: WIDGET_KIND.global.topic,
|
||||
content: [
|
||||
'#photography',
|
||||
'#photooftheday',
|
||||
'#love',
|
||||
'#photo',
|
||||
'#nature',
|
||||
'#picoftheday',
|
||||
'#like',
|
||||
'#photographer',
|
||||
'#beautiful',
|
||||
'#follow',
|
||||
'#art',
|
||||
'#fashion',
|
||||
'#travel',
|
||||
'#bhfyp',
|
||||
'#photoshoot',
|
||||
'#likeforlikes',
|
||||
'#instadaily',
|
||||
'#naturephotography',
|
||||
'#model',
|
||||
'#me',
|
||||
'#smile',
|
||||
'#style',
|
||||
'#instalike',
|
||||
'#happy',
|
||||
'#likes',
|
||||
'#myself',
|
||||
'#followme',
|
||||
'#followforfollowback',
|
||||
],
|
||||
},
|
||||
{
|
||||
title: 'Art',
|
||||
description: '',
|
||||
kind: WIDGET_KIND.global.topic,
|
||||
content: [
|
||||
'#artstr',
|
||||
'#art',
|
||||
'#artist',
|
||||
'#love',
|
||||
'#drawing',
|
||||
'#photography',
|
||||
'#artwork',
|
||||
'#instagood',
|
||||
'#photooftheday',
|
||||
'#painting',
|
||||
'#fashion',
|
||||
'#like',
|
||||
'#artistsoninstagram',
|
||||
'#beautiful',
|
||||
'#illustration',
|
||||
'#digitalart',
|
||||
'#follow',
|
||||
'#design',
|
||||
'#nature',
|
||||
'#picoftheday',
|
||||
'#photo',
|
||||
'#bhfyp',
|
||||
'#sketch',
|
||||
'#style',
|
||||
'#arte',
|
||||
'#happy',
|
||||
'#cute',
|
||||
'#draw',
|
||||
'#artoftheday',
|
||||
],
|
||||
},
|
||||
{
|
||||
title: 'Movie',
|
||||
description: '',
|
||||
kind: WIDGET_KIND.global.topic,
|
||||
content: [
|
||||
'#filmstr',
|
||||
'#moviestr',
|
||||
'#movies',
|
||||
'#movie',
|
||||
'#film',
|
||||
'#cinema',
|
||||
'#films',
|
||||
'#hollywood',
|
||||
'#actor',
|
||||
'#love',
|
||||
'#s',
|
||||
'#art',
|
||||
'#cinematography',
|
||||
'#actress',
|
||||
'#netflix',
|
||||
'#moviescenes',
|
||||
'#music',
|
||||
'#filmmaking',
|
||||
'#horror',
|
||||
'#instagood',
|
||||
'#bollywood',
|
||||
'#movienight',
|
||||
'#photography',
|
||||
'#comedy',
|
||||
'#cinephile',
|
||||
'#cine',
|
||||
'#tv',
|
||||
'#director',
|
||||
'#horrormovies',
|
||||
'#drama',
|
||||
'#filmmaker',
|
||||
],
|
||||
},
|
||||
{
|
||||
title: 'Technology',
|
||||
description: '',
|
||||
kind: WIDGET_KIND.global.topic,
|
||||
content: [
|
||||
'#apple',
|
||||
'#xiaomi',
|
||||
'#huawei',
|
||||
'#ai',
|
||||
'#oppo',
|
||||
'#nostr',
|
||||
'#technology',
|
||||
'#tech',
|
||||
'#innovation',
|
||||
'#engineering',
|
||||
'#business',
|
||||
'#iphone',
|
||||
'#technews',
|
||||
'#science',
|
||||
'#design',
|
||||
'#gadgets',
|
||||
'#electronics',
|
||||
'#android',
|
||||
'#software',
|
||||
'#programming',
|
||||
'#smartphone',
|
||||
'#bhfyp',
|
||||
'#samsung',
|
||||
'#instagood',
|
||||
'#coding',
|
||||
'#computer',
|
||||
'#pro',
|
||||
'#education',
|
||||
'#security',
|
||||
'#gadget',
|
||||
'#mobile',
|
||||
'#technologynews',
|
||||
],
|
||||
},
|
||||
{
|
||||
title: 'Anime',
|
||||
description: '',
|
||||
kind: WIDGET_KIND.global.topic,
|
||||
content: [
|
||||
'#animestr',
|
||||
'#anime',
|
||||
'#manga',
|
||||
'#ntr',
|
||||
'#otaku',
|
||||
'#animeart',
|
||||
'#animegirl',
|
||||
'#cosplay',
|
||||
'#kawaii',
|
||||
'#weeb',
|
||||
'#onepiece',
|
||||
'#demonslayer',
|
||||
'#animeworld',
|
||||
'#aot',
|
||||
'#hentai',
|
||||
'#fanart',
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
export const DEFAULT_WIDGETS: Array<WidgetGroup> = [
|
||||
{
|
||||
title: 'Topics',
|
||||
data: TOPICS,
|
||||
},
|
||||
{
|
||||
title: 'Local',
|
||||
data: [
|
||||
{
|
||||
kind: WidgetKinds.tmp.xfeed,
|
||||
kind: WIDGET_KIND.tmp.xfeed,
|
||||
title: 'Group feeds',
|
||||
description: 'All posts from specific people you want to keep up with',
|
||||
},
|
||||
{
|
||||
kind: WidgetKinds.local.files,
|
||||
kind: WIDGET_KIND.local.files,
|
||||
title: 'Files',
|
||||
description: 'All files shared by people in your circle',
|
||||
description: 'All files shared by people you follow',
|
||||
},
|
||||
{
|
||||
kind: WidgetKinds.local.articles,
|
||||
kind: WIDGET_KIND.local.articles,
|
||||
title: 'Articles',
|
||||
description: 'All articles shared by people in your circle',
|
||||
description: 'All articles shared by people you follow',
|
||||
},
|
||||
],
|
||||
},
|
||||
@ -97,17 +367,17 @@ export const DefaultWidgets: Array<WidgetGroup> = [
|
||||
title: 'Global',
|
||||
data: [
|
||||
{
|
||||
kind: WidgetKinds.tmp.xhashtag,
|
||||
kind: WIDGET_KIND.tmp.xhashtag,
|
||||
title: 'Hashtag',
|
||||
description: 'All posts have a specific hashtag',
|
||||
},
|
||||
{
|
||||
kind: WidgetKinds.global.files,
|
||||
kind: WIDGET_KIND.global.files,
|
||||
title: 'Files',
|
||||
description: 'All files shared by people in your current relay set',
|
||||
},
|
||||
{
|
||||
kind: WidgetKinds.global.articles,
|
||||
kind: WIDGET_KIND.global.articles,
|
||||
title: 'Articles',
|
||||
description: 'All articles shared by people in your current relay set',
|
||||
},
|
||||
@ -117,12 +387,12 @@ export const DefaultWidgets: Array<WidgetGroup> = [
|
||||
title: 'nostr.band',
|
||||
data: [
|
||||
{
|
||||
kind: WidgetKinds.nostrBand.trendingAccounts,
|
||||
kind: WIDGET_KIND.nostrBand.trendingAccounts,
|
||||
title: 'Accounts',
|
||||
description: 'Trending accounts from the last 24 hours',
|
||||
},
|
||||
{
|
||||
kind: WidgetKinds.nostrBand.trendingNotes,
|
||||
kind: WIDGET_KIND.nostrBand.trendingNotes,
|
||||
title: 'Notes',
|
||||
description: 'Trending notes from the last 24 hours',
|
||||
},
|
||||
@ -132,7 +402,7 @@ export const DefaultWidgets: Array<WidgetGroup> = [
|
||||
title: 'Other',
|
||||
data: [
|
||||
{
|
||||
kind: WidgetKinds.local.notification,
|
||||
kind: WIDGET_KIND.local.notification,
|
||||
title: 'Notification',
|
||||
description: 'Everything happens around you',
|
||||
},
|
||||
|
1
src/utils/types.d.ts
vendored
1
src/utils/types.d.ts
vendored
@ -43,6 +43,7 @@ export interface WidgetGroup {
|
||||
export interface WidgetGroupItem {
|
||||
title: string;
|
||||
description: string;
|
||||
content: string;
|
||||
kind: number;
|
||||
icon?: string;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user