This commit is contained in:
Untone 2024-01-23 19:32:57 +03:00
parent e88363e450
commit fdc721ebd0
21 changed files with 113 additions and 112 deletions

View File

@ -1,6 +1,7 @@
node_modules node_modules
public public
*.cjs *.cjs
src/graphql/schema/*.gen.ts
dist/ dist/
.vercel/ .vercel/
src/graphql/client/*
src/graphql/schema/*

View File

@ -1,106 +1,108 @@
module.exports = { module.exports = {
plugins: ["@typescript-eslint", "import", "sonarjs", "unicorn", "promise", "solid", "jest"], plugins: ['@typescript-eslint', 'import', 'sonarjs', 'unicorn', 'promise', 'solid', 'jest'],
extends: [ extends: [
"eslint:recommended", 'eslint:recommended',
"plugin:import/recommended", 'plugin:import/recommended',
"plugin:import/typescript", 'plugin:import/typescript',
"prettier", 'prettier',
"plugin:sonarjs/recommended", 'plugin:sonarjs/recommended',
"plugin:unicorn/recommended", 'plugin:unicorn/recommended',
"plugin:promise/recommended", 'plugin:promise/recommended',
"plugin:solid/recommended", 'plugin:solid/recommended',
"plugin:jest/recommended" 'plugin:jest/recommended',
], ],
overrides: [ overrides: [
{ {
files: ["**/*.ts", "**/*.tsx"], files: ['**/*.ts', '**/*.tsx'],
parser: "@typescript-eslint/parser", parser: '@typescript-eslint/parser',
parserOptions: { parserOptions: {
ecmaVersion: 2021, ecmaVersion: 2021,
ecmaFeatures: { jsx: true }, ecmaFeatures: { jsx: true },
sourceType: "module", sourceType: 'module',
project: "./tsconfig.json" project: './tsconfig.json',
}, },
extends: [ extends: [
"plugin:@typescript-eslint/recommended" 'plugin:@typescript-eslint/recommended',
// Maybe one day... // 'plugin:@typescript-eslint/recommended-requiring-type-checking', // 23-01-2024 896 problems
// 'plugin:@typescript-eslint/recommended-requiring-type-checking'
], ],
rules: { rules: {
"@typescript-eslint/no-unused-vars": [ '@typescript-eslint/no-unused-vars': [
"warn", 'warn',
{ {
argsIgnorePattern: "^_" argsIgnorePattern: '^_',
} },
], ],
"@typescript-eslint/no-non-null-assertion": "error", '@typescript-eslint/no-non-null-assertion': 'error',
// TODO: Remove any usage and enable '@typescript-eslint/no-explicit-any': 'warn',
"@typescript-eslint/no-explicit-any": "off" },
} },
}
], ],
env: { env: {
browser: true, browser: true,
node: true, node: true,
mocha: true mocha: true,
}, },
globals: {}, globals: {},
rules: { rules: {
// Solid // Solid
"solid/reactivity": "off", // FIXME 'solid/reactivity': 'off', // too many 'should be used within JSX'
"solid/no-innerhtml": "off", 'solid/no-innerhtml': 'off',
/** Unicorn **/ /** Unicorn **/
"unicorn/no-null": "off", 'unicorn/no-null': 'off',
"unicorn/filename-case": "off", 'unicorn/filename-case': 'off',
"unicorn/no-array-for-each": "off", 'unicorn/no-array-for-each': 'off',
"unicorn/no-array-reduce": "off", 'unicorn/no-array-reduce': 'off',
"unicorn/prefer-string-replace-all": "warn", 'unicorn/prefer-string-replace-all': 'warn',
"unicorn/prevent-abbreviations": "off", 'unicorn/prevent-abbreviations': 'off',
"unicorn/prefer-module": "off", 'unicorn/prefer-module': 'off',
"unicorn/import-style": "off", 'unicorn/import-style': 'off',
"unicorn/numeric-separators-style": "off", 'unicorn/numeric-separators-style': 'off',
"unicorn/prefer-node-protocol": "off", 'unicorn/prefer-node-protocol': 'off',
"unicorn/prefer-dom-node-append": "off", // FIXME 'unicorn/prefer-dom-node-append': 'off', // FIXME
"unicorn/prefer-top-level-await": "warn", 'unicorn/prefer-top-level-await': 'warn',
"unicorn/consistent-function-scoping": "warn", 'unicorn/consistent-function-scoping': 'warn',
"unicorn/no-array-callback-reference": "warn", 'unicorn/no-array-callback-reference': 'warn',
"unicorn/no-array-method-this-argument": "warn", 'unicorn/no-array-method-this-argument': 'warn',
"unicorn/no-for-loop": "off", 'unicorn/no-for-loop': 'off',
"sonarjs/no-duplicate-string": ["warn", { threshold: 5 }], 'sonarjs/no-duplicate-string': ['warn', { threshold: 5 }],
'sonarjs/prefer-immediate-return': 'warn',
// Promise // Promise
// 'promise/catch-or-return': 'off', // Should be enabled 'promise/catch-or-return': 'off',
"promise/always-return": "off", 'promise/always-return': 'off',
eqeqeq: "error", eqeqeq: 'error',
"no-param-reassign": "error", 'no-param-reassign': 'error',
"no-nested-ternary": "error", 'no-nested-ternary': 'error',
"no-shadow": "error", 'no-shadow': 'error',
"import/order": ["warn", { 'import/order': [
groups: ["type", "builtin", "external", "internal", "parent", "sibling", "index"], 'warn',
{
groups: ['type', 'builtin', 'external', 'internal', 'parent', 'sibling', 'index'],
distinctGroup: false, distinctGroup: false,
pathGroups: [ pathGroups: [
{ {
pattern: "*.scss", pattern: '*.scss',
patternOptions: { matchBase: true }, patternOptions: { matchBase: true },
group: "index", group: 'index',
position: "after" position: 'after',
} },
], ],
"newlines-between": "always", 'newlines-between': 'always',
alphabetize: { alphabetize: {
order: "asc", order: 'asc',
caseInsensitive: true caseInsensitive: true,
} },
}] },
],
}, },
settings: { settings: {
"import/resolver": { 'import/resolver': {
typescript: true, typescript: true,
node: true node: true,
},
},
} }
}
};

