mirror of
https://github.com/PrimalHQ/primal-web-app.git
synced 2024-09-29 00:10:50 +00:00
Fix home sidebar refreshing when navigating to home
This commit is contained in:
parent
ccfb955a46
commit
674738ed01
@ -1,45 +1,17 @@
|
||||
import { Component, createEffect, createSignal, For, onCleanup, onMount, Show } from 'solid-js';
|
||||
import { createStore } from 'solid-js/store';
|
||||
import { APP_ID } from '../../App';
|
||||
import { getMostZapped4h, getTrending24h } from '../../lib/feed';
|
||||
import { humanizeNumber } from '../../lib/stats';
|
||||
import { convertToNotes, sortByRecency, sortingPlan } from '../../stores/note';
|
||||
import { Kind } from '../../constants';
|
||||
import { Component, For, onMount, Show } from 'solid-js';
|
||||
|
||||
import {
|
||||
isConnected,
|
||||
refreshSocketListeners,
|
||||
removeSocketListeners,
|
||||
socket,
|
||||
subscribeTo
|
||||
} from '../../sockets';
|
||||
import {
|
||||
FeedPage,
|
||||
NostrEOSE,
|
||||
NostrEvent,
|
||||
NostrEventContent,
|
||||
NostrMentionContent,
|
||||
NostrNoteActionsContent,
|
||||
NostrNoteContent,
|
||||
NostrStatsContent,
|
||||
NostrUserContent,
|
||||
NoteActions,
|
||||
PrimalNote,
|
||||
SelectionOption
|
||||
} from '../../types/primal';
|
||||
|
||||
import styles from './HomeSidebar.module.scss';
|
||||
import SmallNote from '../SmallNote/SmallNote';
|
||||
import { useIntl } from '@cookbook/solid-intl';
|
||||
import { hourNarrow } from '../../formats';
|
||||
|
||||
import { home as t } from '../../translations';
|
||||
import { useAccountContext } from '../../contexts/AccountContext';
|
||||
import { hookForDev } from '../../lib/devTools';
|
||||
import SelectionBox from '../SelectionBox/SelectionBox';
|
||||
import { getScoredUsers, searchContent } from '../../lib/search';
|
||||
import { store } from '../../services/StoreService';
|
||||
import Loader from '../Loader/Loader';
|
||||
import { readHomeSidebarSelection, saveHomeSidebarSelection } from '../../lib/localStore';
|
||||
import { useHomeContext } from '../../contexts/HomeContext';
|
||||
|
||||
const sidebarOptions = [
|
||||
{
|
||||
@ -85,132 +57,15 @@ const sidebarOptions = [
|
||||
|
||||
const HomeSidebar: Component< { id?: string } > = (props) => {
|
||||
|
||||
const intl = useIntl();
|
||||
const account = useAccountContext();
|
||||
const home = useHomeContext();
|
||||
|
||||
const [searchResults, setSearchResults] = createStore<{ notes: PrimalNote[], page: FeedPage, isFetching: boolean, query: SelectionOption | undefined }>({
|
||||
notes: [],
|
||||
page: {
|
||||
messages: [],
|
||||
users: {},
|
||||
postStats: {},
|
||||
mentions: {},
|
||||
noteActions: {},
|
||||
},
|
||||
isFetching: false,
|
||||
query: undefined,
|
||||
});
|
||||
onMount(() => {
|
||||
if (account?.isKeyLookupDone && home?.sidebar.notes.length === 0) {
|
||||
const stored = readHomeSidebarSelection(account.publicKey) || sidebarOptions[0];
|
||||
|
||||
const saveNotes = (newNotes: PrimalNote[]) => {
|
||||
setSearchResults('notes', () => [ ...newNotes.slice(0, 24) ]);
|
||||
setSearchResults('isFetching', () => false);
|
||||
};
|
||||
|
||||
const updatePage = (content: NostrEventContent) => {
|
||||
if (content.kind === Kind.Metadata) {
|
||||
const user = content as NostrUserContent;
|
||||
|
||||
setSearchResults('page', 'users',
|
||||
(usrs) => ({ ...usrs, [user.pubkey]: { ...user } })
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
if ([Kind.Text, Kind.Repost].includes(content.kind)) {
|
||||
const message = content as NostrNoteContent;
|
||||
|
||||
if (searchResults.page.messages.find(m => m.id === message.id)) {
|
||||
return;
|
||||
}
|
||||
|
||||
setSearchResults('page', 'messages',
|
||||
(msgs) => [ ...msgs, { ...message }]
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (content.kind === Kind.NoteStats) {
|
||||
const statistic = content as NostrStatsContent;
|
||||
const stat = JSON.parse(statistic.content);
|
||||
|
||||
setSearchResults('page', 'postStats',
|
||||
(stats) => ({ ...stats, [stat.event_id]: { ...stat } })
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
if (content.kind === Kind.Mentions) {
|
||||
const mentionContent = content as NostrMentionContent;
|
||||
const mention = JSON.parse(mentionContent.content);
|
||||
|
||||
setSearchResults('page', 'mentions',
|
||||
(mentions) => ({ ...mentions, [mention.id]: { ...mention } })
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
if (content.kind === Kind.NoteActions) {
|
||||
const noteActionContent = content as NostrNoteActionsContent;
|
||||
const noteActions = JSON.parse(noteActionContent.content) as NoteActions;
|
||||
|
||||
setSearchResults('page', 'noteActions',
|
||||
(actions) => ({ ...actions, [noteActions.event_id]: { ...noteActions } })
|
||||
);
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
const savePage = (page: FeedPage) => {
|
||||
const newPosts = convertToNotes(page);
|
||||
|
||||
saveNotes(newPosts);
|
||||
};
|
||||
|
||||
const doSearch = (query: string) => {
|
||||
const subid = `home_sidebar_${APP_ID}`;
|
||||
|
||||
const unsub = subscribeTo(subid, (type, _, content) => {
|
||||
|
||||
if (type === 'EOSE') {
|
||||
savePage(searchResults.page);
|
||||
unsub();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!content) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (type === 'EVENT') {
|
||||
updatePage(content);
|
||||
return;
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
setSearchResults('isFetching', () => true);
|
||||
setSearchResults('notes', () => []);
|
||||
setSearchResults('page', { messages: [], users: {}, postStats: {}, mentions: {}, noteActions: {} });
|
||||
|
||||
getScoredUsers(account?.publicKey, query, 10, subid);
|
||||
}
|
||||
|
||||
createEffect(() => {
|
||||
const query = searchResults.query?.value;
|
||||
query && doSearch(query);
|
||||
});
|
||||
|
||||
createEffect(() => {
|
||||
if (account?.isKeyLookupDone) {
|
||||
const stored = readHomeSidebarSelection(account.publicKey);
|
||||
|
||||
if (stored) {
|
||||
setSearchResults('query', () => ({...stored}));
|
||||
return;
|
||||
}
|
||||
setSearchResults('query', () => ({ ...sidebarOptions[0]}));
|
||||
home?.actions.updateSidebarQuery(stored);
|
||||
home?.actions.doSidebarSearch(home?.sidebar.query?.value || '');
|
||||
}
|
||||
});
|
||||
|
||||
@ -220,21 +75,22 @@ const HomeSidebar: Component< { id?: string } > = (props) => {
|
||||
<div class={styles.headingTrending}>
|
||||
<SelectionBox
|
||||
options={sidebarOptions}
|
||||
value={searchResults.query}
|
||||
value={home?.sidebar.query}
|
||||
onChange={(option: SelectionOption) => {
|
||||
setSearchResults('query', () => ({...option}));
|
||||
saveHomeSidebarSelection(account?.publicKey, option)
|
||||
home?.actions.updateSidebarQuery(option);
|
||||
saveHomeSidebarSelection(account?.publicKey, option);
|
||||
home?.actions.doSidebarSearch(home?.sidebar.query?.value || '');
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<Show
|
||||
when={!searchResults.isFetching}
|
||||
when={!home?.sidebar.isFetching}
|
||||
fallback={
|
||||
<Loader />
|
||||
}
|
||||
>
|
||||
<For each={searchResults.notes}>
|
||||
<For each={home?.sidebar.notes}>
|
||||
{(note) => <SmallNote note={note} />}
|
||||
</For>
|
||||
</Show>
|
||||
|
@ -5,7 +5,7 @@ import { APP_ID } from "../App";
|
||||
import { Kind } from "../constants";
|
||||
import { getEvents, getExploreFeed, getFeed, getFutureExploreFeed, getFutureFeed } from "../lib/feed";
|
||||
import { setLinkPreviews } from "../lib/notes";
|
||||
import { searchContent } from "../lib/search";
|
||||
import { getScoredUsers, searchContent } from "../lib/search";
|
||||
import { isConnected, refreshSocketListeners, removeSocketListeners, socket } from "../sockets";
|
||||
import { sortingPlan, convertToNotes, parseEmptyReposts, paginationPlan } from "../stores/note";
|
||||
import {
|
||||
@ -22,6 +22,7 @@ import {
|
||||
NoteActions,
|
||||
PrimalFeed,
|
||||
PrimalNote,
|
||||
SelectionOption,
|
||||
} from "../types/primal";
|
||||
import { useAccountContext } from "./AccountContext";
|
||||
import { useSettingsContext } from "./SettingsContext";
|
||||
@ -40,6 +41,12 @@ type HomeContextStore = {
|
||||
page: FeedPage,
|
||||
reposts: Record<string, string> | undefined,
|
||||
},
|
||||
sidebar: {
|
||||
notes: PrimalNote[],
|
||||
page: FeedPage,
|
||||
isFetching: boolean,
|
||||
query: SelectionOption | undefined,
|
||||
},
|
||||
actions: {
|
||||
saveNotes: (newNotes: PrimalNote[]) => void,
|
||||
clearNotes: () => void,
|
||||
@ -51,6 +58,8 @@ type HomeContextStore = {
|
||||
savePage: (page: FeedPage) => void,
|
||||
checkForNewNotes: (topic: string | undefined) => void,
|
||||
loadFutureContent: () => void,
|
||||
doSidebarSearch: (query: string) => void,
|
||||
updateSidebarQuery: (selection: SelectionOption) => void,
|
||||
}
|
||||
}
|
||||
|
||||
@ -80,6 +89,18 @@ const initialHomeData = {
|
||||
noteActions: {},
|
||||
},
|
||||
},
|
||||
sidebar: {
|
||||
notes: [],
|
||||
page: {
|
||||
messages: [],
|
||||
users: {},
|
||||
postStats: {},
|
||||
mentions: {},
|
||||
noteActions: {},
|
||||
},
|
||||
isFetching: false,
|
||||
query: undefined,
|
||||
}
|
||||
};
|
||||
|
||||
export const HomeContext = createContext<HomeContextStore>();
|
||||
@ -91,6 +112,106 @@ export const HomeProvider = (props: { children: ContextChildren }) => {
|
||||
|
||||
// ACTIONS --------------------------------------
|
||||
|
||||
const updateSidebarQuery = (selection: SelectionOption) => {
|
||||
updateStore('sidebar', 'query', () => ({ ...selection }));
|
||||
};
|
||||
|
||||
const saveSidebarNotes = (newNotes: PrimalNote[]) => {
|
||||
updateStore('sidebar', 'notes', () => [ ...newNotes.slice(0, 24) ]);
|
||||
updateStore('sidebar', 'isFetching', () => false);
|
||||
};
|
||||
|
||||
const updateSidebarPage = (content: NostrEventContent) => {
|
||||
if (content.kind === Kind.Metadata) {
|
||||
const user = content as NostrUserContent;
|
||||
|
||||
updateStore('sidebar', 'page', 'users',
|
||||
(usrs) => ({ ...usrs, [user.pubkey]: { ...user } })
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
if ([Kind.Text, Kind.Repost].includes(content.kind)) {
|
||||
const message = content as NostrNoteContent;
|
||||
|
||||
if (store.sidebar.page.messages.find(m => m.id === message.id)) {
|
||||
return;
|
||||
}
|
||||
|
||||
updateStore('sidebar', 'page', 'messages',
|
||||
(msgs) => [ ...msgs, { ...message }]
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (content.kind === Kind.NoteStats) {
|
||||
const statistic = content as NostrStatsContent;
|
||||
const stat = JSON.parse(statistic.content);
|
||||
|
||||
updateStore('sidebar', 'page', 'postStats',
|
||||
(stats) => ({ ...stats, [stat.event_id]: { ...stat } })
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
if (content.kind === Kind.Mentions) {
|
||||
const mentionContent = content as NostrMentionContent;
|
||||
const mention = JSON.parse(mentionContent.content);
|
||||
|
||||
updateStore('sidebar', 'page', 'mentions',
|
||||
(mentions) => ({ ...mentions, [mention.id]: { ...mention } })
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
if (content.kind === Kind.NoteActions) {
|
||||
const noteActionContent = content as NostrNoteActionsContent;
|
||||
const noteActions = JSON.parse(noteActionContent.content) as NoteActions;
|
||||
|
||||
updateStore('sidebar', 'page', 'noteActions',
|
||||
(actions) => ({ ...actions, [noteActions.event_id]: { ...noteActions } })
|
||||
);
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
const saveSidebarPage = (page: FeedPage) => {
|
||||
const newPosts = convertToNotes(page);
|
||||
|
||||
saveSidebarNotes(newPosts);
|
||||
};
|
||||
|
||||
const doSidebarSearch = (query: string) => {
|
||||
const subid = `home_sidebar_${APP_ID}`;
|
||||
|
||||
// const unsub = subscribeTo(subid, (type, _, content) => {
|
||||
|
||||
// if (type === 'EOSE') {
|
||||
// saveSidebarPage(store.sidebar.page);
|
||||
// unsub();
|
||||
// return;
|
||||
// }
|
||||
|
||||
// if (!content) {
|
||||
// return;
|
||||
// }
|
||||
|
||||
|
||||
// if (type === 'EVENT') {
|
||||
// updateSidebarPage(content);
|
||||
// return;
|
||||
// }
|
||||
|
||||
// });
|
||||
|
||||
updateStore('sidebar', 'isFetching', () => true);
|
||||
updateStore('sidebar', 'notes', () => []);
|
||||
updateStore('sidebar', 'page', { messages: [], users: {}, postStats: {}, mentions: {}, noteActions: {} });
|
||||
|
||||
getScoredUsers(account?.publicKey, query, 10, subid);
|
||||
}
|
||||
|
||||
const clearFuture = () => {
|
||||
updateStore('future', () => ({
|
||||
notes: [],
|
||||
@ -388,6 +509,23 @@ export const HomeProvider = (props: { children: ContextChildren }) => {
|
||||
|
||||
const [type, subId, content] = message;
|
||||
|
||||
if (subId === `home_sidebar_${APP_ID}`) {
|
||||
if (type === 'EOSE') {
|
||||
saveSidebarPage(store.sidebar.page);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!content) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (type === 'EVENT') {
|
||||
updateSidebarPage(content);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (subId === `home_feed_${APP_ID}`) {
|
||||
if (type === 'EOSE') {
|
||||
const reposts = parseEmptyReposts(store.page);
|
||||
@ -524,6 +662,8 @@ export const HomeProvider = (props: { children: ContextChildren }) => {
|
||||
savePage,
|
||||
checkForNewNotes,
|
||||
loadFutureContent,
|
||||
doSidebarSearch,
|
||||
updateSidebarQuery,
|
||||
},
|
||||
});
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user