dummy-runable
Some checks failed
deploy / test (push) Has been cancelled
deploy / deploy (push) Has been cancelled

This commit is contained in:
Untone 2023-11-29 11:23:08 +03:00
parent 29738ad34a
commit 590ece4d65
13 changed files with 97 additions and 47 deletions

View File

@ -15,7 +15,7 @@ generates:
# Generate types for core # Generate types for core
src/graphql/schema/core.gen.ts: src/graphql/schema/core.gen.ts:
schema: 'https://testapi.discours.io' schema: 'https://core.discours.io'
plugins: plugins:
- 'typescript' - 'typescript'
- 'typescript-operations' - 'typescript-operations'

View File

@ -1,6 +1,5 @@
import { useLocalize } from '../../../context/localize' import { useLocalize } from '../../../context/localize'
import { hideModal } from '../../../stores/ui' import { hideModal } from '../../../stores/ui'
import { apiBaseUrl } from '../../../utils/config'
import { Icon } from '../../_shared/Icon' import { Icon } from '../../_shared/Icon'
import styles from './SocialProviders.module.scss' import styles from './SocialProviders.module.scss'
@ -10,7 +9,11 @@ type Provider = 'facebook' | 'google' | 'vk' | 'github'
// 3rd party provider auth handler // 3rd party provider auth handler
const handleSocialAuthLinkClick = (event: MouseEvent, provider: Provider): void => { const handleSocialAuthLinkClick = (event: MouseEvent, provider: Provider): void => {
event.preventDefault() event.preventDefault()
const popup = window.open(`${apiBaseUrl}/oauth/${provider}`, provider, 'width=740, height=420') const popup = window.open(
`https://auth.discours.io/oauth_login/${provider}`,
provider,
'width=740, height=420',
) // TODO: precalculate window size
popup?.focus() popup?.focus()
hideModal() hideModal()
} }

View File

