Enforce node: schema for builtins, import extensions

This commit is contained in:
Fedor Indutny
2025-09-16 17:39:03 -07:00
committed by GitHub
parent cc6b8795b8
commit c02565eaa8
2096 changed files with 14955 additions and 14023 deletions
+4 -4
View File
@@ -3,10 +3,10 @@
import React, { useMemo } from 'react';
import { VisuallyHidden } from 'react-aria';
import { Button } from 'react-aria-components';
import type { LocalizerType } from '../../types/I18N';
import { type EmojiVariantKey, getEmojiVariantByKey } from './data/emojis';
import { FunStaticEmoji } from './FunEmoji';
import { useFunEmojiLocalizer } from './useFunEmojiLocalizer';
import type { LocalizerType } from '../../types/I18N.js';
import { type EmojiVariantKey, getEmojiVariantByKey } from './data/emojis.js';
import { FunStaticEmoji } from './FunEmoji.js';
import { useFunEmojiLocalizer } from './useFunEmojiLocalizer.js';
/**
* Fun Picker Button
+4 -4
View File
@@ -3,16 +3,16 @@
import { useVirtualizer } from '@tanstack/react-virtual';
import { chunk } from 'lodash';
import React, { useCallback, useEffect, useRef } from 'react';
import { type ComponentMeta } from '../../storybook/types';
import type { FunStaticEmojiProps } from './FunEmoji';
import { FunInlineEmoji, FunStaticEmoji } from './FunEmoji';
import { type ComponentMeta } from '../../storybook/types.js';
import type { FunStaticEmojiProps } from './FunEmoji.js';
import { FunInlineEmoji, FunStaticEmoji } from './FunEmoji.js';
import {
_getAllEmojiVariantKeys,
emojiVariantConstant,
getEmojiParentByKey,
getEmojiParentKeyByVariantKey,
getEmojiVariantByKey,
} from './data/emojis';
} from './data/emojis.js';
export default {
title: 'Components/Fun/FunEmoji',
+2 -2
View File
@@ -3,8 +3,8 @@
import classNames from 'classnames';
import type { CSSProperties } from 'react';
import React, { useMemo } from 'react';
import type { EmojiVariantData } from './data/emojis';
import type { FunImageAriaProps } from './types';
import type { EmojiVariantData } from './data/emojis.js';
import type { FunImageAriaProps } from './types.js';
export const FUN_STATIC_EMOJI_CLASS = 'FunStaticEmoji';
export const FUN_INLINE_EMOJI_CLASS = 'FunInlineEmoji';
@@ -9,25 +9,25 @@ import React, {
useMemo,
useState,
} from 'react';
import type { LocaleEmojiListType } from '../../types/emoji';
import { createLogger } from '../../logging/log';
import * as Errors from '../../types/errors';
import { drop } from '../../util/drop';
import type { LocaleEmojiListType } from '../../types/emoji.js';
import { createLogger } from '../../logging/log.js';
import * as Errors from '../../types/errors.js';
import { drop } from '../../util/drop.js';
import {
getEmojiDefaultEnglishLocalizerIndex,
getEmojiDefaultEnglishSearchIndex,
} from './data/emojis';
} from './data/emojis.js';
import {
createFunEmojiLocalizerIndex,
type FunEmojiLocalizerIndex,
} from './useFunEmojiLocalizer';
} from './useFunEmojiLocalizer.js';
import {
createFunEmojiSearchIndex,
type FunEmojiSearchIndex,
} from './useFunEmojiSearch';
import type { LocalizerType } from '../../types/I18N';
import { strictAssert } from '../../util/assert';
import { isTestOrMockEnvironment } from '../../environment';
} from './useFunEmojiSearch.js';
import type { LocalizerType } from '../../types/I18N.js';
import { strictAssert } from '../../util/assert.js';
import { isTestOrMockEnvironment } from '../../environment.js';
const log = createLogger('FunEmojiLocalizationProvider');
+8 -8
View File
@@ -3,14 +3,14 @@
import React, { useCallback, useState } from 'react';
import { Button } from 'react-aria-components';
import { action } from '@storybook/addon-actions';
import { type ComponentMeta } from '../../storybook/types';
import type { FunEmojiPickerProps } from './FunEmojiPicker';
import { FunEmojiPicker } from './FunEmojiPicker';
import { MOCK_RECENT_EMOJIS, MOCK_THIS_MESSAGE_EMOJIS } from './mocks';
import { FunProvider } from './FunProvider';
import { packs, recentStickers } from '../stickers/mocks';
import { EmojiSkinTone } from './data/emojis';
import { Select } from '../Select';
import { type ComponentMeta } from '../../storybook/types.js';
import type { FunEmojiPickerProps } from './FunEmojiPicker.js';
import { FunEmojiPicker } from './FunEmojiPicker.js';
import { MOCK_RECENT_EMOJIS, MOCK_THIS_MESSAGE_EMOJIS } from './mocks.js';
import { FunProvider } from './FunProvider.js';
import { packs, recentStickers } from '../stickers/mocks.js';
import { EmojiSkinTone } from './data/emojis.js';
import { Select } from '../Select.js';
const { i18n } = window.SignalContext;
+7 -7
View File
@@ -4,13 +4,13 @@ import type { ReactNode } from 'react';
import React, { memo, useCallback } from 'react';
import type { Placement } from 'react-aria';
import { DialogTrigger } from 'react-aria-components';
import { FunPopover } from './base/FunPopover';
import type { FunEmojiSelection } from './panels/FunPanelEmojis';
import { FunPanelEmojis } from './panels/FunPanelEmojis';
import { useFunContext } from './FunProvider';
import type { ThemeType } from '../../types/Util';
import { FunErrorBoundary } from './base/FunErrorBoundary';
import type { EmojiVariantKey } from './data/emojis';
import { FunPopover } from './base/FunPopover.js';
import type { FunEmojiSelection } from './panels/FunPanelEmojis.js';
import { FunPanelEmojis } from './panels/FunPanelEmojis.js';
import { useFunContext } from './FunProvider.js';
import type { ThemeType } from '../../types/Util.js';
import { FunErrorBoundary } from './base/FunErrorBoundary.js';
import type { EmojiVariantKey } from './data/emojis.js';
export type FunEmojiPickerProps = Readonly<{
open: boolean;
+2 -2
View File
@@ -3,8 +3,8 @@
import React, { useEffect, useState, useId } from 'react';
import type { Meta } from '@storybook/react';
import { VisuallyHidden } from 'react-aria';
import { FunGif, FunGifPreview } from './FunGif';
import { LoadingState } from '../../util/loadable';
import { FunGif, FunGifPreview } from './FunGif.js';
import { LoadingState } from '../../util/loadable.js';
export default {
title: 'Components/Fun/FunGif',
+8 -8
View File
@@ -3,14 +3,14 @@
import type { CSSProperties, ForwardedRef } from 'react';
import React, { forwardRef, useEffect, useRef, useState } from 'react';
import { useReducedMotion } from '@react-spring/web';
import { SpinnerV2 } from '../SpinnerV2';
import { strictAssert } from '../../util/assert';
import type { Loadable } from '../../util/loadable';
import { LoadingState } from '../../util/loadable';
import { useIntent } from './base/FunImage';
import { createLogger } from '../../logging/log';
import * as Errors from '../../types/errors';
import { isAbortError } from '../../util/isAbortError';
import { SpinnerV2 } from '../SpinnerV2.js';
import { strictAssert } from '../../util/assert.js';
import type { Loadable } from '../../util/loadable.js';
import { LoadingState } from '../../util/loadable.js';
import { useIntent } from './base/FunImage.js';
import { createLogger } from '../../logging/log.js';
import * as Errors from '../../types/errors.js';
import { isAbortError } from '../../util/isAbortError.js';
const log = createLogger('FunGif');
+7 -7
View File
@@ -3,13 +3,13 @@
import React, { useCallback, useState } from 'react';
import { Button } from 'react-aria-components';
import { action } from '@storybook/addon-actions';
import { type ComponentMeta } from '../../storybook/types';
import { packs, recentStickers } from '../stickers/mocks';
import type { FunPickerProps } from './FunPicker';
import { FunPicker } from './FunPicker';
import { FunProvider } from './FunProvider';
import { MOCK_GIFS_PAGINATED_ONE_PAGE, MOCK_RECENT_EMOJIS } from './mocks';
import { EmojiSkinTone } from './data/emojis';
import { type ComponentMeta } from '../../storybook/types.js';
import { packs, recentStickers } from '../stickers/mocks.js';
import type { FunPickerProps } from './FunPicker.js';
import { FunPicker } from './FunPicker.js';
import { FunProvider } from './FunProvider.js';
import { MOCK_GIFS_PAGINATED_ONE_PAGE, MOCK_RECENT_EMOJIS } from './mocks.js';
import { EmojiSkinTone } from './data/emojis.js';
const { i18n } = window.SignalContext;
+17 -12
View File
@@ -5,18 +5,23 @@ import React, { memo, useCallback, useEffect } from 'react';
import type { Placement } from 'react-aria';
import { DialogTrigger } from 'react-aria-components';
import { createKeybindingsHandler } from 'tinykeys';
import { FunPickerTabKey } from './constants';
import { FunPopover } from './base/FunPopover';
import { FunPickerTab, FunTabList, FunTabPanel, FunTabs } from './base/FunTabs';
import type { FunEmojiSelection } from './panels/FunPanelEmojis';
import { FunPanelEmojis } from './panels/FunPanelEmojis';
import type { FunGifSelection } from './panels/FunPanelGifs';
import { FunPanelGifs } from './panels/FunPanelGifs';
import type { FunStickerSelection } from './panels/FunPanelStickers';
import { FunPanelStickers } from './panels/FunPanelStickers';
import { useFunContext } from './FunProvider';
import type { ThemeType } from '../../types/Util';
import { FunErrorBoundary } from './base/FunErrorBoundary';
import { FunPickerTabKey } from './constants.js';
import { FunPopover } from './base/FunPopover.js';
import {
FunPickerTab,
FunTabList,
FunTabPanel,
FunTabs,
} from './base/FunTabs.js';
import type { FunEmojiSelection } from './panels/FunPanelEmojis.js';
import { FunPanelEmojis } from './panels/FunPanelEmojis.js';
import type { FunGifSelection } from './panels/FunPanelGifs.js';
import { FunPanelGifs } from './panels/FunPanelGifs.js';
import type { FunStickerSelection } from './panels/FunPanelStickers.js';
import { FunPanelStickers } from './panels/FunPanelStickers.js';
import { useFunContext } from './FunProvider.js';
import type { ThemeType } from '../../types/Util.js';
import { FunErrorBoundary } from './base/FunErrorBoundary.js';
/**
* FunPicker
+14 -12
View File
@@ -7,18 +7,20 @@ import React, {
useContext,
useState,
} from 'react';
import { strictAssert } from '../../util/assert';
import type { LocalizerType } from '../../types/I18N';
import type { StickerPackType, StickerType } from '../../state/ducks/stickers';
import type { EmojiSkinTone } from './data/emojis';
import { type EmojiParentKey } from './data/emojis';
import type { FunGifSelection, GifType } from './panels/FunPanelGifs';
import { FunPickerTabKey } from './constants';
import type { fetchGifsFeatured, fetchGifsSearch } from './data/gifs';
import type { tenorDownload } from './data/tenor';
import type { FunEmojiSelection } from './panels/FunPanelEmojis';
import type { FunStickerSelection } from './panels/FunPanelStickers';
import { FunEmojiLocalizationProvider } from './FunEmojiLocalizationProvider';
import { strictAssert } from '../../util/assert.js';
import type { LocalizerType } from '../../types/I18N.js';
import type {
StickerPackType,
StickerType,
} from '../../state/ducks/stickers.js';
import type { EmojiSkinTone, EmojiParentKey } from './data/emojis.js';
import type { FunGifSelection, GifType } from './panels/FunPanelGifs.js';
import { FunPickerTabKey } from './constants.js';
import type { fetchGifsFeatured, fetchGifsSearch } from './data/gifs.js';
import type { tenorDownload } from './data/tenor.js';
import type { FunEmojiSelection } from './panels/FunPanelEmojis.js';
import type { FunStickerSelection } from './panels/FunPanelStickers.js';
import { FunEmojiLocalizationProvider } from './FunEmojiLocalizationProvider.js';
export type FunContextSmartProps = Readonly<{
i18n: LocalizerType;
+5 -5
View File
@@ -3,14 +3,14 @@
import React, { useCallback, useMemo } from 'react';
import type { Selection } from 'react-aria-components';
import { ListBox, ListBoxItem } from 'react-aria-components';
import type { EmojiParentKey } from './data/emojis';
import type { EmojiParentKey } from './data/emojis.js';
import {
EmojiSkinTone,
getEmojiVariantByParentKeyAndSkinTone,
} from './data/emojis';
import { strictAssert } from '../../util/assert';
import { FunStaticEmoji } from './FunEmoji';
import type { LocalizerType } from '../../types/I18N';
} from './data/emojis.js';
import { strictAssert } from '../../util/assert.js';
import { FunStaticEmoji } from './FunEmoji.js';
import type { LocalizerType } from '../../types/I18N.js';
export type FunSkinTonesListProps = Readonly<{
i18n: LocalizerType;
+1 -1
View File
@@ -2,7 +2,7 @@
// SPDX-License-Identifier: AGPL-3.0-only
import React from 'react';
import type { Meta } from '@storybook/react';
import { FunSticker, type FunStickerProps } from './FunSticker';
import { FunSticker, type FunStickerProps } from './FunSticker.js';
export default {
title: 'Components/Fun/FunSticker',
+2 -2
View File
@@ -1,8 +1,8 @@
// Copyright 2024 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import React from 'react';
import { FunImage } from './base/FunImage';
import type { FunImageAriaProps } from './types';
import { FunImage } from './base/FunImage.js';
import type { FunImageAriaProps } from './types.js';
export type FunStickerProps = FunImageAriaProps &
Readonly<{
@@ -4,14 +4,14 @@ import React, { useCallback, useState } from 'react';
import { Button } from 'react-aria-components';
import { action } from '@storybook/addon-actions';
import enMessages from '../../../_locales/en/messages.json';
import { type ComponentMeta } from '../../storybook/types';
import { setupI18n } from '../../util/setupI18n';
import type { FunStickerPickerProps } from './FunStickerPicker';
import { FunStickerPicker } from './FunStickerPicker';
import { MOCK_RECENT_EMOJIS } from './mocks';
import { FunProvider } from './FunProvider';
import { packs, recentStickers } from '../stickers/mocks';
import { EmojiSkinTone } from './data/emojis';
import { type ComponentMeta } from '../../storybook/types.js';
import { setupI18n } from '../../util/setupI18n.js';
import type { FunStickerPickerProps } from './FunStickerPicker.js';
import { FunStickerPicker } from './FunStickerPicker.js';
import { MOCK_RECENT_EMOJIS } from './mocks.js';
import { FunProvider } from './FunProvider.js';
import { packs, recentStickers } from '../stickers/mocks.js';
import { EmojiSkinTone } from './data/emojis.js';
const i18n = setupI18n('en', enMessages);
+7 -7
View File
@@ -4,13 +4,13 @@ import type { ReactNode } from 'react';
import React, { memo, useCallback } from 'react';
import type { Placement } from 'react-aria';
import { DialogTrigger } from 'react-aria-components';
import { FunPopover } from './base/FunPopover';
import type { FunStickerSelection } from './panels/FunPanelStickers';
import { FunPanelStickers } from './panels/FunPanelStickers';
import { useFunContext } from './FunProvider';
import type { ThemeType } from '../../types/Util';
import { FunErrorBoundary } from './base/FunErrorBoundary';
import type { FunTimeStickerStyle } from './constants';
import { FunPopover } from './base/FunPopover.js';
import type { FunStickerSelection } from './panels/FunPanelStickers.js';
import { FunPanelStickers } from './panels/FunPanelStickers.js';
import { useFunContext } from './FunProvider.js';
import type { ThemeType } from '../../types/Util.js';
import { FunErrorBoundary } from './base/FunErrorBoundary.js';
import type { FunTimeStickerStyle } from './constants.js';
export type FunStickerPickerProps = Readonly<{
open: boolean;
+4 -4
View File
@@ -2,10 +2,10 @@
// SPDX-License-Identifier: AGPL-3.0-only
import type { ReactNode, ErrorInfo } from 'react';
import React, { Component, useCallback } from 'react';
import { createLogger } from '../../../logging/log';
import * as Errors from '../../../types/errors';
import { ToastType } from '../../../types/Toast';
import { isProduction } from '../../../util/version';
import { createLogger } from '../../../logging/log.js';
import * as Errors from '../../../types/errors.js';
import { ToastType } from '../../../types/Toast.js';
import { isProduction } from '../../../util/version.js';
const log = createLogger('FunErrorBoundary');
+1 -1
View File
@@ -5,7 +5,7 @@ import React from 'react';
import { FocusScope } from 'react-aria';
import classNames from 'classnames';
import { Button, Dialog, Header, Popover } from 'react-aria-components';
import { FunScrollerSection } from './FunScroller';
import { FunScrollerSection } from './FunScroller.js';
/**
* Grid Container
+3 -3
View File
@@ -4,9 +4,9 @@ import type { ForwardedRef, RefObject } from 'react';
import React, { useRef, useEffect, useState, forwardRef } from 'react';
import classNames from 'classnames';
import { isFocusable } from '@react-aria/focus';
import { strictAssert } from '../../../util/assert';
import { useReducedMotion } from '../../../hooks/useReducedMotion';
import type { FunImageAriaProps } from '../types';
import { strictAssert } from '../../../util/assert.js';
import { useReducedMotion } from '../../../hooks/useReducedMotion.js';
import type { FunImageAriaProps } from '../types.js';
export type FunImageProps = FunImageAriaProps &
Readonly<{
+1 -1
View File
@@ -8,7 +8,7 @@ import type {
} from 'react';
import React, { forwardRef, useCallback, useEffect, useMemo } from 'react';
import { mergeProps } from '@react-aria/utils';
import { strictAssert } from '../../../util/assert';
import { strictAssert } from '../../../util/assert.js';
/**
* Button
+1 -1
View File
@@ -3,7 +3,7 @@
import type { ReactNode, RefObject } from 'react';
import React, { createContext, useContext, useEffect, useState } from 'react';
import { createPortal } from 'react-dom';
import { strictAssert } from '../../../util/assert';
import { strictAssert } from '../../../util/assert.js';
/**
* Tracks the current `data-key` that has a long-press/long-focus
+1 -1
View File
@@ -6,7 +6,7 @@ import type { Placement } from 'react-aria';
import { Dialog, Popover } from 'react-aria-components';
import classNames from 'classnames';
import * as Tooltip from '@radix-ui/react-tooltip';
import { ThemeType } from '../../../types/Util';
import { ThemeType } from '../../../types/Util.js';
export type FunPopoverProps = Readonly<{
placement?: Placement;
+1 -1
View File
@@ -3,7 +3,7 @@
import type { ReactNode } from 'react';
import React from 'react';
import { Button, Header } from 'react-aria-components';
import { SpinnerV2 } from '../../SpinnerV2';
import { SpinnerV2 } from '../../SpinnerV2.js';
export type FunResultsProps = Readonly<{
'aria-busy': boolean;
+2 -2
View File
@@ -18,8 +18,8 @@ import {
isScrollAtTop,
isScrollOverflowVertical,
useScrollObserver,
} from '../../../hooks/useSizeObserver';
import { strictAssert } from '../../../util/assert';
} from '../../../hooks/useSizeObserver.js';
import { strictAssert } from '../../../util/assert.js';
export type FunScrollerProps = Readonly<{
sectionGap: number;
+2 -2
View File
@@ -4,8 +4,8 @@ import type { ChangeEvent } from 'react';
import React, { useCallback } from 'react';
import { VisuallyHidden } from 'react-aria';
import { getInteractionModality } from '@react-aria/interactions';
import type { LocalizerType } from '../../../types/I18N';
import { useFunContext } from '../FunProvider';
import type { LocalizerType } from '../../../types/I18N.js';
import { useFunContext } from '../FunProvider.js';
export type FunSearchProps = Readonly<{
i18n: LocalizerType;
+6 -6
View File
@@ -21,12 +21,12 @@ import {
getScrollLeftDistance,
getScrollRightDistance,
useScrollObserver,
} from '../../../hooks/useSizeObserver';
import { createLogger } from '../../../logging/log';
import * as Errors from '../../../types/errors';
import { strictAssert } from '../../../util/assert';
import { FunImage } from './FunImage';
import { FunTooltip } from './FunTooltip';
} from '../../../hooks/useSizeObserver.js';
import { createLogger } from '../../../logging/log.js';
import * as Errors from '../../../types/errors.js';
import { strictAssert } from '../../../util/assert.js';
import { FunImage } from './FunImage.js';
import { FunTooltip } from './FunTooltip.js';
const log = createLogger('FunSubNav');
+1 -1
View File
@@ -6,7 +6,7 @@ import type { ReactNode } from 'react';
import React, { useCallback, useId } from 'react';
import type { Key } from 'react-aria';
import { Tab, TabList, TabPanel, Tabs } from 'react-aria-components';
import type { FunPickerTabKey } from '../constants';
import type { FunPickerTabKey } from '../constants.js';
export type FunTabsProps = Readonly<{
value: FunPickerTabKey;
+1 -1
View File
@@ -4,7 +4,7 @@
import React, { useRef, useState, type ReactNode } from 'react';
import * as Tooltip from '@radix-ui/react-tooltip';
import { useLayoutEffect } from '@react-aria/utils';
import { strictAssert } from '../../../util/assert';
import { strictAssert } from '../../../util/assert.js';
export type FunTooltipProps = Readonly<{
open?: boolean;
+2 -2
View File
@@ -1,8 +1,8 @@
// Copyright 2025 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import { EmojiPickerCategory } from './data/emojis';
import type { StickerPackType } from '../../state/ducks/stickers';
import { EmojiPickerCategory } from './data/emojis.js';
import type { StickerPackType } from '../../state/ducks/stickers.js';
export enum FunPickerTabKey {
Emoji = 'Emoji',
+5 -5
View File
@@ -2,14 +2,14 @@
// SPDX-License-Identifier: AGPL-3.0-only
import { z } from 'zod';
import emojiRegex from 'emoji-regex';
import { strictAssert } from '../../../util/assert';
import { parseUnknown } from '../../../util/schemas';
import { strictAssert } from '../../../util/assert.js';
import { parseUnknown } from '../../../util/schemas.js';
import type {
FunEmojiSearchIndex,
FunEmojiSearchIndexEntry,
} from '../useFunEmojiSearch';
import type { FunEmojiLocalizerIndex } from '../useFunEmojiLocalizer';
import { removeDiacritics } from '../../../util/removeDiacritics';
} from '../useFunEmojiSearch.js';
import type { FunEmojiLocalizerIndex } from '../useFunEmojiLocalizer.js';
import { removeDiacritics } from '../../../util/removeDiacritics.js';
// Import emoji-datasource dynamically to avoid costly typechecking.
// eslint-disable-next-line import/no-dynamic-require, @typescript-eslint/no-var-requires
+4 -4
View File
@@ -1,14 +1,14 @@
// Copyright 2025 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import { strictAssert } from '../../../util/assert';
import type { GifType } from '../panels/FunPanelGifs';
import { strictAssert } from '../../../util/assert.js';
import type { GifType } from '../panels/FunPanelGifs.js';
import type {
TenorContentFormat,
TenorNextCursor,
TenorResponseResult,
} from './tenor';
import { tenor, isTenorTailCursor } from './tenor';
} from './tenor.js';
import { tenor, isTenorTailCursor } from './tenor.js';
const PREVIEW_CONTENT_FORMAT: TenorContentFormat = 'tinymp4';
const ATTACHMENT_CONTENT_FORMAT: TenorContentFormat = 'mp4';
+4 -4
View File
@@ -1,10 +1,10 @@
// Copyright 2025 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import { useCallback, useEffect, useRef, useState } from 'react';
import { drop } from '../../../util/drop';
import { createLogger } from '../../../logging/log';
import * as Errors from '../../../types/errors';
import { strictAssert } from '../../../util/assert';
import { drop } from '../../../util/drop.js';
import { createLogger } from '../../../logging/log.js';
import * as Errors from '../../../types/errors.js';
import { strictAssert } from '../../../util/assert.js';
const log = createLogger('infinite');
+1 -1
View File
@@ -1,6 +1,6 @@
// Copyright 2025 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import { strictAssert } from '../../../util/assert';
import { strictAssert } from '../../../util/assert.js';
/** @internal Exported for testing */
export const _SEGMENT_SIZE_BUCKETS: ReadonlyArray<number> = [
+3 -3
View File
@@ -3,9 +3,9 @@
import { z } from 'zod';
import type { Simplify } from 'type-fest';
import { strictAssert } from '../../../util/assert';
import { parseUnknown } from '../../../util/schemas';
import { fetchInSegments } from './segments';
import { strictAssert } from '../../../util/assert.js';
import { parseUnknown } from '../../../util/schemas.js';
import { fetchInSegments } from './segments.js';
const BASE_URL = 'https://tenor.googleapis.com/v2';
const API_KEY = 'AIzaSyBt6SUfSsCQic2P2VkNkLjsGI7HGWZI95g';
+1 -1
View File
@@ -1,6 +1,6 @@
// Copyright 2025 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import * as RemoteConfig from '../../RemoteConfig';
import * as RemoteConfig from '../../RemoteConfig.js';
export function isFunPickerEnabled(): boolean {
return RemoteConfig.isEnabled('desktop.funPicker');
+1 -1
View File
@@ -4,7 +4,7 @@ import { focusSafely, getFocusableTreeWalker } from '@react-aria/focus';
import type { ReactNode, RefObject } from 'react';
import React, { useEffect, useRef } from 'react';
import { createKeybindingsHandler } from 'tinykeys';
import { strictAssert } from '../../../util/assert';
import { strictAssert } from '../../../util/assert.js';
export abstract class KeyboardDelegate<State> {
abstract scrollToState(state: State): void;
@@ -2,14 +2,14 @@
// SPDX-License-Identifier: AGPL-3.0-only
import type { VirtualItem, Virtualizer } from '@tanstack/react-virtual';
import { findLast, sortBy } from 'lodash';
import { strictAssert } from '../../../util/assert';
import { strictAssert } from '../../../util/assert.js';
import type {
CellKey,
Layout,
RowKey,
SectionKey,
} from '../virtual/useFunVirtualGrid';
import { KeyboardDelegate } from './FunKeyboard';
} from '../virtual/useFunVirtualGrid.js';
import { KeyboardDelegate } from './FunKeyboard.js';
const PAGE_MARGIN = 0.25; // % of scroll height
@@ -2,8 +2,8 @@
// SPDX-License-Identifier: AGPL-3.0-only
import type { VirtualItem, Virtualizer } from '@tanstack/react-virtual';
import { findLast, maxBy } from 'lodash';
import { strictAssert } from '../../../util/assert';
import { KeyboardDelegate } from './FunKeyboard';
import { strictAssert } from '../../../util/assert.js';
import { KeyboardDelegate } from './FunKeyboard.js';
const PAGE_MARGIN = 0.25; // % of scroll height
+4 -4
View File
@@ -1,15 +1,15 @@
// Copyright 2025 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import { strictAssert } from '../../util/assert';
import type { EmojiParentKey, EmojiVariantKey } from './data/emojis';
import { strictAssert } from '../../util/assert.js';
import type { EmojiParentKey, EmojiVariantKey } from './data/emojis.js';
import {
EmojiSkinTone,
getEmojiParentKeyByEnglishShortName,
getEmojiVariantKeyByParentKeyAndSkinTone,
isEmojiEnglishShortName,
} from './data/emojis';
import type { GifsPaginated } from './data/gifs';
} from './data/emojis.js';
import type { GifsPaginated } from './data/gifs.js';
function getEmoji(input: string): EmojiParentKey {
strictAssert(
+25 -25
View File
@@ -11,15 +11,15 @@ import {
} from 'react-aria-components';
import { VisuallyHidden } from 'react-aria';
import * as Tooltip from '@radix-ui/react-tooltip';
import type { LocalizerType } from '../../../types/I18N';
import { strictAssert } from '../../../util/assert';
import { missingCaseError } from '../../../util/missingCaseError';
import type { FunEmojisSection } from '../constants';
import type { LocalizerType } from '../../../types/I18N.js';
import { strictAssert } from '../../../util/assert.js';
import { missingCaseError } from '../../../util/missingCaseError.js';
import type { FunEmojisSection } from '../constants.js';
import {
FunEmojisBase,
FunEmojisSectionOrder,
FunSectionCommon,
} from '../constants';
} from '../constants.js';
import {
FunGridCell,
FunGridContainer,
@@ -32,23 +32,23 @@ import {
FunGridRow,
FunGridRowGroup,
FunGridScrollerSection,
} from '../base/FunGrid';
import { FunItemButton } from '../base/FunItem';
} from '../base/FunGrid.js';
import { FunItemButton } from '../base/FunItem.js';
import {
FunPanel,
FunPanelBody,
FunPanelFooter,
FunPanelHeader,
} from '../base/FunPanel';
import { FunScroller } from '../base/FunScroller';
import { FunSearch } from '../base/FunSearch';
} from '../base/FunPanel.js';
import { FunScroller } from '../base/FunScroller.js';
import { FunSearch } from '../base/FunSearch.js';
import {
FunSubNav,
FunSubNavIcon,
FunSubNavListBox,
FunSubNavListBoxItem,
} from '../base/FunSubNav';
import type { EmojiParentKey, EmojiVariantKey } from '../data/emojis';
} from '../base/FunSubNav.js';
import type { EmojiParentKey, EmojiVariantKey } from '../data/emojis.js';
import {
EmojiSkinTone,
emojiParentKeyConstant,
@@ -62,23 +62,23 @@ import {
getEmojiParentKeyByVariantKey,
getEmojiVariantByKey,
getEmojiSkinToneByVariantKey,
} from '../data/emojis';
import { useFunEmojiSearch } from '../useFunEmojiSearch';
import { FunKeyboard } from '../keyboard/FunKeyboard';
import type { GridKeyboardState } from '../keyboard/GridKeyboardDelegate';
import { GridKeyboardDelegate } from '../keyboard/GridKeyboardDelegate';
} from '../data/emojis.js';
import { useFunEmojiSearch } from '../useFunEmojiSearch.js';
import { FunKeyboard } from '../keyboard/FunKeyboard.js';
import type { GridKeyboardState } from '../keyboard/GridKeyboardDelegate.js';
import { GridKeyboardDelegate } from '../keyboard/GridKeyboardDelegate.js';
import type {
CellKey,
CellLayoutNode,
GridSectionNode,
} from '../virtual/useFunVirtualGrid';
import { useFunVirtualGrid } from '../virtual/useFunVirtualGrid';
import { FunSkinTonesList } from '../FunSkinTones';
import { FunStaticEmoji } from '../FunEmoji';
import { useFunContext } from '../FunProvider';
import { FunResults, FunResultsHeader } from '../base/FunResults';
import { useFunEmojiLocalizer } from '../useFunEmojiLocalizer';
import { FunTooltip } from '../base/FunTooltip';
} from '../virtual/useFunVirtualGrid.js';
import { useFunVirtualGrid } from '../virtual/useFunVirtualGrid.js';
import { FunSkinTonesList } from '../FunSkinTones.js';
import { FunStaticEmoji } from '../FunEmoji.js';
import { useFunContext } from '../FunProvider.js';
import { FunResults, FunResultsHeader } from '../base/FunResults.js';
import { useFunEmojiLocalizer } from '../useFunEmojiLocalizer.js';
import { FunTooltip } from '../base/FunTooltip.js';
function getTitleForSection(
i18n: LocalizerType,
+30 -27
View File
@@ -14,55 +14,58 @@ import React, {
} from 'react';
import { VisuallyHidden } from 'react-aria';
import { LRUCache } from 'lru-cache';
import { FunItemButton } from '../base/FunItem';
import { FunItemButton } from '../base/FunItem.js';
import {
FunPanel,
FunPanelBody,
FunPanelFooter,
FunPanelHeader,
} from '../base/FunPanel';
import { FunScroller } from '../base/FunScroller';
import { FunSearch } from '../base/FunSearch';
} from '../base/FunPanel.js';
import { FunScroller } from '../base/FunScroller.js';
import { FunSearch } from '../base/FunSearch.js';
import {
FunSubNav,
FunSubNavIcon,
FunSubNavListBox,
FunSubNavListBoxItem,
} from '../base/FunSubNav';
import { FunWaterfallContainer, FunWaterfallItem } from '../base/FunWaterfall';
import type { FunGifsSection } from '../constants';
import { FunGifsCategory, FunSectionCommon } from '../constants';
import { FunKeyboard } from '../keyboard/FunKeyboard';
import type { WaterfallKeyboardState } from '../keyboard/WaterfallKeyboardDelegate';
import { WaterfallKeyboardDelegate } from '../keyboard/WaterfallKeyboardDelegate';
import { useInfiniteQuery } from '../data/infinite';
import { missingCaseError } from '../../../util/missingCaseError';
import { strictAssert } from '../../../util/assert';
import type { GifsPaginated } from '../data/gifs';
import { drop } from '../../../util/drop';
import { useFunContext } from '../FunProvider';
} from '../base/FunSubNav.js';
import {
FunWaterfallContainer,
FunWaterfallItem,
} from '../base/FunWaterfall.js';
import type { FunGifsSection } from '../constants.js';
import { FunGifsCategory, FunSectionCommon } from '../constants.js';
import { FunKeyboard } from '../keyboard/FunKeyboard.js';
import type { WaterfallKeyboardState } from '../keyboard/WaterfallKeyboardDelegate.js';
import { WaterfallKeyboardDelegate } from '../keyboard/WaterfallKeyboardDelegate.js';
import { useInfiniteQuery } from '../data/infinite.js';
import { missingCaseError } from '../../../util/missingCaseError.js';
import { strictAssert } from '../../../util/assert.js';
import type { GifsPaginated } from '../data/gifs.js';
import { drop } from '../../../util/drop.js';
import { useFunContext } from '../FunProvider.js';
import {
FunResults,
FunResultsButton,
FunResultsFigure,
FunResultsHeader,
FunResultsSpinner,
} from '../base/FunResults';
import { FunStaticEmoji } from '../FunEmoji';
import { emojiVariantConstant } from '../data/emojis';
} from '../base/FunResults.js';
import { FunStaticEmoji } from '../FunEmoji.js';
import { emojiVariantConstant } from '../data/emojis.js';
import {
FunLightboxPortal,
FunLightboxBackdrop,
FunLightboxDialog,
FunLightboxProvider,
useFunLightboxKey,
} from '../base/FunLightbox';
import type { tenorDownload } from '../data/tenor';
import { FunGif } from '../FunGif';
import type { LocalizerType } from '../../../types/I18N';
import { isAbortError } from '../../../util/isAbortError';
import { createLogger } from '../../../logging/log';
import * as Errors from '../../../types/errors';
} from '../base/FunLightbox.js';
import type { tenorDownload } from '../data/tenor.js';
import { FunGif } from '../FunGif.js';
import type { LocalizerType } from '../../../types/I18N.js';
import { isAbortError } from '../../../util/isAbortError.js';
import { createLogger } from '../../../logging/log.js';
import * as Errors from '../../../types/errors.js';
const log = createLogger('FunPanelGifs');
+25 -25
View File
@@ -12,20 +12,20 @@ import React, {
import type {
StickerPackType,
StickerType,
} from '../../../state/ducks/stickers';
import type { LocalizerType } from '../../../types/I18N';
import { strictAssert } from '../../../util/assert';
} from '../../../state/ducks/stickers.js';
import type { LocalizerType } from '../../../types/I18N.js';
import { strictAssert } from '../../../util/assert.js';
import type {
FunStickersPackSection,
FunStickersSection,
FunTimeStickerStyle,
} from '../constants';
} from '../constants.js';
import {
FunSectionCommon,
FunStickersSectionBase,
FunTimeStickerStylesOrder,
toFunStickersPackSection,
} from '../constants';
} from '../constants.js';
import {
FunGridCell,
FunGridContainer,
@@ -34,16 +34,16 @@ import {
FunGridRow,
FunGridRowGroup,
FunGridScrollerSection,
} from '../base/FunGrid';
import { FunItemButton } from '../base/FunItem';
} from '../base/FunGrid.js';
import { FunItemButton } from '../base/FunItem.js';
import {
FunPanel,
FunPanelBody,
FunPanelFooter,
FunPanelHeader,
} from '../base/FunPanel';
import { FunScroller } from '../base/FunScroller';
import { FunSearch } from '../base/FunSearch';
} from '../base/FunPanel.js';
import { FunScroller } from '../base/FunScroller.js';
import { FunSearch } from '../base/FunSearch.js';
import {
FunSubNav,
FunSubNavButton,
@@ -53,36 +53,36 @@ import {
FunSubNavListBox,
FunSubNavListBoxItem,
FunSubNavScroller,
} from '../base/FunSubNav';
} from '../base/FunSubNav.js';
import {
type EmojiParentKey,
emojiVariantConstant,
getEmojiParentKeyByValue,
isEmojiParentValue,
} from '../data/emojis';
import { FunKeyboard } from '../keyboard/FunKeyboard';
import type { GridKeyboardState } from '../keyboard/GridKeyboardDelegate';
import { GridKeyboardDelegate } from '../keyboard/GridKeyboardDelegate';
} from '../data/emojis.js';
import { FunKeyboard } from '../keyboard/FunKeyboard.js';
import type { GridKeyboardState } from '../keyboard/GridKeyboardDelegate.js';
import { GridKeyboardDelegate } from '../keyboard/GridKeyboardDelegate.js';
import type {
CellKey,
CellLayoutNode,
GridSectionNode,
} from '../virtual/useFunVirtualGrid';
import { useFunVirtualGrid } from '../virtual/useFunVirtualGrid';
import { useFunContext } from '../FunProvider';
import { FunResults, FunResultsHeader } from '../base/FunResults';
import { FunStaticEmoji } from '../FunEmoji';
} from '../virtual/useFunVirtualGrid.js';
import { useFunVirtualGrid } from '../virtual/useFunVirtualGrid.js';
import { useFunContext } from '../FunProvider.js';
import { FunResults, FunResultsHeader } from '../base/FunResults.js';
import { FunStaticEmoji } from '../FunEmoji.js';
import {
FunLightboxPortal,
FunLightboxBackdrop,
FunLightboxDialog,
FunLightboxProvider,
useFunLightboxKey,
} from '../base/FunLightbox';
import { FunSticker } from '../FunSticker';
import { getAnalogTime } from '../../../util/getAnalogTime';
import { getDateTimeFormatter } from '../../../util/formatTimestamp';
import { useFunEmojiSearch } from '../useFunEmojiSearch';
} from '../base/FunLightbox.js';
import { FunSticker } from '../FunSticker.js';
import { getAnalogTime } from '../../../util/getAnalogTime.js';
import { getDateTimeFormatter } from '../../../util/formatTimestamp.js';
import { useFunEmojiSearch } from '../useFunEmojiSearch.js';
const STICKER_GRID_COLUMNS = 4;
const STICKER_GRID_CELL_WIDTH = 80;
+5 -5
View File
@@ -1,16 +1,16 @@
// Copyright 2025 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import { useMemo } from 'react';
import type { EmojiParentKey, EmojiVariantKey } from './data/emojis';
import type { EmojiParentKey, EmojiVariantKey } from './data/emojis.js';
import {
getEmojiParentByKey,
getEmojiParentKeyByVariantKey,
getEmojiVariantKeyByValue,
isEmojiVariantValue,
} from './data/emojis';
import type { LocaleEmojiListType } from '../../types/emoji';
import { strictAssert } from '../../util/assert';
import { useFunEmojiLocalization } from './FunEmojiLocalizationProvider';
} from './data/emojis.js';
import type { LocaleEmojiListType } from '../../types/emoji.js';
import { strictAssert } from '../../util/assert.js';
import { useFunEmojiLocalization } from './FunEmojiLocalizationProvider.js';
export type FunEmojiLocalizerIndex = Readonly<{
parentKeyToLocaleShortName: ReadonlyMap<EmojiParentKey, string>;
+4 -4
View File
@@ -3,16 +3,16 @@
import Fuse from 'fuse.js';
import { sortBy } from 'lodash';
import { useMemo } from 'react';
import type { EmojiParentKey } from './data/emojis';
import type { EmojiParentKey } from './data/emojis.js';
import {
getEmojiParentByKey,
getEmojiParentKeyByValue,
isEmojiParentValue,
isEmojiParentValueDeprecated,
normalizeShortNameCompletionQuery,
} from './data/emojis';
import type { LocaleEmojiListType } from '../../types/emoji';
import { useFunEmojiLocalization } from './FunEmojiLocalizationProvider';
} from './data/emojis.js';
import type { LocaleEmojiListType } from '../../types/emoji.js';
import { useFunEmojiLocalization } from './FunEmojiLocalizationProvider.js';
export type FunEmojiSearchIndexEntry = Readonly<{
key: EmojiParentKey;
@@ -1,16 +1,16 @@
// Copyright 2025 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import type { Virtualizer } from '@tanstack/react-virtual';
import {
useVirtualizer,
type Range,
type VirtualItem,
type Virtualizer,
} from '@tanstack/react-virtual';
import { chunk, groupBy } from 'lodash';
import type { RefObject } from 'react';
import { useCallback, useMemo } from 'react';
import { strictAssert } from '../../../util/assert';
import { missingCaseError } from '../../../util/missingCaseError';
import { strictAssert } from '../../../util/assert.js';
import { missingCaseError } from '../../../util/missingCaseError.js';
export type SectionKey = `section-${string}`;
export type HeaderKey = `header-${string}`;