prefixed-queries

This commit is contained in:
Untone 2023-12-14 02:56:44 +03:00
parent 9d93ee0a6c
commit dfbbb075e8
14 changed files with 81 additions and 54 deletions

View File

@ -25,7 +25,7 @@ type Props = {
export const AuthorBadge = (props: Props) => {
const [isSubscribing, setIsSubscribing] = createSignal(false)
const {
session,
author,
subscriptions,
actions: { loadSubscriptions, requireAuthentication },
} = useSession()
@ -96,7 +96,7 @@ export const AuthorBadge = (props: Props) => {
</Show>
</a>
</div>
<Show when={props.author.slug !== session()?.user.slug && !props.nameOnly}>
<Show when={props.author.slug !== author()?.slug && !props.nameOnly}>
<div class={styles.actions}>
<Show
when={!props.minimizeSubscribeButton}

View File

@ -32,7 +32,6 @@ type Props = {
export const AuthorCard = (props: Props) => {
const { t, lang } = useLocalize()
const {
session,
author,
subscriptions,
isSessionLoaded,

View File

@ -32,7 +32,7 @@ const MD_WIDTH_BREAKPOINT = 992
export const HeaderAuth = (props: Props) => {
const { t } = useLocalize()
const { page } = useRouter()
const { author, session, isSessionLoaded, isAuthenticated } = useSession()
const { author, isAuthenticated, isSessionLoaded } = useSession()
const {
unreadNotificationsCount,
actions: { showNotificationsPanel },
@ -147,7 +147,7 @@ export const HeaderAuth = (props: Props) => {
</div>
</Show>
<Show when={!session()}>
<Show when={!author()}>
<div class={styles.userControlItem} onClick={handleBellIconClick}>
<div class={styles.button}>
<Icon name="bell-white" counter={1} class={styles.icon} />

View File

@ -13,7 +13,7 @@ type ProfilePopupProps = Omit<PopupProps, 'children'>
export const ProfilePopup = (props: ProfilePopupProps) => {
const {
user,
author,
actions: { signOut },
} = useSession()
@ -23,18 +23,18 @@ export const ProfilePopup = (props: ProfilePopupProps) => {
<Popup {...props} horizontalAnchor="right" variant="bordered">
<ul class="nodash">
<li>
<a href={getPagePath(router, 'author', { slug: user().slug })}>{t('Profile')}</a>
<a href={getPagePath(router, 'author', { slug: author().slug })}>{t('Profile')}</a>
</li>
<li>
<a href={getPagePath(router, 'drafts')}>{t('Drafts')}</a>
</li>
<li>
<a href={`${getPagePath(router, 'author', { slug: user().slug })}?modal=following`}>
<a href={`${getPagePath(router, 'author', { slug: author().slug })}?modal=following`}>
{t('Subscriptions')}
</a>
</li>
<li>
<a href={`${getPagePath(router, 'authorComments', { slug: user().slug })}`}>{t('Comments')}</a>
<a href={`${getPagePath(router, 'authorComments', { slug: author().slug })}`}>{t('Comments')}</a>
</li>
<li>
<a href="#">{t('Bookmarks')}</a>

View File

@ -177,18 +177,18 @@ export const ProfileSettings = () => {
<h4>{t('Userpic')}</h4>
<div class="pretty-form__item">
<div
class={clsx(styles.userpic, { [styles.hasControls]: form.userpic })}
onClick={!form.userpic && handleUploadAvatar}
class={clsx(styles.userpic, { [styles.hasControls]: form.pic })}
onClick={!form.pic && handleUploadAvatar}
>
<Switch>
<Match when={isUserpicUpdating()}>
<Loading />
</Match>
<Match when={form.userpic}>
<Match when={form.pic}>
<div
class={styles.userpicImage}
style={{
'background-image': `url(${getImageUrl(form.userpic, {
'background-image': `url(${getImageUrl(form.pic, {
width: 180,
height: 180,
})})`,
@ -200,7 +200,7 @@ export const ProfileSettings = () => {
<button
ref={triggerRef}
class={styles.control}
onClick={() => updateFormField('userpic', '')}
onClick={() => updateFormField('pic', '')}
>
<Icon name="close" />
</button>
@ -219,7 +219,7 @@ export const ProfileSettings = () => {
</Popover>
</div>
</Match>
<Match when={!form.userpic}>
<Match when={!form.pic}>
<Icon name="user-image-gray" />
{t('Here you can upload your photo')}
</Match>

View File

@ -39,38 +39,33 @@ export const ConnectProvider = (props: { children: JSX.Element }) => {
}
const [retried, setRetried] = createSignal<number>(0)
const listen = () => {
if (isAuthenticated() && !connected() && retried() < 4) {
try {
fetchEventSource('https://connect.discours.io', {
method: 'GET',
headers: {
'Content-Type': 'application/json',
Authorization: getToken(),
},
onmessage(event) {
const m: SSEMessage = JSON.parse(event.data)
console.log('[context.connect] Received message:', m)
const token = getToken()
console.log(`[context.connect] token: ${token}`)
if (token && !connected() && retried() < 4) {
fetchEventSource('https://connect.discours.io', {
method: 'GET',
headers: {
'Content-Type': 'application/json',
Authorization: token,
},
onmessage(event) {
const m: SSEMessage = JSON.parse(event.data)
console.log('[context.connect] Received message:', m)
// Iterate over all registered handlers and call them
messageHandlers().forEach((handler) => handler(m))
},
onclose() {
console.log('[context.connect] sse connection closed by server')
setConnected(false)
},
onerror(err) {
console.error('[context.connect] sse connection error', err)
setConnected(false)
throw new Error(err) // NOTE: simple hack to close the connection
},
})
} catch (err) {
if (retried() < 4) {
// Iterate over all registered handlers and call them
messageHandlers().forEach((handler) => handler(m))
},
onclose() {
console.log('[context.connect] sse connection closed by server')
setConnected(false)
},
onerror(err) {
console.error('[context.connect] sse connection error', err)
setRetried((r) => r + 1)
} else {
console.warn('Not trying to reconnect anymore; listen() should be called again.')
}
}
setConnected(false)
throw new Error(err) // NOTE: simple hack to close the connection
},
})
}
}

View File

@ -10,6 +10,7 @@ import { notifierClient } from '../graphql/client/notifier'
import { Notification } from '../graphql/schema/notifier.gen'
import { SSEMessage, useConnect } from './connect'
import { useSession } from './session'
type NotificationsContextType = {
notificationEntities: Record<number, Notification>
@ -38,12 +39,13 @@ export const NotificationsProvider = (props: { children: JSX.Element }) => {
const [unreadNotificationsCount, setUnreadNotificationsCount] = createSignal(0)
const [totalNotificationsCount, setTotalNotificationsCount] = createSignal(0)
const [notificationEntities, setNotificationEntities] = createStore<Record<number, Notification>>({})
const { isAuthenticated } = useSession()
const apiClient = createMemo(() => {
if (!notifierClient.private) notifierClient.connect()
if (!notifierClient.private && isAuthenticated()) notifierClient.connect()
return notifierClient
})
const { addHandler } = useConnect()
const loadNotifications = async (options: { limit: number; offset?: number }) => {
const loadNotifications = async (options: { limit?: number; offset?: number }) => {
const { notifications, unread, total } = await apiClient().getNotifications(options)
const newNotificationEntities = notifications.reduce((acc, notification) => {
acc[notification.id] = notification

View File

@ -101,7 +101,7 @@ export const SessionProvider = (props: { children: JSX.Element }) => {
async () => {
const u = session()?.user
if (u) {
return (await apiClient.getAuthor({ user: u.id })) ?? null
return (await apiClient.getAuthorId({ user: u.id })) ?? null
}
return null
},

View File

@ -29,6 +29,7 @@ import draftsLoad from '../query/core/articles-load-drafts'
import myFeed from '../query/core/articles-load-feed'
import shoutsLoadSearch from '../query/core/articles-load-search'
import authorBy from '../query/core/author-by'
import authorId from '../query/core/author-id'
import authorFollowers from '../query/core/author-followers'
import authorsAll from '../query/core/authors-all'
import authorFollowed from '../query/core/authors-followed-by'
@ -79,10 +80,14 @@ export const apiClient = {
}
return response.data.load_authors_all
},
getAuthor: async (params: { slug?: string; author_id?: number; user?: string }): Promise<Author> => {
getAuthor: async (params: { slug?: string; author_id?: number }): Promise<Author> => {
const response = await publicGraphQLClient.query(authorBy, params).toPromise()
return response.data.get_author
},
getAuthorId: async (params: { user: string }): Promise<Author> => {
const response = await publicGraphQLClient.query(authorId, params).toPromise()
return response.data.get_author_id
},
getAuthorFollowers: async ({ slug }: { slug: string }): Promise<Author[]> => {
const response = await publicGraphQLClient.query(authorFollowers, { slug }).toPromise()
return response.data.get_author_followers

View File

@ -1,8 +1,8 @@
import { gql } from '@urql/core'
export default gql`
query GetAuthorBy($slug: String, $author_id: Int, $user: String) {
get_author(slug: $slug, author_id: $author_id, user: $user) {
query GetAuthorBy($slug: String, $author_id: Int) {
get_author(slug: $slug, author_id: $author_id) {
id
slug
name

View File

@ -0,0 +1,17 @@
import { gql } from '@urql/core'
export default gql`
query GetAuthorId($user: String!) {
get_author_id(user: $user) {
id
slug
name
bio
about
pic
links
created_at
last_seen
}
}
`

View File

@ -0,0 +1,9 @@
{
"query": "query ValidateToken($params: ValidateJWTTokenInput!) { validate_jwt_token(params: $params) { is_valid claims } }",
"variables": {
"params": {
"token_type": "access_token",
"token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJhbGxvd2VkX3JvbGVzIjpbInJlYWRlciJdLCJhdWQiOiI5YzExMzM3Ny01ZWVhLTRjODktOThlMS02OTMwMjQ2MmZjMDgiLCJleHAiOjE3MDI1MDM3NDksImlhdCI6MTcwMjUwMTk0OSwiaXNzIjoiaHR0cHM6Ly9hdXRoLmRpc2NvdXJzLmlvIiwibG9naW5fbWV0aG9kIjoiYmFzaWNfYXV0aCIsIm5vbmNlIjoiNTNhZmE1NzMtMWZhMC00NDNhLTk4NzktNWE0ZDk3YTQ1OWEzIiwicm9sZXMiOlsicmVhZGVyIl0sInNjb3BlIjpbIm9wZW5pZCIsImVtYWlsIiwicHJvZmlsZSJdLCJzdWIiOiIyNDU3NTc5Yi0yNTk3LTQzNjMtOGU1MC00YWM5ZjY5YzgyMWQiLCJ0b2tlbl90eXBlIjoiYWNjZXNzX3Rva2VuIn0.ImAmAFXkwReYhLvLR1GG3g0mDllQaj7NVWw5q9D7EFUHtpjuNOanlVfzoaqqB6CXkc_uSRlrfiaLkbfCzhbXAWpi49vOI9P2fvLv-41Y0p8FJZnruZDi1c8psyPU5gpCLp3nqtBTTIR2IP-Uu_1oYo2Hl02xdOFjVHw19f-WEf73L6APBPppNeE21IJJy8aU5uXBHv12Y--kH5tEzn83BNBKPm5yWay-k4DVuBnAJt_ODENqm5NAaiG-q2eG3GnXWpjgpDXf0cxVXdtJbvFcPIv-pH7Dm6ae8m4xM7MmVmpzCE5f-Qc1lwcfX51Cr6IMXUjHx0N3n54sKk91CPa_ug"
}
}
}

View File

@ -1,13 +1,13 @@
import { gql } from '@urql/core'
export default gql`
query LoadNotificationsQuery($params: NotificationsQueryParams!) {
load_notifications(params: $params) {
query LoadNotificationsQuery($limit: Int, $offset: Int) {
load_notifications(limit: $limit, offset: $offset) {
notifications {
id
entity
action
paylaod
payload
created_at
seen
}