Merge branch 'dev' of https://github.com/Discours/discoursio-webapp into fix/all-topics-page
This commit is contained in:
commit
24cd1c54a8
|
@ -33,6 +33,7 @@ export const ProfileSettings = () => {
|
||||||
const { t } = useLocalize()
|
const { t } = useLocalize()
|
||||||
const [prevForm, setPrevForm] = createStore({})
|
const [prevForm, setPrevForm] = createStore({})
|
||||||
const [isFormInitialized, setIsFormInitialized] = createSignal(false)
|
const [isFormInitialized, setIsFormInitialized] = createSignal(false)
|
||||||
|
const [isSaving, setIsSaving] = createSignal(false)
|
||||||
const [social, setSocial] = createSignal([])
|
const [social, setSocial] = createSignal([])
|
||||||
const [addLinkForm, setAddLinkForm] = createSignal<boolean>(false)
|
const [addLinkForm, setAddLinkForm] = createSignal<boolean>(false)
|
||||||
const [incorrectUrl, setIncorrectUrl] = createSignal<boolean>(false)
|
const [incorrectUrl, setIncorrectUrl] = createSignal<boolean>(false)
|
||||||
|
@ -70,16 +71,20 @@ export const ProfileSettings = () => {
|
||||||
|
|
||||||
const handleSubmit = async (event: Event) => {
|
const handleSubmit = async (event: Event) => {
|
||||||
event.preventDefault()
|
event.preventDefault()
|
||||||
|
setIsSaving(true)
|
||||||
if (nameInputRef.current.value.length === 0) {
|
if (nameInputRef.current.value.length === 0) {
|
||||||
setNameError(t('Required'))
|
setNameError(t('Required'))
|
||||||
nameInputRef.current.focus()
|
nameInputRef.current.focus()
|
||||||
|
setIsSaving(false)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (slugInputRef.current.value.length === 0) {
|
if (slugInputRef.current.value.length === 0) {
|
||||||
setSlugError(t('Required'))
|
setSlugError(t('Required'))
|
||||||
slugInputRef.current.focus()
|
slugInputRef.current.focus()
|
||||||
|
setIsSaving(false)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await submit(form)
|
await submit(form)
|
||||||
setPrevForm(clone(form))
|
setPrevForm(clone(form))
|
||||||
|
@ -91,6 +96,8 @@ export const ProfileSettings = () => {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
showSnackbar({ type: 'error', body: t('Error') })
|
showSnackbar({ type: 'error', body: t('Error') })
|
||||||
|
} finally {
|
||||||
|
setIsSaving(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
await loadAuthor() // renews author's profile
|
await loadAuthor() // renews author's profile
|
||||||
|
@ -359,7 +366,12 @@ export const ProfileSettings = () => {
|
||||||
}
|
}
|
||||||
onClick={handleCancel}
|
onClick={handleCancel}
|
||||||
/>
|
/>
|
||||||
<Button onClick={handleSubmit} variant="primary" value={t('Save settings')} />
|
<Button
|
||||||
|
onClick={handleSubmit}
|
||||||
|
variant="primary"
|
||||||
|
disabled={isSaving()}
|
||||||
|
value={isSaving() ? t('Saving...') : t('Save settings')}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -40,7 +40,7 @@ export const FullTopic = (props: Props) => {
|
||||||
return (
|
return (
|
||||||
<div class={clsx(styles.topicHeader, 'col-md-16 col-lg-12 offset-md-4 offset-lg-6')}>
|
<div class={clsx(styles.topicHeader, 'col-md-16 col-lg-12 offset-md-4 offset-lg-6')}>
|
||||||
<h1>#{props.topic?.title}</h1>
|
<h1>#{props.topic?.title}</h1>
|
||||||
<p>{props.topic?.body}</p>
|
<p innerHTML={props.topic?.body} />
|
||||||
<div class={clsx(styles.topicActions)}>
|
<div class={clsx(styles.topicActions)}>
|
||||||
<Button
|
<Button
|
||||||
variant="primary"
|
variant="primary"
|
||||||
|
|
|
@ -67,7 +67,7 @@ export const TopicBadge = (props: Props) => {
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<div class={clsx('text-truncate', styles.description)}>{props.topic.body}</div>
|
<div innerHTML={props.topic.body} class={clsx('text-truncate', styles.description)} />
|
||||||
</Show>
|
</Show>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -29,8 +29,6 @@ import stylesArticle from '../../Article/Article.module.scss'
|
||||||
import styles from './Author.module.scss'
|
import styles from './Author.module.scss'
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
shouts: Shout[]
|
|
||||||
author: Author
|
|
||||||
authorSlug: string
|
authorSlug: string
|
||||||
}
|
}
|
||||||
export const PRERENDERED_ARTICLES_COUNT = 12
|
export const PRERENDERED_ARTICLES_COUNT = 12
|
||||||
|
@ -39,8 +37,8 @@ const LOAD_MORE_PAGE_SIZE = 9
|
||||||
export const AuthorView = (props: Props) => {
|
export const AuthorView = (props: Props) => {
|
||||||
const { t } = useLocalize()
|
const { t } = useLocalize()
|
||||||
const { loadSubscriptions } = useFollowing()
|
const { loadSubscriptions } = useFollowing()
|
||||||
const { sortedArticles } = useArticlesStore({ shouts: props.shouts })
|
const { sortedArticles } = useArticlesStore()
|
||||||
const { authorEntities } = useAuthorsStore({ authors: [props.author] })
|
const { authorEntities } = useAuthorsStore()
|
||||||
const { page: getPage, searchParams } = useRouter()
|
const { page: getPage, searchParams } = useRouter()
|
||||||
const [isLoadMoreButtonVisible, setIsLoadMoreButtonVisible] = createSignal(false)
|
const [isLoadMoreButtonVisible, setIsLoadMoreButtonVisible] = createSignal(false)
|
||||||
const [isBioExpanded, setIsBioExpanded] = createSignal(false)
|
const [isBioExpanded, setIsBioExpanded] = createSignal(false)
|
||||||
|
@ -200,10 +198,10 @@ export const AuthorView = (props: Props) => {
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<div class={clsx('col-md-8', styles.additionalControls)}>
|
<div class={clsx('col-md-8', styles.additionalControls)}>
|
||||||
<Show when={props.author?.stat?.rating || props.author?.stat?.rating === 0}>
|
<Show when={author()?.stat?.rating || author()?.stat?.rating === 0}>
|
||||||
<div class={styles.ratingContainer}>
|
<div class={styles.ratingContainer}>
|
||||||
{t('All posts rating')}
|
{t('All posts rating')}
|
||||||
<AuthorShoutsRating author={props.author} class={styles.ratingControl} />
|
<AuthorShoutsRating author={author()} class={styles.ratingControl} />
|
||||||
</div>
|
</div>
|
||||||
</Show>
|
</Show>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -24,34 +24,31 @@ type Props = {
|
||||||
layout: LayoutType
|
layout: LayoutType
|
||||||
}
|
}
|
||||||
|
|
||||||
export const PRERENDERED_ARTICLES_COUNT = 37
|
export const PRERENDERED_ARTICLES_COUNT = 36
|
||||||
const LOAD_MORE_PAGE_SIZE = 11
|
const LOAD_MORE_PAGE_SIZE = 12
|
||||||
|
|
||||||
export const Expo = (props: Props) => {
|
export const Expo = (props: Props) => {
|
||||||
const [isLoaded, setIsLoaded] = createSignal<boolean>(Boolean(props.shouts))
|
const [isLoaded, setIsLoaded] = createSignal<boolean>(Boolean(props.shouts))
|
||||||
const [isLoadMoreButtonVisible, setIsLoadMoreButtonVisible] = createSignal(false)
|
const [isLoadMoreButtonVisible, setIsLoadMoreButtonVisible] = createSignal(false)
|
||||||
|
|
||||||
const [randomTopArticles, setRandomTopArticles] = createSignal<Shout[]>([])
|
const [favoriteTopArticles, setFavoriteTopArticles] = createSignal<Shout[]>([])
|
||||||
const [randomTopMonthArticles, setRandomTopMonthArticles] = createSignal<Shout[]>([])
|
const [reactedTopMonthArticles, setReactedTopMonthArticles] = createSignal<Shout[]>([])
|
||||||
|
|
||||||
const { t } = useLocalize()
|
const { t } = useLocalize()
|
||||||
|
|
||||||
// const { sortedArticles } = useArticlesStore({
|
|
||||||
// shouts: isLoaded() ? props.shouts : [],
|
|
||||||
// })
|
|
||||||
const { sortedArticles } = useArticlesStore({
|
const { sortedArticles } = useArticlesStore({
|
||||||
shouts: props.shouts || [],
|
shouts: isLoaded() ? props.shouts : [],
|
||||||
layout: props.layout,
|
layout: props.layout,
|
||||||
})
|
})
|
||||||
|
|
||||||
const getLoadShoutsFilters = (additionalFilters: LoadShoutsFilters = {}): LoadShoutsFilters => {
|
const getLoadShoutsFilters = (additionalFilters: LoadShoutsFilters = {}): LoadShoutsFilters => {
|
||||||
const filters = { featured: true, ...additionalFilters }
|
const filters = { ...additionalFilters }
|
||||||
|
|
||||||
if (!filters.layouts) filters.layouts = []
|
if (!filters.layouts) filters.layouts = []
|
||||||
if (props.layout) {
|
if (props.layout) {
|
||||||
filters.layouts.push(props.layout)
|
filters.layouts.push(props.layout)
|
||||||
} else {
|
} else {
|
||||||
filters.layouts.push('article')
|
filters.layouts.push('audio', 'video', 'image', 'literature')
|
||||||
}
|
}
|
||||||
|
|
||||||
return filters
|
return filters
|
||||||
|
@ -80,13 +77,12 @@ export const Expo = (props: Props) => {
|
||||||
|
|
||||||
const loadRandomTopArticles = async () => {
|
const loadRandomTopArticles = async () => {
|
||||||
const options: LoadShoutsOptions = {
|
const options: LoadShoutsOptions = {
|
||||||
filters: getLoadShoutsFilters(),
|
filters: { ...getLoadShoutsFilters(), featured: true },
|
||||||
limit: 10,
|
limit: 10,
|
||||||
random_limit: 100,
|
random_limit: 100,
|
||||||
}
|
}
|
||||||
|
|
||||||
const result = await apiClient.getRandomTopShouts({ options })
|
const result = await apiClient.getRandomTopShouts({ options })
|
||||||
setRandomTopArticles(result)
|
setFavoriteTopArticles(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
const loadRandomTopMonthArticles = async () => {
|
const loadRandomTopMonthArticles = async () => {
|
||||||
|
@ -94,19 +90,15 @@ export const Expo = (props: Props) => {
|
||||||
const after = getUnixtime(new Date(now.setMonth(now.getMonth() - 1)))
|
const after = getUnixtime(new Date(now.setMonth(now.getMonth() - 1)))
|
||||||
|
|
||||||
const options: LoadShoutsOptions = {
|
const options: LoadShoutsOptions = {
|
||||||
filters: getLoadShoutsFilters({ after }),
|
filters: { ...getLoadShoutsFilters({ after }), reacted: true },
|
||||||
limit: 10,
|
limit: 10,
|
||||||
random_limit: 10,
|
random_limit: 10,
|
||||||
}
|
}
|
||||||
|
|
||||||
const result = await apiClient.getRandomTopShouts({ options })
|
const result = await apiClient.getRandomTopShouts({ options })
|
||||||
setRandomTopMonthArticles(result)
|
setReactedTopMonthArticles(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
const pages = createMemo<Shout[][]>(() =>
|
|
||||||
splitToPages(sortedArticles(), PRERENDERED_ARTICLES_COUNT, LOAD_MORE_PAGE_SIZE),
|
|
||||||
)
|
|
||||||
|
|
||||||
onMount(() => {
|
onMount(() => {
|
||||||
if (isLoaded()) {
|
if (isLoaded()) {
|
||||||
return
|
return
|
||||||
|
@ -130,8 +122,8 @@ export const Expo = (props: Props) => {
|
||||||
() => props.layout,
|
() => props.layout,
|
||||||
() => {
|
() => {
|
||||||
resetSortedArticles()
|
resetSortedArticles()
|
||||||
setRandomTopArticles([])
|
setFavoriteTopArticles([])
|
||||||
setRandomTopMonthArticles([])
|
setReactedTopMonthArticles([])
|
||||||
loadMore(PRERENDERED_ARTICLES_COUNT + LOAD_MORE_PAGE_SIZE)
|
loadMore(PRERENDERED_ARTICLES_COUNT + LOAD_MORE_PAGE_SIZE)
|
||||||
loadRandomTopArticles()
|
loadRandomTopArticles()
|
||||||
loadRandomTopMonthArticles()
|
loadRandomTopMonthArticles()
|
||||||
|
@ -202,7 +194,7 @@ export const Expo = (props: Props) => {
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<For each={sortedArticles().slice(0, PRERENDERED_ARTICLES_COUNT / 2)}>
|
<For each={sortedArticles().slice(0, LOAD_MORE_PAGE_SIZE)}>
|
||||||
{(shout) => (
|
{(shout) => (
|
||||||
<div class="col-md-6 mt-md-5 col-sm-8 mt-sm-3">
|
<div class="col-md-6 mt-md-5 col-sm-8 mt-sm-3">
|
||||||
<ArticleCard
|
<ArticleCard
|
||||||
|
@ -214,10 +206,10 @@ export const Expo = (props: Props) => {
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</For>
|
</For>
|
||||||
<Show when={randomTopMonthArticles()?.length > 0} keyed={true}>
|
<Show when={reactedTopMonthArticles()?.length > 0} keyed={true}>
|
||||||
<ArticleCardSwiper title={t('Top month articles')} slides={randomTopMonthArticles()} />
|
<ArticleCardSwiper title={t('Top month articles')} slides={reactedTopMonthArticles()} />
|
||||||
</Show>
|
</Show>
|
||||||
<For each={sortedArticles().slice(PRERENDERED_ARTICLES_COUNT / 2, PRERENDERED_ARTICLES_COUNT)}>
|
<For each={sortedArticles().slice(LOAD_MORE_PAGE_SIZE, LOAD_MORE_PAGE_SIZE * 2)}>
|
||||||
{(shout) => (
|
{(shout) => (
|
||||||
<div class="col-md-6 mt-md-5 col-sm-8 mt-sm-3">
|
<div class="col-md-6 mt-md-5 col-sm-8 mt-sm-3">
|
||||||
<ArticleCard
|
<ArticleCard
|
||||||
|
@ -229,12 +221,10 @@ export const Expo = (props: Props) => {
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</For>
|
</For>
|
||||||
<Show when={randomTopArticles()?.length > 0} keyed={true}>
|
<Show when={favoriteTopArticles()?.length > 0} keyed={true}>
|
||||||
<ArticleCardSwiper title={t('Favorite')} slides={randomTopArticles()} />
|
<ArticleCardSwiper title={t('Favorite')} slides={favoriteTopArticles()} />
|
||||||
</Show>
|
</Show>
|
||||||
<For each={pages()}>
|
<For each={sortedArticles().slice(LOAD_MORE_PAGE_SIZE * 2)}>
|
||||||
{(page) => (
|
|
||||||
<For each={page}>
|
|
||||||
{(shout) => (
|
{(shout) => (
|
||||||
<div class="col-md-6 mt-md-5 col-sm-8 mt-sm-3">
|
<div class="col-md-6 mt-md-5 col-sm-8 mt-sm-3">
|
||||||
<ArticleCard
|
<ArticleCard
|
||||||
|
@ -246,8 +236,6 @@ export const Expo = (props: Props) => {
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</For>
|
</For>
|
||||||
)}
|
|
||||||
</For>
|
|
||||||
</div>
|
</div>
|
||||||
<Show when={isLoadMoreButtonVisible()}>
|
<Show when={isLoadMoreButtonVisible()}>
|
||||||
<div class={styles.showMore}>
|
<div class={styles.showMore}>
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
import type { Shout, Topic } from '../../graphql/schema/core.gen'
|
import { LoadShoutsOptions, Shout, Topic } from '../../graphql/schema/core.gen'
|
||||||
|
|
||||||
import { Meta } from '@solidjs/meta'
|
import { Meta } from '@solidjs/meta'
|
||||||
import { clsx } from 'clsx'
|
import { clsx } from 'clsx'
|
||||||
import { For, Show, createEffect, createMemo, createSignal, onMount } from 'solid-js'
|
import { For, Show, createEffect, createMemo, createSignal, on, onMount } from 'solid-js'
|
||||||
|
|
||||||
import { useLocalize } from '../../context/localize'
|
import { useLocalize } from '../../context/localize'
|
||||||
import { useRouter } from '../../stores/router'
|
import { useRouter } from '../../stores/router'
|
||||||
|
@ -21,7 +21,9 @@ import { Row3 } from '../Feed/Row3'
|
||||||
import { FullTopic } from '../Topic/Full'
|
import { FullTopic } from '../Topic/Full'
|
||||||
import { ArticleCardSwiper } from '../_shared/SolidSwiper/ArticleCardSwiper'
|
import { ArticleCardSwiper } from '../_shared/SolidSwiper/ArticleCardSwiper'
|
||||||
|
|
||||||
|
import { apiClient } from '../../graphql/client/core'
|
||||||
import styles from '../../styles/Topic.module.scss'
|
import styles from '../../styles/Topic.module.scss'
|
||||||
|
import { getUnixtime } from '../../utils/getServerDate'
|
||||||
|
|
||||||
type TopicsPageSearchParams = {
|
type TopicsPageSearchParams = {
|
||||||
by: 'comments' | '' | 'recent' | 'viewed' | 'rating' | 'commented'
|
by: 'comments' | '' | 'recent' | 'viewed' | 'rating' | 'commented'
|
||||||
|
@ -43,14 +45,55 @@ export const TopicView = (props: Props) => {
|
||||||
const { sortedArticles } = useArticlesStore({ shouts: props.shouts })
|
const { sortedArticles } = useArticlesStore({ shouts: props.shouts })
|
||||||
const { topicEntities } = useTopicsStore({ topics: [props.topic] })
|
const { topicEntities } = useTopicsStore({ topics: [props.topic] })
|
||||||
const { authorsByTopic } = useAuthorsStore()
|
const { authorsByTopic } = useAuthorsStore()
|
||||||
|
const [favoriteTopArticles, setFavoriteTopArticles] = createSignal<Shout[]>([])
|
||||||
|
const [reactedTopMonthArticles, setReactedTopMonthArticles] = createSignal<Shout[]>([])
|
||||||
|
|
||||||
|
console.log('%c!!! :', 'color: #bada55', sortedArticles())
|
||||||
|
|
||||||
const [topic, setTopic] = createSignal<Topic>()
|
const [topic, setTopic] = createSignal<Topic>()
|
||||||
|
|
||||||
createEffect(() => {
|
createEffect(() => {
|
||||||
const topics = topicEntities()
|
const topics = topicEntities()
|
||||||
if (props.topicSlug && !topic() && topics) {
|
if (props.topicSlug && !topic() && topics) {
|
||||||
setTopic(topics[props.topicSlug])
|
setTopic(topics[props.topicSlug])
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const loadRandomTopArticles = async (topic: string) => {
|
||||||
|
const options: LoadShoutsOptions = {
|
||||||
|
filters: { featured: true, topic: topic },
|
||||||
|
limit: 10,
|
||||||
|
random_limit: 100,
|
||||||
|
}
|
||||||
|
const result = await apiClient.getRandomTopShouts({ options })
|
||||||
|
setFavoriteTopArticles(result)
|
||||||
|
}
|
||||||
|
|
||||||
|
const loadRandomTopMonthArticles = async (topic: string) => {
|
||||||
|
const now = new Date()
|
||||||
|
const after = getUnixtime(new Date(now.setMonth(now.getMonth() - 1)))
|
||||||
|
|
||||||
|
const options: LoadShoutsOptions = {
|
||||||
|
filters: { after: after, featured: true, topic: topic },
|
||||||
|
limit: 10,
|
||||||
|
random_limit: 10,
|
||||||
|
}
|
||||||
|
|
||||||
|
const result = await apiClient.getRandomTopShouts({ options })
|
||||||
|
setReactedTopMonthArticles(result)
|
||||||
|
}
|
||||||
|
|
||||||
|
createEffect(
|
||||||
|
on(
|
||||||
|
() => topic(),
|
||||||
|
() => {
|
||||||
|
loadRandomTopArticles(topic()?.slug)
|
||||||
|
loadRandomTopMonthArticles(topic()?.slug)
|
||||||
|
},
|
||||||
|
{ defer: true },
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
const title = createMemo(
|
const title = createMemo(
|
||||||
() =>
|
() =>
|
||||||
`#${capitalize(
|
`#${capitalize(
|
||||||
|
@ -170,9 +213,9 @@ export const TopicView = (props: Props) => {
|
||||||
beside={sortedArticles()[4]}
|
beside={sortedArticles()[4]}
|
||||||
wrapper={'author'}
|
wrapper={'author'}
|
||||||
/>
|
/>
|
||||||
|
<Show when={reactedTopMonthArticles()?.length > 0} keyed={true}>
|
||||||
<ArticleCardSwiper title={title()} slides={sortedArticles().slice(5, 11)} />
|
<ArticleCardSwiper title={t('Top month articles')} slides={reactedTopMonthArticles()} />
|
||||||
|
</Show>
|
||||||
<Beside
|
<Beside
|
||||||
beside={sortedArticles()[12]}
|
beside={sortedArticles()[12]}
|
||||||
title={t('Top viewed')}
|
title={t('Top viewed')}
|
||||||
|
@ -183,8 +226,10 @@ export const TopicView = (props: Props) => {
|
||||||
<Row2 articles={sortedArticles().slice(13, 15)} isEqual={true} />
|
<Row2 articles={sortedArticles().slice(13, 15)} isEqual={true} />
|
||||||
<Row1 article={sortedArticles()[15]} />
|
<Row1 article={sortedArticles()[15]} />
|
||||||
|
|
||||||
|
<Show when={favoriteTopArticles()?.length > 0} keyed={true}>
|
||||||
|
<ArticleCardSwiper title={t('Favorite')} slides={favoriteTopArticles()} />
|
||||||
|
</Show>
|
||||||
<Show when={sortedArticles().length > 15}>
|
<Show when={sortedArticles().length > 15}>
|
||||||
<ArticleCardSwiper slides={sortedArticles().slice(16, 22)} />
|
|
||||||
<Row3 articles={sortedArticles().slice(23, 26)} />
|
<Row3 articles={sortedArticles().slice(23, 26)} />
|
||||||
<Row2 articles={sortedArticles().slice(26, 28)} />
|
<Row2 articles={sortedArticles().slice(26, 28)} />
|
||||||
</Show>
|
</Show>
|
||||||
|
|
|
@ -2,14 +2,14 @@ import { Accessor, JSX, createContext, createEffect, createSignal, useContext }
|
||||||
import { createStore } from 'solid-js/store'
|
import { createStore } from 'solid-js/store'
|
||||||
|
|
||||||
import { apiClient } from '../graphql/client/core'
|
import { apiClient } from '../graphql/client/core'
|
||||||
import { AuthorFollows, FollowingEntity } from '../graphql/schema/core.gen'
|
import { AuthorFollowsResult, FollowingEntity } from '../graphql/schema/core.gen'
|
||||||
|
|
||||||
import { useSession } from './session'
|
import { useSession } from './session'
|
||||||
|
|
||||||
interface FollowingContextType {
|
interface FollowingContextType {
|
||||||
loading: Accessor<boolean>
|
loading: Accessor<boolean>
|
||||||
subscriptions: AuthorFollows
|
subscriptions: AuthorFollowsResult
|
||||||
setSubscriptions: (subscriptions: AuthorFollows) => void
|
setSubscriptions: (subscriptions: AuthorFollowsResult) => void
|
||||||
setFollowing: (what: FollowingEntity, slug: string, value: boolean) => void
|
setFollowing: (what: FollowingEntity, slug: string, value: boolean) => void
|
||||||
loadSubscriptions: () => void
|
loadSubscriptions: () => void
|
||||||
follow: (what: FollowingEntity, slug: string) => Promise<void>
|
follow: (what: FollowingEntity, slug: string) => Promise<void>
|
||||||
|
@ -23,7 +23,7 @@ export function useFollowing() {
|
||||||
return useContext(FollowingContext)
|
return useContext(FollowingContext)
|
||||||
}
|
}
|
||||||
|
|
||||||
const EMPTY_SUBSCRIPTIONS: AuthorFollows = {
|
const EMPTY_SUBSCRIPTIONS: AuthorFollowsResult = {
|
||||||
topics: [],
|
topics: [],
|
||||||
authors: [],
|
authors: [],
|
||||||
communities: [],
|
communities: [],
|
||||||
|
@ -31,7 +31,7 @@ const EMPTY_SUBSCRIPTIONS: AuthorFollows = {
|
||||||
|
|
||||||
export const FollowingProvider = (props: { children: JSX.Element }) => {
|
export const FollowingProvider = (props: { children: JSX.Element }) => {
|
||||||
const [loading, setLoading] = createSignal<boolean>(false)
|
const [loading, setLoading] = createSignal<boolean>(false)
|
||||||
const [subscriptions, setSubscriptions] = createStore<AuthorFollows>(EMPTY_SUBSCRIPTIONS)
|
const [subscriptions, setSubscriptions] = createStore<AuthorFollowsResult>(EMPTY_SUBSCRIPTIONS)
|
||||||
const { author, session } = useSession()
|
const { author, session } = useSession()
|
||||||
|
|
||||||
const fetchData = async () => {
|
const fetchData = async () => {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import type {
|
import type {
|
||||||
Author,
|
Author,
|
||||||
AuthorFollows,
|
AuthorFollowsResult,
|
||||||
CommonResult,
|
CommonResult,
|
||||||
FollowingEntity,
|
FollowingEntity,
|
||||||
LoadShoutsOptions,
|
LoadShoutsOptions,
|
||||||
|
@ -134,7 +134,7 @@ export const apiClient = {
|
||||||
slug?: string
|
slug?: string
|
||||||
author_id?: number
|
author_id?: number
|
||||||
user?: string
|
user?: string
|
||||||
}): Promise<AuthorFollows> => {
|
}): Promise<AuthorFollowsResult> => {
|
||||||
const response = await publicGraphQLClient.query(authorFollows, params).toPromise()
|
const response = await publicGraphQLClient.query(authorFollows, params).toPromise()
|
||||||
return response.data.get_author_follows
|
return response.data.get_author_follows
|
||||||
},
|
},
|
||||||
|
|
|
@ -56,17 +56,11 @@ export const AuthorPage = (props: PageProps) => {
|
||||||
|
|
||||||
onCleanup(() => resetSortedArticles())
|
onCleanup(() => resetSortedArticles())
|
||||||
|
|
||||||
const usePrerenderedData = props.author?.slug === slug()
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<PageLayout title={props.seo?.title || t('Discours')}>
|
<PageLayout title={props.seo?.title || t('Discours')}>
|
||||||
<ReactionsProvider>
|
<ReactionsProvider>
|
||||||
<Show when={isLoaded()} fallback={<Loading />}>
|
<Show when={isLoaded()} fallback={<Loading />}>
|
||||||
<AuthorView
|
<AuthorView authorSlug={slug()} />
|
||||||
author={usePrerenderedData ? props.author : null}
|
|
||||||
shouts={usePrerenderedData ? props.authorShouts : null}
|
|
||||||
authorSlug={slug()}
|
|
||||||
/>
|
|
||||||
</Show>
|
</Show>
|
||||||
</ReactionsProvider>
|
</ReactionsProvider>
|
||||||
</PageLayout>
|
</PageLayout>
|
||||||
|
|
Loading…
Reference in New Issue
Block a user