article page. & comments fix

This commit is contained in:
Igor Lobanov 2022-12-06 17:03:55 +01:00
parent 2a70e3ebc5
commit e332a8a674
9 changed files with 40 additions and 38 deletions

View File

@ -1,11 +1,10 @@
import { For, Show } from 'solid-js'
import { For, Show, createMemo, createSignal, onMount } from 'solid-js'
import { useSession } from '../../context/session'
import Comment from './Comment'
import { t } from '../../utils/intl'
import { showModal } from '../../stores/ui'
import styles from '../../styles/Article.module.scss'
import { useReactionsStore } from '../../stores/zine/reactions'
import { createMemo, createSignal, onMount } from 'solid-js'
import type { Reaction } from '../../graphql/types.gen'
import { clsx } from 'clsx'
import { byCreated, byStat } from '../../utils/sortby'
@ -14,17 +13,17 @@ import { Loading } from '../Loading'
const ARTICLE_COMMENTS_PAGE_SIZE = 50
const MAX_COMMENT_LEVEL = 6
export const CommentsTree = (props: { shout: string; reactions?: Reaction[] }) => {
export const CommentsTree = (props: { shoutSlug: string }) => {
const [getCommentsPage, setCommentsPage] = createSignal(0)
const [commentsOrder, setCommentsOrder] = createSignal<'rating' | 'createdAt'>('createdAt')
const [isCommentsLoading, setIsCommentsLoading] = createSignal(false)
const [isLoadMoreButtonVisible, setIsLoadMoreButtonVisible] = createSignal(false)
const { session } = useSession()
const { sortedReactions, loadReactionsBy } = useReactionsStore({ reactions: props.reactions })
const { sortedReactions, loadReactionsBy } = useReactionsStore()
const reactions = createMemo<Reaction[]>(() =>
sortedReactions()
.sort(commentsOrder() === 'rating' ? byStat('rating') : byCreated)
.filter((r) => r.shout.slug === props.shout)
.filter((r) => r.shout.slug === props.shoutSlug)
)
const loadMore = async () => {
@ -33,7 +32,7 @@ export const CommentsTree = (props: { shout: string; reactions?: Reaction[] }) =
setIsCommentsLoading(true)
const { hasMore } = await loadReactionsBy({
by: { shout: props.shout, comment: true },
by: { shout: props.shoutSlug, comment: true },
limit: ARTICLE_COMMENTS_PAGE_SIZE,
offset: page * ARTICLE_COMMENTS_PAGE_SIZE
})

View File

@ -222,7 +222,7 @@ export const FullArticle = (props: ArticleProps) => {
)}
</For>
</div>
<CommentsTree shout={props.article?.slug} />
<CommentsTree shoutSlug={props.article?.slug} />
</div>
</div>
)

View File

@ -32,6 +32,7 @@ interface AuthorCardProps {
export const AuthorCard = (props: AuthorCardProps) => {
const {
session,
isSessionLoaded,
actions: { loadSession }
} = useSession()
@ -100,7 +101,7 @@ export const AuthorCard = (props: AuthorCardProps) => {
</Show>
</div>
<ShowOnlyOnClient>
<Show when={session.state !== 'pending'}>
<Show when={isSessionLoaded()}>
<Show when={canFollow()}>
<div class={styles.authorSubscribe}>
<Show

View File

@ -21,7 +21,7 @@ export const HeaderAuth = (props: HeaderAuthProps) => {
const [visibleWarnings, setVisibleWarnings] = createSignal(false)
const { warnings } = useWarningsStore()
const { session, isAuthenticated } = useSession()
const { session, isSessionLoaded, isAuthenticated } = useSession()
const toggleWarnings = () => setVisibleWarnings(!visibleWarnings())
@ -38,7 +38,7 @@ export const HeaderAuth = (props: HeaderAuthProps) => {
return (
<ShowOnlyOnClient>
<Show when={session.state !== 'pending'}>
<Show when={isSessionLoaded()}>
<div class={styles.usernav}>
<div class={clsx(styles.userControl, styles.userControl, 'col')}>
<div class={clsx(styles.userControlItem, styles.userControlItemVerbose)}>

View File

@ -28,6 +28,7 @@ interface TopicProps {
export const TopicCard = (props: TopicProps) => {
const {
session,
isSessionLoaded,
actions: { loadSession }
} = useSession()
@ -89,7 +90,7 @@ export const TopicCard = (props: TopicProps) => {
classList={{ 'col-md-3': !props.compact && !props.subscribeButtonBottom }}
>
<ShowOnlyOnClient>
<Show when={session.state !== 'pending'}>
<Show when={isSessionLoaded()}>
<button
onClick={() => subscribe(!subscribed())}
class="button--light button--subscribe-topic"

View File

@ -27,7 +27,7 @@ export const FEED_PAGE_SIZE = 20
export const FeedView = () => {
// state
const { sortedArticles } = useArticlesStore()
const { sortedReactions: topComments, loadReactionsBy } = useReactionsStore({})
const { sortedReactions: topComments, loadReactionsBy } = useReactionsStore()
const { sortedAuthors } = useAuthorsStore()
const { topTopics } = useTopicsStore()
const { topAuthors } = useTopAuthorsStore()

View File

@ -1,11 +1,12 @@
import type { Accessor, JSX, Resource } from 'solid-js'
import { createContext, createMemo, createResource, onMount, useContext } from 'solid-js'
import { createContext, createMemo, createResource, createSignal, onMount, useContext } from 'solid-js'
import type { AuthResult } from '../graphql/types.gen'
import { apiClient } from '../utils/apiClient'
import { resetToken, setToken } from '../graphql/privateGraphQLClient'
type SessionContextType = {
session: Resource<AuthResult>
isSessionLoaded: Accessor<boolean>
userSlug: Accessor<string>
isAuthenticated: Accessor<boolean>
actions: {
@ -18,6 +19,13 @@ type SessionContextType = {
const SessionContext = createContext<SessionContextType>()
export function useSession() {
return useContext(SessionContext)
}
export const SessionProvider = (props: { children: JSX.Element }) => {
const [isSessionLoaded, setIsSessionLoaded] = createSignal(false)
const getSession = async (): Promise<AuthResult> => {
try {
const authResult = await apiClient.getSession()
@ -25,6 +33,7 @@ const getSession = async (): Promise<AuthResult> => {
return null
}
setToken(authResult.token)
setIsSessionLoaded(true)
return authResult
} catch (error) {
console.error('getSession error:', error)
@ -33,12 +42,10 @@ const getSession = async (): Promise<AuthResult> => {
}
}
export function useSession() {
return useContext(SessionContext)
}
export const SessionProvider = (props: { children: JSX.Element }) => {
const [session, { refetch: loadSession, mutate }] = createResource<AuthResult>(getSession)
const [session, { refetch: loadSession, mutate }] = createResource<AuthResult>(getSession, {
ssrLoadFrom: 'initial',
initialValue: null
})
const userSlug = createMemo(() => session()?.user?.slug)
@ -71,7 +78,7 @@ export const SessionProvider = (props: { children: JSX.Element }) => {
confirmEmail
}
const value: SessionContextType = { session, userSlug, isAuthenticated, actions }
const value: SessionContextType = { session, isSessionLoaded, userSlug, isAuthenticated, actions }
onMount(() => {
loadSession()

View File

@ -22,8 +22,8 @@ export type AuthResult = {
}
export type Author = {
bio?: Maybe<Scalars['String']>
about?: Maybe<Scalars['String']>
bio?: Maybe<Scalars['String']>
caption?: Maybe<Scalars['String']>
id: Scalars['Int']
lastSeen?: Maybe<Scalars['DateTime']>
@ -334,8 +334,6 @@ export type Permission = {
export type ProfileInput = {
about?: InputMaybe<Scalars['String']>
bio?: InputMaybe<Scalars['String']>
slug?: InputMaybe<Scalars['String']>
about?: InputMaybe<Scalars['String']>
links?: InputMaybe<Array<InputMaybe<Scalars['String']>>>
name?: InputMaybe<Scalars['String']>
slug?: InputMaybe<Scalars['String']>

View File

@ -37,11 +37,7 @@ export const deleteReaction = async (reactionId: number) => {
console.debug(resp)
return resp
}
export const useReactionsStore = (initialState: { reactions?: Reaction[] }) => {
if (initialState.reactions) {
setSortedReactions([...initialState.reactions])
}
export const useReactionsStore = () => {
return {
reactionsByShout,
sortedReactions,