async-fixes
This commit is contained in:
parent
238a17a9de
commit
361c916687
10
biome.json
10
biome.json
|
@ -52,11 +52,17 @@
|
|||
"noSvgWithoutTitle": "off"
|
||||
},
|
||||
"nursery": {
|
||||
"useImportRestrictions": "off"
|
||||
"all": true,
|
||||
"useImportRestrictions": "off",
|
||||
"useImportType": "off",
|
||||
"useFilenamingConvention": "off"
|
||||
},
|
||||
"style": {
|
||||
"all": true,
|
||||
"useBlockStatements": "off",
|
||||
"noImplicitBoolean": "off",
|
||||
"useNamingConvention": "off",
|
||||
"noUnusedTemplateLiteral": "off"
|
||||
"noDefaultExport": "off"
|
||||
},
|
||||
"suspicious": {
|
||||
"noConsoleLog": "off",
|
||||
|
|
|
@ -81,8 +81,8 @@ export const FullArticle = (props: Props) => {
|
|||
const canEdit = () => props.article.authors?.some((a) => Boolean(a) && a?.slug === author()?.slug)
|
||||
|
||||
const mainTopic = createMemo(() => {
|
||||
const main_topic_slug = props.article.topics.length > 0 ? props.article.main_topic : null
|
||||
const mt = props.article.topics.find((tpc: Topic) => tpc.slug === main_topic_slug)
|
||||
const mainTopicSlug = props.article.topics.length > 0 ? props.article.main_topic : null
|
||||
const mt = props.article.topics.find((tpc: Topic) => tpc.slug === mainTopicSlug)
|
||||
if (mt) {
|
||||
mt.title = lang() === 'en' ? capitalize(mt.slug.replace(/-/, ' ')) : mt.title
|
||||
return mt
|
||||
|
|
|
@ -52,7 +52,7 @@ export const ShoutRatingControl = (props: ShoutRatingControlProps) => {
|
|||
return deleteReaction(reactionToDelete.id)
|
||||
}
|
||||
|
||||
const handleRatingChange = async (isUpvote: boolean) => {
|
||||
const handleRatingChange = (isUpvote: boolean) => {
|
||||
requireAuthentication(async () => {
|
||||
setIsLoading(true)
|
||||
if (isUpvoted()) {
|
||||
|
|
|
@ -15,7 +15,7 @@ export const AuthGuard = (props: Props) => {
|
|||
const { isAuthenticated, isSessionLoaded } = useSession()
|
||||
const { changeSearchParams } = useRouter<RootSearchParams & AuthModalSearchParams>()
|
||||
|
||||
createEffect(async () => {
|
||||
createEffect(() => {
|
||||
if (props.disabled) {
|
||||
return
|
||||
}
|
||||
|
|
|
@ -51,7 +51,7 @@ export const AuthorBadge = (props: Props) => {
|
|||
const initChat = () => {
|
||||
// eslint-disable-next-line solid/reactivity
|
||||
requireAuthentication(() => {
|
||||
openPage(router, `inbox`)
|
||||
openPage(router, 'inbox')
|
||||
changeSearchParams({
|
||||
initChat: props.author.id.toString(),
|
||||
})
|
||||
|
|
|
@ -2,7 +2,7 @@ import type { Author, Community } from '../../../graphql/schema/core.gen'
|
|||
|
||||
import { openPage, redirectPage } from '@nanostores/router'
|
||||
import { clsx } from 'clsx'
|
||||
import { For, Show, createEffect, createMemo, createSignal, on, onMount } from 'solid-js'
|
||||
import { For, Show, createEffect, createMemo, createSignal, onMount } from 'solid-js'
|
||||
|
||||
import { useFollowing } from '../../../context/following'
|
||||
import { useLocalize } from '../../../context/localize'
|
||||
|
@ -61,7 +61,7 @@ export const AuthorCard = (props: Props) => {
|
|||
const initChat = () => {
|
||||
// eslint-disable-next-line solid/reactivity
|
||||
requireAuthentication(() => {
|
||||
openPage(router, `inbox`)
|
||||
openPage(router, 'inbox')
|
||||
changeSearchParams({
|
||||
initChat: props.author.id.toString(),
|
||||
})
|
||||
|
|
|
@ -89,7 +89,7 @@ export const Footer = () => {
|
|||
},
|
||||
])
|
||||
|
||||
const SOCIAL = [
|
||||
const social = [
|
||||
{
|
||||
name: 'facebook',
|
||||
href: 'https://facebook.com/discoursio',
|
||||
|
@ -146,7 +146,7 @@ export const Footer = () => {
|
|||
<a href="/about/terms-of-use">{t('Terms of use')}</a>
|
||||
</div>
|
||||
<div class={clsx(styles.footerCopyrightSocial, 'col-md-6 col-lg-4')}>
|
||||
<For each={SOCIAL}>
|
||||
<For each={social}>
|
||||
{(social) => (
|
||||
<div class={clsx(styles.socialItem, styles[`socialItem${social.name}`])}>
|
||||
<a href={social.href}>
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import { Buffer } from 'buffer'
|
||||
// biome-ignore lint/nursery/noNodejsModules: TODO: maybe cause problems
|
||||
import { Buffer } from 'node:buffer'
|
||||
|
||||
import { clsx } from 'clsx'
|
||||
import { Show } from 'solid-js'
|
||||
|
|
|
@ -22,12 +22,13 @@ type FloatingMenuProps = {
|
|||
ref: (el: HTMLDivElement) => void
|
||||
}
|
||||
|
||||
const embedData = async (data) => {
|
||||
const embedData = (data) => {
|
||||
const element = document.createRange().createContextualFragment(data)
|
||||
const { attributes } = element.firstChild as HTMLIFrameElement
|
||||
|
||||
const result: { src: string; width?: string; height?: string } = { src: '' }
|
||||
|
||||
// biome-ignore lint/nursery/useForOf: <explanation>
|
||||
for (let i = 0; i < attributes.length; i++) {
|
||||
const attribute = attributes[i]
|
||||
result[attribute.name] = attribute.value
|
||||
|
@ -69,7 +70,7 @@ export const EditorFloatingMenu = (props: FloatingMenuProps) => {
|
|||
.run()
|
||||
}
|
||||
|
||||
const validateEmbed = async (value) => {
|
||||
const validateEmbed = (value) => {
|
||||
const element = document.createRange().createContextualFragment(value)
|
||||
if (element.firstChild?.nodeName !== 'IFRAME') {
|
||||
return t('Error')
|
||||
|
|
|
@ -216,7 +216,7 @@ const SimplifiedEditor = (props: Props) => {
|
|||
}
|
||||
})
|
||||
|
||||
const handleKeyDown = async (event) => {
|
||||
const handleKeyDown = (event) => {
|
||||
if (isEmpty() || !isFocused()) {
|
||||
return
|
||||
}
|
||||
|
|
|
@ -71,7 +71,7 @@ export const TextBubbleMenu = (props: BubbleMenuProps) => {
|
|||
}
|
||||
setListBubbleOpen((prev) => !prev)
|
||||
}
|
||||
const handleKeyDown = async (event) => {
|
||||
const handleKeyDown = (event) => {
|
||||
if (event.code === 'KeyK' && (event.metaKey || event.ctrlKey) && !props.editor.state.selection.empty) {
|
||||
event.preventDefault()
|
||||
setLinkEditorOpen(true)
|
||||
|
|
|
@ -56,7 +56,7 @@ export const UploadModalContent = (props: Props) => {
|
|||
}
|
||||
}
|
||||
|
||||
const handleUpload = async () => {
|
||||
const handleUpload = () => {
|
||||
selectFiles(async ([uploadFile]) => {
|
||||
await runUpload(uploadFile)
|
||||
})
|
||||
|
|
|
@ -57,7 +57,7 @@ export const VideoUploader = (props: Props) => {
|
|||
}
|
||||
}
|
||||
|
||||
const handleUrlInput = async (value: string) => {
|
||||
const handleUrlInput = (value: string) => {
|
||||
setError()
|
||||
if (validateUrl(value)) {
|
||||
props.onVideoAdd(composeMediaItems([{ url: value }]))
|
||||
|
|
|
@ -48,7 +48,7 @@ export const LoginForm = () => {
|
|||
setPassword(newPassword)
|
||||
}
|
||||
|
||||
const handleSendLinkAgainClick = async (event: Event) => {
|
||||
const handleSendLinkAgainClick = (event: Event) => {
|
||||
event.preventDefault()
|
||||
|
||||
setIsLinkSent(true)
|
||||
|
|
|
@ -56,7 +56,7 @@ export const AuthModal = () => {
|
|||
classList={{ [styles.hidden]: mode() !== 'register' && mode() !== 'confirm-email' }}
|
||||
>
|
||||
<div>
|
||||
<h4>{t(`Join the global community of authors!`)}</h4>
|
||||
<h4>{t('Join the global community of authors!')}</h4>
|
||||
<p class={styles.authBenefits}>
|
||||
{t(
|
||||
'Get to know the most intelligent people of our time, edit and discuss the articles, share your expertise, rate and decide what to publish in the magazine',
|
||||
|
|
|
@ -9,7 +9,7 @@ import { useFollowing } from '../../../context/following'
|
|||
import { useLocalize } from '../../../context/localize'
|
||||
import { apiClient } from '../../../graphql/client/core'
|
||||
import { router, useRouter } from '../../../stores/router'
|
||||
import { loadMyFeed, loadShouts, useArticlesStore } from '../../../stores/zine/articles'
|
||||
import { loadShouts, useArticlesStore } from '../../../stores/zine/articles'
|
||||
import { loadAuthor, useAuthorsStore } from '../../../stores/zine/authors'
|
||||
import { getImageUrl } from '../../../utils/getImageUrl'
|
||||
import { getDescription } from '../../../utils/meta'
|
||||
|
@ -61,7 +61,7 @@ export const AuthorView = (props: Props) => {
|
|||
createEffect(() => {
|
||||
if (author()?.id && !author().stat) {
|
||||
const a = loadAuthor({ slug: '', author_id: author().id })
|
||||
console.debug(`[AuthorView] loaded author:`, a)
|
||||
console.debug('[AuthorView] loaded author:', a)
|
||||
}
|
||||
})
|
||||
|
||||
|
@ -128,7 +128,7 @@ export const AuthorView = (props: Props) => {
|
|||
const data = await apiClient.getReactionsBy({
|
||||
by: { comment: false, created_by: commenter.id },
|
||||
})
|
||||
console.debug(`[components.Author] fetched comments`, data)
|
||||
console.debug('[components.Author] fetched comments', data)
|
||||
setCommented(data)
|
||||
}
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@ import { createStore } from 'solid-js/store'
|
|||
|
||||
import { ShoutForm, useEditorContext } from '../../context/editor'
|
||||
import { useLocalize } from '../../context/localize'
|
||||
import { type Shout, type Topic } from '../../graphql/schema/core.gen'
|
||||
import type { Shout, Topic } from '../../graphql/schema/core.gen'
|
||||
import { LayoutType, MediaItem } from '../../pages/types'
|
||||
import { useRouter } from '../../stores/router'
|
||||
import { clone } from '../../utils/clone'
|
||||
|
@ -112,7 +112,7 @@ export const EditView = (props: Props) => {
|
|||
const handleBeforeUnload = (event) => {
|
||||
if (!deepEqual(prevForm, form)) {
|
||||
event.returnValue = t(
|
||||
`There are unsaved changes in your publishing settings. Are you sure you want to leave the page without saving?`,
|
||||
'There are unsaved changes in your publishing settings. Are you sure you want to leave the page without saving?',
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,12 +7,7 @@ import { useLocalize } from '../../../context/localize'
|
|||
import { useReactions } from '../../../context/reactions'
|
||||
import { useSession } from '../../../context/session'
|
||||
import { apiClient } from '../../../graphql/client/core'
|
||||
import {
|
||||
type Author,
|
||||
type LoadShoutsOptions,
|
||||
type Reaction,
|
||||
type Shout,
|
||||
} from '../../../graphql/schema/core.gen'
|
||||
import type { Author, LoadShoutsOptions, Reaction, Shout } from '../../../graphql/schema/core.gen'
|
||||
import { router, useRouter } from '../../../stores/router'
|
||||
import { showModal } from '../../../stores/ui'
|
||||
import { resetSortedArticles, useArticlesStore } from '../../../stores/zine/articles'
|
||||
|
|
|
@ -9,7 +9,6 @@ import { useLocalize } from '../../../context/localize'
|
|||
import { useSession } from '../../../context/session'
|
||||
import { useRouter } from '../../../stores/router'
|
||||
import { showModal } from '../../../stores/ui'
|
||||
import { useAuthorsStore } from '../../../stores/zine/authors'
|
||||
import SimplifiedEditor from '../../Editor/SimplifiedEditor'
|
||||
import DialogCard from '../../Inbox/DialogCard'
|
||||
import DialogHeader from '../../Inbox/DialogHeader'
|
||||
|
@ -83,7 +82,7 @@ export const InboxView = (props: Props) => {
|
|||
}
|
||||
}
|
||||
|
||||
const handleSubmit = async (message: string) => {
|
||||
const handleSubmit = (message: string) => {
|
||||
sendMessage({
|
||||
body: message,
|
||||
chat_id: currentDialog()?.id.toString(),
|
||||
|
|
|
@ -50,7 +50,7 @@ export const SearchView = (props: Props) => {
|
|||
restoreScrollPosition()
|
||||
}
|
||||
|
||||
onMount(async () => {
|
||||
onMount(() => {
|
||||
const q = window.location.pathname.replace('/search/', '') || props.query
|
||||
setQuery(q)
|
||||
searchEl.value = q
|
||||
|
|
|
@ -74,7 +74,7 @@ export const TopicView = (props: Props) => {
|
|||
restoreScrollPosition()
|
||||
}
|
||||
|
||||
onMount(async () => {
|
||||
onMount(() => {
|
||||
if (sortedArticles().length === PRERENDERED_ARTICLES_COUNT) {
|
||||
loadMore()
|
||||
}
|
||||
|
|
|
@ -33,7 +33,7 @@ const GrowingTextarea = (props: Props) => {
|
|||
props.value(textareaValue)
|
||||
}
|
||||
|
||||
const handleKeyDown = async (event) => {
|
||||
const handleKeyDown = (event) => {
|
||||
if (event.key === 'Enter' && event.shiftKey) {
|
||||
return
|
||||
}
|
||||
|
|
|
@ -84,7 +84,7 @@ export const EditorSwiper = (props: Props) => {
|
|||
|
||||
const { selectFiles } = createFileUploader({
|
||||
multiple: true,
|
||||
accept: `image/*`,
|
||||
accept: 'image/*',
|
||||
})
|
||||
|
||||
const initUpload = async (selectedFiles) => {
|
||||
|
|
|
@ -27,6 +27,8 @@ type KebabObjectKeys<T> = {
|
|||
type SwiperRef = HTMLElement & { swiper: Swiper; initialize: () => void }
|
||||
|
||||
declare module 'solid-js' {
|
||||
// biome-ignore lint/style/useNamingConvention: JSX is ok
|
||||
// biome-ignore lint/style/noNamespace: TODO: explain why
|
||||
namespace JSX {
|
||||
interface IntrinsicElements {
|
||||
'swiper-container': SwiperContainerAttributes
|
||||
|
|
|
@ -29,7 +29,7 @@ export interface ConnectContextType {
|
|||
const ConnectContext = createContext<ConnectContextType>()
|
||||
|
||||
export const ConnectProvider = (props: { children: JSX.Element }) => {
|
||||
const [messageHandlers, setHandlers] = createSignal<Array<MessageHandler>>([])
|
||||
const [messageHandlers, setHandlers] = createSignal<MessageHandler[]>([])
|
||||
// const [messages, setMessages] = createSignal<Array<SSEMessage>>([]);
|
||||
const [connected, setConnected] = createSignal(false)
|
||||
const { session } = useSession()
|
||||
|
|
|
@ -13,10 +13,10 @@ type InboxContextType = {
|
|||
chats: Accessor<Chat[]>
|
||||
messages?: Accessor<Message[]>
|
||||
createChat: (members: number[], title: string) => Promise<{ chat: Chat }>
|
||||
loadChats: () => Promise<Array<Chat>>
|
||||
loadRecipients: () => Array<Author>
|
||||
loadMessages: (by: MessagesBy, limit: number, offset: number) => Promise<Array<Message>>
|
||||
getMessages?: (chatId: string) => Promise<Array<Message>>
|
||||
loadChats: () => Promise<Chat[]>
|
||||
loadRecipients: () => Author[]
|
||||
loadMessages: (by: MessagesBy, limit: number, offset: number) => Promise<Message[]>
|
||||
getMessages?: (chatId: string) => Promise<Message[]>
|
||||
sendMessage?: (args: MutationCreate_MessageArgs) => void
|
||||
}
|
||||
|
||||
|
@ -47,7 +47,7 @@ export const InboxProvider = (props: { children: JSX.Element }) => {
|
|||
const { addHandler } = useConnect()
|
||||
addHandler(handleMessage)
|
||||
|
||||
const loadMessages = async (by: MessagesBy, limit = 50, offset = 0): Promise<Array<Message>> => {
|
||||
const loadMessages = async (by: MessagesBy, limit = 50, offset = 0): Promise<Message[]> => {
|
||||
if (inboxClient.private) {
|
||||
const msgs = await inboxClient.loadChatMessages({ by, limit, offset })
|
||||
setMessages((mmm) => [...new Set([...mmm, ...msgs])])
|
||||
|
|
|
@ -58,7 +58,7 @@ export const NotificationsProvider = (props: { children: JSX.Element }) => {
|
|||
setTotalNotificationsCount(total)
|
||||
setUnreadNotificationsCount(unread)
|
||||
setNotificationEntities(newGroupsEntries)
|
||||
console.debug(`[context.notifications] groups updated`, groups)
|
||||
console.debug('[context.notifications] groups updated', groups)
|
||||
return groups
|
||||
}
|
||||
return []
|
||||
|
@ -75,7 +75,7 @@ export const NotificationsProvider = (props: { children: JSX.Element }) => {
|
|||
onMount(() => {
|
||||
addHandler((data: SSEMessage) => {
|
||||
if (data.entity === 'reaction' && isAuthenticated()) {
|
||||
console.info(`[context.notifications] event`, data)
|
||||
console.info('[context.notifications] event', data)
|
||||
loadNotificationsGrouped({ after: after(), limit: Math.max(PAGE_SIZE, loadedNotificationsCount()) })
|
||||
}
|
||||
})
|
||||
|
|
|
@ -38,7 +38,7 @@ export const ProfileFormProvider = (props: { children: JSX.Element }) => {
|
|||
}
|
||||
}
|
||||
|
||||
createEffect(async () => {
|
||||
createEffect(() => {
|
||||
if (author()) {
|
||||
const currentAuthor = author()
|
||||
setForm({
|
||||
|
|
|
@ -5,7 +5,6 @@ import type { Author } from '../graphql/schema/core.gen'
|
|||
import {
|
||||
ApiResponse,
|
||||
AuthToken,
|
||||
AuthorizeResponse,
|
||||
Authorizer,
|
||||
ConfigType,
|
||||
ForgotPasswordInput,
|
||||
|
@ -71,6 +70,7 @@ export type SessionContextType = {
|
|||
authorizer: () => Authorizer
|
||||
}
|
||||
|
||||
// biome-ignore lint/nursery/noEmptyBlockStatements: noop
|
||||
const noop = () => {}
|
||||
|
||||
const SessionContext = createContext<SessionContextType>()
|
||||
|
@ -257,7 +257,7 @@ export const SessionProvider = (props: {
|
|||
),
|
||||
)
|
||||
|
||||
const [authCallback, setAuthCallback] = createSignal<() => void>(() => {})
|
||||
const [authCallback, setAuthCallback] = createSignal<() => void>(noop)
|
||||
const requireAuthentication = (callback: () => void, modalSource: AuthModalSource) => {
|
||||
setAuthCallback((_cb) => callback)
|
||||
if (!session()) {
|
||||
|
@ -285,13 +285,8 @@ export const SessionProvider = (props: {
|
|||
}
|
||||
return { data: resp?.data, errors: resp?.errors }
|
||||
}
|
||||
const signUp = async (params: SignupInput) => {
|
||||
return authenticate(authorizer().signup, params)
|
||||
}
|
||||
|
||||
const signIn = async (params: LoginInput) => {
|
||||
return authenticate(authorizer().login, params)
|
||||
}
|
||||
const signUp = async (params: SignupInput) => await authenticate(authorizer().signup, params)
|
||||
const signIn = async (params: LoginInput) => await authenticate(authorizer().login, params)
|
||||
|
||||
const signOut = async () => {
|
||||
const authResult: ApiResponse<GenericResponse> = await authorizer().logout()
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
import { ROUTES } from '../stores/router'
|
||||
import { getServerRoute } from '../utils/getServerRoute'
|
||||
import { getServerRoute as gsr } from '../utils/getServerRoute'
|
||||
|
||||
export default getServerRoute(ROUTES.drafts)
|
||||
const getServerRoute = () => gsr(ROUTES.drafts)
|
||||
|
||||
export { getServerRoute }
|
||||
|
|
|
@ -6,7 +6,7 @@ import { SearchResult } from '../graphql/schema/core.gen'
|
|||
|
||||
export const onBeforeRender = async (pageContext: PageContext) => {
|
||||
const { q: text } = pageContext.routeParams
|
||||
const searchResults: Array<SearchResult> = await apiClient.getShoutsSearch({ text, limit: 50 })
|
||||
const searchResults: SearchResult[] = await apiClient.getShoutsSearch({ text, limit: 50 })
|
||||
const pageProps: PageProps = { searchResults, seo: { title: '' } }
|
||||
|
||||
return {
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
// /:slug -> /@slug
|
||||
// https://vike.dev/routing
|
||||
// https://www.npmjs.com/package/@nanostores/router
|
||||
export const getServerRoute = (clientRoute: string) => clientRoute.replaceAll(':', '@')
|
||||
import { ROUTES } from '../stores/router'
|
||||
|
||||
export const getServerRoute = (clientRoute: string = ROUTES) => clientRoute.replaceAll(':', '@')
|
||||
|
|
Loading…
Reference in New Issue
Block a user