async-fixes

This commit is contained in:
Untone 2024-02-05 18:04:23 +03:00
parent 238a17a9de
commit 361c916687
32 changed files with 62 additions and 59 deletions

View File

@ -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",

View File

@ -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

View File

@ -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()) {

View File

@ -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
}

View File

@ -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(),
})

View File

@ -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(),
})

View File

@ -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}>

View File

@ -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'

View File

@ -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')

View File

@ -216,7 +216,7 @@ const SimplifiedEditor = (props: Props) => {
}
})
const handleKeyDown = async (event) => {
const handleKeyDown = (event) => {
if (isEmpty() || !isFocused()) {
return
}

View File

@ -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)

View File

@ -56,7 +56,7 @@ export const UploadModalContent = (props: Props) => {
}
}
const handleUpload = async () => {
const handleUpload = () => {
selectFiles(async ([uploadFile]) => {
await runUpload(uploadFile)
})

View File

@ -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 }]))

View File

@ -48,7 +48,7 @@ export const LoginForm = () => {
setPassword(newPassword)
}
const handleSendLinkAgainClick = async (event: Event) => {
const handleSendLinkAgainClick = (event: Event) => {
event.preventDefault()
setIsLinkSent(true)

View File

@ -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',

View File

@ -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)
}

View File

@ -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?',
)
}
}

View File

@ -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'

View File

@ -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(),

View File

@ -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

View File

@ -74,7 +74,7 @@ export const TopicView = (props: Props) => {
restoreScrollPosition()
}
onMount(async () => {
onMount(() => {
if (sortedArticles().length === PRERENDERED_ARTICLES_COUNT) {
loadMore()
}

View File

@ -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
}

View File

@ -84,7 +84,7 @@ export const EditorSwiper = (props: Props) => {
const { selectFiles } = createFileUploader({
multiple: true,
accept: `image/*`,
accept: 'image/*',
})
const initUpload = async (selectedFiles) => {

View File

@ -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

View File

@ -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()

View File

@ -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])])

View File

@ -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()) })
}
})

View File

@ -38,7 +38,7 @@ export const ProfileFormProvider = (props: { children: JSX.Element }) => {
}
}
createEffect(async () => {
createEffect(() => {
if (author()) {
const currentAuthor = author()
setForm({

View File

@ -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()

View File

@ -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 }

View File

@ -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 {

View File

@ -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(':', '@')