diff --git a/app/javascript/flavours/glitch/blurhash.ts b/app/javascript/flavours/glitch/blurhash.ts index dadf2b7f2..cafe7b12d 100644 --- a/app/javascript/flavours/glitch/blurhash.ts +++ b/app/javascript/flavours/glitch/blurhash.ts @@ -86,10 +86,9 @@ const DIGIT_CHARACTERS = [ export const decode83 = (str: string) => { let value = 0; - let c, digit; + let digit; - for (let i = 0; i < str.length; i++) { - c = str[i]; + for (const c of str) { digit = DIGIT_CHARACTERS.indexOf(c); value = value * 83 + digit; } diff --git a/app/javascript/flavours/glitch/components/autosuggest_hashtag.tsx b/app/javascript/flavours/glitch/components/autosuggest_hashtag.tsx index 71955e6b0..6da620014 100644 --- a/app/javascript/flavours/glitch/components/autosuggest_hashtag.tsx +++ b/app/javascript/flavours/glitch/components/autosuggest_hashtag.tsx @@ -6,11 +6,11 @@ interface Props { tag: { name: string; url?: string; - history?: Array<{ + history?: { uses: number; accounts: string; day: string; - }>; + }[]; following?: boolean; type: 'hashtag'; }; diff --git a/app/javascript/flavours/glitch/components/display_name.tsx b/app/javascript/flavours/glitch/components/display_name.tsx index 76c21d00c..a14039432 100644 --- a/app/javascript/flavours/glitch/components/display_name.tsx +++ b/app/javascript/flavours/glitch/components/display_name.tsx @@ -82,7 +82,7 @@ export class DisplayName extends React.PureComponent { } else if (account) { let acct = account.get('acct'); - if (acct.indexOf('@') === -1 && localDomain) { + if (!acct.includes('@') && localDomain) { acct = `${acct}@${localDomain}`; } diff --git a/app/javascript/flavours/glitch/components/short_number.tsx b/app/javascript/flavours/glitch/components/short_number.tsx index 928e371bd..74c3c5d75 100644 --- a/app/javascript/flavours/glitch/components/short_number.tsx +++ b/app/javascript/flavours/glitch/components/short_number.tsx @@ -29,12 +29,12 @@ export const ShortNumberRenderer: React.FC = ({ ); } - const customRenderer = children || renderer || null; + const customRenderer = children ?? renderer ?? null; const displayNumber = ; return ( - customRenderer?.(displayNumber, pluralReady(value, division)) || + customRenderer?.(displayNumber, pluralReady(value, division)) ?? displayNumber ); }; diff --git a/app/javascript/flavours/glitch/features/emoji/emoji_compressed.d.ts b/app/javascript/flavours/glitch/features/emoji/emoji_compressed.d.ts index 2b3375ccc..96e0cc5ea 100644 --- a/app/javascript/flavours/glitch/features/emoji/emoji_compressed.d.ts +++ b/app/javascript/flavours/glitch/features/emoji/emoji_compressed.d.ts @@ -28,9 +28,10 @@ export type SearchData = [ Emoji['unified'], ]; -export interface ShortCodesToEmojiData { - [key: ShortCodesToEmojiDataKey]: [FilenameData, SearchData]; -} +export type ShortCodesToEmojiData = Record< + ShortCodesToEmojiDataKey, + [FilenameData, SearchData] +>; export type EmojisWithoutShortCodes = FilenameData[]; export type EmojiCompressed = [ diff --git a/app/javascript/flavours/glitch/features/emoji/emoji_mart_data_light.ts b/app/javascript/flavours/glitch/features/emoji/emoji_mart_data_light.ts index 62cb84baf..142605b4b 100644 --- a/app/javascript/flavours/glitch/features/emoji/emoji_mart_data_light.ts +++ b/app/javascript/flavours/glitch/features/emoji/emoji_mart_data_light.ts @@ -9,7 +9,7 @@ import emojiCompressed from './emoji_compressed'; import { unicodeToUnifiedName } from './unicode_to_unified_name'; type Emojis = { - [key in keyof ShortCodesToEmojiData]: { + [key in NonNullable]: { native: BaseEmoji['native']; search: Search; short_names: Emoji['short_names']; diff --git a/app/javascript/flavours/glitch/features/home_timeline/components/column_settings.tsx b/app/javascript/flavours/glitch/features/home_timeline/components/column_settings.tsx index 7e6f79a7a..dd873c4ef 100644 --- a/app/javascript/flavours/glitch/features/home_timeline/components/column_settings.tsx +++ b/app/javascript/flavours/glitch/features/home_timeline/components/column_settings.tsx @@ -19,7 +19,7 @@ export const ColumnSettings: React.FC = () => { const dispatch = useAppDispatch(); const onChange = useCallback( (key: string, checked: boolean) => { - void dispatch(changeSetting(['home', ...key], checked)); + dispatch(changeSetting(['home', ...key], checked)); }, [dispatch], ); diff --git a/app/javascript/flavours/glitch/locales/global_locale.ts b/app/javascript/flavours/glitch/locales/global_locale.ts index 01133ca23..2d4329c76 100644 --- a/app/javascript/flavours/glitch/locales/global_locale.ts +++ b/app/javascript/flavours/glitch/locales/global_locale.ts @@ -3,15 +3,19 @@ export interface LocaleData { messages: Record; } -let loadedLocale: LocaleData; +let loadedLocale: LocaleData | undefined; export function setLocale(locale: LocaleData) { loadedLocale = locale; } -export function getLocale() { - if (!loadedLocale && process.env.NODE_ENV === 'development') { - throw new Error('getLocale() called before any locale has been set'); +export function getLocale(): LocaleData { + if (!loadedLocale) { + if (process.env.NODE_ENV === 'development') { + throw new Error('getLocale() called before any locale has been set'); + } else { + return { locale: 'unknown', messages: {} }; + } } return loadedLocale; diff --git a/app/javascript/flavours/glitch/locales/load_locale.ts b/app/javascript/flavours/glitch/locales/load_locale.ts index fa5d13bbc..fb938d4eb 100644 --- a/app/javascript/flavours/glitch/locales/load_locale.ts +++ b/app/javascript/flavours/glitch/locales/load_locale.ts @@ -6,6 +6,7 @@ import { isLocaleLoaded, setLocale } from './global_locale'; const localeLoadingSemaphore = new Semaphore(1); export async function loadLocale() { + // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing -- we want to match empty strings const locale = document.querySelector('html')?.lang || 'en'; // We use a Semaphore here so only one thing can try to load the locales at diff --git a/app/javascript/flavours/glitch/polyfills/base_polyfills.ts b/app/javascript/flavours/glitch/polyfills/base_polyfills.ts index c35ba0d38..71565236c 100644 --- a/app/javascript/flavours/glitch/polyfills/base_polyfills.ts +++ b/app/javascript/flavours/glitch/polyfills/base_polyfills.ts @@ -4,7 +4,7 @@ import 'core-js/features/symbol'; import 'core-js/features/promise/finally'; import { decode as decodeBase64 } from '../utils/base64'; -if (!HTMLCanvasElement.prototype.toBlob) { +if (!Object.hasOwn(HTMLCanvasElement.prototype, 'toBlob')) { const BASE64_MARKER = ';base64,'; Object.defineProperty(HTMLCanvasElement.prototype, 'toBlob', { @@ -17,7 +17,7 @@ if (!HTMLCanvasElement.prototype.toBlob) { const dataURL: string = this.toDataURL(type, quality); let data; - if (dataURL.indexOf(BASE64_MARKER) >= 0) { + if (dataURL.includes(BASE64_MARKER)) { const [, base64] = dataURL.split(BASE64_MARKER); data = decodeBase64(base64); } else { diff --git a/app/javascript/flavours/glitch/polyfills/index.ts b/app/javascript/flavours/glitch/polyfills/index.ts index b2dbfdac0..e166c09d0 100644 --- a/app/javascript/flavours/glitch/polyfills/index.ts +++ b/app/javascript/flavours/glitch/polyfills/index.ts @@ -24,6 +24,7 @@ export function loadPolyfills() { // Latest version of Firefox and Safari do not have IntersectionObserver. // Edge does not have requestIdleCallback. // This avoids shipping them all the polyfills. + /* eslint-disable @typescript-eslint/no-unnecessary-condition -- those properties might not exist in old browsers, even if they are always here in types */ const needsExtraPolyfills = !( window.AbortController && window.IntersectionObserver && @@ -31,6 +32,7 @@ export function loadPolyfills() { 'isIntersecting' in IntersectionObserverEntry.prototype && window.requestIdleCallback ); + /* eslint-enable @typescript-eslint/no-unnecessary-condition */ return Promise.all([ loadIntlPolyfills(), diff --git a/app/javascript/flavours/glitch/polyfills/intl.ts b/app/javascript/flavours/glitch/polyfills/intl.ts index 4d5ee3ccf..b825da662 100644 --- a/app/javascript/flavours/glitch/polyfills/intl.ts +++ b/app/javascript/flavours/glitch/polyfills/intl.ts @@ -80,6 +80,7 @@ async function loadIntlPluralRulesPolyfills(locale: string) { // } export async function loadIntlPolyfills() { + // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing -- we want to match empty strings const locale = document.querySelector('html')?.lang || 'en'; // order is important here diff --git a/app/javascript/flavours/glitch/scroll.ts b/app/javascript/flavours/glitch/scroll.ts index 4188f6475..35e13a452 100644 --- a/app/javascript/flavours/glitch/scroll.ts +++ b/app/javascript/flavours/glitch/scroll.ts @@ -38,11 +38,13 @@ const scroll = ( const isScrollBehaviorSupported = 'scrollBehavior' in document.documentElement.style; -export const scrollRight = (node: Element, position: number) => - isScrollBehaviorSupported - ? node.scrollTo({ left: position, behavior: 'smooth' }) - : scroll(node, 'scrollLeft', position); -export const scrollTop = (node: Element) => - isScrollBehaviorSupported - ? node.scrollTo({ top: 0, behavior: 'smooth' }) - : scroll(node, 'scrollTop', 0); +export const scrollRight = (node: Element, position: number) => { + if (isScrollBehaviorSupported) + node.scrollTo({ left: position, behavior: 'smooth' }); + else scroll(node, 'scrollLeft', position); +}; + +export const scrollTop = (node: Element) => { + if (isScrollBehaviorSupported) node.scrollTo({ top: 0, behavior: 'smooth' }); + else scroll(node, 'scrollTop', 0); +}; diff --git a/app/javascript/flavours/glitch/store/middlewares/loading_bar.ts b/app/javascript/flavours/glitch/store/middlewares/loading_bar.ts index 03217b382..379b3758a 100644 --- a/app/javascript/flavours/glitch/store/middlewares/loading_bar.ts +++ b/app/javascript/flavours/glitch/store/middlewares/loading_bar.ts @@ -16,7 +16,7 @@ const defaultTypeSuffixes: Config['promiseTypeSuffixes'] = [ export const loadingBarMiddleware = ( config: Config = {}, ): Middleware, RootState> => { - const promiseTypeSuffixes = config.promiseTypeSuffixes || defaultTypeSuffixes; + const promiseTypeSuffixes = config.promiseTypeSuffixes ?? defaultTypeSuffixes; return ({ dispatch }) => (next) => @@ -32,7 +32,7 @@ export const loadingBarMiddleware = ( if (action.type.match(isPending)) { dispatch(showLoading()); } else if ( - action.type.match(isFulfilled) || + action.type.match(isFulfilled) ?? action.type.match(isRejected) ) { dispatch(hideLoading()); diff --git a/app/javascript/flavours/glitch/store/middlewares/sounds.ts b/app/javascript/flavours/glitch/store/middlewares/sounds.ts index f7a07149d..48a5762d6 100644 --- a/app/javascript/flavours/glitch/store/middlewares/sounds.ts +++ b/app/javascript/flavours/glitch/store/middlewares/sounds.ts @@ -38,7 +38,7 @@ export const soundsMiddleware = (): Middleware< Record, RootState > => { - const soundCache: { [key: string]: HTMLAudioElement } = {}; + const soundCache: Record = {}; void ready(() => { soundCache.boop = createAudio([ @@ -56,9 +56,9 @@ export const soundsMiddleware = (): Middleware< return () => (next) => (action: AnyAction & { meta?: { sound?: string } }) => { - const sound = action?.meta?.sound; + const sound = action.meta?.sound; - if (sound && soundCache[sound]) { + if (sound && Object.hasOwn(soundCache, sound)) { play(soundCache[sound]); } diff --git a/app/javascript/flavours/glitch/utils/filters.ts b/app/javascript/flavours/glitch/utils/filters.ts index e5c6422e0..d299e80c4 100644 --- a/app/javascript/flavours/glitch/utils/filters.ts +++ b/app/javascript/flavours/glitch/utils/filters.ts @@ -7,7 +7,7 @@ export const toServerSideType = (columnType: string) => { case 'account': return columnType; default: - if (columnType.indexOf('list:') > -1) { + if (columnType.includes('list:')) { return 'home'; } else { return 'public'; // community, account, hashtag diff --git a/app/javascript/flavours/glitch/utils/numbers.ts b/app/javascript/flavours/glitch/utils/numbers.ts index d2c729db7..7139bf803 100644 --- a/app/javascript/flavours/glitch/utils/numbers.ts +++ b/app/javascript/flavours/glitch/utils/numbers.ts @@ -55,7 +55,7 @@ export function toShortNumber(sourceNumber: number): ShortNumber { */ export function pluralReady( sourceNumber: number, - division: DecimalUnits, + division: DecimalUnits | null, ): number { if (division == null || division < DECIMAL_UNITS.HUNDRED) { return sourceNumber; diff --git a/app/javascript/flavours/glitch/uuid.ts b/app/javascript/flavours/glitch/uuid.ts index 0b4d55beb..4d0a8a803 100644 --- a/app/javascript/flavours/glitch/uuid.ts +++ b/app/javascript/flavours/glitch/uuid.ts @@ -4,6 +4,5 @@ export function uuid(a?: string): string { (a as unknown as number) ^ ((Math.random() * 16) >> ((a as unknown as number) / 4)) ).toString(16) - : // eslint-disable-next-line @typescript-eslint/restrict-plus-operands - ('' + 1e7 + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, uuid); + : ('' + 1e7 + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, uuid); }