refactor(imports): replace relative imports with path aliases (#2741)

This commit is contained in:
Hampus authored and GitHub committed 2026-09-13 20:18:22 +02:00
1 parent a59b80ce11
commit 84dcf6b8a8
1834 files changed
+11601 -10725

No files matched your search

@@ -1,6 +1,5 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
import {describe, expect, it} from 'vitest';
import {
COMFY_MESSAGE_GROUP_SPACING_DEFAULT,
COMPACT_MESSAGE_GROUP_SPACING_DEFAULT,
@@ -8,7 +7,8 @@ import {
getMessageGroupSpacingForDisplayMode,
getMessageGroupSpacingPatch,
migrateLegacyMessageGroupSpacing,
} from './MessageGroupSpacing';
} from '@app/features/accessibility/state/MessageGroupSpacing';
import {describe, expect, it} from 'vitest';
describe('MessageGroupSpacing', () => {
it('keeps explicit defaults per display mode', () => {
@@ -1,7 +1,5 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
import {StickerAnimationOptions} from '@fluxer/constants/src/UserConstants';
import {describe, expect, it} from 'vitest';
import {
createMotionPreferencesContext,
createMotionPreferencesSnapshot,
@@ -22,7 +20,9 @@ import {
selectReducedMotionSource,
selectSmoothScrollingEnabled,
transitionMotionPreferencesSnapshot,
} from './MotionPreferencesMachine';
} from '@app/features/accessibility/state/MotionPreferencesMachine';
import {StickerAnimationOptions} from '@fluxer/constants/src/UserConstants';
import {describe, expect, it} from 'vitest';
const {ALWAYS_ANIMATE, ANIMATE_ON_INTERACTION, NEVER_ANIMATE} = StickerAnimationOptions;
@@ -1,9 +1,9 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
import {GenericErrorModal} from '@app/features/app/components/alerts/GenericErrorModal';
import {msg} from '@lingui/core/macro';
import {useLingui} from '@lingui/react/macro';
import {observer} from 'mobx-react-lite';
import {GenericErrorModal} from './GenericErrorModal';
const FEATURE_TEMPORARILY_DISABLED_DESCRIPTOR = msg({
message: 'Feature temporarily disabled',
@@ -1,5 +1,6 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
import {GenericErrorModal} from '@app/features/app/components/alerts/GenericErrorModal';
import {ConfirmModal} from '@app/features/app/components/dialogs/ConfirmModal';
import {PREMIUM_PRODUCT_NAME} from '@app/features/app/config/I18nDisplayConstants';
import {Limits} from '@app/features/app/utils/UserLimits';
@@ -11,7 +12,6 @@ import {MAX_BOOKMARKS_PREMIUM} from '@fluxer/constants/src/LimitConstants';
import {msg, plural} from '@lingui/core/macro';
import {useLingui} from '@lingui/react/macro';
import {observer} from 'mobx-react-lite';
import {GenericErrorModal} from './GenericErrorModal';
const BOOKMARK_LIMIT_REACHED_DESCRIPTOR = msg({
message: 'Bookmark limit reached',
@@ -1,5 +1,6 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
import {GenericErrorModal} from '@app/features/app/components/alerts/GenericErrorModal';
import {ConfirmModal} from '@app/features/app/components/dialogs/ConfirmModal';
import {PREMIUM_PRODUCT_NAME} from '@app/features/app/config/I18nDisplayConstants';
import {Limits} from '@app/features/app/utils/UserLimits';
@@ -11,7 +12,6 @@ import {MAX_FAVORITE_MEMES_PREMIUM} from '@fluxer/constants/src/LimitConstants';
import {msg, plural} from '@lingui/core/macro';
import {useLingui} from '@lingui/react/macro';
import {observer} from 'mobx-react-lite';
import {GenericErrorModal} from './GenericErrorModal';
const SAVED_MEDIA_LIMIT_REACHED_DESCRIPTOR = msg({
message: 'Saved media limit reached',
@@ -1,9 +1,9 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
import {GenericErrorModal} from '@app/features/app/components/alerts/GenericErrorModal';
import {msg} from '@lingui/core/macro';
import {useLingui} from '@lingui/react/macro';
import {observer} from 'mobx-react-lite';
import {GenericErrorModal} from './GenericErrorModal';
const ROLE_NAME_CANNOT_BE_BLANK_DESCRIPTOR = msg({
message: 'Role name is required',
@@ -1,9 +1,9 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
import {GenericErrorModal} from '@app/features/app/components/alerts/GenericErrorModal';
import {msg} from '@lingui/core/macro';
import {useLingui} from '@lingui/react/macro';
import {observer} from 'mobx-react-lite';
import {GenericErrorModal} from './GenericErrorModal';
const GATEWAY_CONNECTION_REQUIRED_DESCRIPTOR = msg({
message: 'Gateway connection required',
@@ -1,8 +1,8 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
import {isForwardableChannelType} from '@app/features/app/components/dialogs/shared/ForwardChannelEligibility';
import {ChannelTypes} from '@fluxer/constants/src/ChannelConstants';
import {describe, expect, it} from 'vitest';
import {isForwardableChannelType} from './ForwardChannelEligibility';
describe('forward channel eligibility', () => {
it('allows every text-based message destination, including text-in-voice channels', () => {
@@ -1,5 +1,7 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
import {isForwardableChannelType} from '@app/features/app/components/dialogs/shared/ForwardChannelEligibility';
import {matchesForwardChannelSearch} from '@app/features/app/components/dialogs/shared/ForwardChannelSearchMatch';
import {formatSlowmodeTime} from '@app/features/channel/components/SlowmodeIndicator';
import type {Channel} from '@app/features/channel/models/Channel';
import {PERSONAL_NOTES_DESCRIPTOR} from '@app/features/i18n/utils/CommonMessageDescriptors';
@@ -8,8 +10,6 @@ import {formatPermissionLabel} from '@app/features/permissions/utils/PermissionU
import {ChannelTypes, Permissions} from '@fluxer/constants/src/ChannelConstants';
import type {I18n} from '@lingui/core';
import {msg} from '@lingui/core/macro';
import {isForwardableChannelType} from './ForwardChannelEligibility';
import {matchesForwardChannelSearch} from './ForwardChannelSearchMatch';
const GUILD_MESSAGES_DISABLED_DESCRIPTOR = msg({
message: 'Sending messages is disabled in this community',
@@ -1,7 +1,10 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
import {
type ForwardChannelSearchValues,
matchesForwardChannelSearch,
} from '@app/features/app/components/dialogs/shared/ForwardChannelSearchMatch';
import {describe, expect, it} from 'vitest';
import {type ForwardChannelSearchValues, matchesForwardChannelSearch} from './ForwardChannelSearchMatch';
const PERSONAL_NOTES = 'personal notes';
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
import {selectFrozenUnreadChannels} from '@app/features/app/components/floating/UnreadChannelOrder';
import {describe, expect, it} from 'vitest';
import {selectFrozenUnreadChannels} from './UnreadChannelOrder';
function ids(channels: ReadonlyArray<{id: string}>): Array<string> {
return channels.map((channel) => channel.id);
@@ -2,6 +2,7 @@
import {Routes} from '@app/app/Routes';
import Accessibility from '@app/features/accessibility/state/Accessibility';
import {GenericErrorModal} from '@app/features/app/components/alerts/GenericErrorModal';
import {ChannelItem} from '@app/features/app/components/layout/ChannelItem';
import channelItemStyles from '@app/features/app/components/layout/ChannelItem.module.css';
import {ChannelItemContent} from '@app/features/app/components/layout/ChannelItemContent';
@@ -70,7 +71,6 @@ import {observer} from 'mobx-react-lite';
import type {MotionValue} from 'motion';
import React, {useCallback, useEffect, useMemo, useRef, useState} from 'react';
import {useDragLayer} from 'react-dnd';
import {GenericErrorModal} from '../alerts/GenericErrorModal';
const CATEGORY_FULL_DESCRIPTOR = msg({
message: 'Category full',
@@ -1,11 +1,11 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
import styles from '@app/features/app/components/layout/NativeTitlebar.module.css';
import {NativeWindowControls} from '@app/features/app/components/layout/NativeWindowControls';
import {FluxerWordmark} from '@app/features/ui/components/icons/FluxerWordmark';
import {getElectronAPI, type NativePlatform} from '@app/features/ui/utils/NativeUtils';
import type React from 'react';
import {useLayoutEffect} from 'react';
import {NativeWindowControls} from './NativeWindowControls';
const STARTUP_NATIVE_TITLEBAR_ID = 'fluxer-startup-native-titlebar';
@@ -1,6 +1,5 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
import {describe, expect, it} from 'vitest';
import {
createScrollIndicatorSnapshot,
getScrollIndicatorStateValue,
@@ -10,7 +9,8 @@ import {
type ScrollIndicatorTargetMeasurement,
selectActiveScrollIndicator,
transitionScrollIndicatorSnapshot,
} from './ScrollIndicatorStateMachine';
} from '@app/features/app/components/layout/ScrollIndicatorStateMachine';
import {describe, expect, it} from 'vitest';
function target(
id: string,
@@ -1,7 +1,10 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
import {
selectUserAreaMicrophoneState,
type UserAreaMicrophoneSignals,
} from '@app/features/app/components/layout/UserAreaState';
import {describe, expect, it} from 'vitest';
import {selectUserAreaMicrophoneState, type UserAreaMicrophoneSignals} from './UserAreaState';
const baseSignals: UserAreaMicrophoneSignals = {
effectiveAudioMuted: false,
@@ -1,5 +1,10 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
import {
type ChannelReorderRect,
type ChannelReorderTarget,
selectChannelReorderIntent,
} from '@app/features/app/components/layout/dnd/ChannelReorderStateMachine';
import {type DragItem, DragItemType, type DropResult} from '@app/features/app/components/layout/types/DndTypes';
import {
type ChannelMoveOperation,
@@ -9,11 +14,6 @@ import type {Channel} from '@app/features/channel/models/Channel';
import {ChannelTypes} from '@fluxer/constants/src/ChannelConstants';
import {computeGuildChannelReorderPlan} from '@fluxer/schema/src/domains/channel/GuildChannelOrdering';
import {describe, expect, it} from 'vitest';
import {
type ChannelReorderRect,
type ChannelReorderTarget,
selectChannelReorderIntent,
} from './ChannelReorderStateMachine';
const rect: ChannelReorderRect = {
top: 100,
@@ -1,8 +1,5 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
import {type DragItem, DragItemType} from '@app/features/app/components/layout/types/DndTypes';
import {ChannelTypes} from '@fluxer/constants/src/ChannelConstants';
import {describe, expect, it} from 'vitest';
import {
type ChannelReorderRect,
type ChannelReorderTarget,
@@ -13,7 +10,10 @@ import {
selectChannelReorderIntent,
selectChannelReorderResolution,
transitionChannelReorderSnapshot,
} from './ChannelReorderStateMachine';
} from '@app/features/app/components/layout/dnd/ChannelReorderStateMachine';
import {type DragItem, DragItemType} from '@app/features/app/components/layout/types/DndTypes';
import {ChannelTypes} from '@fluxer/constants/src/ChannelConstants';
import {describe, expect, it} from 'vitest';
const rect: ChannelReorderRect = {
top: 40,
@@ -1,11 +1,11 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
import {describe, expect, it} from 'vitest';
import {
shouldShowCategoryWhenHidingMutedChannels,
shouldShowChannelInCollapsedCategory,
shouldShowChannelWhenHidingMutedChannels,
} from './ChannelListVisibility';
} from '@app/features/app/components/layout/utils/ChannelListVisibility';
import {describe, expect, it} from 'vitest';
describe('shouldShowChannelWhenHidingMutedChannels', () => {
it('keeps muted channels with visible unread state so mentions are findable', () => {
@@ -1,8 +1,8 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
import {getChannelUnreadState} from '@app/features/app/components/layout/utils/ChannelUnreadState';
import {MessageNotifications} from '@fluxer/constants/src/NotificationConstants';
import {describe, expect, it} from 'vitest';
import {getChannelUnreadState} from './ChannelUnreadState';
describe('getChannelUnreadState', () => {
it('shows a normal unread indicator for all-messages unread badges', () => {
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
import {resolveChannelUnreadState} from './ChannelUnreadStateMachine';
import {resolveChannelUnreadState} from '@app/features/app/components/layout/utils/ChannelUnreadStateMachine';
export interface ChannelUnreadStateInput {
hasUnread: boolean;
@@ -1,14 +1,14 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
import {MessageNotifications} from '@fluxer/constants/src/NotificationConstants';
import {describe, expect, it} from 'vitest';
import type {ChannelUnreadStateInput} from './ChannelUnreadState';
import type {ChannelUnreadStateInput} from '@app/features/app/components/layout/utils/ChannelUnreadState';
import {
type ChannelUnreadStateValue,
createChannelUnreadSnapshot,
selectChannelUnreadState,
transitionChannelUnreadSnapshot,
} from './ChannelUnreadStateMachine';
} from '@app/features/app/components/layout/utils/ChannelUnreadStateMachine';
import {MessageNotifications} from '@fluxer/constants/src/NotificationConstants';
import {describe, expect, it} from 'vitest';
function input(overrides: Partial<ChannelUnreadStateInput> = {}): ChannelUnreadStateInput {
return {
@@ -1,8 +1,11 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
import type {
ChannelUnreadState,
ChannelUnreadStateInput,
} from '@app/features/app/components/layout/utils/ChannelUnreadState';
import {MessageNotifications} from '@fluxer/constants/src/NotificationConstants';
import {assign, initialTransition, type SnapshotFrom, setup, transition} from 'xstate';
import type {ChannelUnreadState, ChannelUnreadStateInput} from './ChannelUnreadState';
interface ChannelUnreadMachineContext extends ChannelUnreadStateInput {}
@@ -1,13 +1,13 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
import {describe, expect, it} from 'vitest';
import {
createSetupWizardSnapshot,
type SetupWizardMachineEvent,
type SetupWizardSnapshot,
selectSetupWizardModel,
transitionSetupWizardSnapshot,
} from './SetupWizardStateMachine';
} from '@app/features/app/components/setup/SetupWizardStateMachine';
import {describe, expect, it} from 'vitest';
function transition(snapshot: SetupWizardSnapshot, event: SetupWizardMachineEvent): SetupWizardSnapshot {
return transitionSetupWizardSnapshot(snapshot, event);
@@ -1,12 +1,12 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
import {describe, expect, it} from 'vitest';
import {
createRandomWelcomeRotationState,
createWelcomeRotationState,
WELCOME_ROTATION,
type WelcomeRotationState,
} from './SetupWizardWelcomeRotation';
} from '@app/features/app/components/setup/SetupWizardWelcomeRotation';
import {describe, expect, it} from 'vitest';
function constantRandom(value: number): () => number {
return () => value;
@@ -1,9 +1,9 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
import Config from '@app/features/app/config/Config';
import {PREMIUM_PRODUCT_FULL_NAME, PREMIUM_PRODUCT_NAME, PRODUCT_NAME} from '@app/features/app/config/ProductConstants';
import {formatAssetUploadExtensions, formatKnownAnimatedAssetExtensions} from '@fluxer/constants/src/AssetFormatPolicy';
import {THE_OTHER_PLATFORM} from '@fluxer/constants/src/ExternalPlatformConstants';
import {PREMIUM_PRODUCT_FULL_NAME, PREMIUM_PRODUCT_NAME, PRODUCT_NAME} from './ProductConstants';
export {PREMIUM_PRODUCT_FULL_NAME, PREMIUM_PRODUCT_NAME, PRODUCT_NAME};
export const PRODUCT_API_NAME = `${PRODUCT_NAME} API`;
@@ -1,18 +1,18 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
import {
canUseWindowFocusedHoverControls,
subscribeWindowHoverControlsChange,
} from '@app/features/ui/utils/WindowFocusInteractionGuard';
import type React from 'react';
import {useCallback, useEffect, useRef, useState} from 'react';
import {
createHoverStateSnapshot,
type HoverStateEvent,
type HoverStateSnapshot,
selectIsHovering,
transitionHoverStateSnapshot,
} from './HoverStateMachine';
} from '@app/features/app/hooks/HoverStateMachine';
import {
canUseWindowFocusedHoverControls,
subscribeWindowHoverControlsChange,
} from '@app/features/ui/utils/WindowFocusInteractionGuard';
import type React from 'react';
import {useCallback, useEffect, useRef, useState} from 'react';
type HoverHook = [React.RefCallback<HTMLElement>, boolean];
@@ -1,7 +1,5 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
import {ChannelTypes} from '@fluxer/constants/src/ChannelConstants';
import {describe, expect, it} from 'vitest';
import {
keyboardEventCanRecoverStaleMacMetaPress,
keyboardEventMatchesCombo,
@@ -9,11 +7,16 @@ import {
keyboardEventStartsComboPress,
keyboardEventTriggerMatchesCombo,
shouldAllowLocalShortcutForChannelTextarea,
} from './KeybindEventUtils';
import {isKeybindAllowedDuringVoiceCallFullscreen, isKeybindBlockedByCompactVoiceCallView} from './KeybindScopeUtils';
import {comboToCombokeysStrings} from './utils/ComboShortcutStrings';
import {keyNameForGlobalHook, physicalKeyNameForGlobalHook} from './utils/GlobalHookKeys';
import {hookShortcutIdForKeybind} from './utils/HookShortcutIds';
} from '@app/features/app/keybindings/KeybindEventUtils';
import {
isKeybindAllowedDuringVoiceCallFullscreen,
isKeybindBlockedByCompactVoiceCallView,
} from '@app/features/app/keybindings/KeybindScopeUtils';
import {comboToCombokeysStrings} from '@app/features/app/keybindings/utils/ComboShortcutStrings';
import {keyNameForGlobalHook, physicalKeyNameForGlobalHook} from '@app/features/app/keybindings/utils/GlobalHookKeys';
import {hookShortcutIdForKeybind} from '@app/features/app/keybindings/utils/HookShortcutIds';
import {ChannelTypes} from '@fluxer/constants/src/ChannelConstants';
import {describe, expect, it} from 'vitest';
const keyEvent = (
overrides: Partial<{
@@ -1,8 +1,12 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
import {
buildCustomRuntimeKeybinds,
buildDefaultRuntimeKeybinds,
getCustomActionOverrides,
} from '@app/features/app/keybindings/utils/RuntimeKeybinds';
import type {CustomKeybindEntry, KeybindCommand, KeybindConfig, KeyCombo} from '@app/features/input/state/InputKeybind';
import {describe, expect, it} from 'vitest';
import {buildCustomRuntimeKeybinds, buildDefaultRuntimeKeybinds, getCustomActionOverrides} from './RuntimeKeybinds';
const action: KeybindCommand = 'voice_toggle_deafen';
const keybind = (combo: KeyCombo): KeybindConfig => ({
@@ -3,7 +3,11 @@
import type {CustomKeybindEntry, KeybindCommand, KeybindConfig, KeyCombo} from '@app/features/input/state/InputKeybind';
import {keyComboHasTriggerInput} from '@app/features/input/state/KeybindResolution';
export {comboModifierSignature, hookShortcutIdForAction, hookShortcutIdForKeybind} from './HookShortcutIds';
export {
comboModifierSignature,
hookShortcutIdForAction,
hookShortcutIdForKeybind,
} from '@app/features/app/keybindings/utils/HookShortcutIds';
export type RuntimeKeybind = KeybindConfig & {
combo: KeyCombo;
@@ -1,9 +1,8 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
import {normalizeGifProviderInfo} from '@app/features/app/state/GifProviderConfig';
import {describe, expect, it} from 'vitest';
import {normalizeGifProviderInfo} from './GifProviderConfig';
describe('normalizeGifProviderInfo', () => {
it('uses Klipy as the default GIF provider display name', () => {
expect(normalizeGifProviderInfo()).toEqual({
@@ -1,10 +1,10 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
import {describe, expect, it} from 'vitest';
import {
shouldShowNativeDesktopUpdateDownloadProgress,
shouldShowNativeDesktopUpdateInApp,
} from './UpdaterPlatformUtils';
} from '@app/features/app/utils/UpdaterPlatformUtils';
import {describe, expect, it} from 'vitest';
describe('UpdaterPlatformUtils', () => {
it('surfaces native desktop update availability in-app on Linux, macOS, and Windows', () => {
@@ -32,7 +32,9 @@ vi.mock('@app/features/auth/state/SudoPrompt', () => ({isAbortError: () => false
const {APIErrorCodes} = await import('@fluxer/constants/src/ApiErrorCodes');
const {HttpError} = await import('@app/features/platform/types/EndpointError');
const {resolveRequiredActionErrorMessage} = await import('./RequiredActionShared');
const {resolveRequiredActionErrorMessage} = await import(
'@app/features/auth/components/modals/required_action/RequiredActionShared'
);
const {
ENTER_VALID_PHONE_DESCRIPTOR,
PHONE_CANNOT_BE_USED_DESCRIPTOR,
@@ -44,7 +46,7 @@ const {
PHONE_NOT_MOBILE_DESCRIPTOR,
SOMETHING_WENT_WRONG_TRY_AGAIN_DESCRIPTOR,
TOO_MANY_ATTEMPTS_DESCRIPTOR,
} = await import('./RequiredActionDescriptors');
} = await import('@app/features/auth/components/modals/required_action/RequiredActionDescriptors');
const i18n = setupI18n({locale: 'en', messages: {en: {}}});
@@ -17,7 +17,9 @@ vi.mock('@app/features/app/config/Config', () => ({
},
}));
const {buildPhoneGateEscapeConfirmCopy, buildPhoneGateEscapeHint} = await import('./RequiredActionEscapeCopy');
const {buildPhoneGateEscapeConfirmCopy, buildPhoneGateEscapeHint} = await import(
'@app/features/auth/components/modals/required_action/RequiredActionEscapeCopy'
);
const i18n = setupI18n({locale: 'en', messages: {en: {}}});
@@ -1,12 +1,12 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
import {describe, expect, it} from 'vitest';
import {
createAuthorizeSnapshot,
getAuthorizeStateValue,
selectAuthorizePhase,
transitionAuthorizeSnapshot,
} from './authorizeMachine';
} from '@app/features/auth/components/pages/oauth_authorize_page/state/authorizeMachine';
import {describe, expect, it} from 'vitest';
describe('authorizeMachine', () => {
it('moves from loading into review and through bot invite success', () => {
@@ -1,9 +1,9 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
import {getUnreadDividerBeforeMessageId} from '@app/features/channel/components/ChannelMessageStreamUtils';
import type {Message} from '@app/features/messaging/models/MessagingMessage';
import type {ChannelStreamItem} from '@app/features/messaging/utils/MessageGroupingUtils';
import {bench, describe} from 'vitest';
import {getUnreadDividerBeforeMessageId} from './ChannelMessageStreamUtils';
const GROUP_ITEMS = Array.from(
{length: 100},
@@ -1,9 +1,9 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
import {getUnreadDividerBeforeMessageId} from '@app/features/channel/components/ChannelMessageStreamUtils';
import type {Message} from '@app/features/messaging/models/MessagingMessage';
import type {ChannelStreamItem} from '@app/features/messaging/utils/MessageGroupingUtils';
import {describe, expect, it} from 'vitest';
import {getUnreadDividerBeforeMessageId} from './ChannelMessageStreamUtils';
function item(messageId: string, showUnreadDividerBefore = false): ChannelStreamItem {
return {
@@ -1,8 +1,8 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
import {splitMediaAndFileAttachments} from '@app/features/channel/components/MessageAttachmentUtils';
import type {MessageAttachment} from '@fluxer/schema/src/domains/message/MessageResponseSchemas';
import {bench, describe} from 'vitest';
import {splitMediaAndFileAttachments} from './MessageAttachmentUtils';
const CONTENT_TYPES = [
'image/png',
@@ -1,8 +1,8 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
import {splitMediaAndFileAttachments} from '@app/features/channel/components/MessageAttachmentUtils';
import type {MessageAttachment} from '@fluxer/schema/src/domains/message/MessageResponseSchemas';
import {describe, expect, it} from 'vitest';
import {splitMediaAndFileAttachments} from './MessageAttachmentUtils';
const baseAttachment = {
id: 'attachment-1',
@@ -1,12 +1,12 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
import type {Message} from '@app/features/messaging/models/MessagingMessage';
import {describe, expect, it} from 'vitest';
import {
buildSearchResultGroups,
buildSearchResultGroupsByMessageId,
countSearchResultChannels,
} from './SearchResultGrouping';
} from '@app/features/channel/components/SearchResultGrouping';
import type {Message} from '@app/features/messaging/models/MessagingMessage';
import {describe, expect, it} from 'vitest';
const message = (id: string, channelId: string): Message => ({id, channelId}) as Message;
@@ -1,9 +1,9 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
import type {SearchMachineState} from '@app/features/channel/components/SearchStateMachine';
import {Channel} from '@app/features/channel/models/Channel';
import {Message} from '@app/features/messaging/models/MessagingMessage';
import type {SearchSegment} from '@app/features/search/utils/SearchSegmentManager';
import type {SearchMachineState} from './SearchStateMachine';
export type {
SearchMachineEvent,
@@ -14,7 +14,7 @@ export type {
SearchMachineStateIndexing,
SearchMachineStateLoading,
SearchMachineStateSuccess,
} from './SearchStateMachine';
} from '@app/features/channel/components/SearchStateMachine';
export const cloneMessageRecord = (message: Message): Message => {
return new Message(message.toJSON(), {skipUserCache: true});
@@ -1,8 +1,8 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
import {resolveSearchScope} from '@app/features/channel/components/SearchScopeResolution';
import type {MessageSearchScope} from '@app/features/search/utils/SearchUtils';
import {describe, expect, it} from 'vitest';
import {resolveSearchScope} from './SearchScopeResolution';
const GUILD_SCOPE_OPTIONS = new Set<MessageSearchScope>([
'current',
@@ -1,11 +1,11 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
import {describe, expect, it} from 'vitest';
import {
createSearchMachineSnapshot,
selectSearchMachineState,
transitionSearchMachineSnapshot,
} from './SearchStateMachine';
} from '@app/features/channel/components/SearchStateMachine';
import {describe, expect, it} from 'vitest';
describe('SearchStateMachine', () => {
it('starts idle and transitions through loading to success', () => {
@@ -1,6 +1,10 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
import {showChannelErrorModal} from '@app/features/channel/components/alerts/ChannelErrorModalUtils';
import {
PREMIUM_TYPE_DESCRIPTOR,
UNREAD_GIFT_COUNT_DESCRIPTOR,
} from '@app/features/channel/components/channel_header_components/developer_tools/DeveloperOptionLabels';
import {
DeveloperOptionCheckbox,
DeveloperOptionRadioItems,
@@ -9,6 +13,8 @@ import {
translateDescriptor,
USE_ACTUAL_VALUE_DESCRIPTOR,
} from '@app/features/channel/components/channel_header_components/developer_tools/DeveloperToolsShared';
import {getPremiumTypeOptions} from '@app/features/channel/components/channel_header_components/developer_tools/OptionPresets';
import {updateOption} from '@app/features/channel/components/channel_header_components/developer_tools/ResetOptions';
import {
applyPremiumScenarioOption,
PREMIUM_SCENARIO_OPTIONS,
@@ -28,9 +34,6 @@ import {msg, plural} from '@lingui/core/macro';
import {Trans, useLingui} from '@lingui/react/macro';
import {observer} from 'mobx-react-lite';
import type React from 'react';
import {PREMIUM_TYPE_DESCRIPTOR, UNREAD_GIFT_COUNT_DESCRIPTOR} from './DeveloperOptionLabels';
import {getPremiumTypeOptions} from './OptionPresets';
import {updateOption} from './ResetOptions';
const logger = new Logger('DeveloperToolsContextMenu/AccountPremiumMenu');
const ACCOUNT_STATE_DESCRIPTOR = msg({
@@ -13,13 +13,20 @@ import {
USE_ACTUAL_VALUE_DESCRIPTOR,
USE_DEFAULT_DESCRIPTOR,
} from '@app/features/channel/components/channel_header_components/developer_tools/DeveloperToolsShared';
import {formatDurationMs} from '@app/features/channel/components/channel_header_components/developer_tools/FormatHelpers';
import {
getPremiumTypeLabel,
LIFETIME_DESCRIPTOR,
} from '@app/features/channel/components/channel_header_components/developer_tools/OptionPresets';
import {
DEVELOPER_OPTION_KEYS,
isDeveloperOptionAtDefault,
resetDeveloperOption,
} from '@app/features/channel/components/channel_header_components/developer_tools/ResetOptions';
import type {DeveloperOptionsState} from '@app/features/devtools/state/DeveloperOptions';
import DeveloperOptions from '@app/features/devtools/state/DeveloperOptions';
import type {I18n, MessageDescriptor} from '@lingui/core';
import {msg} from '@lingui/core/macro';
import {formatDurationMs} from './FormatHelpers';
import {getPremiumTypeLabel, LIFETIME_DESCRIPTOR} from './OptionPresets';
import {DEVELOPER_OPTION_KEYS, isDeveloperOptionAtDefault, resetDeveloperOption} from './ResetOptions';
const ACTIVE_DEVELOPER_OPTION_KEYS = DEVELOPER_OPTION_KEYS.filter((key) => key !== 'premiumScenarioOverride');
export const ATTACHMENT_MOCKS_DESCRIPTOR = msg({
@@ -7,6 +7,7 @@ import {
type RadioMenuOption,
translateDescriptor,
} from '@app/features/channel/components/channel_header_components/developer_tools/DeveloperToolsShared';
import {updateOption} from '@app/features/channel/components/channel_header_components/developer_tools/ResetOptions';
import type {DeveloperOptionsState} from '@app/features/devtools/state/DeveloperOptions';
import DeveloperOptions from '@app/features/devtools/state/DeveloperOptions';
import * as PremiumCommands from '@app/features/premium/commands/PremiumCommands';
@@ -22,7 +23,6 @@ import {useLingui} from '@lingui/react/macro';
import {CrownIcon} from '@phosphor-icons/react';
import {observer} from 'mobx-react-lite';
import type React from 'react';
import {updateOption} from './ResetOptions';
interface DeveloperOptionCheckboxProps<K extends keyof DeveloperOptionsState> {
optionKey: K;
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
import {translateDescriptor} from '@app/features/channel/components/channel_header_components/developer_tools/DeveloperToolsShared';
import {updateOption} from '@app/features/channel/components/channel_header_components/developer_tools/ResetOptions';
import {getToggleGroups, type ToggleGroup} from '@app/features/devtools/components/DeveloperOptionsToggleGroups';
import type {DeveloperOptionsState} from '@app/features/devtools/state/DeveloperOptions';
import DeveloperOptions from '@app/features/devtools/state/DeveloperOptions';
@@ -13,7 +14,6 @@ import {msg} from '@lingui/core/macro';
import {Trans, useLingui} from '@lingui/react/macro';
import {observer} from 'mobx-react-lite';
import type React from 'react';
import {updateOption} from './ResetOptions';
const MENTION_CONTROLS_DESCRIPTOR = msg({
message: 'Mention controls',
@@ -7,6 +7,18 @@ import {
DeveloperOptionRadioItems,
DeveloperOptionRadioSubmenu,
} from '@app/features/channel/components/channel_header_components/developer_tools/DeveloperToolsMenuComponents';
import {
getCountdownTimerOptions,
getGiftDurationOptions,
getMatureContentChannelGateOptions,
getMatureContentMediaGateOptions,
getRequiredActionModeOptions,
getRequiredActionPhoneStepOptions,
getRequiredActionResendOutcomeOptions,
getRequiredActionTabOptions,
getVerificationBarrierOptions,
} from '@app/features/channel/components/channel_header_components/developer_tools/OptionPresets';
import {updateOption} from '@app/features/channel/components/channel_header_components/developer_tools/ResetOptions';
import * as DeveloperOptionsCommands from '@app/features/devtools/commands/DeveloperOptionsCommands';
import DeveloperOptions from '@app/features/devtools/state/DeveloperOptions';
import {remFromPx} from '@app/features/theme/layout/RemFromPx';
@@ -20,18 +32,6 @@ import {Trans, useLingui} from '@lingui/react/macro';
import {PhoneIcon, TrashIcon, UsersIcon} from '@phosphor-icons/react';
import {observer} from 'mobx-react-lite';
import type React from 'react';
import {
getCountdownTimerOptions,
getGiftDurationOptions,
getMatureContentChannelGateOptions,
getMatureContentMediaGateOptions,
getRequiredActionModeOptions,
getRequiredActionPhoneStepOptions,
getRequiredActionResendOutcomeOptions,
getRequiredActionTabOptions,
getVerificationBarrierOptions,
} from './OptionPresets';
import {updateOption} from './ResetOptions';
const VERIFICATION_MEMBERSHIP_BARRIERS_DESCRIPTOR = msg({
message: 'Verification & membership barriers',
@@ -1,5 +1,9 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
import {
getNagbarActionItems,
NAGBAR_OVERRIDES_DESCRIPTOR,
} from '@app/features/channel/components/channel_header_components/developer_tools/NagbarControls';
import {getNagbarControls, type NagbarControlDefinition} from '@app/features/devtools/components/NagbarControls';
import {remFromPx} from '@app/features/theme/layout/RemFromPx';
import {MenuItem} from '@app/features/ui/action_menu/MenuItem';
@@ -10,7 +14,6 @@ import {Trans, useLingui} from '@lingui/react/macro';
import {TrashIcon} from '@phosphor-icons/react';
import {observer} from 'mobx-react-lite';
import type React from 'react';
import {getNagbarActionItems, NAGBAR_OVERRIDES_DESCRIPTOR} from './NagbarControls';
const NagbarOverrideSubmenu: React.FC<{control: NagbarControlDefinition}> = observer(({control}) => {
const {i18n} = useLingui();
@@ -5,12 +5,15 @@ import {
type RadioMenuOption,
USE_ACTUAL_VALUE_DESCRIPTOR,
} from '@app/features/channel/components/channel_header_components/developer_tools/DeveloperToolsShared';
import {
formatDurationMs,
NO_TIMER_DESCRIPTOR,
} from '@app/features/channel/components/channel_header_components/developer_tools/FormatHelpers';
import type {DeveloperOptionsState} from '@app/features/devtools/state/DeveloperOptions';
import {EMAIL_DESCRIPTOR} from '@app/features/i18n/utils/CommonMessageDescriptors';
import {UserPremiumTypes} from '@fluxer/constants/src/UserConstants';
import type {I18n} from '@lingui/core';
import {msg} from '@lingui/core/macro';
import {formatDurationMs, NO_TIMER_DESCRIPTOR} from './FormatHelpers';
export const SUBSCRIPTION_DESCRIPTOR = msg({
message: 'Subscription',
@@ -1,5 +1,6 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
import {getActiveDeveloperOptionEntries} from '@app/features/channel/components/channel_header_components/developer_tools/DeveloperOptionLabels';
import {
ActiveOverrideMenuGroup,
BackendPremiumOverrideMenuGroup,
@@ -10,6 +11,8 @@ import {
humanizeDeveloperStateKey,
nonEmptyText,
} from '@app/features/channel/components/channel_header_components/developer_tools/DeveloperToolsShared';
import {setNagbarUseActual} from '@app/features/channel/components/channel_header_components/developer_tools/NagbarControls';
import {resetAllDeveloperOptions} from '@app/features/channel/components/channel_header_components/developer_tools/ResetOptions';
import {getNagbarControls} from '@app/features/devtools/components/NagbarControls';
import * as PremiumCommands from '@app/features/premium/commands/PremiumCommands';
import {remFromPx} from '@app/features/theme/layout/RemFromPx';
@@ -24,9 +27,6 @@ import {Trans, useLingui} from '@lingui/react/macro';
import {BellRingingIcon, TrashIcon, WarningCircleIcon} from '@phosphor-icons/react';
import {observer} from 'mobx-react-lite';
import type React from 'react';
import {getActiveDeveloperOptionEntries} from './DeveloperOptionLabels';
import {setNagbarUseActual} from './NagbarControls';
import {resetAllDeveloperOptions} from './ResetOptions';
const NO_ACTIVE_OVERRIDES_DESCRIPTOR = msg({
message: 'No active overrides',
@@ -1,9 +1,13 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
import {
buildCsvTableNode,
isCsvAttachment,
parseCsvRows,
} from '@app/features/channel/components/embeds/attachments/CsvAttachmentPreviewUtils';
import {TableAlignment} from '@app/features/messaging/utils/markdown/parser/Enums';
import type {MessageAttachment} from '@fluxer/schema/src/domains/message/MessageResponseSchemas';
import {describe, expect, it} from 'vitest';
import {buildCsvTableNode, isCsvAttachment, parseCsvRows} from './CsvAttachmentPreviewUtils';
function attachmentFixture(fields: Partial<MessageAttachment>): MessageAttachment {
return fields as MessageAttachment;
@@ -1,12 +1,12 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
import {describe, expect, it} from 'vitest';
import {
getEffectiveVideoLayoutDimensions,
hasDifferentAspectRatio,
isInlinePlayableVideoSize,
resolveVideoLayout,
} from './VideoDimensionUtils';
} from '@app/features/channel/components/embeds/media/VideoDimensionUtils';
import {describe, expect, it} from 'vitest';
describe('getEffectiveVideoLayoutDimensions', () => {
it('prefers decoded dimensions over declared upload dimensions', () => {
@@ -1,7 +1,10 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
import {
type FavoriteGifEntry,
slimFavoriteGifEntry,
} from '@app/features/channel/components/pickers/gif/FavoriteGifTypes';
import {describe, expect, it} from 'vitest';
import {type FavoriteGifEntry, slimFavoriteGifEntry} from './FavoriteGifTypes';
function format(src: string, width: number) {
return {src, proxy_src: `https://media.test/external/sig/${src}`, width, height: Math.round(width * 0.84)};
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
import {buildGifPickerGridData} from '@app/features/channel/components/pickers/gif/GifPickerGridData';
import {bench, describe} from 'vitest';
import {buildGifPickerGridData} from './GifPickerGridData';
function gif(index: number, width = 200 + (index % 80), height = 120 + (index % 160)) {
return {
@@ -1,9 +1,9 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
import type {FavoriteGifEntry} from '@app/features/channel/components/pickers/gif/FavoriteGifTypes';
import {buildGifPickerGridData} from '@app/features/channel/components/pickers/gif/GifPickerGridData';
import type {FavoriteAwareGif} from '@app/features/channel/components/pickers/gif/GifPickerTypes';
import {describe, expect, it} from 'vitest';
import type {FavoriteGifEntry} from './FavoriteGifTypes';
import {buildGifPickerGridData} from './GifPickerGridData';
import type {FavoriteAwareGif} from './GifPickerTypes';
function gif(id: string, width = 200, height = 120): FavoriteAwareGif {
return {
@@ -1,9 +1,9 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
import styles from '@app/features/channel/components/GifPicker.module.css';
import {buildGifPickerLoadingSkeletonLayout} from '@app/features/channel/components/pickers/gif/GifPickerLoadingSkeletonGridLayout';
import {motion, useReducedMotion} from 'framer-motion';
import {useLayoutEffect, useMemo, useRef, useState} from 'react';
import {buildGifPickerLoadingSkeletonLayout} from './GifPickerLoadingSkeletonGridLayout';
interface SkeletonViewportSize {
width: number;
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
import {buildGifPickerLoadingSkeletonLayout} from '@app/features/channel/components/pickers/gif/GifPickerLoadingSkeletonGridLayout';
import {bench, describe} from 'vitest';
import {buildGifPickerLoadingSkeletonLayout} from './GifPickerLoadingSkeletonGridLayout';
const VIEWPORTS = [
{viewportWidth: 360, viewportHeight: 480},
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
import {buildGifPickerLoadingSkeletonLayout} from '@app/features/channel/components/pickers/gif/GifPickerLoadingSkeletonGridLayout';
import {describe, expect, it} from 'vitest';
import {buildGifPickerLoadingSkeletonLayout} from './GifPickerLoadingSkeletonGridLayout';
describe('buildGifPickerLoadingSkeletonLayout', () => {
it('lays out GIF-like placeholders with the same masonry constraints as the real grid', () => {
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
import {resolvesToVideo} from '@app/features/channel/components/pickers/gif/GifPickerMediaKind';
import {describe, expect, it} from 'vitest';
import {resolvesToVideo} from './GifPickerMediaKind';
const OPAQUE_PROXY_SRC =
'https://media.test/external/sig/v2/aHR0cHM6Ly9zdGF0aWMua2xpcHkuY29tL2lpLzhjLzZhL2E4LzVsU2U1SFBCLndlYm0';
@@ -1,12 +1,12 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
import {bench, describe} from 'vitest';
import {
createGifPickerRequestId,
createGifPickerSnapshot,
selectGifPickerModel,
transitionGifPickerSnapshot,
} from './GifPickerStateMachine';
} from '@app/features/channel/components/pickers/gif/GifPickerStateMachine';
import {bench, describe} from 'vitest';
const SEARCH_TERMS = Array.from({length: 1_000}, (_, index) => `query-${index}`);
@@ -1,12 +1,12 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
import {describe, expect, it} from 'vitest';
import {
createGifPickerRequestId,
createGifPickerSnapshot,
selectGifPickerModel,
transitionGifPickerSnapshot,
} from './GifPickerStateMachine';
} from '@app/features/channel/components/pickers/gif/GifPickerStateMachine';
import {describe, expect, it} from 'vitest';
describe('GifPickerStateMachine', () => {
it('starts on the featured surface without showing a loading state', () => {
@@ -1,11 +1,11 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
import {describe, expect, it} from 'vitest';
import {
CHANNEL_SEARCH_INDEXING_INITIAL_POLL_INTERVAL_MS,
CHANNEL_SEARCH_INDEXING_MAX_POLL_INTERVAL_MS,
getChannelSearchIndexingPollInterval,
} from './ChannelSearchPolling';
} from '@app/features/channel/utils/ChannelSearchPolling';
import {describe, expect, it} from 'vitest';
describe('getChannelSearchIndexingPollInterval', () => {
it('starts with a short retry interval for newly indexing channels', () => {
@@ -2,10 +2,9 @@
import type {DiscoveryGuild, DiscoverySearchResponse} from '@app/features/discovery/commands/DiscoveryCommands';
import * as DiscoveryCommands from '@app/features/discovery/commands/DiscoveryCommands';
import Discovery from '@app/features/discovery/state/Discovery';
import {beforeEach, describe, expect, test, vi} from 'vitest';
import Discovery from './Discovery';
vi.mock('@app/features/discovery/commands/DiscoveryCommands', () => ({
searchGuilds: vi.fn(),
getCategories: vi.fn(),
@@ -1,8 +1,8 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
import {createEmojiSearchIndex} from '@app/features/emoji/state/EmojiSearchIndex';
import type {FlatEmoji} from '@app/features/emoji/types/EmojiTypes';
import {bench, describe} from 'vitest';
import {createEmojiSearchIndex} from './EmojiSearchIndex';
const EMOJI_COUNT = 20_000;
const QUERY_COUNT = 1_000;
@@ -1,8 +1,8 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
import {createEmojiSearchIndex} from '@app/features/emoji/state/EmojiSearchIndex';
import type {FlatEmoji} from '@app/features/emoji/types/EmojiTypes';
import {describe, expect, test} from 'vitest';
import {createEmojiSearchIndex} from './EmojiSearchIndex';
function emoji(name: string, options: Partial<FlatEmoji> = {}): FlatEmoji {
return {
@@ -1,13 +1,13 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
import {describe, expect, it} from 'vitest';
import {
clampWideAssetAspectRatio,
getAspectRatioRange,
isAspectRatioInRange,
isOriginalImageWithinAssetBounds,
WIDE_ASSET_ASPECT_RATIO_RANGE,
} from './AssetImageGeometry';
} from '@app/features/expressions/utils/AssetImageGeometry';
import {describe, expect, it} from 'vitest';
describe('AssetImageGeometry', () => {
it('builds the flexible wide asset range from the crop height limits', () => {
@@ -1,8 +1,12 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
import {isAnimatedFile} from '@app/features/expressions/utils/AnimatedImageUtils';
import {
isSvgFile,
readBlobAsBase64NoPrefix,
readImageFileAsUploadDataUrl,
} from '@app/features/expressions/utils/ImageUploadFileUtils';
import {EMOJI_MAX_SIZE, STICKER_MAX_SIZE} from '@fluxer/constants/src/LimitConstants';
import {isAnimatedFile} from './AnimatedImageUtils';
import {isSvgFile, readBlobAsBase64NoPrefix, readImageFileAsUploadDataUrl} from './ImageUploadFileUtils';
const EMOJI_MAX_SIZE_FALLBACK = EMOJI_MAX_SIZE;
const STICKER_MAX_SIZE_FALLBACK = STICKER_MAX_SIZE;
@@ -1,7 +1,12 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
import {
getImageUploadMimeType,
isSvgFile,
isSvgMimeType,
normalizeImageMimeType,
} from '@app/features/expressions/utils/ImageUploadFileUtils';
import {describe, expect, it} from 'vitest';
import {getImageUploadMimeType, isSvgFile, isSvgMimeType, normalizeImageMimeType} from './ImageUploadFileUtils';
describe('ImageUploadFileUtils', () => {
it('normalizes image MIME type parameters', () => {
@@ -1,8 +1,8 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
import {selectGuildActivationTarget} from '@app/features/gateway/transport/GuildActivationTarget';
import {FAVORITES_GUILD_ID} from '@fluxer/constants/src/AppConstants';
import {describe, expect, it} from 'vitest';
import {selectGuildActivationTarget} from './GuildActivationTarget';
describe('selectGuildActivationTarget', () => {
it('returns the selected guild on a guild route', () => {
@@ -1,8 +1,8 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
import {createRoleMovePreview} from '@app/features/guild/components/modals/guild_tabs/RoleMoveOperation';
import type {GuildRole} from '@app/features/guild/models/GuildRole';
import {describe, expect, it} from 'vitest';
import {createRoleMovePreview} from './RoleMoveOperation';
const guildId = 'guild-1';
@@ -1,15 +1,15 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
import type {GuildRole} from '@app/features/guild/models/GuildRole';
import {describe, expect, it} from 'vitest';
import {createRoleMovePreview} from './RoleMoveOperation';
import {createRoleMovePreview} from '@app/features/guild/components/modals/guild_tabs/RoleMoveOperation';
import {
type RoleReorderAccess,
type RoleReorderDragItem,
type RoleReorderRect,
type RoleReorderTarget,
selectRoleReorderResolution,
} from './RoleReorderStateMachine';
} from '@app/features/guild/components/modals/guild_tabs/RoleReorderStateMachine';
import type {GuildRole} from '@app/features/guild/models/GuildRole';
import {describe, expect, it} from 'vitest';
const guildId = 'guild-1';
const rect: RoleReorderRect = {
@@ -1,6 +1,5 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
import {describe, expect, it} from 'vitest';
import {
canRoleDropOnTarget,
createRoleReorderSnapshot,
@@ -12,7 +11,8 @@ import {
resolveRoleReorderHover,
selectRoleReorderIntent,
transitionRoleReorderSnapshot,
} from './RoleReorderStateMachine';
} from '@app/features/guild/components/modals/guild_tabs/RoleReorderStateMachine';
import {describe, expect, it} from 'vitest';
const rect: RoleReorderRect = {
top: 20,
@@ -1,14 +1,14 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
import {MessageNotifications} from '@fluxer/constants/src/NotificationConstants';
import {describe, expect, it} from 'vitest';
import {
createGuildReadStateContributionSnapshot,
type GuildReadStateContributionInput,
resolveGuildReadStateContribution,
selectGuildReadStateContribution,
transitionGuildReadStateContributionSnapshot,
} from './GuildReadStateContributionMachine';
} from '@app/features/guild/state/GuildReadStateContributionMachine';
import {MessageNotifications} from '@fluxer/constants/src/NotificationConstants';
import {describe, expect, it} from 'vitest';
function input(overrides: Partial<GuildReadStateContributionInput> = {}): GuildReadStateContributionInput {
return {
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
import {resolveGuildModerationCapabilities} from '@app/features/guild/utils/GuildModerationCapabilityUtils';
import {describe, expect, it} from 'vitest';
import {resolveGuildModerationCapabilities} from './GuildModerationCapabilityUtils';
describe('resolveGuildModerationCapabilities', () => {
const baseOptions = {
@@ -1,13 +1,13 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
import type {GlobalKeyEvent} from '@app/features/platform/types/Electron';
import {describe, expect, it} from 'vitest';
import {
beginGlobalKeyCapture,
type GlobalKeyCaptureApi,
globalKeyEventToCombo,
isGlobalKeyEventModifierKey,
} from './KeybindRecorderCapture';
} from '@app/features/input/components/KeybindRecorderCapture';
import type {GlobalKeyEvent} from '@app/features/platform/types/Electron';
import {describe, expect, it} from 'vitest';
const keyEvent = (event: Partial<GlobalKeyEvent>): GlobalKeyEvent => ({
type: 'keydown',
@@ -82,6 +82,16 @@ import {
ZOOM_IN_DESCRIPTOR,
ZOOM_OUT_DESCRIPTOR,
} from '@app/features/input/state/input_keybind/shared';
import {
getActiveCombosForResolvedAction,
getDisplayKeybindForResolvedAction,
} from '@app/features/input/state/KeybindResolution';
import {
DEFAULT_KEYBOARD_SHORTCUTS_OVERLAY_COMBO,
getKeyboardShortcutsOverlayComboForCurrentLayout,
keyCombosEqual,
SHIFTED_SLASH_FALLBACK_KEYBOARD_SHORTCUTS_OVERLAY_COMBO,
} from '@app/features/input/utils/KeyboardShortcutLayoutUtils';
import AppStorage from '@app/features/platform/state/PersistentStorage';
import {awaitHydration, makePersistent} from '@app/features/platform/utils/MobXPersistence';
import {makeSyncedField} from '@app/features/user/state/SyncedField';
@@ -97,13 +107,6 @@ import {
} from '@fluxer/schema/src/gen/fluxer/user/preferences/v1/preferences_pb';
import type {I18n} from '@lingui/core';
import {makeAutoObservable, runInAction} from 'mobx';
import {
DEFAULT_KEYBOARD_SHORTCUTS_OVERLAY_COMBO,
getKeyboardShortcutsOverlayComboForCurrentLayout,
keyCombosEqual,
SHIFTED_SLASH_FALLBACK_KEYBOARD_SHORTCUTS_OVERLAY_COMBO,
} from '../utils/KeyboardShortcutLayoutUtils';
import {getActiveCombosForResolvedAction, getDisplayKeybindForResolvedAction} from './KeybindResolution';
const KEYBIND_STORE_NAME = 'Keybind';
const KEYBIND_COMMAND_VALUES = [
@@ -1,8 +1,11 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
import type {CustomKeybindEntry, KeybindCommand, KeybindConfig, KeyCombo} from '@app/features/input/state/InputKeybind';
import {
getActiveCombosForResolvedAction,
getDisplayKeybindForResolvedAction,
} from '@app/features/input/state/KeybindResolution';
import {describe, expect, it} from 'vitest';
import type {CustomKeybindEntry, KeybindCommand, KeybindConfig, KeyCombo} from './InputKeybind';
import {getActiveCombosForResolvedAction, getDisplayKeybindForResolvedAction} from './KeybindResolution';
const action: KeybindCommand = 'voice_toggle_deafen';
const keybind = (combo: KeyCombo, overrides: Partial<KeybindConfig> = {}): KeybindConfig => ({
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
import type {CustomKeybindEntry, KeybindConfig, KeyCombo} from './InputKeybind';
import type {CustomKeybindEntry, KeybindConfig, KeyCombo} from '@app/features/input/state/InputKeybind';
export const keyComboHasTriggerInput = (combo: KeyCombo): boolean =>
(combo.key ?? '') !== '' || (combo.code ?? '') !== '' || combo.mouseButton != null || combo.gamepadButton != null;
@@ -12,7 +12,6 @@ import type {MentionSegment} from '@app/features/messaging/utils/TextareaSegment
import {resolveTypedEmojiToken} from '@app/features/messaging/utils/TypedEmojiShortcodeUtils';
import {flxElementClassName} from '@app/lib/react';
import type {I18n} from '@lingui/core';
import type React from 'react';
import {useCallback, useId, useImperativeHandle, useRef, useState} from 'react';
@@ -1,14 +1,14 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
import {MEMBER_LIST_RANGE_MAX_END} from '@fluxer/constants/src/GatewayConstants';
import {describe, expect, it} from 'vitest';
import {
createMemberListViewportSnapshot,
getMemberListViewportStateValue,
resolveMemberListViewportModel,
selectMemberListViewportModel,
transitionMemberListViewportSnapshot,
} from './MemberListViewportStateMachine';
} from '@app/features/member/state/MemberListViewportStateMachine';
import {MEMBER_LIST_RANGE_MAX_END} from '@fluxer/constants/src/GatewayConstants';
import {describe, expect, it} from 'vitest';
const INITIAL_RANGE: Array<[number, number]> = [[0, 99]];
@@ -1,6 +1,5 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
import {bench, describe} from 'vitest';
import {
areMemberListRangesCovered,
areMemberListRangesEqual,
@@ -9,7 +8,8 @@ import {
buildMemberListRangeWindow,
buildMemberListRenderWindow,
normalizeMemberListRanges,
} from './MemberListRangeUtils';
} from '@app/features/member/utils/MemberListRangeUtils';
import {bench, describe} from 'vitest';
const ROW_HEIGHT = 44;
const VIEWPORT_HEIGHT = ROW_HEIGHT * 18;
@@ -1,7 +1,5 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
import {MEMBER_LIST_RANGE_MAX_SPAN} from '@fluxer/constants/src/GatewayConstants';
import {describe, expect, it} from 'vitest';
import {
areMemberListRangesCovered,
areMemberListRangesEqual,
@@ -10,7 +8,9 @@ import {
buildMemberListRangeWindow,
buildMemberListRenderWindow,
normalizeMemberListRanges,
} from './MemberListRangeUtils';
} from '@app/features/member/utils/MemberListRangeUtils';
import {MEMBER_LIST_RANGE_MAX_SPAN} from '@fluxer/constants/src/GatewayConstants';
import {describe, expect, it} from 'vitest';
describe('MemberListRangeUtils', () => {
it('compares ranges after normalization and page splitting', () => {
@@ -1,6 +1,5 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
import {describe, expect, it} from 'vitest';
import {
createMessageFetchExecutionSnapshot,
createMessageFetchPreflightSnapshot,
@@ -13,7 +12,8 @@ import {
selectMessageFetchPreflightDecision,
transitionMessageFetchExecutionSnapshot,
transitionMessageFetchPreflightSnapshot,
} from './MessageFetchStateMachine';
} from '@app/features/messaging/commands/MessageFetchStateMachine';
import {describe, expect, it} from 'vitest';
function preflight(overrides: Partial<MessageFetchPreflightInput> = {}): MessageFetchPreflightInput {
return {
@@ -1,13 +1,13 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
import {describe, expect, it} from 'vitest';
import {
createMessagePageStateSnapshot,
type MessagePageStateInput,
resolveMessagePageState,
selectMessagePageState,
transitionMessagePageStateSnapshot,
} from './MessagePageStateMachine';
} from '@app/features/messaging/commands/MessagePageStateMachine';
import {describe, expect, it} from 'vitest';
function input(overrides: Partial<MessagePageStateInput> = {}): MessagePageStateInput {
return {
@@ -1,10 +1,10 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
import type {MarkdownParseOptions} from '@app/features/messaging/components/markdown/renderers/RendererTypes';
import {MarkdownContext} from '@app/features/messaging/components/markdown/renderers/RendererTypes';
import {parseMarkdownContent as parse} from '@app/features/messaging/utils/markdown/MarkdownParseCache';
import type {Node} from '@app/features/messaging/utils/markdown/parser/Nodes';
import {bench, describe} from 'vitest';
import {MarkdownContext} from './renderers/RendererTypes';
const SIMPLE_CONTENT = 'hello **world** with <@1234567890> and https://fluxer.app';
const RICH_CONTENT = [
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
import {shouldNavigateAfterForward} from '@app/features/messaging/components/modals/ForwardModalUtils';
import {describe, expect, it} from 'vitest';
import {shouldNavigateAfterForward} from './ForwardModalUtils';
describe('ForwardModal', () => {
it('navigates only for an unmodified single-destination forward', () => {
@@ -1,6 +1,5 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
import {describe, expect, it} from 'vitest';
import {
getNearestDefaultRotationDegrees,
isDefaultRotationDegrees,
@@ -8,7 +7,8 @@ import {
normalizeRotationDegrees,
rotateAnticlockwiseDegrees,
rotateClockwiseDegrees,
} from './MediaRotationMath';
} from '@app/features/messaging/components/modals/media_modal/MediaRotationMath';
import {describe, expect, it} from 'vitest';
describe('MediaRotationMath', () => {
it('keeps clockwise animation continuous through a full turn', () => {
@@ -1,6 +1,5 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
import {describe, expect, it} from 'vitest';
import {
clampPanForScale,
clampScale,
@@ -12,7 +11,8 @@ import {
MIN_ZOOM_SCALE,
type PanZoomMetrics,
TAP_MOVE_THRESHOLD,
} from './PanZoomMath';
} from '@app/features/messaging/components/modals/media_modal/pan_zoom/PanZoomMath';
import {describe, expect, it} from 'vitest';
const METRICS: PanZoomMetrics = {
viewportWidth: 800,
@@ -1,12 +1,16 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
import styles from '@app/features/messaging/components/modals/media_modal/pan_zoom/PanZoomSurface.module.css';
import {
type PanZoomTransformSnapshot,
type UsePanZoomSurfaceOptions,
usePanZoomSurface,
} from '@app/features/messaging/components/modals/media_modal/pan_zoom/usePanZoomSurface';
import type {ZoomState} from '@app/features/messaging/components/modals/media_modal/shared';
import {clsx} from 'clsx';
import {motion} from 'framer-motion';
import type {CSSProperties, HTMLAttributes, ReactNode} from 'react';
import {forwardRef, memo, useImperativeHandle} from 'react';
import styles from './PanZoomSurface.module.css';
import {type PanZoomTransformSnapshot, type UsePanZoomSurfaceOptions, usePanZoomSurface} from './usePanZoomSurface';
export interface PanZoomSurfaceHandle {
reset: () => void;
@@ -1,11 +1,5 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
import type {ZoomState} from '@app/features/messaging/components/modals/media_modal/shared';
import {wasPointerDownInside} from '@app/lib/overlay/DismissGuard';
import type {AnimationPlaybackControls, MotionValue} from 'framer-motion';
import {animate, useMotionValue, useReducedMotion} from 'framer-motion';
import type React from 'react';
import {useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState} from 'react';
import {
clampPanForScale,
clampScale,
@@ -22,8 +16,14 @@ import {
TAP_MOVE_THRESHOLD,
ZOOM_STATE_EPSILON,
ZOOM_STEP,
} from './PanZoomMath';
import {useLatestRef} from './useLatestRef';
} from '@app/features/messaging/components/modals/media_modal/pan_zoom/PanZoomMath';
import {useLatestRef} from '@app/features/messaging/components/modals/media_modal/pan_zoom/useLatestRef';
import type {ZoomState} from '@app/features/messaging/components/modals/media_modal/shared';
import {wasPointerDownInside} from '@app/lib/overlay/DismissGuard';
import type {AnimationPlaybackControls, MotionValue} from 'framer-motion';
import {animate, useMotionValue, useReducedMotion} from 'framer-motion';
import type React from 'react';
import {useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState} from 'react';
interface PointerRecord extends Point {
pointerId: number;
@@ -1,13 +1,13 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
import {describe, expect, it} from 'vitest';
import {
type ChannelIncomingMessageInput,
createChannelIncomingMessageSnapshot,
resolveChannelIncomingMessageDecision,
selectChannelIncomingMessageDecision,
transitionChannelIncomingMessageSnapshot,
} from './ChannelIncomingMessageStateMachine';
} from '@app/features/messaging/state/ChannelIncomingMessageStateMachine';
import {describe, expect, it} from 'vitest';
function input(overrides: Partial<ChannelIncomingMessageInput> = {}): ChannelIncomingMessageInput {
return {
@@ -1,6 +1,5 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
import {describe, expect, it} from 'vitest';
import {
type ChannelMessagesLoadInput,
type ChannelMessagesWindowInput,
@@ -17,7 +16,8 @@ import {
selectChannelMessagesWindowStatus,
transitionChannelMessagesLoadSnapshot,
transitionChannelMessagesWindowSnapshot,
} from './ChannelMessagesLoadStateMachine';
} from '@app/features/messaging/state/ChannelMessagesLoadStateMachine';
import {describe, expect, it} from 'vitest';
function input(overrides: Partial<ChannelMessagesLoadInput> = {}): ChannelMessagesLoadInput {
return {
@@ -1,6 +1,5 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
import {describe, expect, it} from 'vitest';
import {
createMessageLocalSendRateLimitSnapshot,
createMessageQueuePayloadRouteSnapshot,
@@ -19,7 +18,8 @@ import {
transitionMessageQueuePayloadRouteSnapshot,
transitionMessageQueueRequestOutcomeSnapshot,
transitionMessageQueueSendExecutionSnapshot,
} from './MessageQueueStateMachine';
} from '@app/features/messaging/state/MessageQueueStateMachine';
import {describe, expect, it} from 'vitest';
function localLimiter(overrides: Partial<MessageLocalSendRateLimitInput> = {}): MessageLocalSendRateLimitInput {
return {
@@ -1,13 +1,13 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
import type {ReactionEmoji} from '@app/features/messaging/utils/ReactionUtils';
import {bench, describe} from 'vitest';
import {
createReactionMachineSnapshot,
emptyMap,
mapToReactions,
transitionReactionSnapshot,
} from './ReactionStateMachine';
} from '@app/features/messaging/state/ReactionStateMachine';
import type {ReactionEmoji} from '@app/features/messaging/utils/ReactionUtils';
import {bench, describe} from 'vitest';
const EMOJIS: Array<ReactionEmoji> = Array.from({length: 32}, (_value, index) => ({
id: index % 3 === 0 ? `emoji-${index}` : undefined,
@@ -1,7 +1,5 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
import type {ReactionEmoji} from '@app/features/messaging/utils/ReactionUtils';
import {describe, expect, it} from 'vitest';
import {
applyAdd,
applyRemove,
@@ -21,7 +19,9 @@ import {
transitionReactionMap,
transitionReactionSnapshot,
untrackReactor,
} from './ReactionStateMachine';
} from '@app/features/messaging/state/ReactionStateMachine';
import type {ReactionEmoji} from '@app/features/messaging/utils/ReactionUtils';
import {describe, expect, it} from 'vitest';
const ME = 'me-user-id';
const ALICE = 'alice-id';
@@ -1,8 +1,8 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
import {filterViewableChannels, pickDefaultGuildChannelId} from '@app/features/messaging/utils/ChannelShared';
import {ChannelTypes} from '@fluxer/constants/src/ChannelConstants';
import {describe, expect, it} from 'vitest';
import {filterViewableChannels, pickDefaultGuildChannelId} from './ChannelShared';
describe('filterViewableChannels', () => {
it('excludes link channels from default navigation fallbacks', () => {
@@ -1,10 +1,9 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
import * as CodeLinkUtils from '@app/features/messaging/utils/CodeLinkUtils';
import {extractEmbeddableCodeLinkContent} from '@app/features/messaging/utils/EmbeddableCodeLinkContent';
import {describe, expect, it} from 'vitest';
import {extractEmbeddableCodeLinkContent} from './EmbeddableCodeLinkContent';
const TEST_LINK_CONFIG: CodeLinkUtils.CodeLinkConfig = {
path: 'invite',
urlBases: ['https://fluxer.app/invite'],
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
import {isEmbeddableImageFile} from '@app/features/messaging/utils/EmbeddableImageTypes';
import {describe, expect, it} from 'vitest';
import {isEmbeddableImageFile} from './EmbeddableImageTypes';
describe('isEmbeddableImageFile', () => {
it('embeds common raster image mime types', () => {
@@ -1,13 +1,13 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
import {describe, expect, it} from 'vitest';
import {
getScaledMediaDimensions,
hasRenderableLocalPreview,
LOCAL_MEDIA_PREVIEW_MAX_BYTES,
shouldEagerlyPreviewLocalImage,
shouldEagerlyPreviewLocalVideo,
} from './LocalAttachmentPreviewUtils';
} from '@app/features/messaging/utils/LocalAttachmentPreviewUtils';
import {describe, expect, it} from 'vitest';
describe('Local attachment preview utils', () => {
it('allows eager image previews at or below the local preview size cap', () => {
@@ -1,12 +1,12 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
import AdvancedSettings from '@app/features/user/state/AdvancedSettings';
import {afterEach, describe, expect, it} from 'vitest';
import {
buildExistingAttachmentEditReferences,
canSubmitEmptyMessageEdit,
isAttachmentOnlyMessage,
} from './MessageEditContentUtils';
} from '@app/features/messaging/utils/MessageEditContentUtils';
import AdvancedSettings from '@app/features/user/state/AdvancedSettings';
import {afterEach, describe, expect, it} from 'vitest';
describe('Message edit content utils', () => {
afterEach(() => {
Loaded 100 of 1834 files, more files were not shown because too many files have changed in this diff. Show more