Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor(ui/auth): ensure compatibility with new client types #1009

Merged
merged 1 commit into from
Oct 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions ui/plugin-auth/DialogExample.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import type { ContextApi } from 'artalk'
import { createSignal } from 'solid-js'
import { Dialog } from './Dialog'
import type { AuthContext } from './types'

interface DialogExampleProps {
ctx: ContextApi
ctx: AuthContext
onClose: () => void
}

Expand Down
10 changes: 5 additions & 5 deletions ui/plugin-auth/DialogMain.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import type { ContextApi } from 'artalk'
import { Show, createResource, createSignal, onMount } from 'solid-js'
import { createResource, createSignal } from 'solid-js'
import { Dialog } from './Dialog'
import { DialogMethods } from './DialogMethods'
import { DialogPageLogin } from './DialogPageLogin'
import { DialogPageRegister } from './DialogPageRegister'
import { createLayer } from './lib/layer'
import { DialogMerge } from './merge/DialogMerge'
import { fetchMethods, LoginMethod } from './lib/methods'
import type { AuthContext } from './types'

interface DialogMainProps {
ctx: ContextApi
ctx: AuthContext
onClose: () => void
onSkip: () => void
}
Expand All @@ -18,7 +18,7 @@ export const DialogMain = (props: DialogMainProps) => {
const { ctx, onClose, onSkip, ...others } = props

const [methods] = createResource(async () => {
return fetchMethods(ctx)
return fetchMethods(ctx.getApi())
.then((m) =>
m.map<LoginMethod>((mm) => {
if (mm.name === 'email') mm.onClick = () => setPage('login')
Expand All @@ -43,7 +43,7 @@ export const DialogMain = (props: DialogMainProps) => {
const onComplete = () => {
onClose()

ctx.get('editor').getUI().$header.style.display = 'none'
ctx.getEditor().getUI().$header.style.display = 'none'

// Check need to merge
ctx
Expand Down
6 changes: 3 additions & 3 deletions ui/plugin-auth/DialogMethods.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { createEffect, createMemo, createSignal, For, Resource } from 'solid-js'
import type { ContextApi } from 'artalk'
import { startOAuthLogin } from './lib/oauth-login'
import { loginByToken } from './lib/token-login'
import { LoginMethod } from './lib/methods'
import type { AuthContext } from './types'

export interface DialogMethodsProps {
ctx: ContextApi
ctx: AuthContext
methods: Resource<LoginMethod[]>
changeTitle: (title: string) => void
onComplete: () => void
Expand All @@ -23,7 +23,7 @@ export const DialogMethods = (props: DialogMethodsProps) => {
(async () => {
const url = /^(http|https):\/\//.test(m.link!)
? m.link!
: `${ctx.getConf().server}${m.link}`
: `${ctx.getConf().get().server}${m.link}`
const { token } = await startOAuthLogin(ctx, url)
loginByToken(ctx, token)
props.onComplete()
Expand Down
4 changes: 2 additions & 2 deletions ui/plugin-auth/DialogPageLogin.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import type { ContextApi } from 'artalk'
import { createStore } from 'solid-js/store'
import { loginByApiRes } from './lib/token-login'
import type { AuthContext } from './types'

export interface DialogPageLoginProps {
ctx: ContextApi
ctx: AuthContext
onRegisterNowClick: () => void
changeTitle: (title: string) => void
onComplete: () => void
Expand Down
4 changes: 2 additions & 2 deletions ui/plugin-auth/DialogPageRegister.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import type { ContextApi } from 'artalk'
import { Show, createSignal, createEffect } from 'solid-js'
import { createStore, reconcile } from 'solid-js/store'
import { VerifyButton } from './VerifyButton'
import { loginByApiRes } from './lib/token-login'
import type { AuthContext } from './types'

export interface DialogPageRegisterProps {
ctx: ContextApi
ctx: AuthContext
onLoginNowClick: () => void
changeTitle: (title: string) => void
onComplete: () => void
Expand Down
16 changes: 8 additions & 8 deletions ui/plugin-auth/EditorUser.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import type { ContextApi } from 'artalk'
import { Show, onCleanup, createSignal } from 'solid-js'
import { render } from 'solid-js/web'
import { AuthContext } from './types'
import { createLayer } from './lib/layer'
import { UserProfileDialog } from './UserProfileDialog'

const EditorUser = ({ ctx }: { ctx: ContextApi }) => {
const EditorUser = ({ ctx }: { ctx: AuthContext }) => {
const logoutHandler = () => {
window.confirm(ctx.$t('logoutConfirm')) &&
ctx.get('user').update({
ctx.getUser().update({
token: '',
name: '',
email: '',
Expand All @@ -16,17 +16,17 @@ const EditorUser = ({ ctx }: { ctx: ContextApi }) => {
})
}

const getUser = () => ({ ...ctx.get('user').getData() }) // Must clone the object to avoid reactivity problem
const getUser = () => ({ ...ctx.getUser().getData() }) // Must clone the object to avoid reactivity problem

const [user, setUser] = createSignal(getUser())

const userChangedHandler = (u: any) => {
setUser(getUser())
}
ctx.on('user-changed', userChangedHandler)
ctx.getEvents().on('user-changed', userChangedHandler)

onCleanup(() => {
ctx.off('user-changed', userChangedHandler)
ctx.getEvents().off('user-changed', userChangedHandler)
})

const openUserProfileDialog = () => {
Expand Down Expand Up @@ -62,8 +62,8 @@ const EditorUser = ({ ctx }: { ctx: ContextApi }) => {
)
}

export const RenderEditorUser = (ctx: ContextApi) => {
const editor = ctx.get('editor')
export const RenderEditorUser = (ctx: AuthContext) => {
const editor = ctx.getEditor()
const findEl = () => editor.getEl().querySelector('.atk-editor-user-wrap')

if (!findEl()) {
Expand Down
15 changes: 8 additions & 7 deletions ui/plugin-auth/UserProfileDialog.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import { ContextApi, LocalUser } from 'artalk'
import { LocalUser } from 'artalk'
import { createResource, createSignal, Resource, Show } from 'solid-js'
import { createStore } from 'solid-js/store'
import type { AuthContext } from './types'
import { Dialog } from './Dialog'
import { VerifyButton } from './VerifyButton'

export interface UserProfileDialogProps {
ctx: ContextApi
ctx: AuthContext
onClose: () => void
}

Expand All @@ -17,7 +18,7 @@ export const UserProfileDialog = (props: UserProfileDialogProps) => {
const [userInfo] = createResource<LocalUser>(async () => {
const { data } = await ctx.getApi().user.getUser()
if (!data.is_login) {
ctx.get('user').logout()
ctx.getUser().logout()
onClose()
throw new Error('No login')
}
Expand All @@ -43,7 +44,7 @@ export const UserProfileDialog = (props: UserProfileDialogProps) => {
}

const UserBasicProfileForm = (
ctx: ContextApi,
ctx: AuthContext,
onChangePassword: () => void,
setTitle: (t: string) => void,
user: Resource<LocalUser>,
Expand All @@ -69,7 +70,7 @@ const UserBasicProfileForm = (
...fields,
})
.then(({ data: { user } }) => {
ctx.get('user').update(user)
ctx.getUser().update(user)
onClose()
})
.catch((e) => {
Expand Down Expand Up @@ -136,7 +137,7 @@ const UserBasicProfileForm = (
}

const UserChangePasswordForm = (
ctx: ContextApi,
ctx: AuthContext,
setTitle: (t: string) => void,
user: Resource<LocalUser>,
onClose: () => void,
Expand Down Expand Up @@ -166,7 +167,7 @@ const UserChangePasswordForm = (
code: fields.code,
})
.then((res) => {
ctx.get('user').logout()
ctx.getUser().logout()
onClose()
})
.catch((err) => {
Expand Down
4 changes: 2 additions & 2 deletions ui/plugin-auth/VerifyButton.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import type { ContextApi } from 'artalk'
import { createSignal } from 'solid-js'
import type { AuthContext } from './types'

interface VerifyButtonProps {
ctx: ContextApi
ctx: AuthContext
getEmail: () => string
onSend?: () => void
}
Expand Down
7 changes: 4 additions & 3 deletions ui/plugin-auth/lib/layer.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import type { ContextApi, Layer } from 'artalk'
import { JSX } from 'solid-js'
import { render } from 'solid-js/web'
import type { Layer } from 'artalk'
import type { AuthContext } from '../types'

export const createLayer = (ctx: ContextApi) => {
const layer = ctx.get('layerManager').create('login')
export const createLayer = (ctx: AuthContext) => {
const layer = ctx.getLayers().create('login')
const show = (el: (l: Layer) => JSX.Element) => {
const $el = document.createElement('div')
render(() => el(layer), $el)
Expand Down
6 changes: 3 additions & 3 deletions ui/plugin-auth/lib/methods.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ContextApi } from 'artalk'
import type { Api } from 'artalk'

export interface LoginMethod {
name: string
Expand All @@ -8,8 +8,8 @@ export interface LoginMethod {
onClick?: () => void
}

export const fetchMethods = async (ctx: ContextApi) => {
const { data } = await ctx.getApi().conf.getSocialLoginProviders()
export const fetchMethods = async (api: Api) => {
const { data } = await api.conf.getSocialLoginProviders()
return data.providers
.map<LoginMethod>(({ name, label, icon, path }) => {
return { name, label, icon, link: path }
Expand Down
4 changes: 2 additions & 2 deletions ui/plugin-auth/lib/oauth-login.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { ContextApi } from 'artalk'
import type { AuthContext } from '../types'

let watchTimer: any = null
let messageHandler: ((evt: MessageEvent) => void) | null = null
Expand All @@ -8,7 +8,7 @@ const clearListener = () => {
messageHandler && window.removeEventListener('message', messageHandler)
}

export const startOAuthLogin = (ctx: ContextApi, url: string) => {
export const startOAuthLogin = (ctx: AuthContext, url: string) => {
clearListener()

const width = 1020
Expand Down
13 changes: 7 additions & 6 deletions ui/plugin-auth/lib/token-login.ts
Original file line number Diff line number Diff line change
@@ -1,25 +1,26 @@
import type { ContextApi, LocalUser } from 'artalk'
import type { LocalUser } from 'artalk'
import type { AuthContext } from '../types'

interface ResponseLoginData {
user: Omit<LocalUser, 'token'>
token: string
}

export const loginByApiRes = (ctx: ContextApi, { user, token }: ResponseLoginData) => {
ctx.get('user').update({
export const loginByApiRes = (ctx: AuthContext, { user, token }: ResponseLoginData) => {
ctx.getUser().update({
...user,
token,
})
}

export const loginByToken = (ctx: ContextApi, token: string) => {
ctx.get('user').update({ token })
export const loginByToken = (ctx: AuthContext, token: string) => {
ctx.getUser().update({ token })
ctx
.getApi()
.user.getUser()
.then((res) => {
const { user } = res.data
ctx.get('user').update({
ctx.getUser().update({
name: user.name,
email: user.email,
link: user.link,
Expand Down
50 changes: 35 additions & 15 deletions ui/plugin-auth/main.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,33 +4,53 @@ import type { ArtalkPlugin } from 'artalk'
import { DialogMain } from './DialogMain'
import { createLayer } from './lib/layer'
import { RenderEditorUser } from './EditorUser'
import type { AuthContext } from './types'

export const ArtalkAuthPlugin: ArtalkPlugin = (ctx) => {
ctx.getApiHandlers().add('need_auth_login', () => {
const editor = ctx.inject('editor')
const api = ctx.inject('api')
const apiHandlers = ctx.inject('apiHandlers')
const user = ctx.inject('user')
const events = ctx.inject('events')
const config = ctx.inject('config')
const layers = ctx.inject('layers')

const authCtx: AuthContext = {
getEditor: () => editor,
getApi: () => api,
getApiHandlers: () => apiHandlers,
getUser: () => user,
getEvents: () => events,
getConf: () => config,
getLayers: () => layers,
$t: (key, args) => ctx.$t(key, args),
}

apiHandlers.add('need_auth_login', () => {
openAuthDialog()
throw new Error('Login required')
})

let anonymous = false
const refreshBtn = () => {
ctx.get('editor').getUI().$submitBtn.innerText =
ctx.get('user').getData().token || anonymous
? ctx.conf.sendBtn || ctx.$t('send')
: ctx.$t('signIn')
editor.getUI().$submitBtn.innerText =
user.getData().token || anonymous
? authCtx.getConf().get().sendBtn || authCtx.$t('send')
: authCtx.$t('signIn')
}

ctx.watchConf(['locale', 'sendBtn'], () => refreshBtn())
ctx.on('user-changed', () => refreshBtn())
authCtx.getConf().watchConf(['locale', 'sendBtn'], () => refreshBtn())
authCtx.getEvents().on('user-changed', () => refreshBtn())

ctx.on('mounted', () => {
ctx.get('editor').getUI().$header.style.display = 'none'
authCtx.getEvents().on('mounted', () => {
editor.getUI().$header.style.display = 'none'

RenderEditorUser(ctx)
RenderEditorUser(authCtx)
})

const onSkip = () => {
ctx.get('editor').getUI().$header.style.display = ''
ctx.get('editor').getUI().$name.focus()
editor.getUI().$header.style.display = ''
editor.getUI().$name.focus()
ctx.updateConf({
beforeSubmit: undefined,
})
Expand All @@ -40,14 +60,14 @@ export const ArtalkAuthPlugin: ArtalkPlugin = (ctx) => {
}

const openAuthDialog = () => {
createLayer(ctx).show((layer) => (
<DialogMain ctx={ctx} onClose={() => layer.destroy()} onSkip={onSkip} />
createLayer(authCtx).show((layer) => (
<DialogMain ctx={authCtx} onClose={() => layer.destroy()} onSkip={onSkip} />
))
}

ctx.updateConf({
beforeSubmit: (editor, next) => {
if (!ctx.get('user').getData().token) {
if (!user.getData().token) {
openAuthDialog()
} else {
next()
Expand Down
4 changes: 2 additions & 2 deletions ui/plugin-auth/merge/DialogMerge.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import type { ContextApi } from 'artalk'
import { createSignal } from 'solid-js'
import { Dialog } from '../Dialog'
import type { AuthContext } from '../types'
import { DialogMergePageConfirm } from './DialogMergePageConfirm'

interface DialogMergeProps {
ctx: ContextApi
ctx: AuthContext
usernames: string[]
onClose: () => void
}
Expand Down
Loading