@ -6,12 +6,12 @@ import { VerifyEmailInput, LoginInput, AuthToken, User } from '@authorizerdev/au
import { createContext, createMemo, createResource, createSignal, onMount, useContext } from 'solid-js' import { createContext, createMemo, createResource, createSignal, onMount, useContext } from 'solid-js'
import { apiClient } from '../graphql/client/core' import { apiClient } from '../graphql/client/core'
import { getToken, resetToken } from '../graphql/privateGraphQLClient'
import { showModal } from '../stores/ui' import { showModal } from '../stores/ui'
import { useAuthorizer } from './authorizer' import { useAuthorizer } from './authorizer'
import { useLocalize } from './localize' import { useLocalize } from './localize'
import { useSnackbar } from './snackbar' import { useSnackbar } from './snackbar'
import { cookieStorage, createStorage } from '@solid-primitives/storage'
export type SessionContextType = { export type SessionContextType = {
session: Resource<AuthToken> session: Resource<AuthToken>
@ -52,7 +52,15 @@ export const SessionProvider = (props: { children: JSX.Element }) => {
actions: { showSnackbar }, actions: { showSnackbar },
} = useSnackbar() } = useSnackbar()
const [, { authorizer }] = useAuthorizer() const [, { authorizer }] = useAuthorizer()
const [authToken, setToken] = createSignal<string>('') // const [getToken, setToken] = createSignal<string>('')
// https://start.solidjs.com/api/createCookieSessionStorage
const [store, setStore, { remove, clear, toJSON }] = createStorage({
api: cookieStorage,
prefix: 'discoursio',
})
const getToken = () => store.token
const setToken = (value) => setStore('token', value)
const resetToken = () => remove('token')
const loadSubscriptions = async (): Promise<void> => { const loadSubscriptions = async (): Promise<void> => {
const result = await apiClient.getMySubscriptions() const result = await apiClient.getMySubscriptions()

View File

@ -10,6 +10,8 @@ import type {
Shout, Shout,
Result, Result,
QueryLoad_Authors_ByArgs, QueryLoad_Authors_ByArgs,
QueryLoad_Shouts_SearchArgs,
QueryLoad_Shouts_ByArgs,
} from '../schema/core.gen' } from '../schema/core.gen'
import createArticle from '../mutation/core/article-create' import createArticle from '../mutation/core/article-create'
@ -25,6 +27,7 @@ import { getPrivateClient } from '../privateGraphQLClient'
import { getPublicClient } from '../publicGraphQLClient' import { getPublicClient } from '../publicGraphQLClient'
import shoutLoad from '../query/core/article-load' import shoutLoad from '../query/core/article-load'
import shoutsLoadBy from '../query/core/articles-load-by' import shoutsLoadBy from '../query/core/articles-load-by'
import shoutsLoadSearch from '../query/core/articles-load-search'
import draftsLoad from '../query/core/articles-load-drafts' import draftsLoad from '../query/core/articles-load-drafts'
import myFeed from '../query/core/articles-load-feed' import myFeed from '../query/core/articles-load-feed'
import authorBy from '../query/core/author-by' import authorBy from '../query/core/author-by'
@ -176,8 +179,8 @@ export const apiClient = {
return resp.data.get_shout return resp.data.get_shout
}, },
getShouts: async (options: LoadShoutsOptions) => { getShouts: async (args: QueryLoad_Shouts_ByArgs) => {
const resp = await publicGraphQLClient.query(shoutsLoadBy, { options }).toPromise() const resp = await publicGraphQLClient.query(shoutsLoadBy, args).toPromise()
if (resp.error) { if (resp.error) {
console.error(resp) console.error(resp)
} }
@ -185,8 +188,17 @@ export const apiClient = {
return resp.data.load_shouts_by return resp.data.load_shouts_by
}, },
getMyFeed: async (options: LoadShoutsOptions) => { getShoutsSearch: async (args: QueryLoad_Shouts_SearchArgs) => {
const resp = await privateGraphQLClient.query(myFeed, { options }).toPromise() const resp = await publicGraphQLClient.query(shoutsLoadSearch, args).toPromise()
if (resp.error) {
console.error(resp)
}
return resp.data.load_shouts_search
},
getMyFeed: async (args: QueryLoad_Shouts_ByArgs) => {
const resp = await privateGraphQLClient.query(myFeed, args).toPromise()
if (resp.error) { if (resp.error) {
console.error(resp) console.error(resp)

View File

@ -0,0 +1,34 @@
import { gql } from '@urql/core'
export default gql`
query MyFeedQuery($options: LoadShoutsOptions) {
load_shouts_search(options: $options) {
id
title
subtitle
slug
layout
cover
topics {
id
title
body
slug
}
authors {
id
name
slug
pic
created_at
}
created_at
published_at
stat {
viewed
reacted
rating
}
}
}
`

View File

@ -14,12 +14,11 @@ export const onBeforeRender = async (pageContext: PageContext) => {
if (!author) { if (!author) {
throw render(404) throw render(404)
} }
const options = {
const authorShouts = await apiClient.getShouts({
filters: { author: slug, visibility: 'community' }, filters: { author: slug, visibility: 'community' },
limit: PRERENDERED_ARTICLES_COUNT, limit: PRERENDERED_ARTICLES_COUNT,
}) }
const authorShouts = await apiClient.getShouts({ options })
const pageProps: PageProps = { author, authorShouts, seo: { title: author.name } } const pageProps: PageProps = { author, authorShouts, seo: { title: author.name } }
return { return {

View File

@ -5,10 +5,11 @@ import { PRERENDERED_ARTICLES_COUNT } from '../../components/Views/Expo/Expo'
import { apiClient } from '../../graphql/client/core' import { apiClient } from '../../graphql/client/core'
export const onBeforeRender = async (_pageContext: PageContext) => { export const onBeforeRender = async (_pageContext: PageContext) => {
const expoShouts = await apiClient.getShouts({ const options = {
filters: { layouts: ['audio', 'video', 'literature', 'image'] }, filters: { layouts: ['audio', 'video', 'literature', 'image'] },
limit: PRERENDERED_ARTICLES_COUNT, limit: PRERENDERED_ARTICLES_COUNT,
}) }
const expoShouts = await apiClient.getShouts({ options })
const pageProps: PageProps = { expoShouts, seo: { title: '' } } const pageProps: PageProps = { expoShouts, seo: { title: '' } }
return { return {
pageContext: { pageContext: {

View File

@ -6,11 +6,11 @@ import { apiClient } from '../../graphql/client/core'
export const onBeforeRender = async (pageContext: PageContext) => { export const onBeforeRender = async (pageContext: PageContext) => {
const { layout } = pageContext.routeParams const { layout } = pageContext.routeParams
const expoShouts = await apiClient.getShouts({ const options = {
filters: { layouts: [layout] }, filters: { layouts: [layout] },
limit: PRERENDERED_ARTICLES_COUNT, limit: PRERENDERED_ARTICLES_COUNT,
}) }
const expoShouts = await apiClient.getShouts({ options })
const pageProps: PageProps = { expoShouts, seo: { title: '' } } const pageProps: PageProps = { expoShouts, seo: { title: '' } }
return { return {

View File

@ -5,11 +5,11 @@ import { PRERENDERED_ARTICLES_COUNT } from '../components/Views/Home'
import { apiClient } from '../graphql/client/core' import { apiClient } from '../graphql/client/core'
export const onBeforeRender = async (_pageContext: PageContext) => { export const onBeforeRender = async (_pageContext: PageContext) => {
const homeShouts = await apiClient.getShouts({ const options = {
filters: { visibility: 'public' }, filters: { visibility: 'public' },
limit: PRERENDERED_ARTICLES_COUNT, limit: PRERENDERED_ARTICLES_COUNT,
}) }
const homeShouts = await apiClient.getShouts({ options })
const pageProps: PageProps = { homeShouts, seo: { title: '' } } const pageProps: PageProps = { homeShouts, seo: { title: '' } }
return { return {

View File

@ -6,7 +6,7 @@ import { apiClient } from '../graphql/client/core'
export const onBeforeRender = async (pageContext: PageContext) => { export const onBeforeRender = async (pageContext: PageContext) => {
const { q } = pageContext.routeParams const { q } = pageContext.routeParams
const searchResults = await apiClient.getShouts({ filters: { title: q, body: q }, limit: 50 }) const searchResults = await apiClient.getShoutsSearch({ text: q, limit: 50 })
const pageProps: PageProps = { searchResults, seo: { title: '' } } const pageProps: PageProps = { searchResults, seo: { title: '' } }

View File

@ -137,12 +137,9 @@ export const loadShout = async (slug: string): Promise<void> => {
export const loadShouts = async ( export const loadShouts = async (
options: LoadShoutsOptions, options: LoadShoutsOptions,
): Promise<{ hasMore: boolean; newShouts: Shout[] }> => { ): Promise<{ hasMore: boolean; newShouts: Shout[] }> => {
const newShouts = await apiClient.getShouts({ options.limit += 1
...options, const newShouts = await apiClient.getShouts({ options })
limit: options.limit + 1, const hasMore = newShouts ?? newShouts.length === options.limit + 1
})
const hasMore = newShouts.length === options.limit + 1
if (hasMore) { if (hasMore) {
newShouts.splice(-1) newShouts.splice(-1)
@ -157,12 +154,9 @@ export const loadShouts = async (
export const loadMyFeed = async ( export const loadMyFeed = async (
options: LoadShoutsOptions, options: LoadShoutsOptions,
): Promise<{ hasMore: boolean; newShouts: Shout[] }> => { ): Promise<{ hasMore: boolean; newShouts: Shout[] }> => {
const newShouts = await apiClient.getMyFeed({ options.limit += 1
...options, const newShouts = await apiClient.getMyFeed({ options })
limit: options.limit + 1, const hasMore = newShouts ?? newShouts.length === options.limit + 1
})
const hasMore = newShouts.length === options.limit + 1
if (hasMore) { if (hasMore) {
newShouts.splice(-1) newShouts.splice(-1)
@ -193,15 +187,17 @@ type InitialState = {
const TOP_MONTH_ARTICLES_COUNT = 10 const TOP_MONTH_ARTICLES_COUNT = 10
export const loadTopMonthArticles = async (): Promise<void> => { export const loadTopMonthArticles = async (): Promise<void> => {
const articles = await apiClient.getShouts({ const daysago = Date.now() - 30 * 24 * 60 * 60 * 1000
const after = Math.floor(daysago / 1000)
const options: LoadShoutsOptions = {
filters: { filters: {
visibility: 'public', visibility: 'public',
// TODO: replace with from, to after,
time_ago: 30 * 24 * 60 * 60 * 1000,
}, },
order_by: 'rating_stat', order_by: 'rating_stat',
limit: TOP_MONTH_ARTICLES_COUNT, limit: TOP_MONTH_ARTICLES_COUNT,
}) }
const articles = await apiClient.getShouts({ options })
addArticles(articles) addArticles(articles)
setTopMonthArticles(articles) setTopMonthArticles(articles)
} }
@ -209,13 +205,14 @@ export const loadTopMonthArticles = async (): Promise<void> => {
const TOP_ARTICLES_COUNT = 10 const TOP_ARTICLES_COUNT = 10
export const loadTopArticles = async (): Promise<void> => { export const loadTopArticles = async (): Promise<void> => {
const articles = await apiClient.getShouts({ const options: LoadShoutsOptions = {
filters: { filters: {
visibility: 'public', visibility: 'public',
}, },
order_by: 'rating_stat', order_by: 'rating_stat',
limit: TOP_ARTICLES_COUNT, limit: TOP_ARTICLES_COUNT,
}) }
const articles = await apiClient.getShouts({ options })
addArticles(articles) addArticles(articles)
setTopArticles(articles) setTopArticles(articles)
} }

View File

@ -27,11 +27,8 @@ export const resetSortedLayoutShouts = () => {
} }
export const loadLayoutShoutsBy = async (options: LoadShoutsOptions): Promise<{ hasMore: boolean }> => { export const loadLayoutShoutsBy = async (options: LoadShoutsOptions): Promise<{ hasMore: boolean }> => {
const newLayoutShouts = await apiClient.getShouts({ options.limit += 1
...options, const newLayoutShouts = await apiClient.getShouts({ options })
limit: options.limit + 1,
})
const hasMore = newLayoutShouts.length === options.limit + 1 const hasMore = newLayoutShouts.length === options.limit + 1
if (hasMore) { if (hasMore) {

View File

@ -2,8 +2,7 @@ import { UploadFile } from '@solid-primitives/upload'
import { UploadedFile } from '../pages/types' import { UploadedFile } from '../pages/types'
import { apiBaseUrl } from './config' const apiBaseUrl = 'https://core.discours.io'
const apiUrl = `${apiBaseUrl}/upload` const apiUrl = `${apiBaseUrl}/upload`
export const handleFileUpload = async (uploadFile: UploadFile): Promise<UploadedFile> => { export const handleFileUpload = async (uploadFile: UploadFile): Promise<UploadedFile> => {