This commit is contained in:
Untone 2024-08-29 17:40:31 +03:00
parent 090295327f
commit 0698900f8d
7 changed files with 90 additions and 52 deletions

View File

@ -27,7 +27,10 @@ export const FullTopic = (props: Props) => {
const [followed, setFollowed] = createSignal() const [followed, setFollowed] = createSignal()
const [title, setTitle] = createSignal('') const [title, setTitle] = createSignal('')
createEffect(on(() => props.topic, (tpc) => { createEffect(
on(
() => props.topic,
(tpc) => {
if (!tpc) return if (!tpc) return
/* FIXME: use title translation*/ /* FIXME: use title translation*/
setTitle((_) => tpc?.title || '') setTitle((_) => tpc?.title || '')
@ -35,7 +38,10 @@ export const FullTopic = (props: Props) => {
lang() === 'en' ? tpc.slug.replace(/-/, ' ') : tpc.title || tpc.slug.replace(/-/, ' '), lang() === 'en' ? tpc.slug.replace(/-/, ' ') : tpc.title || tpc.slug.replace(/-/, ' '),
true true
)}` )}`
}, {} )) },
{}
)
)
createEffect(() => { createEffect(() => {
if (follows?.topics?.length !== 0) { if (follows?.topics?.length !== 0) {

View File

@ -34,9 +34,11 @@ export const ABC = {
export const AllAuthors = (props: Props) => { export const AllAuthors = (props: Props) => {
const { t, lang } = useLocalize() const { t, lang } = useLocalize()
const alphabet = createMemo(() => ABC[lang()] || ABC['ru']) const alphabet = createMemo(() => ABC[lang()] || ABC['ru'])
const [searchParams, ] = useSearchParams<{ by?: string }>() const [searchParams] = useSearchParams<{ by?: string }>()
const { authorsSorted, setAuthorsSort, loadAuthors } = useAuthors() const { authorsSorted, setAuthorsSort, loadAuthors } = useAuthors()
const authors = createMemo(() => (searchParams.by || searchParams.by === 'name') ? props.authors : authorsSorted()) const authors = createMemo(() =>
searchParams.by || searchParams.by === 'name' ? props.authors : authorsSorted()
)
const [loading, setLoading] = createSignal<boolean>(false) const [loading, setLoading] = createSignal<boolean>(false)
// filter // filter
@ -207,7 +209,14 @@ export const AllAuthors = (props: Props) => {
<div class="row"> <div class="row">
<div class="col-lg-20 col-xl-18"> <div class="col-lg-20 col-xl-18">
<div class={stylesAuthorList.action}> <div class={stylesAuthorList.action}>
<Show when={searchParams.by !== 'name' && !searchParams.by && !loading() && ((authorsSorted?.() || []).length || 0) > 0}> <Show
when={
searchParams.by !== 'name' &&
!searchParams.by &&
!loading() &&
((authorsSorted?.() || []).length || 0) > 0
}
>
<Button value={t('Load more')} onClick={loadMoreAuthors} aria-live="polite" /> <Button value={t('Load more')} onClick={loadMoreAuthors} aria-live="polite" />
</Show> </Show>
<Show when={loading()}> <Show when={loading()}>

View File

@ -221,7 +221,7 @@ export const AuthorView = (props: AuthorViewProps) => {
<Show when={Array.isArray(props.shouts) && props.shouts.length > 0}> <Show when={Array.isArray(props.shouts) && props.shouts.length > 0}>
<For each={props.shouts.filter((_, i) => i % 3 === 0)}> <For each={props.shouts.filter((_, i) => i % 3 === 0)}>
{(_shout, index) => { {(_shout, index) => {
const articles = props.shouts.slice(index() * 3, index() * 3 + 3); const articles = props.shouts.slice(index() * 3, index() * 3 + 3)
return ( return (
<> <>
<Switch> <Switch>
@ -236,7 +236,7 @@ export const AuthorView = (props: AuthorViewProps) => {
</Match> </Match>
</Switch> </Switch>
</> </>
); )
}} }}
</For> </For>
</Show> </Show>

View File

@ -62,7 +62,7 @@ export const ProfileSettings = () => {
const { showConfirm } = useUI() const { showConfirm } = useUI()
const [clearAbout, setClearAbout] = createSignal(false) const [clearAbout, setClearAbout] = createSignal(false)
const { showModal, hideModal } = useUI() const { showModal, hideModal } = useUI()
const [loading, setLoading] = createSignal(true); const [loading, setLoading] = createSignal(true)
// Используем createEffect для отслеживания данных сессии и инициализации формы // Используем createEffect для отслеживания данных сессии и инициализации формы
createEffect(() => { createEffect(() => {
@ -72,7 +72,7 @@ export const ProfileSettings = () => {
if (profileData) { if (profileData) {
setPrevForm(profileData) setPrevForm(profileData)
const soc: string[] = filterNulls(profileData.links || []) const soc: string[] = filterNulls(profileData.links || [])
setSocial(soc); setSocial(soc)
setForm(profileData) // Инициализируем форму с данными профиля setForm(profileData) // Инициализируем форму с данными профиля
setIsFormInitialized(true) setIsFormInitialized(true)
} }

View File

@ -46,7 +46,10 @@ export const TopicView = (props: Props) => {
// TODO: filter + sort // TODO: filter + sort
const [sortedFeed, setSortedFeed] = createSignal([] as Shout[]) const [sortedFeed, setSortedFeed] = createSignal([] as Shout[])
createEffect(on(([feedByTopic, () => props.topicSlug, topicEntities]), ([feed, slug, ttt]) => { createEffect(
on(
[feedByTopic, () => props.topicSlug, topicEntities],
([feed, slug, ttt]) => {
if (Object.values(ttt).length === 0) return if (Object.values(ttt).length === 0) return
const sss = (feed[slug] || []) as Shout[] const sss = (feed[slug] || []) as Shout[]
sss && setSortedFeed(sss) sss && setSortedFeed(sss)
@ -54,7 +57,10 @@ export const TopicView = (props: Props) => {
const tpc = ttt[slug] const tpc = ttt[slug]
console.debug('topics loaded', ttt) console.debug('topics loaded', ttt)
tpc && setTopic(tpc) tpc && setTopic(tpc)
}, {})) },
{}
)
)
const loadTopicFollowers = async () => { const loadTopicFollowers = async () => {
const topicFollowersFetcher = loadFollowersByTopic(props.topicSlug) const topicFollowersFetcher = loadFollowersByTopic(props.topicSlug)
@ -101,14 +107,20 @@ export const TopicView = (props: Props) => {
} }
// второй этап начальной загрузки данных // второй этап начальной загрузки данных
createEffect(on(topic, (tpc) => { createEffect(
on(
topic,
(tpc) => {
console.debug('topic loaded', tpc) console.debug('topic loaded', tpc)
if (!tpc) return if (!tpc) return
loadFavoriteTopArticles() loadFavoriteTopArticles()
loadReactedTopMonthArticles() loadReactedTopMonthArticles()
loadTopicAuthors() loadTopicAuthors()
loadTopicFollowers() loadTopicFollowers()
}, { defer: true })) },
{ defer: true }
)
)
// дозагрузка // дозагрузка
const loadMore = async () => { const loadMore = async () => {
@ -138,7 +150,9 @@ export const TopicView = (props: Props) => {
return ( return (
<div class={styles.topicPage}> <div class={styles.topicPage}>
<Suspense fallback={<Loading />}> <Suspense fallback={<Loading />}>
<Show when={topic()}><FullTopic topic={topic() as Topic} followers={followers()} authors={topicAuthors()} /></Show> <Show when={topic()}>
<FullTopic topic={topic() as Topic} followers={followers()} authors={topicAuthors()} />
</Show>
<div class="wide-container"> <div class="wide-container">
<div class={clsx(styles.groupControls, 'row group__controls')}> <div class={clsx(styles.groupControls, 'row group__controls')}>
<div class="col-md-16"> <div class="col-md-16">
@ -218,9 +232,15 @@ export const TopicView = (props: Props) => {
</Show> </Show>
<LoadMoreWrapper loadFunction={loadMore} pageSize={SHOUTS_PER_PAGE}> <LoadMoreWrapper loadFunction={loadMore} pageSize={SHOUTS_PER_PAGE}>
<For each={sortedFeed().slice(19).filter((_, i) => i % 3 === 0)}> <For
each={sortedFeed()
.slice(19)
.filter((_, i) => i % 3 === 0)}
>
{(_shout, index) => { {(_shout, index) => {
const articles = sortedFeed().slice(19).slice(index() * 3, index() * 3 + 3); const articles = sortedFeed()
.slice(19)
.slice(index() * 3, index() * 3 + 3)
return ( return (
<> <>
<Switch> <Switch>
@ -235,7 +255,7 @@ export const TopicView = (props: Props) => {
</Match> </Match>
</Switch> </Switch>
</> </>
); )
}} }}
</For> </For>
</LoadMoreWrapper> </LoadMoreWrapper>

View File

@ -38,7 +38,8 @@ export const LoadMoreWrapper = (props: LoadMoreProps) => {
const newItems = await props.loadFunction(offset()) const newItems = await props.loadFunction(offset())
if (!Array.isArray(newItems)) return if (!Array.isArray(newItems)) return
if (newItems.length === 0) setIsLoadMoreButtonVisible(false) if (newItems.length === 0) setIsLoadMoreButtonVisible(false)
else setItems( else
setItems(
(prev) => (prev) =>
Array.from(new Set([...prev, ...newItems])).sort( Array.from(new Set([...prev, ...newItems])).sort(
byCreated as SortFunction<unknown> byCreated as SortFunction<unknown>

View File

@ -57,11 +57,13 @@ export default function AuthorPage(props: RouteSectionProps<AuthorPageProps>) {
const { addAuthor, authorsEntities } = useAuthors() const { addAuthor, authorsEntities } = useAuthors()
const [author, setAuthor] = createSignal<Author | undefined>(undefined) const [author, setAuthor] = createSignal<Author | undefined>(undefined)
createEffect( createEffect(
on(author, on(
author,
async (profile) => { async (profile) => {
// update only if no profile loaded // update only if no profile loaded
if (!profile) { if (!profile) {
const loadedAuthor = authorsEntities()[props.params.slug] || (await fetchAuthor(props.params.slug)) const loadedAuthor =
authorsEntities()[props.params.slug] || (await fetchAuthor(props.params.slug))
if (loadedAuthor) { if (loadedAuthor) {
addAuthor(loadedAuthor) addAuthor(loadedAuthor)
setAuthor(loadedAuthor) setAuthor(loadedAuthor)
@ -107,7 +109,7 @@ export default function AuthorPage(props: RouteSectionProps<AuthorPageProps>) {
const { addFeed, feedByAuthor } = useFeed() const { addFeed, feedByAuthor } = useFeed()
const [loadMoreHidden, setLoadMoreHidden] = createSignal(true) const [loadMoreHidden, setLoadMoreHidden] = createSignal(true)
const authorShouts = createAsync(async () => { const authorShouts = createAsync(async () => {
const sss: Shout[] = props.data.articles as Shout[] || feedByAuthor()[props.params.slug] || [] const sss: Shout[] = (props.data.articles as Shout[]) || feedByAuthor()[props.params.slug] || []
const result = sss || (await fetchAuthorShouts(props.params.slug, 0)) const result = sss || (await fetchAuthorShouts(props.params.slug, 0))
if (!result) setLoadMoreHidden(true) if (!result) setLoadMoreHidden(true)
return result return result