mirror of
https://github.com/PrimalHQ/primal-web-app.git
synced 2024-09-30 00:41:09 +00:00
Topic links
This commit is contained in:
parent
a69f7d5950
commit
ccdecc01ce
@ -110,7 +110,7 @@ const Router: Component = () => {
|
|||||||
<Route path="/" component={Layout} >
|
<Route path="/" component={Layout} >
|
||||||
<Route path="/" component={Landing} />
|
<Route path="/" component={Landing} />
|
||||||
<Route path="/home" component={Home} />
|
<Route path="/home" component={Home} />
|
||||||
<Route path="/reads" component={Reads} />
|
<Route path="/reads/:topic?" component={Reads} />
|
||||||
<Route path="/thread/:id" component={Thread} />
|
<Route path="/thread/:id" component={Thread} />
|
||||||
<Route path="/e/:id" component={Thread} />
|
<Route path="/e/:id" component={Thread} />
|
||||||
<Route path="/explore/:scope?/:timeframe?" component={Explore} />
|
<Route path="/explore/:scope?/:timeframe?" component={Explore} />
|
||||||
|
@ -241,9 +241,9 @@ const ArticlePreview: Component<{
|
|||||||
</div>
|
</div>
|
||||||
<For each={props.article.tags.slice(0, 3)}>
|
<For each={props.article.tags.slice(0, 3)}>
|
||||||
{tag => (
|
{tag => (
|
||||||
<div class={styles.tag}>
|
<A href={`/reads/${tag}`} class={styles.tag}>
|
||||||
{tag}
|
{tag}
|
||||||
</div>
|
</A>
|
||||||
)}
|
)}
|
||||||
</For>
|
</For>
|
||||||
<Show when={props.article.tags.length > 3}>
|
<Show when={props.article.tags.length > 3}>
|
||||||
|
@ -24,6 +24,7 @@ import { getParametrizedEvent, getParametrizedEvents } from '../../lib/notes';
|
|||||||
import { decodeIdentifier } from '../../lib/keys';
|
import { decodeIdentifier } from '../../lib/keys';
|
||||||
import ArticleShort from '../ArticlePreview/ArticleShort';
|
import ArticleShort from '../ArticlePreview/ArticleShort';
|
||||||
import AuthorSubscribe from '../AuthorSubscribe/AuthorSubscribe';
|
import AuthorSubscribe from '../AuthorSubscribe/AuthorSubscribe';
|
||||||
|
import { A } from '@solidjs/router';
|
||||||
|
|
||||||
const sidebarOptions = [
|
const sidebarOptions = [
|
||||||
{
|
{
|
||||||
@ -227,7 +228,7 @@ const ReadsSidebar: Component< { id?: string } > = (props) => {
|
|||||||
>
|
>
|
||||||
<div class={styles.section}>
|
<div class={styles.section}>
|
||||||
<For each={topics}>
|
<For each={topics}>
|
||||||
{(topic) => <div class={styles.topic}>{topic}</div>}
|
{(topic) => <A href={`/reads/${topic}`} class={styles.topic}>{topic}</A>}
|
||||||
</For>
|
</For>
|
||||||
</div>
|
</div>
|
||||||
</Show>
|
</Show>
|
||||||
|
@ -60,7 +60,7 @@ type ReadsContextStore = {
|
|||||||
saveNotes: (newNotes: PrimalArticle[]) => void,
|
saveNotes: (newNotes: PrimalArticle[]) => void,
|
||||||
clearNotes: () => void,
|
clearNotes: () => void,
|
||||||
fetchNotes: (topic: string, subId: string, until?: number) => void,
|
fetchNotes: (topic: string, subId: string, until?: number) => void,
|
||||||
fetchNextPage: () => void,
|
fetchNextPage: (topic?: string) => void,
|
||||||
selectFeed: (feed: PrimalFeed | undefined) => void,
|
selectFeed: (feed: PrimalFeed | undefined) => void,
|
||||||
updateScrollTop: (top: number) => void,
|
updateScrollTop: (top: number) => void,
|
||||||
updatePage: (content: NostrEventContent) => void,
|
updatePage: (content: NostrEventContent) => void,
|
||||||
@ -70,6 +70,7 @@ type ReadsContextStore = {
|
|||||||
doSidebarSearch: (query: string) => void,
|
doSidebarSearch: (query: string) => void,
|
||||||
updateSidebarQuery: (selection: SelectionOption) => void,
|
updateSidebarQuery: (selection: SelectionOption) => void,
|
||||||
getFirstPage: () => void,
|
getFirstPage: () => void,
|
||||||
|
resetSelectedFeed: () => void;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -309,6 +310,7 @@ export const ReadsProvider = (props: { children: ContextChildren }) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const fetchNotes = (topic: string, subId: string, until = 0, includeReplies?: boolean) => {
|
const fetchNotes = (topic: string, subId: string, until = 0, includeReplies?: boolean) => {
|
||||||
|
|
||||||
const t = topic === 'none' ? '' : topic;//account?.publicKey || '532d830dffe09c13e75e8b145c825718fc12b0003f61d61e9077721c7fff93cb';
|
const t = topic === 'none' ? '' : topic;//account?.publicKey || '532d830dffe09c13e75e8b145c825718fc12b0003f61d61e9077721c7fff93cb';
|
||||||
const [scope, timeframe] = t.split(';');
|
const [scope, timeframe] = t.split(';');
|
||||||
|
|
||||||
@ -317,6 +319,11 @@ export const ReadsProvider = (props: { children: ContextChildren }) => {
|
|||||||
|
|
||||||
if (scope && timeframe) {
|
if (scope && timeframe) {
|
||||||
|
|
||||||
|
if (scope === 'filter') {
|
||||||
|
getArticlesFeed(account?.publicKey, undefined, `reads_feed_${subId}`, until, 20, timeframe);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (scope === 'search') {
|
if (scope === 'search') {
|
||||||
searchContent(account?.publicKey, `reads_feed_${subId}`, decodeURI(timeframe));
|
searchContent(account?.publicKey, `reads_feed_${subId}`, decodeURI(timeframe));
|
||||||
return;
|
return;
|
||||||
@ -345,7 +352,7 @@ export const ReadsProvider = (props: { children: ContextChildren }) => {
|
|||||||
clearFuture();
|
clearFuture();
|
||||||
};
|
};
|
||||||
|
|
||||||
const fetchNextPage = () => {
|
const fetchNextPage = (mainTopic?: string) => {
|
||||||
if (store.isFetching) {
|
if (store.isFetching) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -357,7 +364,7 @@ export const ReadsProvider = (props: { children: ContextChildren }) => {
|
|||||||
|
|
||||||
updateStore('lastNote', () => ({ ...lastNote }));
|
updateStore('lastNote', () => ({ ...lastNote }));
|
||||||
|
|
||||||
const topic = store.selectedFeed?.hex;
|
const topic = mainTopic ? `filter;${mainTopic}` : store.selectedFeed?.hex;
|
||||||
const includeReplies = store.selectedFeed?.includeReplies;
|
const includeReplies = store.selectedFeed?.includeReplies;
|
||||||
|
|
||||||
if (!topic) {
|
if (!topic) {
|
||||||
@ -391,7 +398,7 @@ export const ReadsProvider = (props: { children: ContextChildren }) => {
|
|||||||
|
|
||||||
let currentFeed: PrimalFeed | undefined;
|
let currentFeed: PrimalFeed | undefined;
|
||||||
|
|
||||||
const selectFeed = (feed: PrimalFeed | undefined) => {
|
const selectFeed = (feed: PrimalFeed | undefined, force?: boolean) => {
|
||||||
if (feed?.hex !== undefined && (feed.hex !== currentFeed?.hex || feed.includeReplies !== currentFeed?.includeReplies)) {
|
if (feed?.hex !== undefined && (feed.hex !== currentFeed?.hex || feed.includeReplies !== currentFeed?.includeReplies)) {
|
||||||
currentFeed = { ...feed };
|
currentFeed = { ...feed };
|
||||||
// saveStoredFeed(account?.publicKey, currentFeed);
|
// saveStoredFeed(account?.publicKey, currentFeed);
|
||||||
@ -402,6 +409,11 @@ export const ReadsProvider = (props: { children: ContextChildren }) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const resetSelectedFeed = () => {
|
||||||
|
currentFeed = undefined;
|
||||||
|
updateStore('selectedFeed', () => undefined);
|
||||||
|
};
|
||||||
|
|
||||||
const getFirstPage = () => {
|
const getFirstPage = () => {
|
||||||
const feed = store.selectedFeed;
|
const feed = store.selectedFeed;
|
||||||
if (!feed?.hex) return;
|
if (!feed?.hex) return;
|
||||||
@ -792,13 +804,6 @@ export const ReadsProvider = (props: { children: ContextChildren }) => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
createEffect(() => {
|
|
||||||
if (account?.isKeyLookupDone && account.publicKey) {
|
|
||||||
|
|
||||||
selectFeed({ hex: account.publicKey, name: 'My Reads'});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
onCleanup(() => {
|
onCleanup(() => {
|
||||||
removeSocketListeners(
|
removeSocketListeners(
|
||||||
socket(),
|
socket(),
|
||||||
@ -817,6 +822,7 @@ export const ReadsProvider = (props: { children: ContextChildren }) => {
|
|||||||
fetchNotes,
|
fetchNotes,
|
||||||
fetchNextPage,
|
fetchNextPage,
|
||||||
selectFeed,
|
selectFeed,
|
||||||
|
resetSelectedFeed,
|
||||||
updateScrollTop,
|
updateScrollTop,
|
||||||
updatePage,
|
updatePage,
|
||||||
savePage,
|
savePage,
|
||||||
|
@ -47,7 +47,7 @@ export const getFeed = (user_pubkey: string | undefined, pubkey: string | undef
|
|||||||
]));
|
]));
|
||||||
}
|
}
|
||||||
|
|
||||||
export const getArticlesFeed = (user_pubkey: string | undefined, pubkey: string | undefined, subid: string, until = 0, limit = 20) => {
|
export const getArticlesFeed = (user_pubkey: string | undefined, pubkey: string | undefined, subid: string, until = 0, limit = 20, topic?: string) => {
|
||||||
// if (!pubkey) {
|
// if (!pubkey) {
|
||||||
// return;
|
// return;
|
||||||
// }
|
// }
|
||||||
@ -66,6 +66,11 @@ export const getArticlesFeed = (user_pubkey: string | undefined, pubkey: string
|
|||||||
payload.user_pubkey = user_pubkey;
|
payload.user_pubkey = user_pubkey;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (topic) {
|
||||||
|
// @ts-ignore
|
||||||
|
payload.topic = topic;
|
||||||
|
}
|
||||||
|
|
||||||
sendMessage(JSON.stringify([
|
sendMessage(JSON.stringify([
|
||||||
"REQ",
|
"REQ",
|
||||||
subid,
|
subid,
|
||||||
|
@ -70,6 +70,21 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.backIcon {
|
||||||
|
display: inline-block;
|
||||||
|
border: none;
|
||||||
|
box-shadow: none;
|
||||||
|
background-color: unset;
|
||||||
|
margin: 0px;
|
||||||
|
padding: 0px;
|
||||||
|
width: 16px;
|
||||||
|
height: 16px;
|
||||||
|
background-color: var(--text-secondary);
|
||||||
|
-webkit-mask: url(../assets/icons/back.svg) no-repeat center;
|
||||||
|
mask: url(../assets/icons/back.svg) no-repeat center;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@media only screen and (max-width: 1300px) {
|
@media only screen and (max-width: 1300px) {
|
||||||
.newContentNotification {
|
.newContentNotification {
|
||||||
left: calc(calc(100vw - 1032px) / 2 + 48px + 32px);
|
left: calc(calc(100vw - 1032px) / 2 + 48px + 32px);
|
||||||
|
@ -982,9 +982,9 @@ const Longform: Component< { naddr: string } > = (props) => {
|
|||||||
<div class={styles.tags}>
|
<div class={styles.tags}>
|
||||||
<For each={store.article?.tags}>
|
<For each={store.article?.tags}>
|
||||||
{tag => (
|
{tag => (
|
||||||
<div class={styles.tag}>
|
<A href={`/reads/${tag}`} class={styles.tag}>
|
||||||
{tag}
|
{tag}
|
||||||
</div>
|
</A>
|
||||||
)}
|
)}
|
||||||
</For>
|
</For>
|
||||||
</div>
|
</div>
|
||||||
|
@ -38,6 +38,9 @@ import PageCaption from '../components/PageCaption/PageCaption';
|
|||||||
import ReadsSidebar from '../components/HomeSidebar/ReadsSidebar';
|
import ReadsSidebar from '../components/HomeSidebar/ReadsSidebar';
|
||||||
import ReedSelect from '../components/FeedSelect/ReedSelect';
|
import ReedSelect from '../components/FeedSelect/ReedSelect';
|
||||||
import ReadsHeader from '../components/HomeHeader/ReadsHeader';
|
import ReadsHeader from '../components/HomeHeader/ReadsHeader';
|
||||||
|
import { Link, useParams } from '@solidjs/router';
|
||||||
|
import { APP_ID } from '../App';
|
||||||
|
import ButtonGhost from '../components/Buttons/ButtonGhost';
|
||||||
|
|
||||||
|
|
||||||
const Home: Component = () => {
|
const Home: Component = () => {
|
||||||
@ -46,6 +49,7 @@ const Home: Component = () => {
|
|||||||
const account = useAccountContext();
|
const account = useAccountContext();
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
const app = useAppContext();
|
const app = useAppContext();
|
||||||
|
const params = useParams();
|
||||||
|
|
||||||
const isPageLoading = () => context?.isFetching;
|
const isPageLoading = () => context?.isFetching;
|
||||||
|
|
||||||
@ -130,7 +134,21 @@ const Home: Component = () => {
|
|||||||
|
|
||||||
onMount(() => {
|
onMount(() => {
|
||||||
context?.actions.doSidebarSearch('')
|
context?.actions.doSidebarSearch('')
|
||||||
})
|
});
|
||||||
|
|
||||||
|
createEffect(() => {
|
||||||
|
if (account?.isKeyLookupDone && account.publicKey) {
|
||||||
|
context?.actions.clearNotes();
|
||||||
|
|
||||||
|
if (params.topic) {
|
||||||
|
context?.actions.fetchNotes(`filter;${decodeURIComponent(params.topic)}`, APP_ID);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
context?.actions.resetSelectedFeed();
|
||||||
|
context?.actions.selectFeed({ hex: account.publicKey, name: 'My Reads'});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div class={styles.homeContent}>
|
<div class={styles.homeContent}>
|
||||||
@ -142,12 +160,29 @@ const Home: Component = () => {
|
|||||||
</Wormhole>
|
</Wormhole>
|
||||||
|
|
||||||
<PageCaption title={intl.formatMessage(reads.pageTitle)}>
|
<PageCaption title={intl.formatMessage(reads.pageTitle)}>
|
||||||
|
<Show
|
||||||
|
when={params.topic}
|
||||||
|
fallback={
|
||||||
<ReadsHeader
|
<ReadsHeader
|
||||||
hasNewPosts={() => {}}
|
hasNewPosts={() => {}}
|
||||||
loadNewContent={() => {}}
|
loadNewContent={() => {}}
|
||||||
newPostCount={() => {}}
|
newPostCount={() => {}}
|
||||||
newPostAuthors={[]}
|
newPostAuthors={[]}
|
||||||
/>
|
/>
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<div class={styles.readsTopicHeader}>
|
||||||
|
<Link
|
||||||
|
class={styles.backToReads}
|
||||||
|
href={'/reads'}
|
||||||
|
>
|
||||||
|
Reads:
|
||||||
|
</Link>
|
||||||
|
<span>
|
||||||
|
{decodeURIComponent(params.topic)}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</Show>
|
||||||
</PageCaption>
|
</PageCaption>
|
||||||
|
|
||||||
<StickySidebar>
|
<StickySidebar>
|
||||||
@ -181,7 +216,7 @@ const Home: Component = () => {
|
|||||||
</div>
|
</div>
|
||||||
</Match>
|
</Match>
|
||||||
</Switch>
|
</Switch>
|
||||||
<Paginator loadNextPage={context?.actions.fetchNextPage}/>
|
<Paginator loadNextPage={() => context?.actions.fetchNextPage(params.topic)}/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
Loading…
Reference in New Issue
Block a user