code review
This commit is contained in:
parent
269f7328d8
commit
338d9e3d08
|
@ -10,7 +10,7 @@ import { showModal } from '../../stores/ui'
|
|||
import { incrementView } from '../../stores/zine/articles'
|
||||
import MD from './MD'
|
||||
import { SharePopup } from './SharePopup'
|
||||
import { useAuth } from '../../context/auth'
|
||||
import { useSession } from '../../context/session'
|
||||
|
||||
const MAX_COMMENT_LEVEL = 6
|
||||
|
||||
|
@ -38,7 +38,7 @@ const formatDate = (date: Date) => {
|
|||
}
|
||||
|
||||
export const FullArticle = (props: ArticleProps) => {
|
||||
const { session } = useAuth()
|
||||
const { session } = useSession()
|
||||
|
||||
onMount(() => {
|
||||
incrementView({ articleSlug: props.article.slug })
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
import { Icon } from '../Nav/Icon'
|
||||
import styles from '../Nav/Popup.module.scss'
|
||||
import { t } from '../../utils/intl'
|
||||
import { Popup, PopupProps } from '../Nav/Popup'
|
||||
|
||||
import styles from '../_shared/Popup.module.scss'
|
||||
import type { PopupProps } from '../_shared/Popup'
|
||||
import { Popup } from '../_shared/Popup'
|
||||
|
||||
type SharePopupProps = Omit<PopupProps, 'children'>
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ import { t } from '../../utils/intl'
|
|||
import { locale } from '../../stores/ui'
|
||||
import { follow, unfollow } from '../../stores/zine/common'
|
||||
import { clsx } from 'clsx'
|
||||
import { useAuth } from '../../context/auth'
|
||||
import { useSession } from '../../context/session'
|
||||
|
||||
interface AuthorCardProps {
|
||||
compact?: boolean
|
||||
|
@ -23,7 +23,7 @@ interface AuthorCardProps {
|
|||
}
|
||||
|
||||
export const AuthorCard = (props: AuthorCardProps) => {
|
||||
const { session } = useAuth()
|
||||
const { session } = useSession()
|
||||
|
||||
const subscribed = createMemo<boolean>(
|
||||
() => session()?.news?.authors?.some((u) => u === props.author.slug) || false
|
||||
|
|
|
@ -6,7 +6,7 @@ import { Icon } from '../Nav/Icon'
|
|||
import { useTopicsStore } from '../../stores/zine/topics'
|
||||
import { useArticlesStore } from '../../stores/zine/articles'
|
||||
import { useSeenStore } from '../../stores/zine/seen'
|
||||
import { useAuth } from '../../context/auth'
|
||||
import { useSession } from '../../context/session'
|
||||
|
||||
type FeedSidebarProps = {
|
||||
authors: Author[]
|
||||
|
@ -14,7 +14,7 @@ type FeedSidebarProps = {
|
|||
|
||||
export const FeedSidebar = (props: FeedSidebarProps) => {
|
||||
const { getSeen: seen } = useSeenStore()
|
||||
const { session } = useAuth()
|
||||
const { session } = useSession()
|
||||
const { authorEntities } = useAuthorsStore({ authors: props.authors })
|
||||
const { articlesByTopic } = useArticlesStore()
|
||||
const { topicEntities } = useTopicsStore()
|
||||
|
|
|
@ -5,14 +5,14 @@ import { hideModal } from '../../../stores/ui'
|
|||
import { createMemo, createSignal, onMount, Show } from 'solid-js'
|
||||
import { handleClientRouteLinkClick, useRouter } from '../../../stores/router'
|
||||
import type { ConfirmEmailSearchParams } from './types'
|
||||
import { useAuth } from '../../../context/auth'
|
||||
import { ApiError } from '../../../utils/apiClient'
|
||||
import { useSession } from '../../../context/session'
|
||||
|
||||
export const EmailConfirm = () => {
|
||||
const {
|
||||
session,
|
||||
actions: { confirmEmail }
|
||||
} = useAuth()
|
||||
} = useSession()
|
||||
|
||||
const [isTokenExpired, setIsTokenExpired] = createSignal(false)
|
||||
const [isTokenInvalid, setIsTokenInvalid] = createSignal(false)
|
||||
|
|
|
@ -7,8 +7,8 @@ import { email, setEmail } from './sharedLogic'
|
|||
import type { AuthModalSearchParams } from './types'
|
||||
import { isValidEmail } from './validators'
|
||||
import { locale } from '../../../stores/ui'
|
||||
import { signSendLink } from '../../../context/auth'
|
||||
import { ApiError } from '../../../utils/apiClient'
|
||||
import { signSendLink } from '../../../stores/auth'
|
||||
|
||||
type FormFields = {
|
||||
email: string
|
||||
|
|
|
@ -9,7 +9,8 @@ import { email, setEmail } from './sharedLogic'
|
|||
import { useRouter } from '../../../stores/router'
|
||||
import type { AuthModalSearchParams } from './types'
|
||||
import { hideModal, locale } from '../../../stores/ui'
|
||||
import { signSendLink, useAuth } from '../../../context/auth'
|
||||
import { useSession } from '../../../context/session'
|
||||
import { signSendLink } from '../../../stores/auth'
|
||||
|
||||
type FormFields = {
|
||||
email: string
|
||||
|
@ -28,7 +29,7 @@ export const LoginForm = () => {
|
|||
|
||||
const {
|
||||
actions: { signIn }
|
||||
} = useAuth()
|
||||
} = useSession()
|
||||
|
||||
const { changeSearchParam } = useRouter<AuthModalSearchParams>()
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@ import { useRouter } from '../../../stores/router'
|
|||
import type { AuthModalSearchParams } from './types'
|
||||
import { hideModal } from '../../../stores/ui'
|
||||
import { checkEmail, useEmailChecks } from '../../../stores/emailChecks'
|
||||
import { register } from '../../../context/auth'
|
||||
import { register } from '../../../stores/auth'
|
||||
|
||||
type FormFields = {
|
||||
name: string
|
||||
|
|
|
@ -9,19 +9,19 @@ import { ProfilePopup } from './ProfilePopup'
|
|||
import Userpic from '../Author/Userpic'
|
||||
import type { Author } from '../../graphql/types.gen'
|
||||
import { showModal, useWarningsStore } from '../../stores/ui'
|
||||
import { useAuth } from '../../context/auth'
|
||||
import { ClientContainer } from '../_shared/ClientContainer'
|
||||
import { useSession } from '../../context/session'
|
||||
|
||||
type HeaderAuthProps = {
|
||||
setIsProfilePopupVisible: (value: boolean) => void
|
||||
}
|
||||
|
||||
export const HeaderAuth = (props: HeaderAuthProps) => {
|
||||
const [isMounted, setIsMounted] = createSignal(false)
|
||||
const { page } = useRouter()
|
||||
const [visibleWarnings, setVisibleWarnings] = createSignal(false)
|
||||
const { warnings } = useWarningsStore()
|
||||
|
||||
const { session, isAuthenticated } = useAuth()
|
||||
const { session, isAuthenticated } = useSession()
|
||||
|
||||
const toggleWarnings = () => setVisibleWarnings(!visibleWarnings())
|
||||
|
||||
|
@ -36,12 +36,8 @@ export const HeaderAuth = (props: HeaderAuthProps) => {
|
|||
toggleWarnings()
|
||||
}
|
||||
|
||||
onMount(() => {
|
||||
setIsMounted(true)
|
||||
})
|
||||
|
||||
return (
|
||||
<Show when={isMounted()}>
|
||||
<ClientContainer>
|
||||
<Show when={!session.loading}>
|
||||
<div class={styles.usernav}>
|
||||
<div class={clsx(styles.userControl, styles.userControl, 'col')}>
|
||||
|
@ -106,6 +102,6 @@ export const HeaderAuth = (props: HeaderAuthProps) => {
|
|||
</div>
|
||||
</div>
|
||||
</Show>
|
||||
</Show>
|
||||
</ClientContainer>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -3,13 +3,13 @@ import type { Author } from '../../graphql/types.gen'
|
|||
import { t } from '../../utils/intl'
|
||||
import { hideModal } from '../../stores/ui'
|
||||
import { createMemo, For } from 'solid-js'
|
||||
import { useAuth } from '../../context/auth'
|
||||
import { useSession } from '../../context/session'
|
||||
|
||||
export const ProfileModal = () => {
|
||||
const {
|
||||
session,
|
||||
actions: { signOut }
|
||||
} = useAuth()
|
||||
} = useSession()
|
||||
|
||||
const quit = () => {
|
||||
signOut()
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import { Popup, PopupProps } from './Popup'
|
||||
import styles from './Popup.module.scss'
|
||||
import { useAuth } from '../../context/auth'
|
||||
import { useSession } from '../../context/session'
|
||||
import type { PopupProps } from '../_shared/Popup'
|
||||
import { Popup } from '../_shared/Popup'
|
||||
import styles from '../_shared/Popup.module.scss'
|
||||
|
||||
type ProfilePopupProps = Omit<PopupProps, 'children'>
|
||||
|
||||
|
@ -8,7 +9,7 @@ export const ProfilePopup = (props: ProfilePopupProps) => {
|
|||
const {
|
||||
session,
|
||||
actions: { signOut }
|
||||
} = useAuth()
|
||||
} = useSession()
|
||||
|
||||
return (
|
||||
<Popup {...props} horizontalAnchor="right">
|
||||
|
|
|
@ -29,7 +29,7 @@ import { TermsOfUsePage } from './Pages/about/TermsOfUsePage'
|
|||
import { ThanksPage } from './Pages/about/ThanksPage'
|
||||
import { CreatePage } from './Pages/CreatePage'
|
||||
import { ConnectPage } from './Pages/ConnectPage'
|
||||
import { AuthProvider } from '../context/auth'
|
||||
import { SessionProvider } from '../context/session'
|
||||
|
||||
// TODO: lazy load
|
||||
// const HomePage = lazy(() => import('./Pages/HomePage'))
|
||||
|
@ -103,8 +103,8 @@ export const Root = (props: PageProps) => {
|
|||
}
|
||||
|
||||
return (
|
||||
<AuthProvider>
|
||||
<SessionProvider>
|
||||
<Dynamic component={pageComponent()} {...props} />
|
||||
</AuthProvider>
|
||||
</SessionProvider>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@ import { locale } from '../../stores/ui'
|
|||
import { follow, unfollow } from '../../stores/zine/common'
|
||||
import { getLogger } from '../../utils/logger'
|
||||
import { clsx } from 'clsx'
|
||||
import { useAuth } from '../../context/auth'
|
||||
import { useSession } from '../../context/session'
|
||||
|
||||
const log = getLogger('TopicCard')
|
||||
|
||||
|
@ -24,7 +24,7 @@ interface TopicProps {
|
|||
}
|
||||
|
||||
export const TopicCard = (props: TopicProps) => {
|
||||
const { session } = useAuth()
|
||||
const { session } = useSession()
|
||||
|
||||
const subscribed = createMemo(() => {
|
||||
if (!session()?.user?.slug || !session()?.news?.topics) {
|
||||
|
|
|
@ -5,14 +5,14 @@ import styles from './Full.module.scss'
|
|||
import { follow, unfollow } from '../../stores/zine/common'
|
||||
import { t } from '../../utils/intl'
|
||||
import { clsx } from 'clsx'
|
||||
import { useAuth } from '../../context/auth'
|
||||
import { useSession } from '../../context/session'
|
||||
|
||||
type Props = {
|
||||
topic: Topic
|
||||
}
|
||||
|
||||
export const FullTopic = (props: Props) => {
|
||||
const { session } = useAuth()
|
||||
const { session } = useSession()
|
||||
|
||||
const subscribed = createMemo(() => session()?.news?.topics?.includes(props.topic?.slug))
|
||||
return (
|
||||
|
|
|
@ -7,7 +7,7 @@ import { useAuthorsStore, setAuthorsSort } from '../../stores/zine/authors'
|
|||
import { handleClientRouteLinkClick, useRouter } from '../../stores/router'
|
||||
import styles from '../../styles/AllTopics.module.scss'
|
||||
import { clsx } from 'clsx'
|
||||
import { useAuth } from '../../context/auth'
|
||||
import { useSession } from '../../context/session'
|
||||
|
||||
type AllAuthorsPageSearchParams = {
|
||||
by: '' | 'name' | 'shouts' | 'rating'
|
||||
|
@ -23,7 +23,7 @@ export const AllAuthorsView = (props: Props) => {
|
|||
const { sortedAuthors } = useAuthorsStore({ authors: props.authors })
|
||||
const [limit, setLimit] = createSignal(PAGE_SIZE)
|
||||
|
||||
const { session } = useAuth()
|
||||
const { session } = useSession()
|
||||
|
||||
createEffect(() => {
|
||||
setAuthorsSort(searchParams().by || 'shouts')
|
||||
|
|
|
@ -7,7 +7,7 @@ import { handleClientRouteLinkClick, useRouter } from '../../stores/router'
|
|||
import { TopicCard } from '../Topic/Card'
|
||||
import styles from '../../styles/AllTopics.module.scss'
|
||||
import { clsx } from 'clsx'
|
||||
import { useAuth } from '../../context/auth'
|
||||
import { useSession } from '../../context/session'
|
||||
|
||||
type AllTopicsPageSearchParams = {
|
||||
by: 'shouts' | 'authors' | 'title' | ''
|
||||
|
@ -28,7 +28,7 @@ export const AllTopicsView = (props: AllTopicsViewProps) => {
|
|||
sortBy: searchParams().by || 'shouts'
|
||||
})
|
||||
|
||||
const { session } = useAuth()
|
||||
const { session } = useSession()
|
||||
|
||||
createEffect(() => {
|
||||
setTopicsSort(searchParams().by || 'shouts')
|
||||
|
|
|
@ -1,17 +1,11 @@
|
|||
import { Show, onMount, createSignal } from 'solid-js'
|
||||
import { Editor } from '../EditorNew/Editor'
|
||||
import { ClientContainer } from '../_shared/ClientContainer'
|
||||
|
||||
export const CreateView = () => {
|
||||
// don't render anything on server
|
||||
// usage of isServer causing hydration errors
|
||||
const [isMounted, setIsMounted] = createSignal(false)
|
||||
|
||||
onMount(() => setIsMounted(true))
|
||||
|
||||
return (
|
||||
<Show when={isMounted()}>
|
||||
<ClientContainer>
|
||||
<Editor />
|
||||
</Show>
|
||||
</ClientContainer>
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@ import { useReactionsStore } from '../../stores/zine/reactions'
|
|||
import { useAuthorsStore } from '../../stores/zine/authors'
|
||||
import { useTopicsStore } from '../../stores/zine/topics'
|
||||
import { useTopAuthorsStore } from '../../stores/zine/topAuthors'
|
||||
import { useAuth } from '../../context/auth'
|
||||
import { useSession } from '../../context/session'
|
||||
|
||||
// const AUTHORSHIP_REACTIONS = [
|
||||
// ReactionKind.Accept,
|
||||
|
@ -32,7 +32,7 @@ export const FeedView = () => {
|
|||
const { sortedAuthors } = useAuthorsStore()
|
||||
const { topTopics } = useTopicsStore()
|
||||
const { topAuthors } = useTopAuthorsStore()
|
||||
const { session } = useAuth()
|
||||
const { session } = useSession()
|
||||
|
||||
const topReactions = createMemo(() => sortBy(reactions(), byCreated))
|
||||
|
||||
|
|
12
src/components/_shared/ClientContainer.tsx
Normal file
12
src/components/_shared/ClientContainer.tsx
Normal file
|
@ -0,0 +1,12 @@
|
|||
import type { JSX } from 'solid-js'
|
||||
import { createSignal, onMount, Show } from 'solid-js'
|
||||
|
||||
// show children only on client side
|
||||
// usage of isServer causing hydration errors
|
||||
export const ClientContainer = (props: { children: JSX.Element }) => {
|
||||
const [isMounted, setIsMounted] = createSignal(false)
|
||||
|
||||
onMount(() => setIsMounted(true))
|
||||
|
||||
return <Show when={isMounted()}>{props.children}</Show>
|
||||
}
|
|
@ -4,7 +4,7 @@ import type { AuthResult } from '../graphql/types.gen'
|
|||
import { apiClient } from '../utils/apiClient'
|
||||
import { resetToken, setToken } from '../graphql/privateGraphQLClient'
|
||||
|
||||
type AuthContextType = {
|
||||
type SessionContextType = {
|
||||
session: InitializedResource<AuthResult>
|
||||
isAuthenticated: Accessor<boolean>
|
||||
actions: {
|
||||
|
@ -15,7 +15,7 @@ type AuthContextType = {
|
|||
}
|
||||
}
|
||||
|
||||
const AuthContext = createContext<AuthContextType>()
|
||||
const SessionContext = createContext<SessionContextType>()
|
||||
|
||||
const refreshSession = async (): Promise<AuthResult> => {
|
||||
try {
|
||||
|
@ -32,31 +32,11 @@ const refreshSession = async (): Promise<AuthResult> => {
|
|||
}
|
||||
}
|
||||
|
||||
export const register = async ({
|
||||
name,
|
||||
email,
|
||||
password
|
||||
}: {
|
||||
name: string
|
||||
email: string
|
||||
password: string
|
||||
}) => {
|
||||
await apiClient.authRegister({
|
||||
name,
|
||||
email,
|
||||
password
|
||||
})
|
||||
export function useSession() {
|
||||
return useContext(SessionContext)
|
||||
}
|
||||
|
||||
export const signSendLink = async ({ email, lang }: { email: string; lang: string }) => {
|
||||
return await apiClient.authSendLink({ email, lang })
|
||||
}
|
||||
|
||||
export function useAuth() {
|
||||
return useContext(AuthContext)
|
||||
}
|
||||
|
||||
export const AuthProvider = (props: { children: JSX.Element }) => {
|
||||
export const SessionProvider = (props: { children: JSX.Element }) => {
|
||||
const [session, { refetch: refetchRefreshSession, mutate }] = createResource<AuthResult>(refreshSession, {
|
||||
ssrLoadFrom: 'initial',
|
||||
initialValue: null
|
||||
|
@ -91,11 +71,11 @@ export const AuthProvider = (props: { children: JSX.Element }) => {
|
|||
confirmEmail
|
||||
}
|
||||
|
||||
const value: AuthContextType = { session, isAuthenticated, actions }
|
||||
const value: SessionContextType = { session, isAuthenticated, actions }
|
||||
|
||||
onMount(() => {
|
||||
refetchRefreshSession()
|
||||
})
|
||||
|
||||
return <AuthContext.Provider value={value}>{props.children}</AuthContext.Provider>
|
||||
return <SessionContext.Provider value={value}>{props.children}</SessionContext.Provider>
|
||||
}
|
21
src/stores/auth.ts
Normal file
21
src/stores/auth.ts
Normal file
|
@ -0,0 +1,21 @@
|
|||
import { apiClient } from '../utils/apiClient'
|
||||
|
||||
export const register = async ({
|
||||
name,
|
||||
email,
|
||||
password
|
||||
}: {
|
||||
name: string
|
||||
email: string
|
||||
password: string
|
||||
}) => {
|
||||
await apiClient.authRegister({
|
||||
name,
|
||||
email,
|
||||
password
|
||||
})
|
||||
}
|
||||
|
||||
export const signSendLink = async ({ email, lang }: { email: string; lang: string }) => {
|
||||
return await apiClient.authSendLink({ email, lang })
|
||||
}
|
Loading…
Reference in New Issue
Block a user