View File

@ -7,6 +7,8 @@
"stylelint-scss" "stylelint-scss"
], ],
"rules": { "rules": {
"keyframes-name-pattern": null,
"declaration-block-no-redundant-longhand-properties": null,
"selector-class-pattern": null, "selector-class-pattern": null,
"no-descending-specificity": null, "no-descending-specificity": null,
"scss/function-no-unknown": null, "scss/function-no-unknown": null,

View File

@ -300,8 +300,8 @@ export const FullArticle = (props: Props) => {
const originalWidth = iframe.getAttribute('width') || style.width.replace('px', '') const originalWidth = iframe.getAttribute('width') || style.width.replace('px', '')
const originalHeight = iframe.getAttribute('height') || style.height.replace('px', '') const originalHeight = iframe.getAttribute('height') || style.height.replace('px', '')
const width = Number(originalWidth) const width: IframeSize['width'] = Number(originalWidth)
const height = Number(originalHeight) const height: IframeSize['height'] = Number(originalHeight)
if (containerWidth < width) { if (containerWidth < width) {
const aspectRatio = width / height const aspectRatio = width / height

View File

@ -12,11 +12,7 @@ type Props = {
} }
export const AuthGuard = (props: Props) => { export const AuthGuard = (props: Props) => {
const { const { isAuthenticated, isSessionLoaded } = useSession()
isAuthenticated,
isSessionLoaded,
actions: { loadSession },
} = useSession()
const { changeSearchParams } = useRouter<RootSearchParams & AuthModalSearchParams>() const { changeSearchParams } = useRouter<RootSearchParams & AuthModalSearchParams>()
createEffect(async () => { createEffect(async () => {

View File

@ -30,9 +30,7 @@ export const Donate = () => {
const initiated = () => { const initiated = () => {
// eslint-disable-next-line @typescript-eslint/no-explicit-any // eslint-disable-next-line @typescript-eslint/no-explicit-any
const { const CloudPayments = window['cp'] // Checkout(cpOptions)
cp: { CloudPayments },
} = window as any // Checkout(cpOptions)
setWidget(new CloudPayments()) setWidget(new CloudPayments())
console.log('[donate] payments initiated') console.log('[donate] payments initiated')
setCustomerReciept({ setCustomerReciept({

View File

@ -3,7 +3,7 @@ import { Node } from '@tiptap/core'
export interface IframeOptions { export interface IframeOptions {
allowFullscreen: boolean allowFullscreen: boolean
HTMLAttributes: { HTMLAttributes: {
[key: string]: any [key: string]: string | number
} }
} }

View File

@ -16,7 +16,7 @@ export const ToggleTextWrap = Extension.create({
return { return {
addTextWrap: addTextWrap:
(attributes) => (attributes) =>
({ commands, state }) => { ({ commands, state: _s }) => {
return commands.setMark('span', attributes) return commands.setMark('span', attributes)
}, },

View File

@ -1,7 +1,7 @@
import type { PopupProps } from '../../_shared/Popup' import type { PopupProps } from '../../_shared/Popup'
import { clsx } from 'clsx' import { clsx } from 'clsx'
import { createEffect, createSignal, onMount, Show } from 'solid-js' import { createSignal, Show } from 'solid-js'
import { useLocalize } from '../../../context/localize' import { useLocalize } from '../../../context/localize'
import { Popup } from '../../_shared/Popup' import { Popup } from '../../_shared/Popup'

View File

@ -33,10 +33,6 @@
margin-right: 1.2rem; margin-right: 1.2rem;
} }
.userpic {
margin-right: 1.2rem;
}
.selected { .selected {
font-weight: 700; font-weight: 700;
} }

View File

@ -38,12 +38,14 @@
a { a {
border: none !important; border: none !important;
} }
.facebook, .facebook,
.google, .google,
.vk, .vk,
.telegram { .telegram {
border: none; border: none;
} }
.github:hover { .github:hover {
img { img {
filter: invert(1); filter: invert(1);

View File

@ -1,4 +1,4 @@
@mixin searchFilterControl { @mixin search-filter-control {
background: rgb(64 64 64 / 50%); background: rgb(64 64 64 / 50%);
border-radius: 10rem; border-radius: 10rem;
color: #fff; color: #fff;
@ -69,7 +69,7 @@
} }
.topTopic { .topTopic {
@include searchFilterControl; @include search-filter-control;
} }
.filterSwitcher { .filterSwitcher {
@ -99,5 +99,5 @@
} }
.filterResultsControl { .filterResultsControl {
@include searchFilterControl; @include search-filter-control;
} }

View File

@ -93,12 +93,10 @@
align-items: center; align-items: center;
justify-content: center; justify-content: center;
z-index: 10001; z-index: 10001;
font-size: 1.2rem; font-size: 1.2rem;
border-radius: 6px; border-radius: 6px;
background-color: rgb(0 0 0 / 80%); background-color: rgb(0 0 0 / 80%);
color: #fff; color: #fff;
pointer-events: none; pointer-events: none;
} }

View File

@ -87,6 +87,7 @@
&.mobileView { &.mobileView {
.container { .container {
padding: 0; padding: 0;
.thumbs { .thumbs {
& swiper-slide { & swiper-slide {
// bind to html element <swiper-slide/> // bind to html element <swiper-slide/>

View File

@ -6,7 +6,7 @@ import { useLocalize } from '../../../context/localize'
import styles from './TimeAgo.module.scss' import styles from './TimeAgo.module.scss'
type Props = { type Props = {
date: any date: string | number | Date
class?: string class?: string
} }

View File

@ -11,7 +11,8 @@ export interface SSEMessage {
id: string id: string
entity: string // follower | shout | reaction entity: string // follower | shout | reaction
action: string // create | delete | update | join | follow | seen action: string // create | delete | update | join | follow | seen
payload: any // Author | Shout | Reaction | Message // eslint-disable-next-line @typescript-eslint/no-explicit-any
payload: any // Author Shout Message Reaction Chat
created_at?: number // unixtime x1000 created_at?: number // unixtime x1000
seen?: boolean seen?: boolean
} }

View File

@ -43,10 +43,13 @@ export const ReactionsProvider = (props: { children: JSX.Element }) => {
offset?: number offset?: number
}): Promise<Reaction[]> => { }): Promise<Reaction[]> => {
const reactions = await apiClient.getReactionsBy({ by, limit, offset }) const reactions = await apiClient.getReactionsBy({ by, limit, offset })
const newReactionEntities = reactions.reduce((acc, reaction) => { const newReactionEntities = reactions.reduce(
(acc: { [reaction_id: number]: Reaction }, reaction: Reaction) => {
acc[reaction.id] = reaction acc[reaction.id] = reaction
return acc return acc
}, {}) },
{},
)
setReactionEntities(newReactionEntities) setReactionEntities(newReactionEntities)
return reactions return reactions
} }
@ -79,9 +82,9 @@ export const ReactionsProvider = (props: { children: JSX.Element }) => {
} }
const deleteReaction = async (reaction_id: number): Promise<void> => { const deleteReaction = async (reaction_id: number): Promise<void> => {
const _reaction = await apiClient.destroyReaction(reaction_id) const r = await apiClient.destroyReaction(reaction_id)
setReactionEntities({ setReactionEntities({
[reaction_id]: undefined, [r.id]: undefined,
}) })
} }

View File

@ -83,7 +83,7 @@ const EMPTY_SUBSCRIPTIONS = {
} }
export const SessionProvider = (props: { export const SessionProvider = (props: {
onStateChangeCallback(state: any): unknown onStateChangeCallback(state: AuthToken): unknown
children: JSX.Element children: JSX.Element
}) => { }) => {
const { t } = useLocalize() const { t } = useLocalize()

View File

@ -7,8 +7,7 @@ export type PageContext = PageContextBuiltInClientWithClientRouting & {
Page: (pageProps: PageProps) => Component Page: (pageProps: PageProps) => Component
pageProps: PageProps pageProps: PageProps
lng: string lng: string
// FIXME typing cookies: { [key: string]: string | number | undefined } | null
cookies: any
documentProps?: { documentProps?: {
title?: string title?: string
description?: string description?: string

View File

@ -595,7 +595,9 @@ figure {
figure { figure {
figcaption { figcaption {
color: rgb(0 0 0 / 60%); color: rgb(0 0 0 / 60%);
@include font-size(1.2rem); @include font-size(1.2rem);
line-height: 1.5; line-height: 1.5;
} }
} }

View File

@ -1,10 +1,10 @@
const pageLoadManager: { const pageLoadManager: {
promise: Promise<any> promise: Promise<void>
} = { promise: Promise.resolve() } } = { promise: Promise.resolve() }
export const getPageLoadManagerPromise = () => { export const getPageLoadManagerPromise = () => {
return pageLoadManager.promise return pageLoadManager.promise
} }
export const setPageLoadManagerPromise = (promise: Promise<any>) => { export const setPageLoadManagerPromise = (promise: Promise<void>) => {
pageLoadManager.promise = promise pageLoadManager.promise = promise
} }