mainpage-loadmore-hide
This commit is contained in:
parent
ab05a9e539
commit
7573c6334c
|
@ -8,6 +8,8 @@ import sassDts from 'vite-plugin-sass-dts'
|
||||||
const isVercel = Boolean(process?.env.VERCEL)
|
const isVercel = Boolean(process?.env.VERCEL)
|
||||||
const isBun = Boolean(process.env.BUN)
|
const isBun = Boolean(process.env.BUN)
|
||||||
|
|
||||||
|
console.info(`[app.config] build for ${isVercel ? 'vercel' : isBun? 'bun' : 'node'}!`)
|
||||||
|
|
||||||
const polyfillOptions = {
|
const polyfillOptions = {
|
||||||
include: ['path', 'stream', 'util'],
|
include: ['path', 'stream', 'util'],
|
||||||
exclude: ['http'],
|
exclude: ['http'],
|
||||||
|
|
|
@ -1,9 +1,8 @@
|
||||||
import { A, useLocation } from '@solidjs/router'
|
import { A, useLocation } from '@solidjs/router'
|
||||||
import { clsx } from 'clsx'
|
import { clsx } from 'clsx'
|
||||||
import { For, Match, Show, Switch, createEffect, createMemo, createSignal, on, onMount } from 'solid-js'
|
import { For, Match, Show, Switch, createEffect, createMemo, createSignal, on } from 'solid-js'
|
||||||
import { Loading } from '~/components/_shared/Loading'
|
import { Loading } from '~/components/_shared/Loading'
|
||||||
import { useAuthors } from '~/context/authors'
|
import { useAuthors } from '~/context/authors'
|
||||||
import { useFeed } from '~/context/feed'
|
|
||||||
import { useFollowing } from '~/context/following'
|
import { useFollowing } from '~/context/following'
|
||||||
import { useGraphQL } from '~/context/graphql'
|
import { useGraphQL } from '~/context/graphql'
|
||||||
import { useLocalize } from '~/context/localize'
|
import { useLocalize } from '~/context/localize'
|
||||||
|
@ -28,7 +27,6 @@ type AuthorViewProps = {
|
||||||
selectedTab: string
|
selectedTab: string
|
||||||
shouts?: Shout[]
|
shouts?: Shout[]
|
||||||
author?: Author
|
author?: Author
|
||||||
topics?: Topic[]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const PRERENDERED_ARTICLES_COUNT = 12
|
export const PRERENDERED_ARTICLES_COUNT = 12
|
||||||
|
@ -40,7 +38,6 @@ export const AuthorView = (props: AuthorViewProps) => {
|
||||||
const loc = useLocation()
|
const loc = useLocation()
|
||||||
const { session } = useSession()
|
const { session } = useSession()
|
||||||
const { query } = useGraphQL()
|
const { query } = useGraphQL()
|
||||||
const { sortedFeed } = useFeed()
|
|
||||||
const { loadAuthor, authorsEntities } = useAuthors()
|
const { loadAuthor, authorsEntities } = useAuthors()
|
||||||
const { followers: myFollowers, follows: myFollows } = useFollowing()
|
const { followers: myFollowers, follows: myFollows } = useFollowing()
|
||||||
|
|
||||||
|
@ -55,7 +52,7 @@ export const AuthorView = (props: AuthorViewProps) => {
|
||||||
// derivatives
|
// derivatives
|
||||||
const me = createMemo<Author>(() => session()?.user?.app_data?.profile as Author)
|
const me = createMemo<Author>(() => session()?.user?.app_data?.profile as Author)
|
||||||
const pages = createMemo<Shout[][]>(() =>
|
const pages = createMemo<Shout[][]>(() =>
|
||||||
paginate(sortedFeed(), PRERENDERED_ARTICLES_COUNT, LOAD_MORE_PAGE_SIZE)
|
paginate((props.shouts || []).slice(1), PRERENDERED_ARTICLES_COUNT, LOAD_MORE_PAGE_SIZE)
|
||||||
)
|
)
|
||||||
|
|
||||||
// 1 // проверяет не собственный ли это профиль, иначе - загружает
|
// 1 // проверяет не собственный ли это профиль, иначе - загружает
|
||||||
|
@ -107,20 +104,20 @@ export const AuthorView = (props: AuthorViewProps) => {
|
||||||
// event handlers
|
// event handlers
|
||||||
let bioContainerRef: HTMLDivElement
|
let bioContainerRef: HTMLDivElement
|
||||||
let bioWrapperRef: HTMLDivElement
|
let bioWrapperRef: HTMLDivElement
|
||||||
const checkBioHeight = () => {
|
const checkBioHeight = (bio = bioWrapperRef) => {
|
||||||
if (bioContainerRef) {
|
if (!bio) return
|
||||||
const showExpand = bioContainerRef.offsetHeight > bioWrapperRef.offsetHeight
|
const showExpand = bioContainerRef.offsetHeight > bio.offsetHeight
|
||||||
setShowExpandBioControl(showExpand)
|
setShowExpandBioControl(showExpand)
|
||||||
console.debug('[AuthorView] mounted, show expand bio container:', showExpand)
|
console.debug('[AuthorView] mounted, show expand bio container:', showExpand)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
const handleDeleteComment = (id: number) => {
|
const handleDeleteComment = (id: number) => {
|
||||||
setCommented((prev) => (prev || []).filter((comment) => comment.id !== id))
|
setCommented((prev) => (prev || []).filter((comment) => comment.id !== id))
|
||||||
}
|
}
|
||||||
|
|
||||||
// on load
|
// on load
|
||||||
onMount(checkBioHeight)
|
createEffect(on(() => bioContainerRef, checkBioHeight))
|
||||||
|
createEffect(on(() => props.selectedTab, (tab) => tab && console.log('[views.Author] profile tab switched')))
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div class={styles.authorPage}>
|
<div class={styles.authorPage}>
|
||||||
|
@ -227,18 +224,18 @@ export const AuthorView = (props: AuthorViewProps) => {
|
||||||
</div>
|
</div>
|
||||||
</Show>
|
</Show>
|
||||||
|
|
||||||
<Show when={sortedFeed().length > 0}>
|
<Show when={Array.isArray(props.shouts) && props.shouts.length > 0 && props.shouts[0]}>
|
||||||
<Row1 article={sortedFeed()[0]} noauthor={true} nodate={true} />
|
<Row1 article={props.shouts?.[0] as Shout} noauthor={true} nodate={true} />
|
||||||
|
|
||||||
<Show when={sortedFeed().length > 1}>
|
<Show when={props.shouts && props.shouts.length > 1}>
|
||||||
<Switch>
|
<Switch>
|
||||||
<Match when={sortedFeed().length === 2}>
|
<Match when={props.shouts && props.shouts.length === 2}>
|
||||||
<Row2 articles={sortedFeed()} isEqual={true} noauthor={true} nodate={true} />
|
<Row2 articles={props.shouts as Shout[]} isEqual={true} noauthor={true} nodate={true} />
|
||||||
</Match>
|
</Match>
|
||||||
<Match when={sortedFeed().length === 3}>
|
<Match when={props.shouts && props.shouts.length === 3}>
|
||||||
<Row3 articles={sortedFeed()} noauthor={true} nodate={true} />
|
<Row3 articles={props.shouts as Shout[]} noauthor={true} nodate={true} />
|
||||||
</Match>
|
</Match>
|
||||||
<Match when={sortedFeed().length > 3}>
|
<Match when={props.shouts && props.shouts.length > 3}>
|
||||||
<For each={pages()}>
|
<For each={pages()}>
|
||||||
{(page) => (
|
{(page) => (
|
||||||
<>
|
<>
|
||||||
|
|
|
@ -39,6 +39,12 @@ export type FeedProps = {
|
||||||
order?: '' | 'likes' | 'hot'
|
order?: '' | 'likes' | 'hot'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const PERIODS = {
|
||||||
|
'day': 24 * 60 * 60,
|
||||||
|
'month': 30 * 24 * 60 * 60,
|
||||||
|
'year': 365 * 24 * 60 * 60
|
||||||
|
}
|
||||||
|
|
||||||
export const FeedView = (props: FeedProps) => {
|
export const FeedView = (props: FeedProps) => {
|
||||||
const { t } = useLocalize()
|
const { t } = useLocalize()
|
||||||
const loc = useLocation()
|
const loc = useLocation()
|
||||||
|
@ -59,9 +65,6 @@ export const FeedView = (props: FeedProps) => {
|
||||||
const { topAuthors } = useAuthors()
|
const { topAuthors } = useAuthors()
|
||||||
const [topComments, setTopComments] = createSignal<Reaction[]>([])
|
const [topComments, setTopComments] = createSignal<Reaction[]>([])
|
||||||
const [searchParams, changeSearchParams] = useSearchParams<FeedSearchParams>()
|
const [searchParams, changeSearchParams] = useSearchParams<FeedSearchParams>()
|
||||||
const asOption = (o: string) => ({ value: o, title: t(o) })
|
|
||||||
const asOptions = (opts: string[]) => opts.map(asOption)
|
|
||||||
const currentPeriod = createMemo(() => asOption(searchParams?.period || ''))
|
|
||||||
const loadTopComments = async () => {
|
const loadTopComments = async () => {
|
||||||
const comments = await loadReactionsBy({ by: { comment: true }, limit: 50 })
|
const comments = await loadReactionsBy({ by: { comment: true }, limit: 50 })
|
||||||
setTopComments(comments.sort(byCreated).reverse())
|
setTopComments(comments.sort(byCreated).reverse())
|
||||||
|
@ -94,6 +97,13 @@ export const FeedView = (props: FeedProps) => {
|
||||||
setShareData(shared)
|
setShareData(shared)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const asOption = (o: string) => {
|
||||||
|
const value = Math.floor(Date.now()/1000) - PERIODS[o as keyof typeof PERIODS]
|
||||||
|
return { value, title: t(o) }
|
||||||
|
}
|
||||||
|
const asOptions = (opts: string[]) => opts.map(asOption)
|
||||||
|
const currentPeriod = createMemo(() => asOption(searchParams?.period || ''))
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div class="feed">
|
<div class="feed">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
|
|
|
@ -89,7 +89,7 @@ export const NotificationsProvider = (props: { children: JSX.Element }) => {
|
||||||
if (data.entity === 'reaction' && authorized()) {
|
if (data.entity === 'reaction' && authorized()) {
|
||||||
console.info('[context.notifications] event', data)
|
console.info('[context.notifications] event', data)
|
||||||
loadNotificationsGrouped({
|
loadNotificationsGrouped({
|
||||||
after: after() || Date.now(),
|
after: after() || now,
|
||||||
limit: Math.max(PAGE_SIZE, loadedNotificationsCount())
|
limit: Math.max(PAGE_SIZE, loadedNotificationsCount())
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -108,14 +108,14 @@ export const NotificationsProvider = (props: { children: JSX.Element }) => {
|
||||||
const markSeenAll = async () => {
|
const markSeenAll = async () => {
|
||||||
if (authorized()) {
|
if (authorized()) {
|
||||||
const _resp = await mutation(markSeenAfterMutation, { after: after() }).toPromise()
|
const _resp = await mutation(markSeenAfterMutation, { after: after() }).toPromise()
|
||||||
await loadNotificationsGrouped({ after: after() || Date.now(), limit: loadedNotificationsCount() })
|
await loadNotificationsGrouped({ after: after() || now, limit: loadedNotificationsCount() })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const markSeen = async (notification_id: number) => {
|
const markSeen = async (notification_id: number) => {
|
||||||
if (authorized()) {
|
if (authorized()) {
|
||||||
await mutation(markSeenMutation, { notification_id }).toPromise()
|
await mutation(markSeenMutation, { notification_id }).toPromise()
|
||||||
await loadNotificationsGrouped({ after: after() || Date.now(), limit: loadedNotificationsCount() })
|
await loadNotificationsGrouped({ after: after() || now, limit: loadedNotificationsCount() })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -58,6 +58,10 @@ export const loadShouts = (options: LoadShoutsOptions) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
export const loadReactions = (options: QueryLoad_Reactions_ByArgs) => {
|
export const loadReactions = (options: QueryLoad_Reactions_ByArgs) => {
|
||||||
|
if (!options.by) {
|
||||||
|
console.debug(options)
|
||||||
|
throw new Error('[api] wrong loadReactions call')
|
||||||
|
}
|
||||||
const kind = options.by?.comment ? 'comments' : options.by?.rating ? 'votes' : 'reactions'
|
const kind = options.by?.comment ? 'comments' : options.by?.rating ? 'votes' : 'reactions'
|
||||||
const allorone = options.by?.shout ? `shout-${options.by.shout}` : 'all'
|
const allorone = options.by?.shout ? `shout-${options.by.shout}` : 'all'
|
||||||
const page = `${options.offset || 0}-${(options?.limit || 0) + (options.offset || 0)}`
|
const page = `${options.offset || 0}-${(options?.limit || 0) + (options.offset || 0)}`
|
||||||
|
|
|
@ -45,6 +45,7 @@
|
||||||
"Artworks": "Артворки",
|
"Artworks": "Артворки",
|
||||||
"Audio": "Аудио",
|
"Audio": "Аудио",
|
||||||
"Author": "Автор",
|
"Author": "Автор",
|
||||||
|
"author profile was not found": "не удалось найти профиль автора",
|
||||||
"Authors": "Авторы",
|
"Authors": "Авторы",
|
||||||
"Autotypograph": "Автотипограф",
|
"Autotypograph": "Автотипограф",
|
||||||
"Back": "Назад",
|
"Back": "Назад",
|
||||||
|
|
|
@ -109,7 +109,7 @@ export default function HomePage(props: RouteSectionProps<HomeViewProps>) {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<PageLayout withPadding={true} title={t('Discours')} key="home">
|
<PageLayout withPadding={true} title={t('Discours')} key="home">
|
||||||
<LoadMoreWrapper loadFunction={loadMoreFeatured} pageSize={SHOUTS_PER_PAGE}>
|
<LoadMoreWrapper loadFunction={loadMoreFeatured} pageSize={SHOUTS_PER_PAGE} hidden={!featuredFeed()}>
|
||||||
<HomeView
|
<HomeView
|
||||||
featuredShouts={featuredFeed() || (shouts() as Shout[])}
|
featuredShouts={featuredFeed() || (shouts() as Shout[])}
|
||||||
topMonthShouts={topMonthFeed() as Shout[]}
|
topMonthShouts={topMonthFeed() as Shout[]}
|
||||||
|
|
|
@ -39,7 +39,7 @@ type SlugPageProps = {
|
||||||
|
|
||||||
export default (props: RouteSectionProps<SlugPageProps>) => {
|
export default (props: RouteSectionProps<SlugPageProps>) => {
|
||||||
if (props.params.slug.startsWith('@')) {
|
if (props.params.slug.startsWith('@')) {
|
||||||
console.debug('[slug] starts with @, render as author page')
|
console.debug('[routes] [slug]/[...tab] starts with @, render as author page')
|
||||||
const patchedProps = {
|
const patchedProps = {
|
||||||
...props,
|
...props,
|
||||||
params: {
|
params: {
|
||||||
|
@ -51,7 +51,7 @@ export default (props: RouteSectionProps<SlugPageProps>) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (props.params.slug.startsWith('!')) {
|
if (props.params.slug.startsWith('!')) {
|
||||||
console.debug('[slug] starts with !, render as topic page')
|
console.debug('[routes] [slug]/[...tab] starts with !, render as topic page')
|
||||||
const patchedProps = {
|
const patchedProps = {
|
||||||
...props,
|
...props,
|
||||||
params: {
|
params: {
|
||||||
|
@ -74,7 +74,7 @@ export default (props: RouteSectionProps<SlugPageProps>) => {
|
||||||
await loadGAScript(gaIdentity)
|
await loadGAScript(gaIdentity)
|
||||||
initGA(gaIdentity)
|
initGA(gaIdentity)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.warn('Failed to connect Google Analytics:', error)
|
console.warn('[routes] [slug]/[...tab] Failed to connect Google Analytics:', error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { RouteSectionProps, createAsync } from '@solidjs/router'
|
import { RouteSectionProps } from '@solidjs/router'
|
||||||
import { ErrorBoundary, createEffect, createMemo } from 'solid-js'
|
import { ErrorBoundary, createEffect, createMemo, createSignal, on } from 'solid-js'
|
||||||
import { AuthorView } from '~/components/Views/Author'
|
import { AuthorView } from '~/components/Views/Author'
|
||||||
import { FourOuFourView } from '~/components/Views/FourOuFour'
|
import { FourOuFourView } from '~/components/Views/FourOuFour'
|
||||||
import { LoadMoreItems, LoadMoreWrapper } from '~/components/_shared/LoadMoreWrapper'
|
import { LoadMoreItems, LoadMoreWrapper } from '~/components/_shared/LoadMoreWrapper'
|
||||||
|
@ -13,6 +13,9 @@ import {
|
||||||
Author,
|
Author,
|
||||||
LoadShoutsOptions,
|
LoadShoutsOptions,
|
||||||
QueryLoad_Authors_ByArgs,
|
QueryLoad_Authors_ByArgs,
|
||||||
|
QueryLoad_Reactions_ByArgs,
|
||||||
|
Reaction,
|
||||||
|
ReactionKind,
|
||||||
Shout,
|
Shout,
|
||||||
Topic
|
Topic
|
||||||
} from '~/graphql/schema/core.gen'
|
} from '~/graphql/schema/core.gen'
|
||||||
|
@ -25,6 +28,16 @@ const fetchAuthorShouts = async (slug: string, offset?: number) => {
|
||||||
return await shoutsLoader()
|
return await shoutsLoader()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const fetchAuthorComments = async (slug: string, offset?: number) => {
|
||||||
|
const opts: QueryLoad_Reactions_ByArgs = {
|
||||||
|
by: { comment: true, author: slug },
|
||||||
|
limit: SHOUTS_PER_PAGE,
|
||||||
|
offset
|
||||||
|
}
|
||||||
|
const shoutsLoader = loadReactions(opts)
|
||||||
|
return await shoutsLoader()
|
||||||
|
}
|
||||||
|
|
||||||
const fetchAllTopics = async () => {
|
const fetchAllTopics = async () => {
|
||||||
const topicsFetcher = loadTopics()
|
const topicsFetcher = loadTopics()
|
||||||
return await topicsFetcher()
|
return await topicsFetcher()
|
||||||
|
@ -51,18 +64,8 @@ export type AuthorPageProps = { articles?: Shout[]; author?: Author; topics?: To
|
||||||
|
|
||||||
export default function AuthorPage(props: RouteSectionProps<AuthorPageProps>) {
|
export default function AuthorPage(props: RouteSectionProps<AuthorPageProps>) {
|
||||||
const { addAuthor, authorsEntities } = useAuthors()
|
const { addAuthor, authorsEntities } = useAuthors()
|
||||||
const articles = createAsync(
|
const [author, setAuthor] = createSignal<Author | undefined>(undefined)
|
||||||
async () => props.data.articles || (await fetchAuthorShouts(props.params.slug)) || []
|
|
||||||
)
|
|
||||||
const author = createAsync(async () => {
|
|
||||||
const loadedBefore = authorsEntities()[props.params.slug]
|
|
||||||
if (loadedBefore) return loadedBefore
|
|
||||||
|
|
||||||
const a = props.data.author || (await fetchAuthor(props.params.slug))
|
|
||||||
a && addAuthor(a)
|
|
||||||
return a
|
|
||||||
})
|
|
||||||
const topics = createAsync(async () => props.data.topics || (await fetchAllTopics()))
|
|
||||||
const { t } = useLocalize()
|
const { t } = useLocalize()
|
||||||
const title = createMemo(() => `${author()?.name || ''}`)
|
const title = createMemo(() => `${author()?.name || ''}`)
|
||||||
|
|
||||||
|
@ -83,28 +86,44 @@ export default function AuthorPage(props: RouteSectionProps<AuthorPageProps>) {
|
||||||
: getImageUrl('production/image/logo_image.png')
|
: getImageUrl('production/image/logo_image.png')
|
||||||
)
|
)
|
||||||
|
|
||||||
const selectedTab = createMemo(() => (props.params.tab in ['comments', 'about'] ? props.params.tab : ''))
|
// author comments
|
||||||
const { addReactions } = useReactions()
|
const { addReactions, reactionEntities } = useReactions()
|
||||||
const loadMoreComments = async () => {
|
const commentsByAuthor = createMemo(() =>
|
||||||
const commentsFetcher = loadReactions({
|
Object.values(reactionEntities).filter(
|
||||||
by: { comment: true, created_by: author()?.id }
|
(r: Reaction) => r.kind === ReactionKind.Comment && r.created_by.id === author()?.id
|
||||||
})
|
)
|
||||||
const ccc = await commentsFetcher()
|
)
|
||||||
ccc && addReactions(ccc)
|
// author shouts
|
||||||
return ccc as LoadMoreItems
|
|
||||||
}
|
|
||||||
const { addFeed, feedByAuthor } = useFeed()
|
const { addFeed, feedByAuthor } = useFeed()
|
||||||
const loadMoreAuthorShouts = async () => {
|
const shoutsByAuthor = createMemo(() => feedByAuthor()[props.params.slug])
|
||||||
const slug = author()?.slug
|
|
||||||
const offset = feedByAuthor()[props.params.slug].length
|
createEffect(
|
||||||
const shoutsFetcher = loadShouts({
|
on(
|
||||||
filters: { author: slug },
|
[() => props.params.slug || '', author],
|
||||||
offset,
|
async ([slug, profile]) => {
|
||||||
limit: SHOUTS_PER_PAGE
|
if (!profile) {
|
||||||
})
|
const loadedAuthor = authorsEntities()[slug] || (await fetchAuthor(slug))
|
||||||
const sss = await shoutsFetcher()
|
if (loadedAuthor) {
|
||||||
sss && addFeed(sss)
|
addAuthor(loadedAuthor)
|
||||||
return sss as LoadMoreItems
|
setAuthor(loadedAuthor)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ defer: true }
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
const loadAuthorDataMore = async (offset = 0) => {
|
||||||
|
if (props.params.tab === 'comments') {
|
||||||
|
const commentsOffset = commentsByAuthor().length
|
||||||
|
const loadedComments = await fetchAuthorComments(props.params.slug, commentsOffset)
|
||||||
|
loadedComments && addReactions(loadedComments)
|
||||||
|
return (loadedComments || []) as LoadMoreItems
|
||||||
|
}
|
||||||
|
const shoutsOffset = shoutsByAuthor().length
|
||||||
|
const loadedShouts = await fetchAuthorShouts(props.params.slug, shoutsOffset)
|
||||||
|
loadedShouts && addFeed(loadedShouts)
|
||||||
|
return (loadedShouts || []) as LoadMoreItems
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -118,16 +137,15 @@ export default function AuthorPage(props: RouteSectionProps<AuthorPageProps>) {
|
||||||
>
|
>
|
||||||
<ReactionsProvider>
|
<ReactionsProvider>
|
||||||
<LoadMoreWrapper
|
<LoadMoreWrapper
|
||||||
loadFunction={selectedTab() === 'comments' ? loadMoreComments : loadMoreAuthorShouts}
|
loadFunction={loadAuthorDataMore}
|
||||||
pageSize={SHOUTS_PER_PAGE}
|
pageSize={SHOUTS_PER_PAGE}
|
||||||
hidden={selectedTab() !== '' || selectedTab() !== 'comments'}
|
hidden={!props.params.tab || props.params.tab !== 'comments'}
|
||||||
>
|
>
|
||||||
<AuthorView
|
<AuthorView
|
||||||
author={author() as Author}
|
author={author() as Author}
|
||||||
selectedTab={selectedTab()}
|
selectedTab={props.params.tab}
|
||||||
authorSlug={props.params.slug}
|
authorSlug={props.params.slug}
|
||||||
shouts={feedByAuthor()[props.params.slug] || (articles() as Shout[])}
|
shouts={shoutsByAuthor()}
|
||||||
topics={topics()}
|
|
||||||
/>
|
/>
|
||||||
</LoadMoreWrapper>
|
</LoadMoreWrapper>
|
||||||
</ReactionsProvider>
|
</ReactionsProvider>
|
||||||
|
|
|
@ -7,6 +7,7 @@ import { Icon } from '~/components/_shared/Icon'
|
||||||
import { PageLayout } from '~/components/_shared/PageLayout'
|
import { PageLayout } from '~/components/_shared/PageLayout'
|
||||||
import { useGraphQL } from '~/context/graphql'
|
import { useGraphQL } from '~/context/graphql'
|
||||||
import { useLocalize } from '~/context/localize'
|
import { useLocalize } from '~/context/localize'
|
||||||
|
import { useSnackbar } from '~/context/ui'
|
||||||
import createShoutMutation from '~/graphql/mutation/core/article-create'
|
import createShoutMutation from '~/graphql/mutation/core/article-create'
|
||||||
import styles from '~/styles/Create.module.scss'
|
import styles from '~/styles/Create.module.scss'
|
||||||
import { LayoutType } from '~/types/common'
|
import { LayoutType } from '~/types/common'
|
||||||
|
@ -14,11 +15,18 @@ import { LayoutType } from '~/types/common'
|
||||||
export default () => {
|
export default () => {
|
||||||
const { t } = useLocalize()
|
const { t } = useLocalize()
|
||||||
const client = useGraphQL()
|
const client = useGraphQL()
|
||||||
|
const {showSnackbar} = useSnackbar()
|
||||||
const navigate = useNavigate()
|
const navigate = useNavigate()
|
||||||
const handleCreate = async (layout: LayoutType) => {
|
const handleCreate = async (layout: LayoutType) => {
|
||||||
|
console.debug('[routes : edit/new] handling create click...')
|
||||||
const result = await client.mutation(createShoutMutation, { shout: { layout: layout } }).toPromise()
|
const result = await client.mutation(createShoutMutation, { shout: { layout: layout } }).toPromise()
|
||||||
if (result) {
|
if (result) {
|
||||||
const shout = result.data.create_shout
|
console.debug(result)
|
||||||
|
const {shout, error} = result.data.create_shout
|
||||||
|
if (error) showSnackbar({
|
||||||
|
body: `${t('Error')}: ${t(error)}`,
|
||||||
|
type: 'error'
|
||||||
|
})
|
||||||
if (shout?.id) navigate(`/edit/${shout.id}`)
|
if (shout?.id) navigate(`/edit/${shout.id}`)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -34,8 +42,8 @@ export default () => {
|
||||||
<ul class={clsx('nodash', styles.list)}>
|
<ul class={clsx('nodash', styles.list)}>
|
||||||
<For each={['Article', 'Literature', 'Image', 'Audio', 'Video']}>
|
<For each={['Article', 'Literature', 'Image', 'Audio', 'Video']}>
|
||||||
{(layout: string) => (
|
{(layout: string) => (
|
||||||
<li>
|
<li onClick={() => handleCreate(layout.toLowerCase() as LayoutType)}>
|
||||||
<div class={styles.link} onClick={() => handleCreate(layout.toLowerCase() as LayoutType)}>
|
<div class={styles.link}>
|
||||||
<Icon name={`create-${layout.toLowerCase()}`} class={styles.icon} />
|
<Icon name={`create-${layout.toLowerCase()}`} class={styles.icon} />
|
||||||
<div>{t(layout)}</div>
|
<div>{t(layout)}</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
Loading…
Reference in New Issue
Block a user