Page MenuHomePhorge

D6692.1765293242.diff
No OneTemporary

Size
905 KB
Referenced Files
None
Subscribers
None

D6692.1765293242.diff

This file is larger than 256 KB, so syntax highlighting was skipped.
diff --git a/desktop/src/main.js b/desktop/src/main.js
--- a/desktop/src/main.js
+++ b/desktop/src/main.js
@@ -12,8 +12,8 @@
import fs from 'fs';
import path from 'path';
-import { initAutoUpdate } from './auto-update';
-import { handleSquirrelEvent } from './handle-squirrel-event';
+import { initAutoUpdate } from './auto-update.js';
+import { handleSquirrelEvent } from './handle-squirrel-event.js';
const isDev = process.env.ENV === 'dev';
const url = isDev ? 'http://localhost/comm/' : 'https://web.comm.app';
diff --git a/desktop/src/preload.js b/desktop/src/preload.js
--- a/desktop/src/preload.js
+++ b/desktop/src/preload.js
@@ -2,7 +2,7 @@
import { contextBridge, ipcRenderer } from 'electron/renderer';
-import type { ElectronBridge } from 'lib/types/electron-types';
+import type { ElectronBridge } from 'lib/types/electron-types.js';
const bridge: ElectronBridge = {
onNavigate: callback => {
diff --git a/keyserver/src/bots/commbot.js b/keyserver/src/bots/commbot.js
--- a/keyserver/src/bots/commbot.js
+++ b/keyserver/src/bots/commbot.js
@@ -2,11 +2,11 @@
import invariant from 'invariant';
-import bots from 'lib/facts/bots';
-import { threadTypes } from 'lib/types/thread-types';
+import bots from 'lib/facts/bots.js';
+import { threadTypes } from 'lib/types/thread-types.js';
-import { createThread } from '../creators/thread-creator';
-import { createBotViewer } from '../session/bots';
+import { createThread } from '../creators/thread-creator.js';
+import { createBotViewer } from '../session/bots.js';
const { commbot } = bots;
diff --git a/keyserver/src/creators/account-creator.js b/keyserver/src/creators/account-creator.js
--- a/keyserver/src/creators/account-creator.js
+++ b/keyserver/src/creators/account-creator.js
@@ -3,52 +3,52 @@
import invariant from 'invariant';
import bcrypt from 'twin-bcrypt';
-import ashoat from 'lib/facts/ashoat';
-import bots from 'lib/facts/bots';
-import genesis from 'lib/facts/genesis';
+import ashoat from 'lib/facts/ashoat.js';
+import bots from 'lib/facts/bots.js';
+import genesis from 'lib/facts/genesis.js';
import { policyTypes } from 'lib/facts/policies.js';
import {
validUsernameRegex,
oldValidUsernameRegex,
-} from 'lib/shared/account-utils';
-import { hasMinCodeVersion } from 'lib/shared/version-utils';
+} from 'lib/shared/account-utils.js';
+import { hasMinCodeVersion } from 'lib/shared/version-utils.js';
import type {
RegisterResponse,
RegisterRequest,
-} from 'lib/types/account-types';
+} from 'lib/types/account-types.js';
import type {
PlatformDetails,
DeviceTokenUpdateRequest,
} from 'lib/types/device-types.js';
import type { CalendarQuery } from 'lib/types/entry-types.js';
-import { messageTypes } from 'lib/types/message-types';
+import { messageTypes } from 'lib/types/message-types.js';
import type { SIWESocialProof } from 'lib/types/siwe-types.js';
-import { threadTypes } from 'lib/types/thread-types';
-import { ServerError } from 'lib/utils/errors';
-import { values } from 'lib/utils/objects';
-import { reservedUsernamesSet } from 'lib/utils/reserved-users';
+import { threadTypes } from 'lib/types/thread-types.js';
+import { ServerError } from 'lib/utils/errors.js';
+import { values } from 'lib/utils/objects.js';
+import { reservedUsernamesSet } from 'lib/utils/reserved-users.js';
import { isValidEthereumAddress } from 'lib/utils/siwe-utils.js';
-import { dbQuery, SQL } from '../database/database';
-import { deleteCookie } from '../deleters/cookie-deleters';
-import { fetchThreadInfos } from '../fetchers/thread-fetchers';
+import { dbQuery, SQL } from '../database/database.js';
+import { deleteCookie } from '../deleters/cookie-deleters.js';
+import { fetchThreadInfos } from '../fetchers/thread-fetchers.js';
import {
fetchLoggedInUserInfo,
fetchKnownUserInfos,
-} from '../fetchers/user-fetchers';
-import { verifyCalendarQueryThreadIDs } from '../responders/entry-responders';
-import { createNewUserCookie, setNewSession } from '../session/cookies';
-import { createScriptViewer } from '../session/scripts';
-import type { Viewer } from '../session/viewer';
-import { updateThread } from '../updaters/thread-updaters';
+} from '../fetchers/user-fetchers.js';
+import { verifyCalendarQueryThreadIDs } from '../responders/entry-responders.js';
+import { createNewUserCookie, setNewSession } from '../session/cookies.js';
+import { createScriptViewer } from '../session/scripts.js';
+import type { Viewer } from '../session/viewer.js';
+import { updateThread } from '../updaters/thread-updaters.js';
import { viewerAcknowledgmentUpdater } from '../updaters/viewer-acknowledgment-updater.js';
-import createIDs from './id-creator';
-import createMessages from './message-creator';
+import createIDs from './id-creator.js';
+import createMessages from './message-creator.js';
import {
createThread,
createPrivateThread,
privateThreadDescription,
-} from './thread-creator';
+} from './thread-creator.js';
const { commbot } = bots;
diff --git a/keyserver/src/creators/day-creator.js b/keyserver/src/creators/day-creator.js
--- a/keyserver/src/creators/day-creator.js
+++ b/keyserver/src/creators/day-creator.js
@@ -1,9 +1,9 @@
// @flow
-import { ServerError } from 'lib/utils/errors';
+import { ServerError } from 'lib/utils/errors.js';
-import { dbQuery, SQL } from '../database/database';
-import createIDs from './id-creator';
+import { dbQuery, SQL } from '../database/database.js';
+import createIDs from './id-creator.js';
const MYSQL_DUPLICATE_ENTRY_FOR_KEY_ERROR_CODE = 1062;
diff --git a/keyserver/src/creators/entry-creator.js b/keyserver/src/creators/entry-creator.js
--- a/keyserver/src/creators/entry-creator.js
+++ b/keyserver/src/creators/entry-creator.js
@@ -5,24 +5,24 @@
import type {
CreateEntryRequest,
SaveEntryResponse,
-} from 'lib/types/entry-types';
-import { messageTypes } from 'lib/types/message-types';
-import { threadPermissions } from 'lib/types/thread-types';
-import { dateFromString } from 'lib/utils/date-utils';
-import { ServerError } from 'lib/utils/errors';
-import { values } from 'lib/utils/objects';
+} from 'lib/types/entry-types.js';
+import { messageTypes } from 'lib/types/message-types.js';
+import { threadPermissions } from 'lib/types/thread-types.js';
+import { dateFromString } from 'lib/utils/date-utils.js';
+import { ServerError } from 'lib/utils/errors.js';
+import { values } from 'lib/utils/objects.js';
-import fetchOrCreateDayID from '../creators/day-creator';
-import createIDs from '../creators/id-creator';
-import createMessages from '../creators/message-creator';
-import { dbQuery, SQL } from '../database/database';
-import { fetchEntryInfoForLocalID } from '../fetchers/entry-fetchers';
-import { fetchMessageInfoForEntryAction } from '../fetchers/message-fetchers';
-import { checkThreadPermission } from '../fetchers/thread-permission-fetchers';
-import { fetchUpdateInfoForEntryUpdate } from '../fetchers/update-fetchers';
-import type { Viewer } from '../session/viewer';
-import { createUpdateDatasForChangedEntryInfo } from '../updaters/entry-updaters';
-import { creationString } from '../utils/idempotent';
+import fetchOrCreateDayID from '../creators/day-creator.js';
+import createIDs from '../creators/id-creator.js';
+import createMessages from '../creators/message-creator.js';
+import { dbQuery, SQL } from '../database/database.js';
+import { fetchEntryInfoForLocalID } from '../fetchers/entry-fetchers.js';
+import { fetchMessageInfoForEntryAction } from '../fetchers/message-fetchers.js';
+import { checkThreadPermission } from '../fetchers/thread-permission-fetchers.js';
+import { fetchUpdateInfoForEntryUpdate } from '../fetchers/update-fetchers.js';
+import type { Viewer } from '../session/viewer.js';
+import { createUpdateDatasForChangedEntryInfo } from '../updaters/entry-updaters.js';
+import { creationString } from '../utils/idempotent.js';
async function createEntry(
viewer: Viewer,
diff --git a/keyserver/src/creators/id-creator.js b/keyserver/src/creators/id-creator.js
--- a/keyserver/src/creators/id-creator.js
+++ b/keyserver/src/creators/id-creator.js
@@ -2,7 +2,7 @@
import invariant from 'invariant';
-import { dbQuery, SQL } from '../database/database';
+import { dbQuery, SQL } from '../database/database.js';
async function createIDs(
tableName: string,
diff --git a/keyserver/src/creators/message-creator.js b/keyserver/src/creators/message-creator.js
--- a/keyserver/src/creators/message-creator.js
+++ b/keyserver/src/creators/message-creator.js
@@ -1,48 +1,48 @@
// @flow
import invariant from 'invariant';
-import _pickBy from 'lodash/fp/pickBy';
+import _pickBy from 'lodash/fp/pickBy.js';
-import { permissionLookup } from 'lib/permissions/thread-permissions';
+import { permissionLookup } from 'lib/permissions/thread-permissions.js';
import {
rawMessageInfoFromMessageData,
shimUnsupportedRawMessageInfos,
stripLocalIDs,
-} from 'lib/shared/message-utils';
-import { pushTypes } from 'lib/shared/messages/message-spec';
-import { messageSpecs } from 'lib/shared/messages/message-specs';
+} from 'lib/shared/message-utils.js';
+import { pushTypes } from 'lib/shared/messages/message-spec.js';
+import { messageSpecs } from 'lib/shared/messages/message-specs.js';
import {
messageTypes,
messageDataLocalID,
type MessageData,
type RawMessageInfo,
-} from 'lib/types/message-types';
-import { redisMessageTypes } from 'lib/types/redis-types';
-import { threadPermissions } from 'lib/types/thread-types';
-import { updateTypes } from 'lib/types/update-types';
-import { promiseAll } from 'lib/utils/promises';
+} from 'lib/types/message-types.js';
+import { redisMessageTypes } from 'lib/types/redis-types.js';
+import { threadPermissions } from 'lib/types/thread-types.js';
+import { updateTypes } from 'lib/types/update-types.js';
+import { promiseAll } from 'lib/utils/promises.js';
import {
dbQuery,
SQL,
appendSQLArray,
mergeOrConditions,
-} from '../database/database';
+} from '../database/database.js';
import {
fetchMessageInfoForLocalID,
fetchMessageInfoByID,
-} from '../fetchers/message-fetchers';
-import { fetchOtherSessionsForViewer } from '../fetchers/session-fetchers';
-import { fetchServerThreadInfos } from '../fetchers/thread-fetchers';
-import { sendPushNotifs } from '../push/send';
-import { handleAsyncPromise } from '../responders/handlers';
-import type { Viewer } from '../session/viewer';
-import { earliestFocusedTimeConsideredExpired } from '../shared/focused-times';
-import { publisher } from '../socket/redis';
-import { creationString } from '../utils/idempotent';
-import createIDs from './id-creator';
-import type { UpdatesForCurrentSession } from './update-creator';
-import { createUpdates } from './update-creator';
+} from '../fetchers/message-fetchers.js';
+import { fetchOtherSessionsForViewer } from '../fetchers/session-fetchers.js';
+import { fetchServerThreadInfos } from '../fetchers/thread-fetchers.js';
+import { sendPushNotifs } from '../push/send.js';
+import { handleAsyncPromise } from '../responders/handlers.js';
+import type { Viewer } from '../session/viewer.js';
+import { earliestFocusedTimeConsideredExpired } from '../shared/focused-times.js';
+import { publisher } from '../socket/redis.js';
+import { creationString } from '../utils/idempotent.js';
+import createIDs from './id-creator.js';
+import type { UpdatesForCurrentSession } from './update-creator.js';
+import { createUpdates } from './update-creator.js';
type UserThreadInfo = {
+devices: Map<
diff --git a/keyserver/src/creators/message-report-creator.js b/keyserver/src/creators/message-report-creator.js
--- a/keyserver/src/creators/message-report-creator.js
+++ b/keyserver/src/creators/message-report-creator.js
@@ -1,26 +1,26 @@
// @flow
-import bots from 'lib/facts/bots';
-import { createMessageQuote } from 'lib/shared/message-utils';
-import { type MessageReportCreationRequest } from 'lib/types/message-report-types';
-import { messageTypes } from 'lib/types/message-types';
-import type { RawMessageInfo } from 'lib/types/message-types';
-import type { ServerThreadInfo } from 'lib/types/thread-types';
-import { ServerError } from 'lib/utils/errors';
-import { promiseAll } from 'lib/utils/promises';
-
-import { createCommbotThread } from '../bots/commbot';
-import { fetchMessageInfoByID } from '../fetchers/message-fetchers';
+import bots from 'lib/facts/bots.js';
+import { createMessageQuote } from 'lib/shared/message-utils.js';
+import { type MessageReportCreationRequest } from 'lib/types/message-report-types.js';
+import { messageTypes } from 'lib/types/message-types.js';
+import type { RawMessageInfo } from 'lib/types/message-types.js';
+import type { ServerThreadInfo } from 'lib/types/thread-types.js';
+import { ServerError } from 'lib/utils/errors.js';
+import { promiseAll } from 'lib/utils/promises.js';
+
+import { createCommbotThread } from '../bots/commbot.js';
+import { fetchMessageInfoByID } from '../fetchers/message-fetchers.js';
import {
fetchPersonalThreadID,
serverThreadInfoFromMessageInfo,
-} from '../fetchers/thread-fetchers';
+} from '../fetchers/thread-fetchers.js';
import {
fetchUsername,
fetchKeyserverAdminID,
-} from '../fetchers/user-fetchers';
-import type { Viewer } from '../session/viewer';
-import createMessages from './message-creator';
+} from '../fetchers/user-fetchers.js';
+import type { Viewer } from '../session/viewer.js';
+import createMessages from './message-creator.js';
const { commbot } = bots;
diff --git a/keyserver/src/creators/one-time-keys-creator.js b/keyserver/src/creators/one-time-keys-creator.js
--- a/keyserver/src/creators/one-time-keys-creator.js
+++ b/keyserver/src/creators/one-time-keys-creator.js
@@ -1,7 +1,7 @@
// @flow
-import { dbQuery, SQL } from '../database/database';
-import type { Viewer } from '../session/viewer';
+import { dbQuery, SQL } from '../database/database.js';
+import type { Viewer } from '../session/viewer.js';
async function saveOneTimeKeys(
viewer: Viewer,
diff --git a/keyserver/src/creators/relationship-creators.js b/keyserver/src/creators/relationship-creators.js
--- a/keyserver/src/creators/relationship-creators.js
+++ b/keyserver/src/creators/relationship-creators.js
@@ -1,25 +1,25 @@
// @flow
-import _flatten from 'lodash/fp/flatten';
-import _flow from 'lodash/fp/flow';
-import _groupBy from 'lodash/fp/groupBy';
-import _isEqual from 'lodash/fp/isEqual';
-import _map from 'lodash/fp/map';
-import _mapValues from 'lodash/fp/mapValues';
-import _uniqWith from 'lodash/fp/uniqWith';
-import _values from 'lodash/fp/values';
+import _flatten from 'lodash/fp/flatten.js';
+import _flow from 'lodash/fp/flow.js';
+import _groupBy from 'lodash/fp/groupBy.js';
+import _isEqual from 'lodash/fp/isEqual.js';
+import _map from 'lodash/fp/map.js';
+import _mapValues from 'lodash/fp/mapValues.js';
+import _uniqWith from 'lodash/fp/uniqWith.js';
+import _values from 'lodash/fp/values.js';
import {
type UndirectedStatus,
undirectedStatus,
-} from 'lib/types/relationship-types';
-import { getAllTuples } from 'lib/utils/array';
+} from 'lib/types/relationship-types.js';
+import { getAllTuples } from 'lib/utils/array.js';
import {
updateUndirectedRelationships,
updateDatasForUserPairs,
-} from '../updaters/relationship-updaters';
-import { createUpdates } from './update-creator';
+} from '../updaters/relationship-updaters.js';
+import { createUpdates } from './update-creator.js';
type QueryResult = {
+thread: number,
diff --git a/keyserver/src/creators/report-creator.js b/keyserver/src/creators/report-creator.js
--- a/keyserver/src/creators/report-creator.js
+++ b/keyserver/src/creators/report-creator.js
@@ -1,13 +1,13 @@
// @flow
-import _isEqual from 'lodash/fp/isEqual';
+import _isEqual from 'lodash/fp/isEqual.js';
-import bots from 'lib/facts/bots';
+import bots from 'lib/facts/bots.js';
import {
filterRawEntryInfosByCalendarQuery,
serverEntryInfosObject,
-} from 'lib/shared/entry-utils';
-import { messageTypes } from 'lib/types/message-types';
+} from 'lib/shared/entry-utils.js';
+import { messageTypes } from 'lib/types/message-types.js';
import {
type ReportCreationRequest,
type ReportCreationResponse,
@@ -15,21 +15,21 @@
type EntryInconsistencyReportCreationRequest,
type UserInconsistencyReportCreationRequest,
reportTypes,
-} from 'lib/types/report-types';
-import { values } from 'lib/utils/objects';
+} from 'lib/types/report-types.js';
+import { values } from 'lib/utils/objects.js';
import {
sanitizeReduxReport,
type ReduxCrashReport,
-} from 'lib/utils/sanitization';
+} from 'lib/utils/sanitization.js';
-import { dbQuery, SQL } from '../database/database';
-import { fetchUsername } from '../fetchers/user-fetchers';
-import { handleAsyncPromise } from '../responders/handlers';
-import { createBotViewer } from '../session/bots';
-import type { Viewer } from '../session/viewer';
-import { getAndAssertCommAppURLFacts } from '../utils/urls';
-import createIDs from './id-creator';
-import createMessages from './message-creator';
+import { dbQuery, SQL } from '../database/database.js';
+import { fetchUsername } from '../fetchers/user-fetchers.js';
+import { handleAsyncPromise } from '../responders/handlers.js';
+import { createBotViewer } from '../session/bots.js';
+import type { Viewer } from '../session/viewer.js';
+import { getAndAssertCommAppURLFacts } from '../utils/urls.js';
+import createIDs from './id-creator.js';
+import createMessages from './message-creator.js';
const { commbot } = bots;
diff --git a/keyserver/src/creators/role-creator.js b/keyserver/src/creators/role-creator.js
--- a/keyserver/src/creators/role-creator.js
+++ b/keyserver/src/creators/role-creator.js
@@ -8,10 +8,10 @@
type ThreadRolePermissionsBlob,
type ThreadType,
threadTypes,
-} from 'lib/types/thread-types';
+} from 'lib/types/thread-types.js';
-import { dbQuery, SQL } from '../database/database';
-import createIDs from './id-creator';
+import { dbQuery, SQL } from '../database/database.js';
+import createIDs from './id-creator.js';
type InitialRoles = {
default: RoleInfo,
diff --git a/keyserver/src/creators/session-creator.js b/keyserver/src/creators/session-creator.js
--- a/keyserver/src/creators/session-creator.js
+++ b/keyserver/src/creators/session-creator.js
@@ -1,9 +1,9 @@
// @flow
-import type { CalendarQuery } from 'lib/types/entry-types';
+import type { CalendarQuery } from 'lib/types/entry-types.js';
-import { dbQuery, SQL } from '../database/database';
-import type { Viewer } from '../session/viewer';
+import { dbQuery, SQL } from '../database/database.js';
+import type { Viewer } from '../session/viewer.js';
async function createSession(
viewer: Viewer,
diff --git a/keyserver/src/creators/thread-creator.js b/keyserver/src/creators/thread-creator.js
--- a/keyserver/src/creators/thread-creator.js
+++ b/keyserver/src/creators/thread-creator.js
@@ -2,55 +2,55 @@
import invariant from 'invariant';
-import bots from 'lib/facts/bots';
-import genesis from 'lib/facts/genesis';
+import bots from 'lib/facts/bots.js';
+import genesis from 'lib/facts/genesis.js';
import {
generatePendingThreadColor,
generateRandomColor,
getThreadTypeParentRequirement,
-} from 'lib/shared/thread-utils';
-import { hasMinCodeVersion } from 'lib/shared/version-utils';
-import type { Shape } from 'lib/types/core';
-import { messageTypes } from 'lib/types/message-types';
+} from 'lib/shared/thread-utils.js';
+import { hasMinCodeVersion } from 'lib/shared/version-utils.js';
+import type { Shape } from 'lib/types/core.js';
+import { messageTypes } from 'lib/types/message-types.js';
import {
type ServerNewThreadRequest,
type NewThreadResponse,
threadTypes,
threadPermissions,
threadTypeIsCommunityRoot,
-} from 'lib/types/thread-types';
-import type { UserInfos } from 'lib/types/user-types';
-import { pushAll } from 'lib/utils/array';
-import { ServerError } from 'lib/utils/errors';
-import { promiseAll } from 'lib/utils/promises';
-import { firstLine } from 'lib/utils/string-utils';
-
-import { dbQuery, SQL } from '../database/database';
-import { fetchMessageInfoByID } from '../fetchers/message-fetchers';
+} from 'lib/types/thread-types.js';
+import type { UserInfos } from 'lib/types/user-types.js';
+import { pushAll } from 'lib/utils/array.js';
+import { ServerError } from 'lib/utils/errors.js';
+import { promiseAll } from 'lib/utils/promises.js';
+import { firstLine } from 'lib/utils/string-utils.js';
+
+import { dbQuery, SQL } from '../database/database.js';
+import { fetchMessageInfoByID } from '../fetchers/message-fetchers.js';
import {
determineThreadAncestry,
personalThreadQuery,
-} from '../fetchers/thread-fetchers';
+} from '../fetchers/thread-fetchers.js';
import {
checkThreadPermission,
validateCandidateMembers,
-} from '../fetchers/thread-permission-fetchers';
-import type { Viewer } from '../session/viewer';
+} from '../fetchers/thread-permission-fetchers.js';
+import type { Viewer } from '../session/viewer.js';
import {
changeRole,
recalculateThreadPermissions,
commitMembershipChangeset,
getChangesetCommitResultForExistingThread,
-} from '../updaters/thread-permission-updaters';
-import { joinThread } from '../updaters/thread-updaters';
-import RelationshipChangeset from '../utils/relationship-changeset';
-import createIDs from './id-creator';
-import createMessages from './message-creator';
+} from '../updaters/thread-permission-updaters.js';
+import { joinThread } from '../updaters/thread-updaters.js';
+import RelationshipChangeset from '../utils/relationship-changeset.js';
+import createIDs from './id-creator.js';
+import createMessages from './message-creator.js';
import {
createInitialRolesForNewThread,
getRolePermissionBlobs,
-} from './role-creator';
-import type { UpdatesForCurrentSession } from './update-creator';
+} from './role-creator.js';
+import type { UpdatesForCurrentSession } from './update-creator.js';
const { commbot } = bots;
diff --git a/keyserver/src/creators/update-creator.js b/keyserver/src/creators/update-creator.js
--- a/keyserver/src/creators/update-creator.js
+++ b/keyserver/src/creators/update-creator.js
@@ -2,61 +2,61 @@
import invariant from 'invariant';
-import { nonThreadCalendarFilters } from 'lib/selectors/calendar-filter-selectors';
+import { nonThreadCalendarFilters } from 'lib/selectors/calendar-filter-selectors.js';
import {
keyForUpdateData,
keyForUpdateInfo,
rawUpdateInfoFromUpdateData,
-} from 'lib/shared/update-utils';
+} from 'lib/shared/update-utils.js';
import {
type RawEntryInfo,
type FetchEntryInfosBase,
type CalendarQuery,
defaultCalendarQuery,
-} from 'lib/types/entry-types';
+} from 'lib/types/entry-types.js';
import {
defaultNumberPerThread,
type FetchMessageInfosResult,
-} from 'lib/types/message-types';
+} from 'lib/types/message-types.js';
import {
type UpdateTarget,
redisMessageTypes,
type NewUpdatesRedisMessage,
-} from 'lib/types/redis-types';
-import type { RawThreadInfo } from 'lib/types/thread-types';
+} from 'lib/types/redis-types.js';
+import type { RawThreadInfo } from 'lib/types/thread-types.js';
import {
type ServerUpdateInfo,
type UpdateData,
type RawUpdateInfo,
type CreateUpdatesResult,
updateTypes,
-} from 'lib/types/update-types';
+} from 'lib/types/update-types.js';
import type {
UserInfos,
LoggedInUserInfo,
OldLoggedInUserInfo,
-} from 'lib/types/user-types';
-import { promiseAll } from 'lib/utils/promises';
+} from 'lib/types/user-types.js';
+import { promiseAll } from 'lib/utils/promises.js';
-import { dbQuery, SQL, mergeAndConditions } from '../database/database';
-import type { SQLStatementType } from '../database/types';
-import { deleteUpdatesByConditions } from '../deleters/update-deleters';
+import { dbQuery, SQL, mergeAndConditions } from '../database/database.js';
+import type { SQLStatementType } from '../database/types.js';
+import { deleteUpdatesByConditions } from '../deleters/update-deleters.js';
import {
fetchEntryInfos,
fetchEntryInfosByID,
-} from '../fetchers/entry-fetchers';
-import { fetchMessageInfos } from '../fetchers/message-fetchers';
+} from '../fetchers/entry-fetchers.js';
+import { fetchMessageInfos } from '../fetchers/message-fetchers.js';
import {
fetchThreadInfos,
type FetchThreadInfosResult,
-} from '../fetchers/thread-fetchers';
+} from '../fetchers/thread-fetchers.js';
import {
fetchKnownUserInfos,
fetchCurrentUserInfo,
-} from '../fetchers/user-fetchers';
-import type { Viewer } from '../session/viewer';
-import { channelNameForUpdateTarget, publisher } from '../socket/redis';
-import createIDs from './id-creator';
+} from '../fetchers/user-fetchers.js';
+import type { Viewer } from '../session/viewer.js';
+import { channelNameForUpdateTarget, publisher } from '../socket/redis.js';
+import createIDs from './id-creator.js';
export type UpdatesForCurrentSession =
// This is the default if no Viewer is passed, or if an isSocket Viewer is
diff --git a/keyserver/src/creators/upload-creator.js b/keyserver/src/creators/upload-creator.js
--- a/keyserver/src/creators/upload-creator.js
+++ b/keyserver/src/creators/upload-creator.js
@@ -2,18 +2,18 @@
import crypto from 'crypto';
-import { shimUploadURI } from 'lib/media/media-utils';
+import { shimUploadURI } from 'lib/media/media-utils.js';
import type {
MediaType,
UploadMultimediaResult,
Dimensions,
-} from 'lib/types/media-types';
-import { ServerError } from 'lib/utils/errors';
+} from 'lib/types/media-types.js';
+import { ServerError } from 'lib/utils/errors.js';
-import { dbQuery, SQL } from '../database/database';
-import { getUploadURL } from '../fetchers/upload-fetchers';
-import type { Viewer } from '../session/viewer';
-import createIDs from './id-creator';
+import { dbQuery, SQL } from '../database/database.js';
+import { getUploadURL } from '../fetchers/upload-fetchers.js';
+import type { Viewer } from '../session/viewer.js';
+import createIDs from './id-creator.js';
export type UploadInput = {
name: string,
diff --git a/keyserver/src/cron/backups.js b/keyserver/src/cron/backups.js
--- a/keyserver/src/cron/backups.js
+++ b/keyserver/src/cron/backups.js
@@ -9,8 +9,8 @@
import { promisify } from 'util';
import zlib from 'zlib';
-import { getDBConfig, type DBConfig } from '../database/db-config';
-import { importJSON } from '../utils/import-json';
+import { getDBConfig, type DBConfig } from '../database/db-config.js';
+import { importJSON } from '../utils/import-json.js';
const readdir = promisify(fs.readdir);
const lstat = promisify(fs.lstat);
diff --git a/keyserver/src/cron/cron.js b/keyserver/src/cron/cron.js
--- a/keyserver/src/cron/cron.js
+++ b/keyserver/src/cron/cron.js
@@ -3,26 +3,26 @@
import cluster from 'cluster';
import schedule from 'node-schedule';
-import { deleteOrphanedActivity } from '../deleters/activity-deleters';
-import { deleteExpiredCookies } from '../deleters/cookie-deleters';
-import { deleteOrphanedDays } from '../deleters/day-deleters';
-import { deleteOrphanedEntries } from '../deleters/entry-deleters';
-import { deleteOrphanedMemberships } from '../deleters/membership-deleters';
-import { deleteOrphanedMessages } from '../deleters/message-deleters';
-import { deleteOrphanedNotifs } from '../deleters/notif-deleters';
-import { deleteOrphanedRevisions } from '../deleters/revision-deleters';
-import { deleteOrphanedRoles } from '../deleters/role-deleters';
+import { deleteOrphanedActivity } from '../deleters/activity-deleters.js';
+import { deleteExpiredCookies } from '../deleters/cookie-deleters.js';
+import { deleteOrphanedDays } from '../deleters/day-deleters.js';
+import { deleteOrphanedEntries } from '../deleters/entry-deleters.js';
+import { deleteOrphanedMemberships } from '../deleters/membership-deleters.js';
+import { deleteOrphanedMessages } from '../deleters/message-deleters.js';
+import { deleteOrphanedNotifs } from '../deleters/notif-deleters.js';
+import { deleteOrphanedRevisions } from '../deleters/revision-deleters.js';
+import { deleteOrphanedRoles } from '../deleters/role-deleters.js';
import {
deleteOrphanedSessions,
deleteOldWebSessions,
-} from '../deleters/session-deleters';
+} from '../deleters/session-deleters.js';
import { deleteStaleSIWENonceEntries } from '../deleters/siwe-nonce-deleters.js';
-import { deleteInaccessibleThreads } from '../deleters/thread-deleters';
-import { deleteExpiredUpdates } from '../deleters/update-deleters';
-import { deleteUnassignedUploads } from '../deleters/upload-deleters';
-import { backupDB } from './backups';
-import { createDailyUpdatesThread } from './daily-updates';
-import { updateAndReloadGeoipDB } from './update-geoip-db';
+import { deleteInaccessibleThreads } from '../deleters/thread-deleters.js';
+import { deleteExpiredUpdates } from '../deleters/update-deleters.js';
+import { deleteUnassignedUploads } from '../deleters/upload-deleters.js';
+import { backupDB } from './backups.js';
+import { createDailyUpdatesThread } from './daily-updates.js';
+import { updateAndReloadGeoipDB } from './update-geoip-db.js';
if (cluster.isMaster) {
schedule.scheduleJob(
diff --git a/keyserver/src/cron/daily-updates.js b/keyserver/src/cron/daily-updates.js
--- a/keyserver/src/cron/daily-updates.js
+++ b/keyserver/src/cron/daily-updates.js
@@ -2,20 +2,20 @@
import invariant from 'invariant';
-import ashoat from 'lib/facts/ashoat';
-import { messageTypes } from 'lib/types/message-types';
-import { threadTypes } from 'lib/types/thread-types';
+import ashoat from 'lib/facts/ashoat.js';
+import { messageTypes } from 'lib/types/message-types.js';
+import { threadTypes } from 'lib/types/thread-types.js';
import {
getDate,
dateString,
prettyDateWithoutYear,
prettyDateWithoutDay,
-} from 'lib/utils/date-utils';
+} from 'lib/utils/date-utils.js';
-import createMessages from '../creators/message-creator';
-import { createThread } from '../creators/thread-creator';
-import { fetchEntryInfosForThreadThisWeek } from '../fetchers/entry-fetchers';
-import { createScriptViewer } from '../session/scripts';
+import createMessages from '../creators/message-creator.js';
+import { createThread } from '../creators/thread-creator.js';
+import { fetchEntryInfosForThreadThisWeek } from '../fetchers/entry-fetchers.js';
+import { createScriptViewer } from '../session/scripts.js';
const devUpdateThread = '1358777';
const weeklyDevSyncScheduleThread = '4138372';
diff --git a/keyserver/src/cron/update-geoip-db.js b/keyserver/src/cron/update-geoip-db.js
--- a/keyserver/src/cron/update-geoip-db.js
+++ b/keyserver/src/cron/update-geoip-db.js
@@ -4,8 +4,8 @@
import cluster from 'cluster';
import geoip from 'geoip-lite';
-import { handleAsyncPromise } from '../responders/handlers';
-import { importJSON } from '../utils/import-json';
+import { handleAsyncPromise } from '../responders/handlers.js';
+import { importJSON } from '../utils/import-json.js';
async function updateGeoipDB(): Promise<void> {
const geoipLicense = await importJSON({
diff --git a/keyserver/src/database/database.js b/keyserver/src/database/database.js
--- a/keyserver/src/database/database.js
+++ b/keyserver/src/database/database.js
@@ -2,14 +2,14 @@
import type { ConnectionOptions, QueryResults, PoolOptions } from 'mysql';
import mysql from 'mysql2';
-import mysqlPromise from 'mysql2/promise';
+import mysqlPromise from 'mysql2/promise.js';
import SQL from 'sql-template-strings';
-import { getScriptContext } from '../scripts/script-context';
-import { connectionLimit, queryWarnTime } from './consts';
-import { getDBConfig } from './db-config';
-import DatabaseMonitor from './monitor';
-import type { Pool, SQLOrString, SQLStatementType } from './types';
+import { getScriptContext } from '../scripts/script-context.js';
+import { connectionLimit, queryWarnTime } from './consts.js';
+import { getDBConfig } from './db-config.js';
+import DatabaseMonitor from './monitor.js';
+import type { Pool, SQLOrString, SQLStatementType } from './types.js';
const SQLStatement: SQLStatementType = SQL.SQLStatement;
diff --git a/keyserver/src/database/db-config.js b/keyserver/src/database/db-config.js
--- a/keyserver/src/database/db-config.js
+++ b/keyserver/src/database/db-config.js
@@ -2,7 +2,7 @@
import invariant from 'invariant';
-import { importJSON } from '../utils/import-json';
+import { importJSON } from '../utils/import-json.js';
type DBType = 'mariadb10.8';
export type DBConfig = {
diff --git a/keyserver/src/database/db-version.js b/keyserver/src/database/db-version.js
--- a/keyserver/src/database/db-version.js
+++ b/keyserver/src/database/db-version.js
@@ -2,7 +2,7 @@
import type { QueryResults } from 'mysql';
-import { dbQuery, SQL } from './database';
+import { dbQuery, SQL } from './database.js';
const dbVersionMetadataKey = 'db_version';
diff --git a/keyserver/src/database/migration-config.js b/keyserver/src/database/migration-config.js
--- a/keyserver/src/database/migration-config.js
+++ b/keyserver/src/database/migration-config.js
@@ -4,8 +4,8 @@
import { policyTypes } from 'lib/facts/policies.js';
-import { dbQuery, SQL } from '../database/database';
-import { updateRolesAndPermissionsForAllThreads } from '../updaters/thread-permission-updaters';
+import { dbQuery, SQL } from '../database/database.js';
+import { updateRolesAndPermissionsForAllThreads } from '../updaters/thread-permission-updaters.js';
const migrations: $ReadOnlyMap<number, () => Promise<void>> = new Map([
[
diff --git a/keyserver/src/database/migrations.js b/keyserver/src/database/migrations.js
--- a/keyserver/src/database/migrations.js
+++ b/keyserver/src/database/migrations.js
@@ -2,14 +2,14 @@
import type { QueryResults } from 'mysql';
-import { isDev } from 'lib/utils/dev-utils';
-import { getMessageForException } from 'lib/utils/errors';
-import sleep from 'lib/utils/sleep';
+import { isDev } from 'lib/utils/dev-utils.js';
+import { getMessageForException } from 'lib/utils/errors.js';
+import sleep from 'lib/utils/sleep.js';
-import { dbQuery, SQL, setConnectionContext } from './database';
-import { fetchDBVersion, updateDBVersion } from './db-version';
-import { migrations } from './migration-config';
-import { setupDB } from './setup-db';
+import { dbQuery, SQL, setConnectionContext } from './database.js';
+import { fetchDBVersion, updateDBVersion } from './db-version.js';
+import { migrations } from './migration-config.js';
+import { setupDB } from './setup-db.js';
async function migrate(): Promise<boolean> {
if (isDev) {
diff --git a/keyserver/src/database/monitor.js b/keyserver/src/database/monitor.js
--- a/keyserver/src/database/monitor.js
+++ b/keyserver/src/database/monitor.js
@@ -1,7 +1,7 @@
// @flow
-import { queryWarnTime } from './consts';
-import type { Pool } from './types';
+import { queryWarnTime } from './consts.js';
+import type { Pool } from './types.js';
function countDecimals(num: number) {
return 1 + (num === 0 ? 0 : Math.floor(Math.log10(num)));
diff --git a/keyserver/src/database/setup-db.js b/keyserver/src/database/setup-db.js
--- a/keyserver/src/database/setup-db.js
+++ b/keyserver/src/database/setup-db.js
@@ -1,18 +1,18 @@
// @flow
-import ashoat from 'lib/facts/ashoat';
-import bots from 'lib/facts/bots';
-import genesis from 'lib/facts/genesis';
-import { usernameMaxLength } from 'lib/shared/account-utils';
-import { sortIDs } from 'lib/shared/relationship-utils';
-import { undirectedStatus } from 'lib/types/relationship-types';
-import { threadTypes } from 'lib/types/thread-types';
-
-import { createThread } from '../creators/thread-creator';
-import { dbQuery, SQL } from '../database/database';
-import { updateDBVersion } from '../database/db-version';
-import { newDatabaseVersion } from '../database/migration-config';
-import { createScriptViewer } from '../session/scripts';
+import ashoat from 'lib/facts/ashoat.js';
+import bots from 'lib/facts/bots.js';
+import genesis from 'lib/facts/genesis.js';
+import { usernameMaxLength } from 'lib/shared/account-utils.js';
+import { sortIDs } from 'lib/shared/relationship-utils.js';
+import { undirectedStatus } from 'lib/types/relationship-types.js';
+import { threadTypes } from 'lib/types/thread-types.js';
+
+import { createThread } from '../creators/thread-creator.js';
+import { dbQuery, SQL } from '../database/database.js';
+import { updateDBVersion } from '../database/db-version.js';
+import { newDatabaseVersion } from '../database/migration-config.js';
+import { createScriptViewer } from '../session/scripts.js';
async function setupDB() {
await createTables();
diff --git a/keyserver/src/deleters/account-deleters.js b/keyserver/src/deleters/account-deleters.js
--- a/keyserver/src/deleters/account-deleters.js
+++ b/keyserver/src/deleters/account-deleters.js
@@ -5,20 +5,20 @@
import type {
LogOutResponse,
DeleteAccountRequest,
-} from 'lib/types/account-types';
-import { updateTypes } from 'lib/types/update-types';
-import type { UserInfo } from 'lib/types/user-types';
-import { ServerError } from 'lib/utils/errors';
-import { values } from 'lib/utils/objects';
-import { promiseAll } from 'lib/utils/promises';
+} from 'lib/types/account-types.js';
+import { updateTypes } from 'lib/types/update-types.js';
+import type { UserInfo } from 'lib/types/user-types.js';
+import { ServerError } from 'lib/utils/errors.js';
+import { values } from 'lib/utils/objects.js';
+import { promiseAll } from 'lib/utils/promises.js';
-import { createUpdates } from '../creators/update-creator';
-import { dbQuery, SQL } from '../database/database';
-import { fetchKnownUserInfos } from '../fetchers/user-fetchers';
-import { rescindPushNotifs } from '../push/rescind';
-import { handleAsyncPromise } from '../responders/handlers';
-import { createNewAnonymousCookie } from '../session/cookies';
-import type { Viewer } from '../session/viewer';
+import { createUpdates } from '../creators/update-creator.js';
+import { dbQuery, SQL } from '../database/database.js';
+import { fetchKnownUserInfos } from '../fetchers/user-fetchers.js';
+import { rescindPushNotifs } from '../push/rescind.js';
+import { handleAsyncPromise } from '../responders/handlers.js';
+import { createNewAnonymousCookie } from '../session/cookies.js';
+import type { Viewer } from '../session/viewer.js';
async function deleteAccount(
viewer: Viewer,
diff --git a/keyserver/src/deleters/activity-deleters.js b/keyserver/src/deleters/activity-deleters.js
--- a/keyserver/src/deleters/activity-deleters.js
+++ b/keyserver/src/deleters/activity-deleters.js
@@ -1,8 +1,8 @@
// @flow
-import { dbQuery, SQL } from '../database/database';
-import type { Viewer } from '../session/viewer';
-import { earliestFocusedTimeConsideredExpired } from '../shared/focused-times';
+import { dbQuery, SQL } from '../database/database.js';
+import type { Viewer } from '../session/viewer.js';
+import { earliestFocusedTimeConsideredExpired } from '../shared/focused-times.js';
async function deleteActivityForViewerSession(
viewer: Viewer,
diff --git a/keyserver/src/deleters/cookie-deleters.js b/keyserver/src/deleters/cookie-deleters.js
--- a/keyserver/src/deleters/cookie-deleters.js
+++ b/keyserver/src/deleters/cookie-deleters.js
@@ -2,10 +2,10 @@
import invariant from 'invariant';
-import { cookieLifetime } from 'lib/types/session-types';
+import { cookieLifetime } from 'lib/types/session-types.js';
-import { dbQuery, SQL, mergeOrConditions } from '../database/database';
-import type { SQLStatementType } from '../database/types';
+import { dbQuery, SQL, mergeOrConditions } from '../database/database.js';
+import type { SQLStatementType } from '../database/types.js';
async function deleteCookiesByConditions(
conditions: $ReadOnlyArray<SQLStatementType>,
diff --git a/keyserver/src/deleters/day-deleters.js b/keyserver/src/deleters/day-deleters.js
--- a/keyserver/src/deleters/day-deleters.js
+++ b/keyserver/src/deleters/day-deleters.js
@@ -1,6 +1,6 @@
// @flow
-import { dbQuery, SQL } from '../database/database';
+import { dbQuery, SQL } from '../database/database.js';
async function deleteOrphanedDays(): Promise<void> {
await dbQuery(SQL`
diff --git a/keyserver/src/deleters/entry-deleters.js b/keyserver/src/deleters/entry-deleters.js
--- a/keyserver/src/deleters/entry-deleters.js
+++ b/keyserver/src/deleters/entry-deleters.js
@@ -5,21 +5,21 @@
DeleteEntryResponse,
RestoreEntryRequest,
RestoreEntryResponse,
-} from 'lib/types/entry-types';
-import { messageTypes } from 'lib/types/message-types';
-import { threadPermissions } from 'lib/types/thread-types';
-import { dateString } from 'lib/utils/date-utils';
-import { ServerError } from 'lib/utils/errors';
-import { values } from 'lib/utils/objects';
+} from 'lib/types/entry-types.js';
+import { messageTypes } from 'lib/types/message-types.js';
+import { threadPermissions } from 'lib/types/thread-types.js';
+import { dateString } from 'lib/utils/date-utils.js';
+import { ServerError } from 'lib/utils/errors.js';
+import { values } from 'lib/utils/objects.js';
-import createIDs from '../creators/id-creator';
-import createMessages from '../creators/message-creator';
-import { dbQuery, SQL } from '../database/database';
-import { checkThreadPermissionForEntry } from '../fetchers/entry-fetchers';
-import { fetchMessageInfoForEntryAction } from '../fetchers/message-fetchers';
-import { fetchUpdateInfoForEntryUpdate } from '../fetchers/update-fetchers';
-import type { Viewer } from '../session/viewer';
-import { createUpdateDatasForChangedEntryInfo } from '../updaters/entry-updaters';
+import createIDs from '../creators/id-creator.js';
+import createMessages from '../creators/message-creator.js';
+import { dbQuery, SQL } from '../database/database.js';
+import { checkThreadPermissionForEntry } from '../fetchers/entry-fetchers.js';
+import { fetchMessageInfoForEntryAction } from '../fetchers/message-fetchers.js';
+import { fetchUpdateInfoForEntryUpdate } from '../fetchers/update-fetchers.js';
+import type { Viewer } from '../session/viewer.js';
+import { createUpdateDatasForChangedEntryInfo } from '../updaters/entry-updaters.js';
const lastRevisionQuery = (entryID: string) => SQL`
SELECT r.id, r.author, r.text, r.session, r.last_update, r.deleted,
diff --git a/keyserver/src/deleters/membership-deleters.js b/keyserver/src/deleters/membership-deleters.js
--- a/keyserver/src/deleters/membership-deleters.js
+++ b/keyserver/src/deleters/membership-deleters.js
@@ -1,6 +1,6 @@
// @flow
-import { dbQuery, SQL } from '../database/database';
+import { dbQuery, SQL } from '../database/database.js';
async function deleteOrphanedMemberships(): Promise<void> {
await dbQuery(SQL`
diff --git a/keyserver/src/deleters/message-deleters.js b/keyserver/src/deleters/message-deleters.js
--- a/keyserver/src/deleters/message-deleters.js
+++ b/keyserver/src/deleters/message-deleters.js
@@ -1,6 +1,6 @@
// @flow
-import { dbQuery, SQL } from '../database/database';
+import { dbQuery, SQL } from '../database/database.js';
async function deleteOrphanedMessages(): Promise<void> {
await dbQuery(SQL`
diff --git a/keyserver/src/deleters/notif-deleters.js b/keyserver/src/deleters/notif-deleters.js
--- a/keyserver/src/deleters/notif-deleters.js
+++ b/keyserver/src/deleters/notif-deleters.js
@@ -1,6 +1,6 @@
// @flow
-import { dbQuery, SQL } from '../database/database';
+import { dbQuery, SQL } from '../database/database.js';
async function deleteOrphanedNotifs(): Promise<void> {
await dbQuery(SQL`
diff --git a/keyserver/src/deleters/one-time-key-deleters.js b/keyserver/src/deleters/one-time-key-deleters.js
--- a/keyserver/src/deleters/one-time-key-deleters.js
+++ b/keyserver/src/deleters/one-time-key-deleters.js
@@ -1,6 +1,6 @@
// @flow
-import { dbQuery, SQL } from '../database/database';
+import { dbQuery, SQL } from '../database/database.js';
async function deleteOneTimeKey(
session: string,
diff --git a/keyserver/src/deleters/revision-deleters.js b/keyserver/src/deleters/revision-deleters.js
--- a/keyserver/src/deleters/revision-deleters.js
+++ b/keyserver/src/deleters/revision-deleters.js
@@ -1,6 +1,6 @@
// @flow
-import { dbQuery, SQL } from '../database/database';
+import { dbQuery, SQL } from '../database/database.js';
async function deleteOrphanedRevisions(): Promise<void> {
await dbQuery(SQL`
diff --git a/keyserver/src/deleters/role-deleters.js b/keyserver/src/deleters/role-deleters.js
--- a/keyserver/src/deleters/role-deleters.js
+++ b/keyserver/src/deleters/role-deleters.js
@@ -1,6 +1,6 @@
// @flow
-import { dbQuery, SQL } from '../database/database';
+import { dbQuery, SQL } from '../database/database.js';
async function deleteOrphanedRoles(): Promise<void> {
await dbQuery(SQL`
diff --git a/keyserver/src/deleters/session-deleters.js b/keyserver/src/deleters/session-deleters.js
--- a/keyserver/src/deleters/session-deleters.js
+++ b/keyserver/src/deleters/session-deleters.js
@@ -1,6 +1,6 @@
// @flow
-import { dbQuery, SQL } from '../database/database';
+import { dbQuery, SQL } from '../database/database.js';
async function deleteOrphanedSessions(): Promise<void> {
await dbQuery(SQL`
diff --git a/keyserver/src/deleters/siwe-nonce-deleters.js b/keyserver/src/deleters/siwe-nonce-deleters.js
--- a/keyserver/src/deleters/siwe-nonce-deleters.js
+++ b/keyserver/src/deleters/siwe-nonce-deleters.js
@@ -1,6 +1,6 @@
// @flow
-import { dbQuery, SQL } from '../database/database';
+import { dbQuery, SQL } from '../database/database.js';
// 30 minutes = 30min * 60sec * 1000ms
export const nonceLifetime = 30 * 60 * 1000;
diff --git a/keyserver/src/deleters/thread-deleters.js b/keyserver/src/deleters/thread-deleters.js
--- a/keyserver/src/deleters/thread-deleters.js
+++ b/keyserver/src/deleters/thread-deleters.js
@@ -1,25 +1,25 @@
// @flow
-import { permissionLookup } from 'lib/permissions/thread-permissions';
-import { hasMinCodeVersion } from 'lib/shared/version-utils';
+import { permissionLookup } from 'lib/permissions/thread-permissions.js';
+import { hasMinCodeVersion } from 'lib/shared/version-utils.js';
import {
type ThreadDeletionRequest,
type LeaveThreadResult,
threadPermissions,
-} from 'lib/types/thread-types';
-import { updateTypes } from 'lib/types/update-types';
-import { ServerError } from 'lib/utils/errors';
+} from 'lib/types/thread-types.js';
+import { updateTypes } from 'lib/types/update-types.js';
+import { ServerError } from 'lib/utils/errors.js';
-import { createUpdates } from '../creators/update-creator';
-import { dbQuery, SQL } from '../database/database';
+import { createUpdates } from '../creators/update-creator.js';
+import { dbQuery, SQL } from '../database/database.js';
import {
fetchThreadInfos,
fetchServerThreadInfos,
-} from '../fetchers/thread-fetchers';
-import { fetchThreadPermissionsBlob } from '../fetchers/thread-permission-fetchers';
-import { fetchUpdateInfoForThreadDeletion } from '../fetchers/update-fetchers';
-import { rescindPushNotifs } from '../push/rescind';
-import type { Viewer } from '../session/viewer';
+} from '../fetchers/thread-fetchers.js';
+import { fetchThreadPermissionsBlob } from '../fetchers/thread-permission-fetchers.js';
+import { fetchUpdateInfoForThreadDeletion } from '../fetchers/update-fetchers.js';
+import { rescindPushNotifs } from '../push/rescind.js';
+import type { Viewer } from '../session/viewer.js';
async function deleteThread(
viewer: Viewer,
diff --git a/keyserver/src/deleters/update-deleters.js b/keyserver/src/deleters/update-deleters.js
--- a/keyserver/src/deleters/update-deleters.js
+++ b/keyserver/src/deleters/update-deleters.js
@@ -2,9 +2,9 @@
import invariant from 'invariant';
-import { dbQuery, SQL, mergeOrConditions } from '../database/database';
-import type { SQLStatementType } from '../database/types';
-import type { Viewer } from '../session/viewer';
+import { dbQuery, SQL, mergeOrConditions } from '../database/database.js';
+import type { SQLStatementType } from '../database/types.js';
+import type { Viewer } from '../session/viewer.js';
async function deleteUpdatesByConditions(
conditions: $ReadOnlyArray<SQLStatementType>,
diff --git a/keyserver/src/deleters/upload-deleters.js b/keyserver/src/deleters/upload-deleters.js
--- a/keyserver/src/deleters/upload-deleters.js
+++ b/keyserver/src/deleters/upload-deleters.js
@@ -1,9 +1,9 @@
// @flow
-import { ServerError } from 'lib/utils/errors';
+import { ServerError } from 'lib/utils/errors.js';
-import { dbQuery, SQL } from '../database/database';
-import type { Viewer } from '../session/viewer';
+import { dbQuery, SQL } from '../database/database.js';
+import type { Viewer } from '../session/viewer.js';
async function deleteUpload(viewer: Viewer, id: string): Promise<void> {
if (!viewer.loggedIn) {
diff --git a/keyserver/src/emails/sendmail.js b/keyserver/src/emails/sendmail.js
--- a/keyserver/src/emails/sendmail.js
+++ b/keyserver/src/emails/sendmail.js
@@ -3,7 +3,7 @@
import invariant from 'invariant';
import nodemailer from 'nodemailer';
-import { isDev } from 'lib/utils/dev-utils';
+import { isDev } from 'lib/utils/dev-utils.js';
import { importJSON } from '../utils/import-json.js';
diff --git a/keyserver/src/emails/subscribe-email-updates.js b/keyserver/src/emails/subscribe-email-updates.js
--- a/keyserver/src/emails/subscribe-email-updates.js
+++ b/keyserver/src/emails/subscribe-email-updates.js
@@ -3,11 +3,11 @@
import * as React from 'react';
import { Item, Span, renderEmail } from 'react-html-email';
-import ashoat from 'lib/facts/ashoat';
-import type { EmailSubscriptionRequest } from 'lib/types/account-types';
+import ashoat from 'lib/facts/ashoat.js';
+import type { EmailSubscriptionRequest } from 'lib/types/account-types.js';
-import getSendmail from './sendmail';
-import Template from './template.react';
+import getSendmail from './sendmail.js';
+import Template from './template.react.js';
async function sendEmailSubscriptionRequestToAshoat(
request: EmailSubscriptionRequest,
diff --git a/keyserver/src/endpoints.js b/keyserver/src/endpoints.js
--- a/keyserver/src/endpoints.js
+++ b/keyserver/src/endpoints.js
@@ -1,13 +1,13 @@
// @flow
import { baseLegalPolicies } from 'lib/facts/policies.js';
-import type { Endpoint } from 'lib/types/endpoints';
+import type { Endpoint } from 'lib/types/endpoints.js';
import {
updateActivityResponder,
threadSetUnreadStatusResponder,
-} from './responders/activity-responders';
-import { deviceTokenUpdateResponder } from './responders/device-responders';
+} from './responders/activity-responders.js';
+import { deviceTokenUpdateResponder } from './responders/device-responders.js';
import {
entryFetchResponder,
entryRevisionFetchResponder,
@@ -16,24 +16,24 @@
entryDeletionResponder,
entryRestorationResponder,
calendarQueryUpdateResponder,
-} from './responders/entry-responders';
-import type { JSONResponder } from './responders/handlers';
-import { getSessionPublicKeysResponder } from './responders/keys-responders';
-import { messageReportCreationResponder } from './responders/message-report-responder';
+} from './responders/entry-responders.js';
+import type { JSONResponder } from './responders/handlers.js';
+import { getSessionPublicKeysResponder } from './responders/keys-responders.js';
+import { messageReportCreationResponder } from './responders/message-report-responder.js';
import {
textMessageCreationResponder,
messageFetchResponder,
multimediaMessageCreationResponder,
reactionMessageCreationResponder,
-} from './responders/message-responders';
-import { updateRelationshipsResponder } from './responders/relationship-responders';
+} from './responders/message-responders.js';
+import { updateRelationshipsResponder } from './responders/relationship-responders.js';
import {
reportCreationResponder,
reportMultiCreationResponder,
errorReportFetchInfosResponder,
-} from './responders/report-responders';
-import { userSearchResponder } from './responders/search-responders';
-import { siweNonceResponder } from './responders/siwe-nonce-responders';
+} from './responders/report-responders.js';
+import { userSearchResponder } from './responders/search-responders.js';
+import { siweNonceResponder } from './responders/siwe-nonce-responders.js';
import {
threadDeletionResponder,
roleUpdateResponder,
@@ -42,7 +42,7 @@
threadUpdateResponder,
threadCreationResponder,
threadJoinResponder,
-} from './responders/thread-responders';
+} from './responders/thread-responders.js';
import {
userSubscriptionUpdateResponder,
passwordUpdateResponder,
@@ -56,9 +56,9 @@
oldPasswordUpdateResponder,
updateUserSettingsResponder,
policyAcknowledgmentResponder,
-} from './responders/user-responders';
-import { codeVerificationResponder } from './responders/verification-responders';
-import { uploadDeletionResponder } from './uploads/uploads';
+} from './responders/user-responders.js';
+import { codeVerificationResponder } from './responders/verification-responders.js';
+import { uploadDeletionResponder } from './uploads/uploads.js';
const jsonEndpoints: { [id: Endpoint]: JSONResponder } = {
create_account: {
diff --git a/keyserver/src/fetchers/entry-fetchers.js b/keyserver/src/fetchers/entry-fetchers.js
--- a/keyserver/src/fetchers/entry-fetchers.js
+++ b/keyserver/src/fetchers/entry-fetchers.js
@@ -2,38 +2,38 @@
import invariant from 'invariant';
-import { permissionLookup } from 'lib/permissions/thread-permissions';
+import { permissionLookup } from 'lib/permissions/thread-permissions.js';
import {
filteredThreadIDs,
filterExists,
nonExcludeDeletedCalendarFilters,
-} from 'lib/selectors/calendar-filter-selectors';
-import { rawEntryInfoWithinCalendarQuery } from 'lib/shared/entry-utils';
+} from 'lib/selectors/calendar-filter-selectors.js';
+import { rawEntryInfoWithinCalendarQuery } from 'lib/shared/entry-utils.js';
import type {
CalendarQuery,
FetchEntryInfosBase,
DeltaEntryInfosResponse,
RawEntryInfo,
-} from 'lib/types/entry-types';
-import { calendarThreadFilterTypes } from 'lib/types/filter-types';
-import type { HistoryRevisionInfo } from 'lib/types/history-types';
+} from 'lib/types/entry-types.js';
+import { calendarThreadFilterTypes } from 'lib/types/filter-types.js';
+import type { HistoryRevisionInfo } from 'lib/types/history-types.js';
import {
threadPermissions,
type ThreadPermission,
-} from 'lib/types/thread-types';
-import { dateString } from 'lib/utils/date-utils';
-import { ServerError } from 'lib/utils/errors';
+} from 'lib/types/thread-types.js';
+import { dateString } from 'lib/utils/date-utils.js';
+import { ServerError } from 'lib/utils/errors.js';
import {
dbQuery,
SQL,
mergeAndConditions,
mergeOrConditions,
-} from '../database/database';
-import type { SQLStatementType } from '../database/types';
-import type { Viewer } from '../session/viewer';
-import { creationString } from '../utils/idempotent';
-import { checkIfThreadIsBlocked } from './thread-permission-fetchers';
+} from '../database/database.js';
+import type { SQLStatementType } from '../database/types.js';
+import type { Viewer } from '../session/viewer.js';
+import { creationString } from '../utils/idempotent.js';
+import { checkIfThreadIsBlocked } from './thread-permission-fetchers.js';
async function fetchEntryInfo(
viewer: Viewer,
diff --git a/keyserver/src/fetchers/key-fetchers.js b/keyserver/src/fetchers/key-fetchers.js
--- a/keyserver/src/fetchers/key-fetchers.js
+++ b/keyserver/src/fetchers/key-fetchers.js
@@ -1,11 +1,11 @@
// @flow
-import type { SessionPublicKeys } from 'lib/types/session-types';
-import { minimumOneTimeKeysRequired } from 'lib/utils/crypto-utils';
-import { ServerError } from 'lib/utils/errors';
+import type { SessionPublicKeys } from 'lib/types/session-types.js';
+import { minimumOneTimeKeysRequired } from 'lib/utils/crypto-utils.js';
+import { ServerError } from 'lib/utils/errors.js';
-import { dbQuery, SQL } from '../database/database';
-import { deleteOneTimeKey } from '../deleters/one-time-key-deleters';
+import { dbQuery, SQL } from '../database/database.js';
+import { deleteOneTimeKey } from '../deleters/one-time-key-deleters.js';
async function checkIfSessionHasEnoughOneTimeKeys(
session: string,
diff --git a/keyserver/src/fetchers/message-fetchers.js b/keyserver/src/fetchers/message-fetchers.js
--- a/keyserver/src/fetchers/message-fetchers.js
+++ b/keyserver/src/fetchers/message-fetchers.js
@@ -5,10 +5,10 @@
import {
sortMessageInfoList,
shimUnsupportedRawMessageInfos,
-} from 'lib/shared/message-utils';
-import { messageSpecs } from 'lib/shared/messages/message-specs';
-import { notifCollapseKeyForRawMessageInfo } from 'lib/shared/notif-utils';
-import { hasMinCodeVersion } from 'lib/shared/version-utils';
+} from 'lib/shared/message-utils.js';
+import { messageSpecs } from 'lib/shared/messages/message-specs.js';
+import { notifCollapseKeyForRawMessageInfo } from 'lib/shared/notif-utils.js';
+import { hasMinCodeVersion } from 'lib/shared/version-utils.js';
import {
type RawMessageInfo,
type RawComposableMessageInfo,
@@ -21,24 +21,27 @@
messageTruncationStatus,
type FetchMessageInfosResult,
defaultMaxMessageAge,
-} from 'lib/types/message-types';
-import { threadPermissions } from 'lib/types/thread-types';
-import { ServerError } from 'lib/utils/errors';
+} from 'lib/types/message-types.js';
+import { threadPermissions } from 'lib/types/thread-types.js';
+import { ServerError } from 'lib/utils/errors.js';
import {
dbQuery,
SQL,
mergeOrConditions,
mergeAndConditions,
-} from '../database/database';
-import type { SQLStatementType } from '../database/types';
-import type { PushInfo } from '../push/send';
-import type { Viewer } from '../session/viewer';
-import { creationString, localIDFromCreationString } from '../utils/idempotent';
+} from '../database/database.js';
+import type { SQLStatementType } from '../database/types.js';
+import type { PushInfo } from '../push/send.js';
+import type { Viewer } from '../session/viewer.js';
+import {
+ creationString,
+ localIDFromCreationString,
+} from '../utils/idempotent.js';
import {
constructMediaFromMediaMessageContentsAndUploadRows,
mediaFromRow,
-} from './upload-fetchers';
+} from './upload-fetchers.js';
export type CollapsableNotifInfo = {
collapseKey: ?string,
diff --git a/keyserver/src/fetchers/relationship-fetchers.js b/keyserver/src/fetchers/relationship-fetchers.js
--- a/keyserver/src/fetchers/relationship-fetchers.js
+++ b/keyserver/src/fetchers/relationship-fetchers.js
@@ -1,12 +1,15 @@
// @flow
-import _groupBy from 'lodash/fp/groupBy';
+import _groupBy from 'lodash/fp/groupBy.js';
-import type { RelationshipErrors } from 'lib/types/relationship-types';
-import { undirectedStatus, directedStatus } from 'lib/types/relationship-types';
+import type { RelationshipErrors } from 'lib/types/relationship-types.js';
+import {
+ undirectedStatus,
+ directedStatus,
+} from 'lib/types/relationship-types.js';
-import { dbQuery, SQL } from '../database/database';
-import type { Viewer } from '../session/viewer';
+import { dbQuery, SQL } from '../database/database.js';
+import type { Viewer } from '../session/viewer.js';
type RelationshipOperation =
| 'delete_directed'
diff --git a/keyserver/src/fetchers/report-fetchers.js b/keyserver/src/fetchers/report-fetchers.js
--- a/keyserver/src/fetchers/report-fetchers.js
+++ b/keyserver/src/fetchers/report-fetchers.js
@@ -1,17 +1,17 @@
// @flow
-import { isStaff } from 'lib/shared/user-utils';
+import { isStaff } from 'lib/shared/user-utils.js';
import {
type FetchErrorReportInfosResponse,
type FetchErrorReportInfosRequest,
type ReduxToolsImport,
reportTypes,
-} from 'lib/types/report-types';
-import { ServerError } from 'lib/utils/errors';
-import { values } from 'lib/utils/objects';
+} from 'lib/types/report-types.js';
+import { ServerError } from 'lib/utils/errors.js';
+import { values } from 'lib/utils/objects.js';
-import { dbQuery, SQL } from '../database/database';
-import type { Viewer } from '../session/viewer';
+import { dbQuery, SQL } from '../database/database.js';
+import type { Viewer } from '../session/viewer.js';
async function fetchErrorReportInfos(
viewer: Viewer,
diff --git a/keyserver/src/fetchers/role-fetchers.js b/keyserver/src/fetchers/role-fetchers.js
--- a/keyserver/src/fetchers/role-fetchers.js
+++ b/keyserver/src/fetchers/role-fetchers.js
@@ -1,8 +1,8 @@
// @flow
-import type { RoleInfo } from 'lib/types/thread-types';
+import type { RoleInfo } from 'lib/types/thread-types.js';
-import { dbQuery, SQL } from '../database/database';
+import { dbQuery, SQL } from '../database/database.js';
async function fetchRoles(threadID: string): Promise<RoleInfo[]> {
const query = SQL`
diff --git a/keyserver/src/fetchers/session-fetchers.js b/keyserver/src/fetchers/session-fetchers.js
--- a/keyserver/src/fetchers/session-fetchers.js
+++ b/keyserver/src/fetchers/session-fetchers.js
@@ -1,9 +1,9 @@
// @flow
-import type { CalendarQuery } from 'lib/types/entry-types';
+import type { CalendarQuery } from 'lib/types/entry-types.js';
-import { dbQuery, SQL } from '../database/database';
-import type { Viewer } from '../session/viewer';
+import { dbQuery, SQL } from '../database/database.js';
+import type { Viewer } from '../session/viewer.js';
type CalendarSessionResult = {
userID: string,
diff --git a/keyserver/src/fetchers/thread-fetchers.js b/keyserver/src/fetchers/thread-fetchers.js
--- a/keyserver/src/fetchers/thread-fetchers.js
+++ b/keyserver/src/fetchers/thread-fetchers.js
@@ -1,24 +1,24 @@
// @flow
-import { getAllThreadPermissions } from 'lib/permissions/thread-permissions';
+import { getAllThreadPermissions } from 'lib/permissions/thread-permissions.js';
import {
rawThreadInfoFromServerThreadInfo,
getContainingThreadID,
getCommunity,
-} from 'lib/shared/thread-utils';
-import { hasMinCodeVersion } from 'lib/shared/version-utils';
-import type { RawMessageInfo, MessageInfo } from 'lib/types/message-types';
+} from 'lib/shared/thread-utils.js';
+import { hasMinCodeVersion } from 'lib/shared/version-utils.js';
+import type { RawMessageInfo, MessageInfo } from 'lib/types/message-types.js';
import {
threadTypes,
type ThreadType,
type RawThreadInfo,
type ServerThreadInfo,
-} from 'lib/types/thread-types';
-import { ServerError } from 'lib/utils/errors';
+} from 'lib/types/thread-types.js';
+import { ServerError } from 'lib/utils/errors.js';
-import { dbQuery, SQL } from '../database/database';
-import type { SQLStatementType } from '../database/types';
-import type { Viewer } from '../session/viewer';
+import { dbQuery, SQL } from '../database/database.js';
+import type { SQLStatementType } from '../database/types.js';
+import type { Viewer } from '../session/viewer.js';
type FetchServerThreadInfosResult = {
+threadInfos: { +[id: string]: ServerThreadInfo },
diff --git a/keyserver/src/fetchers/thread-permission-fetchers.js b/keyserver/src/fetchers/thread-permission-fetchers.js
--- a/keyserver/src/fetchers/thread-permission-fetchers.js
+++ b/keyserver/src/fetchers/thread-permission-fetchers.js
@@ -4,24 +4,24 @@
permissionLookup,
makePermissionsBlob,
getRoleForPermissions,
-} from 'lib/permissions/thread-permissions';
-import { relationshipBlockedInEitherDirection } from 'lib/shared/relationship-utils';
+} from 'lib/permissions/thread-permissions.js';
+import { relationshipBlockedInEitherDirection } from 'lib/shared/relationship-utils.js';
import {
threadFrozenDueToBlock,
permissionsDisabledByBlock,
-} from 'lib/shared/thread-utils';
-import { userRelationshipStatus } from 'lib/types/relationship-types';
+} from 'lib/shared/thread-utils.js';
+import { userRelationshipStatus } from 'lib/types/relationship-types.js';
import type {
ThreadType,
ThreadPermission,
ThreadPermissionsBlob,
ThreadRolePermissionsBlob,
-} from 'lib/types/thread-types';
+} from 'lib/types/thread-types.js';
-import { dbQuery, SQL } from '../database/database';
-import type { Viewer } from '../session/viewer';
-import { fetchThreadInfos } from './thread-fetchers';
-import { fetchKnownUserInfos } from './user-fetchers';
+import { dbQuery, SQL } from '../database/database.js';
+import type { Viewer } from '../session/viewer.js';
+import { fetchThreadInfos } from './thread-fetchers.js';
+import { fetchKnownUserInfos } from './user-fetchers.js';
// Note that it's risky to verify permissions by inspecting the blob directly.
// There are other factors that can override permissions in the permissions
diff --git a/keyserver/src/fetchers/update-fetchers.js b/keyserver/src/fetchers/update-fetchers.js
--- a/keyserver/src/fetchers/update-fetchers.js
+++ b/keyserver/src/fetchers/update-fetchers.js
@@ -2,22 +2,22 @@
import invariant from 'invariant';
-import type { CalendarQuery } from 'lib/types/entry-types';
+import type { CalendarQuery } from 'lib/types/entry-types.js';
import {
type RawUpdateInfo,
updateTypes,
assertUpdateType,
-} from 'lib/types/update-types';
-import { ServerError } from 'lib/utils/errors';
+} from 'lib/types/update-types.js';
+import { ServerError } from 'lib/utils/errors.js';
-import type { ViewerInfo } from '../creators/update-creator';
+import type { ViewerInfo } from '../creators/update-creator.js';
import {
type FetchUpdatesResult,
fetchUpdateInfosWithRawUpdateInfos,
-} from '../creators/update-creator';
-import { dbQuery, SQL } from '../database/database';
-import type { SQLStatementType } from '../database/types';
-import type { Viewer } from '../session/viewer';
+} from '../creators/update-creator.js';
+import { dbQuery, SQL } from '../database/database.js';
+import type { SQLStatementType } from '../database/types.js';
+import type { Viewer } from '../session/viewer.js';
const defaultUpdateFetchResult = { updateInfos: [], userInfos: {} };
diff --git a/keyserver/src/fetchers/upload-fetchers.js b/keyserver/src/fetchers/upload-fetchers.js
--- a/keyserver/src/fetchers/upload-fetchers.js
+++ b/keyserver/src/fetchers/upload-fetchers.js
@@ -1,15 +1,15 @@
// @flow
-import _keyBy from 'lodash/fp/keyBy';
+import _keyBy from 'lodash/fp/keyBy.js';
-import type { Media } from 'lib/types/media-types';
+import type { Media } from 'lib/types/media-types.js';
import type { MediaMessageServerDBContent } from 'lib/types/messages/media.js';
import { getUploadIDsFromMediaMessageServerDBContents } from 'lib/types/messages/media.js';
-import { ServerError } from 'lib/utils/errors';
+import { ServerError } from 'lib/utils/errors.js';
-import { dbQuery, SQL } from '../database/database';
-import type { Viewer } from '../session/viewer';
-import { getAndAssertCommAppURLFacts } from '../utils/urls';
+import { dbQuery, SQL } from '../database/database.js';
+import type { Viewer } from '../session/viewer.js';
+import { getAndAssertCommAppURLFacts } from '../utils/urls.js';
type UploadInfo = {
content: Buffer,
diff --git a/keyserver/src/fetchers/user-fetchers.js b/keyserver/src/fetchers/user-fetchers.js
--- a/keyserver/src/fetchers/user-fetchers.js
+++ b/keyserver/src/fetchers/user-fetchers.js
@@ -1,15 +1,15 @@
// @flow
-import { hasMinCodeVersion } from 'lib/shared/version-utils';
+import { hasMinCodeVersion } from 'lib/shared/version-utils.js';
import {
undirectedStatus,
directedStatus,
userRelationshipStatus,
-} from 'lib/types/relationship-types';
+} from 'lib/types/relationship-types.js';
import {
communityThreadTypes,
threadPermissions,
-} from 'lib/types/thread-types';
+} from 'lib/types/thread-types.js';
import type {
UserInfos,
CurrentUserInfo,
@@ -17,11 +17,11 @@
LoggedInUserInfo,
OldLoggedInUserInfo,
GlobalUserInfo,
-} from 'lib/types/user-types';
-import { ServerError } from 'lib/utils/errors';
+} from 'lib/types/user-types.js';
+import { ServerError } from 'lib/utils/errors.js';
-import { dbQuery, SQL } from '../database/database';
-import type { Viewer } from '../session/viewer';
+import { dbQuery, SQL } from '../database/database.js';
+import type { Viewer } from '../session/viewer.js';
async function fetchUserInfos(
userIDs: string[],
diff --git a/keyserver/src/keyserver.js b/keyserver/src/keyserver.js
--- a/keyserver/src/keyserver.js
+++ b/keyserver/src/keyserver.js
@@ -6,36 +6,36 @@
import expressWs from 'express-ws';
import os from 'os';
-import './cron/cron';
-import { migrate } from './database/migrations';
-import { jsonEndpoints } from './endpoints';
-import { emailSubscriptionResponder } from './responders/comm-landing-responders';
+import './cron/cron.js';
+import { migrate } from './database/migrations.js';
+import { jsonEndpoints } from './endpoints.js';
+import { emailSubscriptionResponder } from './responders/comm-landing-responders.js';
import {
jsonHandler,
httpGetHandler,
downloadHandler,
htmlHandler,
uploadHandler,
-} from './responders/handlers';
-import landingHandler from './responders/landing-handler';
-import { errorReportDownloadResponder } from './responders/report-responders';
+} from './responders/handlers.js';
+import landingHandler from './responders/landing-handler.js';
+import { errorReportDownloadResponder } from './responders/report-responders.js';
import {
createNewVersionResponder,
markVersionDeployedResponder,
-} from './responders/version-responders';
-import { websiteResponder } from './responders/website-responders';
-import { onConnection } from './socket/socket';
+} from './responders/version-responders.js';
+import { websiteResponder } from './responders/website-responders.js';
+import { onConnection } from './socket/socket.js';
import {
multerProcessor,
multimediaUploadResponder,
uploadDownloadResponder,
-} from './uploads/uploads';
+} from './uploads/uploads.js';
import {
prefetchAllURLFacts,
getSquadCalURLFacts,
getLandingURLFacts,
getCommAppURLFacts,
-} from './utils/urls';
+} from './utils/urls.js';
(async () => {
await prefetchAllURLFacts();
diff --git a/keyserver/src/push/providers.js b/keyserver/src/push/providers.js
--- a/keyserver/src/push/providers.js
+++ b/keyserver/src/push/providers.js
@@ -6,7 +6,7 @@
import type { FirebaseApp } from 'firebase-admin';
import invariant from 'invariant';
-import { importJSON } from '../utils/import-json';
+import { importJSON } from '../utils/import-json.js';
type APNPushProfile = 'apn_config' | 'comm_apn_config';
function getAPNPushProfileForCodeVersion(codeVersion: ?number): APNPushProfile {
diff --git a/keyserver/src/push/rescind.js b/keyserver/src/push/rescind.js
--- a/keyserver/src/push/rescind.js
+++ b/keyserver/src/push/rescind.js
@@ -3,15 +3,15 @@
import apn from '@parse/node-apn';
import invariant from 'invariant';
-import { threadSubscriptions } from 'lib/types/subscription-types';
-import { threadPermissions } from 'lib/types/thread-types';
-import { promiseAll } from 'lib/utils/promises';
+import { threadSubscriptions } from 'lib/types/subscription-types.js';
+import { threadPermissions } from 'lib/types/thread-types.js';
+import { promiseAll } from 'lib/utils/promises.js';
-import createIDs from '../creators/id-creator';
-import { dbQuery, SQL } from '../database/database';
-import type { SQLStatementType } from '../database/types';
-import { getAPNsNotificationTopic } from './providers';
-import { apnPush, fcmPush } from './utils';
+import createIDs from '../creators/id-creator.js';
+import { dbQuery, SQL } from '../database/database.js';
+import type { SQLStatementType } from '../database/types.js';
+import { getAPNsNotificationTopic } from './providers.js';
+import { apnPush, fcmPush } from './utils.js';
async function rescindPushNotifs(
notifCondition: SQLStatementType,
diff --git a/keyserver/src/push/send.js b/keyserver/src/push/send.js
--- a/keyserver/src/push/send.js
+++ b/keyserver/src/push/send.js
@@ -3,51 +3,51 @@
import apn from '@parse/node-apn';
import type { ResponseFailure } from '@parse/node-apn';
import invariant from 'invariant';
-import _cloneDeep from 'lodash/fp/cloneDeep';
-import _flow from 'lodash/fp/flow';
-import _mapValues from 'lodash/fp/mapValues';
-import _pickBy from 'lodash/fp/pickBy';
-import uuidv4 from 'uuid/v4';
+import _cloneDeep from 'lodash/fp/cloneDeep.js';
+import _flow from 'lodash/fp/flow.js';
+import _mapValues from 'lodash/fp/mapValues.js';
+import _pickBy from 'lodash/fp/pickBy.js';
+import uuidv4 from 'uuid/v4.js';
-import { oldValidUsernameRegex } from 'lib/shared/account-utils';
+import { oldValidUsernameRegex } from 'lib/shared/account-utils.js';
import {
createMessageInfo,
sortMessageInfoList,
shimUnsupportedRawMessageInfos,
-} from 'lib/shared/message-utils';
-import { messageSpecs } from 'lib/shared/messages/message-specs';
-import { notifTextsForMessageInfo } from 'lib/shared/notif-utils';
+} from 'lib/shared/message-utils.js';
+import { messageSpecs } from 'lib/shared/messages/message-specs.js';
+import { notifTextsForMessageInfo } from 'lib/shared/notif-utils.js';
import {
rawThreadInfoFromServerThreadInfo,
threadInfoFromRawThreadInfo,
-} from 'lib/shared/thread-utils';
-import type { DeviceType } from 'lib/types/device-types';
+} from 'lib/shared/thread-utils.js';
+import type { DeviceType } from 'lib/types/device-types.js';
import {
type RawMessageInfo,
type MessageInfo,
messageTypes,
-} from 'lib/types/message-types';
-import type { ServerThreadInfo, ThreadInfo } from 'lib/types/thread-types';
-import { updateTypes } from 'lib/types/update-types';
-import { promiseAll } from 'lib/utils/promises';
-
-import createIDs from '../creators/id-creator';
-import { createUpdates } from '../creators/update-creator';
-import { dbQuery, SQL, mergeOrConditions } from '../database/database';
-import type { CollapsableNotifInfo } from '../fetchers/message-fetchers';
-import { fetchCollapsableNotifs } from '../fetchers/message-fetchers';
-import { fetchServerThreadInfos } from '../fetchers/thread-fetchers';
-import { fetchUserInfos } from '../fetchers/user-fetchers';
-import type { Viewer } from '../session/viewer';
-import { getENSNames } from '../utils/ens-cache';
-import { getAPNsNotificationTopic } from './providers';
+} from 'lib/types/message-types.js';
+import type { ServerThreadInfo, ThreadInfo } from 'lib/types/thread-types.js';
+import { updateTypes } from 'lib/types/update-types.js';
+import { promiseAll } from 'lib/utils/promises.js';
+
+import createIDs from '../creators/id-creator.js';
+import { createUpdates } from '../creators/update-creator.js';
+import { dbQuery, SQL, mergeOrConditions } from '../database/database.js';
+import type { CollapsableNotifInfo } from '../fetchers/message-fetchers.js';
+import { fetchCollapsableNotifs } from '../fetchers/message-fetchers.js';
+import { fetchServerThreadInfos } from '../fetchers/thread-fetchers.js';
+import { fetchUserInfos } from '../fetchers/user-fetchers.js';
+import type { Viewer } from '../session/viewer.js';
+import { getENSNames } from '../utils/ens-cache.js';
+import { getAPNsNotificationTopic } from './providers.js';
import {
apnPush,
fcmPush,
getUnreadCounts,
apnMaxNotificationPayloadByteSize,
fcmMaxNotificationPayloadByteSize,
-} from './utils';
+} from './utils.js';
type Device = {
+deviceType: DeviceType,
diff --git a/keyserver/src/push/utils.js b/keyserver/src/push/utils.js
--- a/keyserver/src/push/utils.js
+++ b/keyserver/src/push/utils.js
@@ -5,16 +5,16 @@
import type { FirebaseApp, FirebaseError } from 'firebase-admin';
import invariant from 'invariant';
-import { threadSubscriptions } from 'lib/types/subscription-types';
-import { threadPermissions } from 'lib/types/thread-types';
+import { threadSubscriptions } from 'lib/types/subscription-types.js';
+import { threadPermissions } from 'lib/types/thread-types.js';
-import { dbQuery, SQL } from '../database/database';
+import { dbQuery, SQL } from '../database/database.js';
import {
getAPNPushProfileForCodeVersion,
getFCMPushProfileForCodeVersion,
getAPNProvider,
getFCMProvider,
-} from './providers';
+} from './providers.js';
const fcmTokenInvalidationErrors = new Set([
'messaging/registration-token-not-registered',
diff --git a/keyserver/src/responders/activity-responders.js b/keyserver/src/responders/activity-responders.js
--- a/keyserver/src/responders/activity-responders.js
+++ b/keyserver/src/responders/activity-responders.js
@@ -8,15 +8,15 @@
UpdateActivityRequest,
SetThreadUnreadStatusRequest,
SetThreadUnreadStatusResult,
-} from 'lib/types/activity-types';
-import { tShape } from 'lib/utils/validation-utils';
+} from 'lib/types/activity-types.js';
+import { tShape } from 'lib/utils/validation-utils.js';
-import type { Viewer } from '../session/viewer';
+import type { Viewer } from '../session/viewer.js';
import {
activityUpdater,
setThreadUnreadStatus,
-} from '../updaters/activity-updaters';
-import { validateInput } from '../utils/validation-utils';
+} from '../updaters/activity-updaters.js';
+import { validateInput } from '../utils/validation-utils.js';
const activityUpdatesInputValidator: TList<TInterface> = t.list(
tShape({
diff --git a/keyserver/src/responders/comm-landing-responders.js b/keyserver/src/responders/comm-landing-responders.js
--- a/keyserver/src/responders/comm-landing-responders.js
+++ b/keyserver/src/responders/comm-landing-responders.js
@@ -2,12 +2,12 @@
import type { $Response, $Request } from 'express';
-import { type EmailSubscriptionRequest } from 'lib/types/account-types';
-import { ServerError } from 'lib/utils/errors';
-import { tShape, tEmail } from 'lib/utils/validation-utils';
+import { type EmailSubscriptionRequest } from 'lib/types/account-types.js';
+import { ServerError } from 'lib/utils/errors.js';
+import { tShape, tEmail } from 'lib/utils/validation-utils.js';
-import { sendEmailSubscriptionRequestToAshoat } from '../emails/subscribe-email-updates';
-import { checkInputValidator } from '../utils/validation-utils';
+import { sendEmailSubscriptionRequestToAshoat } from '../emails/subscribe-email-updates.js';
+import { checkInputValidator } from '../utils/validation-utils.js';
const emailSubscriptionInputValidator = tShape({
email: tEmail,
diff --git a/keyserver/src/responders/device-responders.js b/keyserver/src/responders/device-responders.js
--- a/keyserver/src/responders/device-responders.js
+++ b/keyserver/src/responders/device-responders.js
@@ -3,12 +3,12 @@
import t from 'tcomb';
import type { TInterface } from 'tcomb';
-import type { DeviceTokenUpdateRequest } from 'lib/types/device-types';
-import { tShape, tPlatformDetails } from 'lib/utils/validation-utils';
+import type { DeviceTokenUpdateRequest } from 'lib/types/device-types.js';
+import { tShape, tPlatformDetails } from 'lib/utils/validation-utils.js';
-import type { Viewer } from '../session/viewer';
-import { deviceTokenUpdater } from '../updaters/device-token-updaters';
-import { validateInput } from '../utils/validation-utils';
+import type { Viewer } from '../session/viewer.js';
+import { deviceTokenUpdater } from '../updaters/device-token-updaters.js';
+import { validateInput } from '../utils/validation-utils.js';
const deviceTokenUpdateRequestInputValidator: TInterface = tShape({
deviceToken: t.maybe(t.String),
diff --git a/keyserver/src/responders/entry-responders.js b/keyserver/src/responders/entry-responders.js
--- a/keyserver/src/responders/entry-responders.js
+++ b/keyserver/src/responders/entry-responders.js
@@ -3,7 +3,7 @@
import t from 'tcomb';
import type { TInterface } from 'tcomb';
-import { filteredThreadIDs } from 'lib/selectors/calendar-filter-selectors';
+import { filteredThreadIDs } from 'lib/selectors/calendar-filter-selectors.js';
import type {
CalendarQuery,
SaveEntryRequest,
@@ -15,30 +15,30 @@
FetchEntryInfosResponse,
DeltaEntryInfosResult,
SaveEntryResponse,
-} from 'lib/types/entry-types';
-import { calendarThreadFilterTypes } from 'lib/types/filter-types';
+} from 'lib/types/entry-types.js';
+import { calendarThreadFilterTypes } from 'lib/types/filter-types.js';
import type {
FetchEntryRevisionInfosResult,
FetchEntryRevisionInfosRequest,
-} from 'lib/types/history-types';
-import { ServerError } from 'lib/utils/errors';
-import { tString, tShape, tDate } from 'lib/utils/validation-utils';
+} from 'lib/types/history-types.js';
+import { ServerError } from 'lib/utils/errors.js';
+import { tString, tShape, tDate } from 'lib/utils/validation-utils.js';
-import createEntry from '../creators/entry-creator';
-import { deleteEntry, restoreEntry } from '../deleters/entry-deleters';
+import createEntry from '../creators/entry-creator.js';
+import { deleteEntry, restoreEntry } from '../deleters/entry-deleters.js';
import {
fetchEntryInfos,
fetchEntryRevisionInfo,
fetchEntriesForSession,
-} from '../fetchers/entry-fetchers';
-import { verifyThreadIDs } from '../fetchers/thread-fetchers';
-import type { Viewer } from '../session/viewer';
+} from '../fetchers/entry-fetchers.js';
+import { verifyThreadIDs } from '../fetchers/thread-fetchers.js';
+import type { Viewer } from '../session/viewer.js';
import {
updateEntry,
compareNewCalendarQuery,
-} from '../updaters/entry-updaters';
-import { commitSessionUpdate } from '../updaters/session-updaters';
-import { validateInput } from '../utils/validation-utils';
+} from '../updaters/entry-updaters.js';
+import { commitSessionUpdate } from '../updaters/session-updaters.js';
+import { validateInput } from '../utils/validation-utils.js';
const entryQueryInputValidator: TInterface = tShape({
navID: t.maybe(t.String),
diff --git a/keyserver/src/responders/handlers.js b/keyserver/src/responders/handlers.js
--- a/keyserver/src/responders/handlers.js
+++ b/keyserver/src/responders/handlers.js
@@ -2,9 +2,9 @@
import type { $Response, $Request } from 'express';
-import { ServerError } from 'lib/utils/errors';
+import { ServerError } from 'lib/utils/errors.js';
-import { deleteCookie } from '../deleters/cookie-deleters';
+import { deleteCookie } from '../deleters/cookie-deleters.js';
import type { PolicyType } from '../lib/facts/policies.js';
import {
fetchViewerForJSONRequest,
@@ -12,11 +12,14 @@
fetchViewerForHomeRequest,
addCookieToHomeResponse,
createNewAnonymousCookie,
-} from '../session/cookies';
-import type { Viewer } from '../session/viewer';
-import { type AppURLFacts, getAppURLFactsFromRequestURL } from '../utils/urls';
+} from '../session/cookies.js';
+import type { Viewer } from '../session/viewer.js';
+import {
+ type AppURLFacts,
+ getAppURLFactsFromRequestURL,
+} from '../utils/urls.js';
import { policiesValidator } from '../utils/validation-utils.js';
-import { getMessageForException } from './utils';
+import { getMessageForException } from './utils.js';
export type JSONResponder = {
responder: (viewer: Viewer, input: any) => Promise<*>,
diff --git a/keyserver/src/responders/keys-responders.js b/keyserver/src/responders/keys-responders.js
--- a/keyserver/src/responders/keys-responders.js
+++ b/keyserver/src/responders/keys-responders.js
@@ -2,13 +2,13 @@
import t from 'tcomb';
-import type { GetSessionPublicKeysArgs } from 'lib/types/request-types';
-import type { SessionPublicKeys } from 'lib/types/session-types';
-import { tShape } from 'lib/utils/validation-utils';
+import type { GetSessionPublicKeysArgs } from 'lib/types/request-types.js';
+import type { SessionPublicKeys } from 'lib/types/session-types.js';
+import { tShape } from 'lib/utils/validation-utils.js';
-import { fetchSessionPublicKeys } from '../fetchers/key-fetchers';
-import type { Viewer } from '../session/viewer';
-import { validateInput } from '../utils/validation-utils';
+import { fetchSessionPublicKeys } from '../fetchers/key-fetchers.js';
+import type { Viewer } from '../session/viewer.js';
+import { validateInput } from '../utils/validation-utils.js';
const getSessionPublicKeysInputValidator = tShape({
session: t.String,
diff --git a/keyserver/src/responders/landing-handler.js b/keyserver/src/responders/landing-handler.js
--- a/keyserver/src/responders/landing-handler.js
+++ b/keyserver/src/responders/landing-handler.js
@@ -12,10 +12,10 @@
isValidSIWENonce,
} from 'lib/utils/siwe-utils.js';
-import { type LandingSSRProps } from '../landing/landing-ssr.react';
-import { waitForStream } from '../utils/json-stream';
-import { getAndAssertLandingURLFacts } from '../utils/urls';
-import { getMessageForException } from './utils';
+import { getMessageForException } from './utils.js';
+import { type LandingSSRProps } from '../landing/landing-ssr.react.js';
+import { waitForStream } from '../utils/json-stream.js';
+import { getAndAssertLandingURLFacts } from '../utils/urls.js';
async function landingHandler(req: $Request, res: $Response) {
try {
diff --git a/keyserver/src/responders/message-report-responder.js b/keyserver/src/responders/message-report-responder.js
--- a/keyserver/src/responders/message-report-responder.js
+++ b/keyserver/src/responders/message-report-responder.js
@@ -5,12 +5,12 @@
import {
type MessageReportCreationRequest,
type MessageReportCreationResult,
-} from 'lib/types/message-report-types';
-import { tShape } from 'lib/utils/validation-utils';
+} from 'lib/types/message-report-types.js';
+import { tShape } from 'lib/utils/validation-utils.js';
-import createMessageReport from '../creators/message-report-creator';
-import type { Viewer } from '../session/viewer';
-import { validateInput } from '../utils/validation-utils';
+import createMessageReport from '../creators/message-report-creator.js';
+import type { Viewer } from '../session/viewer.js';
+import { validateInput } from '../utils/validation-utils.js';
const messageReportCreationRequestInputValidator = tShape({
messageID: t.String,
diff --git a/keyserver/src/responders/message-responders.js b/keyserver/src/responders/message-responders.js
--- a/keyserver/src/responders/message-responders.js
+++ b/keyserver/src/responders/message-responders.js
@@ -3,9 +3,12 @@
import invariant from 'invariant';
import t from 'tcomb';
-import { onlyOneEmojiRegex } from 'lib/shared/emojis';
-import { createMediaMessageData, trimMessage } from 'lib/shared/message-utils';
-import { relationshipBlockedInEitherDirection } from 'lib/shared/relationship-utils';
+import { onlyOneEmojiRegex } from 'lib/shared/emojis.js';
+import {
+ createMediaMessageData,
+ trimMessage,
+} from 'lib/shared/message-utils.js';
+import { relationshipBlockedInEitherDirection } from 'lib/shared/relationship-utils.js';
import type { Media } from 'lib/types/media-types.js';
import {
messageTypes,
@@ -16,33 +19,37 @@
type FetchMessageInfosRequest,
defaultNumberPerThread,
type SendMessageResponse,
-} from 'lib/types/message-types';
-import type { ReactionMessageData } from 'lib/types/messages/reaction';
-import type { TextMessageData } from 'lib/types/messages/text';
-import { threadPermissions } from 'lib/types/thread-types';
-import { ServerError } from 'lib/utils/errors';
-import { tRegex, tShape, tMediaMessageMedia } from 'lib/utils/validation-utils';
-
-import createMessages from '../creators/message-creator';
-import { SQL } from '../database/database';
+} from 'lib/types/message-types.js';
+import type { ReactionMessageData } from 'lib/types/messages/reaction.js';
+import type { TextMessageData } from 'lib/types/messages/text.js';
+import { threadPermissions } from 'lib/types/thread-types.js';
+import { ServerError } from 'lib/utils/errors.js';
+import {
+ tRegex,
+ tShape,
+ tMediaMessageMedia,
+} from 'lib/utils/validation-utils.js';
+
+import createMessages from '../creators/message-creator.js';
+import { SQL } from '../database/database.js';
import {
fetchMessageInfos,
fetchMessageInfoForLocalID,
fetchMessageInfoByID,
-} from '../fetchers/message-fetchers';
-import { fetchServerThreadInfos } from '../fetchers/thread-fetchers';
-import { checkThreadPermission } from '../fetchers/thread-permission-fetchers';
+} from '../fetchers/message-fetchers.js';
+import { fetchServerThreadInfos } from '../fetchers/thread-fetchers.js';
+import { checkThreadPermission } from '../fetchers/thread-permission-fetchers.js';
import {
fetchMedia,
fetchMediaFromMediaMessageContent,
-} from '../fetchers/upload-fetchers';
-import { fetchKnownUserInfos } from '../fetchers/user-fetchers';
-import type { Viewer } from '../session/viewer';
+} from '../fetchers/upload-fetchers.js';
+import { fetchKnownUserInfos } from '../fetchers/user-fetchers.js';
+import type { Viewer } from '../session/viewer.js';
import {
assignMedia,
assignMessageContainerToMedia,
-} from '../updaters/upload-updaters';
-import { validateInput } from '../utils/validation-utils';
+} from '../updaters/upload-updaters.js';
+import { validateInput } from '../utils/validation-utils.js';
const sendTextMessageRequestInputValidator = tShape({
threadID: t.String,
diff --git a/keyserver/src/responders/relationship-responders.js b/keyserver/src/responders/relationship-responders.js
--- a/keyserver/src/responders/relationship-responders.js
+++ b/keyserver/src/responders/relationship-responders.js
@@ -6,12 +6,12 @@
type RelationshipRequest,
type RelationshipErrors,
relationshipActionsList,
-} from 'lib/types/relationship-types';
-import { tShape } from 'lib/utils/validation-utils';
+} from 'lib/types/relationship-types.js';
+import { tShape } from 'lib/utils/validation-utils.js';
-import type { Viewer } from '../session/viewer';
-import { updateRelationships } from '../updaters/relationship-updaters';
-import { validateInput } from '../utils/validation-utils';
+import type { Viewer } from '../session/viewer.js';
+import { updateRelationships } from '../updaters/relationship-updaters.js';
+import { validateInput } from '../utils/validation-utils.js';
const updateRelationshipInputValidator = tShape({
action: t.enums.of(relationshipActionsList, 'relationship action'),
diff --git a/keyserver/src/responders/report-responders.js b/keyserver/src/responders/report-responders.js
--- a/keyserver/src/responders/report-responders.js
+++ b/keyserver/src/responders/report-responders.js
@@ -10,22 +10,22 @@
type FetchErrorReportInfosResponse,
type FetchErrorReportInfosRequest,
reportTypes,
-} from 'lib/types/report-types';
-import { ServerError } from 'lib/utils/errors';
+} from 'lib/types/report-types.js';
+import { ServerError } from 'lib/utils/errors.js';
import {
tShape,
tPlatform,
tPlatformDetails,
-} from 'lib/utils/validation-utils';
+} from 'lib/utils/validation-utils.js';
-import createReport from '../creators/report-creator';
+import createReport from '../creators/report-creator.js';
import {
fetchErrorReportInfos,
fetchReduxToolsImport,
-} from '../fetchers/report-fetchers';
-import type { Viewer } from '../session/viewer';
-import { validateInput } from '../utils/validation-utils';
-import { newEntryQueryInputValidator } from './entry-responders';
+} from '../fetchers/report-fetchers.js';
+import type { Viewer } from '../session/viewer.js';
+import { validateInput } from '../utils/validation-utils.js';
+import { newEntryQueryInputValidator } from './entry-responders.js';
const tActionSummary = tShape({
type: t.String,
diff --git a/keyserver/src/responders/search-responders.js b/keyserver/src/responders/search-responders.js
--- a/keyserver/src/responders/search-responders.js
+++ b/keyserver/src/responders/search-responders.js
@@ -5,12 +5,12 @@
import type {
UserSearchRequest,
UserSearchResult,
-} from 'lib/types/search-types';
-import { tShape } from 'lib/utils/validation-utils';
+} from 'lib/types/search-types.js';
+import { tShape } from 'lib/utils/validation-utils.js';
-import { searchForUsers } from '../search/users';
-import type { Viewer } from '../session/viewer';
-import { validateInput } from '../utils/validation-utils';
+import { searchForUsers } from '../search/users.js';
+import type { Viewer } from '../session/viewer.js';
+import { validateInput } from '../utils/validation-utils.js';
const userSearchRequestInputValidator = tShape({
prefix: t.maybe(t.String),
diff --git a/keyserver/src/responders/siwe-nonce-responders.js b/keyserver/src/responders/siwe-nonce-responders.js
--- a/keyserver/src/responders/siwe-nonce-responders.js
+++ b/keyserver/src/responders/siwe-nonce-responders.js
@@ -2,9 +2,9 @@
import { generateNonce } from 'siwe';
-import type { SIWENonceResponse } from 'lib/types/siwe-types';
+import type { SIWENonceResponse } from 'lib/types/siwe-types.js';
-import { createSIWENonceEntry } from '../creators/siwe-nonce-creator';
+import { createSIWENonceEntry } from '../creators/siwe-nonce-creator.js';
async function siweNonceResponder(): Promise<SIWENonceResponse> {
const generatedNonce = generateNonce();
diff --git a/keyserver/src/responders/thread-responders.js b/keyserver/src/responders/thread-responders.js
--- a/keyserver/src/responders/thread-responders.js
+++ b/keyserver/src/responders/thread-responders.js
@@ -16,30 +16,30 @@
type ServerThreadJoinRequest,
type ThreadJoinResult,
threadTypes,
-} from 'lib/types/thread-types';
-import { values } from 'lib/utils/objects';
+} from 'lib/types/thread-types.js';
+import { values } from 'lib/utils/objects.js';
import {
tShape,
tNumEnum,
tColor,
tPassword,
-} from 'lib/utils/validation-utils';
+} from 'lib/utils/validation-utils.js';
-import { createThread } from '../creators/thread-creator';
-import { deleteThread } from '../deleters/thread-deleters';
-import type { Viewer } from '../session/viewer';
+import { createThread } from '../creators/thread-creator.js';
+import { deleteThread } from '../deleters/thread-deleters.js';
+import type { Viewer } from '../session/viewer.js';
import {
updateRole,
removeMembers,
leaveThread,
updateThread,
joinThread,
-} from '../updaters/thread-updaters';
-import { validateInput } from '../utils/validation-utils';
+} from '../updaters/thread-updaters.js';
+import { validateInput } from '../utils/validation-utils.js';
import {
entryQueryInputValidator,
verifyCalendarQueryThreadIDs,
-} from './entry-responders';
+} from './entry-responders.js';
const threadDeletionRequestInputValidator = tShape({
threadID: t.String,
diff --git a/keyserver/src/responders/thread-responders.test.js b/keyserver/src/responders/thread-responders.test.js
--- a/keyserver/src/responders/thread-responders.test.js
+++ b/keyserver/src/responders/thread-responders.test.js
@@ -1,8 +1,8 @@
// @flow
-import { threadTypes } from 'lib/types/thread-types';
+import { threadTypes } from 'lib/types/thread-types.js';
-import { newThreadRequestInputValidator } from './thread-responders';
+import { newThreadRequestInputValidator } from './thread-responders.js';
describe('Thread responders', () => {
describe('New thread request validator', () => {
diff --git a/keyserver/src/responders/user-responders.js b/keyserver/src/responders/user-responders.js
--- a/keyserver/src/responders/user-responders.js
+++ b/keyserver/src/responders/user-responders.js
@@ -6,7 +6,7 @@
import bcrypt from 'twin-bcrypt';
import { baseLegalPolicies, policies } from 'lib/facts/policies.js';
-import { hasMinCodeVersion } from 'lib/shared/version-utils';
+import { hasMinCodeVersion } from 'lib/shared/version-utils.js';
import type {
ResetPasswordRequest,
LogOutResponse,
@@ -18,14 +18,14 @@
UpdatePasswordRequest,
UpdateUserSettingsRequest,
PolicyAcknowledgmentRequest,
-} from 'lib/types/account-types';
+} from 'lib/types/account-types.js';
import {
userSettingsTypes,
notificationTypeValues,
logInActionSources,
-} from 'lib/types/account-types';
+} from 'lib/types/account-types.js';
import type { CalendarQuery } from 'lib/types/entry-types.js';
-import { defaultNumberPerThread } from 'lib/types/message-types';
+import { defaultNumberPerThread } from 'lib/types/message-types.js';
import type {
SIWEAuthRequest,
SIWEMessage,
@@ -34,11 +34,11 @@
import type {
SubscriptionUpdateRequest,
SubscriptionUpdateResponse,
-} from 'lib/types/subscription-types';
-import type { PasswordUpdate } from 'lib/types/user-types';
-import { ServerError } from 'lib/utils/errors';
-import { values } from 'lib/utils/objects';
-import { promiseAll } from 'lib/utils/promises';
+} from 'lib/types/subscription-types.js';
+import type { PasswordUpdate } from 'lib/types/user-types.js';
+import { ServerError } from 'lib/utils/errors.js';
+import { values } from 'lib/utils/objects.js';
+import { promiseAll } from 'lib/utils/promises.js';
import {
getPublicKeyFromSIWEStatement,
isValidSIWEMessage,
@@ -52,47 +52,47 @@
tEmail,
tOldValidUsername,
tRegex,
-} from 'lib/utils/validation-utils';
+} from 'lib/utils/validation-utils.js';
import {
createAccount,
processSIWEAccountCreation,
-} from '../creators/account-creator';
-import { dbQuery, SQL } from '../database/database';
-import { deleteAccount } from '../deleters/account-deleters';
-import { deleteCookie } from '../deleters/cookie-deleters';
+} from '../creators/account-creator.js';
+import { dbQuery, SQL } from '../database/database.js';
+import { deleteAccount } from '../deleters/account-deleters.js';
+import { deleteCookie } from '../deleters/cookie-deleters.js';
import { checkAndInvalidateSIWENonceEntry } from '../deleters/siwe-nonce-deleters.js';
-import { fetchEntryInfos } from '../fetchers/entry-fetchers';
-import { fetchMessageInfos } from '../fetchers/message-fetchers';
+import { fetchEntryInfos } from '../fetchers/entry-fetchers.js';
+import { fetchMessageInfos } from '../fetchers/message-fetchers.js';
import { fetchNotAcknowledgedPolicies } from '../fetchers/policy-acknowledgment-fetchers.js';
-import { fetchThreadInfos } from '../fetchers/thread-fetchers';
+import { fetchThreadInfos } from '../fetchers/thread-fetchers.js';
import {
fetchKnownUserInfos,
fetchLoggedInUserInfo,
fetchUserIDForEthereumAddress,
-} from '../fetchers/user-fetchers';
+} from '../fetchers/user-fetchers.js';
import {
createNewAnonymousCookie,
createNewUserCookie,
setNewSession,
-} from '../session/cookies';
-import type { Viewer } from '../session/viewer';
+} from '../session/cookies.js';
+import type { Viewer } from '../session/viewer.js';
import {
accountUpdater,
checkAndSendVerificationEmail,
checkAndSendPasswordResetEmail,
updatePassword,
updateUserSettings,
-} from '../updaters/account-updaters';
-import { userSubscriptionUpdater } from '../updaters/user-subscription-updaters';
+} from '../updaters/account-updaters.js';
+import { userSubscriptionUpdater } from '../updaters/user-subscription-updaters.js';
import { viewerAcknowledgmentUpdater } from '../updaters/viewer-acknowledgment-updater.js';
-import { validateInput } from '../utils/validation-utils';
+import { validateInput } from '../utils/validation-utils.js';
import {
entryQueryInputValidator,
newEntryQueryInputValidator,
normalizeCalendarQuery,
verifyCalendarQueryThreadIDs,
-} from './entry-responders';
+} from './entry-responders.js';
const subscriptionUpdateRequestInputValidator = tShape({
threadID: t.String,
diff --git a/keyserver/src/responders/verification-responders.js b/keyserver/src/responders/verification-responders.js
--- a/keyserver/src/responders/verification-responders.js
+++ b/keyserver/src/responders/verification-responders.js
@@ -2,12 +2,12 @@
import t from 'tcomb';
-import type { HandleVerificationCodeResult } from 'lib/types/verify-types';
-import { ServerError } from 'lib/utils/errors';
-import { tShape } from 'lib/utils/validation-utils';
+import type { HandleVerificationCodeResult } from 'lib/types/verify-types.js';
+import { ServerError } from 'lib/utils/errors.js';
+import { tShape } from 'lib/utils/validation-utils.js';
-import type { Viewer } from '../session/viewer';
-import { validateInput } from '../utils/validation-utils';
+import type { Viewer } from '../session/viewer.js';
+import { validateInput } from '../utils/validation-utils.js';
const codeVerificationRequestInputValidator = tShape({
code: t.String,
diff --git a/keyserver/src/responders/version-responders.js b/keyserver/src/responders/version-responders.js
--- a/keyserver/src/responders/version-responders.js
+++ b/keyserver/src/responders/version-responders.js
@@ -3,15 +3,15 @@
import type { $Response, $Request } from 'express';
import t from 'tcomb';
-import { isStaff } from 'lib/shared/user-utils';
-import type { CreateNewVersionsRequest } from 'lib/types/version-types';
-import { ServerError } from 'lib/utils/errors';
-import { tShape, tDeviceType } from 'lib/utils/validation-utils';
+import { isStaff } from 'lib/shared/user-utils.js';
+import type { CreateNewVersionsRequest } from 'lib/types/version-types.js';
+import { ServerError } from 'lib/utils/errors.js';
+import { tShape, tDeviceType } from 'lib/utils/validation-utils.js';
-import createIDs from '../creators/id-creator';
-import { dbQuery, SQL } from '../database/database';
-import type { Viewer } from '../session/viewer';
-import { validateInput } from '../utils/validation-utils';
+import createIDs from '../creators/id-creator.js';
+import { dbQuery, SQL } from '../database/database.js';
+import type { Viewer } from '../session/viewer.js';
+import { validateInput } from '../utils/validation-utils.js';
const createNewVersionInputValidator = tShape({
codeVersion: t.Number,
diff --git a/keyserver/src/responders/website-responders.js b/keyserver/src/responders/website-responders.js
--- a/keyserver/src/responders/website-responders.js
+++ b/keyserver/src/responders/website-responders.js
@@ -3,46 +3,46 @@
import html from 'common-tags/lib/html';
import type { $Response, $Request } from 'express';
import fs from 'fs';
-import _keyBy from 'lodash/fp/keyBy';
+import _keyBy from 'lodash/fp/keyBy.js';
import * as React from 'react';
import ReactDOMServer from 'react-dom/server';
import { promisify } from 'util';
import { baseLegalPolicies } from 'lib/facts/policies.js';
-import { daysToEntriesFromEntryInfos } from 'lib/reducers/entry-reducer';
-import { freshMessageStore } from 'lib/reducers/message-reducer';
-import { mostRecentlyReadThread } from 'lib/selectors/thread-selectors';
-import { mostRecentMessageTimestamp } from 'lib/shared/message-utils';
+import { daysToEntriesFromEntryInfos } from 'lib/reducers/entry-reducer.js';
+import { freshMessageStore } from 'lib/reducers/message-reducer.js';
+import { mostRecentlyReadThread } from 'lib/selectors/thread-selectors.js';
+import { mostRecentMessageTimestamp } from 'lib/shared/message-utils.js';
import {
threadHasPermission,
threadIsPending,
parsePendingThreadID,
createPendingThread,
-} from 'lib/shared/thread-utils';
-import { defaultWebEnabledApps } from 'lib/types/enabled-apps';
-import { defaultCalendarFilters } from 'lib/types/filter-types';
-import { defaultNumberPerThread } from 'lib/types/message-types';
-import { defaultEnabledReports } from 'lib/types/report-types';
-import { defaultConnectionInfo } from 'lib/types/socket-types';
-import { threadPermissions, threadTypes } from 'lib/types/thread-types';
-import { currentDateInTimeZone } from 'lib/utils/date-utils';
-import { ServerError } from 'lib/utils/errors';
-import { promiseAll } from 'lib/utils/promises';
-import getTitle from 'web/title/getTitle';
-import { navInfoFromURL } from 'web/url-utils';
+} from 'lib/shared/thread-utils.js';
+import { defaultWebEnabledApps } from 'lib/types/enabled-apps.js';
+import { defaultCalendarFilters } from 'lib/types/filter-types.js';
+import { defaultNumberPerThread } from 'lib/types/message-types.js';
+import { defaultEnabledReports } from 'lib/types/report-types.js';
+import { defaultConnectionInfo } from 'lib/types/socket-types.js';
+import { threadPermissions, threadTypes } from 'lib/types/thread-types.js';
+import { currentDateInTimeZone } from 'lib/utils/date-utils.js';
+import { ServerError } from 'lib/utils/errors.js';
+import { promiseAll } from 'lib/utils/promises.js';
+import getTitle from 'web/title/getTitle.js';
+import { navInfoFromURL } from 'web/url-utils.js';
-import { fetchEntryInfos } from '../fetchers/entry-fetchers';
-import { fetchMessageInfos } from '../fetchers/message-fetchers';
+import { fetchEntryInfos } from '../fetchers/entry-fetchers.js';
+import { fetchMessageInfos } from '../fetchers/message-fetchers.js';
import { hasAnyNotAcknowledgedPolicies } from '../fetchers/policy-acknowledgment-fetchers.js';
-import { fetchThreadInfos } from '../fetchers/thread-fetchers';
+import { fetchThreadInfos } from '../fetchers/thread-fetchers.js';
import {
fetchCurrentUserInfo,
fetchKnownUserInfos,
-} from '../fetchers/user-fetchers';
-import { setNewSession } from '../session/cookies';
-import { Viewer } from '../session/viewer';
-import { streamJSON, waitForStream } from '../utils/json-stream';
-import { getAppURLFactsFromRequestURL } from '../utils/urls';
+} from '../fetchers/user-fetchers.js';
+import { setNewSession } from '../session/cookies.js';
+import { Viewer } from '../session/viewer.js';
+import { streamJSON, waitForStream } from '../utils/json-stream.js';
+import { getAppURLFactsFromRequestURL } from '../utils/urls.js';
const { renderToNodeStream } = ReactDOMServer;
diff --git a/keyserver/src/scripts/add-edit-thread-detailed-permissions.js b/keyserver/src/scripts/add-edit-thread-detailed-permissions.js
--- a/keyserver/src/scripts/add-edit-thread-detailed-permissions.js
+++ b/keyserver/src/scripts/add-edit-thread-detailed-permissions.js
@@ -1,17 +1,17 @@
// @flow
-import bots from 'lib/facts/bots';
-import { assertThreadType } from 'lib/types/thread-types';
+import bots from 'lib/facts/bots.js';
+import { assertThreadType } from 'lib/types/thread-types.js';
-import { dbQuery, SQL } from '../database/database';
-import { createScriptViewer } from '../session/scripts';
-import { updateRoles } from '../updaters/role-updaters';
+import { dbQuery, SQL } from '../database/database.js';
+import { createScriptViewer } from '../session/scripts.js';
+import { updateRoles } from '../updaters/role-updaters.js';
import {
recalculateThreadPermissions,
commitMembershipChangeset,
-} from '../updaters/thread-permission-updaters';
-import RelationshipChangeset from '../utils/relationship-changeset';
-import { main } from './utils';
+} from '../updaters/thread-permission-updaters.js';
+import RelationshipChangeset from '../utils/relationship-changeset.js';
+import { main } from './utils.js';
async function addEditThreadDetailedPermissions() {
const batchSize = 10;
diff --git a/keyserver/src/scripts/add-indexes-for-account-deletion.js b/keyserver/src/scripts/add-indexes-for-account-deletion.js
--- a/keyserver/src/scripts/add-indexes-for-account-deletion.js
+++ b/keyserver/src/scripts/add-indexes-for-account-deletion.js
@@ -1,8 +1,8 @@
// @flow
-import { dbQuery, SQL } from '../database/database';
-import { setScriptContext } from './script-context';
-import { main } from './utils';
+import { dbQuery, SQL } from '../database/database.js';
+import { setScriptContext } from './script-context.js';
+import { main } from './utils.js';
setScriptContext({
allowMultiStatementSQLQueries: true,
diff --git a/keyserver/src/scripts/add-key-column-for-sessions.js b/keyserver/src/scripts/add-key-column-for-sessions.js
--- a/keyserver/src/scripts/add-key-column-for-sessions.js
+++ b/keyserver/src/scripts/add-key-column-for-sessions.js
@@ -1,7 +1,7 @@
// @flow
-import { dbQuery, SQL } from '../database/database';
-import { main } from './utils';
+import { dbQuery, SQL } from '../database/database.js';
+import { main } from './utils.js';
async function addPublicKeyColumn() {
await dbQuery(SQL`
diff --git a/keyserver/src/scripts/add-key-column-for-users.js b/keyserver/src/scripts/add-key-column-for-users.js
--- a/keyserver/src/scripts/add-key-column-for-users.js
+++ b/keyserver/src/scripts/add-key-column-for-users.js
@@ -1,7 +1,7 @@
// @flow
-import { dbQuery, SQL } from '../database/database';
-import { main } from './utils';
+import { dbQuery, SQL } from '../database/database.js';
+import { main } from './utils.js';
async function addPublicKeyColumn() {
await dbQuery(SQL`
diff --git a/keyserver/src/scripts/add-leave-thread-permissions.js b/keyserver/src/scripts/add-leave-thread-permissions.js
--- a/keyserver/src/scripts/add-leave-thread-permissions.js
+++ b/keyserver/src/scripts/add-leave-thread-permissions.js
@@ -1,10 +1,10 @@
// @flow
-import { threadPermissions, threadTypes } from 'lib/types/thread-types';
+import { threadPermissions, threadTypes } from 'lib/types/thread-types.js';
-import { dbQuery, SQL } from '../database/database';
-import { recalculateAllThreadPermissions } from '../updaters/thread-permission-updaters';
-import { endScript } from './utils';
+import { dbQuery, SQL } from '../database/database.js';
+import { recalculateAllThreadPermissions } from '../updaters/thread-permission-updaters.js';
+import { endScript } from './utils.js';
async function main() {
try {
diff --git a/keyserver/src/scripts/add-primary-column-for-cookies.js b/keyserver/src/scripts/add-primary-column-for-cookies.js
--- a/keyserver/src/scripts/add-primary-column-for-cookies.js
+++ b/keyserver/src/scripts/add-primary-column-for-cookies.js
@@ -1,7 +1,7 @@
// @flow
-import { dbQuery, SQL } from '../database/database';
-import { main } from './utils';
+import { dbQuery, SQL } from '../database/database.js';
+import { main } from './utils.js';
async function addPrimaryColumn() {
await dbQuery(SQL`
diff --git a/keyserver/src/scripts/add-source-message-column.js b/keyserver/src/scripts/add-source-message-column.js
--- a/keyserver/src/scripts/add-source-message-column.js
+++ b/keyserver/src/scripts/add-source-message-column.js
@@ -1,7 +1,7 @@
// @flow
-import { dbQuery, SQL } from '../database/database';
-import { main } from './utils';
+import { dbQuery, SQL } from '../database/database.js';
+import { main } from './utils.js';
async function deleteUnreadColumn() {
await dbQuery(SQL`
diff --git a/keyserver/src/scripts/add-staff.js b/keyserver/src/scripts/add-staff.js
--- a/keyserver/src/scripts/add-staff.js
+++ b/keyserver/src/scripts/add-staff.js
@@ -1,10 +1,10 @@
// @flow
-import bots from 'lib/facts/bots';
+import bots from 'lib/facts/bots.js';
-import { createScriptViewer } from '../session/scripts';
-import { updateThread } from '../updaters/thread-updaters';
-import { main } from './utils';
+import { createScriptViewer } from '../session/scripts.js';
+import { updateThread } from '../updaters/thread-updaters.js';
+import { main } from './utils.js';
const newStaffIDs = ['518252'];
diff --git a/keyserver/src/scripts/add-target-time-index-to-updates-table.js b/keyserver/src/scripts/add-target-time-index-to-updates-table.js
--- a/keyserver/src/scripts/add-target-time-index-to-updates-table.js
+++ b/keyserver/src/scripts/add-target-time-index-to-updates-table.js
@@ -1,8 +1,8 @@
// @flow
-import { dbQuery, SQL } from '../database/database';
-import { setScriptContext } from './script-context';
-import { main } from './utils';
+import { dbQuery, SQL } from '../database/database.js';
+import { setScriptContext } from './script-context.js';
+import { main } from './utils.js';
setScriptContext({
allowMultiStatementSQLQueries: true,
diff --git a/keyserver/src/scripts/add-thread-ancestry.js b/keyserver/src/scripts/add-thread-ancestry.js
--- a/keyserver/src/scripts/add-thread-ancestry.js
+++ b/keyserver/src/scripts/add-thread-ancestry.js
@@ -1,11 +1,14 @@
// @flow
-import { getContainingThreadID, getCommunity } from 'lib/shared/thread-utils';
-import type { ServerThreadInfo } from 'lib/types/thread-types';
+import {
+ getContainingThreadID,
+ getCommunity,
+} from 'lib/shared/thread-utils.js';
+import type { ServerThreadInfo } from 'lib/types/thread-types.js';
-import { dbQuery, SQL } from '../database/database';
-import { fetchServerThreadInfos } from '../fetchers/thread-fetchers';
-import { main } from './utils';
+import { dbQuery, SQL } from '../database/database.js';
+import { fetchServerThreadInfos } from '../fetchers/thread-fetchers.js';
+import { main } from './utils.js';
async function addColumnAndIndexes() {
await dbQuery(SQL`
diff --git a/keyserver/src/scripts/create-community.js b/keyserver/src/scripts/create-community.js
--- a/keyserver/src/scripts/create-community.js
+++ b/keyserver/src/scripts/create-community.js
@@ -1,11 +1,11 @@
// @flow
-import ashoat from 'lib/facts/ashoat';
-import { threadTypes } from 'lib/types/thread-types';
+import ashoat from 'lib/facts/ashoat.js';
+import { threadTypes } from 'lib/types/thread-types.js';
-import { createThread } from '../creators/thread-creator';
-import { createScriptViewer } from '../session/scripts';
-import { main } from './utils';
+import { createThread } from '../creators/thread-creator.js';
+import { createScriptViewer } from '../session/scripts.js';
+import { main } from './utils.js';
const communityName = 'New community';
diff --git a/keyserver/src/scripts/create-db.js b/keyserver/src/scripts/create-db.js
--- a/keyserver/src/scripts/create-db.js
+++ b/keyserver/src/scripts/create-db.js
@@ -1,6 +1,6 @@
// @flow
-import { setupDB } from '../database/setup-db';
-import { main } from './utils';
+import { setupDB } from '../database/setup-db.js';
+import { main } from './utils.js';
main([setupDB]);
diff --git a/keyserver/src/scripts/create-friend-relationships.js b/keyserver/src/scripts/create-friend-relationships.js
--- a/keyserver/src/scripts/create-friend-relationships.js
+++ b/keyserver/src/scripts/create-friend-relationships.js
@@ -1,10 +1,10 @@
// @flow
-import { undirectedStatus } from 'lib/types/relationship-types';
+import { undirectedStatus } from 'lib/types/relationship-types.js';
-import { createUndirectedRelationships } from '../creators/relationship-creators';
-import { dbQuery, SQL } from '../database/database';
-import { endScript } from './utils';
+import { createUndirectedRelationships } from '../creators/relationship-creators.js';
+import { dbQuery, SQL } from '../database/database.js';
+import { endScript } from './utils.js';
async function main() {
try {
diff --git a/keyserver/src/scripts/create-many-threads-to-trigger-crash-loop.js b/keyserver/src/scripts/create-many-threads-to-trigger-crash-loop.js
--- a/keyserver/src/scripts/create-many-threads-to-trigger-crash-loop.js
+++ b/keyserver/src/scripts/create-many-threads-to-trigger-crash-loop.js
@@ -1,9 +1,9 @@
// @flow
-import ashoat from 'lib/facts/ashoat';
+import ashoat from 'lib/facts/ashoat.js';
-import { createThread } from '../creators/thread-creator';
-import { createScriptViewer } from '../session/scripts';
-import { main } from './utils';
+import { createThread } from '../creators/thread-creator.js';
+import { createScriptViewer } from '../session/scripts.js';
+import { main } from './utils.js';
const testUserID = '';
const numOfThreads = 1000;
diff --git a/keyserver/src/scripts/create-metadata-table.js b/keyserver/src/scripts/create-metadata-table.js
--- a/keyserver/src/scripts/create-metadata-table.js
+++ b/keyserver/src/scripts/create-metadata-table.js
@@ -1,7 +1,7 @@
// @flow
-import { dbQuery, SQL } from '../database/database';
-import { main } from './utils';
+import { dbQuery, SQL } from '../database/database.js';
+import { main } from './utils.js';
async function createTable() {
await dbQuery(SQL`
diff --git a/keyserver/src/scripts/create-one-time-keys-table.js b/keyserver/src/scripts/create-one-time-keys-table.js
--- a/keyserver/src/scripts/create-one-time-keys-table.js
+++ b/keyserver/src/scripts/create-one-time-keys-table.js
@@ -1,7 +1,7 @@
// @flow
-import { dbQuery, SQL } from '../database/database';
-import { main, endScript } from './utils';
+import { dbQuery, SQL } from '../database/database.js';
+import { main, endScript } from './utils.js';
async function addOneTimeKeysTable() {
await dbQuery(SQL`
diff --git a/keyserver/src/scripts/create-one-time-settings-table.js b/keyserver/src/scripts/create-one-time-settings-table.js
--- a/keyserver/src/scripts/create-one-time-settings-table.js
+++ b/keyserver/src/scripts/create-one-time-settings-table.js
@@ -1,7 +1,7 @@
// @flow
-import { dbQuery, SQL } from '../database/database';
-import { main, endScript } from './utils';
+import { dbQuery, SQL } from '../database/database.js';
+import { main, endScript } from './utils.js';
async function addOneTimeSettingsTable() {
await dbQuery(SQL`
diff --git a/keyserver/src/scripts/create-relationships.js b/keyserver/src/scripts/create-relationships.js
--- a/keyserver/src/scripts/create-relationships.js
+++ b/keyserver/src/scripts/create-relationships.js
@@ -1,11 +1,11 @@
// @flow
-import { undirectedStatus } from 'lib/types/relationship-types';
+import { undirectedStatus } from 'lib/types/relationship-types.js';
-import { createUndirectedRelationships } from '../creators/relationship-creators';
-import { dbQuery, SQL } from '../database/database';
-import { saveMemberships } from '../updaters/thread-permission-updaters';
-import { endScript } from './utils';
+import { createUndirectedRelationships } from '../creators/relationship-creators.js';
+import { dbQuery, SQL } from '../database/database.js';
+import { saveMemberships } from '../updaters/thread-permission-updaters.js';
+import { endScript } from './utils.js';
async function main() {
try {
diff --git a/keyserver/src/scripts/create-sidebar-permissions.js b/keyserver/src/scripts/create-sidebar-permissions.js
--- a/keyserver/src/scripts/create-sidebar-permissions.js
+++ b/keyserver/src/scripts/create-sidebar-permissions.js
@@ -3,11 +3,11 @@
import {
threadPermissions,
threadPermissionPropagationPrefixes,
-} from 'lib/types/thread-types';
+} from 'lib/types/thread-types.js';
-import { dbQuery, SQL } from '../database/database';
-import { recalculateAllThreadPermissions } from '../updaters/thread-permission-updaters';
-import { endScript } from './utils';
+import { dbQuery, SQL } from '../database/database.js';
+import { recalculateAllThreadPermissions } from '../updaters/thread-permission-updaters.js';
+import { endScript } from './utils.js';
async function main() {
try {
diff --git a/keyserver/src/scripts/create-user-messages-table.js b/keyserver/src/scripts/create-user-messages-table.js
--- a/keyserver/src/scripts/create-user-messages-table.js
+++ b/keyserver/src/scripts/create-user-messages-table.js
@@ -1,7 +1,7 @@
// @flow
-import { dbQuery, SQL } from '../database/database';
-import { main } from './utils';
+import { dbQuery, SQL } from '../database/database.js';
+import { main } from './utils.js';
async function createTable() {
await dbQuery(SQL`
diff --git a/keyserver/src/scripts/delete-emails.js b/keyserver/src/scripts/delete-emails.js
--- a/keyserver/src/scripts/delete-emails.js
+++ b/keyserver/src/scripts/delete-emails.js
@@ -1,8 +1,8 @@
// @flow
-import { dbQuery, SQL } from '../database/database';
-import { setScriptContext } from './script-context';
-import { main } from './utils';
+import { dbQuery, SQL } from '../database/database.js';
+import { setScriptContext } from './script-context.js';
+import { main } from './utils.js';
setScriptContext({
allowMultiStatementSQLQueries: true,
diff --git a/keyserver/src/scripts/delete-memberships-of-deleted-users.js b/keyserver/src/scripts/delete-memberships-of-deleted-users.js
--- a/keyserver/src/scripts/delete-memberships-of-deleted-users.js
+++ b/keyserver/src/scripts/delete-memberships-of-deleted-users.js
@@ -1,7 +1,7 @@
// @flow
-import { dbQuery, SQL } from '../database/database';
-import { main } from './utils';
+import { dbQuery, SQL } from '../database/database.js';
+import { main } from './utils.js';
async function deleteMemberships() {
const query = SQL`
diff --git a/keyserver/src/scripts/delete-unread-column.js b/keyserver/src/scripts/delete-unread-column.js
--- a/keyserver/src/scripts/delete-unread-column.js
+++ b/keyserver/src/scripts/delete-unread-column.js
@@ -1,7 +1,7 @@
// @flow
-import { dbQuery, SQL } from '../database/database';
-import { endScript } from './utils';
+import { dbQuery, SQL } from '../database/database.js';
+import { endScript } from './utils.js';
async function deleteUnreadColumn() {
try {
diff --git a/keyserver/src/scripts/fix-new-thread-types.js b/keyserver/src/scripts/fix-new-thread-types.js
--- a/keyserver/src/scripts/fix-new-thread-types.js
+++ b/keyserver/src/scripts/fix-new-thread-types.js
@@ -1,12 +1,12 @@
// @flow
-import bots from 'lib/facts/bots';
-import { threadTypes, assertThreadType } from 'lib/types/thread-types';
+import bots from 'lib/facts/bots.js';
+import { threadTypes, assertThreadType } from 'lib/types/thread-types.js';
-import { dbQuery, SQL } from '../database/database';
-import { createScriptViewer } from '../session/scripts';
-import { updateThread } from '../updaters/thread-updaters';
-import { main } from './utils';
+import { dbQuery, SQL } from '../database/database.js';
+import { createScriptViewer } from '../session/scripts.js';
+import { updateThread } from '../updaters/thread-updaters.js';
+import { main } from './utils.js';
const batchSize = 10;
const updateThreadOptions = { forceUpdateRoot: true };
diff --git a/keyserver/src/scripts/generate-olm-config.js b/keyserver/src/scripts/generate-olm-config.js
--- a/keyserver/src/scripts/generate-olm-config.js
+++ b/keyserver/src/scripts/generate-olm-config.js
@@ -5,7 +5,7 @@
import path from 'path';
import uuid from 'uuid';
-import { main } from './utils';
+import { main } from './utils.js';
const olmConfigRelativePath = './secrets/olm_config.json';
diff --git a/keyserver/src/scripts/image-size.js b/keyserver/src/scripts/image-size.js
--- a/keyserver/src/scripts/image-size.js
+++ b/keyserver/src/scripts/image-size.js
@@ -2,8 +2,8 @@
import sizeOf from 'buffer-image-size';
-import { dbQuery, SQL } from '../database/database';
-import { endScript } from './utils';
+import { dbQuery, SQL } from '../database/database.js';
+import { endScript } from './utils.js';
async function main() {
try {
diff --git a/keyserver/src/scripts/make-channel-private.js b/keyserver/src/scripts/make-channel-private.js
--- a/keyserver/src/scripts/make-channel-private.js
+++ b/keyserver/src/scripts/make-channel-private.js
@@ -1,11 +1,11 @@
// @flow
-import ashoat from 'lib/facts/ashoat';
-import { threadTypes } from 'lib/types/thread-types';
+import ashoat from 'lib/facts/ashoat.js';
+import { threadTypes } from 'lib/types/thread-types.js';
-import { createScriptViewer } from '../session/scripts';
-import { updateThread } from '../updaters/thread-updaters';
-import { main } from './utils';
+import { createScriptViewer } from '../session/scripts.js';
+import { updateThread } from '../updaters/thread-updaters.js';
+import { main } from './utils.js';
const channelID = '-1';
diff --git a/keyserver/src/scripts/make-notif-columns-optional.js b/keyserver/src/scripts/make-notif-columns-optional.js
--- a/keyserver/src/scripts/make-notif-columns-optional.js
+++ b/keyserver/src/scripts/make-notif-columns-optional.js
@@ -1,7 +1,7 @@
// @flow
-import { dbQuery, SQL } from '../database/database';
-import { endScript } from './utils';
+import { dbQuery, SQL } from '../database/database.js';
+import { endScript } from './utils.js';
async function main() {
try {
diff --git a/keyserver/src/scripts/make-source-message-unique.js b/keyserver/src/scripts/make-source-message-unique.js
--- a/keyserver/src/scripts/make-source-message-unique.js
+++ b/keyserver/src/scripts/make-source-message-unique.js
@@ -1,7 +1,7 @@
// @flow
-import { dbQuery, SQL } from '../database/database';
-import { main } from './utils';
+import { dbQuery, SQL } from '../database/database.js';
+import { main } from './utils.js';
async function makeSourceMessageUnique() {
await dbQuery(SQL`
diff --git a/keyserver/src/scripts/merge-users.js b/keyserver/src/scripts/merge-users.js
--- a/keyserver/src/scripts/merge-users.js
+++ b/keyserver/src/scripts/merge-users.js
@@ -1,21 +1,21 @@
// @flow
-import type { Shape } from 'lib/types/core';
-import type { ServerThreadInfo } from 'lib/types/thread-types';
-import { type UpdateData, updateTypes } from 'lib/types/update-types';
-
-import { createUpdates } from '../creators/update-creator';
-import { dbQuery, SQL } from '../database/database';
-import type { SQLStatementType } from '../database/types';
-import { deleteAccount } from '../deleters/account-deleters';
-import { fetchServerThreadInfos } from '../fetchers/thread-fetchers';
-import { createScriptViewer } from '../session/scripts';
+import type { Shape } from 'lib/types/core.js';
+import type { ServerThreadInfo } from 'lib/types/thread-types.js';
+import { type UpdateData, updateTypes } from 'lib/types/update-types.js';
+
+import { createUpdates } from '../creators/update-creator.js';
+import { dbQuery, SQL } from '../database/database.js';
+import type { SQLStatementType } from '../database/types.js';
+import { deleteAccount } from '../deleters/account-deleters.js';
+import { fetchServerThreadInfos } from '../fetchers/thread-fetchers.js';
+import { createScriptViewer } from '../session/scripts.js';
import {
changeRole,
commitMembershipChangeset,
-} from '../updaters/thread-permission-updaters';
-import RelationshipChangeset from '../utils/relationship-changeset';
-import { endScript } from './utils';
+} from '../updaters/thread-permission-updaters.js';
+import RelationshipChangeset from '../utils/relationship-changeset.js';
+import { endScript } from './utils.js';
async function main() {
try {
diff --git a/keyserver/src/scripts/move-threads.js b/keyserver/src/scripts/move-threads.js
--- a/keyserver/src/scripts/move-threads.js
+++ b/keyserver/src/scripts/move-threads.js
@@ -1,11 +1,11 @@
// @flow
-import ashoat from 'lib/facts/ashoat';
-import { threadTypes } from 'lib/types/thread-types';
+import ashoat from 'lib/facts/ashoat.js';
+import { threadTypes } from 'lib/types/thread-types.js';
-import { createScriptViewer } from '../session/scripts';
-import { updateThread } from '../updaters/thread-updaters';
-import { main } from './utils';
+import { createScriptViewer } from '../session/scripts.js';
+import { updateThread } from '../updaters/thread-updaters.js';
+import { main } from './utils.js';
async function moveThreads() {
const viewer = createScriptViewer(ashoat.id);
diff --git a/keyserver/src/scripts/rename-sidebar-message-fields.js b/keyserver/src/scripts/rename-sidebar-message-fields.js
--- a/keyserver/src/scripts/rename-sidebar-message-fields.js
+++ b/keyserver/src/scripts/rename-sidebar-message-fields.js
@@ -1,9 +1,9 @@
// @flow
-import { messageTypes } from 'lib/types/message-types';
+import { messageTypes } from 'lib/types/message-types.js';
-import { dbQuery, SQL } from '../database/database';
-import { main } from './utils';
+import { dbQuery, SQL } from '../database/database.js';
+import { main } from './utils.js';
async function renameSidebarSource() {
const query = SQL`
diff --git a/keyserver/src/scripts/rename-user-column-for-one-time-keys.js b/keyserver/src/scripts/rename-user-column-for-one-time-keys.js
--- a/keyserver/src/scripts/rename-user-column-for-one-time-keys.js
+++ b/keyserver/src/scripts/rename-user-column-for-one-time-keys.js
@@ -1,7 +1,7 @@
// @flow
-import { dbQuery, SQL } from '../database/database';
-import { main } from './utils';
+import { dbQuery, SQL } from '../database/database.js';
+import { main } from './utils.js';
async function renameUserToSession() {
await dbQuery(SQL`
diff --git a/keyserver/src/scripts/rename-user.js b/keyserver/src/scripts/rename-user.js
--- a/keyserver/src/scripts/rename-user.js
+++ b/keyserver/src/scripts/rename-user.js
@@ -1,12 +1,12 @@
// @flow
-import { updateTypes } from 'lib/types/update-types';
+import { updateTypes } from 'lib/types/update-types.js';
-import { createUpdates } from '../creators/update-creator';
-import { dbQuery, SQL } from '../database/database';
-import { fetchKnownUserInfos } from '../fetchers/user-fetchers';
-import { createScriptViewer } from '../session/scripts';
-import { main } from './utils';
+import { createUpdates } from '../creators/update-creator.js';
+import { dbQuery, SQL } from '../database/database.js';
+import { fetchKnownUserInfos } from '../fetchers/user-fetchers.js';
+import { createScriptViewer } from '../session/scripts.js';
+import { main } from './utils.js';
const userID = '5';
const newUsername = 'commbot';
diff --git a/keyserver/src/scripts/rescind-notifs.js b/keyserver/src/scripts/rescind-notifs.js
--- a/keyserver/src/scripts/rescind-notifs.js
+++ b/keyserver/src/scripts/rescind-notifs.js
@@ -1,11 +1,11 @@
// @flow
-import { threadTypes } from 'lib/types/thread-types';
+import { threadTypes } from 'lib/types/thread-types.js';
-import { dbQuery, SQL } from '../database/database';
-import { createScriptViewer } from '../session/scripts';
-import { activityUpdater } from '../updaters/activity-updaters';
-import { main } from './utils';
+import { dbQuery, SQL } from '../database/database.js';
+import { createScriptViewer } from '../session/scripts.js';
+import { activityUpdater } from '../updaters/activity-updaters.js';
+import { main } from './utils.js';
async function rescindNotifs() {
const fetchRescindThreadInfo = SQL`
diff --git a/keyserver/src/scripts/reset-password.js b/keyserver/src/scripts/reset-password.js
--- a/keyserver/src/scripts/reset-password.js
+++ b/keyserver/src/scripts/reset-password.js
@@ -2,8 +2,8 @@
import bcrypt from 'twin-bcrypt';
-import { dbQuery, SQL } from '../database/database';
-import { main } from './utils';
+import { dbQuery, SQL } from '../database/database.js';
+import { main } from './utils.js';
const userID = '-1';
const password = 'password';
diff --git a/keyserver/src/scripts/set-last-read-messages.js b/keyserver/src/scripts/set-last-read-messages.js
--- a/keyserver/src/scripts/set-last-read-messages.js
+++ b/keyserver/src/scripts/set-last-read-messages.js
@@ -1,10 +1,10 @@
// @flow
-import { messageTypes } from 'lib/types/message-types';
-import { threadPermissions } from 'lib/types/thread-types';
+import { messageTypes } from 'lib/types/message-types.js';
+import { threadPermissions } from 'lib/types/thread-types.js';
-import { dbQuery, SQL } from '../database/database';
-import { endScript } from './utils';
+import { dbQuery, SQL } from '../database/database.js';
+import { endScript } from './utils.js';
async function main() {
try {
diff --git a/keyserver/src/scripts/setup-sidebars.js b/keyserver/src/scripts/setup-sidebars.js
--- a/keyserver/src/scripts/setup-sidebars.js
+++ b/keyserver/src/scripts/setup-sidebars.js
@@ -1,12 +1,12 @@
// @flow
-import { messageSpecs } from 'lib/shared/messages/message-specs';
-import { messageTypes } from 'lib/types/message-types';
-import { updateTypes } from 'lib/types/update-types';
+import { messageSpecs } from 'lib/shared/messages/message-specs.js';
+import { messageTypes } from 'lib/types/message-types.js';
+import { updateTypes } from 'lib/types/update-types.js';
-import { createUpdates } from '../creators/update-creator';
-import { dbQuery, mergeOrConditions, SQL } from '../database/database';
-import { main } from './utils';
+import { createUpdates } from '../creators/update-creator.js';
+import { dbQuery, mergeOrConditions, SQL } from '../database/database.js';
+import { main } from './utils.js';
async function addRepliesCountColumn() {
const update = SQL`
diff --git a/keyserver/src/scripts/sidebar-know-of-migration.js b/keyserver/src/scripts/sidebar-know-of-migration.js
--- a/keyserver/src/scripts/sidebar-know-of-migration.js
+++ b/keyserver/src/scripts/sidebar-know-of-migration.js
@@ -1,17 +1,17 @@
// @flow
-import bots from 'lib/facts/bots';
-import { threadTypes, type ThreadType } from 'lib/types/thread-types';
+import bots from 'lib/facts/bots.js';
+import { threadTypes, type ThreadType } from 'lib/types/thread-types.js';
-import { dbQuery, SQL } from '../database/database';
-import { createScriptViewer } from '../session/scripts';
-import { updateRoles } from '../updaters/role-updaters';
+import { dbQuery, SQL } from '../database/database.js';
+import { createScriptViewer } from '../session/scripts.js';
+import { updateRoles } from '../updaters/role-updaters.js';
import {
recalculateThreadPermissions,
commitMembershipChangeset,
-} from '../updaters/thread-permission-updaters';
-import RelationshipChangeset from '../utils/relationship-changeset';
-import { main } from './utils';
+} from '../updaters/thread-permission-updaters.js';
+import RelationshipChangeset from '../utils/relationship-changeset.js';
+import { main } from './utils.js';
async function updatePrivateThreads() {
console.log('updating private threads');
diff --git a/keyserver/src/scripts/soft-launch-migration.js b/keyserver/src/scripts/soft-launch-migration.js
--- a/keyserver/src/scripts/soft-launch-migration.js
+++ b/keyserver/src/scripts/soft-launch-migration.js
@@ -2,27 +2,27 @@
import invariant from 'invariant';
-import ashoat from 'lib/facts/ashoat';
-import bots from 'lib/facts/bots';
-import genesis from 'lib/facts/genesis';
-import testers from 'lib/facts/testers';
-import { messageTypes } from 'lib/types/message-types';
-import { threadTypes, type ThreadType } from 'lib/types/thread-types';
-
-import createMessages from '../creators/message-creator';
-import { createThread } from '../creators/thread-creator';
-import { dbQuery, SQL } from '../database/database';
-import { fetchServerThreadInfos } from '../fetchers/thread-fetchers';
-import { fetchAllUserIDs } from '../fetchers/user-fetchers';
-import { createScriptViewer } from '../session/scripts';
-import type { Viewer } from '../session/viewer';
+import ashoat from 'lib/facts/ashoat.js';
+import bots from 'lib/facts/bots.js';
+import genesis from 'lib/facts/genesis.js';
+import testers from 'lib/facts/testers.js';
+import { messageTypes } from 'lib/types/message-types.js';
+import { threadTypes, type ThreadType } from 'lib/types/thread-types.js';
+
+import createMessages from '../creators/message-creator.js';
+import { createThread } from '../creators/thread-creator.js';
+import { dbQuery, SQL } from '../database/database.js';
+import { fetchServerThreadInfos } from '../fetchers/thread-fetchers.js';
+import { fetchAllUserIDs } from '../fetchers/user-fetchers.js';
+import { createScriptViewer } from '../session/scripts.js';
+import type { Viewer } from '../session/viewer.js';
import {
recalculateThreadPermissions,
commitMembershipChangeset,
saveMemberships,
-} from '../updaters/thread-permission-updaters';
-import { updateThread } from '../updaters/thread-updaters';
-import { main } from './utils';
+} from '../updaters/thread-permission-updaters.js';
+import { updateThread } from '../updaters/thread-updaters.js';
+import { main } from './utils.js';
const batchSize = 10;
const createThreadOptions = { forceAddMembers: true };
diff --git a/keyserver/src/scripts/update-geoip.js b/keyserver/src/scripts/update-geoip.js
--- a/keyserver/src/scripts/update-geoip.js
+++ b/keyserver/src/scripts/update-geoip.js
@@ -1,7 +1,7 @@
// @flow
-import { updateGeoipDB } from '../cron/update-geoip-db';
-import { endScript } from './utils';
+import { updateGeoipDB } from '../cron/update-geoip-db.js';
+import { endScript } from './utils.js';
async function main() {
try {
diff --git a/keyserver/src/scripts/utils.js b/keyserver/src/scripts/utils.js
--- a/keyserver/src/scripts/utils.js
+++ b/keyserver/src/scripts/utils.js
@@ -1,8 +1,8 @@
// @flow
-import { endPool } from '../database/database';
-import { endFirebase, endAPNs } from '../push/providers';
-import { publisher } from '../socket/redis';
+import { endPool } from '../database/database.js';
+import { endFirebase, endAPNs } from '../push/providers.js';
+import { publisher } from '../socket/redis.js';
function endScript() {
endPool();
diff --git a/keyserver/src/search/users.js b/keyserver/src/search/users.js
--- a/keyserver/src/search/users.js
+++ b/keyserver/src/search/users.js
@@ -1,9 +1,9 @@
// @flow
-import type { UserSearchRequest } from 'lib/types/search-types';
-import type { GlobalAccountUserInfo } from 'lib/types/user-types';
+import type { UserSearchRequest } from 'lib/types/search-types.js';
+import type { GlobalAccountUserInfo } from 'lib/types/user-types.js';
-import { dbQuery, SQL } from '../database/database';
+import { dbQuery, SQL } from '../database/database.js';
async function searchForUsers(
query: UserSearchRequest,
diff --git a/keyserver/src/session/bots.js b/keyserver/src/session/bots.js
--- a/keyserver/src/session/bots.js
+++ b/keyserver/src/session/bots.js
@@ -1,9 +1,9 @@
// @flow
-import bots from 'lib/facts/bots';
-import { ServerError } from 'lib/utils/errors';
+import bots from 'lib/facts/bots.js';
+import { ServerError } from 'lib/utils/errors.js';
-import { Viewer } from './viewer';
+import { Viewer } from './viewer.js';
// Note that since the returned Viewer doesn't have a valid cookieID or
// sessionID, a lot of things can go wrong when trying to use it with certain
diff --git a/keyserver/src/session/cookies.js b/keyserver/src/session/cookies.js
--- a/keyserver/src/session/cookies.js
+++ b/keyserver/src/session/cookies.js
@@ -6,10 +6,10 @@
import bcrypt from 'twin-bcrypt';
import url from 'url';
-import { hasMinCodeVersion } from 'lib/shared/version-utils';
-import type { Shape } from 'lib/types/core';
-import type { Platform, PlatformDetails } from 'lib/types/device-types';
-import type { CalendarQuery } from 'lib/types/entry-types';
+import { hasMinCodeVersion } from 'lib/shared/version-utils.js';
+import type { Shape } from 'lib/types/core.js';
+import type { Platform, PlatformDetails } from 'lib/types/device-types.js';
+import type { CalendarQuery } from 'lib/types/entry-types.js';
import {
type ServerSessionChange,
cookieLifetime,
@@ -18,24 +18,27 @@
cookieTypes,
sessionIdentifierTypes,
type SessionIdentifierType,
-} from 'lib/types/session-types';
+} from 'lib/types/session-types.js';
import type { SIWESocialProof } from 'lib/types/siwe-types.js';
-import type { InitialClientSocketMessage } from 'lib/types/socket-types';
-import type { UserInfo } from 'lib/types/user-types';
-import { values } from 'lib/utils/objects';
-import { promiseAll } from 'lib/utils/promises';
-
-import createIDs from '../creators/id-creator';
-import { createSession } from '../creators/session-creator';
-import { dbQuery, SQL } from '../database/database';
-import { deleteCookie } from '../deleters/cookie-deleters';
-import { handleAsyncPromise } from '../responders/handlers';
-import { clearDeviceToken } from '../updaters/device-token-updaters';
-import { updateThreadMembers } from '../updaters/thread-updaters';
-import { assertSecureRequest } from '../utils/security-utils';
-import { type AppURLFacts, getAppURLFactsFromRequestURL } from '../utils/urls';
-import { Viewer } from './viewer';
-import type { AnonymousViewerData, UserViewerData } from './viewer';
+import type { InitialClientSocketMessage } from 'lib/types/socket-types.js';
+import type { UserInfo } from 'lib/types/user-types.js';
+import { values } from 'lib/utils/objects.js';
+import { promiseAll } from 'lib/utils/promises.js';
+
+import createIDs from '../creators/id-creator.js';
+import { createSession } from '../creators/session-creator.js';
+import { dbQuery, SQL } from '../database/database.js';
+import { deleteCookie } from '../deleters/cookie-deleters.js';
+import { handleAsyncPromise } from '../responders/handlers.js';
+import { clearDeviceToken } from '../updaters/device-token-updaters.js';
+import { updateThreadMembers } from '../updaters/thread-updaters.js';
+import { assertSecureRequest } from '../utils/security-utils.js';
+import {
+ type AppURLFacts,
+ getAppURLFactsFromRequestURL,
+} from '../utils/urls.js';
+import { Viewer } from './viewer.js';
+import type { AnonymousViewerData, UserViewerData } from './viewer.js';
function cookieIsExpired(lastUsed: number) {
return lastUsed + cookieLifetime <= Date.now();
diff --git a/keyserver/src/session/scripts.js b/keyserver/src/session/scripts.js
--- a/keyserver/src/session/scripts.js
+++ b/keyserver/src/session/scripts.js
@@ -1,6 +1,6 @@
// @flow
-import { Viewer } from './viewer';
+import { Viewer } from './viewer.js';
// Note that since the returned Viewer doesn't have a valid cookieID or
// sessionID, a lot of things can go wrong when trying to use it with certain
diff --git a/keyserver/src/session/version.js b/keyserver/src/session/version.js
--- a/keyserver/src/session/version.js
+++ b/keyserver/src/session/version.js
@@ -1,10 +1,10 @@
// @flow
-import { hasMinCodeVersion } from 'lib/shared/version-utils';
-import type { PlatformDetails } from 'lib/types/device-types';
-import { ServerError } from 'lib/utils/errors';
+import { hasMinCodeVersion } from 'lib/shared/version-utils.js';
+import type { PlatformDetails } from 'lib/types/device-types.js';
+import { ServerError } from 'lib/utils/errors.js';
-import type { Viewer } from './viewer';
+import type { Viewer } from './viewer.js';
async function verifyClientSupported(
viewer: Viewer,
diff --git a/keyserver/src/session/viewer.js b/keyserver/src/session/viewer.js
--- a/keyserver/src/session/viewer.js
+++ b/keyserver/src/session/viewer.js
@@ -3,16 +3,16 @@
import geoip from 'geoip-lite';
import invariant from 'invariant';
-import type { Platform, PlatformDetails } from 'lib/types/device-types';
-import type { CalendarQuery } from 'lib/types/entry-types';
+import type { Platform, PlatformDetails } from 'lib/types/device-types.js';
+import type { CalendarQuery } from 'lib/types/entry-types.js';
import {
type CookieSource,
type SessionIdentifierType,
cookieTypes,
type CookieType,
sessionIdentifierTypes,
-} from 'lib/types/session-types';
-import { ServerError } from 'lib/utils/errors';
+} from 'lib/types/session-types.js';
+import { ServerError } from 'lib/utils/errors.js';
export type UserViewerData = {
+loggedIn: true,
diff --git a/keyserver/src/socket/redis.js b/keyserver/src/socket/redis.js
--- a/keyserver/src/socket/redis.js
+++ b/keyserver/src/socket/redis.js
@@ -2,16 +2,16 @@
import type { RedisClient } from 'redis';
import redis from 'redis';
-import uuidv4 from 'uuid/v4';
+import uuidv4 from 'uuid/v4.js';
import {
redisMessageTypes,
type RedisMessage,
type UpdateTarget,
type SessionIdentifier,
-} from 'lib/types/redis-types';
+} from 'lib/types/redis-types.js';
-import { getScriptContext } from '../scripts/script-context';
+import { getScriptContext } from '../scripts/script-context.js';
function channelNameForUpdateTarget(updateTarget: UpdateTarget): string {
if (updateTarget.sessionID) {
diff --git a/keyserver/src/socket/session-utils.js b/keyserver/src/socket/session-utils.js
--- a/keyserver/src/socket/session-utils.js
+++ b/keyserver/src/socket/session-utils.js
@@ -8,20 +8,20 @@
usersInRawEntryInfos,
serverEntryInfo,
serverEntryInfosObject,
-} from 'lib/shared/entry-utils';
-import { usersInThreadInfo } from 'lib/shared/thread-utils';
-import { hasMinCodeVersion } from 'lib/shared/version-utils';
-import type { UpdateActivityResult } from 'lib/types/activity-types';
-import { isDeviceType } from 'lib/types/device-types';
+} from 'lib/shared/entry-utils.js';
+import { usersInThreadInfo } from 'lib/shared/thread-utils.js';
+import { hasMinCodeVersion } from 'lib/shared/version-utils.js';
+import type { UpdateActivityResult } from 'lib/types/activity-types.js';
+import { isDeviceType } from 'lib/types/device-types.js';
import type {
CalendarQuery,
DeltaEntryInfosResponse,
-} from 'lib/types/entry-types';
+} from 'lib/types/entry-types.js';
import {
reportTypes,
type ThreadInconsistencyReportCreationRequest,
type EntryInconsistencyReportCreationRequest,
-} from 'lib/types/report-types';
+} from 'lib/types/report-types.js';
import {
serverRequestTypes,
type ThreadInconsistencyClientResponse,
@@ -29,46 +29,46 @@
type ClientResponse,
type ServerServerRequest,
type ServerCheckStateServerRequest,
-} from 'lib/types/request-types';
-import { sessionCheckFrequency } from 'lib/types/session-types';
-import { hash } from 'lib/utils/objects';
-import { promiseAll } from 'lib/utils/promises';
+} from 'lib/types/request-types.js';
+import { sessionCheckFrequency } from 'lib/types/session-types.js';
+import { hash } from 'lib/utils/objects.js';
+import { promiseAll } from 'lib/utils/promises.js';
import {
tShape,
tPlatform,
tPlatformDetails,
-} from 'lib/utils/validation-utils';
+} from 'lib/utils/validation-utils.js';
-import { saveOneTimeKeys } from '../creators/one-time-keys-creator';
-import createReport from '../creators/report-creator';
-import { SQL } from '../database/database';
+import { saveOneTimeKeys } from '../creators/one-time-keys-creator.js';
+import createReport from '../creators/report-creator.js';
+import { SQL } from '../database/database.js';
import {
fetchEntryInfos,
fetchEntryInfosByID,
fetchEntriesForSession,
-} from '../fetchers/entry-fetchers';
-import { checkIfSessionHasEnoughOneTimeKeys } from '../fetchers/key-fetchers';
-import { fetchThreadInfos } from '../fetchers/thread-fetchers';
+} from '../fetchers/entry-fetchers.js';
+import { checkIfSessionHasEnoughOneTimeKeys } from '../fetchers/key-fetchers.js';
+import { fetchThreadInfos } from '../fetchers/thread-fetchers.js';
import {
fetchCurrentUserInfo,
fetchUserInfos,
fetchKnownUserInfos,
-} from '../fetchers/user-fetchers';
-import { activityUpdatesInputValidator } from '../responders/activity-responders';
-import { handleAsyncPromise } from '../responders/handlers';
+} from '../fetchers/user-fetchers.js';
+import { activityUpdatesInputValidator } from '../responders/activity-responders.js';
+import { handleAsyncPromise } from '../responders/handlers.js';
import {
threadInconsistencyReportValidatorShape,
entryInconsistencyReportValidatorShape,
-} from '../responders/report-responders';
+} from '../responders/report-responders.js';
import {
setNewSession,
setCookiePlatform,
setCookiePlatformDetails,
-} from '../session/cookies';
-import type { Viewer } from '../session/viewer';
-import { activityUpdater } from '../updaters/activity-updaters';
-import { compareNewCalendarQuery } from '../updaters/entry-updaters';
-import type { SessionUpdate } from '../updaters/session-updaters';
+} from '../session/cookies.js';
+import type { Viewer } from '../session/viewer.js';
+import { activityUpdater } from '../updaters/activity-updaters.js';
+import { compareNewCalendarQuery } from '../updaters/entry-updaters.js';
+import type { SessionUpdate } from '../updaters/session-updaters.js';
const clientResponseInputValidator: TUnion<TInterface> = t.union([
tShape({
diff --git a/keyserver/src/socket/socket.js b/keyserver/src/socket/socket.js
--- a/keyserver/src/socket/socket.js
+++ b/keyserver/src/socket/socket.js
@@ -2,26 +2,26 @@
import type { $Request } from 'express';
import invariant from 'invariant';
-import _debounce from 'lodash/debounce';
+import _debounce from 'lodash/debounce.js';
import t from 'tcomb';
import WebSocket from 'ws';
import { baseLegalPolicies } from 'lib/facts/policies.js';
-import { mostRecentMessageTimestamp } from 'lib/shared/message-utils';
+import { mostRecentMessageTimestamp } from 'lib/shared/message-utils.js';
import {
serverRequestSocketTimeout,
serverResponseTimeout,
-} from 'lib/shared/timeouts';
-import { mostRecentUpdateTimestamp } from 'lib/shared/update-utils';
-import type { Shape } from 'lib/types/core';
-import { endpointIsSocketSafe } from 'lib/types/endpoints';
-import { defaultNumberPerThread } from 'lib/types/message-types';
-import { redisMessageTypes, type RedisMessage } from 'lib/types/redis-types';
+} from 'lib/shared/timeouts.js';
+import { mostRecentUpdateTimestamp } from 'lib/shared/update-utils.js';
+import type { Shape } from 'lib/types/core.js';
+import { endpointIsSocketSafe } from 'lib/types/endpoints.js';
+import { defaultNumberPerThread } from 'lib/types/message-types.js';
+import { redisMessageTypes, type RedisMessage } from 'lib/types/redis-types.js';
import {
cookieSources,
sessionCheckFrequency,
stateCheckInactivityActivationInterval,
-} from 'lib/types/session-types';
+} from 'lib/types/session-types.js';
import {
type ClientSocketMessage,
type InitialClientSocketMessage,
@@ -36,55 +36,55 @@
clientSocketMessageTypes,
stateSyncPayloadTypes,
serverSocketMessageTypes,
-} from 'lib/types/socket-types';
-import { ServerError } from 'lib/utils/errors';
-import { values } from 'lib/utils/objects';
-import { promiseAll } from 'lib/utils/promises';
-import SequentialPromiseResolver from 'lib/utils/sequential-promise-resolver';
-import sleep from 'lib/utils/sleep';
-import { tShape, tCookie } from 'lib/utils/validation-utils';
-
-import { fetchUpdateInfosWithRawUpdateInfos } from '../creators/update-creator';
-import { deleteActivityForViewerSession } from '../deleters/activity-deleters';
-import { deleteCookie } from '../deleters/cookie-deleters';
-import { deleteUpdatesBeforeTimeTargetingSession } from '../deleters/update-deleters';
-import { jsonEndpoints } from '../endpoints';
-import { fetchEntryInfos } from '../fetchers/entry-fetchers';
+} from 'lib/types/socket-types.js';
+import { ServerError } from 'lib/utils/errors.js';
+import { values } from 'lib/utils/objects.js';
+import { promiseAll } from 'lib/utils/promises.js';
+import SequentialPromiseResolver from 'lib/utils/sequential-promise-resolver.js';
+import sleep from 'lib/utils/sleep.js';
+import { tShape, tCookie } from 'lib/utils/validation-utils.js';
+
+import { fetchUpdateInfosWithRawUpdateInfos } from '../creators/update-creator.js';
+import { deleteActivityForViewerSession } from '../deleters/activity-deleters.js';
+import { deleteCookie } from '../deleters/cookie-deleters.js';
+import { deleteUpdatesBeforeTimeTargetingSession } from '../deleters/update-deleters.js';
+import { jsonEndpoints } from '../endpoints.js';
+import { fetchEntryInfos } from '../fetchers/entry-fetchers.js';
import {
fetchMessageInfosSince,
getMessageFetchResultFromRedisMessages,
-} from '../fetchers/message-fetchers';
-import { fetchThreadInfos } from '../fetchers/thread-fetchers';
-import { fetchUpdateInfos } from '../fetchers/update-fetchers';
+} from '../fetchers/message-fetchers.js';
+import { fetchThreadInfos } from '../fetchers/thread-fetchers.js';
+import { fetchUpdateInfos } from '../fetchers/update-fetchers.js';
import {
fetchCurrentUserInfo,
fetchKnownUserInfos,
-} from '../fetchers/user-fetchers';
+} from '../fetchers/user-fetchers.js';
import {
newEntryQueryInputValidator,
verifyCalendarQueryThreadIDs,
-} from '../responders/entry-responders';
-import { handleAsyncPromise } from '../responders/handlers';
+} from '../responders/entry-responders.js';
+import { handleAsyncPromise } from '../responders/handlers.js';
import {
fetchViewerForSocket,
extendCookieLifespan,
createNewAnonymousCookie,
-} from '../session/cookies';
-import { Viewer } from '../session/viewer';
-import { commitSessionUpdate } from '../updaters/session-updaters';
-import { assertSecureRequest } from '../utils/security-utils';
+} from '../session/cookies.js';
+import { Viewer } from '../session/viewer.js';
+import { commitSessionUpdate } from '../updaters/session-updaters.js';
+import { assertSecureRequest } from '../utils/security-utils.js';
import {
checkInputValidator,
checkClientSupported,
policiesValidator,
-} from '../utils/validation-utils';
-import { RedisSubscriber } from './redis';
+} from '../utils/validation-utils.js';
+import { RedisSubscriber } from './redis.js';
import {
clientResponseInputValidator,
processClientResponses,
initializeSession,
checkState,
-} from './session-utils';
+} from './session-utils.js';
const clientSocketMessageInputValidator = t.union([
tShape({
diff --git a/keyserver/src/updaters/account-updaters.js b/keyserver/src/updaters/account-updaters.js
--- a/keyserver/src/updaters/account-updaters.js
+++ b/keyserver/src/updaters/account-updaters.js
@@ -7,14 +7,14 @@
UpdatePasswordRequest,
UpdateUserSettingsRequest,
LogInResponse,
-} from 'lib/types/account-types';
-import { updateTypes } from 'lib/types/update-types';
-import type { PasswordUpdate } from 'lib/types/user-types';
-import { ServerError } from 'lib/utils/errors';
+} from 'lib/types/account-types.js';
+import { updateTypes } from 'lib/types/update-types.js';
+import type { PasswordUpdate } from 'lib/types/user-types.js';
+import { ServerError } from 'lib/utils/errors.js';
-import { createUpdates } from '../creators/update-creator';
-import { dbQuery, SQL } from '../database/database';
-import type { Viewer } from '../session/viewer';
+import { createUpdates } from '../creators/update-creator.js';
+import { dbQuery, SQL } from '../database/database.js';
+import type { Viewer } from '../session/viewer.js';
async function accountUpdater(
viewer: Viewer,
diff --git a/keyserver/src/updaters/activity-updaters.js b/keyserver/src/updaters/activity-updaters.js
--- a/keyserver/src/updaters/activity-updaters.js
+++ b/keyserver/src/updaters/activity-updaters.js
@@ -1,33 +1,33 @@
// @flow
import invariant from 'invariant';
-import _difference from 'lodash/fp/difference';
-import _max from 'lodash/fp/max';
+import _difference from 'lodash/fp/difference.js';
+import _max from 'lodash/fp/max.js';
-import { localIDPrefix } from 'lib/shared/message-utils';
+import { localIDPrefix } from 'lib/shared/message-utils.js';
import type {
UpdateActivityResult,
UpdateActivityRequest,
SetThreadUnreadStatusRequest,
SetThreadUnreadStatusResult,
-} from 'lib/types/activity-types';
-import { messageTypes } from 'lib/types/message-types';
-import { threadPermissions } from 'lib/types/thread-types';
-import { updateTypes } from 'lib/types/update-types';
-import { ServerError } from 'lib/utils/errors';
-
-import { createUpdates } from '../creators/update-creator';
-import { dbQuery, SQL, mergeOrConditions } from '../database/database';
-import type { SQLStatementType } from '../database/types';
-import { deleteActivityForViewerSession } from '../deleters/activity-deleters';
+} from 'lib/types/activity-types.js';
+import { messageTypes } from 'lib/types/message-types.js';
+import { threadPermissions } from 'lib/types/thread-types.js';
+import { updateTypes } from 'lib/types/update-types.js';
+import { ServerError } from 'lib/utils/errors.js';
+
+import { createUpdates } from '../creators/update-creator.js';
+import { dbQuery, SQL, mergeOrConditions } from '../database/database.js';
+import type { SQLStatementType } from '../database/types.js';
+import { deleteActivityForViewerSession } from '../deleters/activity-deleters.js';
import {
checkThread,
getValidThreads,
-} from '../fetchers/thread-permission-fetchers';
-import { rescindPushNotifs } from '../push/rescind';
-import { updateBadgeCount } from '../push/send';
-import type { Viewer } from '../session/viewer';
-import { earliestFocusedTimeConsideredExpired } from '../shared/focused-times';
+} from '../fetchers/thread-permission-fetchers.js';
+import { rescindPushNotifs } from '../push/rescind.js';
+import { updateBadgeCount } from '../push/send.js';
+import type { Viewer } from '../session/viewer.js';
+import { earliestFocusedTimeConsideredExpired } from '../shared/focused-times.js';
type PartialThreadStatus = {
+focusActive: boolean,
diff --git a/keyserver/src/updaters/device-token-updaters.js b/keyserver/src/updaters/device-token-updaters.js
--- a/keyserver/src/updaters/device-token-updaters.js
+++ b/keyserver/src/updaters/device-token-updaters.js
@@ -3,11 +3,11 @@
import {
type DeviceTokenUpdateRequest,
isDeviceType,
-} from 'lib/types/device-types';
-import { ServerError } from 'lib/utils/errors';
+} from 'lib/types/device-types.js';
+import { ServerError } from 'lib/utils/errors.js';
-import { dbQuery, SQL } from '../database/database';
-import type { Viewer } from '../session/viewer';
+import { dbQuery, SQL } from '../database/database.js';
+import type { Viewer } from '../session/viewer.js';
async function deviceTokenUpdater(
viewer: Viewer,
diff --git a/keyserver/src/updaters/entry-updaters.js b/keyserver/src/updaters/entry-updaters.js
--- a/keyserver/src/updaters/entry-updaters.js
+++ b/keyserver/src/updaters/entry-updaters.js
@@ -1,40 +1,40 @@
// @flow
import invariant from 'invariant';
-import _isEqual from 'lodash/fp/isEqual';
+import _isEqual from 'lodash/fp/isEqual.js';
import {
rawEntryInfoWithinCalendarQuery,
calendarQueryDifference,
-} from 'lib/shared/entry-utils';
+} from 'lib/shared/entry-utils.js';
import {
type SaveEntryRequest,
type SaveEntryResponse,
type RawEntryInfo,
type CalendarQuery,
defaultCalendarQuery,
-} from 'lib/types/entry-types';
-import { messageTypes } from 'lib/types/message-types';
-import { threadPermissions } from 'lib/types/thread-types';
+} from 'lib/types/entry-types.js';
+import { messageTypes } from 'lib/types/message-types.js';
+import { threadPermissions } from 'lib/types/thread-types.js';
import {
updateTypes,
type ServerCreateUpdatesResponse,
-} from 'lib/types/update-types';
-import { dateString } from 'lib/utils/date-utils';
-import { ServerError } from 'lib/utils/errors';
-import { values } from 'lib/utils/objects';
+} from 'lib/types/update-types.js';
+import { dateString } from 'lib/utils/date-utils.js';
+import { ServerError } from 'lib/utils/errors.js';
+import { values } from 'lib/utils/objects.js';
-import createIDs from '../creators/id-creator';
-import createMessages from '../creators/message-creator';
-import { createUpdates } from '../creators/update-creator';
-import { dbQuery, SQL } from '../database/database';
+import createIDs from '../creators/id-creator.js';
+import createMessages from '../creators/message-creator.js';
+import { createUpdates } from '../creators/update-creator.js';
+import { dbQuery, SQL } from '../database/database.js';
import {
fetchEntryInfo,
checkThreadPermissionForEntry,
-} from '../fetchers/entry-fetchers';
-import { fetchActiveSessionsForThread } from '../fetchers/session-fetchers';
-import type { Viewer } from '../session/viewer';
-import type { SessionUpdate } from './session-updaters';
+} from '../fetchers/entry-fetchers.js';
+import { fetchActiveSessionsForThread } from '../fetchers/session-fetchers.js';
+import type { Viewer } from '../session/viewer.js';
+import type { SessionUpdate } from './session-updaters.js';
const defaultUpdateCreationResponse = { viewerUpdates: [], userInfos: [] };
async function updateEntry(
diff --git a/keyserver/src/updaters/relationship-updaters.js b/keyserver/src/updaters/relationship-updaters.js
--- a/keyserver/src/updaters/relationship-updaters.js
+++ b/keyserver/src/updaters/relationship-updaters.js
@@ -2,8 +2,8 @@
import invariant from 'invariant';
-import { sortIDs } from 'lib/shared/relationship-utils';
-import { messageTypes } from 'lib/types/message-types';
+import { sortIDs } from 'lib/shared/relationship-utils.js';
+import { messageTypes } from 'lib/types/message-types.js';
import {
type RelationshipRequest,
type RelationshipErrors,
@@ -11,20 +11,20 @@
relationshipActions,
undirectedStatus,
directedStatus,
-} from 'lib/types/relationship-types';
-import { threadTypes } from 'lib/types/thread-types';
-import { updateTypes, type UpdateData } from 'lib/types/update-types';
-import { cartesianProduct } from 'lib/utils/array';
-import { ServerError } from 'lib/utils/errors';
-import { promiseAll } from 'lib/utils/promises';
-
-import createMessages from '../creators/message-creator';
-import { createThread } from '../creators/thread-creator';
-import { createUpdates } from '../creators/update-creator';
-import { dbQuery, SQL, mergeOrConditions } from '../database/database';
-import { fetchFriendRequestRelationshipOperations } from '../fetchers/relationship-fetchers';
-import { fetchUserInfos } from '../fetchers/user-fetchers';
-import type { Viewer } from '../session/viewer';
+} from 'lib/types/relationship-types.js';
+import { threadTypes } from 'lib/types/thread-types.js';
+import { updateTypes, type UpdateData } from 'lib/types/update-types.js';
+import { cartesianProduct } from 'lib/utils/array.js';
+import { ServerError } from 'lib/utils/errors.js';
+import { promiseAll } from 'lib/utils/promises.js';
+
+import createMessages from '../creators/message-creator.js';
+import { createThread } from '../creators/thread-creator.js';
+import { createUpdates } from '../creators/update-creator.js';
+import { dbQuery, SQL, mergeOrConditions } from '../database/database.js';
+import { fetchFriendRequestRelationshipOperations } from '../fetchers/relationship-fetchers.js';
+import { fetchUserInfos } from '../fetchers/user-fetchers.js';
+import type { Viewer } from '../session/viewer.js';
async function updateRelationships(
viewer: Viewer,
diff --git a/keyserver/src/updaters/role-updaters.js b/keyserver/src/updaters/role-updaters.js
--- a/keyserver/src/updaters/role-updaters.js
+++ b/keyserver/src/updaters/role-updaters.js
@@ -1,15 +1,15 @@
// @flow
import invariant from 'invariant';
-import _isEqual from 'lodash/fp/isEqual';
+import _isEqual from 'lodash/fp/isEqual.js';
-import type { ThreadType } from 'lib/types/thread-types';
+import type { ThreadType } from 'lib/types/thread-types.js';
-import createIDs from '../creators/id-creator';
-import { getRolePermissionBlobs } from '../creators/role-creator';
-import { dbQuery, SQL } from '../database/database';
-import { fetchRoles } from '../fetchers/role-fetchers';
-import type { Viewer } from '../session/viewer';
+import createIDs from '../creators/id-creator.js';
+import { getRolePermissionBlobs } from '../creators/role-creator.js';
+import { dbQuery, SQL } from '../database/database.js';
+import { fetchRoles } from '../fetchers/role-fetchers.js';
+import type { Viewer } from '../session/viewer.js';
async function updateRoles(
viewer: Viewer,
diff --git a/keyserver/src/updaters/session-updaters.js b/keyserver/src/updaters/session-updaters.js
--- a/keyserver/src/updaters/session-updaters.js
+++ b/keyserver/src/updaters/session-updaters.js
@@ -1,10 +1,10 @@
// @flow
-import type { Shape } from 'lib/types/core';
-import type { CalendarQuery } from 'lib/types/entry-types';
+import type { Shape } from 'lib/types/core.js';
+import type { CalendarQuery } from 'lib/types/entry-types.js';
-import { dbQuery, SQL } from '../database/database';
-import type { Viewer } from '../session/viewer';
+import { dbQuery, SQL } from '../database/database.js';
+import type { Viewer } from '../session/viewer.js';
export type SessionUpdate = Shape<{
+query: CalendarQuery,
diff --git a/keyserver/src/updaters/thread-permission-updaters.js b/keyserver/src/updaters/thread-permission-updaters.js
--- a/keyserver/src/updaters/thread-permission-updaters.js
+++ b/keyserver/src/updaters/thread-permission-updaters.js
@@ -1,47 +1,47 @@
// @flow
import invariant from 'invariant';
-import _isEqual from 'lodash/fp/isEqual';
+import _isEqual from 'lodash/fp/isEqual.js';
-import bots from 'lib/facts/bots';
-import genesis from 'lib/facts/genesis';
+import bots from 'lib/facts/bots.js';
+import genesis from 'lib/facts/genesis.js';
import {
makePermissionsBlob,
makePermissionsForChildrenBlob,
getRoleForPermissions,
-} from 'lib/permissions/thread-permissions';
-import type { CalendarQuery } from 'lib/types/entry-types';
+} from 'lib/permissions/thread-permissions.js';
+import type { CalendarQuery } from 'lib/types/entry-types.js';
import {
type ThreadPermissionsBlob,
type ThreadRolePermissionsBlob,
type ThreadType,
assertThreadType,
-} from 'lib/types/thread-types';
+} from 'lib/types/thread-types.js';
import {
updateTypes,
type ServerUpdateInfo,
type CreateUpdatesResult,
-} from 'lib/types/update-types';
-import { pushAll } from 'lib/utils/array';
-import { ServerError } from 'lib/utils/errors';
+} from 'lib/types/update-types.js';
+import { pushAll } from 'lib/utils/array.js';
+import { ServerError } from 'lib/utils/errors.js';
import {
createUpdates,
type UpdatesForCurrentSession,
-} from '../creators/update-creator';
-import { dbQuery, SQL } from '../database/database';
+} from '../creators/update-creator.js';
+import { dbQuery, SQL } from '../database/database.js';
import {
fetchServerThreadInfos,
rawThreadInfosFromServerThreadInfos,
type FetchThreadInfosResult,
-} from '../fetchers/thread-fetchers';
-import { rescindPushNotifs } from '../push/rescind';
-import { createScriptViewer } from '../session/scripts';
-import type { Viewer } from '../session/viewer';
-import { updateRoles } from '../updaters/role-updaters';
-import DepthQueue from '../utils/depth-queue';
-import RelationshipChangeset from '../utils/relationship-changeset';
-import { updateChangedUndirectedRelationships } from './relationship-updaters';
+} from '../fetchers/thread-fetchers.js';
+import { rescindPushNotifs } from '../push/rescind.js';
+import { createScriptViewer } from '../session/scripts.js';
+import type { Viewer } from '../session/viewer.js';
+import { updateRoles } from '../updaters/role-updaters.js';
+import DepthQueue from '../utils/depth-queue.js';
+import RelationshipChangeset from '../utils/relationship-changeset.js';
+import { updateChangedUndirectedRelationships } from './relationship-updaters.js';
export type MembershipRowToSave = {
+operation: 'save',
diff --git a/keyserver/src/updaters/thread-updaters.js b/keyserver/src/updaters/thread-updaters.js
--- a/keyserver/src/updaters/thread-updaters.js
+++ b/keyserver/src/updaters/thread-updaters.js
@@ -1,15 +1,18 @@
// @flow
-import { filteredThreadIDs } from 'lib/selectors/calendar-filter-selectors';
+import { filteredThreadIDs } from 'lib/selectors/calendar-filter-selectors.js';
import {
threadHasAdminRole,
roleIsAdminRole,
viewerIsMember,
getThreadTypeParentRequirement,
-} from 'lib/shared/thread-utils';
-import { hasMinCodeVersion } from 'lib/shared/version-utils';
-import type { Shape } from 'lib/types/core';
-import { messageTypes, defaultNumberPerThread } from 'lib/types/message-types';
+} from 'lib/shared/thread-utils.js';
+import { hasMinCodeVersion } from 'lib/shared/version-utils.js';
+import type { Shape } from 'lib/types/core.js';
+import {
+ messageTypes,
+ defaultNumberPerThread,
+} from 'lib/types/message-types.js';
import {
type RoleChangeRequest,
type ChangeThreadSettingsResult,
@@ -21,41 +24,41 @@
type ThreadJoinResult,
threadPermissions,
threadTypes,
-} from 'lib/types/thread-types';
-import { updateTypes } from 'lib/types/update-types';
-import { ServerError } from 'lib/utils/errors';
-import { promiseAll } from 'lib/utils/promises';
-import { firstLine } from 'lib/utils/string-utils';
-
-import createMessages from '../creators/message-creator';
-import { getRolePermissionBlobs } from '../creators/role-creator';
-import { createUpdates } from '../creators/update-creator';
-import { dbQuery, SQL } from '../database/database';
-import { fetchEntryInfos } from '../fetchers/entry-fetchers';
-import { fetchMessageInfos } from '../fetchers/message-fetchers';
+} from 'lib/types/thread-types.js';
+import { updateTypes } from 'lib/types/update-types.js';
+import { ServerError } from 'lib/utils/errors.js';
+import { promiseAll } from 'lib/utils/promises.js';
+import { firstLine } from 'lib/utils/string-utils.js';
+
+import createMessages from '../creators/message-creator.js';
+import { getRolePermissionBlobs } from '../creators/role-creator.js';
+import { createUpdates } from '../creators/update-creator.js';
+import { dbQuery, SQL } from '../database/database.js';
+import { fetchEntryInfos } from '../fetchers/entry-fetchers.js';
+import { fetchMessageInfos } from '../fetchers/message-fetchers.js';
import {
fetchThreadInfos,
fetchServerThreadInfos,
determineThreadAncestry,
-} from '../fetchers/thread-fetchers';
+} from '../fetchers/thread-fetchers.js';
import {
checkThreadPermission,
viewerIsMember as fetchViewerIsMember,
checkThread,
validateCandidateMembers,
-} from '../fetchers/thread-permission-fetchers';
+} from '../fetchers/thread-permission-fetchers.js';
import {
verifyUserIDs,
verifyUserOrCookieIDs,
-} from '../fetchers/user-fetchers';
-import type { Viewer } from '../session/viewer';
-import RelationshipChangeset from '../utils/relationship-changeset';
-import { updateRoles } from './role-updaters';
+} from '../fetchers/user-fetchers.js';
+import type { Viewer } from '../session/viewer.js';
+import RelationshipChangeset from '../utils/relationship-changeset.js';
+import { updateRoles } from './role-updaters.js';
import {
changeRole,
recalculateThreadPermissions,
commitMembershipChangeset,
-} from './thread-permission-updaters';
+} from './thread-permission-updaters.js';
async function updateRole(
viewer: Viewer,
diff --git a/keyserver/src/updaters/upload-updaters.js b/keyserver/src/updaters/upload-updaters.js
--- a/keyserver/src/updaters/upload-updaters.js
+++ b/keyserver/src/updaters/upload-updaters.js
@@ -3,8 +3,8 @@
import type { MediaMessageServerDBContent } from 'lib/types/messages/media.js';
import { getUploadIDsFromMediaMessageServerDBContents } from 'lib/types/messages/media.js';
-import { dbQuery, SQL } from '../database/database';
-import type { Viewer } from '../session/viewer';
+import { dbQuery, SQL } from '../database/database.js';
+import type { Viewer } from '../session/viewer.js';
async function assignMedia(
viewer: Viewer,
diff --git a/keyserver/src/updaters/user-subscription-updaters.js b/keyserver/src/updaters/user-subscription-updaters.js
--- a/keyserver/src/updaters/user-subscription-updaters.js
+++ b/keyserver/src/updaters/user-subscription-updaters.js
@@ -1,17 +1,17 @@
// @flow
-import { viewerIsMember } from 'lib/shared/thread-utils';
+import { viewerIsMember } from 'lib/shared/thread-utils.js';
import type {
ThreadSubscription,
SubscriptionUpdateRequest,
-} from 'lib/types/subscription-types';
-import { updateTypes } from 'lib/types/update-types';
-import { ServerError } from 'lib/utils/errors';
-
-import { createUpdates } from '../creators/update-creator';
-import { dbQuery, SQL } from '../database/database';
-import { fetchThreadInfos } from '../fetchers/thread-fetchers';
-import type { Viewer } from '../session/viewer';
+} from 'lib/types/subscription-types.js';
+import { updateTypes } from 'lib/types/update-types.js';
+import { ServerError } from 'lib/utils/errors.js';
+
+import { createUpdates } from '../creators/update-creator.js';
+import { dbQuery, SQL } from '../database/database.js';
+import { fetchThreadInfos } from '../fetchers/thread-fetchers.js';
+import type { Viewer } from '../session/viewer.js';
async function userSubscriptionUpdater(
viewer: Viewer,
diff --git a/keyserver/src/uploads/media-utils.js b/keyserver/src/uploads/media-utils.js
--- a/keyserver/src/uploads/media-utils.js
+++ b/keyserver/src/uploads/media-utils.js
@@ -8,12 +8,12 @@
serverTranscodableTypes,
serverCanHandleTypes,
readableFilename,
-} from 'lib/media/file-utils';
-import { getImageProcessingPlan } from 'lib/media/image-utils';
-import type { Dimensions } from 'lib/types/media-types';
-import { deepFileInfoFromData } from 'web/media/file-utils';
+} from 'lib/media/file-utils.js';
+import { getImageProcessingPlan } from 'lib/media/image-utils.js';
+import type { Dimensions } from 'lib/types/media-types.js';
+import { deepFileInfoFromData } from 'web/media/file-utils.js';
-import type { UploadInput } from '../creators/upload-creator';
+import type { UploadInput } from '../creators/upload-creator.js';
function initializeSharp(buffer: Buffer, mime: string) {
if (mime !== 'image/bmp') {
diff --git a/keyserver/src/uploads/uploads.js b/keyserver/src/uploads/uploads.js
--- a/keyserver/src/uploads/uploads.js
+++ b/keyserver/src/uploads/uploads.js
@@ -9,19 +9,19 @@
UploadMultimediaResult,
UploadDeletionRequest,
Dimensions,
-} from 'lib/types/media-types';
-import { ServerError } from 'lib/utils/errors';
+} from 'lib/types/media-types.js';
+import { ServerError } from 'lib/utils/errors.js';
-import createUploads from '../creators/upload-creator';
-import { deleteUpload } from '../deleters/upload-deleters';
+import createUploads from '../creators/upload-creator.js';
+import { deleteUpload } from '../deleters/upload-deleters.js';
import {
fetchUpload,
fetchUploadChunk,
getUploadSize,
-} from '../fetchers/upload-fetchers';
-import type { MulterRequest } from '../responders/handlers';
-import type { Viewer } from '../session/viewer';
-import { validateAndConvert } from './media-utils';
+} from '../fetchers/upload-fetchers.js';
+import type { MulterRequest } from '../responders/handlers.js';
+import type { Viewer } from '../session/viewer.js';
+import { validateAndConvert } from './media-utils.js';
const upload = multer();
const multerProcessor: Middleware<> = upload.array('multimedia');
diff --git a/keyserver/src/utils/ens-cache.js b/keyserver/src/utils/ens-cache.js
--- a/keyserver/src/utils/ens-cache.js
+++ b/keyserver/src/utils/ens-cache.js
@@ -2,11 +2,11 @@
import { ethers } from 'ethers';
-import { ENSCache, type EthersProvider } from 'lib/utils/ens-cache';
+import { ENSCache, type EthersProvider } from 'lib/utils/ens-cache.js';
import {
getENSNames as baseGetENSNames,
type GetENSNames,
-} from 'lib/utils/ens-helpers';
+} from 'lib/utils/ens-helpers.js';
const alchemyKey = process.env.COMM_ALCHEMY_KEY;
diff --git a/keyserver/src/utils/idempotent.js b/keyserver/src/utils/idempotent.js
--- a/keyserver/src/utils/idempotent.js
+++ b/keyserver/src/utils/idempotent.js
@@ -1,6 +1,6 @@
// @flow
-import type { Viewer } from '../session/viewer';
+import type { Viewer } from '../session/viewer.js';
function creationString(viewer: Viewer, localID: string): string {
return `${viewer.session}|${localID}`;
diff --git a/keyserver/src/utils/olm-utils.js b/keyserver/src/utils/olm-utils.js
--- a/keyserver/src/utils/olm-utils.js
+++ b/keyserver/src/utils/olm-utils.js
@@ -2,7 +2,7 @@
import invariant from 'invariant';
-import { importJSON } from './import-json';
+import { importJSON } from './import-json.js';
type OlmConfig = {
+picklingKey: string,
diff --git a/keyserver/src/utils/relationship-changeset.js b/keyserver/src/utils/relationship-changeset.js
--- a/keyserver/src/utils/relationship-changeset.js
+++ b/keyserver/src/utils/relationship-changeset.js
@@ -2,11 +2,11 @@
import invariant from 'invariant';
-import { sortIDs } from 'lib/shared/relationship-utils';
+import { sortIDs } from 'lib/shared/relationship-utils.js';
import {
type UndirectedRelationshipRow,
undirectedStatus,
-} from 'lib/types/relationship-types';
+} from 'lib/types/relationship-types.js';
type RelationshipStatus = 'existing' | 'potentially_missing';
diff --git a/keyserver/src/utils/security-utils.js b/keyserver/src/utils/security-utils.js
--- a/keyserver/src/utils/security-utils.js
+++ b/keyserver/src/utils/security-utils.js
@@ -2,7 +2,7 @@
import type { $Request } from 'express';
-import { getAppURLFactsFromRequestURL } from './urls';
+import { getAppURLFactsFromRequestURL } from './urls.js';
function assertSecureRequest(req: $Request) {
const { https, proxy } = getAppURLFactsFromRequestURL(req.originalUrl);
diff --git a/keyserver/src/utils/urls.js b/keyserver/src/utils/urls.js
--- a/keyserver/src/utils/urls.js
+++ b/keyserver/src/utils/urls.js
@@ -2,9 +2,9 @@
import invariant from 'invariant';
-import { values } from 'lib/utils/objects';
+import { values } from 'lib/utils/objects.js';
-import { importJSON } from './import-json';
+import { importJSON } from './import-json.js';
export type AppURLFacts = {
+baseDomain: string,
diff --git a/keyserver/src/utils/validation-utils.js b/keyserver/src/utils/validation-utils.js
--- a/keyserver/src/utils/validation-utils.js
+++ b/keyserver/src/utils/validation-utils.js
@@ -2,17 +2,17 @@
import type { PolicyType } from 'lib/facts/policies.js';
import { hasMinCodeVersion } from 'lib/shared/version-utils.js';
-import { ServerError } from 'lib/utils/errors';
+import { ServerError } from 'lib/utils/errors.js';
import {
tCookie,
tPassword,
tPlatform,
tPlatformDetails,
-} from 'lib/utils/validation-utils';
+} from 'lib/utils/validation-utils.js';
import { fetchNotAcknowledgedPolicies } from '../fetchers/policy-acknowledgment-fetchers.js';
-import { verifyClientSupported } from '../session/version';
-import type { Viewer } from '../session/viewer';
+import { verifyClientSupported } from '../session/version.js';
+import type { Viewer } from '../session/viewer.js';
async function validateInput(viewer: Viewer, inputValidator: *, input: *) {
if (!viewer.isSocket) {
diff --git a/landing/app-landing.react.js b/landing/app-landing.react.js
--- a/landing/app-landing.react.js
+++ b/landing/app-landing.react.js
@@ -2,13 +2,13 @@
import * as React from 'react';
-import { assetMetaData } from './asset-meta-data';
-import HeroContent from './hero-content.react';
-import InfoBlock from './info-block.react';
+import { assetMetaData } from './asset-meta-data.js';
+import HeroContent from './hero-content.react.js';
+import InfoBlock from './info-block.react.js';
import css from './landing.css';
-import Picture from './Picture.react';
-import StarBackground from './star-background.react';
-import usePreloadAssets from './use-pre-load-assets.react';
+import Picture from './Picture.react.js';
+import StarBackground from './star-background.react.js';
+import usePreloadAssets from './use-pre-load-assets.react.js';
function AppLanding(): React.Node {
usePreloadAssets(assetMetaData);
diff --git a/landing/footer.react.js b/landing/footer.react.js
--- a/landing/footer.react.js
+++ b/landing/footer.react.js
@@ -6,7 +6,7 @@
import { NavLink } from 'react-router-dom';
import css from './footer.css';
-import SubscriptionForm from './subscription-form.react';
+import SubscriptionForm from './subscription-form.react.js';
const navLinkProps = {
activeStyle: {
diff --git a/landing/hero-content.react.js b/landing/hero-content.react.js
--- a/landing/hero-content.react.js
+++ b/landing/hero-content.react.js
@@ -3,9 +3,9 @@
import * as React from 'react';
import TextLoop from 'react-text-loop';
-import { assetMetaData } from './asset-meta-data';
+import { assetMetaData } from './asset-meta-data.js';
import css from './hero-content.css';
-import SubscriptionForm from './subscription-form.react';
+import SubscriptionForm from './subscription-form.react.js';
function HeroContent(): React.Node {
const [hero] = assetMetaData;
diff --git a/landing/info-block.react.js b/landing/info-block.react.js
--- a/landing/info-block.react.js
+++ b/landing/info-block.react.js
@@ -3,7 +3,7 @@
import * as React from 'react';
import css from './info-block.css';
-import Picture from './Picture.react';
+import Picture from './Picture.react.js';
type InfoBlockProps = {
+title: string,
diff --git a/landing/investor-data.js b/landing/investor-data.js
--- a/landing/investor-data.js
+++ b/landing/investor-data.js
@@ -1,9 +1,9 @@
// @flow
-import _keyBy from 'lodash/fp/keyBy';
-import _shuffle from 'lodash/fp/shuffle';
+import _keyBy from 'lodash/fp/keyBy.js';
+import _shuffle from 'lodash/fp/shuffle.js';
-import { assetsCacheURLPrefix } from './asset-meta-data';
+import { assetsCacheURLPrefix } from './asset-meta-data.js';
type Investors = {
+id: string,
diff --git a/landing/investor-profile-modal.react.js b/landing/investor-profile-modal.react.js
--- a/landing/investor-profile-modal.react.js
+++ b/landing/investor-profile-modal.react.js
@@ -2,12 +2,12 @@
import * as React from 'react';
-import ModalOverlay from 'lib/components/modal-overlay.react';
-import { useModalContext } from 'lib/components/modal-provider.react';
+import ModalOverlay from 'lib/components/modal-overlay.react.js';
+import { useModalContext } from 'lib/components/modal-provider.react.js';
-import { keyedInvestorData } from './investor-data';
+import { keyedInvestorData } from './investor-data.js';
import css from './investor-profile-modal.css';
-import InvestorProfile from './investor-profile.react';
+import InvestorProfile from './investor-profile.react.js';
type Props = {
+investorID: string,
diff --git a/landing/investors.react.js b/landing/investors.react.js
--- a/landing/investors.react.js
+++ b/landing/investors.react.js
@@ -2,11 +2,11 @@
import * as React from 'react';
-import { useModalContext } from 'lib/components/modal-provider.react';
+import { useModalContext } from 'lib/components/modal-provider.react.js';
-import { shuffledInvestorsData } from './investor-data';
-import InvestorProfileModal from './investor-profile-modal.react';
-import InvestorProfile from './investor-profile.react';
+import { shuffledInvestorsData } from './investor-data.js';
+import InvestorProfileModal from './investor-profile-modal.react.js';
+import InvestorProfile from './investor-profile.react.js';
import css from './investors.css';
function Investors(): React.Node {
diff --git a/landing/keyservers.react.js b/landing/keyservers.react.js
--- a/landing/keyservers.react.js
+++ b/landing/keyservers.react.js
@@ -3,12 +3,12 @@
import { create } from '@lottiefiles/lottie-interactivity';
import * as React from 'react';
-import { useIsomorphicLayoutEffect } from 'lib/hooks/isomorphic-layout-effect.react';
+import { useIsomorphicLayoutEffect } from 'lib/hooks/isomorphic-layout-effect.react.js';
-import { assetsCacheURLPrefix } from './asset-meta-data';
+import { assetsCacheURLPrefix } from './asset-meta-data.js';
import css from './keyservers.css';
-import ReadDocsButton from './read-docs-btn.react';
-import StarBackground from './star-background.react';
+import ReadDocsButton from './read-docs-btn.react.js';
+import StarBackground from './star-background.react.js';
function Keyservers(): React.Node {
React.useEffect(() => {
diff --git a/landing/landing-ssr.react.js b/landing/landing-ssr.react.js
--- a/landing/landing-ssr.react.js
+++ b/landing/landing-ssr.react.js
@@ -3,7 +3,7 @@
import * as React from 'react';
import { StaticRouter } from 'react-router';
-import Landing from './landing.react';
+import Landing from './landing.react.js';
import { SIWEContext } from './siwe-context.js';
export type LandingSSRProps = {
diff --git a/landing/landing.react.js b/landing/landing.react.js
--- a/landing/landing.react.js
+++ b/landing/landing.react.js
@@ -6,21 +6,21 @@
import {
ModalProvider,
useModalContext,
-} from 'lib/components/modal-provider.react';
+} from 'lib/components/modal-provider.react.js';
-import AppLanding from './app-landing.react';
-import Footer from './footer.react';
-import Header from './header.react';
-import Investors from './investors.react';
-import Keyservers from './keyservers.react';
+import AppLanding from './app-landing.react.js';
+import Footer from './footer.react.js';
+import Header from './header.react.js';
+import Investors from './investors.react.js';
+import Keyservers from './keyservers.react.js';
import css from './landing.css';
-import Privacy from './privacy.react';
-import QR from './qr.react';
-import SIWE from './siwe.react';
-import Support from './support.react';
-import Team from './team.react';
-import Terms from './terms.react';
-import useScrollToTopOnNavigate from './use-scroll-to-top-on-navigate.react';
+import Privacy from './privacy.react.js';
+import QR from './qr.react.js';
+import SIWE from './siwe.react.js';
+import Support from './support.react.js';
+import Team from './team.react.js';
+import Terms from './terms.react.js';
+import useScrollToTopOnNavigate from './use-scroll-to-top-on-navigate.react.js';
import './reset.css';
import './global.css';
diff --git a/landing/read-docs-btn.react.js b/landing/read-docs-btn.react.js
--- a/landing/read-docs-btn.react.js
+++ b/landing/read-docs-btn.react.js
@@ -2,7 +2,7 @@
import * as React from 'react';
-import { assetsCacheURLPrefix } from './asset-meta-data';
+import { assetsCacheURLPrefix } from './asset-meta-data.js';
import css from './read-docs-btn.css';
function ReadDocsButton(): React.Node {
diff --git a/landing/root.js b/landing/root.js
--- a/landing/root.js
+++ b/landing/root.js
@@ -3,7 +3,7 @@
import * as React from 'react';
import { BrowserRouter } from 'react-router-dom';
-import Landing from './landing.react';
+import Landing from './landing.react.js';
import { SIWEContext } from './siwe-context.js';
declare var routerBasename: string;
diff --git a/landing/script.js b/landing/script.js
--- a/landing/script.js
+++ b/landing/script.js
@@ -8,7 +8,7 @@
import React from 'react';
import { hydrateRoot } from 'react-dom/client';
-import Root from './root';
+import Root from './root.js';
const root = document.getElementById('react-root');
invariant(root, "cannot find id='react-root' element!");
diff --git a/landing/siwe.react.js b/landing/siwe.react.js
--- a/landing/siwe.react.js
+++ b/landing/siwe.react.js
@@ -10,19 +10,22 @@
connectorsForWallets,
} from '@rainbow-me/rainbowkit';
import invariant from 'invariant';
-import _merge from 'lodash/fp/merge';
+import _merge from 'lodash/fp/merge.js';
import * as React from 'react';
import '@rainbow-me/rainbowkit/dist/index.css';
import { useAccount, useSigner, WagmiConfig } from 'wagmi';
-import type { SIWEWebViewMessage } from 'lib/types/siwe-types';
+import type { SIWEWebViewMessage } from 'lib/types/siwe-types.js';
import {
getSIWEStatementForPublicKey,
siweStatementWithoutPublicKey,
siweMessageSigningExplanationStatements,
createSIWEMessage,
} from 'lib/utils/siwe-utils.js';
-import { configureWagmiChains, createWagmiClient } from 'lib/utils/wagmi-utils';
+import {
+ configureWagmiChains,
+ createWagmiClient,
+} from 'lib/utils/wagmi-utils.js';
import { SIWEContext } from './siwe-context.js';
import css from './siwe.css';
diff --git a/landing/subscription-form.react.js b/landing/subscription-form.react.js
--- a/landing/subscription-form.react.js
+++ b/landing/subscription-form.react.js
@@ -2,7 +2,7 @@
import * as React from 'react';
-import { validEmailRegex } from 'lib/shared/account-utils';
+import { validEmailRegex } from 'lib/shared/account-utils.js';
import css from './subscription-form.css';
diff --git a/landing/team.react.js b/landing/team.react.js
--- a/landing/team.react.js
+++ b/landing/team.react.js
@@ -2,9 +2,9 @@
import * as React from 'react';
-import { assetsCacheURLPrefix } from './asset-meta-data';
+import { assetsCacheURLPrefix } from './asset-meta-data.js';
import Button from './button.react.js';
-import TeamProfile from './team-profile.react';
+import TeamProfile from './team-profile.react.js';
import css from './team.css';
function Team(): React.Node {
diff --git a/landing/use-pre-load-assets.react.js b/landing/use-pre-load-assets.react.js
--- a/landing/use-pre-load-assets.react.js
+++ b/landing/use-pre-load-assets.react.js
@@ -2,7 +2,7 @@
import * as React from 'react';
-import { type Asset } from './asset-meta-data';
+import { type Asset } from './asset-meta-data.js';
function usePreloadAssets(assets: Asset[]) {
React.useEffect(() => {
diff --git a/lib/actions/activity-actions.js b/lib/actions/activity-actions.js
--- a/lib/actions/activity-actions.js
+++ b/lib/actions/activity-actions.js
@@ -6,8 +6,8 @@
SetThreadUnreadStatusPayload,
SetThreadUnreadStatusRequest,
SetThreadUnreadStatusResult,
-} from '../types/activity-types';
-import type { CallServerEndpoint } from '../utils/call-server-endpoint';
+} from '../types/activity-types.js';
+import type { CallServerEndpoint } from '../utils/call-server-endpoint.js';
const updateActivityActionTypes = Object.freeze({
started: 'UPDATE_ACTIVITY_STARTED',
diff --git a/lib/actions/device-actions.js b/lib/actions/device-actions.js
--- a/lib/actions/device-actions.js
+++ b/lib/actions/device-actions.js
@@ -1,7 +1,7 @@
// @flow
-import type { CallServerEndpoint } from '../utils/call-server-endpoint';
-import { getConfig } from '../utils/config';
+import type { CallServerEndpoint } from '../utils/call-server-endpoint.js';
+import { getConfig } from '../utils/config.js';
const setDeviceTokenActionTypes = Object.freeze({
started: 'SET_DEVICE_TOKEN_STARTED',
diff --git a/lib/actions/entry-actions.js b/lib/actions/entry-actions.js
--- a/lib/actions/entry-actions.js
+++ b/lib/actions/entry-actions.js
@@ -1,6 +1,6 @@
// @flow
-import { localIDPrefix } from '../shared/message-utils';
+import { localIDPrefix } from '../shared/message-utils.js';
import type {
RawEntryInfo,
CalendarQuery,
@@ -14,10 +14,10 @@
RestoreEntryResult,
FetchEntryInfosResult,
CalendarQueryUpdateResult,
-} from '../types/entry-types';
-import type { HistoryRevisionInfo } from '../types/history-types';
-import type { CallServerEndpoint } from '../utils/call-server-endpoint';
-import { dateFromString } from '../utils/date-utils';
+} from '../types/entry-types.js';
+import type { HistoryRevisionInfo } from '../types/history-types.js';
+import type { CallServerEndpoint } from '../utils/call-server-endpoint.js';
+import { dateFromString } from '../utils/date-utils.js';
const fetchEntriesActionTypes = Object.freeze({
started: 'FETCH_ENTRIES_STARTED',
diff --git a/lib/actions/message-actions.js b/lib/actions/message-actions.js
--- a/lib/actions/message-actions.js
+++ b/lib/actions/message-actions.js
@@ -7,12 +7,12 @@
SendMessageResult,
SendReactionMessageRequest,
SimpleMessagesPayload,
-} from '../types/message-types';
+} from '../types/message-types.js';
import type { MediaMessageServerDBContent } from '../types/messages/media.js';
import type {
CallServerEndpoint,
CallServerEndpointResultInfo,
-} from '../utils/call-server-endpoint';
+} from '../utils/call-server-endpoint.js';
const fetchMessagesBeforeCursorActionTypes = Object.freeze({
started: 'FETCH_MESSAGES_BEFORE_CURSOR_STARTED',
diff --git a/lib/actions/message-report-actions.js b/lib/actions/message-report-actions.js
--- a/lib/actions/message-report-actions.js
+++ b/lib/actions/message-report-actions.js
@@ -3,8 +3,8 @@
import type {
MessageReportCreationRequest,
MessageReportCreationResult,
-} from '../types/message-report-types';
-import type { CallServerEndpoint } from '../utils/call-server-endpoint';
+} from '../types/message-report-types.js';
+import type { CallServerEndpoint } from '../utils/call-server-endpoint.js';
const sendMessageReportActionTypes = Object.freeze({
started: 'SEND_MESSAGE_REPORT_STARTED',
diff --git a/lib/actions/relationship-actions.js b/lib/actions/relationship-actions.js
--- a/lib/actions/relationship-actions.js
+++ b/lib/actions/relationship-actions.js
@@ -3,9 +3,9 @@
import type {
RelationshipRequest,
RelationshipErrors,
-} from '../types/relationship-types';
-import type { CallServerEndpoint } from '../utils/call-server-endpoint';
-import { ServerError } from '../utils/errors';
+} from '../types/relationship-types.js';
+import type { CallServerEndpoint } from '../utils/call-server-endpoint.js';
+import { ServerError } from '../utils/errors.js';
const updateRelationshipsActionTypes = Object.freeze({
started: 'UPDATE_RELATIONSHIPS_STARTED',
diff --git a/lib/actions/report-actions.js b/lib/actions/report-actions.js
--- a/lib/actions/report-actions.js
+++ b/lib/actions/report-actions.js
@@ -3,8 +3,8 @@
import type {
ClientReportCreationRequest,
ReportCreationResponse,
-} from '../types/report-types';
-import type { CallServerEndpoint } from '../utils/call-server-endpoint';
+} from '../types/report-types.js';
+import type { CallServerEndpoint } from '../utils/call-server-endpoint.js';
const sendReportActionTypes = Object.freeze({
started: 'SEND_REPORT_STARTED',
diff --git a/lib/actions/siwe-actions.js b/lib/actions/siwe-actions.js
--- a/lib/actions/siwe-actions.js
+++ b/lib/actions/siwe-actions.js
@@ -6,7 +6,7 @@
logInActionSources,
} from '../types/account-types.js';
import type { SIWEAuthServerCall } from '../types/siwe-types.js';
-import type { CallServerEndpoint } from '../utils/call-server-endpoint';
+import type { CallServerEndpoint } from '../utils/call-server-endpoint.js';
import { getConfig } from '../utils/config.js';
import { mergeUserInfos } from './user-actions.js';
diff --git a/lib/actions/thread-actions.js b/lib/actions/thread-actions.js
--- a/lib/actions/thread-actions.js
+++ b/lib/actions/thread-actions.js
@@ -10,9 +10,9 @@
NewThreadResult,
ClientThreadJoinRequest,
ThreadJoinPayload,
-} from '../types/thread-types';
-import type { CallServerEndpoint } from '../utils/call-server-endpoint';
-import { values } from '../utils/objects';
+} from '../types/thread-types.js';
+import type { CallServerEndpoint } from '../utils/call-server-endpoint.js';
+import { values } from '../utils/objects.js';
const deleteThreadActionTypes = Object.freeze({
started: 'DELETE_THREAD_STARTED',
diff --git a/lib/actions/upload-actions.js b/lib/actions/upload-actions.js
--- a/lib/actions/upload-actions.js
+++ b/lib/actions/upload-actions.js
@@ -1,9 +1,12 @@
// @flow
-import type { Shape } from '../types/core';
-import type { UploadMultimediaResult, Dimensions } from '../types/media-types';
-import type { CallServerEndpoint } from '../utils/call-server-endpoint';
-import type { UploadBlob } from '../utils/upload-blob';
+import type { Shape } from '../types/core.js';
+import type {
+ UploadMultimediaResult,
+ Dimensions,
+} from '../types/media-types.js';
+import type { CallServerEndpoint } from '../utils/call-server-endpoint.js';
+import type { UploadBlob } from '../utils/upload-blob.js';
export type MultimediaUploadCallbacks = Shape<{
onProgress: (percent: number) => void,
diff --git a/lib/actions/user-actions.js b/lib/actions/user-actions.js
--- a/lib/actions/user-actions.js
+++ b/lib/actions/user-actions.js
@@ -1,6 +1,6 @@
// @flow
-import threadWatcher from '../shared/thread-watcher';
+import threadWatcher from '../shared/thread-watcher.js';
import type {
LogOutResult,
LogInInfo,
@@ -9,21 +9,21 @@
RegisterInfo,
UpdateUserSettingsRequest,
PolicyAcknowledgmentRequest,
-} from '../types/account-types';
-import type { GetSessionPublicKeysArgs } from '../types/request-types';
-import type { UserSearchResult } from '../types/search-types';
+} from '../types/account-types.js';
+import type { GetSessionPublicKeysArgs } from '../types/request-types.js';
+import type { UserSearchResult } from '../types/search-types.js';
import type {
SessionPublicKeys,
PreRequestUserState,
-} from '../types/session-types';
+} from '../types/session-types.js';
import type {
SubscriptionUpdateRequest,
SubscriptionUpdateResult,
-} from '../types/subscription-types';
-import type { UserInfo, PasswordUpdate } from '../types/user-types';
-import type { CallServerEndpoint } from '../utils/call-server-endpoint';
-import { getConfig } from '../utils/config';
-import sleep from '../utils/sleep';
+} from '../types/subscription-types.js';
+import type { UserInfo, PasswordUpdate } from '../types/user-types.js';
+import type { CallServerEndpoint } from '../utils/call-server-endpoint.js';
+import { getConfig } from '../utils/config.js';
+import sleep from '../utils/sleep.js';
const logOutActionTypes = Object.freeze({
started: 'LOG_OUT_STARTED',
diff --git a/lib/components/ens-cache-provider.react.js b/lib/components/ens-cache-provider.react.js
--- a/lib/components/ens-cache-provider.react.js
+++ b/lib/components/ens-cache-provider.react.js
@@ -2,11 +2,11 @@
import * as React from 'react';
-import { ENSCache, type EthersProvider } from '../utils/ens-cache';
+import { ENSCache, type EthersProvider } from '../utils/ens-cache.js';
import {
getENSNames as baseGetENSNames,
type GetENSNames,
-} from '../utils/ens-helpers';
+} from '../utils/ens-helpers.js';
type ENSCacheContextType = {
+ensCache: ?ENSCache,
diff --git a/lib/components/modal-provider.react.js b/lib/components/modal-provider.react.js
--- a/lib/components/modal-provider.react.js
+++ b/lib/components/modal-provider.react.js
@@ -3,7 +3,7 @@
import invariant from 'invariant';
import * as React from 'react';
-import { getUUID } from '../utils/uuid';
+import { getUUID } from '../utils/uuid.js';
export type PushModal = React.Node => string;
diff --git a/lib/components/thread-draft-updater.react.js b/lib/components/thread-draft-updater.react.js
--- a/lib/components/thread-draft-updater.react.js
+++ b/lib/components/thread-draft-updater.react.js
@@ -4,11 +4,11 @@
import * as React from 'react';
import { useDispatch } from 'react-redux';
-import { moveDraftActionType } from '../actions/draft-actions';
-import { pendingToRealizedThreadIDsSelector } from '../selectors/thread-selectors';
-import { draftKeyFromThreadID } from '../shared/thread-utils';
-import type { AppState } from '../types/redux-types';
-import { useSelector } from '../utils/redux-utils';
+import { moveDraftActionType } from '../actions/draft-actions.js';
+import { pendingToRealizedThreadIDsSelector } from '../selectors/thread-selectors.js';
+import { draftKeyFromThreadID } from '../shared/thread-utils.js';
+import type { AppState } from '../types/redux-types.js';
+import { useSelector } from '../utils/redux-utils.js';
const ThreadDraftUpdater: React.ComponentType<{}> = React.memo<{}>(
function ThreadDraftUpdater() {
diff --git a/lib/hooks/child-threads.js b/lib/hooks/child-threads.js
--- a/lib/hooks/child-threads.js
+++ b/lib/hooks/child-threads.js
@@ -5,18 +5,21 @@
import {
fetchSingleMostRecentMessagesFromThreads,
fetchSingleMostRecentMessagesFromThreadsActionTypes,
-} from '../actions/message-actions';
+} from '../actions/message-actions.js';
import {
useFilteredChatListData,
type ChatThreadItem,
-} from '../selectors/chat-selectors';
-import { useGlobalThreadSearchIndex } from '../selectors/nav-selectors';
-import { childThreadInfos } from '../selectors/thread-selectors';
-import { threadInChatList } from '../shared/thread-utils';
-import threadWatcher from '../shared/thread-watcher';
-import type { ThreadInfo } from '../types/thread-types';
-import { useDispatchActionPromise, useServerCall } from '../utils/action-utils';
-import { useSelector } from '../utils/redux-utils';
+} from '../selectors/chat-selectors.js';
+import { useGlobalThreadSearchIndex } from '../selectors/nav-selectors.js';
+import { childThreadInfos } from '../selectors/thread-selectors.js';
+import { threadInChatList } from '../shared/thread-utils.js';
+import threadWatcher from '../shared/thread-watcher.js';
+import type { ThreadInfo } from '../types/thread-types.js';
+import {
+ useDispatchActionPromise,
+ useServerCall,
+} from '../utils/action-utils.js';
+import { useSelector } from '../utils/redux-utils.js';
type ThreadFilter = {
+predicate?: (thread: ThreadInfo) => boolean,
diff --git a/lib/hooks/disconnected-bar.js b/lib/hooks/disconnected-bar.js
--- a/lib/hooks/disconnected-bar.js
+++ b/lib/hooks/disconnected-bar.js
@@ -3,8 +3,8 @@
import * as React from 'react';
import { useDispatch } from 'react-redux';
-import { updateDisconnectedBarActionType } from '../types/socket-types';
-import { useSelector } from '../utils/redux-utils';
+import { updateDisconnectedBarActionType } from '../types/socket-types.js';
+import { useSelector } from '../utils/redux-utils.js';
function useDisconnectedBarVisibilityHandler(networkConnected: boolean): void {
const dispatch = useDispatch();
diff --git a/lib/hooks/ens-cache.js b/lib/hooks/ens-cache.js
--- a/lib/hooks/ens-cache.js
+++ b/lib/hooks/ens-cache.js
@@ -3,9 +3,9 @@
import invariant from 'invariant';
import * as React from 'react';
-import { ENSCacheContext } from '../components/ens-cache-provider.react';
-import { userIdentifiedByETHAddress } from '../shared/account-utils';
-import { stringForUser } from '../shared/user-utils';
+import { ENSCacheContext } from '../components/ens-cache-provider.react.js';
+import { userIdentifiedByETHAddress } from '../shared/account-utils.js';
+import { stringForUser } from '../shared/user-utils.js';
type BaseUserInfo = { +username?: ?string, ... };
function useENSNames<T: ?BaseUserInfo>(users: $ReadOnlyArray<T>): T[] {
diff --git a/lib/hooks/inline-engagement-text.react.js b/lib/hooks/inline-engagement-text.react.js
--- a/lib/hooks/inline-engagement-text.react.js
+++ b/lib/hooks/inline-engagement-text.react.js
@@ -1,6 +1,6 @@
// @flow
-import type { ThreadInfo } from '../types/thread-types';
+import type { ThreadInfo } from '../types/thread-types.js';
function useInlineEngagementText(threadInfo: ?ThreadInfo): string {
if (!threadInfo) {
diff --git a/lib/hooks/promote-sidebar.react.js b/lib/hooks/promote-sidebar.react.js
--- a/lib/hooks/promote-sidebar.react.js
+++ b/lib/hooks/promote-sidebar.react.js
@@ -5,18 +5,24 @@
import {
changeThreadSettingsActionTypes,
changeThreadSettings,
-} from '../actions/thread-actions';
-import { createLoadingStatusSelector } from '../selectors/loading-selectors';
-import { threadInfoSelector } from '../selectors/thread-selectors';
-import { threadHasPermission, threadIsSidebar } from '../shared/thread-utils';
-import type { LoadingStatus } from '../types/loading-types';
+} from '../actions/thread-actions.js';
+import { createLoadingStatusSelector } from '../selectors/loading-selectors.js';
+import { threadInfoSelector } from '../selectors/thread-selectors.js';
+import {
+ threadHasPermission,
+ threadIsSidebar,
+} from '../shared/thread-utils.js';
+import type { LoadingStatus } from '../types/loading-types.js';
import {
threadTypes,
type ThreadInfo,
threadPermissions,
-} from '../types/thread-types';
-import { useServerCall, useDispatchActionPromise } from '../utils/action-utils';
-import { useSelector } from '../utils/redux-utils';
+} from '../types/thread-types.js';
+import {
+ useServerCall,
+ useDispatchActionPromise,
+} from '../utils/action-utils.js';
+import { useSelector } from '../utils/redux-utils.js';
function canPromoteSidebar(
sidebarThreadInfo: ThreadInfo,
diff --git a/lib/hooks/relationship-prompt.js b/lib/hooks/relationship-prompt.js
--- a/lib/hooks/relationship-prompt.js
+++ b/lib/hooks/relationship-prompt.js
@@ -7,15 +7,18 @@
import {
updateRelationships as serverUpdateRelationships,
updateRelationshipsActionTypes,
-} from '../actions/relationship-actions';
-import { getSingleOtherUser } from '../shared/thread-utils';
+} from '../actions/relationship-actions.js';
+import { getSingleOtherUser } from '../shared/thread-utils.js';
import {
type RelationshipAction,
relationshipActions,
-} from '../types/relationship-types';
-import type { ThreadInfo } from '../types/thread-types';
-import type { UserInfo } from '../types/user-types';
-import { useDispatchActionPromise, useServerCall } from '../utils/action-utils';
+} from '../types/relationship-types.js';
+import type { ThreadInfo } from '../types/thread-types.js';
+import type { UserInfo } from '../types/user-types.js';
+import {
+ useDispatchActionPromise,
+ useServerCall,
+} from '../utils/action-utils.js';
type RelationshipCallbacks = {
+blockUser: () => void,
diff --git a/lib/hooks/search-threads.js b/lib/hooks/search-threads.js
--- a/lib/hooks/search-threads.js
+++ b/lib/hooks/search-threads.js
@@ -5,17 +5,17 @@
import {
type ChatThreadItem,
useFilteredChatListData,
-} from '../selectors/chat-selectors';
-import { useThreadSearchIndex } from '../selectors/nav-selectors';
-import { sidebarInfoSelector } from '../selectors/thread-selectors';
-import { threadIsChannel } from '../shared/thread-utils';
-import type { SetState } from '../types/hook-types';
+} from '../selectors/chat-selectors.js';
+import { useThreadSearchIndex } from '../selectors/nav-selectors.js';
+import { sidebarInfoSelector } from '../selectors/thread-selectors.js';
+import { threadIsChannel } from '../shared/thread-utils.js';
+import type { SetState } from '../types/hook-types.js';
import type {
SidebarInfo,
ThreadInfo,
RawThreadInfo,
-} from '../types/thread-types';
-import { useSelector } from '../utils/redux-utils';
+} from '../types/thread-types.js';
+import { useSelector } from '../utils/redux-utils.js';
export type ThreadSearchState = {
+text: string,
diff --git a/lib/hooks/toggle-unread-status.js b/lib/hooks/toggle-unread-status.js
--- a/lib/hooks/toggle-unread-status.js
+++ b/lib/hooks/toggle-unread-status.js
@@ -5,13 +5,16 @@
import {
setThreadUnreadStatus,
setThreadUnreadStatusActionTypes,
-} from '../actions/activity-actions';
+} from '../actions/activity-actions.js';
import type {
SetThreadUnreadStatusPayload,
SetThreadUnreadStatusRequest,
-} from '../types/activity-types';
-import type { ThreadInfo } from '../types/thread-types';
-import { useDispatchActionPromise, useServerCall } from '../utils/action-utils';
+} from '../types/activity-types.js';
+import type { ThreadInfo } from '../types/thread-types.js';
+import {
+ useDispatchActionPromise,
+ useServerCall,
+} from '../utils/action-utils.js';
function useToggleUnreadStatus(
threadInfo: ThreadInfo,
diff --git a/lib/media/file-utils.js b/lib/media/file-utils.js
--- a/lib/media/file-utils.js
+++ b/lib/media/file-utils.js
@@ -3,8 +3,8 @@
import fileType from 'file-type';
import invariant from 'invariant';
-import type { Shape } from '../types/core';
-import type { MediaType } from '../types/media-types';
+import type { Shape } from '../types/core.js';
+import type { MediaType } from '../types/media-types.js';
type ResultMIME = 'image/png' | 'image/jpeg';
type MediaConfig = {
diff --git a/lib/media/image-utils.js b/lib/media/image-utils.js
--- a/lib/media/image-utils.js
+++ b/lib/media/image-utils.js
@@ -1,8 +1,8 @@
// @flow
-import type { Dimensions } from '../types/media-types';
-import { getTargetMIME } from './file-utils';
-import { maxDimensions } from './media-utils';
+import type { Dimensions } from '../types/media-types.js';
+import { getTargetMIME } from './file-utils.js';
+import { maxDimensions } from './media-utils.js';
const { height: maxHeight, width: maxWidth } = maxDimensions;
diff --git a/lib/media/media-utils.js b/lib/media/media-utils.js
--- a/lib/media/media-utils.js
+++ b/lib/media/media-utils.js
@@ -2,12 +2,12 @@
import invariant from 'invariant';
-import type { PlatformDetails } from '../types/device-types';
-import type { Media } from '../types/media-types';
+import type { PlatformDetails } from '../types/device-types.js';
+import type { Media } from '../types/media-types.js';
import type {
MultimediaMessageInfo,
RawMultimediaMessageInfo,
-} from '../types/message-types';
+} from '../types/message-types.js';
const maxDimensions = Object.freeze({ width: 1920, height: 1920 });
diff --git a/lib/media/video-utils.js b/lib/media/video-utils.js
--- a/lib/media/video-utils.js
+++ b/lib/media/video-utils.js
@@ -2,10 +2,10 @@
import invariant from 'invariant';
-import type { Dimensions, MediaMissionFailure } from '../types/media-types';
-import { getUUID } from '../utils/uuid';
-import { replaceExtension, sanitizeFilename } from './file-utils';
-import { maxDimensions } from './media-utils';
+import type { Dimensions, MediaMissionFailure } from '../types/media-types.js';
+import { getUUID } from '../utils/uuid.js';
+import { replaceExtension, sanitizeFilename } from './file-utils.js';
+import { maxDimensions } from './media-utils.js';
const { height: maxHeight, width: maxWidth } = maxDimensions;
diff --git a/lib/permissions/prefixes.js b/lib/permissions/prefixes.js
--- a/lib/permissions/prefixes.js
+++ b/lib/permissions/prefixes.js
@@ -9,7 +9,7 @@
type ThreadPermissionFilterPrefix,
threadTypes,
type ThreadType,
-} from '../types/thread-types';
+} from '../types/thread-types.js';
type ParsedThreadPermissionString = {
+permission: ThreadPermission,
diff --git a/lib/permissions/thread-permissions.js b/lib/permissions/thread-permissions.js
--- a/lib/permissions/thread-permissions.js
+++ b/lib/permissions/thread-permissions.js
@@ -9,11 +9,11 @@
type ThreadPermissionsInfo,
threadPermissions,
threadPermissionPropagationPrefixes,
-} from '../types/thread-types';
+} from '../types/thread-types.js';
import {
parseThreadPermissionString,
includeThreadPermissionForThreadType,
-} from './prefixes';
+} from './prefixes.js';
function permissionLookup(
permissions: ?ThreadPermissionsBlob | ?ThreadPermissionsInfo,
diff --git a/lib/reducers/calendar-filters-reducer.js b/lib/reducers/calendar-filters-reducer.js
--- a/lib/reducers/calendar-filters-reducer.js
+++ b/lib/reducers/calendar-filters-reducer.js
@@ -1,24 +1,24 @@
// @flow
-import { siweAuthActionTypes } from '../actions/siwe-actions';
+import { siweAuthActionTypes } from '../actions/siwe-actions.js';
import {
newThreadActionTypes,
joinThreadActionTypes,
leaveThreadActionTypes,
deleteThreadActionTypes,
-} from '../actions/thread-actions';
+} from '../actions/thread-actions.js';
import {
logOutActionTypes,
deleteAccountActionTypes,
logInActionTypes,
registerActionTypes,
-} from '../actions/user-actions';
+} from '../actions/user-actions.js';
import {
filteredThreadIDs,
nonThreadCalendarFilters,
nonExcludeDeletedCalendarFilters,
-} from '../selectors/calendar-filter-selectors';
-import { threadInFilterList } from '../shared/thread-utils';
+} from '../selectors/calendar-filter-selectors.js';
+import { threadInFilterList } from '../shared/thread-utils.js';
import {
type CalendarFilter,
defaultCalendarFilters,
@@ -26,19 +26,19 @@
clearCalendarThreadFilter,
setCalendarDeletedFilter,
calendarThreadFilterTypes,
-} from '../types/filter-types';
-import type { BaseAction } from '../types/redux-types';
+} from '../types/filter-types.js';
+import type { BaseAction } from '../types/redux-types.js';
import {
fullStateSyncActionType,
incrementalStateSyncActionType,
-} from '../types/socket-types';
-import type { RawThreadInfo } from '../types/thread-types';
+} from '../types/socket-types.js';
+import type { RawThreadInfo } from '../types/thread-types.js';
import {
updateTypes,
type ClientUpdateInfo,
processUpdatesActionType,
-} from '../types/update-types';
-import { setNewSessionActionType } from '../utils/action-utils';
+} from '../types/update-types.js';
+import { setNewSessionActionType } from '../utils/action-utils.js';
export default function reduceCalendarFilters(
state: $ReadOnlyArray<CalendarFilter>,
diff --git a/lib/reducers/connection-reducer.js b/lib/reducers/connection-reducer.js
--- a/lib/reducers/connection-reducer.js
+++ b/lib/reducers/connection-reducer.js
@@ -1,17 +1,17 @@
// @flow
-import { updateActivityActionTypes } from '../actions/activity-actions';
-import { updateCalendarQueryActionTypes } from '../actions/entry-actions';
-import { siweAuthActionTypes } from '../actions/siwe-actions';
+import { updateActivityActionTypes } from '../actions/activity-actions.js';
+import { updateCalendarQueryActionTypes } from '../actions/entry-actions.js';
+import { siweAuthActionTypes } from '../actions/siwe-actions.js';
import {
logOutActionTypes,
deleteAccountActionTypes,
logInActionTypes,
registerActionTypes,
-} from '../actions/user-actions';
-import { queueActivityUpdatesActionType } from '../types/activity-types';
-import { defaultCalendarQuery } from '../types/entry-types';
-import { type BaseAction, rehydrateActionType } from '../types/redux-types';
+} from '../actions/user-actions.js';
+import { queueActivityUpdatesActionType } from '../types/activity-types.js';
+import { defaultCalendarQuery } from '../types/entry-types.js';
+import { type BaseAction, rehydrateActionType } from '../types/redux-types.js';
import {
type ConnectionInfo,
updateConnectionStatusActionType,
@@ -19,10 +19,10 @@
incrementalStateSyncActionType,
setLateResponseActionType,
updateDisconnectedBarActionType,
-} from '../types/socket-types';
-import { setNewSessionActionType } from '../utils/action-utils';
-import { getConfig } from '../utils/config';
-import { unsupervisedBackgroundActionType } from './lifecycle-state-reducer';
+} from '../types/socket-types.js';
+import { setNewSessionActionType } from '../utils/action-utils.js';
+import { getConfig } from '../utils/config.js';
+import { unsupervisedBackgroundActionType } from './lifecycle-state-reducer.js';
export default function reduceConnectionInfo(
state: ConnectionInfo,
diff --git a/lib/reducers/data-loaded-reducer.js b/lib/reducers/data-loaded-reducer.js
--- a/lib/reducers/data-loaded-reducer.js
+++ b/lib/reducers/data-loaded-reducer.js
@@ -1,14 +1,14 @@
// @flow
-import { siweAuthActionTypes } from '../actions/siwe-actions';
+import { siweAuthActionTypes } from '../actions/siwe-actions.js';
import {
logOutActionTypes,
deleteAccountActionTypes,
logInActionTypes,
registerActionTypes,
-} from '../actions/user-actions';
-import type { BaseAction } from '../types/redux-types';
-import { setNewSessionActionType } from '../utils/action-utils';
+} from '../actions/user-actions.js';
+import type { BaseAction } from '../types/redux-types.js';
+import { setNewSessionActionType } from '../utils/action-utils.js';
export default function reduceDataLoaded(
state: boolean,
diff --git a/lib/reducers/draft-reducer.js b/lib/reducers/draft-reducer.js
--- a/lib/reducers/draft-reducer.js
+++ b/lib/reducers/draft-reducer.js
@@ -1,17 +1,17 @@
// @flow
-import { setClientDBStoreActionType } from '../actions/client-db-store-actions';
+import { setClientDBStoreActionType } from '../actions/client-db-store-actions.js';
import {
moveDraftActionType,
updateDraftActionType,
-} from '../actions/draft-actions';
+} from '../actions/draft-actions.js';
import {
deleteAccountActionTypes,
logOutActionTypes,
-} from '../actions/user-actions';
-import type { DraftStore, DraftStoreOperation } from '../types/draft-types';
-import type { BaseAction } from '../types/redux-types';
-import { setNewSessionActionType } from '../utils/action-utils';
+} from '../actions/user-actions.js';
+import type { DraftStore, DraftStoreOperation } from '../types/draft-types.js';
+import type { BaseAction } from '../types/redux-types.js';
+import { setNewSessionActionType } from '../utils/action-utils.js';
type ReduceDraftStoreResult = {
+draftStoreOperations: $ReadOnlyArray<DraftStoreOperation>,
diff --git a/lib/reducers/enabled-apps-reducer.js b/lib/reducers/enabled-apps-reducer.js
--- a/lib/reducers/enabled-apps-reducer.js
+++ b/lib/reducers/enabled-apps-reducer.js
@@ -4,12 +4,12 @@
deleteAccountActionTypes,
logOutActionTypes,
} from '../actions/user-actions.js';
-import type { EnabledApps } from '../types/enabled-apps';
+import type { EnabledApps } from '../types/enabled-apps.js';
import {
defaultEnabledApps,
defaultWebEnabledApps,
-} from '../types/enabled-apps';
-import type { BaseAction } from '../types/redux-types';
+} from '../types/enabled-apps.js';
+import type { BaseAction } from '../types/redux-types.js';
import { setNewSessionActionType } from '../utils/action-utils.js';
export const enableAppActionType = 'ENABLE_APP';
diff --git a/lib/reducers/entry-reducer.js b/lib/reducers/entry-reducer.js
--- a/lib/reducers/entry-reducer.js
+++ b/lib/reducers/entry-reducer.js
@@ -1,17 +1,17 @@
// @flow
import invariant from 'invariant';
-import _filter from 'lodash/fp/filter';
-import _flow from 'lodash/fp/flow';
-import _groupBy from 'lodash/fp/groupBy';
-import _isEqual from 'lodash/fp/isEqual';
-import _map from 'lodash/fp/map';
-import _mapKeys from 'lodash/fp/mapKeys';
-import _mapValues from 'lodash/fp/mapValues';
-import _omitBy from 'lodash/fp/omitBy';
-import _pickBy from 'lodash/fp/pickBy';
-import _sortBy from 'lodash/fp/sortBy';
-import _union from 'lodash/fp/union';
+import _filter from 'lodash/fp/filter.js';
+import _flow from 'lodash/fp/flow.js';
+import _groupBy from 'lodash/fp/groupBy.js';
+import _isEqual from 'lodash/fp/isEqual.js';
+import _map from 'lodash/fp/map.js';
+import _mapKeys from 'lodash/fp/mapKeys.js';
+import _mapValues from 'lodash/fp/mapValues.js';
+import _omitBy from 'lodash/fp/omitBy.js';
+import _pickBy from 'lodash/fp/pickBy.js';
+import _sortBy from 'lodash/fp/sortBy.js';
+import _union from 'lodash/fp/union.js';
import {
fetchEntriesActionTypes,
@@ -23,8 +23,8 @@
deleteEntryActionTypes,
fetchRevisionsForEntryActionTypes,
restoreEntryActionTypes,
-} from '../actions/entry-actions';
-import { siweAuthActionTypes } from '../actions/siwe-actions';
+} from '../actions/entry-actions.js';
+import { siweAuthActionTypes } from '../actions/siwe-actions.js';
import {
deleteThreadActionTypes,
leaveThreadActionTypes,
@@ -33,48 +33,48 @@
removeUsersFromThreadActionTypes,
changeThreadMemberRolesActionTypes,
newThreadActionTypes,
-} from '../actions/thread-actions';
+} from '../actions/thread-actions.js';
import {
logOutActionTypes,
deleteAccountActionTypes,
logInActionTypes,
-} from '../actions/user-actions';
+} from '../actions/user-actions.js';
import {
entryID,
filterRawEntryInfosByCalendarQuery,
serverEntryInfosObject,
-} from '../shared/entry-utils';
-import { threadInFilterList } from '../shared/thread-utils';
+} from '../shared/entry-utils.js';
+import { threadInFilterList } from '../shared/thread-utils.js';
import type {
RawEntryInfo,
EntryStore,
CalendarQuery,
-} from '../types/entry-types';
-import type { BaseAction } from '../types/redux-types';
+} from '../types/entry-types.js';
+import type { BaseAction } from '../types/redux-types.js';
import {
type ClientEntryInconsistencyReportCreationRequest,
reportTypes,
-} from '../types/report-types';
+} from '../types/report-types.js';
import {
serverRequestTypes,
processServerRequestsActionType,
-} from '../types/request-types';
+} from '../types/request-types.js';
import {
fullStateSyncActionType,
incrementalStateSyncActionType,
-} from '../types/socket-types';
-import { type RawThreadInfo } from '../types/thread-types';
+} from '../types/socket-types.js';
+import { type RawThreadInfo } from '../types/thread-types.js';
import {
updateTypes,
type ClientUpdateInfo,
processUpdatesActionType,
-} from '../types/update-types';
-import { actionLogger } from '../utils/action-logger';
-import { setNewSessionActionType } from '../utils/action-utils';
-import { getConfig } from '../utils/config';
-import { dateString } from '../utils/date-utils';
-import { values } from '../utils/objects';
-import { sanitizeActionSecrets } from '../utils/sanitization';
+} from '../types/update-types.js';
+import { actionLogger } from '../utils/action-logger.js';
+import { setNewSessionActionType } from '../utils/action-utils.js';
+import { getConfig } from '../utils/config.js';
+import { dateString } from '../utils/date-utils.js';
+import { values } from '../utils/objects.js';
+import { sanitizeActionSecrets } from '../utils/sanitization.js';
function daysToEntriesFromEntryInfos(
entryInfos: $ReadOnlyArray<RawEntryInfo>,
diff --git a/lib/reducers/lifecycle-state-reducer.js b/lib/reducers/lifecycle-state-reducer.js
--- a/lib/reducers/lifecycle-state-reducer.js
+++ b/lib/reducers/lifecycle-state-reducer.js
@@ -1,7 +1,7 @@
// @flow
-import type { LifecycleState } from '../types/lifecycle-state-types';
-import type { BaseAction } from '../types/redux-types';
+import type { LifecycleState } from '../types/lifecycle-state-types.js';
+import type { BaseAction } from '../types/redux-types.js';
export const unsupervisedBackgroundActionType = 'UNSUPERVISED_BACKGROUND';
export const updateLifecycleStateActionType = 'UPDATE_LIFECYCLE_STATE';
diff --git a/lib/reducers/loading-reducer.js b/lib/reducers/loading-reducer.js
--- a/lib/reducers/loading-reducer.js
+++ b/lib/reducers/loading-reducer.js
@@ -1,10 +1,10 @@
// @flow
-import _omit from 'lodash/fp/omit';
+import _omit from 'lodash/fp/omit.js';
-import type { LoadingStatus } from '../types/loading-types';
-import type { BaseAction } from '../types/redux-types';
-import type { ActionTypes } from '../utils/action-utils';
+import type { LoadingStatus } from '../types/loading-types.js';
+import type { BaseAction } from '../types/redux-types.js';
+import type { ActionTypes } from '../utils/action-utils.js';
const fetchKeyRegistry: Set<string> = new Set();
const registerFetchKey = (actionTypes: ActionTypes<*, *, *>) => {
diff --git a/lib/reducers/local-id-reducer.js b/lib/reducers/local-id-reducer.js
--- a/lib/reducers/local-id-reducer.js
+++ b/lib/reducers/local-id-reducer.js
@@ -2,7 +2,7 @@
import invariant from 'invariant';
-import { createLocalEntryActionType } from '../actions/entry-actions';
+import { createLocalEntryActionType } from '../actions/entry-actions.js';
import {
sendTextMessageActionTypes,
sendMultimediaMessageActionTypes,
@@ -11,24 +11,24 @@
fetchMessagesBeforeCursorActionTypes,
fetchMostRecentMessagesActionTypes,
sendReactionMessageActionTypes,
-} from '../actions/message-actions';
-import { joinThreadActionTypes } from '../actions/thread-actions';
+} from '../actions/message-actions.js';
+import { joinThreadActionTypes } from '../actions/thread-actions.js';
import {
numberFromLocalID,
highestLocalIDSelector,
-} from '../selectors/local-id-selectors';
-import type { RawMessageInfo } from '../types/message-types';
-import type { BaseAction } from '../types/redux-types';
-import { rehydrateActionType } from '../types/redux-types';
+} from '../selectors/local-id-selectors.js';
+import type { RawMessageInfo } from '../types/message-types.js';
+import type { BaseAction } from '../types/redux-types.js';
+import { rehydrateActionType } from '../types/redux-types.js';
import {
fullStateSyncActionType,
incrementalStateSyncActionType,
-} from '../types/socket-types';
+} from '../types/socket-types.js';
import {
updateTypes,
type ClientUpdateInfo,
processUpdatesActionType,
-} from '../types/update-types';
+} from '../types/update-types.js';
export default function reduceNextLocalID(
state: number,
diff --git a/lib/reducers/master-reducer.js b/lib/reducers/master-reducer.js
--- a/lib/reducers/master-reducer.js
+++ b/lib/reducers/master-reducer.js
@@ -1,31 +1,34 @@
// @flow
-import { siweAuthActionTypes } from '../actions/siwe-actions';
-import { registerActionTypes, logInActionTypes } from '../actions/user-actions';
-import type { BaseNavInfo } from '../types/nav-types';
-import type { BaseAppState, BaseAction } from '../types/redux-types';
+import { siweAuthActionTypes } from '../actions/siwe-actions.js';
+import {
+ registerActionTypes,
+ logInActionTypes,
+} from '../actions/user-actions.js';
+import type { BaseNavInfo } from '../types/nav-types.js';
+import type { BaseAppState, BaseAction } from '../types/redux-types.js';
import {
fullStateSyncActionType,
incrementalStateSyncActionType,
-} from '../types/socket-types';
-import type { StoreOperations } from '../types/store-ops-types';
-import reduceCalendarFilters from './calendar-filters-reducer';
-import reduceConnectionInfo from './connection-reducer';
-import reduceDataLoaded from './data-loaded-reducer';
-import { reduceDraftStore } from './draft-reducer';
-import reduceEnabledApps from './enabled-apps-reducer';
-import { reduceEntryInfos } from './entry-reducer';
-import reduceLifecycleState from './lifecycle-state-reducer';
-import { reduceLoadingStatuses } from './loading-reducer';
-import reduceNextLocalID from './local-id-reducer';
-import { reduceMessageStore } from './message-reducer';
-import reduceBaseNavInfo from './nav-reducer';
+} from '../types/socket-types.js';
+import type { StoreOperations } from '../types/store-ops-types.js';
+import reduceCalendarFilters from './calendar-filters-reducer.js';
+import reduceConnectionInfo from './connection-reducer.js';
+import reduceDataLoaded from './data-loaded-reducer.js';
+import { reduceDraftStore } from './draft-reducer.js';
+import reduceEnabledApps from './enabled-apps-reducer.js';
+import { reduceEntryInfos } from './entry-reducer.js';
+import reduceLifecycleState from './lifecycle-state-reducer.js';
+import { reduceLoadingStatuses } from './loading-reducer.js';
+import reduceNextLocalID from './local-id-reducer.js';
+import { reduceMessageStore } from './message-reducer.js';
+import reduceBaseNavInfo from './nav-reducer.js';
import policiesReducer from './policies-reducer.js';
-import reduceReportStore from './report-store-reducer';
-import { reduceThreadInfos } from './thread-reducer';
-import reduceUpdatesCurrentAsOf from './updates-reducer';
-import reduceURLPrefix from './url-prefix-reducer';
-import { reduceCurrentUserInfo, reduceUserInfos } from './user-reducer';
+import reduceReportStore from './report-store-reducer.js';
+import { reduceThreadInfos } from './thread-reducer.js';
+import reduceUpdatesCurrentAsOf from './updates-reducer.js';
+import reduceURLPrefix from './url-prefix-reducer.js';
+import { reduceCurrentUserInfo, reduceUserInfos } from './user-reducer.js';
export default function baseReducer<N: BaseNavInfo, T: BaseAppState<N>>(
state: T,
diff --git a/lib/reducers/message-reducer.js b/lib/reducers/message-reducer.js
--- a/lib/reducers/message-reducer.js
+++ b/lib/reducers/message-reducer.js
@@ -1,26 +1,26 @@
// @flow
import invariant from 'invariant';
-import _difference from 'lodash/fp/difference';
-import _flow from 'lodash/fp/flow';
-import _isEqual from 'lodash/fp/isEqual';
-import _keyBy from 'lodash/fp/keyBy';
-import _map from 'lodash/fp/map';
-import _mapKeys from 'lodash/fp/mapKeys';
-import _mapValues from 'lodash/fp/mapValues';
-import _omit from 'lodash/fp/omit';
-import _omitBy from 'lodash/fp/omitBy';
-import _pick from 'lodash/fp/pick';
-import _pickBy from 'lodash/fp/pickBy';
-import _uniq from 'lodash/fp/uniq';
-
-import { setClientDBStoreActionType } from '../actions/client-db-store-actions';
+import _difference from 'lodash/fp/difference.js';
+import _flow from 'lodash/fp/flow.js';
+import _isEqual from 'lodash/fp/isEqual.js';
+import _keyBy from 'lodash/fp/keyBy.js';
+import _map from 'lodash/fp/map.js';
+import _mapKeys from 'lodash/fp/mapKeys.js';
+import _mapValues from 'lodash/fp/mapValues.js';
+import _omit from 'lodash/fp/omit.js';
+import _omitBy from 'lodash/fp/omitBy.js';
+import _pick from 'lodash/fp/pick.js';
+import _pickBy from 'lodash/fp/pickBy.js';
+import _uniq from 'lodash/fp/uniq.js';
+
+import { setClientDBStoreActionType } from '../actions/client-db-store-actions.js';
import {
createEntryActionTypes,
saveEntryActionTypes,
deleteEntryActionTypes,
restoreEntryActionTypes,
-} from '../actions/entry-actions';
+} from '../actions/entry-actions.js';
import {
fetchMessagesBeforeCursorActionTypes,
fetchMostRecentMessagesActionTypes,
@@ -32,9 +32,9 @@
messageStorePruneActionType,
createLocalMessageActionType,
fetchSingleMostRecentMessagesFromThreadsActionTypes,
-} from '../actions/message-actions';
-import { sendMessageReportActionTypes } from '../actions/message-report-actions';
-import { siweAuthActionTypes } from '../actions/siwe-actions';
+} from '../actions/message-actions.js';
+import { sendMessageReportActionTypes } from '../actions/message-report-actions.js';
+import { siweAuthActionTypes } from '../actions/siwe-actions.js';
import {
changeThreadSettingsActionTypes,
deleteThreadActionTypes,
@@ -43,30 +43,30 @@
removeUsersFromThreadActionTypes,
changeThreadMemberRolesActionTypes,
joinThreadActionTypes,
-} from '../actions/thread-actions';
-import { updateMultimediaMessageMediaActionType } from '../actions/upload-actions';
+} from '../actions/thread-actions.js';
+import { updateMultimediaMessageMediaActionType } from '../actions/upload-actions.js';
import {
logOutActionTypes,
deleteAccountActionTypes,
logInActionTypes,
registerActionTypes,
-} from '../actions/user-actions';
-import { pendingToRealizedThreadIDsSelector } from '../selectors/thread-selectors';
+} from '../actions/user-actions.js';
+import { pendingToRealizedThreadIDsSelector } from '../selectors/thread-selectors.js';
import {
messageID,
combineTruncationStatuses,
sortMessageInfoList,
sortMessageIDs,
mergeThreadMessageInfos,
-} from '../shared/message-utils';
+} from '../shared/message-utils.js';
import {
threadHasPermission,
threadInChatList,
threadIsPending,
-} from '../shared/thread-utils';
-import threadWatcher from '../shared/thread-watcher';
-import { unshimMessageInfos } from '../shared/unshim-utils';
-import type { Media, Image } from '../types/media-types';
+} from '../shared/thread-utils.js';
+import threadWatcher from '../shared/thread-watcher.js';
+import { unshimMessageInfos } from '../shared/unshim-utils.js';
+import type { Media, Image } from '../types/media-types.js';
import {
type RawMessageInfo,
type LocalMessageInfo,
@@ -79,23 +79,26 @@
messageTruncationStatus,
messageTypes,
defaultNumberPerThread,
-} from '../types/message-types';
-import type { RawImagesMessageInfo } from '../types/messages/images';
-import type { RawMediaMessageInfo } from '../types/messages/media';
-import { type BaseAction } from '../types/redux-types';
-import { processServerRequestsActionType } from '../types/request-types';
+} from '../types/message-types.js';
+import type { RawImagesMessageInfo } from '../types/messages/images.js';
+import type { RawMediaMessageInfo } from '../types/messages/media.js';
+import { type BaseAction } from '../types/redux-types.js';
+import { processServerRequestsActionType } from '../types/request-types.js';
import {
fullStateSyncActionType,
incrementalStateSyncActionType,
-} from '../types/socket-types';
-import { type RawThreadInfo, threadPermissions } from '../types/thread-types';
+} from '../types/socket-types.js';
+import {
+ type RawThreadInfo,
+ threadPermissions,
+} from '../types/thread-types.js';
import {
updateTypes,
type ClientUpdateInfo,
processUpdatesActionType,
-} from '../types/update-types';
-import { setNewSessionActionType } from '../utils/action-utils';
-import { translateClientDBMessageInfosToRawMessageInfos } from '../utils/message-ops-utils';
+} from '../types/update-types.js';
+import { setNewSessionActionType } from '../utils/action-utils.js';
+import { translateClientDBMessageInfosToRawMessageInfos } from '../utils/message-ops-utils.js';
const _mapValuesWithKeys = _mapValues.convert({ cap: false });
diff --git a/lib/reducers/message-reducer.test.js b/lib/reducers/message-reducer.test.js
--- a/lib/reducers/message-reducer.test.js
+++ b/lib/reducers/message-reducer.test.js
@@ -2,11 +2,11 @@
import invariant from 'invariant';
-import { createPendingThread } from '../shared/thread-utils';
-import type { MessageStore } from '../types/message-types';
-import { messageTypes } from '../types/message-types';
-import { threadTypes } from '../types/thread-types';
-import { reduceMessageStore } from './message-reducer';
+import { createPendingThread } from '../shared/thread-utils.js';
+import type { MessageStore } from '../types/message-types.js';
+import { messageTypes } from '../types/message-types.js';
+import { threadTypes } from '../types/thread-types.js';
+import { reduceMessageStore } from './message-reducer.js';
const messageStoreBeforeMediaUpdate: MessageStore = {
messages: {
diff --git a/lib/reducers/nav-reducer.js b/lib/reducers/nav-reducer.js
--- a/lib/reducers/nav-reducer.js
+++ b/lib/reducers/nav-reducer.js
@@ -1,14 +1,17 @@
// @flow
-import { updateCalendarQueryActionTypes } from '../actions/entry-actions';
-import { siweAuthActionTypes } from '../actions/siwe-actions';
-import { logInActionTypes, registerActionTypes } from '../actions/user-actions';
-import type { BaseNavInfo } from '../types/nav-types';
-import type { BaseAction } from '../types/redux-types';
+import { updateCalendarQueryActionTypes } from '../actions/entry-actions.js';
+import { siweAuthActionTypes } from '../actions/siwe-actions.js';
+import {
+ logInActionTypes,
+ registerActionTypes,
+} from '../actions/user-actions.js';
+import type { BaseNavInfo } from '../types/nav-types.js';
+import type { BaseAction } from '../types/redux-types.js';
import {
fullStateSyncActionType,
incrementalStateSyncActionType,
-} from '../types/socket-types';
+} from '../types/socket-types.js';
export default function reduceBaseNavInfo<T: BaseNavInfo>(
state: T,
diff --git a/lib/reducers/policies-reducer.js b/lib/reducers/policies-reducer.js
--- a/lib/reducers/policies-reducer.js
+++ b/lib/reducers/policies-reducer.js
@@ -10,7 +10,7 @@
type UserPolicies,
forcePolicyAcknowledgmentActionType,
} from '../types/policy-types.js';
-import type { BaseAction } from '../types/redux-types';
+import type { BaseAction } from '../types/redux-types.js';
function policiesReducer(
state: UserPolicies,
diff --git a/lib/reducers/report-store-reducer.js b/lib/reducers/report-store-reducer.js
--- a/lib/reducers/report-store-reducer.js
+++ b/lib/reducers/report-store-reducer.js
@@ -4,24 +4,24 @@
sendReportActionTypes,
sendReportsActionTypes,
queueReportsActionType,
-} from '../actions/report-actions';
-import { siweAuthActionTypes } from '../actions/siwe-actions';
+} from '../actions/report-actions.js';
+import { siweAuthActionTypes } from '../actions/siwe-actions.js';
import {
logOutActionTypes,
deleteAccountActionTypes,
logInActionTypes,
-} from '../actions/user-actions';
-import { isStaff } from '../shared/user-utils';
-import type { BaseAction } from '../types/redux-types';
+} from '../actions/user-actions.js';
+import { isStaff } from '../shared/user-utils.js';
+import type { BaseAction } from '../types/redux-types.js';
import {
type ReportStore,
defaultEnabledReports,
defaultDevEnabledReports,
type ClientReportCreationRequest,
-} from '../types/report-types';
-import { setNewSessionActionType } from '../utils/action-utils';
-import { isDev } from '../utils/dev-utils';
-import { isReportEnabled } from '../utils/report-utils';
+} from '../types/report-types.js';
+import { setNewSessionActionType } from '../utils/action-utils.js';
+import { isDev } from '../utils/dev-utils.js';
+import { isReportEnabled } from '../utils/report-utils.js';
export const updateReportsEnabledActionType = 'UPDATE_REPORTS_ENABLED';
diff --git a/lib/reducers/thread-reducer.js b/lib/reducers/thread-reducer.js
--- a/lib/reducers/thread-reducer.js
+++ b/lib/reducers/thread-reducer.js
@@ -1,14 +1,14 @@
// @flow
-import _isEqual from 'lodash/fp/isEqual';
+import _isEqual from 'lodash/fp/isEqual.js';
import {
setThreadUnreadStatusActionTypes,
updateActivityActionTypes,
-} from '../actions/activity-actions';
+} from '../actions/activity-actions.js';
import { setClientDBStoreActionType } from '../actions/client-db-store-actions.js';
-import { saveMessagesActionType } from '../actions/message-actions';
-import { siweAuthActionTypes } from '../actions/siwe-actions';
+import { saveMessagesActionType } from '../actions/message-actions.js';
+import { siweAuthActionTypes } from '../actions/siwe-actions.js';
import {
changeThreadSettingsActionTypes,
deleteThreadActionTypes,
@@ -17,41 +17,41 @@
changeThreadMemberRolesActionTypes,
joinThreadActionTypes,
leaveThreadActionTypes,
-} from '../actions/thread-actions';
+} from '../actions/thread-actions.js';
import {
logOutActionTypes,
deleteAccountActionTypes,
logInActionTypes,
registerActionTypes,
updateSubscriptionActionTypes,
-} from '../actions/user-actions';
-import type { BaseAction } from '../types/redux-types';
+} from '../actions/user-actions.js';
+import type { BaseAction } from '../types/redux-types.js';
import {
type ClientThreadInconsistencyReportCreationRequest,
reportTypes,
-} from '../types/report-types';
+} from '../types/report-types.js';
import {
serverRequestTypes,
processServerRequestsActionType,
-} from '../types/request-types';
+} from '../types/request-types.js';
import {
fullStateSyncActionType,
incrementalStateSyncActionType,
-} from '../types/socket-types';
+} from '../types/socket-types.js';
import type {
RawThreadInfo,
ThreadStore,
ThreadStoreOperation,
-} from '../types/thread-types';
+} from '../types/thread-types.js';
import {
updateTypes,
type ClientUpdateInfo,
processUpdatesActionType,
-} from '../types/update-types';
-import { actionLogger } from '../utils/action-logger';
-import { setNewSessionActionType } from '../utils/action-utils';
-import { getConfig } from '../utils/config';
-import { sanitizeActionSecrets } from '../utils/sanitization';
+} from '../types/update-types.js';
+import { actionLogger } from '../utils/action-logger.js';
+import { setNewSessionActionType } from '../utils/action-utils.js';
+import { getConfig } from '../utils/config.js';
+import { sanitizeActionSecrets } from '../utils/sanitization.js';
function generateOpsForThreadUpdates(
threadInfos: { +[id: string]: RawThreadInfo },
diff --git a/lib/reducers/updates-reducer.js b/lib/reducers/updates-reducer.js
--- a/lib/reducers/updates-reducer.js
+++ b/lib/reducers/updates-reducer.js
@@ -1,13 +1,13 @@
// @flow
-import { siweAuthActionTypes } from '../actions/siwe-actions';
-import { logInActionTypes } from '../actions/user-actions';
-import type { BaseAction } from '../types/redux-types';
+import { siweAuthActionTypes } from '../actions/siwe-actions.js';
+import { logInActionTypes } from '../actions/user-actions.js';
+import type { BaseAction } from '../types/redux-types.js';
import {
fullStateSyncActionType,
incrementalStateSyncActionType,
-} from '../types/socket-types';
-import { processUpdatesActionType } from '../types/update-types';
+} from '../types/socket-types.js';
+import { processUpdatesActionType } from '../types/update-types.js';
function reduceUpdatesCurrentAsOf(
currentAsOf: number,
diff --git a/lib/reducers/url-prefix-reducer.js b/lib/reducers/url-prefix-reducer.js
--- a/lib/reducers/url-prefix-reducer.js
+++ b/lib/reducers/url-prefix-reducer.js
@@ -1,7 +1,7 @@
// @flow
-import type { BaseAction } from '../types/redux-types';
-import { setURLPrefix } from '../utils/url-utils';
+import type { BaseAction } from '../types/redux-types.js';
+import { setURLPrefix } from '../utils/url-utils.js';
export default function reduceURLPrefix(
state: string,
diff --git a/lib/reducers/user-reducer.js b/lib/reducers/user-reducer.js
--- a/lib/reducers/user-reducer.js
+++ b/lib/reducers/user-reducer.js
@@ -1,43 +1,46 @@
// @flow
-import _isEqual from 'lodash/fp/isEqual';
-import _keyBy from 'lodash/fp/keyBy';
+import _isEqual from 'lodash/fp/isEqual.js';
+import _keyBy from 'lodash/fp/keyBy.js';
-import { siweAuthActionTypes } from '../actions/siwe-actions';
+import { siweAuthActionTypes } from '../actions/siwe-actions.js';
import {
joinThreadActionTypes,
newThreadActionTypes,
-} from '../actions/thread-actions';
+} from '../actions/thread-actions.js';
import {
logOutActionTypes,
deleteAccountActionTypes,
logInActionTypes,
registerActionTypes,
setUserSettingsActionTypes,
-} from '../actions/user-actions';
-import type { BaseAction } from '../types/redux-types';
+} from '../actions/user-actions.js';
+import type { BaseAction } from '../types/redux-types.js';
import {
type UserInconsistencyReportCreationRequest,
reportTypes,
-} from '../types/report-types';
+} from '../types/report-types.js';
import {
serverRequestTypes,
processServerRequestsActionType,
-} from '../types/request-types';
+} from '../types/request-types.js';
import {
fullStateSyncActionType,
incrementalStateSyncActionType,
-} from '../types/socket-types';
-import { updateTypes, processUpdatesActionType } from '../types/update-types';
+} from '../types/socket-types.js';
+import {
+ updateTypes,
+ processUpdatesActionType,
+} from '../types/update-types.js';
import type {
CurrentUserInfo,
UserStore,
UserInfos,
-} from '../types/user-types';
-import { actionLogger } from '../utils/action-logger';
-import { setNewSessionActionType } from '../utils/action-utils';
-import { getConfig } from '../utils/config';
-import { sanitizeActionSecrets } from '../utils/sanitization';
+} from '../types/user-types.js';
+import { actionLogger } from '../utils/action-logger.js';
+import { setNewSessionActionType } from '../utils/action-utils.js';
+import { getConfig } from '../utils/config.js';
+import { sanitizeActionSecrets } from '../utils/sanitization.js';
function reduceCurrentUserInfo(
state: ?CurrentUserInfo,
diff --git a/lib/selectors/account-selectors.js b/lib/selectors/account-selectors.js
--- a/lib/selectors/account-selectors.js
+++ b/lib/selectors/account-selectors.js
@@ -2,14 +2,14 @@
import { createSelector } from 'reselect';
-import type { LogInExtraInfo } from '../types/account-types';
-import { isDeviceType } from '../types/device-types';
-import type { CalendarQuery } from '../types/entry-types';
-import type { AppState } from '../types/redux-types';
-import type { PreRequestUserState } from '../types/session-types';
-import type { CurrentUserInfo } from '../types/user-types';
-import { getConfig } from '../utils/config';
-import { currentCalendarQuery } from './nav-selectors';
+import type { LogInExtraInfo } from '../types/account-types.js';
+import { isDeviceType } from '../types/device-types.js';
+import type { CalendarQuery } from '../types/entry-types.js';
+import type { AppState } from '../types/redux-types.js';
+import type { PreRequestUserState } from '../types/session-types.js';
+import type { CurrentUserInfo } from '../types/user-types.js';
+import { getConfig } from '../utils/config.js';
+import { currentCalendarQuery } from './nav-selectors.js';
const logInExtraInfoSelector: (
state: AppState,
diff --git a/lib/selectors/calendar-filter-selectors.js b/lib/selectors/calendar-filter-selectors.js
--- a/lib/selectors/calendar-filter-selectors.js
+++ b/lib/selectors/calendar-filter-selectors.js
@@ -6,8 +6,8 @@
type CalendarFilter,
calendarThreadFilterTypes,
type CalendarThreadFilterType,
-} from '../types/filter-types';
-import type { BaseAppState } from '../types/redux-types';
+} from '../types/filter-types.js';
+import type { BaseAppState } from '../types/redux-types.js';
function filteredThreadIDs(
calendarFilters: $ReadOnlyArray<CalendarFilter>,
diff --git a/lib/selectors/calendar-selectors.js b/lib/selectors/calendar-selectors.js
--- a/lib/selectors/calendar-selectors.js
+++ b/lib/selectors/calendar-selectors.js
@@ -2,15 +2,15 @@
import * as React from 'react';
-import { rawEntryInfoWithinActiveRange } from '../shared/entry-utils';
-import SearchIndex from '../shared/search-index';
-import { threadInFilterList } from '../shared/thread-utils';
-import type { FilterThreadInfo } from '../types/filter-types';
-import { useResolvedThreadInfosObj } from '../utils/entity-helpers';
-import { values } from '../utils/objects';
-import { useSelector } from '../utils/redux-utils';
-import { currentCalendarQuery } from './nav-selectors';
-import { threadInfoSelector } from './thread-selectors';
+import { rawEntryInfoWithinActiveRange } from '../shared/entry-utils.js';
+import SearchIndex from '../shared/search-index.js';
+import { threadInFilterList } from '../shared/thread-utils.js';
+import type { FilterThreadInfo } from '../types/filter-types.js';
+import { useResolvedThreadInfosObj } from '../utils/entity-helpers.js';
+import { values } from '../utils/objects.js';
+import { useSelector } from '../utils/redux-utils.js';
+import { currentCalendarQuery } from './nav-selectors.js';
+import { threadInfoSelector } from './thread-selectors.js';
function useFilterThreadInfos(
calendarActive: boolean,
diff --git a/lib/selectors/chat-selectors.js b/lib/selectors/chat-selectors.js
--- a/lib/selectors/chat-selectors.js
+++ b/lib/selectors/chat-selectors.js
@@ -1,10 +1,10 @@
// @flow
import invariant from 'invariant';
-import _filter from 'lodash/fp/filter';
-import _flow from 'lodash/fp/flow';
-import _map from 'lodash/fp/map';
-import _orderBy from 'lodash/fp/orderBy';
+import _filter from 'lodash/fp/filter.js';
+import _flow from 'lodash/fp/flow.js';
+import _map from 'lodash/fp/map.js';
+import _orderBy from 'lodash/fp/orderBy.js';
import * as React from 'react';
import { useSelector } from 'react-redux';
import { createSelector } from 'reselect';
@@ -16,12 +16,12 @@
createMessageInfo,
getMostRecentNonLocalMessageID,
sortMessageInfoList,
-} from '../shared/message-utils';
+} from '../shared/message-utils.js';
import {
threadIsPending,
threadIsTopLevel,
threadInChatList,
-} from '../shared/thread-utils';
+} from '../shared/thread-utils.js';
import {
type MessageInfo,
type MessageStore,
@@ -30,8 +30,8 @@
type LocalMessageInfo,
messageTypes,
isComposableMessageType,
-} from '../types/message-types';
-import type { BaseAppState } from '../types/redux-types';
+} from '../types/message-types.js';
+import type { BaseAppState } from '../types/redux-types.js';
import {
type ThreadInfo,
type RawThreadInfo,
@@ -39,20 +39,20 @@
maxReadSidebars,
maxUnreadSidebars,
threadTypes,
-} from '../types/thread-types';
+} from '../types/thread-types.js';
import type {
UserInfo,
AccountUserInfo,
RelativeUserInfo,
-} from '../types/user-types';
-import { threeDays } from '../utils/date-utils';
-import type { EntityText } from '../utils/entity-text';
-import memoize2 from '../utils/memoize';
+} from '../types/user-types.js';
+import { threeDays } from '../utils/date-utils.js';
+import type { EntityText } from '../utils/entity-text.js';
+import memoize2 from '../utils/memoize.js';
import {
threadInfoSelector,
sidebarInfoSelector,
threadInfoFromSourceMessageIDSelector,
-} from './thread-selectors';
+} from './thread-selectors.js';
export type SidebarItem =
| {
diff --git a/lib/selectors/loading-selectors.js b/lib/selectors/loading-selectors.js
--- a/lib/selectors/loading-selectors.js
+++ b/lib/selectors/loading-selectors.js
@@ -1,16 +1,16 @@
// @flow
import invariant from 'invariant';
-import _includes from 'lodash/fp/includes';
-import _isEmpty from 'lodash/fp/isEmpty';
-import _memoize from 'lodash/memoize';
+import _includes from 'lodash/fp/includes.js';
+import _isEmpty from 'lodash/fp/isEmpty.js';
+import _memoize from 'lodash/memoize.js';
import { createSelector } from 'reselect';
-import { registerFetchKey } from '../reducers/loading-reducer';
-import type { LoadingStatus } from '../types/loading-types';
-import type { BaseAppState } from '../types/redux-types';
-import type { ActionTypes } from '../utils/action-utils';
-import { values } from '../utils/objects';
+import { registerFetchKey } from '../reducers/loading-reducer.js';
+import type { LoadingStatus } from '../types/loading-types.js';
+import type { BaseAppState } from '../types/redux-types.js';
+import type { ActionTypes } from '../utils/action-utils.js';
+import { values } from '../utils/objects.js';
function loadingStatusFromInfo(loadingStatusInfo: {
[idx: number]: LoadingStatus,
diff --git a/lib/selectors/local-id-selectors.js b/lib/selectors/local-id-selectors.js
--- a/lib/selectors/local-id-selectors.js
+++ b/lib/selectors/local-id-selectors.js
@@ -2,7 +2,7 @@
import invariant from 'invariant';
-import type { BaseAppState } from '../types/redux-types';
+import type { BaseAppState } from '../types/redux-types.js';
const localIDExtractionRegex = /^local([0-9]+)$/;
diff --git a/lib/selectors/nav-selectors.js b/lib/selectors/nav-selectors.js
--- a/lib/selectors/nav-selectors.js
+++ b/lib/selectors/nav-selectors.js
@@ -3,18 +3,21 @@
import * as React from 'react';
import { createSelector } from 'reselect';
-import { useENSNames } from '../hooks/ens-cache';
-import SearchIndex from '../shared/search-index';
-import { memberHasAdminPowers } from '../shared/thread-utils';
-import type { Platform } from '../types/device-types';
-import { type CalendarQuery, defaultCalendarQuery } from '../types/entry-types';
-import type { CalendarFilter } from '../types/filter-types';
-import type { BaseNavInfo } from '../types/nav-types';
-import type { BaseAppState } from '../types/redux-types';
-import type { RawThreadInfo, ThreadInfo } from '../types/thread-types';
-import { getConfig } from '../utils/config';
-import { values } from '../utils/objects';
-import { useSelector } from '../utils/redux-utils';
+import { useENSNames } from '../hooks/ens-cache.js';
+import SearchIndex from '../shared/search-index.js';
+import { memberHasAdminPowers } from '../shared/thread-utils.js';
+import type { Platform } from '../types/device-types.js';
+import {
+ type CalendarQuery,
+ defaultCalendarQuery,
+} from '../types/entry-types.js';
+import type { CalendarFilter } from '../types/filter-types.js';
+import type { BaseNavInfo } from '../types/nav-types.js';
+import type { BaseAppState } from '../types/redux-types.js';
+import type { RawThreadInfo, ThreadInfo } from '../types/thread-types.js';
+import { getConfig } from '../utils/config.js';
+import { values } from '../utils/objects.js';
+import { useSelector } from '../utils/redux-utils.js';
function timeUntilCalendarRangeExpiration(
lastUserInteractionCalendar: number,
diff --git a/lib/selectors/relationship-selectors.js b/lib/selectors/relationship-selectors.js
--- a/lib/selectors/relationship-selectors.js
+++ b/lib/selectors/relationship-selectors.js
@@ -1,14 +1,14 @@
// @flow
-import _orderBy from 'lodash/fp/orderBy';
+import _orderBy from 'lodash/fp/orderBy.js';
import { createSelector } from 'reselect';
-import type { BaseAppState } from '../types/redux-types';
+import type { BaseAppState } from '../types/redux-types.js';
import {
userRelationshipStatus,
type UserRelationships,
-} from '../types/relationship-types';
-import type { UserInfos } from '../types/user-types';
+} from '../types/relationship-types.js';
+import type { UserInfos } from '../types/user-types.js';
const userRelationshipsSelector: (
state: BaseAppState<*>,
diff --git a/lib/selectors/server-calls.js b/lib/selectors/server-calls.js
--- a/lib/selectors/server-calls.js
+++ b/lib/selectors/server-calls.js
@@ -2,9 +2,9 @@
import { createSelector } from 'reselect';
-import type { AppState } from '../types/redux-types';
-import { type ConnectionStatus } from '../types/socket-types';
-import { type CurrentUserInfo } from '../types/user-types';
+import type { AppState } from '../types/redux-types.js';
+import { type ConnectionStatus } from '../types/socket-types.js';
+import { type CurrentUserInfo } from '../types/user-types.js';
export type ServerCallState = {
+cookie: ?string,
diff --git a/lib/selectors/socket-selectors.js b/lib/selectors/socket-selectors.js
--- a/lib/selectors/socket-selectors.js
+++ b/lib/selectors/socket-selectors.js
@@ -6,24 +6,24 @@
serverEntryInfo,
serverEntryInfosObject,
filterRawEntryInfosByCalendarQuery,
-} from '../shared/entry-utils';
-import threadWatcher from '../shared/thread-watcher';
-import type { RawEntryInfo, CalendarQuery } from '../types/entry-types';
-import type { AppState } from '../types/redux-types';
-import type { ClientReportCreationRequest } from '../types/report-types';
+} from '../shared/entry-utils.js';
+import threadWatcher from '../shared/thread-watcher.js';
+import type { RawEntryInfo, CalendarQuery } from '../types/entry-types.js';
+import type { AppState } from '../types/redux-types.js';
+import type { ClientReportCreationRequest } from '../types/report-types.js';
import {
serverRequestTypes,
type ClientServerRequest,
type ClientClientResponse,
-} from '../types/request-types';
-import type { SessionState } from '../types/session-types';
-import type { OneTimeKeyGenerator } from '../types/socket-types';
-import type { RawThreadInfo } from '../types/thread-types';
-import type { CurrentUserInfo, UserInfos } from '../types/user-types';
-import { getConfig } from '../utils/config';
-import { minimumOneTimeKeysRequired } from '../utils/crypto-utils';
-import { values, hash } from '../utils/objects';
-import { currentCalendarQuery } from './nav-selectors';
+} from '../types/request-types.js';
+import type { SessionState } from '../types/session-types.js';
+import type { OneTimeKeyGenerator } from '../types/socket-types.js';
+import type { RawThreadInfo } from '../types/thread-types.js';
+import type { CurrentUserInfo, UserInfos } from '../types/user-types.js';
+import { getConfig } from '../utils/config.js';
+import { minimumOneTimeKeysRequired } from '../utils/crypto-utils.js';
+import { values, hash } from '../utils/objects.js';
+import { currentCalendarQuery } from './nav-selectors.js';
const queuedReports: (
state: AppState,
diff --git a/lib/selectors/thread-selectors.js b/lib/selectors/thread-selectors.js
--- a/lib/selectors/thread-selectors.js
+++ b/lib/selectors/thread-selectors.js
@@ -1,19 +1,19 @@
// @flow
-import _compact from 'lodash/fp/compact';
-import _filter from 'lodash/fp/filter';
-import _flow from 'lodash/fp/flow';
-import _map from 'lodash/fp/map';
-import _mapValues from 'lodash/fp/mapValues';
-import _orderBy from 'lodash/fp/orderBy';
-import _some from 'lodash/fp/some';
-import _sortBy from 'lodash/fp/sortBy';
-import _memoize from 'lodash/memoize';
+import _compact from 'lodash/fp/compact.js';
+import _filter from 'lodash/fp/filter.js';
+import _flow from 'lodash/fp/flow.js';
+import _map from 'lodash/fp/map.js';
+import _mapValues from 'lodash/fp/mapValues.js';
+import _orderBy from 'lodash/fp/orderBy.js';
+import _some from 'lodash/fp/some.js';
+import _sortBy from 'lodash/fp/sortBy.js';
+import _memoize from 'lodash/memoize.js';
import { createSelector } from 'reselect';
import { createObjectSelector } from 'reselect-map';
-import { createEntryInfo } from '../shared/entry-utils';
-import { getMostRecentNonLocalMessageID } from '../shared/message-utils';
+import { createEntryInfo } from '../shared/entry-utils.js';
+import { getMostRecentNonLocalMessageID } from '../shared/message-utils.js';
import {
threadInHomeChatList,
threadInBackgroundChatList,
@@ -25,10 +25,10 @@
roleIsAdminRole,
threadIsPending,
getPendingThreadID,
-} from '../shared/thread-utils';
-import type { EntryInfo } from '../types/entry-types';
-import type { MessageStore, RawMessageInfo } from '../types/message-types';
-import type { BaseAppState } from '../types/redux-types';
+} from '../shared/thread-utils.js';
+import type { EntryInfo } from '../types/entry-types.js';
+import type { MessageStore, RawMessageInfo } from '../types/message-types.js';
+import type { BaseAppState } from '../types/redux-types.js';
import {
type ThreadInfo,
type RawThreadInfo,
@@ -37,14 +37,14 @@
threadTypes,
type SidebarInfo,
threadTypeIsCommunityRoot,
-} from '../types/thread-types';
-import { dateString, dateFromString } from '../utils/date-utils';
-import { values } from '../utils/objects';
+} from '../types/thread-types.js';
+import { dateString, dateFromString } from '../utils/date-utils.js';
+import { values } from '../utils/objects.js';
import {
filteredThreadIDsSelector,
includeDeletedSelector,
-} from './calendar-filter-selectors';
-import { relativeMemberInfoSelectorForMembersOfThread } from './user-selectors';
+} from './calendar-filter-selectors.js';
+import { relativeMemberInfoSelectorForMembersOfThread } from './user-selectors.js';
const _mapValuesWithKeys = _mapValues.convert({ cap: false });
diff --git a/lib/selectors/user-selectors.js b/lib/selectors/user-selectors.js
--- a/lib/selectors/user-selectors.js
+++ b/lib/selectors/user-selectors.js
@@ -1,25 +1,25 @@
// @flow
-import _memoize from 'lodash/memoize';
+import _memoize from 'lodash/memoize.js';
import { createSelector } from 'reselect';
-import SearchIndex from '../shared/search-index';
+import SearchIndex from '../shared/search-index.js';
import {
getSingleOtherUser,
memberHasAdminPowers,
-} from '../shared/thread-utils';
-import type { BaseAppState } from '../types/redux-types';
-import { userRelationshipStatus } from '../types/relationship-types';
+} from '../shared/thread-utils.js';
+import type { BaseAppState } from '../types/redux-types.js';
+import { userRelationshipStatus } from '../types/relationship-types.js';
import {
type RawThreadInfo,
type RelativeMemberInfo,
threadTypes,
-} from '../types/thread-types';
+} from '../types/thread-types.js';
import type {
UserInfos,
RelativeUserInfo,
AccountUserInfo,
-} from '../types/user-types';
+} from '../types/user-types.js';
// Used for specific message payloads that include an array of user IDs, ie.
// array of initial users, array of added users
diff --git a/lib/shared/account-utils.js b/lib/shared/account-utils.js
--- a/lib/shared/account-utils.js
+++ b/lib/shared/account-utils.js
@@ -3,11 +3,11 @@
import {
logInActionSources,
type LogInActionSource,
-} from '../types/account-types';
-import type { AppState } from '../types/redux-types';
-import type { PreRequestUserState } from '../types/session-types';
-import type { CurrentUserInfo } from '../types/user-types';
-import { isValidEthereumAddress } from '../utils/siwe-utils';
+} from '../types/account-types.js';
+import type { AppState } from '../types/redux-types.js';
+import type { PreRequestUserState } from '../types/session-types.js';
+import type { CurrentUserInfo } from '../types/user-types.js';
+import { isValidEthereumAddress } from '../utils/siwe-utils.js';
const usernameMaxLength = 191;
const usernameMinLength = 1;
diff --git a/lib/shared/ancestor-threads.js b/lib/shared/ancestor-threads.js
--- a/lib/shared/ancestor-threads.js
+++ b/lib/shared/ancestor-threads.js
@@ -1,13 +1,13 @@
// @flow
-import genesis from '../facts/genesis';
+import genesis from '../facts/genesis.js';
import {
threadInfoSelector,
ancestorThreadInfos,
-} from '../selectors/thread-selectors';
-import { threadIsPending } from '../shared/thread-utils';
-import { type ThreadInfo } from '../types/thread-types';
-import { useSelector } from '../utils/redux-utils';
+} from '../selectors/thread-selectors.js';
+import { threadIsPending } from '../shared/thread-utils.js';
+import { type ThreadInfo } from '../types/thread-types.js';
+import { useSelector } from '../utils/redux-utils.js';
function useAncestorThreads(
threadInfo: ThreadInfo,
diff --git a/lib/shared/emojis.test.js b/lib/shared/emojis.test.js
--- a/lib/shared/emojis.test.js
+++ b/lib/shared/emojis.test.js
@@ -1,6 +1,6 @@
// @flow
-import { onlyOneEmojiRegex } from './emojis';
+import { onlyOneEmojiRegex } from './emojis.js';
describe('onlyOneEmojiRegex', () => {
it('should match for (👍)', () => {
diff --git a/lib/shared/entry-utils.js b/lib/shared/entry-utils.js
--- a/lib/shared/entry-utils.js
+++ b/lib/shared/entry-utils.js
@@ -1,21 +1,21 @@
// @flow
import invariant from 'invariant';
-import _isEqual from 'lodash/fp/isEqual';
+import _isEqual from 'lodash/fp/isEqual.js';
import {
filteredThreadIDs,
nonThreadCalendarFilters,
filterExists,
-} from '../selectors/calendar-filter-selectors';
+} from '../selectors/calendar-filter-selectors.js';
import type {
RawEntryInfo,
EntryInfo,
CalendarQuery,
-} from '../types/entry-types';
-import { calendarThreadFilterTypes } from '../types/filter-types';
-import type { UserInfos } from '../types/user-types';
-import { dateString, getDate, dateFromString } from '../utils/date-utils';
+} from '../types/entry-types.js';
+import { calendarThreadFilterTypes } from '../types/filter-types.js';
+import type { UserInfos } from '../types/user-types.js';
+import { dateString, getDate, dateFromString } from '../utils/date-utils.js';
type HasEntryIDs = { localID?: string, id?: string, ... };
function entryKey(entryInfo: HasEntryIDs): string {
diff --git a/lib/shared/markdown.js b/lib/shared/markdown.js
--- a/lib/shared/markdown.js
+++ b/lib/shared/markdown.js
@@ -2,8 +2,8 @@
import invariant from 'invariant';
-import type { RelativeMemberInfo } from '../types/thread-types';
-import { oldValidUsernameRegexString } from './account-utils';
+import type { RelativeMemberInfo } from '../types/thread-types.js';
+import { oldValidUsernameRegexString } from './account-utils.js';
// simple-markdown types
export type State = {
diff --git a/lib/shared/message-utils.js b/lib/shared/message-utils.js
--- a/lib/shared/message-utils.js
+++ b/lib/shared/message-utils.js
@@ -1,14 +1,14 @@
// @flow
import invariant from 'invariant';
-import _maxBy from 'lodash/fp/maxBy';
-import _orderBy from 'lodash/fp/orderBy';
+import _maxBy from 'lodash/fp/maxBy.js';
+import _orderBy from 'lodash/fp/orderBy.js';
import * as React from 'react';
-import { useStringForUser } from '../hooks/ens-cache';
-import { userIDsToRelativeUserInfos } from '../selectors/user-selectors';
-import type { PlatformDetails } from '../types/device-types';
-import type { Media } from '../types/media-types';
+import { useStringForUser } from '../hooks/ens-cache.js';
+import { userIDsToRelativeUserInfos } from '../selectors/user-selectors.js';
+import type { PlatformDetails } from '../types/device-types.js';
+import type { Media } from '../types/media-types.js';
import {
type MessageInfo,
type RawMessageInfo,
@@ -23,19 +23,22 @@
messageTruncationStatus,
type RawComposableMessageInfo,
type ThreadMessageInfo,
-} from '../types/message-types';
-import type { ImagesMessageData } from '../types/messages/images';
-import type { MediaMessageData } from '../types/messages/media';
+} from '../types/message-types.js';
+import type { ImagesMessageData } from '../types/messages/images.js';
+import type { MediaMessageData } from '../types/messages/media.js';
import type {
RawReactionMessageInfo,
ReactionMessageInfo,
-} from '../types/messages/reaction';
-import { type ThreadInfo } from '../types/thread-types';
-import type { UserInfos } from '../types/user-types';
-import { type EntityText, useEntityTextAsString } from '../utils/entity-text';
-import { codeBlockRegex, type ParserRules } from './markdown';
-import { messageSpecs } from './messages/message-specs';
-import { threadIsGroupChat } from './thread-utils';
+} from '../types/messages/reaction.js';
+import { type ThreadInfo } from '../types/thread-types.js';
+import type { UserInfos } from '../types/user-types.js';
+import {
+ type EntityText,
+ useEntityTextAsString,
+} from '../utils/entity-text.js';
+import { codeBlockRegex, type ParserRules } from './markdown.js';
+import { messageSpecs } from './messages/message-specs.js';
+import { threadIsGroupChat } from './thread-utils.js';
const localIDPrefix = 'local';
diff --git a/lib/shared/messages/add-members-message-spec.js b/lib/shared/messages/add-members-message-spec.js
--- a/lib/shared/messages/add-members-message-spec.js
+++ b/lib/shared/messages/add-members-message-spec.js
@@ -2,28 +2,28 @@
import invariant from 'invariant';
-import { messageTypes } from '../../types/message-types';
+import { messageTypes } from '../../types/message-types.js';
import type {
MessageInfo,
ClientDBMessageInfo,
-} from '../../types/message-types';
+} from '../../types/message-types.js';
import type {
AddMembersMessageData,
AddMembersMessageInfo,
RawAddMembersMessageInfo,
-} from '../../types/messages/add-members';
-import type { NotifTexts } from '../../types/notif-types';
-import type { ThreadInfo } from '../../types/thread-types';
-import type { RelativeUserInfo } from '../../types/user-types';
+} from '../../types/messages/add-members.js';
+import type { NotifTexts } from '../../types/notif-types.js';
+import type { ThreadInfo } from '../../types/thread-types.js';
+import type { RelativeUserInfo } from '../../types/user-types.js';
import {
ET,
type EntityText,
pluralizeEntityText,
-} from '../../utils/entity-text';
-import { values } from '../../utils/objects';
-import { notifRobotextForMessageInfo } from '../notif-utils';
-import type { CreateMessageInfoParams, MessageSpec } from './message-spec';
-import { joinResult } from './utils';
+} from '../../utils/entity-text.js';
+import { values } from '../../utils/objects.js';
+import { notifRobotextForMessageInfo } from '../notif-utils.js';
+import type { CreateMessageInfoParams, MessageSpec } from './message-spec.js';
+import { joinResult } from './utils.js';
export const addMembersMessageSpec: MessageSpec<
AddMembersMessageData,
diff --git a/lib/shared/messages/change-role-message-spec.js b/lib/shared/messages/change-role-message-spec.js
--- a/lib/shared/messages/change-role-message-spec.js
+++ b/lib/shared/messages/change-role-message-spec.js
@@ -2,33 +2,33 @@
import invariant from 'invariant';
-import { messageTypes } from '../../types/message-types';
+import { messageTypes } from '../../types/message-types.js';
import type {
MessageInfo,
ClientDBMessageInfo,
-} from '../../types/message-types';
+} from '../../types/message-types.js';
import type {
ChangeRoleMessageData,
ChangeRoleMessageInfo,
RawChangeRoleMessageInfo,
-} from '../../types/messages/change-role';
-import type { NotifTexts } from '../../types/notif-types';
-import type { ThreadInfo } from '../../types/thread-types';
-import type { RelativeUserInfo } from '../../types/user-types';
+} from '../../types/messages/change-role.js';
+import type { NotifTexts } from '../../types/notif-types.js';
+import type { ThreadInfo } from '../../types/thread-types.js';
+import type { RelativeUserInfo } from '../../types/user-types.js';
import {
ET,
type EntityText,
pluralizeEntityText,
-} from '../../utils/entity-text';
-import { values } from '../../utils/objects';
-import { notifRobotextForMessageInfo } from '../notif-utils';
+} from '../../utils/entity-text.js';
+import { values } from '../../utils/objects.js';
+import { notifRobotextForMessageInfo } from '../notif-utils.js';
import {
pushTypes,
type CreateMessageInfoParams,
type MessageSpec,
type RobotextParams,
-} from './message-spec';
-import { joinResult } from './utils';
+} from './message-spec.js';
+import { joinResult } from './utils.js';
export const changeRoleMessageSpec: MessageSpec<
ChangeRoleMessageData,
diff --git a/lib/shared/messages/change-settings-message-spec.js b/lib/shared/messages/change-settings-message-spec.js
--- a/lib/shared/messages/change-settings-message-spec.js
+++ b/lib/shared/messages/change-settings-message-spec.js
@@ -2,26 +2,26 @@
import invariant from 'invariant';
-import { messageTypes } from '../../types/message-types';
+import { messageTypes } from '../../types/message-types.js';
import type {
MessageInfo,
ClientDBMessageInfo,
-} from '../../types/message-types';
+} from '../../types/message-types.js';
import type {
ChangeSettingsMessageData,
ChangeSettingsMessageInfo,
RawChangeSettingsMessageInfo,
-} from '../../types/messages/change-settings';
-import type { NotifTexts } from '../../types/notif-types';
-import { assertThreadType } from '../../types/thread-types';
-import type { ThreadInfo } from '../../types/thread-types';
-import type { RelativeUserInfo } from '../../types/user-types';
-import { ET, type EntityText } from '../../utils/entity-text';
-import { validHexColorRegex } from '../account-utils';
-import { notifRobotextForMessageInfo } from '../notif-utils';
-import { threadLabel } from '../thread-utils';
-import { pushTypes, type MessageSpec } from './message-spec';
-import { joinResult } from './utils';
+} from '../../types/messages/change-settings.js';
+import type { NotifTexts } from '../../types/notif-types.js';
+import { assertThreadType } from '../../types/thread-types.js';
+import type { ThreadInfo } from '../../types/thread-types.js';
+import type { RelativeUserInfo } from '../../types/user-types.js';
+import { ET, type EntityText } from '../../utils/entity-text.js';
+import { validHexColorRegex } from '../account-utils.js';
+import { notifRobotextForMessageInfo } from '../notif-utils.js';
+import { threadLabel } from '../thread-utils.js';
+import { pushTypes, type MessageSpec } from './message-spec.js';
+import { joinResult } from './utils.js';
export const changeSettingsMessageSpec: MessageSpec<
ChangeSettingsMessageData,
diff --git a/lib/shared/messages/create-entry-message-spec.js b/lib/shared/messages/create-entry-message-spec.js
--- a/lib/shared/messages/create-entry-message-spec.js
+++ b/lib/shared/messages/create-entry-message-spec.js
@@ -2,24 +2,24 @@
import invariant from 'invariant';
-import { messageTypes } from '../../types/message-types';
+import { messageTypes } from '../../types/message-types.js';
import type {
MessageInfo,
ClientDBMessageInfo,
-} from '../../types/message-types';
+} from '../../types/message-types.js';
import type {
CreateEntryMessageData,
CreateEntryMessageInfo,
RawCreateEntryMessageInfo,
-} from '../../types/messages/create-entry';
-import type { NotifTexts } from '../../types/notif-types';
-import type { ThreadInfo } from '../../types/thread-types';
-import type { RelativeUserInfo } from '../../types/user-types';
-import { prettyDate } from '../../utils/date-utils';
-import { ET, type EntityText } from '../../utils/entity-text';
-import { notifTextsForEntryCreationOrEdit } from '../notif-utils';
-import { pushTypes, type MessageSpec } from './message-spec';
-import { joinResult } from './utils';
+} from '../../types/messages/create-entry.js';
+import type { NotifTexts } from '../../types/notif-types.js';
+import type { ThreadInfo } from '../../types/thread-types.js';
+import type { RelativeUserInfo } from '../../types/user-types.js';
+import { prettyDate } from '../../utils/date-utils.js';
+import { ET, type EntityText } from '../../utils/entity-text.js';
+import { notifTextsForEntryCreationOrEdit } from '../notif-utils.js';
+import { pushTypes, type MessageSpec } from './message-spec.js';
+import { joinResult } from './utils.js';
export const createEntryMessageSpec: MessageSpec<
CreateEntryMessageData,
diff --git a/lib/shared/messages/create-sidebar-message-spec.js b/lib/shared/messages/create-sidebar-message-spec.js
--- a/lib/shared/messages/create-sidebar-message-spec.js
+++ b/lib/shared/messages/create-sidebar-message-spec.js
@@ -2,33 +2,33 @@
import invariant from 'invariant';
-import type { PlatformDetails } from '../../types/device-types';
-import { messageTypes } from '../../types/message-types';
+import type { PlatformDetails } from '../../types/device-types.js';
+import { messageTypes } from '../../types/message-types.js';
import type {
MessageInfo,
ClientDBMessageInfo,
-} from '../../types/message-types';
+} from '../../types/message-types.js';
import type {
CreateSidebarMessageData,
CreateSidebarMessageInfo,
RawCreateSidebarMessageInfo,
-} from '../../types/messages/create-sidebar';
-import type { RawUnsupportedMessageInfo } from '../../types/messages/unsupported';
-import type { NotifTexts } from '../../types/notif-types';
-import type { ThreadInfo } from '../../types/thread-types';
-import type { RelativeUserInfo } from '../../types/user-types';
+} from '../../types/messages/create-sidebar.js';
+import type { RawUnsupportedMessageInfo } from '../../types/messages/unsupported.js';
+import type { NotifTexts } from '../../types/notif-types.js';
+import type { ThreadInfo } from '../../types/thread-types.js';
+import type { RelativeUserInfo } from '../../types/user-types.js';
import {
ET,
type EntityText,
pluralizeEntityText,
-} from '../../utils/entity-text';
-import { hasMinCodeVersion } from '../version-utils';
+} from '../../utils/entity-text.js';
+import { hasMinCodeVersion } from '../version-utils.js';
import {
pushTypes,
type CreateMessageInfoParams,
type MessageSpec,
-} from './message-spec';
-import { assertSingleMessageInfo } from './utils';
+} from './message-spec.js';
+import { assertSingleMessageInfo } from './utils.js';
export const createSidebarMessageSpec: MessageSpec<
CreateSidebarMessageData,
diff --git a/lib/shared/messages/create-sub-thread-message-spec.js b/lib/shared/messages/create-sub-thread-message-spec.js
--- a/lib/shared/messages/create-sub-thread-message-spec.js
+++ b/lib/shared/messages/create-sub-thread-message-spec.js
@@ -2,30 +2,30 @@
import invariant from 'invariant';
-import { permissionLookup } from '../../permissions/thread-permissions';
-import { messageTypes } from '../../types/message-types';
+import { permissionLookup } from '../../permissions/thread-permissions.js';
+import { messageTypes } from '../../types/message-types.js';
import type {
MessageInfo,
ClientDBMessageInfo,
-} from '../../types/message-types';
+} from '../../types/message-types.js';
import type {
CreateSubthreadMessageData,
CreateSubthreadMessageInfo,
RawCreateSubthreadMessageInfo,
-} from '../../types/messages/create-subthread';
-import type { NotifTexts } from '../../types/notif-types';
-import { threadPermissions, threadTypes } from '../../types/thread-types';
-import type { ThreadInfo } from '../../types/thread-types';
-import type { RelativeUserInfo } from '../../types/user-types';
-import { ET, type EntityText } from '../../utils/entity-text';
-import { notifTextsForSubthreadCreation } from '../notif-utils';
+} from '../../types/messages/create-subthread.js';
+import type { NotifTexts } from '../../types/notif-types.js';
+import { threadPermissions, threadTypes } from '../../types/thread-types.js';
+import type { ThreadInfo } from '../../types/thread-types.js';
+import type { RelativeUserInfo } from '../../types/user-types.js';
+import { ET, type EntityText } from '../../utils/entity-text.js';
+import { notifTextsForSubthreadCreation } from '../notif-utils.js';
import {
pushTypes,
type CreateMessageInfoParams,
type MessageSpec,
type GeneratesNotifsParams,
-} from './message-spec';
-import { assertSingleMessageInfo } from './utils';
+} from './message-spec.js';
+import { assertSingleMessageInfo } from './utils.js';
export const createSubThreadMessageSpec: MessageSpec<
CreateSubthreadMessageData,
diff --git a/lib/shared/messages/create-thread-message-spec.js b/lib/shared/messages/create-thread-message-spec.js
--- a/lib/shared/messages/create-thread-message-spec.js
+++ b/lib/shared/messages/create-thread-message-spec.js
@@ -2,32 +2,32 @@
import invariant from 'invariant';
-import { messageTypes } from '../../types/message-types';
+import { messageTypes } from '../../types/message-types.js';
import type {
MessageInfo,
ClientDBMessageInfo,
-} from '../../types/message-types';
+} from '../../types/message-types.js';
import type {
CreateThreadMessageData,
CreateThreadMessageInfo,
RawCreateThreadMessageInfo,
-} from '../../types/messages/create-thread';
-import type { NotifTexts } from '../../types/notif-types';
-import type { ThreadInfo } from '../../types/thread-types';
-import type { RelativeUserInfo } from '../../types/user-types';
+} from '../../types/messages/create-thread.js';
+import type { NotifTexts } from '../../types/notif-types.js';
+import type { ThreadInfo } from '../../types/thread-types.js';
+import type { RelativeUserInfo } from '../../types/user-types.js';
import {
ET,
type EntityText,
pluralizeEntityText,
-} from '../../utils/entity-text';
-import { notifTextsForSubthreadCreation } from '../notif-utils';
-import { threadNoun } from '../thread-utils';
+} from '../../utils/entity-text.js';
+import { notifTextsForSubthreadCreation } from '../notif-utils.js';
+import { threadNoun } from '../thread-utils.js';
import {
pushTypes,
type CreateMessageInfoParams,
type MessageSpec,
-} from './message-spec';
-import { assertSingleMessageInfo } from './utils';
+} from './message-spec.js';
+import { assertSingleMessageInfo } from './utils.js';
export const createThreadMessageSpec: MessageSpec<
CreateThreadMessageData,
diff --git a/lib/shared/messages/delete-entry-message-spec.js b/lib/shared/messages/delete-entry-message-spec.js
--- a/lib/shared/messages/delete-entry-message-spec.js
+++ b/lib/shared/messages/delete-entry-message-spec.js
@@ -2,23 +2,23 @@
import invariant from 'invariant';
-import { messageTypes } from '../../types/message-types';
+import { messageTypes } from '../../types/message-types.js';
import type {
MessageInfo,
ClientDBMessageInfo,
-} from '../../types/message-types';
+} from '../../types/message-types.js';
import type {
DeleteEntryMessageData,
DeleteEntryMessageInfo,
RawDeleteEntryMessageInfo,
-} from '../../types/messages/delete-entry';
-import type { NotifTexts } from '../../types/notif-types';
-import type { ThreadInfo } from '../../types/thread-types';
-import type { RelativeUserInfo } from '../../types/user-types';
-import { prettyDate } from '../../utils/date-utils';
-import { ET, type EntityText } from '../../utils/entity-text';
-import { pushTypes, type MessageSpec } from './message-spec';
-import { assertSingleMessageInfo } from './utils';
+} from '../../types/messages/delete-entry.js';
+import type { NotifTexts } from '../../types/notif-types.js';
+import type { ThreadInfo } from '../../types/thread-types.js';
+import type { RelativeUserInfo } from '../../types/user-types.js';
+import { prettyDate } from '../../utils/date-utils.js';
+import { ET, type EntityText } from '../../utils/entity-text.js';
+import { pushTypes, type MessageSpec } from './message-spec.js';
+import { assertSingleMessageInfo } from './utils.js';
export const deleteEntryMessageSpec: MessageSpec<
DeleteEntryMessageData,
diff --git a/lib/shared/messages/edit-entry-message-spec.js b/lib/shared/messages/edit-entry-message-spec.js
--- a/lib/shared/messages/edit-entry-message-spec.js
+++ b/lib/shared/messages/edit-entry-message-spec.js
@@ -2,24 +2,24 @@
import invariant from 'invariant';
-import { messageTypes } from '../../types/message-types';
+import { messageTypes } from '../../types/message-types.js';
import type {
MessageInfo,
ClientDBMessageInfo,
-} from '../../types/message-types';
+} from '../../types/message-types.js';
import type {
EditEntryMessageData,
EditEntryMessageInfo,
RawEditEntryMessageInfo,
-} from '../../types/messages/edit-entry';
-import type { NotifTexts } from '../../types/notif-types';
-import type { ThreadInfo } from '../../types/thread-types';
-import type { RelativeUserInfo } from '../../types/user-types';
-import { prettyDate } from '../../utils/date-utils';
-import { ET, type EntityText } from '../../utils/entity-text';
-import { notifTextsForEntryCreationOrEdit } from '../notif-utils';
-import { pushTypes, type MessageSpec } from './message-spec';
-import { joinResult } from './utils';
+} from '../../types/messages/edit-entry.js';
+import type { NotifTexts } from '../../types/notif-types.js';
+import type { ThreadInfo } from '../../types/thread-types.js';
+import type { RelativeUserInfo } from '../../types/user-types.js';
+import { prettyDate } from '../../utils/date-utils.js';
+import { ET, type EntityText } from '../../utils/entity-text.js';
+import { notifTextsForEntryCreationOrEdit } from '../notif-utils.js';
+import { pushTypes, type MessageSpec } from './message-spec.js';
+import { joinResult } from './utils.js';
export const editEntryMessageSpec: MessageSpec<
EditEntryMessageData,
diff --git a/lib/shared/messages/join-thread-message-spec.js b/lib/shared/messages/join-thread-message-spec.js
--- a/lib/shared/messages/join-thread-message-spec.js
+++ b/lib/shared/messages/join-thread-message-spec.js
@@ -2,27 +2,27 @@
import invariant from 'invariant';
-import { messageTypes } from '../../types/message-types';
+import { messageTypes } from '../../types/message-types.js';
import type {
MessageInfo,
ClientDBMessageInfo,
-} from '../../types/message-types';
+} from '../../types/message-types.js';
import type {
JoinThreadMessageData,
JoinThreadMessageInfo,
RawJoinThreadMessageInfo,
-} from '../../types/messages/join-thread';
-import type { NotifTexts } from '../../types/notif-types';
-import type { ThreadInfo } from '../../types/thread-types';
-import type { RelativeUserInfo } from '../../types/user-types';
+} from '../../types/messages/join-thread.js';
+import type { NotifTexts } from '../../types/notif-types.js';
+import type { ThreadInfo } from '../../types/thread-types.js';
+import type { RelativeUserInfo } from '../../types/user-types.js';
import {
ET,
type EntityText,
pluralizeEntityText,
-} from '../../utils/entity-text';
-import { values } from '../../utils/objects';
-import type { MessageSpec } from './message-spec';
-import { joinResult } from './utils';
+} from '../../utils/entity-text.js';
+import { values } from '../../utils/objects.js';
+import type { MessageSpec } from './message-spec.js';
+import { joinResult } from './utils.js';
export const joinThreadMessageSpec: MessageSpec<
JoinThreadMessageData,
diff --git a/lib/shared/messages/leave-thread-message-spec.js b/lib/shared/messages/leave-thread-message-spec.js
--- a/lib/shared/messages/leave-thread-message-spec.js
+++ b/lib/shared/messages/leave-thread-message-spec.js
@@ -2,27 +2,27 @@
import invariant from 'invariant';
-import { messageTypes } from '../../types/message-types';
+import { messageTypes } from '../../types/message-types.js';
import type {
MessageInfo,
ClientDBMessageInfo,
-} from '../../types/message-types';
+} from '../../types/message-types.js';
import type {
LeaveThreadMessageData,
LeaveThreadMessageInfo,
RawLeaveThreadMessageInfo,
-} from '../../types/messages/leave-thread';
-import type { NotifTexts } from '../../types/notif-types';
-import type { ThreadInfo } from '../../types/thread-types';
-import type { RelativeUserInfo } from '../../types/user-types';
+} from '../../types/messages/leave-thread.js';
+import type { NotifTexts } from '../../types/notif-types.js';
+import type { ThreadInfo } from '../../types/thread-types.js';
+import type { RelativeUserInfo } from '../../types/user-types.js';
import {
ET,
type EntityText,
pluralizeEntityText,
-} from '../../utils/entity-text';
-import { values } from '../../utils/objects';
-import type { MessageSpec } from './message-spec';
-import { joinResult } from './utils';
+} from '../../utils/entity-text.js';
+import { values } from '../../utils/objects.js';
+import type { MessageSpec } from './message-spec.js';
+import { joinResult } from './utils.js';
export const leaveThreadMessageSpec: MessageSpec<
LeaveThreadMessageData,
diff --git a/lib/shared/messages/message-spec.js b/lib/shared/messages/message-spec.js
--- a/lib/shared/messages/message-spec.js
+++ b/lib/shared/messages/message-spec.js
@@ -1,20 +1,20 @@
// @flow
-import type { PlatformDetails } from '../../types/device-types';
-import type { Media } from '../../types/media-types';
+import type { PlatformDetails } from '../../types/device-types.js';
+import type { Media } from '../../types/media-types.js';
import type {
MessageInfo,
ClientDBMessageInfo,
RawComposableMessageInfo,
RawMessageInfo,
RawRobotextMessageInfo,
-} from '../../types/message-types';
-import type { RawUnsupportedMessageInfo } from '../../types/messages/unsupported';
-import type { NotifTexts } from '../../types/notif-types';
-import type { ThreadInfo } from '../../types/thread-types';
-import type { RelativeUserInfo } from '../../types/user-types';
-import type { EntityText } from '../../utils/entity-text';
-import { type ParserRules } from '../markdown';
+} from '../../types/message-types.js';
+import type { RawUnsupportedMessageInfo } from '../../types/messages/unsupported.js';
+import type { NotifTexts } from '../../types/notif-types.js';
+import type { ThreadInfo } from '../../types/thread-types.js';
+import type { RelativeUserInfo } from '../../types/user-types.js';
+import type { EntityText } from '../../utils/entity-text.js';
+import { type ParserRules } from '../markdown.js';
export type MessageTitleParam<Info> = {
+messageInfo: Info,
diff --git a/lib/shared/messages/message-specs.js b/lib/shared/messages/message-specs.js
--- a/lib/shared/messages/message-specs.js
+++ b/lib/shared/messages/message-specs.js
@@ -1,26 +1,26 @@
// @flow
-import { messageTypes, type MessageType } from '../../types/message-types';
-import { addMembersMessageSpec } from './add-members-message-spec';
-import { changeRoleMessageSpec } from './change-role-message-spec';
-import { changeSettingsMessageSpec } from './change-settings-message-spec';
-import { createEntryMessageSpec } from './create-entry-message-spec';
-import { createSidebarMessageSpec } from './create-sidebar-message-spec';
-import { createSubThreadMessageSpec } from './create-sub-thread-message-spec';
-import { createThreadMessageSpec } from './create-thread-message-spec';
-import { deleteEntryMessageSpec } from './delete-entry-message-spec';
-import { editEntryMessageSpec } from './edit-entry-message-spec';
-import { joinThreadMessageSpec } from './join-thread-message-spec';
-import { leaveThreadMessageSpec } from './leave-thread-message-spec';
-import { type MessageSpec } from './message-spec';
-import { multimediaMessageSpec } from './multimedia-message-spec';
-import { reactionMessageSpec } from './reaction-message-spec';
-import { removeMembersMessageSpec } from './remove-members-message-spec';
-import { restoreEntryMessageSpec } from './restore-entry-message-spec';
-import { sidebarSourceMessageSpec } from './sidebar-source-message-spec';
-import { textMessageSpec } from './text-message-spec';
-import { unsupportedMessageSpec } from './unsupported-message-spec';
-import { updateRelationshipMessageSpec } from './update-relationship-message-spec';
+import { messageTypes, type MessageType } from '../../types/message-types.js';
+import { addMembersMessageSpec } from './add-members-message-spec.js';
+import { changeRoleMessageSpec } from './change-role-message-spec.js';
+import { changeSettingsMessageSpec } from './change-settings-message-spec.js';
+import { createEntryMessageSpec } from './create-entry-message-spec.js';
+import { createSidebarMessageSpec } from './create-sidebar-message-spec.js';
+import { createSubThreadMessageSpec } from './create-sub-thread-message-spec.js';
+import { createThreadMessageSpec } from './create-thread-message-spec.js';
+import { deleteEntryMessageSpec } from './delete-entry-message-spec.js';
+import { editEntryMessageSpec } from './edit-entry-message-spec.js';
+import { joinThreadMessageSpec } from './join-thread-message-spec.js';
+import { leaveThreadMessageSpec } from './leave-thread-message-spec.js';
+import { type MessageSpec } from './message-spec.js';
+import { multimediaMessageSpec } from './multimedia-message-spec.js';
+import { reactionMessageSpec } from './reaction-message-spec.js';
+import { removeMembersMessageSpec } from './remove-members-message-spec.js';
+import { restoreEntryMessageSpec } from './restore-entry-message-spec.js';
+import { sidebarSourceMessageSpec } from './sidebar-source-message-spec.js';
+import { textMessageSpec } from './text-message-spec.js';
+import { unsupportedMessageSpec } from './unsupported-message-spec.js';
+import { updateRelationshipMessageSpec } from './update-relationship-message-spec.js';
export const messageSpecs: {
[MessageType]: MessageSpec<*, *, *>,
diff --git a/lib/shared/messages/multimedia-message-spec.js b/lib/shared/messages/multimedia-message-spec.js
--- a/lib/shared/messages/multimedia-message-spec.js
+++ b/lib/shared/messages/multimedia-message-spec.js
@@ -6,50 +6,50 @@
contentStringForMediaArray,
multimediaMessagePreview,
shimUploadURI,
-} from '../../media/media-utils';
-import type { PlatformDetails } from '../../types/device-types';
-import type { Media, Video, Image } from '../../types/media-types';
+} from '../../media/media-utils.js';
+import type { PlatformDetails } from '../../types/device-types.js';
+import type { Media, Video, Image } from '../../types/media-types.js';
import {
messageTypes,
assertMessageType,
isMediaMessageType,
-} from '../../types/message-types';
+} from '../../types/message-types.js';
import type {
MessageInfo,
RawMessageInfo,
RawMultimediaMessageInfo,
ClientDBMessageInfo,
-} from '../../types/message-types';
+} from '../../types/message-types.js';
import type {
ImagesMessageData,
RawImagesMessageInfo,
ImagesMessageInfo,
-} from '../../types/messages/images';
+} from '../../types/messages/images.js';
import type {
MediaMessageData,
MediaMessageInfo,
RawMediaMessageInfo,
-} from '../../types/messages/media';
-import { getMediaMessageServerDBContentsFromMedia } from '../../types/messages/media';
-import type { RawUnsupportedMessageInfo } from '../../types/messages/unsupported';
-import type { NotifTexts } from '../../types/notif-types';
-import type { ThreadInfo } from '../../types/thread-types';
-import type { RelativeUserInfo } from '../../types/user-types';
-import { ET } from '../../utils/entity-text';
+} from '../../types/messages/media.js';
+import { getMediaMessageServerDBContentsFromMedia } from '../../types/messages/media.js';
+import type { RawUnsupportedMessageInfo } from '../../types/messages/unsupported.js';
+import type { NotifTexts } from '../../types/notif-types.js';
+import type { ThreadInfo } from '../../types/thread-types.js';
+import type { RelativeUserInfo } from '../../types/user-types.js';
+import { ET } from '../../utils/entity-text.js';
import {
translateClientDBMediaInfosToMedia,
translateClientDBMediaInfoToImage,
-} from '../../utils/message-ops-utils';
-import { createMediaMessageInfo } from '../message-utils';
-import { threadIsGroupChat } from '../thread-utils';
-import { hasMinCodeVersion } from '../version-utils';
+} from '../../utils/message-ops-utils.js';
+import { createMediaMessageInfo } from '../message-utils.js';
+import { threadIsGroupChat } from '../thread-utils.js';
+import { hasMinCodeVersion } from '../version-utils.js';
import {
pushTypes,
type MessageSpec,
type MessageTitleParam,
type RawMessageInfoFromServerDBRowParams,
-} from './message-spec';
-import { joinResult } from './utils';
+} from './message-spec.js';
+import { joinResult } from './utils.js';
export const multimediaMessageSpec: MessageSpec<
MediaMessageData | ImagesMessageData,
diff --git a/lib/shared/messages/reaction-message-spec.js b/lib/shared/messages/reaction-message-spec.js
--- a/lib/shared/messages/reaction-message-spec.js
+++ b/lib/shared/messages/reaction-message-spec.js
@@ -2,32 +2,32 @@
import invariant from 'invariant';
-import type { PlatformDetails } from '../../types/device-types';
+import type { PlatformDetails } from '../../types/device-types.js';
import {
assertMessageType,
messageTypes,
type MessageInfo,
type ClientDBMessageInfo,
-} from '../../types/message-types';
+} from '../../types/message-types.js';
import type {
ReactionMessageData,
RawReactionMessageInfo,
ReactionMessageInfo,
-} from '../../types/messages/reaction';
-import type { RawUnsupportedMessageInfo } from '../../types/messages/unsupported';
-import type { NotifTexts } from '../../types/notif-types';
-import type { ThreadInfo } from '../../types/thread-types';
-import type { RelativeUserInfo } from '../../types/user-types';
-import { ET } from '../../utils/entity-text';
-import { threadIsGroupChat } from '../thread-utils';
-import { hasMinCodeVersion } from '../version-utils';
+} from '../../types/messages/reaction.js';
+import type { RawUnsupportedMessageInfo } from '../../types/messages/unsupported.js';
+import type { NotifTexts } from '../../types/notif-types.js';
+import type { ThreadInfo } from '../../types/thread-types.js';
+import type { RelativeUserInfo } from '../../types/user-types.js';
+import { ET } from '../../utils/entity-text.js';
+import { threadIsGroupChat } from '../thread-utils.js';
+import { hasMinCodeVersion } from '../version-utils.js';
import {
pushTypes,
type MessageSpec,
type MessageTitleParam,
type GeneratesNotifsParams,
-} from './message-spec';
-import { assertSingleMessageInfo, joinResult } from './utils';
+} from './message-spec.js';
+import { assertSingleMessageInfo, joinResult } from './utils.js';
export const reactionMessageSpec: MessageSpec<
ReactionMessageData,
diff --git a/lib/shared/messages/remove-members-message-spec.js b/lib/shared/messages/remove-members-message-spec.js
--- a/lib/shared/messages/remove-members-message-spec.js
+++ b/lib/shared/messages/remove-members-message-spec.js
@@ -2,28 +2,28 @@
import invariant from 'invariant';
-import { messageTypes } from '../../types/message-types';
+import { messageTypes } from '../../types/message-types.js';
import type {
MessageInfo,
ClientDBMessageInfo,
-} from '../../types/message-types';
+} from '../../types/message-types.js';
import type {
RawRemoveMembersMessageInfo,
RemoveMembersMessageData,
RemoveMembersMessageInfo,
-} from '../../types/messages/remove-members';
-import type { NotifTexts } from '../../types/notif-types';
-import type { ThreadInfo } from '../../types/thread-types';
-import type { RelativeUserInfo } from '../../types/user-types';
+} from '../../types/messages/remove-members.js';
+import type { NotifTexts } from '../../types/notif-types.js';
+import type { ThreadInfo } from '../../types/thread-types.js';
+import type { RelativeUserInfo } from '../../types/user-types.js';
import {
ET,
type EntityText,
pluralizeEntityText,
-} from '../../utils/entity-text';
-import { values } from '../../utils/objects';
-import { notifRobotextForMessageInfo } from '../notif-utils';
-import type { CreateMessageInfoParams, MessageSpec } from './message-spec';
-import { joinResult } from './utils';
+} from '../../utils/entity-text.js';
+import { values } from '../../utils/objects.js';
+import { notifRobotextForMessageInfo } from '../notif-utils.js';
+import type { CreateMessageInfoParams, MessageSpec } from './message-spec.js';
+import { joinResult } from './utils.js';
export const removeMembersMessageSpec: MessageSpec<
RemoveMembersMessageData,
diff --git a/lib/shared/messages/restore-entry-message-spec.js b/lib/shared/messages/restore-entry-message-spec.js
--- a/lib/shared/messages/restore-entry-message-spec.js
+++ b/lib/shared/messages/restore-entry-message-spec.js
@@ -2,23 +2,23 @@
import invariant from 'invariant';
-import { messageTypes } from '../../types/message-types';
+import { messageTypes } from '../../types/message-types.js';
import type {
MessageInfo,
ClientDBMessageInfo,
-} from '../../types/message-types';
+} from '../../types/message-types.js';
import type {
RawRestoreEntryMessageInfo,
RestoreEntryMessageData,
RestoreEntryMessageInfo,
-} from '../../types/messages/restore-entry';
-import type { NotifTexts } from '../../types/notif-types';
-import type { ThreadInfo } from '../../types/thread-types';
-import type { RelativeUserInfo } from '../../types/user-types';
-import { prettyDate } from '../../utils/date-utils';
-import { ET, type EntityText } from '../../utils/entity-text';
-import { pushTypes, type MessageSpec } from './message-spec';
-import { assertSingleMessageInfo } from './utils';
+} from '../../types/messages/restore-entry.js';
+import type { NotifTexts } from '../../types/notif-types.js';
+import type { ThreadInfo } from '../../types/thread-types.js';
+import type { RelativeUserInfo } from '../../types/user-types.js';
+import { prettyDate } from '../../utils/date-utils.js';
+import { ET, type EntityText } from '../../utils/entity-text.js';
+import { pushTypes, type MessageSpec } from './message-spec.js';
+import { assertSingleMessageInfo } from './utils.js';
export const restoreEntryMessageSpec: MessageSpec<
RestoreEntryMessageData,
diff --git a/lib/shared/messages/sidebar-source-message-spec.js b/lib/shared/messages/sidebar-source-message-spec.js
--- a/lib/shared/messages/sidebar-source-message-spec.js
+++ b/lib/shared/messages/sidebar-source-message-spec.js
@@ -2,27 +2,27 @@
import invariant from 'invariant';
-import type { PlatformDetails } from '../../types/device-types';
+import type { PlatformDetails } from '../../types/device-types.js';
import type {
MessageInfo,
RawSidebarSourceMessageInfo,
SidebarSourceMessageData,
SidebarSourceMessageInfo,
ClientDBMessageInfo,
-} from '../../types/message-types';
-import { messageTypes } from '../../types/message-types';
-import type { RawUnsupportedMessageInfo } from '../../types/messages/unsupported';
-import type { NotifTexts } from '../../types/notif-types';
-import type { ThreadInfo } from '../../types/thread-types';
-import type { RelativeUserInfo } from '../../types/user-types';
-import { hasMinCodeVersion } from '../version-utils';
+} from '../../types/message-types.js';
+import { messageTypes } from '../../types/message-types.js';
+import type { RawUnsupportedMessageInfo } from '../../types/messages/unsupported.js';
+import type { NotifTexts } from '../../types/notif-types.js';
+import type { ThreadInfo } from '../../types/thread-types.js';
+import type { RelativeUserInfo } from '../../types/user-types.js';
+import { hasMinCodeVersion } from '../version-utils.js';
import type {
CreateMessageInfoParams,
MessageSpec,
NotificationTextsParams,
RawMessageInfoFromServerDBRowParams,
-} from './message-spec';
-import { assertSingleMessageInfo } from './utils';
+} from './message-spec.js';
+import { assertSingleMessageInfo } from './utils.js';
export const sidebarSourceMessageSpec: MessageSpec<
SidebarSourceMessageData,
diff --git a/lib/shared/messages/text-message-spec.js b/lib/shared/messages/text-message-spec.js
--- a/lib/shared/messages/text-message-spec.js
+++ b/lib/shared/messages/text-message-spec.js
@@ -3,33 +3,33 @@
import invariant from 'invariant';
import * as SimpleMarkdown from 'simple-markdown';
-import { messageTypes } from '../../types/message-types';
+import { messageTypes } from '../../types/message-types.js';
import type {
MessageInfo,
ClientDBMessageInfo,
-} from '../../types/message-types';
+} from '../../types/message-types.js';
import type {
RawTextMessageInfo,
TextMessageData,
TextMessageInfo,
-} from '../../types/messages/text';
-import type { NotifTexts } from '../../types/notif-types';
-import type { ThreadInfo } from '../../types/thread-types';
-import type { RelativeUserInfo } from '../../types/user-types';
-import { ET } from '../../utils/entity-text';
+} from '../../types/messages/text.js';
+import type { NotifTexts } from '../../types/notif-types.js';
+import type { ThreadInfo } from '../../types/thread-types.js';
+import type { RelativeUserInfo } from '../../types/user-types.js';
+import { ET } from '../../utils/entity-text.js';
import {
type ASTNode,
type SingleASTNode,
stripSpoilersFromNotifications,
stripSpoilersFromMarkdownAST,
-} from '../markdown';
-import { threadIsGroupChat } from '../thread-utils';
+} from '../markdown.js';
+import { threadIsGroupChat } from '../thread-utils.js';
import {
pushTypes,
type MessageSpec,
type RawMessageInfoFromServerDBRowParams,
-} from './message-spec';
-import { assertSingleMessageInfo } from './utils';
+} from './message-spec.js';
+import { assertSingleMessageInfo } from './utils.js';
/**
* most of the markdown leaves contain `content` field
diff --git a/lib/shared/messages/unsupported-message-spec.js b/lib/shared/messages/unsupported-message-spec.js
--- a/lib/shared/messages/unsupported-message-spec.js
+++ b/lib/shared/messages/unsupported-message-spec.js
@@ -5,14 +5,14 @@
import {
messageTypes,
type ClientDBMessageInfo,
-} from '../../types/message-types';
+} from '../../types/message-types.js';
import type {
RawUnsupportedMessageInfo,
UnsupportedMessageInfo,
-} from '../../types/messages/unsupported';
-import type { RelativeUserInfo } from '../../types/user-types';
-import { ET, type EntityText } from '../../utils/entity-text';
-import { pushTypes, type MessageSpec } from './message-spec';
+} from '../../types/messages/unsupported.js';
+import type { RelativeUserInfo } from '../../types/user-types.js';
+import { ET, type EntityText } from '../../utils/entity-text.js';
+import { pushTypes, type MessageSpec } from './message-spec.js';
export const unsupportedMessageSpec: MessageSpec<
null,
diff --git a/lib/shared/messages/update-relationship-message-spec.js b/lib/shared/messages/update-relationship-message-spec.js
--- a/lib/shared/messages/update-relationship-message-spec.js
+++ b/lib/shared/messages/update-relationship-message-spec.js
@@ -2,29 +2,29 @@
import invariant from 'invariant';
-import type { PlatformDetails } from '../../types/device-types';
-import { messageTypes } from '../../types/message-types';
+import type { PlatformDetails } from '../../types/device-types.js';
+import { messageTypes } from '../../types/message-types.js';
import type {
MessageInfo,
ClientDBMessageInfo,
-} from '../../types/message-types';
-import type { RawUnsupportedMessageInfo } from '../../types/messages/unsupported';
+} from '../../types/message-types.js';
+import type { RawUnsupportedMessageInfo } from '../../types/messages/unsupported.js';
import type {
RawUpdateRelationshipMessageInfo,
UpdateRelationshipMessageData,
UpdateRelationshipMessageInfo,
-} from '../../types/messages/update-relationship';
-import type { NotifTexts } from '../../types/notif-types';
-import type { ThreadInfo } from '../../types/thread-types';
-import type { RelativeUserInfo } from '../../types/user-types';
-import { ET, type EntityText } from '../../utils/entity-text';
-import { hasMinCodeVersion } from '../version-utils';
+} from '../../types/messages/update-relationship.js';
+import type { NotifTexts } from '../../types/notif-types.js';
+import type { ThreadInfo } from '../../types/thread-types.js';
+import type { RelativeUserInfo } from '../../types/user-types.js';
+import { ET, type EntityText } from '../../utils/entity-text.js';
+import { hasMinCodeVersion } from '../version-utils.js';
import {
pushTypes,
type CreateMessageInfoParams,
type MessageSpec,
-} from './message-spec';
-import { assertSingleMessageInfo } from './utils';
+} from './message-spec.js';
+import { assertSingleMessageInfo } from './utils.js';
export const updateRelationshipMessageSpec: MessageSpec<
UpdateRelationshipMessageData,
diff --git a/lib/shared/messages/utils.js b/lib/shared/messages/utils.js
--- a/lib/shared/messages/utils.js
+++ b/lib/shared/messages/utils.js
@@ -1,6 +1,6 @@
// @flow
-import type { MessageInfo } from '../../types/message-types';
+import type { MessageInfo } from '../../types/message-types.js';
export function assertSingleMessageInfo(
messageInfos: $ReadOnlyArray<MessageInfo>,
diff --git a/lib/shared/notif-utils.js b/lib/shared/notif-utils.js
--- a/lib/shared/notif-utils.js
+++ b/lib/shared/notif-utils.js
@@ -8,24 +8,24 @@
type RobotextMessageInfo,
type MessageType,
messageTypes,
-} from '../types/message-types';
-import type { NotifTexts, ResolvedNotifTexts } from '../types/notif-types';
-import type { ThreadInfo, ThreadType } from '../types/thread-types';
-import type { RelativeUserInfo } from '../types/user-types';
-import { prettyDate } from '../utils/date-utils';
-import type { GetENSNames } from '../utils/ens-helpers';
+} from '../types/message-types.js';
+import type { NotifTexts, ResolvedNotifTexts } from '../types/notif-types.js';
+import type { ThreadInfo, ThreadType } from '../types/thread-types.js';
+import type { RelativeUserInfo } from '../types/user-types.js';
+import { prettyDate } from '../utils/date-utils.js';
+import type { GetENSNames } from '../utils/ens-helpers.js';
import {
ET,
getEntityTextAsString,
pluralizeEntityText,
type EntityText,
type UserEntity,
-} from '../utils/entity-text';
-import { promiseAll } from '../utils/promises';
-import { trimText } from '../utils/text-utils';
-import { robotextForMessageInfo } from './message-utils';
-import { messageSpecs } from './messages/message-specs';
-import { threadNoun } from './thread-utils';
+} from '../utils/entity-text.js';
+import { promiseAll } from '../utils/promises.js';
+import { trimText } from '../utils/text-utils.js';
+import { robotextForMessageInfo } from './message-utils.js';
+import { messageSpecs } from './messages/message-specs.js';
+import { threadNoun } from './thread-utils.js';
async function notifTextsForMessageInfo(
messageInfos: MessageInfo[],
diff --git a/lib/shared/reaction-utils.js b/lib/shared/reaction-utils.js
--- a/lib/shared/reaction-utils.js
+++ b/lib/shared/reaction-utils.js
@@ -1,20 +1,20 @@
// @flow
import invariant from 'invariant';
-import _sortBy from 'lodash/fp/sortBy';
+import _sortBy from 'lodash/fp/sortBy.js';
import * as React from 'react';
-import { useENSNames } from '../hooks/ens-cache';
-import type { MessageReactionInfo } from '../selectors/chat-selectors';
+import { useENSNames } from '../hooks/ens-cache.js';
+import type { MessageReactionInfo } from '../selectors/chat-selectors.js';
import type {
RobotextMessageInfo,
ComposableMessageInfo,
-} from '../types/message-types';
-import { threadPermissions, type ThreadInfo } from '../types/thread-types';
-import { useSelector } from '../utils/redux-utils';
-import { relationshipBlockedInEitherDirection } from './relationship-utils';
-import { threadHasPermission } from './thread-utils';
-import { stringForUserExplicit } from './user-utils';
+} from '../types/message-types.js';
+import { threadPermissions, type ThreadInfo } from '../types/thread-types.js';
+import { useSelector } from '../utils/redux-utils.js';
+import { relationshipBlockedInEitherDirection } from './relationship-utils.js';
+import { threadHasPermission } from './thread-utils.js';
+import { stringForUserExplicit } from './user-utils.js';
function stringForReactionList(
reactions: $ReadOnlyMap<string, MessageReactionInfo>,
diff --git a/lib/shared/reaction-utils.test.js b/lib/shared/reaction-utils.test.js
--- a/lib/shared/reaction-utils.test.js
+++ b/lib/shared/reaction-utils.test.js
@@ -1,7 +1,7 @@
// @flow
-import type { MessageReactionInfo } from '../selectors/chat-selectors';
-import { stringForReactionList } from './reaction-utils';
+import type { MessageReactionInfo } from '../selectors/chat-selectors.js';
+import { stringForReactionList } from './reaction-utils.js';
describe(
'stringForReactionList(' +
diff --git a/lib/shared/relationship-utils.js b/lib/shared/relationship-utils.js
--- a/lib/shared/relationship-utils.js
+++ b/lib/shared/relationship-utils.js
@@ -9,8 +9,8 @@
relationshipButtons,
relationshipActions,
type RelationshipAction,
-} from '../types/relationship-types';
-import type { UserInfo } from '../types/user-types';
+} from '../types/relationship-types.js';
+import type { UserInfo } from '../types/user-types.js';
function sortIDs(firstId: string, secondId: string): string[] {
return [Number(firstId), Number(secondId)]
diff --git a/lib/shared/report-utils.js b/lib/shared/report-utils.js
--- a/lib/shared/report-utils.js
+++ b/lib/shared/report-utils.js
@@ -5,11 +5,11 @@
import {
type ClientReportCreationRequest,
reportTypes,
-} from '../types/report-types';
+} from '../types/report-types.js';
import {
type ClientInconsistencyResponse,
serverRequestTypes,
-} from '../types/request-types';
+} from '../types/request-types.js';
function inconsistencyResponsesToReports(
responses: $ReadOnlyArray<ClientInconsistencyResponse>,
diff --git a/lib/shared/search-utils.js b/lib/shared/search-utils.js
--- a/lib/shared/search-utils.js
+++ b/lib/shared/search-utils.js
@@ -1,20 +1,20 @@
// @flow
-import genesis from '../facts/genesis';
-import { userRelationshipStatus } from '../types/relationship-types';
+import genesis from '../facts/genesis.js';
+import { userRelationshipStatus } from '../types/relationship-types.js';
import {
type ThreadInfo,
type ThreadType,
threadTypes,
threadPermissions,
-} from '../types/thread-types';
-import type { AccountUserInfo, UserListItem } from '../types/user-types';
-import SearchIndex from './search-index';
+} from '../types/thread-types.js';
+import type { AccountUserInfo, UserListItem } from '../types/user-types.js';
+import SearchIndex from './search-index.js';
import {
userIsMember,
threadMemberHasPermission,
getContainingThreadID,
-} from './thread-utils';
+} from './thread-utils.js';
const notFriendNotice = 'not friend';
diff --git a/lib/shared/thread-utils.js b/lib/shared/thread-utils.js
--- a/lib/shared/thread-utils.js
+++ b/lib/shared/thread-utils.js
@@ -1,7 +1,7 @@
// @flow
import invariant from 'invariant';
-import _find from 'lodash/fp/find';
+import _find from 'lodash/fp/find.js';
import * as React from 'react';
import stringHash from 'string-hash';
import tinycolor from 'tinycolor2';
@@ -9,39 +9,39 @@
import {
fetchMostRecentMessagesActionTypes,
fetchMostRecentMessages,
-} from '../actions/message-actions';
+} from '../actions/message-actions.js';
import {
changeThreadMemberRolesActionTypes,
newThreadActionTypes,
removeUsersFromThreadActionTypes,
-} from '../actions/thread-actions';
-import { searchUsers as searchUserCall } from '../actions/user-actions';
-import ashoat from '../facts/ashoat';
-import genesis from '../facts/genesis';
+} from '../actions/thread-actions.js';
+import { searchUsers as searchUserCall } from '../actions/user-actions.js';
+import ashoat from '../facts/ashoat.js';
+import genesis from '../facts/genesis.js';
import {
permissionLookup,
getAllThreadPermissions,
makePermissionsBlob,
-} from '../permissions/thread-permissions';
+} from '../permissions/thread-permissions.js';
import type {
ChatThreadItem,
ChatMessageInfoItem,
-} from '../selectors/chat-selectors';
-import { useGlobalThreadSearchIndex } from '../selectors/nav-selectors';
+} from '../selectors/chat-selectors.js';
+import { useGlobalThreadSearchIndex } from '../selectors/nav-selectors.js';
import {
threadInfoSelector,
pendingToRealizedThreadIDsSelector,
-} from '../selectors/thread-selectors';
+} from '../selectors/thread-selectors.js';
import {
getRelativeMemberInfos,
usersWithPersonalThreadSelector,
-} from '../selectors/user-selectors';
-import type { CalendarQuery } from '../types/entry-types';
+} from '../selectors/user-selectors.js';
+import type { CalendarQuery } from '../types/entry-types.js';
import type {
RobotextMessageInfo,
ComposableMessageInfo,
-} from '../types/message-types';
-import { userRelationshipStatus } from '../types/relationship-types';
+} from '../types/message-types.js';
+import { userRelationshipStatus } from '../types/relationship-types.js';
import {
type RawThreadInfo,
type ThreadInfo,
@@ -61,31 +61,34 @@
threadPermissions,
threadTypeIsCommunityRoot,
assertThreadType,
-} from '../types/thread-types';
-import { type ClientUpdateInfo, updateTypes } from '../types/update-types';
+} from '../types/thread-types.js';
+import { type ClientUpdateInfo, updateTypes } from '../types/update-types.js';
import type {
GlobalAccountUserInfo,
UserInfos,
UserInfo,
AccountUserInfo,
-} from '../types/user-types';
-import { useDispatchActionPromise, useServerCall } from '../utils/action-utils';
-import type { DispatchActionPromise } from '../utils/action-utils';
-import type { GetENSNames } from '../utils/ens-helpers';
+} from '../types/user-types.js';
+import {
+ useDispatchActionPromise,
+ useServerCall,
+} from '../utils/action-utils.js';
+import type { DispatchActionPromise } from '../utils/action-utils.js';
+import type { GetENSNames } from '../utils/ens-helpers.js';
import {
ET,
entityTextToRawString,
getEntityTextAsString,
type UserEntity,
-} from '../utils/entity-text';
-import { values } from '../utils/objects';
-import { useSelector } from '../utils/redux-utils';
-import { firstLine } from '../utils/string-utils';
-import { trimText } from '../utils/text-utils';
-import { type ParserRules } from './markdown';
-import { getMessageTitle } from './message-utils';
-import { relationshipBlockedInEitherDirection } from './relationship-utils';
-import threadWatcher from './thread-watcher';
+} from '../utils/entity-text.js';
+import { values } from '../utils/objects.js';
+import { useSelector } from '../utils/redux-utils.js';
+import { firstLine } from '../utils/string-utils.js';
+import { trimText } from '../utils/text-utils.js';
+import { type ParserRules } from './markdown.js';
+import { getMessageTitle } from './message-utils.js';
+import { relationshipBlockedInEitherDirection } from './relationship-utils.js';
+import threadWatcher from './thread-watcher.js';
function colorIsDark(color: string): boolean {
return tinycolor(`#${color}`).isDark();
diff --git a/lib/shared/thread-utils.test.js b/lib/shared/thread-utils.test.js
--- a/lib/shared/thread-utils.test.js
+++ b/lib/shared/thread-utils.test.js
@@ -1,7 +1,7 @@
// @flow
-import { threadTypes } from '../types/thread-types';
-import { parsePendingThreadID } from './thread-utils';
+import { threadTypes } from '../types/thread-types.js';
+import { parsePendingThreadID } from './thread-utils.js';
describe('parsePendingThreadID(pendingThreadID: string)', () => {
it('should return correct data for real pending sidebar ID', () => {
diff --git a/lib/shared/typeahead-utils.js b/lib/shared/typeahead-utils.js
--- a/lib/shared/typeahead-utils.js
+++ b/lib/shared/typeahead-utils.js
@@ -1,9 +1,9 @@
// @flow
-import type { RelativeMemberInfo } from '../types/thread-types';
-import SearchIndex from './search-index';
-import { threadOtherMembers } from './thread-utils';
-import { stringForUserExplicit } from './user-utils';
+import type { RelativeMemberInfo } from '../types/thread-types.js';
+import SearchIndex from './search-index.js';
+import { threadOtherMembers } from './thread-utils.js';
+import { stringForUserExplicit } from './user-utils.js';
export type TypeaheadMatchedStrings = {
+textBeforeAtSymbol: string,
diff --git a/lib/shared/unshim-utils.js b/lib/shared/unshim-utils.js
--- a/lib/shared/unshim-utils.js
+++ b/lib/shared/unshim-utils.js
@@ -1,14 +1,14 @@
// @flow
-import _mapValues from 'lodash/fp/mapValues';
+import _mapValues from 'lodash/fp/mapValues.js';
import {
type MessageStore,
type RawMessageInfo,
type MessageType,
messageTypes,
-} from '../types/message-types';
-import { messageSpecs } from './messages/message-specs';
+} from '../types/message-types.js';
+import { messageSpecs } from './messages/message-specs.js';
function unshimFunc(
messageInfo: RawMessageInfo,
diff --git a/lib/shared/update-utils.js b/lib/shared/update-utils.js
--- a/lib/shared/update-utils.js
+++ b/lib/shared/update-utils.js
@@ -1,14 +1,14 @@
// @flow
import invariant from 'invariant';
-import _maxBy from 'lodash/fp/maxBy';
+import _maxBy from 'lodash/fp/maxBy.js';
import {
type ServerUpdateInfo,
type UpdateData,
type RawUpdateInfo,
updateTypes,
-} from '../types/update-types';
+} from '../types/update-types.js';
function mostRecentUpdateTimestamp(
updateInfos: ServerUpdateInfo[],
diff --git a/lib/shared/user-utils.js b/lib/shared/user-utils.js
--- a/lib/shared/user-utils.js
+++ b/lib/shared/user-utils.js
@@ -1,16 +1,16 @@
// @flow
-import bots from '../facts/bots';
-import staff from '../facts/staff';
-import { useENSNames } from '../hooks/ens-cache';
+import bots from '../facts/bots.js';
+import staff from '../facts/staff.js';
+import { useENSNames } from '../hooks/ens-cache.js';
import type {
ServerThreadInfo,
RawThreadInfo,
ThreadInfo,
-} from '../types/thread-types';
-import type { UserInfo } from '../types/user-types';
-import { useSelector } from '../utils/redux-utils';
-import { memberHasAdminPowers } from './thread-utils';
+} from '../types/thread-types.js';
+import type { UserInfo } from '../types/user-types.js';
+import { useSelector } from '../utils/redux-utils.js';
+import { memberHasAdminPowers } from './thread-utils.js';
function stringForUser(user: {
+username?: ?string,
diff --git a/lib/shared/version-utils.js b/lib/shared/version-utils.js
--- a/lib/shared/version-utils.js
+++ b/lib/shared/version-utils.js
@@ -1,6 +1,6 @@
// @flow
-import type { PlatformDetails } from '../types/device-types';
+import type { PlatformDetails } from '../types/device-types.js';
function hasMinCodeVersion(
platformDetails: ?PlatformDetails,
diff --git a/lib/socket/activity-handler.react.js b/lib/socket/activity-handler.react.js
--- a/lib/socket/activity-handler.react.js
+++ b/lib/socket/activity-handler.react.js
@@ -6,11 +6,14 @@
import {
updateActivityActionTypes,
updateActivity,
-} from '../actions/activity-actions';
-import { getMostRecentNonLocalMessageID } from '../shared/message-utils';
-import { queueActivityUpdatesActionType } from '../types/activity-types';
-import { useServerCall, useDispatchActionPromise } from '../utils/action-utils';
-import { useSelector } from '../utils/redux-utils';
+} from '../actions/activity-actions.js';
+import { getMostRecentNonLocalMessageID } from '../shared/message-utils.js';
+import { queueActivityUpdatesActionType } from '../types/activity-types.js';
+import {
+ useServerCall,
+ useDispatchActionPromise,
+} from '../utils/action-utils.js';
+import { useSelector } from '../utils/redux-utils.js';
type Props = {
+activeThread: ?string,
diff --git a/lib/socket/api-request-handler.react.js b/lib/socket/api-request-handler.react.js
--- a/lib/socket/api-request-handler.react.js
+++ b/lib/socket/api-request-handler.react.js
@@ -3,16 +3,16 @@
import invariant from 'invariant';
import * as React from 'react';
-import type { APIRequest } from '../types/endpoints';
+import type { APIRequest } from '../types/endpoints.js';
import {
clientSocketMessageTypes,
serverSocketMessageTypes,
type ClientSocketMessageWithoutID,
type ConnectionInfo,
-} from '../types/socket-types';
-import { registerActiveSocket } from '../utils/action-utils';
-import { useSelector } from '../utils/redux-utils';
-import { InflightRequests, SocketOffline } from './inflight-requests';
+} from '../types/socket-types.js';
+import { registerActiveSocket } from '../utils/action-utils.js';
+import { useSelector } from '../utils/redux-utils.js';
+import { InflightRequests, SocketOffline } from './inflight-requests.js';
type BaseProps = {
+inflightRequests: ?InflightRequests,
diff --git a/lib/socket/calendar-query-handler.react.js b/lib/socket/calendar-query-handler.react.js
--- a/lib/socket/calendar-query-handler.react.js
+++ b/lib/socket/calendar-query-handler.react.js
@@ -1,26 +1,26 @@
// @flow
-import _isEqual from 'lodash/fp/isEqual';
+import _isEqual from 'lodash/fp/isEqual.js';
import * as React from 'react';
import {
updateCalendarQueryActionTypes,
updateCalendarQuery,
-} from '../actions/entry-actions';
-import { timeUntilCalendarRangeExpiration } from '../selectors/nav-selectors';
-import { useIsAppForegrounded } from '../shared/lifecycle-utils';
+} from '../actions/entry-actions.js';
+import { timeUntilCalendarRangeExpiration } from '../selectors/nav-selectors.js';
+import { useIsAppForegrounded } from '../shared/lifecycle-utils.js';
import type {
CalendarQuery,
CalendarQueryUpdateResult,
CalendarQueryUpdateStartingPayload,
-} from '../types/entry-types';
-import { type ConnectionInfo } from '../types/socket-types';
+} from '../types/entry-types.js';
+import { type ConnectionInfo } from '../types/socket-types.js';
import {
type DispatchActionPromise,
useDispatchActionPromise,
useServerCall,
-} from '../utils/action-utils';
-import { useSelector } from '../utils/redux-utils';
+} from '../utils/action-utils.js';
+import { useSelector } from '../utils/redux-utils.js';
type BaseProps = {
+currentCalendarQuery: () => CalendarQuery,
diff --git a/lib/socket/inflight-requests.js b/lib/socket/inflight-requests.js
--- a/lib/socket/inflight-requests.js
+++ b/lib/socket/inflight-requests.js
@@ -5,7 +5,7 @@
import {
clientRequestVisualTimeout,
clientRequestSocketTimeout,
-} from '../shared/timeouts';
+} from '../shared/timeouts.js';
import {
type ClientServerSocketMessage,
type ClientStateSyncServerSocketMessage,
@@ -15,9 +15,9 @@
type APIResponseServerSocketMessage,
type ServerSocketMessageType,
serverSocketMessageTypes,
-} from '../types/socket-types';
-import { ServerError, ExtendableError } from '../utils/errors';
-import sleep from '../utils/sleep';
+} from '../types/socket-types.js';
+import { ServerError, ExtendableError } from '../utils/errors.js';
+import sleep from '../utils/sleep.js';
type ValidResponseMessageMap = {
a: ClientStateSyncServerSocketMessage,
diff --git a/lib/socket/message-handler.react.js b/lib/socket/message-handler.react.js
--- a/lib/socket/message-handler.react.js
+++ b/lib/socket/message-handler.react.js
@@ -3,12 +3,12 @@
import * as React from 'react';
import { useDispatch } from 'react-redux';
-import { processMessagesActionType } from '../actions/message-actions';
+import { processMessagesActionType } from '../actions/message-actions.js';
import {
type ClientServerSocketMessage,
serverSocketMessageTypes,
type SocketListener,
-} from '../types/socket-types';
+} from '../types/socket-types.js';
type Props = {
+addListener: (listener: SocketListener) => void,
diff --git a/lib/socket/report-handler.react.js b/lib/socket/report-handler.react.js
--- a/lib/socket/report-handler.react.js
+++ b/lib/socket/report-handler.react.js
@@ -2,18 +2,21 @@
import * as React from 'react';
-import { sendReportsActionTypes, sendReports } from '../actions/report-actions';
-import { queuedReports as queuedReportsSelector } from '../selectors/socket-selectors';
+import {
+ sendReportsActionTypes,
+ sendReports,
+} from '../actions/report-actions.js';
+import { queuedReports as queuedReportsSelector } from '../selectors/socket-selectors.js';
import {
type ClientReportCreationRequest,
type ClearDeliveredReportsPayload,
-} from '../types/report-types';
+} from '../types/report-types.js';
import {
type DispatchActionPromise,
useDispatchActionPromise,
useServerCall,
-} from '../utils/action-utils';
-import { useSelector } from '../utils/redux-utils';
+} from '../utils/action-utils.js';
+import { useSelector } from '../utils/redux-utils.js';
type BaseProps = {
+canSendReports: boolean,
diff --git a/lib/socket/request-response-handler.react.js b/lib/socket/request-response-handler.react.js
--- a/lib/socket/request-response-handler.react.js
+++ b/lib/socket/request-response-handler.react.js
@@ -4,13 +4,13 @@
import * as React from 'react';
import { useDispatch } from 'react-redux';
-import type { CalendarQuery } from '../types/entry-types';
-import type { Dispatch } from '../types/redux-types';
+import type { CalendarQuery } from '../types/entry-types.js';
+import type { Dispatch } from '../types/redux-types.js';
import {
processServerRequestsActionType,
type ClientClientResponse,
type ClientServerRequest,
-} from '../types/request-types';
+} from '../types/request-types.js';
import {
type ClientRequestsServerSocketMessage,
type ClientServerSocketMessage,
@@ -19,10 +19,10 @@
type ClientSocketMessageWithoutID,
type SocketListener,
type ConnectionInfo,
-} from '../types/socket-types';
-import { ServerError } from '../utils/errors';
-import { useSelector } from '../utils/redux-utils';
-import { InflightRequests, SocketTimeout } from './inflight-requests';
+} from '../types/socket-types.js';
+import { ServerError } from '../utils/errors.js';
+import { useSelector } from '../utils/redux-utils.js';
+import { InflightRequests, SocketTimeout } from './inflight-requests.js';
type BaseProps = {
+inflightRequests: ?InflightRequests,
diff --git a/lib/socket/socket.react.js b/lib/socket/socket.react.js
--- a/lib/socket/socket.react.js
+++ b/lib/socket/socket.react.js
@@ -1,32 +1,35 @@
// @flow
import invariant from 'invariant';
-import _throttle from 'lodash/throttle';
+import _throttle from 'lodash/throttle.js';
import * as React from 'react';
-import { updateActivityActionTypes } from '../actions/activity-actions';
-import { logOutActionTypes } from '../actions/user-actions';
-import { unsupervisedBackgroundActionType } from '../reducers/lifecycle-state-reducer';
+import { updateActivityActionTypes } from '../actions/activity-actions.js';
+import { logOutActionTypes } from '../actions/user-actions.js';
+import { unsupervisedBackgroundActionType } from '../reducers/lifecycle-state-reducer.js';
import {
pingFrequency,
serverRequestSocketTimeout,
clientRequestVisualTimeout,
clientRequestSocketTimeout,
-} from '../shared/timeouts';
-import { logInActionSources, type LogOutResult } from '../types/account-types';
-import type { CalendarQuery } from '../types/entry-types';
+} from '../shared/timeouts.js';
+import {
+ logInActionSources,
+ type LogOutResult,
+} from '../types/account-types.js';
+import type { CalendarQuery } from '../types/entry-types.js';
import { forcePolicyAcknowledgmentActionType } from '../types/policy-types.js';
-import type { Dispatch } from '../types/redux-types';
+import type { Dispatch } from '../types/redux-types.js';
import {
serverRequestTypes,
type ClientClientResponse,
type ClientServerRequest,
-} from '../types/request-types';
+} from '../types/request-types.js';
import {
type SessionState,
type SessionIdentification,
type PreRequestUserState,
-} from '../types/session-types';
+} from '../types/session-types.js';
import {
clientSocketMessageTypes,
type ClientClientSocketMessage,
@@ -46,30 +49,30 @@
type SocketListener,
type ConnectionStatus,
setLateResponseActionType,
-} from '../types/socket-types';
-import type { CommTransportLayer } from '../types/socket-types';
-import { actionLogger } from '../utils/action-logger';
-import type { DispatchActionPromise } from '../utils/action-utils';
+} from '../types/socket-types.js';
+import type { CommTransportLayer } from '../types/socket-types.js';
+import { actionLogger } from '../utils/action-logger.js';
+import type { DispatchActionPromise } from '../utils/action-utils.js';
import {
setNewSessionActionType,
fetchNewCookieFromNativeCredentials,
-} from '../utils/action-utils';
-import { getConfig } from '../utils/config';
-import { ServerError } from '../utils/errors';
-import { promiseAll } from '../utils/promises';
-import sleep from '../utils/sleep';
-import ActivityHandler from './activity-handler.react';
-import APIRequestHandler from './api-request-handler.react';
-import CalendarQueryHandler from './calendar-query-handler.react';
+} from '../utils/action-utils.js';
+import { getConfig } from '../utils/config.js';
+import { ServerError } from '../utils/errors.js';
+import { promiseAll } from '../utils/promises.js';
+import sleep from '../utils/sleep.js';
+import ActivityHandler from './activity-handler.react.js';
+import APIRequestHandler from './api-request-handler.react.js';
+import CalendarQueryHandler from './calendar-query-handler.react.js';
import {
InflightRequests,
SocketTimeout,
SocketOffline,
-} from './inflight-requests';
-import MessageHandler from './message-handler.react';
-import ReportHandler from './report-handler.react';
-import RequestResponseHandler from './request-response-handler.react';
-import UpdateHandler from './update-handler.react';
+} from './inflight-requests.js';
+import MessageHandler from './message-handler.react.js';
+import ReportHandler from './report-handler.react.js';
+import RequestResponseHandler from './request-response-handler.react.js';
+import UpdateHandler from './update-handler.react.js';
const remainingTimeAfterVisualTimeout =
clientRequestSocketTimeout - clientRequestVisualTimeout;
diff --git a/lib/socket/update-handler.react.js b/lib/socket/update-handler.react.js
--- a/lib/socket/update-handler.react.js
+++ b/lib/socket/update-handler.react.js
@@ -10,9 +10,9 @@
type ClientServerSocketMessage,
serverSocketMessageTypes,
clientSocketMessageTypes,
-} from '../types/socket-types';
-import { processUpdatesActionType } from '../types/update-types';
-import { useSelector } from '../utils/redux-utils';
+} from '../types/socket-types.js';
+import { processUpdatesActionType } from '../types/update-types.js';
+import { useSelector } from '../utils/redux-utils.js';
type Props = {
+sendMessage: (message: ClientSocketMessageWithoutID) => number,
diff --git a/lib/types/account-types.js b/lib/types/account-types.js
--- a/lib/types/account-types.js
+++ b/lib/types/account-types.js
@@ -1,26 +1,26 @@
// @flow
import type { PolicyType } from '../facts/policies.js';
-import { values } from '../utils/objects';
-import type { PlatformDetails } from './device-types';
+import { values } from '../utils/objects.js';
+import type { PlatformDetails } from './device-types.js';
import type {
CalendarQuery,
CalendarResult,
RawEntryInfo,
-} from './entry-types';
+} from './entry-types.js';
import type {
RawMessageInfo,
MessageTruncationStatuses,
GenericMessagesResult,
-} from './message-types';
-import type { PreRequestUserState } from './session-types';
-import type { RawThreadInfo } from './thread-types';
+} from './message-types.js';
+import type { PreRequestUserState } from './session-types.js';
+import type { RawThreadInfo } from './thread-types.js';
import type {
UserInfo,
LoggedOutUserInfo,
LoggedInUserInfo,
OldLoggedInUserInfo,
-} from './user-types';
+} from './user-types.js';
export type ResetPasswordRequest = {
+usernameOrEmail: string,
diff --git a/lib/types/entry-types.js b/lib/types/entry-types.js
--- a/lib/types/entry-types.js
+++ b/lib/types/entry-types.js
@@ -4,15 +4,15 @@
fifteenDaysEarlier,
fifteenDaysLater,
thisMonthDates,
-} from '../utils/date-utils';
-import type { Platform } from './device-types';
-import { type CalendarFilter, defaultCalendarFilters } from './filter-types';
-import type { RawMessageInfo } from './message-types';
+} from '../utils/date-utils.js';
+import type { Platform } from './device-types.js';
+import { type CalendarFilter, defaultCalendarFilters } from './filter-types.js';
+import type { RawMessageInfo } from './message-types.js';
import type {
ServerCreateUpdatesResponse,
ClientCreateUpdatesResponse,
-} from './update-types';
-import type { UserInfo, AccountUserInfo } from './user-types';
+} from './update-types.js';
+import type { UserInfo, AccountUserInfo } from './user-types.js';
export type RawEntryInfo = {
id?: string, // null if local copy without ID yet
diff --git a/lib/types/filter-types.js b/lib/types/filter-types.js
--- a/lib/types/filter-types.js
+++ b/lib/types/filter-types.js
@@ -1,6 +1,6 @@
// @flow
-import type { ResolvedThreadInfo } from './thread-types';
+import type { ResolvedThreadInfo } from './thread-types.js';
export const calendarThreadFilterTypes = Object.freeze({
THREAD_LIST: 'threads',
diff --git a/lib/types/media-types.js b/lib/types/media-types.js
--- a/lib/types/media-types.js
+++ b/lib/types/media-types.js
@@ -1,7 +1,7 @@
// @flow
-import type { Shape } from './core';
-import { type Platform } from './device-types';
+import type { Shape } from './core.js';
+import { type Platform } from './device-types.js';
export type Dimensions = $ReadOnly<{
+height: number,
diff --git a/lib/types/message-report-types.js b/lib/types/message-report-types.js
--- a/lib/types/message-report-types.js
+++ b/lib/types/message-report-types.js
@@ -1,6 +1,6 @@
// @flow
-import type { RawMessageInfo } from './message-types';
+import type { RawMessageInfo } from './message-types.js';
export type MessageReportCreationRequest = {
+messageID: string,
diff --git a/lib/types/message-types.js b/lib/types/message-types.js
--- a/lib/types/message-types.js
+++ b/lib/types/message-types.js
@@ -2,104 +2,104 @@
import invariant from 'invariant';
-import type { CallServerEndpointResultInfoInterface } from '../utils/call-server-endpoint';
-import { type ClientDBMediaInfo } from './media-types';
+import type { CallServerEndpointResultInfoInterface } from '../utils/call-server-endpoint.js';
+import { type ClientDBMediaInfo } from './media-types.js';
import type {
AddMembersMessageData,
AddMembersMessageInfo,
RawAddMembersMessageInfo,
-} from './messages/add-members';
+} from './messages/add-members.js';
import type {
ChangeRoleMessageData,
ChangeRoleMessageInfo,
RawChangeRoleMessageInfo,
-} from './messages/change-role';
+} from './messages/change-role.js';
import type {
ChangeSettingsMessageData,
ChangeSettingsMessageInfo,
RawChangeSettingsMessageInfo,
-} from './messages/change-settings';
+} from './messages/change-settings.js';
import type {
CreateEntryMessageData,
CreateEntryMessageInfo,
RawCreateEntryMessageInfo,
-} from './messages/create-entry';
+} from './messages/create-entry.js';
import type {
CreateSidebarMessageData,
CreateSidebarMessageInfo,
RawCreateSidebarMessageInfo,
-} from './messages/create-sidebar';
+} from './messages/create-sidebar.js';
import type {
CreateSubthreadMessageData,
CreateSubthreadMessageInfo,
RawCreateSubthreadMessageInfo,
-} from './messages/create-subthread';
+} from './messages/create-subthread.js';
import type {
CreateThreadMessageData,
CreateThreadMessageInfo,
RawCreateThreadMessageInfo,
-} from './messages/create-thread';
+} from './messages/create-thread.js';
import type {
DeleteEntryMessageData,
DeleteEntryMessageInfo,
RawDeleteEntryMessageInfo,
-} from './messages/delete-entry';
+} from './messages/delete-entry.js';
import type {
EditEntryMessageData,
EditEntryMessageInfo,
RawEditEntryMessageInfo,
-} from './messages/edit-entry';
+} from './messages/edit-entry.js';
import type {
ImagesMessageData,
ImagesMessageInfo,
RawImagesMessageInfo,
-} from './messages/images';
+} from './messages/images.js';
import type {
JoinThreadMessageData,
JoinThreadMessageInfo,
RawJoinThreadMessageInfo,
-} from './messages/join-thread';
+} from './messages/join-thread.js';
import type {
LeaveThreadMessageData,
LeaveThreadMessageInfo,
RawLeaveThreadMessageInfo,
-} from './messages/leave-thread';
+} from './messages/leave-thread.js';
import type {
MediaMessageData,
MediaMessageInfo,
MediaMessageServerDBContent,
RawMediaMessageInfo,
-} from './messages/media';
+} from './messages/media.js';
import type {
ReactionMessageData,
RawReactionMessageInfo,
ReactionMessageInfo,
-} from './messages/reaction';
+} from './messages/reaction.js';
import type {
RawRemoveMembersMessageInfo,
RemoveMembersMessageData,
RemoveMembersMessageInfo,
-} from './messages/remove-members';
+} from './messages/remove-members.js';
import type {
RawRestoreEntryMessageInfo,
RestoreEntryMessageData,
RestoreEntryMessageInfo,
-} from './messages/restore-entry';
+} from './messages/restore-entry.js';
import type {
RawTextMessageInfo,
TextMessageData,
TextMessageInfo,
-} from './messages/text';
+} from './messages/text.js';
import type {
RawUnsupportedMessageInfo,
UnsupportedMessageInfo,
-} from './messages/unsupported';
+} from './messages/unsupported.js';
import type {
RawUpdateRelationshipMessageInfo,
UpdateRelationshipMessageData,
UpdateRelationshipMessageInfo,
-} from './messages/update-relationship';
-import { type RelativeUserInfo, type UserInfos } from './user-types';
+} from './messages/update-relationship.js';
+import { type RelativeUserInfo, type UserInfos } from './user-types.js';
export const messageTypes = Object.freeze({
TEXT: 0,
diff --git a/lib/types/messages/add-members.js b/lib/types/messages/add-members.js
--- a/lib/types/messages/add-members.js
+++ b/lib/types/messages/add-members.js
@@ -1,6 +1,6 @@
// @flow
-import type { RelativeUserInfo } from '../user-types';
+import type { RelativeUserInfo } from '../user-types.js';
export type AddMembersMessageData = {
type: 2,
diff --git a/lib/types/messages/change-role.js b/lib/types/messages/change-role.js
--- a/lib/types/messages/change-role.js
+++ b/lib/types/messages/change-role.js
@@ -1,6 +1,6 @@
// @flow
-import type { RelativeUserInfo } from '../user-types';
+import type { RelativeUserInfo } from '../user-types.js';
export type ChangeRoleMessageData = {
type: 6,
diff --git a/lib/types/messages/change-settings.js b/lib/types/messages/change-settings.js
--- a/lib/types/messages/change-settings.js
+++ b/lib/types/messages/change-settings.js
@@ -1,6 +1,6 @@
// @flow
-import type { RelativeUserInfo } from '../user-types';
+import type { RelativeUserInfo } from '../user-types.js';
export type ChangeSettingsMessageData = {
type: 4,
diff --git a/lib/types/messages/create-entry.js b/lib/types/messages/create-entry.js
--- a/lib/types/messages/create-entry.js
+++ b/lib/types/messages/create-entry.js
@@ -1,6 +1,6 @@
// @flow
-import type { RelativeUserInfo } from '../user-types';
+import type { RelativeUserInfo } from '../user-types.js';
export type CreateEntryMessageData = {
type: 9,
diff --git a/lib/types/messages/create-sidebar.js b/lib/types/messages/create-sidebar.js
--- a/lib/types/messages/create-sidebar.js
+++ b/lib/types/messages/create-sidebar.js
@@ -1,7 +1,7 @@
// @flow
-import type { ThreadInfo } from '../thread-types';
-import type { RelativeUserInfo } from '../user-types';
+import type { ThreadInfo } from '../thread-types.js';
+import type { RelativeUserInfo } from '../user-types.js';
export type CreateSidebarMessageData = {
+type: 18,
diff --git a/lib/types/messages/create-subthread.js b/lib/types/messages/create-subthread.js
--- a/lib/types/messages/create-subthread.js
+++ b/lib/types/messages/create-subthread.js
@@ -1,7 +1,7 @@
// @flow
-import type { ThreadInfo } from '../thread-types';
-import type { RelativeUserInfo } from '../user-types';
+import type { ThreadInfo } from '../thread-types.js';
+import type { RelativeUserInfo } from '../user-types.js';
export type CreateSubthreadMessageData = {
type: 3,
diff --git a/lib/types/messages/create-thread.js b/lib/types/messages/create-thread.js
--- a/lib/types/messages/create-thread.js
+++ b/lib/types/messages/create-thread.js
@@ -1,7 +1,7 @@
// @flow
-import type { ThreadInfo, ThreadType } from '../thread-types';
-import type { RelativeUserInfo } from '../user-types';
+import type { ThreadInfo, ThreadType } from '../thread-types.js';
+import type { RelativeUserInfo } from '../user-types.js';
export type CreateThreadMessageData = {
type: 1,
diff --git a/lib/types/messages/delete-entry.js b/lib/types/messages/delete-entry.js
--- a/lib/types/messages/delete-entry.js
+++ b/lib/types/messages/delete-entry.js
@@ -1,6 +1,6 @@
// @flow
-import type { RelativeUserInfo } from '../user-types';
+import type { RelativeUserInfo } from '../user-types.js';
export type DeleteEntryMessageData = {
type: 11,
diff --git a/lib/types/messages/edit-entry.js b/lib/types/messages/edit-entry.js
--- a/lib/types/messages/edit-entry.js
+++ b/lib/types/messages/edit-entry.js
@@ -1,6 +1,6 @@
// @flow
-import type { RelativeUserInfo } from '../user-types';
+import type { RelativeUserInfo } from '../user-types.js';
export type EditEntryMessageData = {
type: 10,
diff --git a/lib/types/messages/images.js b/lib/types/messages/images.js
--- a/lib/types/messages/images.js
+++ b/lib/types/messages/images.js
@@ -1,7 +1,7 @@
// @flow
-import type { Image } from '../media-types';
-import type { RelativeUserInfo } from '../user-types';
+import type { Image } from '../media-types.js';
+import type { RelativeUserInfo } from '../user-types.js';
export type ImagesMessageData = {
type: 14,
diff --git a/lib/types/messages/join-thread.js b/lib/types/messages/join-thread.js
--- a/lib/types/messages/join-thread.js
+++ b/lib/types/messages/join-thread.js
@@ -1,6 +1,6 @@
// @flow
-import type { RelativeUserInfo } from '../user-types';
+import type { RelativeUserInfo } from '../user-types.js';
export type JoinThreadMessageData = {
type: 8,
diff --git a/lib/types/messages/leave-thread.js b/lib/types/messages/leave-thread.js
--- a/lib/types/messages/leave-thread.js
+++ b/lib/types/messages/leave-thread.js
@@ -1,6 +1,6 @@
// @flow
-import type { RelativeUserInfo } from '../user-types';
+import type { RelativeUserInfo } from '../user-types.js';
export type LeaveThreadMessageData = {
type: 7,
diff --git a/lib/types/messages/media.js b/lib/types/messages/media.js
--- a/lib/types/messages/media.js
+++ b/lib/types/messages/media.js
@@ -1,7 +1,7 @@
// @flow
-import type { Media } from '../media-types';
-import type { RelativeUserInfo } from '../user-types';
+import type { Media } from '../media-types.js';
+import type { RelativeUserInfo } from '../user-types.js';
export type MediaMessageData = {
type: 15,
diff --git a/lib/types/messages/reaction.js b/lib/types/messages/reaction.js
--- a/lib/types/messages/reaction.js
+++ b/lib/types/messages/reaction.js
@@ -1,6 +1,6 @@
// @flow
-import type { RelativeUserInfo } from '../user-types';
+import type { RelativeUserInfo } from '../user-types.js';
export type ReactionMessageData = {
+type: 19,
diff --git a/lib/types/messages/remove-members.js b/lib/types/messages/remove-members.js
--- a/lib/types/messages/remove-members.js
+++ b/lib/types/messages/remove-members.js
@@ -1,6 +1,6 @@
// @flow
-import type { RelativeUserInfo } from '../user-types';
+import type { RelativeUserInfo } from '../user-types.js';
export type RemoveMembersMessageData = {
type: 5,
diff --git a/lib/types/messages/restore-entry.js b/lib/types/messages/restore-entry.js
--- a/lib/types/messages/restore-entry.js
+++ b/lib/types/messages/restore-entry.js
@@ -1,6 +1,6 @@
// @flow
-import type { RelativeUserInfo } from '../user-types';
+import type { RelativeUserInfo } from '../user-types.js';
export type RestoreEntryMessageData = {
type: 12,
diff --git a/lib/types/messages/text.js b/lib/types/messages/text.js
--- a/lib/types/messages/text.js
+++ b/lib/types/messages/text.js
@@ -1,6 +1,6 @@
// @flow
-import type { RelativeUserInfo } from '../user-types';
+import type { RelativeUserInfo } from '../user-types.js';
export type TextMessageData = {
type: 0,
diff --git a/lib/types/messages/unsupported.js b/lib/types/messages/unsupported.js
--- a/lib/types/messages/unsupported.js
+++ b/lib/types/messages/unsupported.js
@@ -1,6 +1,6 @@
// @flow
-import type { RelativeUserInfo } from '../user-types';
+import type { RelativeUserInfo } from '../user-types.js';
export type RawUnsupportedMessageInfo = {
type: 13,
diff --git a/lib/types/messages/update-relationship.js b/lib/types/messages/update-relationship.js
--- a/lib/types/messages/update-relationship.js
+++ b/lib/types/messages/update-relationship.js
@@ -1,6 +1,6 @@
// @flow
-import type { RelativeUserInfo } from '../user-types';
+import type { RelativeUserInfo } from '../user-types.js';
export type UpdateRelationshipMessageData = {
+type: 16,
diff --git a/lib/types/notif-types.js b/lib/types/notif-types.js
--- a/lib/types/notif-types.js
+++ b/lib/types/notif-types.js
@@ -1,6 +1,6 @@
// @flow
-import type { EntityText, UserEntity } from '../utils/entity-text';
+import type { EntityText, UserEntity } from '../utils/entity-text.js';
export type NotifTexts = {
+merged: string | EntityText,
diff --git a/lib/types/redis-types.js b/lib/types/redis-types.js
--- a/lib/types/redis-types.js
+++ b/lib/types/redis-types.js
@@ -1,7 +1,7 @@
// @flow
-import type { RawMessageInfo } from './message-types';
-import type { RawUpdateInfo } from './update-types';
+import type { RawMessageInfo } from './message-types.js';
+import type { RawUpdateInfo } from './update-types.js';
// The types of messages that can be published to Redis
export const redisMessageTypes = Object.freeze({
diff --git a/lib/types/redux-types.js b/lib/types/redux-types.js
--- a/lib/types/redux-types.js
+++ b/lib/types/redux-types.js
@@ -1,20 +1,20 @@
// @flow
-import type { Shape } from '../types/core';
+import type { Shape } from '../types/core.js';
import type {
LogOutResult,
LogInStartingPayload,
LogInResult,
RegisterResult,
DefaultNotificationPayload,
-} from './account-types';
+} from './account-types.js';
import type {
ActivityUpdateSuccessPayload,
QueueActivityUpdatesPayload,
SetThreadUnreadStatusPayload,
-} from './activity-types';
-import type { ClientDBDraftInfo, DraftStore } from './draft-types';
-import type { EnabledApps, SupportedApps } from './enabled-apps';
+} from './activity-types.js';
+import type { ClientDBDraftInfo, DraftStore } from './draft-types.js';
+import type { EnabledApps, SupportedApps } from './enabled-apps.js';
import type {
RawEntryInfo,
EntryStore,
@@ -25,16 +25,16 @@
FetchEntryInfosResult,
CalendarQueryUpdateResult,
CalendarQueryUpdateStartingPayload,
-} from './entry-types';
+} from './entry-types.js';
import type {
CalendarFilter,
CalendarThreadFilter,
SetCalendarDeletedFilterPayload,
-} from './filter-types';
-import type { LifecycleState } from './lifecycle-state-types';
-import type { LoadingStatus, LoadingInfo } from './loading-types';
-import type { UpdateMultimediaMessageMediaPayload } from './media-types';
-import type { MessageReportCreationResult } from './message-report-types';
+} from './filter-types.js';
+import type { LifecycleState } from './lifecycle-state-types.js';
+import type { LoadingStatus, LoadingInfo } from './loading-types.js';
+import type { UpdateMultimediaMessageMediaPayload } from './media-types.js';
+import type { MessageReportCreationResult } from './message-report-types.js';
import type {
MessageStore,
RawMultimediaMessageInfo,
@@ -46,25 +46,25 @@
LocallyComposedMessageInfo,
ClientDBMessageInfo,
SimpleMessagesPayload,
-} from './message-types';
-import type { RawReactionMessageInfo } from './messages/reaction';
-import type { RawTextMessageInfo } from './messages/text';
-import type { BaseNavInfo } from './nav-types';
+} from './message-types.js';
+import type { RawReactionMessageInfo } from './messages/reaction.js';
+import type { RawTextMessageInfo } from './messages/text.js';
+import type { BaseNavInfo } from './nav-types.js';
import {
type ForcePolicyAcknowledgmentPayload,
type PolicyAcknowledgmentPayload,
type UserPolicies,
} from './policy-types.js';
-import type { RelationshipErrors } from './relationship-types';
+import type { RelationshipErrors } from './relationship-types.js';
import type {
EnabledReports,
ClearDeliveredReportsPayload,
QueueReportsPayload,
ReportStore,
-} from './report-types';
-import type { ProcessServerRequestsPayload } from './request-types';
-import type { UserSearchResult } from './search-types';
-import type { SetSessionPayload } from './session-types';
+} from './report-types.js';
+import type { ProcessServerRequestsPayload } from './request-types.js';
+import type { UserSearchResult } from './search-types.js';
+import type { SetSessionPayload } from './session-types.js';
import type {
ConnectionInfo,
StateSyncFullActionPayload,
@@ -72,17 +72,17 @@
UpdateConnectionStatusPayload,
SetLateResponsePayload,
UpdateDisconnectedBarPayload,
-} from './socket-types';
-import type { SubscriptionUpdateResult } from './subscription-types';
+} from './socket-types.js';
+import type { SubscriptionUpdateResult } from './subscription-types.js';
import type {
ThreadStore,
ChangeThreadSettingsPayload,
LeaveThreadPayload,
NewThreadResult,
ThreadJoinPayload,
-} from './thread-types';
-import type { ClientUpdatesResultWithUserInfos } from './update-types';
-import type { CurrentUserInfo, UserStore } from './user-types';
+} from './thread-types.js';
+import type { ClientUpdatesResultWithUserInfos } from './update-types.js';
+import type { CurrentUserInfo, UserStore } from './user-types.js';
export type BaseAppState<NavInfo: BaseNavInfo> = {
navInfo: NavInfo,
diff --git a/lib/types/relationship-types.js b/lib/types/relationship-types.js
--- a/lib/types/relationship-types.js
+++ b/lib/types/relationship-types.js
@@ -1,7 +1,7 @@
// @flow
-import { values } from '../utils/objects';
-import type { AccountUserInfo } from './user-types';
+import { values } from '../utils/objects.js';
+import type { AccountUserInfo } from './user-types.js';
export const undirectedStatus = Object.freeze({
KNOW_OF: 0,
diff --git a/lib/types/report-types.js b/lib/types/report-types.js
--- a/lib/types/report-types.js
+++ b/lib/types/report-types.js
@@ -2,12 +2,12 @@
import invariant from 'invariant';
-import { type PlatformDetails } from './device-types';
-import { type RawEntryInfo, type CalendarQuery } from './entry-types';
-import { type MediaMission } from './media-types';
-import type { AppState, BaseAction } from './redux-types';
-import { type RawThreadInfo } from './thread-types';
-import type { UserInfo, UserInfos } from './user-types';
+import { type PlatformDetails } from './device-types.js';
+import { type RawEntryInfo, type CalendarQuery } from './entry-types.js';
+import { type MediaMission } from './media-types.js';
+import type { AppState, BaseAction } from './redux-types.js';
+import { type RawThreadInfo } from './thread-types.js';
+import type { UserInfo, UserInfos } from './user-types.js';
export type EnabledReports = {
+crashReports: boolean,
diff --git a/lib/types/request-types.js b/lib/types/request-types.js
--- a/lib/types/request-types.js
+++ b/lib/types/request-types.js
@@ -2,22 +2,22 @@
import invariant from 'invariant';
-import { type ActivityUpdate } from './activity-types';
-import type { Shape } from './core';
-import type { Platform, PlatformDetails } from './device-types';
-import type { RawEntryInfo, CalendarQuery } from './entry-types';
+import { type ActivityUpdate } from './activity-types.js';
+import type { Shape } from './core.js';
+import type { Platform, PlatformDetails } from './device-types.js';
+import type { RawEntryInfo, CalendarQuery } from './entry-types.js';
import type {
ThreadInconsistencyReportShape,
EntryInconsistencyReportShape,
ClientThreadInconsistencyReportShape,
ClientEntryInconsistencyReportShape,
-} from './report-types';
-import type { RawThreadInfo } from './thread-types';
+} from './report-types.js';
+import type { RawThreadInfo } from './thread-types.js';
import type {
CurrentUserInfo,
OldCurrentUserInfo,
AccountUserInfo,
-} from './user-types';
+} from './user-types.js';
// "Server requests" are requests for information that the server delivers to
// clients. Clients then respond to those requests with a "client response".
diff --git a/lib/types/search-types.js b/lib/types/search-types.js
--- a/lib/types/search-types.js
+++ b/lib/types/search-types.js
@@ -1,6 +1,6 @@
// @flow
-import type { GlobalAccountUserInfo } from './user-types';
+import type { GlobalAccountUserInfo } from './user-types.js';
export type UserSearchRequest = {
prefix?: string,
diff --git a/lib/types/session-types.js b/lib/types/session-types.js
--- a/lib/types/session-types.js
+++ b/lib/types/session-types.js
@@ -1,14 +1,14 @@
// @flow
-import type { LogInActionSource } from './account-types';
-import type { Shape } from './core';
-import type { CalendarQuery } from './entry-types';
-import type { RawThreadInfo } from './thread-types';
+import type { LogInActionSource } from './account-types.js';
+import type { Shape } from './core.js';
+import type { CalendarQuery } from './entry-types.js';
+import type { RawThreadInfo } from './thread-types.js';
import {
type UserInfo,
type CurrentUserInfo,
type LoggedOutUserInfo,
-} from './user-types';
+} from './user-types.js';
export const cookieLifetime = 30 * 24 * 60 * 60 * 1000; // in milliseconds
// Interval the server waits after a state check before starting a new one
diff --git a/lib/types/siwe-types.js b/lib/types/siwe-types.js
--- a/lib/types/siwe-types.js
+++ b/lib/types/siwe-types.js
@@ -4,8 +4,8 @@
import {
type DeviceTokenUpdateRequest,
type PlatformDetails,
-} from './device-types';
-import { type CalendarQuery } from './entry-types';
+} from './device-types.js';
+import { type CalendarQuery } from './entry-types.js';
export type SIWENonceResponse = {
+nonce: string,
diff --git a/lib/types/socket-types.js b/lib/types/socket-types.js
--- a/lib/types/socket-types.js
+++ b/lib/types/socket-types.js
@@ -5,35 +5,35 @@
import {
type ActivityUpdate,
type UpdateActivityResult,
-} from './activity-types';
-import type { Platform } from './device-types';
-import type { APIRequest } from './endpoints';
+} from './activity-types.js';
+import type { Platform } from './device-types.js';
+import type { APIRequest } from './endpoints.js';
import {
type RawEntryInfo,
type CalendarQuery,
defaultCalendarQuery,
-} from './entry-types';
-import type { MessagesResponse, NewMessagesPayload } from './message-types';
+} from './entry-types.js';
+import type { MessagesResponse, NewMessagesPayload } from './message-types.js';
import type {
ServerServerRequest,
ClientServerRequest,
ClientResponse,
ClientClientResponse,
-} from './request-types';
-import type { SessionState, SessionIdentification } from './session-types';
-import type { RawThreadInfo } from './thread-types';
+} from './request-types.js';
+import type { SessionState, SessionIdentification } from './session-types.js';
+import type { RawThreadInfo } from './thread-types.js';
import type {
ClientUpdatesResult,
ClientUpdatesResultWithUserInfos,
ServerUpdatesResult,
ServerUpdatesResultWithUserInfos,
-} from './update-types';
+} from './update-types.js';
import type {
UserInfo,
CurrentUserInfo,
OldCurrentUserInfo,
LoggedOutUserInfo,
-} from './user-types';
+} from './user-types.js';
// The types of messages that the client sends across the socket
export const clientSocketMessageTypes = Object.freeze({
diff --git a/lib/types/store-ops-types.js b/lib/types/store-ops-types.js
--- a/lib/types/store-ops-types.js
+++ b/lib/types/store-ops-types.js
@@ -1,8 +1,8 @@
// @flow
-import type { DraftStoreOperation } from './draft-types';
-import type { MessageStoreOperation } from './message-types';
-import type { ThreadStoreOperation } from './thread-types';
+import type { DraftStoreOperation } from './draft-types.js';
+import type { MessageStoreOperation } from './message-types.js';
+import type { ThreadStoreOperation } from './thread-types.js';
export type StoreOperations = {
+draftStoreOperations: $ReadOnlyArray<DraftStoreOperation>,
diff --git a/lib/types/subscription-types.js b/lib/types/subscription-types.js
--- a/lib/types/subscription-types.js
+++ b/lib/types/subscription-types.js
@@ -1,6 +1,6 @@
// @flow
-import type { Shape } from './core';
+import type { Shape } from './core.js';
export const threadSubscriptions = Object.freeze({
home: 'home',
diff --git a/lib/types/thread-types.js b/lib/types/thread-types.js
--- a/lib/types/thread-types.js
+++ b/lib/types/thread-types.js
@@ -2,16 +2,16 @@
import invariant from 'invariant';
-import type { UserEntity } from '../utils/entity-text';
-import type { Shape } from './core';
-import type { CalendarQuery, RawEntryInfo } from './entry-types';
+import type { UserEntity } from '../utils/entity-text.js';
+import type { Shape } from './core.js';
+import type { CalendarQuery, RawEntryInfo } from './entry-types.js';
import type {
RawMessageInfo,
MessageTruncationStatuses,
-} from './message-types';
-import type { ThreadSubscription } from './subscription-types';
-import type { ServerUpdateInfo, ClientUpdateInfo } from './update-types';
-import type { UserInfo, UserInfos } from './user-types';
+} from './message-types.js';
+import type { ThreadSubscription } from './subscription-types.js';
+import type { ServerUpdateInfo, ClientUpdateInfo } from './update-types.js';
+import type { UserInfo, UserInfos } from './user-types.js';
export const threadTypes = Object.freeze({
//OPEN: 0, (DEPRECATED)
diff --git a/lib/types/update-types.js b/lib/types/update-types.js
--- a/lib/types/update-types.js
+++ b/lib/types/update-types.js
@@ -2,15 +2,18 @@
import invariant from 'invariant';
-import type { RawEntryInfo } from './entry-types';
-import type { RawMessageInfo, MessageTruncationStatus } from './message-types';
-import type { RawThreadInfo } from './thread-types';
+import type { RawEntryInfo } from './entry-types.js';
+import type {
+ RawMessageInfo,
+ MessageTruncationStatus,
+} from './message-types.js';
+import type { RawThreadInfo } from './thread-types.js';
import type {
UserInfo,
UserInfos,
LoggedInUserInfo,
OldLoggedInUserInfo,
-} from './user-types';
+} from './user-types.js';
export const updateTypes = Object.freeze({
DELETE_ACCOUNT: 0,
diff --git a/lib/types/user-types.js b/lib/types/user-types.js
--- a/lib/types/user-types.js
+++ b/lib/types/user-types.js
@@ -1,8 +1,8 @@
// @flow
-import type { DefaultNotificationPayload } from './account-types';
-import type { UserRelationshipStatus } from './relationship-types';
-import type { UserInconsistencyReportCreationRequest } from './report-types';
+import type { DefaultNotificationPayload } from './account-types.js';
+import type { UserRelationshipStatus } from './relationship-types.js';
+import type { UserInconsistencyReportCreationRequest } from './report-types.js';
export type GlobalUserInfo = {
+id: string,
diff --git a/lib/types/version-types.js b/lib/types/version-types.js
--- a/lib/types/version-types.js
+++ b/lib/types/version-types.js
@@ -1,6 +1,6 @@
// @flow
-import type { DeviceType } from './device-types';
+import type { DeviceType } from './device-types.js';
export type CreateNewVersionsRequest = {
+codeVersion: number,
diff --git a/lib/utils/action-logger.js b/lib/utils/action-logger.js
--- a/lib/utils/action-logger.js
+++ b/lib/utils/action-logger.js
@@ -3,9 +3,9 @@
import { type Middleware } from 'redux';
import inspect from 'util-inspect';
-import { rehydrateActionType } from '../types/redux-types';
-import type { ActionSummary } from '../types/report-types';
-import { sanitizeActionSecrets } from './sanitization';
+import { rehydrateActionType } from '../types/redux-types.js';
+import type { ActionSummary } from '../types/report-types.js';
+import { sanitizeActionSecrets } from './sanitization.js';
const uninterestingActionTypes = new Set(['Navigation/COMPLETE_TRANSITION']);
const maxActionSummaryLength = 500;
diff --git a/lib/utils/action-utils.js b/lib/utils/action-utils.js
--- a/lib/utils/action-utils.js
+++ b/lib/utils/action-utils.js
@@ -1,37 +1,37 @@
// @flow
-import _memoize from 'lodash/memoize';
+import _memoize from 'lodash/memoize.js';
import * as React from 'react';
import { useSelector, useDispatch } from 'react-redux';
import { createSelector } from 'reselect';
-import { serverCallStateSelector } from '../selectors/server-calls';
+import { serverCallStateSelector } from '../selectors/server-calls.js';
import {
logInActionSources,
type LogInActionSource,
type LogInStartingPayload,
type LogInResult,
-} from '../types/account-types';
-import type { Endpoint, SocketAPIHandler } from '../types/endpoints';
-import type { LoadingOptions, LoadingInfo } from '../types/loading-types';
+} from '../types/account-types.js';
+import type { Endpoint, SocketAPIHandler } from '../types/endpoints.js';
+import type { LoadingOptions, LoadingInfo } from '../types/loading-types.js';
import type {
ActionPayload,
Dispatch,
PromisedAction,
BaseAction,
-} from '../types/redux-types';
+} from '../types/redux-types.js';
import type {
ClientSessionChange,
PreRequestUserState,
-} from '../types/session-types';
-import type { ConnectionStatus } from '../types/socket-types';
-import type { CurrentUserInfo } from '../types/user-types';
-import callServerEndpoint from './call-server-endpoint';
+} from '../types/session-types.js';
+import type { ConnectionStatus } from '../types/socket-types.js';
+import type { CurrentUserInfo } from '../types/user-types.js';
+import callServerEndpoint from './call-server-endpoint.js';
import type {
CallServerEndpoint,
CallServerEndpointOptions,
-} from './call-server-endpoint';
-import { getConfig } from './config';
+} from './call-server-endpoint.js';
+import { getConfig } from './config.js';
let nextPromiseIndex = 0;
diff --git a/lib/utils/call-server-endpoint.js b/lib/utils/call-server-endpoint.js
--- a/lib/utils/call-server-endpoint.js
+++ b/lib/utils/call-server-endpoint.js
@@ -1,26 +1,26 @@
// @flow
-import { callServerEndpointTimeout } from '../shared/timeouts';
-import { SocketOffline, SocketTimeout } from '../socket/inflight-requests';
-import type { Shape } from '../types/core';
+import { callServerEndpointTimeout } from '../shared/timeouts.js';
+import { SocketOffline, SocketTimeout } from '../socket/inflight-requests.js';
+import type { Shape } from '../types/core.js';
import {
type Endpoint,
type SocketAPIHandler,
endpointIsSocketPreferred,
endpointIsSocketOnly,
-} from '../types/endpoints';
+} from '../types/endpoints.js';
import { forcePolicyAcknowledgmentActionType } from '../types/policy-types.js';
import type { Dispatch } from '../types/redux-types.js';
import type {
ServerSessionChange,
ClientSessionChange,
-} from '../types/session-types';
-import type { ConnectionStatus } from '../types/socket-types';
-import type { CurrentUserInfo } from '../types/user-types';
-import { getConfig } from './config';
-import { ServerError, FetchTimeout } from './errors';
-import sleep from './sleep';
-import { uploadBlob, type UploadBlob } from './upload-blob';
+} from '../types/session-types.js';
+import type { ConnectionStatus } from '../types/socket-types.js';
+import type { CurrentUserInfo } from '../types/user-types.js';
+import { getConfig } from './config.js';
+import { ServerError, FetchTimeout } from './errors.js';
+import sleep from './sleep.js';
+import { uploadBlob, type UploadBlob } from './upload-blob.js';
export type CallServerEndpointOptions = Shape<{
// null timeout means no timeout, which is the default for uploadBlob
diff --git a/lib/utils/config.js b/lib/utils/config.js
--- a/lib/utils/config.js
+++ b/lib/utils/config.js
@@ -2,10 +2,10 @@
import invariant from 'invariant';
-import type { LogInActionSource } from '../types/account-types';
-import type { PlatformDetails } from '../types/device-types';
-import type { DispatchRecoveryAttempt } from './action-utils';
-import type { CallServerEndpoint } from './call-server-endpoint';
+import type { LogInActionSource } from '../types/account-types.js';
+import type { PlatformDetails } from '../types/device-types.js';
+import type { DispatchRecoveryAttempt } from './action-utils.js';
+import type { CallServerEndpoint } from './call-server-endpoint.js';
export type Config = {
+resolveInvalidatedCookie: ?(
diff --git a/lib/utils/ens-cache.js b/lib/utils/ens-cache.js
--- a/lib/utils/ens-cache.js
+++ b/lib/utils/ens-cache.js
@@ -2,7 +2,7 @@
import namehash from 'eth-ens-namehash';
-import sleep from './sleep';
+import sleep from './sleep.js';
const cacheTimeout = 24 * 60 * 60 * 1000; // one day
const failedQueryCacheTimeout = 5 * 60 * 1000; // five minutes
diff --git a/lib/utils/ens-cache.test.js b/lib/utils/ens-cache.test.js
--- a/lib/utils/ens-cache.test.js
+++ b/lib/utils/ens-cache.test.js
@@ -2,7 +2,7 @@
import { ethers } from 'ethers';
-import { ENSCache } from './ens-cache';
+import { ENSCache } from './ens-cache.js';
const provider = new ethers.providers.AlchemyProvider(
'mainnet',
diff --git a/lib/utils/ens-helpers.js b/lib/utils/ens-helpers.js
--- a/lib/utils/ens-helpers.js
+++ b/lib/utils/ens-helpers.js
@@ -1,7 +1,7 @@
// @flow
-import { userIdentifiedByETHAddress } from '../shared/account-utils';
-import { ENSCache } from './ens-cache';
+import { userIdentifiedByETHAddress } from '../shared/account-utils.js';
+import { ENSCache } from './ens-cache.js';
type BaseUserInfo = { +username?: ?string, ... };
export type GetENSNames = <T: ?BaseUserInfo>(
diff --git a/lib/utils/entity-helpers.js b/lib/utils/entity-helpers.js
--- a/lib/utils/entity-helpers.js
+++ b/lib/utils/entity-helpers.js
@@ -3,13 +3,13 @@
import invariant from 'invariant';
import * as React from 'react';
-import type { ThreadInfo, ResolvedThreadInfo } from '../types/thread-types';
-import { values } from '../utils/objects';
+import type { ThreadInfo, ResolvedThreadInfo } from '../types/thread-types.js';
+import { values } from '../utils/objects.js';
import {
ET,
useENSNamesForEntityText,
entityTextToRawString,
-} from './entity-text';
+} from './entity-text.js';
function useResolvedThreadInfos(
threadInfos: $ReadOnlyArray<ThreadInfo>,
diff --git a/lib/utils/entity-text.js b/lib/utils/entity-text.js
--- a/lib/utils/entity-text.js
+++ b/lib/utils/entity-text.js
@@ -3,17 +3,17 @@
import invariant from 'invariant';
import * as React from 'react';
-import { useENSNames } from '../hooks/ens-cache';
-import { threadNoun } from '../shared/thread-utils';
-import { stringForUser } from '../shared/user-utils';
+import { useENSNames } from '../hooks/ens-cache.js';
+import { threadNoun } from '../shared/thread-utils.js';
+import { stringForUser } from '../shared/user-utils.js';
import {
threadTypes,
type ThreadType,
type RawThreadInfo,
type ThreadInfo,
-} from '../types/thread-types';
-import { basePluralize } from '../utils/text-utils';
-import type { GetENSNames } from './ens-helpers';
+} from '../types/thread-types.js';
+import { basePluralize } from '../utils/text-utils.js';
+import type { GetENSNames } from './ens-helpers.js';
export type UserEntity = {
+type: 'user',
diff --git a/lib/utils/entity-text.test.js b/lib/utils/entity-text.test.js
--- a/lib/utils/entity-text.test.js
+++ b/lib/utils/entity-text.test.js
@@ -1,6 +1,6 @@
// @flow
-import { ET } from './entity-text';
+import { ET } from './entity-text.js';
const someUserEntity = {
type: 'user',
diff --git a/lib/utils/errors.js b/lib/utils/errors.js
--- a/lib/utils/errors.js
+++ b/lib/utils/errors.js
@@ -2,7 +2,7 @@
import copyError from 'utils-copy-error';
-import type { PlatformDetails } from '../types/device-types';
+import type { PlatformDetails } from '../types/device-types.js';
class ExtendableError extends Error {
constructor(message: string) {
diff --git a/lib/utils/math-utils.test.js b/lib/utils/math-utils.test.js
--- a/lib/utils/math-utils.test.js
+++ b/lib/utils/math-utils.test.js
@@ -1,6 +1,6 @@
// @flow
-import { leastPositiveResidue } from './math-utils';
+import { leastPositiveResidue } from './math-utils.js';
describe('leastPositiveResidue', () => {
it('x should be equal to 2 for x ≡ 8 (mod 3)', () => {
diff --git a/lib/utils/memoize.js b/lib/utils/memoize.js
--- a/lib/utils/memoize.js
+++ b/lib/utils/memoize.js
@@ -1,6 +1,6 @@
// @flow
-import _memoize from 'lodash/memoize';
+import _memoize from 'lodash/memoize.js';
export default function memoize2<T, U, V>(
f: (t: T, u: U) => V,
diff --git a/lib/utils/message-ops-utils.js b/lib/utils/message-ops-utils.js
--- a/lib/utils/message-ops-utils.js
+++ b/lib/utils/message-ops-utils.js
@@ -1,15 +1,15 @@
// @flow
-import _keyBy from 'lodash/fp/keyBy';
+import _keyBy from 'lodash/fp/keyBy.js';
-import { messageID } from '../shared/message-utils';
-import { messageSpecs } from '../shared/messages/message-specs';
+import { messageID } from '../shared/message-utils.js';
+import { messageSpecs } from '../shared/messages/message-specs.js';
import type {
Media,
ClientDBMediaInfo,
Image,
Video,
-} from '../types/media-types';
+} from '../types/media-types.js';
import {
type ClientDBMessageInfo,
type RawMessageInfo,
@@ -17,7 +17,7 @@
assertMessageType,
type MessageStoreOperation,
type ClientDBMessageStoreOperation,
-} from '../types/message-types';
+} from '../types/message-types.js';
import type { MediaMessageServerDBContent } from '../types/messages/media.js';
function translateMediaToClientDBMediaInfos(
diff --git a/lib/utils/message-ops-utils.test.js b/lib/utils/message-ops-utils.test.js
--- a/lib/utils/message-ops-utils.test.js
+++ b/lib/utils/message-ops-utils.test.js
@@ -3,27 +3,27 @@
import type {
ClientDBMessageInfo,
RawSidebarSourceMessageInfo,
-} from '../types/message-types';
-import type { RawAddMembersMessageInfo } from '../types/messages/add-members';
-import type { RawChangeSettingsMessageInfo } from '../types/messages/change-settings';
-import type { RawCreateEntryMessageInfo } from '../types/messages/create-entry';
-import type { RawCreateSidebarMessageInfo } from '../types/messages/create-sidebar';
-import type { RawCreateSubthreadMessageInfo } from '../types/messages/create-subthread';
-import type { RawCreateThreadMessageInfo } from '../types/messages/create-thread';
-import type { RawDeleteEntryMessageInfo } from '../types/messages/delete-entry';
-import type { RawEditEntryMessageInfo } from '../types/messages/edit-entry';
-import type { RawImagesMessageInfo } from '../types/messages/images';
-import type { RawJoinThreadMessageInfo } from '../types/messages/join-thread';
-import type { RawLeaveThreadMessageInfo } from '../types/messages/leave-thread';
-import type { RawRemoveMembersMessageInfo } from '../types/messages/remove-members';
-import type { RawRestoreEntryMessageInfo } from '../types/messages/restore-entry';
-import type { RawTextMessageInfo } from '../types/messages/text';
-import type { RawUpdateRelationshipMessageInfo } from '../types/messages/update-relationship';
+} from '../types/message-types.js';
+import type { RawAddMembersMessageInfo } from '../types/messages/add-members.js';
+import type { RawChangeSettingsMessageInfo } from '../types/messages/change-settings.js';
+import type { RawCreateEntryMessageInfo } from '../types/messages/create-entry.js';
+import type { RawCreateSidebarMessageInfo } from '../types/messages/create-sidebar.js';
+import type { RawCreateSubthreadMessageInfo } from '../types/messages/create-subthread.js';
+import type { RawCreateThreadMessageInfo } from '../types/messages/create-thread.js';
+import type { RawDeleteEntryMessageInfo } from '../types/messages/delete-entry.js';
+import type { RawEditEntryMessageInfo } from '../types/messages/edit-entry.js';
+import type { RawImagesMessageInfo } from '../types/messages/images.js';
+import type { RawJoinThreadMessageInfo } from '../types/messages/join-thread.js';
+import type { RawLeaveThreadMessageInfo } from '../types/messages/leave-thread.js';
+import type { RawRemoveMembersMessageInfo } from '../types/messages/remove-members.js';
+import type { RawRestoreEntryMessageInfo } from '../types/messages/restore-entry.js';
+import type { RawTextMessageInfo } from '../types/messages/text.js';
+import type { RawUpdateRelationshipMessageInfo } from '../types/messages/update-relationship.js';
import {
translateRawMessageInfoToClientDBMessageInfo,
translateClientDBMessageInfoToRawMessageInfo,
translateClientDBMediaInfosToMedia,
-} from './message-ops-utils';
+} from './message-ops-utils.js';
test('TEXT: rawMessageInfo -> clientDBMessageInfo -> rawMessageInfo', () => {
const rawTextMessageInfo: RawTextMessageInfo = {
diff --git a/lib/utils/objects.js b/lib/utils/objects.js
--- a/lib/utils/objects.js
+++ b/lib/utils/objects.js
@@ -2,8 +2,8 @@
import stableStringify from 'fast-json-stable-stringify';
import invariant from 'invariant';
-import _difference from 'lodash/fp/difference';
-import _isEqual from 'lodash/fp/isEqual';
+import _difference from 'lodash/fp/difference.js';
+import _isEqual from 'lodash/fp/isEqual.js';
import stringHash from 'string-hash';
type Map<K, T> = { +[key: K]: T };
diff --git a/lib/utils/redux-utils.js b/lib/utils/redux-utils.js
--- a/lib/utils/redux-utils.js
+++ b/lib/utils/redux-utils.js
@@ -2,7 +2,7 @@
import { useSelector as reactReduxUseSelector } from 'react-redux';
-import type { AppState } from '../types/redux-types';
+import type { AppState } from '../types/redux-types.js';
function useSelector<SS>(
selector: (state: AppState) => SS,
diff --git a/lib/utils/report-utils.js b/lib/utils/report-utils.js
--- a/lib/utils/report-utils.js
+++ b/lib/utils/report-utils.js
@@ -5,8 +5,8 @@
type EnabledReports,
type ClientReportCreationRequest,
reportTypes,
-} from '../types/report-types';
-import { useSelector } from './redux-utils';
+} from '../types/report-types.js';
+import { useSelector } from './redux-utils.js';
function useIsReportEnabled(reportType: SupportedReports): boolean {
return useSelector(state => state.reportStore.enabledReports[reportType]);
diff --git a/lib/utils/sanitization.js b/lib/utils/sanitization.js
--- a/lib/utils/sanitization.js
+++ b/lib/utils/sanitization.js
@@ -3,13 +3,13 @@
import clone from 'just-clone';
import stringHash from 'string-hash';
-import { setDeviceTokenActionTypes } from '../actions/device-actions';
+import { setDeviceTokenActionTypes } from '../actions/device-actions.js';
import type {
BaseAction,
NativeAppState,
AppState,
-} from '../types/redux-types';
-import { setNewSessionActionType } from './action-utils';
+} from '../types/redux-types.js';
+import { setNewSessionActionType } from './action-utils.js';
export type ReduxCrashReport = {
+preloadedState: AppState,
diff --git a/lib/utils/thread-ops-utils.js b/lib/utils/thread-ops-utils.js
--- a/lib/utils/thread-ops-utils.js
+++ b/lib/utils/thread-ops-utils.js
@@ -6,7 +6,7 @@
type ClientDBThreadStoreOperation,
type RawThreadInfo,
assertThreadType,
-} from '../types/thread-types';
+} from '../types/thread-types.js';
function convertRawThreadInfoToClientDBThreadInfo(
rawThreadInfo: RawThreadInfo,
diff --git a/lib/utils/upload-blob.js b/lib/utils/upload-blob.js
--- a/lib/utils/upload-blob.js
+++ b/lib/utils/upload-blob.js
@@ -1,13 +1,13 @@
// @flow
import invariant from 'invariant';
-import _throttle from 'lodash/throttle';
+import _throttle from 'lodash/throttle.js';
import type {
CallServerEndpointOptions,
CallServerEndpointResponse,
-} from './call-server-endpoint';
-import { getConfig } from './config';
+} from './call-server-endpoint.js';
+import { getConfig } from './config.js';
function uploadBlob(
url: string,
diff --git a/lib/utils/url-utils.js b/lib/utils/url-utils.js
--- a/lib/utils/url-utils.js
+++ b/lib/utils/url-utils.js
@@ -2,7 +2,7 @@
import urlParseLax from 'url-parse-lax';
-import { pendingThreadIDRegex } from '../shared/thread-utils';
+import { pendingThreadIDRegex } from '../shared/thread-utils.js';
export type URLInfo = {
+year?: number,
diff --git a/lib/utils/validation-utils.js b/lib/utils/validation-utils.js
--- a/lib/utils/validation-utils.js
+++ b/lib/utils/validation-utils.js
@@ -14,7 +14,7 @@
validEmailRegex,
oldValidUsernameRegex,
validHexColorRegex,
-} from '../shared/account-utils';
+} from '../shared/account-utils.js';
function tBool(value: boolean): TIrreducible<boolean> {
return t.irreducible('literal bool', x => x === value);
diff --git a/lib/utils/validation-utils.test.js b/lib/utils/validation-utils.test.js
--- a/lib/utils/validation-utils.test.js
+++ b/lib/utils/validation-utils.test.js
@@ -1,12 +1,12 @@
// @flow
-import { threadTypes } from '../types/thread-types';
-import { values } from '../utils/objects';
+import { threadTypes } from '../types/thread-types.js';
+import { values } from '../utils/objects.js';
import {
tMediaMessagePhoto,
tMediaMessageVideo,
tNumEnum,
-} from './validation-utils';
+} from './validation-utils.js';
describe('Validation utils', () => {
describe('tNumEnum validator', () => {
diff --git a/native/__tests__/test.js b/native/__tests__/test.js
--- a/native/__tests__/test.js
+++ b/native/__tests__/test.js
@@ -4,7 +4,7 @@
import * as React from 'react';
import renderer from 'react-test-renderer';
-import Root from '../root.react';
+import Root from '../root.react.js';
// Note: test renderer must be required after react-native.
diff --git a/native/account/log-in-panel.react.js b/native/account/log-in-panel.react.js
--- a/native/account/log-in-panel.react.js
+++ b/native/account/log-in-panel.react.js
@@ -5,40 +5,40 @@
import { View, StyleSheet, Alert, Keyboard, Platform } from 'react-native';
import Animated from 'react-native-reanimated';
-import { logInActionTypes, logIn } from 'lib/actions/user-actions';
-import { createLoadingStatusSelector } from 'lib/selectors/loading-selectors';
+import { logInActionTypes, logIn } from 'lib/actions/user-actions.js';
+import { createLoadingStatusSelector } from 'lib/selectors/loading-selectors.js';
import {
validEmailRegex,
oldValidUsernameRegex,
-} from 'lib/shared/account-utils';
+} from 'lib/shared/account-utils.js';
import {
type LogInInfo,
type LogInExtraInfo,
type LogInResult,
type LogInStartingPayload,
logInActionSources,
-} from 'lib/types/account-types';
-import type { LoadingStatus } from 'lib/types/loading-types';
+} from 'lib/types/account-types.js';
+import type { LoadingStatus } from 'lib/types/loading-types.js';
import {
useServerCall,
useDispatchActionPromise,
type DispatchActionPromise,
-} from 'lib/utils/action-utils';
-
-import SWMansionIcon from '../components/swmansion-icon.react';
-import { commCoreModule } from '../native-modules';
-import { NavContext } from '../navigation/navigation-context';
-import { useSelector } from '../redux/redux-utils';
-import { nativeLogInExtraInfoSelector } from '../selectors/account-selectors';
-import type { KeyPressEvent } from '../types/react-native';
-import type { StateContainer } from '../utils/state-container';
-import { TextInput } from './modal-components.react';
+} from 'lib/utils/action-utils.js';
+
+import SWMansionIcon from '../components/swmansion-icon.react.js';
+import { commCoreModule } from '../native-modules.js';
+import { NavContext } from '../navigation/navigation-context.js';
+import { useSelector } from '../redux/redux-utils.js';
+import { nativeLogInExtraInfoSelector } from '../selectors/account-selectors.js';
+import type { KeyPressEvent } from '../types/react-native.js';
+import type { StateContainer } from '../utils/state-container.js';
+import { TextInput } from './modal-components.react.js';
import {
fetchNativeCredentials,
setNativeCredentials,
-} from './native-credentials';
-import { PanelButton, Panel } from './panel-components.react';
-import PasswordInput from './password-input.react';
+} from './native-credentials.js';
+import { PanelButton, Panel } from './panel-components.react.js';
+import PasswordInput from './password-input.react.js';
export type LogInState = {
+usernameInputText: ?string,
diff --git a/native/account/logged-out-modal.react.js b/native/account/logged-out-modal.react.js
--- a/native/account/logged-out-modal.react.js
+++ b/native/account/logged-out-modal.react.js
@@ -1,7 +1,7 @@
// @flow
-import Icon from '@expo/vector-icons/FontAwesome';
-import _isEqual from 'lodash/fp/isEqual';
+import Icon from '@expo/vector-icons/FontAwesome.js';
+import _isEqual from 'lodash/fp/isEqual.js';
import * as React from 'react';
import {
View,
@@ -17,49 +17,52 @@
import { SafeAreaView } from 'react-native-safe-area-context';
import { useDispatch } from 'react-redux';
-import { isLoggedIn } from 'lib/selectors/user-selectors';
-import { logInActionSources } from 'lib/types/account-types';
-import type { Dispatch } from 'lib/types/redux-types';
-import { fetchNewCookieFromNativeCredentials } from 'lib/utils/action-utils';
+import { isLoggedIn } from 'lib/selectors/user-selectors.js';
+import { logInActionSources } from 'lib/types/account-types.js';
+import type { Dispatch } from 'lib/types/redux-types.js';
+import { fetchNewCookieFromNativeCredentials } from 'lib/utils/action-utils.js';
import EthereumLogo from '../components/ethereum-logo.react.js';
-import KeyboardAvoidingView from '../components/keyboard-avoiding-view.react';
-import ConnectedStatusBar from '../connected-status-bar.react';
+import KeyboardAvoidingView from '../components/keyboard-avoiding-view.react.js';
+import ConnectedStatusBar from '../connected-status-bar.react.js';
import {
addKeyboardShowListener,
addKeyboardDismissListener,
removeKeyboardListener,
-} from '../keyboard/keyboard';
-import { createIsForegroundSelector } from '../navigation/nav-selectors';
-import { NavContext } from '../navigation/navigation-context';
-import { LoggedOutModalRouteName } from '../navigation/route-names';
-import { resetUserStateActionType } from '../redux/action-types';
-import { useSelector } from '../redux/redux-utils';
-import { usePersistedStateLoaded } from '../selectors/app-state-selectors';
+} from '../keyboard/keyboard.js';
+import { createIsForegroundSelector } from '../navigation/nav-selectors.js';
+import { NavContext } from '../navigation/navigation-context.js';
+import { LoggedOutModalRouteName } from '../navigation/route-names.js';
+import { resetUserStateActionType } from '../redux/action-types.js';
+import { useSelector } from '../redux/redux-utils.js';
+import { usePersistedStateLoaded } from '../selectors/app-state-selectors.js';
import {
type DerivedDimensionsInfo,
derivedDimensionsInfoSelector,
-} from '../selectors/dimensions-selectors';
-import { splashStyleSelector } from '../splash';
-import { useStyles } from '../themes/colors';
-import type { EventSubscription, KeyboardEvent } from '../types/react-native';
-import type { ImageStyle } from '../types/styles';
+} from '../selectors/dimensions-selectors.js';
+import { splashStyleSelector } from '../splash.js';
+import { useStyles } from '../themes/colors.js';
+import type {
+ EventSubscription,
+ KeyboardEvent,
+} from '../types/react-native.js';
+import type { ImageStyle } from '../types/styles.js';
import {
runTiming,
ratchetAlongWithKeyboardHeight,
-} from '../utils/animation-utils';
+} from '../utils/animation-utils.js';
import {
type StateContainer,
type StateChange,
setStateForContainer,
-} from '../utils/state-container';
-import { splashBackgroundURI } from './background-info';
-import LogInPanel from './log-in-panel.react';
-import type { LogInState } from './log-in-panel.react';
-import LoggedOutStaffInfo from './logged-out-staff-info.react';
-import RegisterPanel from './register-panel.react';
-import type { RegisterState } from './register-panel.react';
-import SIWEPanel from './siwe-panel.react';
+} from '../utils/state-container.js';
+import { splashBackgroundURI } from './background-info.js';
+import LogInPanel from './log-in-panel.react.js';
+import type { LogInState } from './log-in-panel.react.js';
+import LoggedOutStaffInfo from './logged-out-staff-info.react.js';
+import RegisterPanel from './register-panel.react.js';
+import type { RegisterState } from './register-panel.react.js';
+import SIWEPanel from './siwe-panel.react.js';
let initialAppLoad = true;
const safeAreaEdges = ['top', 'bottom'];
diff --git a/native/account/logged-out-staff-info.react.js b/native/account/logged-out-staff-info.react.js
--- a/native/account/logged-out-staff-info.react.js
+++ b/native/account/logged-out-staff-info.react.js
@@ -3,10 +3,10 @@
import * as React from 'react';
import { Text, View } from 'react-native';
-import SWMansionIcon from '../components/swmansion-icon.react';
-import { StaffContext } from '../staff/staff-context';
-import { useStyles, useColors } from '../themes/colors';
-import { isStaffRelease, useStaffCanSee } from '../utils/staff-utils';
+import SWMansionIcon from '../components/swmansion-icon.react.js';
+import { StaffContext } from '../staff/staff-context.js';
+import { useStyles, useColors } from '../themes/colors.js';
+import { isStaffRelease, useStaffCanSee } from '../utils/staff-utils.js';
function LoggedOutStaffInfo(): React.Node {
const staffCanSee = useStaffCanSee();
diff --git a/native/account/modal-components.react.js b/native/account/modal-components.react.js
--- a/native/account/modal-components.react.js
+++ b/native/account/modal-components.react.js
@@ -4,7 +4,7 @@
import * as React from 'react';
import { TextInput as BaseTextInput, View, StyleSheet } from 'react-native';
-import CoreTextInput from '../components/text-input.react';
+import CoreTextInput from '../components/text-input.react.js';
type Props = React.ElementConfig<typeof BaseTextInput>;
class TextInput extends React.PureComponent<Props> {
diff --git a/native/account/panel-components.react.js b/native/account/panel-components.react.js
--- a/native/account/panel-components.react.js
+++ b/native/account/panel-components.react.js
@@ -1,6 +1,6 @@
// @flow
-import Icon from '@expo/vector-icons/FontAwesome';
+import Icon from '@expo/vector-icons/FontAwesome.js';
import * as React from 'react';
import {
View,
@@ -11,11 +11,11 @@
} from 'react-native';
import Animated from 'react-native-reanimated';
-import type { LoadingStatus } from 'lib/types/loading-types';
+import type { LoadingStatus } from 'lib/types/loading-types.js';
-import Button from '../components/button.react';
-import { useSelector } from '../redux/redux-utils';
-import type { ViewStyle } from '../types/styles';
+import Button from '../components/button.react.js';
+import { useSelector } from '../redux/redux-utils.js';
+import type { ViewStyle } from '../types/styles.js';
type ButtonProps = {
+text: string,
diff --git a/native/account/password-input.react.js b/native/account/password-input.react.js
--- a/native/account/password-input.react.js
+++ b/native/account/password-input.react.js
@@ -3,9 +3,9 @@
import * as React from 'react';
import { TextInput as BaseTextInput, View, StyleSheet } from 'react-native';
-import Button from '../components/button.react';
-import SWMansionIcon from '../components/swmansion-icon.react';
-import { TextInput } from './modal-components.react';
+import Button from '../components/button.react.js';
+import SWMansionIcon from '../components/swmansion-icon.react.js';
+import { TextInput } from './modal-components.react.js';
type Props = React.ElementConfig<typeof BaseTextInput>;
diff --git a/native/account/register-panel.react.js b/native/account/register-panel.react.js
--- a/native/account/register-panel.react.js
+++ b/native/account/register-panel.react.js
@@ -13,31 +13,31 @@
} from 'react-native';
import Animated from 'react-native-reanimated';
-import { registerActionTypes, register } from 'lib/actions/user-actions';
-import { createLoadingStatusSelector } from 'lib/selectors/loading-selectors';
-import { validUsernameRegex } from 'lib/shared/account-utils';
+import { registerActionTypes, register } from 'lib/actions/user-actions.js';
+import { createLoadingStatusSelector } from 'lib/selectors/loading-selectors.js';
+import { validUsernameRegex } from 'lib/shared/account-utils.js';
import type {
RegisterInfo,
LogInExtraInfo,
RegisterResult,
LogInStartingPayload,
-} from 'lib/types/account-types';
-import type { LoadingStatus } from 'lib/types/loading-types';
+} from 'lib/types/account-types.js';
+import type { LoadingStatus } from 'lib/types/loading-types.js';
import {
useServerCall,
useDispatchActionPromise,
type DispatchActionPromise,
-} from 'lib/utils/action-utils';
-
-import SWMansionIcon from '../components/swmansion-icon.react';
-import { NavContext } from '../navigation/navigation-context';
-import { useSelector } from '../redux/redux-utils';
-import { nativeLogInExtraInfoSelector } from '../selectors/account-selectors';
-import type { KeyPressEvent } from '../types/react-native';
-import { type StateContainer } from '../utils/state-container';
-import { TextInput } from './modal-components.react';
-import { setNativeCredentials } from './native-credentials';
-import { PanelButton, Panel } from './panel-components.react';
+} from 'lib/utils/action-utils.js';
+
+import SWMansionIcon from '../components/swmansion-icon.react.js';
+import { NavContext } from '../navigation/navigation-context.js';
+import { useSelector } from '../redux/redux-utils.js';
+import { nativeLogInExtraInfoSelector } from '../selectors/account-selectors.js';
+import type { KeyPressEvent } from '../types/react-native.js';
+import { type StateContainer } from '../utils/state-container.js';
+import { TextInput } from './modal-components.react.js';
+import { setNativeCredentials } from './native-credentials.js';
+import { PanelButton, Panel } from './panel-components.react.js';
export type RegisterState = {
+usernameInputText: string,
diff --git a/native/account/resolve-invalidated-cookie.js b/native/account/resolve-invalidated-cookie.js
--- a/native/account/resolve-invalidated-cookie.js
+++ b/native/account/resolve-invalidated-cookie.js
@@ -1,14 +1,14 @@
// @flow
-import { logInActionTypes, logIn } from 'lib/actions/user-actions';
-import type { LogInActionSource } from 'lib/types/account-types';
-import type { DispatchRecoveryAttempt } from 'lib/utils/action-utils';
-import type { CallServerEndpoint } from 'lib/utils/call-server-endpoint';
+import { logInActionTypes, logIn } from 'lib/actions/user-actions.js';
+import type { LogInActionSource } from 'lib/types/account-types.js';
+import type { DispatchRecoveryAttempt } from 'lib/utils/action-utils.js';
+import type { CallServerEndpoint } from 'lib/utils/call-server-endpoint.js';
-import { getGlobalNavContext } from '../navigation/icky-global';
-import { store } from '../redux/redux-setup';
-import { nativeLogInExtraInfoSelector } from '../selectors/account-selectors';
-import { fetchNativeKeychainCredentials } from './native-credentials';
+import { getGlobalNavContext } from '../navigation/icky-global.js';
+import { store } from '../redux/redux-setup.js';
+import { nativeLogInExtraInfoSelector } from '../selectors/account-selectors.js';
+import { fetchNativeKeychainCredentials } from './native-credentials.js';
async function resolveInvalidatedCookie(
callServerEndpoint: CallServerEndpoint,
diff --git a/native/account/siwe-panel.react.js b/native/account/siwe-panel.react.js
--- a/native/account/siwe-panel.react.js
+++ b/native/account/siwe-panel.react.js
@@ -11,21 +11,21 @@
getSIWENonceActionTypes,
siweAuth,
siweAuthActionTypes,
-} from 'lib/actions/siwe-actions';
-import { createLoadingStatusSelector } from 'lib/selectors/loading-selectors';
-import type { LogInStartingPayload } from 'lib/types/account-types';
-import type { SIWEWebViewMessage } from 'lib/types/siwe-types';
+} from 'lib/actions/siwe-actions.js';
+import { createLoadingStatusSelector } from 'lib/selectors/loading-selectors.js';
+import type { LogInStartingPayload } from 'lib/types/account-types.js';
+import type { SIWEWebViewMessage } from 'lib/types/siwe-types.js';
import {
useServerCall,
useDispatchActionPromise,
-} from 'lib/utils/action-utils';
+} from 'lib/utils/action-utils.js';
-import { commCoreModule } from '../native-modules';
-import { NavContext } from '../navigation/navigation-context';
-import { useSelector } from '../redux/redux-utils';
-import { nativeLogInExtraInfoSelector } from '../selectors/account-selectors';
-import { defaultLandingURLPrefix } from '../utils/url-utils';
-import type { LoggedOutMode } from './logged-out-modal.react';
+import { commCoreModule } from '../native-modules.js';
+import { NavContext } from '../navigation/navigation-context.js';
+import { useSelector } from '../redux/redux-utils.js';
+import { nativeLogInExtraInfoSelector } from '../selectors/account-selectors.js';
+import { defaultLandingURLPrefix } from '../utils/url-utils.js';
+import type { LoggedOutMode } from './logged-out-modal.react.js';
const commSIWE = `${defaultLandingURLPrefix}/siwe`;
diff --git a/native/account/terms-and-privacy-modal.react.js b/native/account/terms-and-privacy-modal.react.js
--- a/native/account/terms-and-privacy-modal.react.js
+++ b/native/account/terms-and-privacy-modal.react.js
@@ -14,21 +14,21 @@
import {
policyAcknowledgment,
policyAcknowledgmentActionTypes,
-} from 'lib/actions/user-actions';
-import { type PolicyType, policyTypes } from 'lib/facts/policies';
-import { createLoadingStatusSelector } from 'lib/selectors/loading-selectors';
+} from 'lib/actions/user-actions.js';
+import { type PolicyType, policyTypes } from 'lib/facts/policies.js';
+import { createLoadingStatusSelector } from 'lib/selectors/loading-selectors.js';
import {
useDispatchActionPromise,
useServerCall,
-} from 'lib/utils/action-utils';
-import { acknowledgePolicy } from 'lib/utils/policy-acknowledge-utlis';
-
-import Button from '../components/button.react';
-import Modal from '../components/modal.react';
-import type { RootNavigationProp } from '../navigation/root-navigator.react';
-import type { NavigationRoute } from '../navigation/route-names';
-import { useSelector } from '../redux/redux-utils';
-import { useStyles } from '../themes/colors';
+} from 'lib/utils/action-utils.js';
+import { acknowledgePolicy } from 'lib/utils/policy-acknowledge-utlis.js';
+
+import Button from '../components/button.react.js';
+import Modal from '../components/modal.react.js';
+import type { RootNavigationProp } from '../navigation/root-navigator.react.js';
+import type { NavigationRoute } from '../navigation/route-names.js';
+import { useSelector } from '../redux/redux-utils.js';
+import { useStyles } from '../themes/colors.js';
export type TermsAndPrivacyModalParams = {
+policyType: PolicyType,
diff --git a/native/apps/app-listing.react.js b/native/apps/app-listing.react.js
--- a/native/apps/app-listing.react.js
+++ b/native/apps/app-listing.react.js
@@ -7,11 +7,11 @@
import {
disableAppActionType,
enableAppActionType,
-} from 'lib/reducers/enabled-apps-reducer';
-import type { SupportedApps } from 'lib/types/enabled-apps';
+} from 'lib/reducers/enabled-apps-reducer.js';
+import type { SupportedApps } from 'lib/types/enabled-apps.js';
-import SWMansionIcon from '../components/swmansion-icon.react';
-import { useColors, useStyles } from '../themes/colors';
+import SWMansionIcon from '../components/swmansion-icon.react.js';
+import { useColors, useStyles } from '../themes/colors.js';
type Props = {
+id: SupportedApps | 'chat',
diff --git a/native/apps/apps-directory.react.js b/native/apps/apps-directory.react.js
--- a/native/apps/apps-directory.react.js
+++ b/native/apps/apps-directory.react.js
@@ -4,8 +4,8 @@
import { Text, FlatList, View } from 'react-native';
import { useSelector } from 'react-redux';
-import { useStyles } from '../themes/colors';
-import AppListing from './app-listing.react';
+import { useStyles } from '../themes/colors.js';
+import AppListing from './app-listing.react.js';
const APP_DIRECTORY_DATA = [
{
diff --git a/native/calendar/calendar-input-bar.react.js b/native/calendar/calendar-input-bar.react.js
--- a/native/calendar/calendar-input-bar.react.js
+++ b/native/calendar/calendar-input-bar.react.js
@@ -3,8 +3,8 @@
import * as React from 'react';
import { View, Text } from 'react-native';
-import Button from '../components/button.react';
-import { useStyles } from '../themes/colors';
+import Button from '../components/button.react.js';
+import { useStyles } from '../themes/colors.js';
type Props = {
+onSave: () => void,
diff --git a/native/calendar/calendar.react.js b/native/calendar/calendar.react.js
--- a/native/calendar/calendar.react.js
+++ b/native/calendar/calendar.react.js
@@ -1,14 +1,14 @@
// @flow
import invariant from 'invariant';
-import _filter from 'lodash/fp/filter';
-import _find from 'lodash/fp/find';
-import _findIndex from 'lodash/fp/findIndex';
-import _map from 'lodash/fp/map';
-import _pickBy from 'lodash/fp/pickBy';
-import _size from 'lodash/fp/size';
-import _sum from 'lodash/fp/sum';
-import _throttle from 'lodash/throttle';
+import _filter from 'lodash/fp/filter.js';
+import _find from 'lodash/fp/find.js';
+import _findIndex from 'lodash/fp/findIndex.js';
+import _map from 'lodash/fp/map.js';
+import _pickBy from 'lodash/fp/pickBy.js';
+import _size from 'lodash/fp/size.js';
+import _sum from 'lodash/fp/sum.js';
+import _throttle from 'lodash/throttle.js';
import * as React from 'react';
import {
View,
@@ -23,79 +23,83 @@
import {
updateCalendarQueryActionTypes,
updateCalendarQuery,
-} from 'lib/actions/entry-actions';
-import { createLoadingStatusSelector } from 'lib/selectors/loading-selectors';
-import { entryKey } from 'lib/shared/entry-utils';
+} from 'lib/actions/entry-actions.js';
+import { createLoadingStatusSelector } from 'lib/selectors/loading-selectors.js';
+import { entryKey } from 'lib/shared/entry-utils.js';
import type {
EntryInfo,
CalendarQuery,
CalendarQueryUpdateResult,
-} from 'lib/types/entry-types';
-import type { CalendarFilter } from 'lib/types/filter-types';
-import type { LoadingStatus } from 'lib/types/loading-types';
-import type { ConnectionStatus } from 'lib/types/socket-types';
-import type { ThreadInfo } from 'lib/types/thread-types';
+} from 'lib/types/entry-types.js';
+import type { CalendarFilter } from 'lib/types/filter-types.js';
+import type { LoadingStatus } from 'lib/types/loading-types.js';
+import type { ConnectionStatus } from 'lib/types/socket-types.js';
+import type { ThreadInfo } from 'lib/types/thread-types.js';
import {
useServerCall,
useDispatchActionPromise,
type DispatchActionPromise,
-} from 'lib/utils/action-utils';
-import { dateString, prettyDate, dateFromString } from 'lib/utils/date-utils';
-import sleep from 'lib/utils/sleep';
-
-import ContentLoading from '../components/content-loading.react';
-import KeyboardAvoidingView from '../components/keyboard-avoiding-view.react';
-import ListLoadingIndicator from '../components/list-loading-indicator.react';
-import NodeHeightMeasurer from '../components/node-height-measurer.react';
+} from 'lib/utils/action-utils.js';
+import {
+ dateString,
+ prettyDate,
+ dateFromString,
+} from 'lib/utils/date-utils.js';
+import sleep from 'lib/utils/sleep.js';
+
+import ContentLoading from '../components/content-loading.react.js';
+import KeyboardAvoidingView from '../components/keyboard-avoiding-view.react.js';
+import ListLoadingIndicator from '../components/list-loading-indicator.react.js';
+import NodeHeightMeasurer from '../components/node-height-measurer.react.js';
import {
addKeyboardShowListener,
addKeyboardDismissListener,
removeKeyboardListener,
-} from '../keyboard/keyboard';
-import DisconnectedBar from '../navigation/disconnected-bar.react';
+} from '../keyboard/keyboard.js';
+import DisconnectedBar from '../navigation/disconnected-bar.react.js';
import {
createIsForegroundSelector,
createActiveTabSelector,
-} from '../navigation/nav-selectors';
-import { NavContext } from '../navigation/navigation-context';
+} from '../navigation/nav-selectors.js';
+import { NavContext } from '../navigation/navigation-context.js';
import {
CalendarRouteName,
ThreadPickerModalRouteName,
-} from '../navigation/route-names';
-import type { NavigationRoute } from '../navigation/route-names';
-import type { TabNavigationProp } from '../navigation/tab-navigator.react';
-import { useSelector } from '../redux/redux-utils';
-import { calendarListData } from '../selectors/calendar-selectors';
+} from '../navigation/route-names.js';
+import type { NavigationRoute } from '../navigation/route-names.js';
+import type { TabNavigationProp } from '../navigation/tab-navigator.react.js';
+import { useSelector } from '../redux/redux-utils.js';
+import { calendarListData } from '../selectors/calendar-selectors.js';
import type {
CalendarItem,
SectionHeaderItem,
SectionFooterItem,
LoaderItem,
-} from '../selectors/calendar-selectors';
+} from '../selectors/calendar-selectors.js';
import {
type DerivedDimensionsInfo,
derivedDimensionsInfoSelector,
-} from '../selectors/dimensions-selectors';
+} from '../selectors/dimensions-selectors.js';
import {
useColors,
useStyles,
useIndicatorStyle,
type Colors,
type IndicatorStyle,
-} from '../themes/colors';
+} from '../themes/colors.js';
import type {
EventSubscription,
ScrollEvent,
ViewableItemsChange,
KeyboardEvent,
-} from '../types/react-native';
-import CalendarInputBar from './calendar-input-bar.react';
+} from '../types/react-native.js';
+import CalendarInputBar from './calendar-input-bar.react.js';
import {
Entry,
InternalEntry,
dummyNodeForEntryHeightMeasurement,
-} from './entry.react';
-import SectionFooter from './section-footer.react';
+} from './entry.react.js';
+import SectionFooter from './section-footer.react.js';
export type EntryInfoWithHeight = {
...EntryInfo,
diff --git a/native/calendar/entry.react.js b/native/calendar/entry.react.js
--- a/native/calendar/entry.react.js
+++ b/native/calendar/entry.react.js
@@ -1,9 +1,9 @@
// @flow
-import Icon from '@expo/vector-icons/FontAwesome';
+import Icon from '@expo/vector-icons/FontAwesome.js';
import invariant from 'invariant';
-import _isEqual from 'lodash/fp/isEqual';
-import _omit from 'lodash/fp/omit';
+import _isEqual from 'lodash/fp/isEqual.js';
+import _omit from 'lodash/fp/omit.js';
import * as React from 'react';
import {
View,
@@ -27,11 +27,11 @@
deleteEntryActionTypes,
deleteEntry,
concurrentModificationResetActionType,
-} from 'lib/actions/entry-actions';
-import { registerFetchKey } from 'lib/reducers/loading-reducer';
-import { entryKey } from 'lib/shared/entry-utils';
-import { colorIsDark, threadHasPermission } from 'lib/shared/thread-utils';
-import type { Shape } from 'lib/types/core';
+} from 'lib/actions/entry-actions.js';
+import { registerFetchKey } from 'lib/reducers/loading-reducer.js';
+import { entryKey } from 'lib/shared/entry-utils.js';
+import { colorIsDark, threadHasPermission } from 'lib/shared/thread-utils.js';
+import type { Shape } from 'lib/types/core.js';
import type {
CreateEntryInfo,
SaveEntryInfo,
@@ -41,46 +41,46 @@
DeleteEntryInfo,
DeleteEntryResult,
CalendarQuery,
-} from 'lib/types/entry-types';
-import type { LoadingStatus } from 'lib/types/loading-types';
-import type { Dispatch } from 'lib/types/redux-types';
+} from 'lib/types/entry-types.js';
+import type { LoadingStatus } from 'lib/types/loading-types.js';
+import type { Dispatch } from 'lib/types/redux-types.js';
import {
type ThreadInfo,
type ResolvedThreadInfo,
threadPermissions,
-} from 'lib/types/thread-types';
+} from 'lib/types/thread-types.js';
import {
useServerCall,
useDispatchActionPromise,
type DispatchActionPromise,
-} from 'lib/utils/action-utils';
-import { dateString } from 'lib/utils/date-utils';
-import { useResolvedThreadInfo } from 'lib/utils/entity-helpers';
-import { ServerError } from 'lib/utils/errors';
-import sleep from 'lib/utils/sleep';
+} from 'lib/utils/action-utils.js';
+import { dateString } from 'lib/utils/date-utils.js';
+import { useResolvedThreadInfo } from 'lib/utils/entity-helpers.js';
+import { ServerError } from 'lib/utils/errors.js';
+import sleep from 'lib/utils/sleep.js';
import {
type MessageListParams,
useNavigateToThread,
-} from '../chat/message-list-types';
-import Button from '../components/button.react';
-import { SingleLine } from '../components/single-line.react';
-import TextInput from '../components/text-input.react';
-import Markdown from '../markdown/markdown.react';
-import { inlineMarkdownRules } from '../markdown/rules.react';
+} from '../chat/message-list-types.js';
+import Button from '../components/button.react.js';
+import { SingleLine } from '../components/single-line.react.js';
+import TextInput from '../components/text-input.react.js';
+import Markdown from '../markdown/markdown.react.js';
+import { inlineMarkdownRules } from '../markdown/rules.react.js';
import {
createIsForegroundSelector,
nonThreadCalendarQuery,
-} from '../navigation/nav-selectors';
-import { NavContext } from '../navigation/navigation-context';
-import { ThreadPickerModalRouteName } from '../navigation/route-names';
-import type { TabNavigationProp } from '../navigation/tab-navigator.react';
-import { useSelector } from '../redux/redux-utils';
-import { colors, useStyles } from '../themes/colors';
-import type { LayoutEvent } from '../types/react-native';
-import { waitForInteractions } from '../utils/timers';
-import type { EntryInfoWithHeight } from './calendar.react';
-import LoadingIndicator from './loading-indicator.react';
+} from '../navigation/nav-selectors.js';
+import { NavContext } from '../navigation/navigation-context.js';
+import { ThreadPickerModalRouteName } from '../navigation/route-names.js';
+import type { TabNavigationProp } from '../navigation/tab-navigator.react.js';
+import { useSelector } from '../redux/redux-utils.js';
+import { colors, useStyles } from '../themes/colors.js';
+import type { LayoutEvent } from '../types/react-native.js';
+import { waitForInteractions } from '../utils/timers.js';
+import type { EntryInfoWithHeight } from './calendar.react.js';
+import LoadingIndicator from './loading-indicator.react.js';
function hueDistance(firstColor: string, secondColor: string): number {
const firstHue = tinycolor(firstColor).toHsv().h;
diff --git a/native/calendar/loading-indicator.react.js b/native/calendar/loading-indicator.react.js
--- a/native/calendar/loading-indicator.react.js
+++ b/native/calendar/loading-indicator.react.js
@@ -1,10 +1,10 @@
// @flow
-import Icon from '@expo/vector-icons/Feather';
+import Icon from '@expo/vector-icons/Feather.js';
import * as React from 'react';
import { ActivityIndicator, StyleSheet, Platform } from 'react-native';
-import type { LoadingStatus } from 'lib/types/loading-types';
+import type { LoadingStatus } from 'lib/types/loading-types.js';
type Props = {
+loadingStatus: LoadingStatus,
diff --git a/native/calendar/section-footer.react.js b/native/calendar/section-footer.react.js
--- a/native/calendar/section-footer.react.js
+++ b/native/calendar/section-footer.react.js
@@ -3,9 +3,9 @@
import * as React from 'react';
import { View, Text, TouchableWithoutFeedback } from 'react-native';
-import Button from '../components/button.react';
-import SWMansionIcon from '../components/swmansion-icon.react';
-import { type Colors, useStyles, useColors } from '../themes/colors';
+import Button from '../components/button.react.js';
+import SWMansionIcon from '../components/swmansion-icon.react.js';
+import { type Colors, useStyles, useColors } from '../themes/colors.js';
type BaseProps = {
+dateString: string,
diff --git a/native/calendar/thread-picker-modal.react.js b/native/calendar/thread-picker-modal.react.js
--- a/native/calendar/thread-picker-modal.react.js
+++ b/native/calendar/thread-picker-modal.react.js
@@ -8,17 +8,17 @@
import {
createLocalEntry,
createLocalEntryActionType,
-} from 'lib/actions/entry-actions';
-import { useGlobalThreadSearchIndex } from 'lib/selectors/nav-selectors';
-import { onScreenEntryEditableThreadInfos } from 'lib/selectors/thread-selectors';
+} from 'lib/actions/entry-actions.js';
+import { useGlobalThreadSearchIndex } from 'lib/selectors/nav-selectors.js';
+import { onScreenEntryEditableThreadInfos } from 'lib/selectors/thread-selectors.js';
-import Modal from '../components/modal.react';
-import ThreadList from '../components/thread-list.react';
-import { RootNavigatorContext } from '../navigation/root-navigator-context';
-import type { RootNavigationProp } from '../navigation/root-navigator.react';
-import type { NavigationRoute } from '../navigation/route-names';
-import { useSelector } from '../redux/redux-utils';
-import { waitForInteractions } from '../utils/timers';
+import Modal from '../components/modal.react.js';
+import ThreadList from '../components/thread-list.react.js';
+import { RootNavigatorContext } from '../navigation/root-navigator-context.js';
+import type { RootNavigationProp } from '../navigation/root-navigator.react.js';
+import type { NavigationRoute } from '../navigation/route-names.js';
+import { useSelector } from '../redux/redux-utils.js';
+import { waitForInteractions } from '../utils/timers.js';
export type ThreadPickerModalParams = {
+presentedFrom: string,
diff --git a/native/chat/background-chat-thread-list.react.js b/native/chat/background-chat-thread-list.react.js
--- a/native/chat/background-chat-thread-list.react.js
+++ b/native/chat/background-chat-thread-list.react.js
@@ -3,18 +3,18 @@
import * as React from 'react';
import { Text, View } from 'react-native';
-import { unreadBackgroundCount } from 'lib/selectors/thread-selectors';
+import { unreadBackgroundCount } from 'lib/selectors/thread-selectors.js';
import {
threadInBackgroundChatList,
emptyItemText,
-} from 'lib/shared/thread-utils';
+} from 'lib/shared/thread-utils.js';
-import BackgroundTabIllustration from '../components/background-tab-illustration.react';
-import type { NavigationRoute } from '../navigation/route-names';
-import { useSelector } from '../redux/redux-utils';
-import { useStyles } from '../themes/colors';
-import ChatThreadList from './chat-thread-list.react';
-import type { ChatTopTabsNavigationProp } from './chat.react';
+import BackgroundTabIllustration from '../components/background-tab-illustration.react.js';
+import type { NavigationRoute } from '../navigation/route-names.js';
+import { useSelector } from '../redux/redux-utils.js';
+import { useStyles } from '../themes/colors.js';
+import ChatThreadList from './chat-thread-list.react.js';
+import type { ChatTopTabsNavigationProp } from './chat.react.js';
type BackgroundChatThreadListProps = {
navigation: ChatTopTabsNavigationProp<'BackgroundChatThreadList'>,
diff --git a/native/chat/chat-context-provider.react.js b/native/chat/chat-context-provider.react.js
--- a/native/chat/chat-context-provider.react.js
+++ b/native/chat/chat-context-provider.react.js
@@ -2,13 +2,13 @@
import * as React from 'react';
-import type { ChatMessageItem } from 'lib/selectors/chat-selectors';
-import type { ThreadInfo } from 'lib/types/thread-types';
+import type { ChatMessageItem } from 'lib/selectors/chat-selectors.js';
+import type { ThreadInfo } from 'lib/types/thread-types.js';
-import type { ChatMessageItemWithHeight } from '../types/chat-types';
-import { ChatContext } from './chat-context';
-import type { SidebarAnimationType } from './chat-context';
-import ChatItemHeightMeasurer from './chat-item-height-measurer.react';
+import type { ChatMessageItemWithHeight } from '../types/chat-types.js';
+import { ChatContext } from './chat-context.js';
+import type { SidebarAnimationType } from './chat-context.js';
+import ChatItemHeightMeasurer from './chat-item-height-measurer.react.js';
type Props = {
+children: React.Node,
diff --git a/native/chat/chat-context.js b/native/chat/chat-context.js
--- a/native/chat/chat-context.js
+++ b/native/chat/chat-context.js
@@ -3,11 +3,11 @@
import invariant from 'invariant';
import * as React from 'react';
-import type { ChatMessageItem } from 'lib/selectors/chat-selectors';
-import type { SetState } from 'lib/types/hook-types';
-import type { ThreadInfo } from 'lib/types/thread-types';
+import type { ChatMessageItem } from 'lib/selectors/chat-selectors.js';
+import type { SetState } from 'lib/types/hook-types.js';
+import type { ThreadInfo } from 'lib/types/thread-types.js';
-import type { ChatMessageItemWithHeight } from '../types/chat-types';
+import type { ChatMessageItemWithHeight } from '../types/chat-types.js';
export type MessagesMeasurer = (
?$ReadOnlyArray<ChatMessageItem>,
diff --git a/native/chat/chat-header.react.js b/native/chat/chat-header.react.js
--- a/native/chat/chat-header.react.js
+++ b/native/chat/chat-header.react.js
@@ -3,10 +3,10 @@
import type { StackHeaderProps } from '@react-navigation/stack';
import * as React from 'react';
-import Header from '../navigation/header.react';
-import { createActiveTabSelector } from '../navigation/nav-selectors';
-import { NavContext } from '../navigation/navigation-context';
-import { ChatRouteName } from '../navigation/route-names';
+import Header from '../navigation/header.react.js';
+import { createActiveTabSelector } from '../navigation/nav-selectors.js';
+import { NavContext } from '../navigation/navigation-context.js';
+import { ChatRouteName } from '../navigation/route-names.js';
const activeTabSelector = createActiveTabSelector(ChatRouteName);
diff --git a/native/chat/chat-input-bar.react.js b/native/chat/chat-input-bar.react.js
--- a/native/chat/chat-input-bar.react.js
+++ b/native/chat/chat-input-bar.react.js
@@ -1,8 +1,8 @@
// @flow
-import Icon from '@expo/vector-icons/Ionicons';
+import Icon from '@expo/vector-icons/Ionicons.js';
import invariant from 'invariant';
-import _throttle from 'lodash/throttle';
+import _throttle from 'lodash/throttle.js';
import * as React from 'react';
import {
View,
@@ -21,19 +21,19 @@
import {
moveDraftActionType,
updateDraftActionType,
-} from 'lib/actions/draft-actions';
+} from 'lib/actions/draft-actions.js';
import {
joinThreadActionTypes,
joinThread,
newThreadActionTypes,
-} from 'lib/actions/thread-actions';
-import { createLoadingStatusSelector } from 'lib/selectors/loading-selectors';
+} from 'lib/actions/thread-actions.js';
+import { createLoadingStatusSelector } from 'lib/selectors/loading-selectors.js';
import {
relativeMemberInfoSelectorForMembersOfThread,
userStoreSearchIndex,
-} from 'lib/selectors/user-selectors';
-import { localIDPrefix, trimMessage } from 'lib/shared/message-utils';
-import SearchIndex from 'lib/shared/search-index';
+} from 'lib/selectors/user-selectors.js';
+import { localIDPrefix, trimMessage } from 'lib/shared/message-utils.js';
+import SearchIndex from 'lib/shared/search-index.js';
import {
threadHasPermission,
viewerIsMember,
@@ -42,62 +42,62 @@
checkIfDefaultMembersAreVoiced,
draftKeyFromThreadID,
colorIsDark,
-} from 'lib/shared/thread-utils';
+} from 'lib/shared/thread-utils.js';
import {
getTypeaheadUserSuggestions,
getTypeaheadRegexMatches,
type Selection,
-} from 'lib/shared/typeahead-utils';
-import type { CalendarQuery } from 'lib/types/entry-types';
-import type { LoadingStatus } from 'lib/types/loading-types';
-import type { PhotoPaste } from 'lib/types/media-types';
-import { messageTypes } from 'lib/types/message-types';
-import type { Dispatch } from 'lib/types/redux-types';
+} from 'lib/shared/typeahead-utils.js';
+import type { CalendarQuery } from 'lib/types/entry-types.js';
+import type { LoadingStatus } from 'lib/types/loading-types.js';
+import type { PhotoPaste } from 'lib/types/media-types.js';
+import { messageTypes } from 'lib/types/message-types.js';
+import type { Dispatch } from 'lib/types/redux-types.js';
import {
type ThreadInfo,
threadPermissions,
type ClientThreadJoinRequest,
type ThreadJoinPayload,
-} from 'lib/types/thread-types';
-import type { RelativeMemberInfo } from 'lib/types/thread-types';
-import { type UserInfos } from 'lib/types/user-types';
+} from 'lib/types/thread-types.js';
+import type { RelativeMemberInfo } from 'lib/types/thread-types.js';
+import { type UserInfos } from 'lib/types/user-types.js';
import {
type DispatchActionPromise,
useServerCall,
useDispatchActionPromise,
-} from 'lib/utils/action-utils';
-
-import Button from '../components/button.react';
-import ClearableTextInput from '../components/clearable-text-input.react';
-import type { SyncedSelectionData } from '../components/selectable-text-input';
-import SelectableTextInput from '../components/selectable-text-input.react';
-import SWMansionIcon from '../components/swmansion-icon.react';
-import { type InputState, InputStateContext } from '../input/input-state';
-import { getKeyboardHeight } from '../keyboard/keyboard';
-import KeyboardInputHost from '../keyboard/keyboard-input-host.react';
+} from 'lib/utils/action-utils.js';
+
+import Button from '../components/button.react.js';
+import ClearableTextInput from '../components/clearable-text-input.react.js';
+import type { SyncedSelectionData } from '../components/selectable-text-input.js';
+import SelectableTextInput from '../components/selectable-text-input.react.js';
+import SWMansionIcon from '../components/swmansion-icon.react.js';
+import { type InputState, InputStateContext } from '../input/input-state.js';
+import KeyboardInputHost from '../keyboard/keyboard-input-host.react.js';
import {
type KeyboardState,
KeyboardContext,
-} from '../keyboard/keyboard-state';
+} from '../keyboard/keyboard-state.js';
+import { getKeyboardHeight } from '../keyboard/keyboard.js';
import {
nonThreadCalendarQuery,
activeThreadSelector,
-} from '../navigation/nav-selectors';
-import { NavContext } from '../navigation/navigation-context';
+} from '../navigation/nav-selectors.js';
+import { NavContext } from '../navigation/navigation-context.js';
import {
type NavigationRoute,
CameraModalRouteName,
ImagePasteModalRouteName,
-} from '../navigation/route-names';
-import { useSelector } from '../redux/redux-utils';
-import { type Colors, useStyles, useColors } from '../themes/colors';
-import type { LayoutEvent } from '../types/react-native';
-import { type AnimatedViewStyle, AnimatedView } from '../types/styles';
-import { runTiming } from '../utils/animation-utils';
-import { nativeTypeaheadRegex } from '../utils/typeahead-utils';
-import { ChatContext } from './chat-context';
-import type { ChatNavigationProp } from './chat.react';
-import TypeaheadTooltip from './typeahead-tooltip.react';
+} from '../navigation/route-names.js';
+import { useSelector } from '../redux/redux-utils.js';
+import { type Colors, useStyles, useColors } from '../themes/colors.js';
+import type { LayoutEvent } from '../types/react-native.js';
+import { type AnimatedViewStyle, AnimatedView } from '../types/styles.js';
+import { runTiming } from '../utils/animation-utils.js';
+import { nativeTypeaheadRegex } from '../utils/typeahead-utils.js';
+import { ChatContext } from './chat-context.js';
+import type { ChatNavigationProp } from './chat.react.js';
+import TypeaheadTooltip from './typeahead-tooltip.react.js';
/* eslint-disable import/no-named-as-default-member */
const {
diff --git a/native/chat/chat-item-height-measurer.react.js b/native/chat/chat-item-height-measurer.react.js
--- a/native/chat/chat-item-height-measurer.react.js
+++ b/native/chat/chat-item-height-measurer.react.js
@@ -3,20 +3,20 @@
import invariant from 'invariant';
import * as React from 'react';
-import type { ChatMessageItem } from 'lib/selectors/chat-selectors';
-import { messageID } from 'lib/shared/message-utils';
-import { messageTypes, type MessageType } from 'lib/types/message-types';
-import { entityTextToRawString } from 'lib/utils/entity-text';
+import type { ChatMessageItem } from 'lib/selectors/chat-selectors.js';
+import { messageID } from 'lib/shared/message-utils.js';
+import { messageTypes, type MessageType } from 'lib/types/message-types.js';
+import { entityTextToRawString } from 'lib/utils/entity-text.js';
-import NodeHeightMeasurer from '../components/node-height-measurer.react';
-import { InputStateContext } from '../input/input-state';
-import type { MeasurementTask } from './chat-context-provider.react';
-import { useComposedMessageMaxWidth } from './composed-message-width';
-import { dummyNodeForRobotextMessageHeightMeasurement } from './inner-robotext-message.react';
-import { dummyNodeForTextMessageHeightMeasurement } from './inner-text-message.react';
-import { MessageListContextProvider } from './message-list-types';
-import { multimediaMessageContentSizes } from './multimedia-message-utils';
-import { chatMessageItemKey } from './utils';
+import NodeHeightMeasurer from '../components/node-height-measurer.react.js';
+import { InputStateContext } from '../input/input-state.js';
+import type { MeasurementTask } from './chat-context-provider.react.js';
+import { useComposedMessageMaxWidth } from './composed-message-width.js';
+import { dummyNodeForRobotextMessageHeightMeasurement } from './inner-robotext-message.react.js';
+import { dummyNodeForTextMessageHeightMeasurement } from './inner-text-message.react.js';
+import { MessageListContextProvider } from './message-list-types.js';
+import { multimediaMessageContentSizes } from './multimedia-message-utils.js';
+import { chatMessageItemKey } from './utils.js';
type Props = {
+measurement: MeasurementTask,
diff --git a/native/chat/chat-list.react.js b/native/chat/chat-list.react.js
--- a/native/chat/chat-list.react.js
+++ b/native/chat/chat-list.react.js
@@ -1,7 +1,7 @@
// @flow
import invariant from 'invariant';
-import _sum from 'lodash/fp/sum';
+import _sum from 'lodash/fp/sum.js';
import * as React from 'react';
import {
Animated,
@@ -13,20 +13,20 @@
} from 'react-native';
import { FlatList } from 'react-native-gesture-handler';
-import { localIDPrefix } from 'lib/shared/message-utils';
+import { localIDPrefix } from 'lib/shared/message-utils.js';
import {
type KeyboardState,
KeyboardContext,
-} from '../keyboard/keyboard-state';
-import type { TabNavigationProp } from '../navigation/tab-navigator.react';
-import { useSelector } from '../redux/redux-utils';
-import type { ChatMessageItemWithHeight } from '../types/chat-types';
-import type { ScrollEvent } from '../types/react-native';
-import type { ViewStyle } from '../types/styles';
-import type { ChatNavigationProp } from './chat.react';
-import NewMessagesPill from './new-messages-pill.react';
-import { chatMessageItemHeight, chatMessageItemKey } from './utils';
+} from '../keyboard/keyboard-state.js';
+import type { TabNavigationProp } from '../navigation/tab-navigator.react.js';
+import { useSelector } from '../redux/redux-utils.js';
+import type { ChatMessageItemWithHeight } from '../types/chat-types.js';
+import type { ScrollEvent } from '../types/react-native.js';
+import type { ViewStyle } from '../types/styles.js';
+import type { ChatNavigationProp } from './chat.react.js';
+import NewMessagesPill from './new-messages-pill.react.js';
+import { chatMessageItemHeight, chatMessageItemKey } from './utils.js';
type FlatListElementRef = React.ElementRef<typeof ReactNativeFlatList>;
type FlatListProps = React.ElementConfig<typeof ReactNativeFlatList>;
diff --git a/native/chat/chat-router.js b/native/chat/chat-router.js
--- a/native/chat/chat-router.js
+++ b/native/chat/chat-router.js
@@ -11,23 +11,23 @@
} from '@react-navigation/native';
import { StackRouter, CommonActions } from '@react-navigation/native';
-import type { ThreadInfo } from 'lib/types/thread-types';
+import type { ThreadInfo } from 'lib/types/thread-types.js';
import {
clearScreensActionType,
replaceWithThreadActionType,
clearThreadsActionType,
pushNewThreadActionType,
-} from '../navigation/action-types';
+} from '../navigation/action-types.js';
import {
removeScreensFromStack,
getThreadIDFromRoute,
-} from '../navigation/navigation-utils';
+} from '../navigation/navigation-utils.js';
import {
ChatThreadListRouteName,
ComposeSubchannelRouteName,
-} from '../navigation/route-names';
-import { createNavigateToThreadAction } from './message-list-types';
+} from '../navigation/route-names.js';
+import { createNavigateToThreadAction } from './message-list-types.js';
type ClearScreensAction = {
+type: 'CLEAR_SCREENS',
diff --git a/native/chat/chat-thread-list-item.react.js b/native/chat/chat-thread-list-item.react.js
--- a/native/chat/chat-thread-list-item.react.js
+++ b/native/chat/chat-thread-list-item.react.js
@@ -3,22 +3,22 @@
import * as React from 'react';
import { Text, View } from 'react-native';
-import type { ChatThreadItem } from 'lib/selectors/chat-selectors';
-import type { ThreadInfo } from 'lib/types/thread-types';
-import type { UserInfo } from 'lib/types/user-types';
-import { shortAbsoluteDate } from 'lib/utils/date-utils';
-import { useResolvedThreadInfo } from 'lib/utils/entity-helpers';
+import type { ChatThreadItem } from 'lib/selectors/chat-selectors.js';
+import type { ThreadInfo } from 'lib/types/thread-types.js';
+import type { UserInfo } from 'lib/types/user-types.js';
+import { shortAbsoluteDate } from 'lib/utils/date-utils.js';
+import { useResolvedThreadInfo } from 'lib/utils/entity-helpers.js';
-import Button from '../components/button.react';
-import ColorSplotch from '../components/color-splotch.react';
-import { SingleLine } from '../components/single-line.react';
-import ThreadAncestorsLabel from '../components/thread-ancestors-label.react';
-import UnreadDot from '../components/unread-dot.react';
-import { useColors, useStyles } from '../themes/colors';
-import ChatThreadListSeeMoreSidebars from './chat-thread-list-see-more-sidebars.react';
-import ChatThreadListSidebar from './chat-thread-list-sidebar.react';
-import MessagePreview from './message-preview.react';
-import SwipeableThread from './swipeable-thread.react';
+import Button from '../components/button.react.js';
+import ColorSplotch from '../components/color-splotch.react.js';
+import { SingleLine } from '../components/single-line.react.js';
+import ThreadAncestorsLabel from '../components/thread-ancestors-label.react.js';
+import UnreadDot from '../components/unread-dot.react.js';
+import { useColors, useStyles } from '../themes/colors.js';
+import ChatThreadListSeeMoreSidebars from './chat-thread-list-see-more-sidebars.react.js';
+import ChatThreadListSidebar from './chat-thread-list-sidebar.react.js';
+import MessagePreview from './message-preview.react.js';
+import SwipeableThread from './swipeable-thread.react.js';
type Props = {
+data: ChatThreadItem,
diff --git a/native/chat/chat-thread-list-see-more-sidebars.react.js b/native/chat/chat-thread-list-see-more-sidebars.react.js
--- a/native/chat/chat-thread-list-see-more-sidebars.react.js
+++ b/native/chat/chat-thread-list-see-more-sidebars.react.js
@@ -1,14 +1,14 @@
// @flow
-import Icon from '@expo/vector-icons/Ionicons';
+import Icon from '@expo/vector-icons/Ionicons.js';
import * as React from 'react';
import { Text } from 'react-native';
-import type { ThreadInfo } from 'lib/types/thread-types';
+import type { ThreadInfo } from 'lib/types/thread-types.js';
-import Button from '../components/button.react';
-import { useColors, useStyles } from '../themes/colors';
-import { sidebarHeight } from './sidebar-item.react';
+import Button from '../components/button.react.js';
+import { useColors, useStyles } from '../themes/colors.js';
+import { sidebarHeight } from './sidebar-item.react.js';
type Props = {
+threadInfo: ThreadInfo,
diff --git a/native/chat/chat-thread-list-sidebar.react.js b/native/chat/chat-thread-list-sidebar.react.js
--- a/native/chat/chat-thread-list-sidebar.react.js
+++ b/native/chat/chat-thread-list-sidebar.react.js
@@ -3,15 +3,15 @@
import * as React from 'react';
import { View } from 'react-native';
-import type { ThreadInfo, SidebarInfo } from 'lib/types/thread-types';
+import type { ThreadInfo, SidebarInfo } from 'lib/types/thread-types.js';
-import ExtendedArrow from '../components/arrow-extended.react';
-import Arrow from '../components/arrow.react';
-import Button from '../components/button.react';
-import UnreadDot from '../components/unread-dot.react';
-import { useColors, useStyles } from '../themes/colors';
-import { SidebarItem, sidebarHeight } from './sidebar-item.react';
-import SwipeableThread from './swipeable-thread.react';
+import ExtendedArrow from '../components/arrow-extended.react.js';
+import Arrow from '../components/arrow.react.js';
+import Button from '../components/button.react.js';
+import UnreadDot from '../components/unread-dot.react.js';
+import { useColors, useStyles } from '../themes/colors.js';
+import { SidebarItem, sidebarHeight } from './sidebar-item.react.js';
+import SwipeableThread from './swipeable-thread.react.js';
type Props = {
+sidebarInfo: SidebarInfo,
diff --git a/native/chat/chat-thread-list.react.js b/native/chat/chat-thread-list.react.js
--- a/native/chat/chat-thread-list.react.js
+++ b/native/chat/chat-thread-list.react.js
@@ -1,8 +1,8 @@
// @flow
-import IonIcon from '@expo/vector-icons/Ionicons';
+import IonIcon from '@expo/vector-icons/Ionicons.js';
import invariant from 'invariant';
-import _sum from 'lodash/fp/sum';
+import _sum from 'lodash/fp/sum.js';
import * as React from 'react';
import {
View,
@@ -16,56 +16,56 @@
import Animated from 'react-native-reanimated';
import { createSelector } from 'reselect';
-import { searchUsers } from 'lib/actions/user-actions';
+import { searchUsers } from 'lib/actions/user-actions.js';
import {
type ChatThreadItem,
useFlattenedChatListData,
-} from 'lib/selectors/chat-selectors';
-import { useGlobalThreadSearchIndex } from 'lib/selectors/nav-selectors';
-import { usersWithPersonalThreadSelector } from 'lib/selectors/user-selectors';
-import SearchIndex from 'lib/shared/search-index';
+} from 'lib/selectors/chat-selectors.js';
+import { useGlobalThreadSearchIndex } from 'lib/selectors/nav-selectors.js';
+import { usersWithPersonalThreadSelector } from 'lib/selectors/user-selectors.js';
+import SearchIndex from 'lib/shared/search-index.js';
import {
createPendingThread,
getThreadListSearchResults,
-} from 'lib/shared/thread-utils';
-import type { UserSearchResult } from 'lib/types/search-types';
-import type { ThreadInfo } from 'lib/types/thread-types';
-import { threadTypes } from 'lib/types/thread-types';
-import type { GlobalAccountUserInfo, UserInfo } from 'lib/types/user-types';
-import { useServerCall } from 'lib/utils/action-utils';
-
-import Button from '../components/button.react';
-import Search from '../components/search.react';
+} from 'lib/shared/thread-utils.js';
+import type { UserSearchResult } from 'lib/types/search-types.js';
+import type { ThreadInfo } from 'lib/types/thread-types.js';
+import { threadTypes } from 'lib/types/thread-types.js';
+import type { GlobalAccountUserInfo, UserInfo } from 'lib/types/user-types.js';
+import { useServerCall } from 'lib/utils/action-utils.js';
+
+import Button from '../components/button.react.js';
+import Search from '../components/search.react.js';
import {
SidebarListModalRouteName,
HomeChatThreadListRouteName,
BackgroundChatThreadListRouteName,
type NavigationRoute,
-} from '../navigation/route-names';
-import type { TabNavigationProp } from '../navigation/tab-navigator.react';
-import { useSelector } from '../redux/redux-utils';
+} from '../navigation/route-names.js';
+import type { TabNavigationProp } from '../navigation/tab-navigator.react.js';
+import { useSelector } from '../redux/redux-utils.js';
import {
type IndicatorStyle,
indicatorStyleSelector,
useStyles,
-} from '../themes/colors';
-import type { ScrollEvent } from '../types/react-native';
-import { AnimatedView, type AnimatedStyleObj } from '../types/styles';
-import { animateTowards } from '../utils/animation-utils';
+} from '../themes/colors.js';
+import type { ScrollEvent } from '../types/react-native.js';
+import { AnimatedView, type AnimatedStyleObj } from '../types/styles.js';
+import { animateTowards } from '../utils/animation-utils.js';
import {
ChatThreadListItem,
chatThreadListItemHeight,
spacerHeight,
-} from './chat-thread-list-item.react';
+} from './chat-thread-list-item.react.js';
import type {
ChatTopTabsNavigationProp,
ChatNavigationProp,
-} from './chat.react';
+} from './chat.react.js';
import {
type MessageListParams,
useNavigateToThread,
-} from './message-list-types';
-import { sidebarHeight } from './sidebar-item.react';
+} from './message-list-types.js';
+import { sidebarHeight } from './sidebar-item.react.js';
const floatingActions = [
{
diff --git a/native/chat/chat.react.js b/native/chat/chat.react.js
--- a/native/chat/chat.react.js
+++ b/native/chat/chat.react.js
@@ -23,20 +23,20 @@
import { Platform, View, useWindowDimensions } from 'react-native';
import { useSelector } from 'react-redux';
-import ThreadDraftUpdater from 'lib/components/thread-draft-updater.react';
-import { isLoggedIn } from 'lib/selectors/user-selectors';
+import ThreadDraftUpdater from 'lib/components/thread-draft-updater.react.js';
+import { isLoggedIn } from 'lib/selectors/user-selectors.js';
import {
threadIsPending,
threadMembersWithoutAddedAshoat,
-} from 'lib/shared/thread-utils';
+} from 'lib/shared/thread-utils.js';
-import KeyboardAvoidingView from '../components/keyboard-avoiding-view.react';
-import SWMansionIcon from '../components/swmansion-icon.react';
-import { InputStateContext } from '../input/input-state';
-import CommunityDrawerButton from '../navigation/community-drawer-button.react';
-import type { CommunityDrawerNavigationProp } from '../navigation/community-drawer-navigator.react';
-import HeaderBackButton from '../navigation/header-back-button.react';
-import { defaultStackScreenOptions } from '../navigation/options';
+import KeyboardAvoidingView from '../components/keyboard-avoiding-view.react.js';
+import SWMansionIcon from '../components/swmansion-icon.react.js';
+import { InputStateContext } from '../input/input-state.js';
+import CommunityDrawerButton from '../navigation/community-drawer-button.react.js';
+import type { CommunityDrawerNavigationProp } from '../navigation/community-drawer-navigator.react.js';
+import HeaderBackButton from '../navigation/header-back-button.react.js';
+import { defaultStackScreenOptions } from '../navigation/options.js';
import {
ComposeSubchannelRouteName,
DeleteThreadRouteName,
@@ -48,22 +48,22 @@
type ScreenParamList,
type ChatParamList,
type ChatTopTabsParamList,
-} from '../navigation/route-names';
-import { useColors, useStyles } from '../themes/colors';
-import BackgroundChatThreadList from './background-chat-thread-list.react';
-import ChatHeader from './chat-header.react';
-import ChatRouter, { type ChatRouterNavigationHelpers } from './chat-router';
-import ComposeSubchannel from './compose-subchannel.react';
-import ComposeThreadButton from './compose-thread-button.react';
-import HomeChatThreadList from './home-chat-thread-list.react';
-import MessageListContainer from './message-list-container.react';
-import MessageListHeaderTitle from './message-list-header-title.react';
-import MessageStorePruner from './message-store-pruner.react';
-import DeleteThread from './settings/delete-thread.react';
-import ThreadSettings from './settings/thread-settings.react';
-import ThreadScreenPruner from './thread-screen-pruner.react';
-import ThreadSettingsButton from './thread-settings-button.react';
-import ThreadSettingsHeaderTitle from './thread-settings-header-title.react';
+} from '../navigation/route-names.js';
+import { useColors, useStyles } from '../themes/colors.js';
+import BackgroundChatThreadList from './background-chat-thread-list.react.js';
+import ChatHeader from './chat-header.react.js';
+import ChatRouter, { type ChatRouterNavigationHelpers } from './chat-router.js';
+import ComposeSubchannel from './compose-subchannel.react.js';
+import ComposeThreadButton from './compose-thread-button.react.js';
+import HomeChatThreadList from './home-chat-thread-list.react.js';
+import MessageListContainer from './message-list-container.react.js';
+import MessageListHeaderTitle from './message-list-header-title.react.js';
+import MessageStorePruner from './message-store-pruner.react.js';
+import DeleteThread from './settings/delete-thread.react.js';
+import ThreadSettings from './settings/thread-settings.react.js';
+import ThreadScreenPruner from './thread-screen-pruner.react.js';
+import ThreadSettingsButton from './thread-settings-button.react.js';
+import ThreadSettingsHeaderTitle from './thread-settings-header-title.react.js';
const unboundStyles = {
keyboardAvoidingView: {
diff --git a/native/chat/compose-subchannel.react.js b/native/chat/compose-subchannel.react.js
--- a/native/chat/compose-subchannel.react.js
+++ b/native/chat/compose-subchannel.react.js
@@ -1,43 +1,43 @@
// @flow
import invariant from 'invariant';
-import _filter from 'lodash/fp/filter';
-import _flow from 'lodash/fp/flow';
-import _sortBy from 'lodash/fp/sortBy';
+import _filter from 'lodash/fp/filter.js';
+import _flow from 'lodash/fp/flow.js';
+import _sortBy from 'lodash/fp/sortBy.js';
import * as React from 'react';
import { View, Text, Alert } from 'react-native';
-import { newThreadActionTypes, newThread } from 'lib/actions/thread-actions';
-import { useENSNames } from 'lib/hooks/ens-cache';
-import { threadInfoSelector } from 'lib/selectors/thread-selectors';
+import { newThreadActionTypes, newThread } from 'lib/actions/thread-actions.js';
+import { useENSNames } from 'lib/hooks/ens-cache.js';
+import { threadInfoSelector } from 'lib/selectors/thread-selectors.js';
import {
userInfoSelectorForPotentialMembers,
userSearchIndexForPotentialMembers,
-} from 'lib/selectors/user-selectors';
-import { getPotentialMemberItems } from 'lib/shared/search-utils';
-import { threadInFilterList, userIsMember } from 'lib/shared/thread-utils';
+} from 'lib/selectors/user-selectors.js';
+import { getPotentialMemberItems } from 'lib/shared/search-utils.js';
+import { threadInFilterList, userIsMember } from 'lib/shared/thread-utils.js';
import {
type ThreadInfo,
type ThreadType,
threadTypes,
-} from 'lib/types/thread-types';
-import { type AccountUserInfo } from 'lib/types/user-types';
+} from 'lib/types/thread-types.js';
+import { type AccountUserInfo } from 'lib/types/user-types.js';
import {
useServerCall,
useDispatchActionPromise,
-} from 'lib/utils/action-utils';
+} from 'lib/utils/action-utils.js';
-import LinkButton from '../components/link-button.react';
-import { createTagInput } from '../components/tag-input.react';
-import ThreadList from '../components/thread-list.react';
-import UserList from '../components/user-list.react';
-import { useCalendarQuery } from '../navigation/nav-selectors';
-import type { NavigationRoute } from '../navigation/route-names';
-import { useSelector } from '../redux/redux-utils';
-import { useStyles } from '../themes/colors';
-import type { ChatNavigationProp } from './chat.react';
-import { useNavigateToThread } from './message-list-types';
-import ParentThreadHeader from './parent-thread-header.react';
+import LinkButton from '../components/link-button.react.js';
+import { createTagInput } from '../components/tag-input.react.js';
+import ThreadList from '../components/thread-list.react.js';
+import UserList from '../components/user-list.react.js';
+import { useCalendarQuery } from '../navigation/nav-selectors.js';
+import type { NavigationRoute } from '../navigation/route-names.js';
+import { useSelector } from '../redux/redux-utils.js';
+import { useStyles } from '../themes/colors.js';
+import type { ChatNavigationProp } from './chat.react.js';
+import { useNavigateToThread } from './message-list-types.js';
+import ParentThreadHeader from './parent-thread-header.react.js';
const TagInput = createTagInput<AccountUserInfo>();
diff --git a/native/chat/compose-thread-button.react.js b/native/chat/compose-thread-button.react.js
--- a/native/chat/compose-thread-button.react.js
+++ b/native/chat/compose-thread-button.react.js
@@ -3,15 +3,15 @@
import * as React from 'react';
import { StyleSheet } from 'react-native';
-import { createPendingThread } from 'lib/shared/thread-utils';
-import { threadTypes } from 'lib/types/thread-types';
+import { createPendingThread } from 'lib/shared/thread-utils.js';
+import { threadTypes } from 'lib/types/thread-types.js';
-import Button from '../components/button.react';
-import SWMansionIcon from '../components/swmansion-icon.react';
-import { MessageListRouteName } from '../navigation/route-names';
-import { useSelector } from '../redux/redux-utils';
-import { type Colors, useColors } from '../themes/colors';
-import type { ChatNavigationProp } from './chat.react';
+import Button from '../components/button.react.js';
+import SWMansionIcon from '../components/swmansion-icon.react.js';
+import { MessageListRouteName } from '../navigation/route-names.js';
+import { useSelector } from '../redux/redux-utils.js';
+import { type Colors, useColors } from '../themes/colors.js';
+import type { ChatNavigationProp } from './chat.react.js';
type BaseProps = {
+navigate: $PropertyType<ChatNavigationProp<'ChatThreadList'>, 'navigate'>,
diff --git a/native/chat/composed-message-width.js b/native/chat/composed-message-width.js
--- a/native/chat/composed-message-width.js
+++ b/native/chat/composed-message-width.js
@@ -1,6 +1,6 @@
// @flow
-import { useSelector } from '../redux/redux-utils';
+import { useSelector } from '../redux/redux-utils.js';
function useMessageListScreenWidth(): number {
return useSelector(state => {
diff --git a/native/chat/composed-message.react.js b/native/chat/composed-message.react.js
--- a/native/chat/composed-message.react.js
+++ b/native/chat/composed-message.react.js
@@ -1,32 +1,32 @@
// @flow
-import Icon from '@expo/vector-icons/Feather';
+import Icon from '@expo/vector-icons/Feather.js';
import invariant from 'invariant';
import * as React from 'react';
import { StyleSheet, View } from 'react-native';
import Animated from 'react-native-reanimated';
-import { createMessageReply } from 'lib/shared/message-utils';
-import { assertComposableMessageType } from 'lib/types/message-types';
+import { createMessageReply } from 'lib/shared/message-utils.js';
+import { assertComposableMessageType } from 'lib/types/message-types.js';
-import { type InputState, InputStateContext } from '../input/input-state';
-import { type Colors, useColors } from '../themes/colors';
-import type { ChatMessageInfoItemWithHeight } from '../types/chat-types';
-import { type AnimatedStyleObj, AnimatedView } from '../types/styles';
+import { type InputState, InputStateContext } from '../input/input-state.js';
+import { type Colors, useColors } from '../themes/colors.js';
+import type { ChatMessageInfoItemWithHeight } from '../types/chat-types.js';
+import { type AnimatedStyleObj, AnimatedView } from '../types/styles.js';
import {
clusterEndHeight,
inlineEngagementStyle,
inlineEngagementLeftStyle,
inlineEngagementRightStyle,
composedMessageStyle,
-} from './chat-constants';
-import { useComposedMessageMaxWidth } from './composed-message-width';
-import { FailedSend } from './failed-send.react';
-import { InlineEngagement } from './inline-engagement.react';
-import { MessageHeader } from './message-header.react';
-import { useNavigateToSidebar } from './sidebar-navigation';
-import SwipeableMessage from './swipeable-message.react';
-import { useContentAndHeaderOpacity, useDeliveryIconOpacity } from './utils';
+} from './chat-constants.js';
+import { useComposedMessageMaxWidth } from './composed-message-width.js';
+import { FailedSend } from './failed-send.react.js';
+import { InlineEngagement } from './inline-engagement.react.js';
+import { MessageHeader } from './message-header.react.js';
+import { useNavigateToSidebar } from './sidebar-navigation.js';
+import SwipeableMessage from './swipeable-message.react.js';
+import { useContentAndHeaderOpacity, useDeliveryIconOpacity } from './utils.js';
/* eslint-disable import/no-named-as-default-member */
const { Node } = Animated;
diff --git a/native/chat/failed-send.react.js b/native/chat/failed-send.react.js
--- a/native/chat/failed-send.react.js
+++ b/native/chat/failed-send.react.js
@@ -4,20 +4,20 @@
import * as React from 'react';
import { Text, View } from 'react-native';
-import { messageID } from 'lib/shared/message-utils';
+import { messageID } from 'lib/shared/message-utils.js';
import {
assertComposableRawMessage,
messageTypes,
-} from 'lib/types/message-types';
-import type { RawComposableMessageInfo } from 'lib/types/message-types';
+} from 'lib/types/message-types.js';
+import type { RawComposableMessageInfo } from 'lib/types/message-types.js';
-import Button from '../components/button.react';
-import { type InputState, InputStateContext } from '../input/input-state';
-import { useSelector } from '../redux/redux-utils';
-import { useStyles } from '../themes/colors';
-import type { ChatMessageInfoItemWithHeight } from '../types/chat-types';
-import { multimediaMessageSendFailed } from './multimedia-message-utils';
-import textMessageSendFailed from './text-message-send-failed';
+import Button from '../components/button.react.js';
+import { type InputState, InputStateContext } from '../input/input-state.js';
+import { useSelector } from '../redux/redux-utils.js';
+import { useStyles } from '../themes/colors.js';
+import type { ChatMessageInfoItemWithHeight } from '../types/chat-types.js';
+import { multimediaMessageSendFailed } from './multimedia-message-utils.js';
+import textMessageSendFailed from './text-message-send-failed.js';
const failedSendHeight = 22;
diff --git a/native/chat/home-chat-thread-list.react.js b/native/chat/home-chat-thread-list.react.js
--- a/native/chat/home-chat-thread-list.react.js
+++ b/native/chat/home-chat-thread-list.react.js
@@ -2,11 +2,11 @@
import * as React from 'react';
-import { threadInHomeChatList } from 'lib/shared/thread-utils';
+import { threadInHomeChatList } from 'lib/shared/thread-utils.js';
-import type { NavigationRoute } from '../navigation/route-names';
-import ChatThreadList from './chat-thread-list.react';
-import type { ChatTopTabsNavigationProp } from './chat.react';
+import type { NavigationRoute } from '../navigation/route-names.js';
+import ChatThreadList from './chat-thread-list.react.js';
+import type { ChatTopTabsNavigationProp } from './chat.react.js';
type HomeChatThreadListProps = {
navigation: ChatTopTabsNavigationProp<'HomeChatThreadList'>,
diff --git a/native/chat/image-paste-modal.react.js b/native/chat/image-paste-modal.react.js
--- a/native/chat/image-paste-modal.react.js
+++ b/native/chat/image-paste-modal.react.js
@@ -5,15 +5,15 @@
import { Button, View, Image } from 'react-native';
import filesystem from 'react-native-fs';
-import type { PhotoPaste } from 'lib/types/media-types';
-import type { ThreadInfo } from 'lib/types/thread-types';
-import sleep from 'lib/utils/sleep';
+import type { PhotoPaste } from 'lib/types/media-types.js';
+import type { ThreadInfo } from 'lib/types/thread-types.js';
+import sleep from 'lib/utils/sleep.js';
-import Modal from '../components/modal.react';
-import { InputStateContext } from '../input/input-state';
-import type { RootNavigationProp } from '../navigation/root-navigator.react';
-import type { NavigationRoute } from '../navigation/route-names';
-import { useStyles } from '../themes/colors';
+import Modal from '../components/modal.react.js';
+import { InputStateContext } from '../input/input-state.js';
+import type { RootNavigationProp } from '../navigation/root-navigator.react.js';
+import type { NavigationRoute } from '../navigation/route-names.js';
+import { useStyles } from '../themes/colors.js';
export type ImagePasteModalParams = {
+imagePasteStagingInfo: PhotoPaste,
diff --git a/native/chat/inline-engagement.react.js b/native/chat/inline-engagement.react.js
--- a/native/chat/inline-engagement.react.js
+++ b/native/chat/inline-engagement.react.js
@@ -8,23 +8,23 @@
interpolateNode,
} from 'react-native-reanimated';
-import useInlineEngagementText from 'lib/hooks/inline-engagement-text.react';
-import type { MessageReactionInfo } from 'lib/selectors/chat-selectors';
-import { stringForReactionList } from 'lib/shared/reaction-utils';
-import type { ThreadInfo } from 'lib/types/thread-types';
-
-import CommIcon from '../components/comm-icon.react';
-import GestureTouchableOpacity from '../components/gesture-touchable-opacity.react';
-import { MessageReactionsModalRouteName } from '../navigation/route-names';
-import { useStyles } from '../themes/colors';
-import type { ChatMessageInfoItemWithHeight } from '../types/chat-types';
+import useInlineEngagementText from 'lib/hooks/inline-engagement-text.react.js';
+import type { MessageReactionInfo } from 'lib/selectors/chat-selectors.js';
+import { stringForReactionList } from 'lib/shared/reaction-utils.js';
+import type { ThreadInfo } from 'lib/types/thread-types.js';
+
+import CommIcon from '../components/comm-icon.react.js';
+import GestureTouchableOpacity from '../components/gesture-touchable-opacity.react.js';
+import { MessageReactionsModalRouteName } from '../navigation/route-names.js';
+import { useStyles } from '../themes/colors.js';
+import type { ChatMessageInfoItemWithHeight } from '../types/chat-types.js';
import {
inlineEngagementStyle,
inlineEngagementCenterStyle,
inlineEngagementRightStyle,
composedMessageStyle,
-} from './chat-constants';
-import { useNavigateToThread } from './message-list-types';
+} from './chat-constants.js';
+import { useNavigateToThread } from './message-list-types.js';
type Props = {
+threadInfo: ?ThreadInfo,
diff --git a/native/chat/inline-multimedia.react.js b/native/chat/inline-multimedia.react.js
--- a/native/chat/inline-multimedia.react.js
+++ b/native/chat/inline-multimedia.react.js
@@ -1,18 +1,18 @@
// @flow
-import Icon from '@expo/vector-icons/Feather';
-import IonIcon from '@expo/vector-icons/Ionicons';
+import Icon from '@expo/vector-icons/Feather.js';
+import IonIcon from '@expo/vector-icons/Ionicons.js';
import * as React from 'react';
import { View, StyleSheet, Text } from 'react-native';
import * as Progress from 'react-native-progress';
import tinycolor from 'tinycolor2';
-import { isLocalUploadID } from 'lib/media/media-utils';
-import type { MediaInfo } from 'lib/types/media-types';
+import { isLocalUploadID } from 'lib/media/media-utils.js';
+import type { MediaInfo } from 'lib/types/media-types.js';
-import GestureTouchableOpacity from '../components/gesture-touchable-opacity.react';
-import type { PendingMultimediaUpload } from '../input/input-state';
-import Multimedia from '../media/multimedia.react';
+import GestureTouchableOpacity from '../components/gesture-touchable-opacity.react.js';
+import type { PendingMultimediaUpload } from '../input/input-state.js';
+import Multimedia from '../media/multimedia.react.js';
type Props = {
+mediaInfo: MediaInfo,
diff --git a/native/chat/inner-multimedia-message.react.js b/native/chat/inner-multimedia-message.react.js
--- a/native/chat/inner-multimedia-message.react.js
+++ b/native/chat/inner-multimedia-message.react.js
@@ -3,18 +3,24 @@
import * as React from 'react';
import { StyleSheet, TouchableWithoutFeedback, View } from 'react-native';
-import type { Corners, Media, MediaInfo } from 'lib/types/media-types';
+import type { Corners, Media, MediaInfo } from 'lib/types/media-types.js';
-import type { ChatMultimediaMessageInfoItem } from '../types/chat-types';
-import type { LayoutCoordinates, VerticalBounds } from '../types/layout-types';
-import type { ViewStyle } from '../types/styles';
-import MultimediaMessageMultimedia from './multimedia-message-multimedia.react';
-import { getMediaPerRow, spaceBetweenImages } from './multimedia-message-utils';
+import type { ChatMultimediaMessageInfoItem } from '../types/chat-types.js';
+import type {
+ LayoutCoordinates,
+ VerticalBounds,
+} from '../types/layout-types.js';
+import type { ViewStyle } from '../types/styles.js';
+import MultimediaMessageMultimedia from './multimedia-message-multimedia.react.js';
+import {
+ getMediaPerRow,
+ spaceBetweenImages,
+} from './multimedia-message-utils.js';
import {
allCorners,
filterCorners,
getRoundedContainerStyle,
-} from './rounded-corners';
+} from './rounded-corners.js';
const borderRadius = 16;
diff --git a/native/chat/inner-robotext-message.react.js b/native/chat/inner-robotext-message.react.js
--- a/native/chat/inner-robotext-message.react.js
+++ b/native/chat/inner-robotext-message.react.js
@@ -4,20 +4,20 @@
import * as React from 'react';
import { Text, TouchableWithoutFeedback, View } from 'react-native';
-import { threadInfoSelector } from 'lib/selectors/thread-selectors';
+import { threadInfoSelector } from 'lib/selectors/thread-selectors.js';
import {
entityTextToReact,
entityTextToRawString,
useENSNamesForEntityText,
type EntityText,
-} from 'lib/utils/entity-text';
-
-import Markdown from '../markdown/markdown.react';
-import { inlineMarkdownRules } from '../markdown/rules.react';
-import { useSelector } from '../redux/redux-utils';
-import { useOverlayStyles } from '../themes/colors';
-import type { ChatRobotextMessageInfoItemWithHeight } from '../types/chat-types';
-import { useNavigateToThread } from './message-list-types';
+} from 'lib/utils/entity-text.js';
+
+import Markdown from '../markdown/markdown.react.js';
+import { inlineMarkdownRules } from '../markdown/rules.react.js';
+import { useSelector } from '../redux/redux-utils.js';
+import { useOverlayStyles } from '../themes/colors.js';
+import type { ChatRobotextMessageInfoItemWithHeight } from '../types/chat-types.js';
+import { useNavigateToThread } from './message-list-types.js';
function dummyNodeForRobotextMessageHeightMeasurement(
robotext: EntityText,
diff --git a/native/chat/inner-text-message.react.js b/native/chat/inner-text-message.react.js
--- a/native/chat/inner-text-message.react.js
+++ b/native/chat/inner-text-message.react.js
@@ -4,24 +4,24 @@
import { View, StyleSheet, TouchableWithoutFeedback } from 'react-native';
import Animated from 'react-native-reanimated';
-import { colorIsDark } from 'lib/shared/thread-utils';
-
-import GestureTouchableOpacity from '../components/gesture-touchable-opacity.react';
-import Markdown from '../markdown/markdown.react';
-import { useSelector } from '../redux/redux-utils';
-import { useColors, colors } from '../themes/colors';
-import type { ChatTextMessageInfoItemWithHeight } from '../types/chat-types';
-import { useComposedMessageMaxWidth } from './composed-message-width';
-import { useTextMessageMarkdownRules } from './message-list-types';
+import { colorIsDark } from 'lib/shared/thread-utils.js';
+
+import GestureTouchableOpacity from '../components/gesture-touchable-opacity.react.js';
+import Markdown from '../markdown/markdown.react.js';
+import { useSelector } from '../redux/redux-utils.js';
+import { useColors, colors } from '../themes/colors.js';
+import type { ChatTextMessageInfoItemWithHeight } from '../types/chat-types.js';
+import { useComposedMessageMaxWidth } from './composed-message-width.js';
+import { useTextMessageMarkdownRules } from './message-list-types.js';
import {
allCorners,
filterCorners,
getRoundedContainerStyle,
-} from './rounded-corners';
+} from './rounded-corners.js';
import {
TextMessageMarkdownContext,
useTextMessageMarkdown,
-} from './text-message-markdown-context';
+} from './text-message-markdown-context.js';
/* eslint-disable import/no-named-as-default-member */
const { Node } = Animated;
diff --git a/native/chat/message-header.react.js b/native/chat/message-header.react.js
--- a/native/chat/message-header.react.js
+++ b/native/chat/message-header.react.js
@@ -3,14 +3,14 @@
import * as React from 'react';
import { View } from 'react-native';
-import { useStringForUser } from 'lib/hooks/ens-cache';
+import { useStringForUser } from 'lib/hooks/ens-cache.js';
-import { SingleLine } from '../components/single-line.react';
-import { useStyles } from '../themes/colors';
-import type { ChatMessageInfoItemWithHeight } from '../types/chat-types';
-import { clusterEndHeight } from './chat-constants';
-import type { DisplayType } from './timestamp.react';
-import { Timestamp, timestampHeight } from './timestamp.react';
+import { SingleLine } from '../components/single-line.react.js';
+import { useStyles } from '../themes/colors.js';
+import type { ChatMessageInfoItemWithHeight } from '../types/chat-types.js';
+import { clusterEndHeight } from './chat-constants.js';
+import type { DisplayType } from './timestamp.react.js';
+import { Timestamp, timestampHeight } from './timestamp.react.js';
type Props = {
+item: ChatMessageInfoItemWithHeight,
diff --git a/native/chat/message-list-container.react.js b/native/chat/message-list-container.react.js
--- a/native/chat/message-list-container.react.js
+++ b/native/chat/message-list-container.react.js
@@ -5,42 +5,42 @@
import * as React from 'react';
import { View } from 'react-native';
-import genesis from 'lib/facts/genesis';
+import genesis from 'lib/facts/genesis.js';
import {
type ChatMessageItem,
useMessageListData,
-} from 'lib/selectors/chat-selectors';
-import { threadInfoSelector } from 'lib/selectors/thread-selectors';
+} from 'lib/selectors/chat-selectors.js';
+import { threadInfoSelector } from 'lib/selectors/thread-selectors.js';
import {
userInfoSelectorForPotentialMembers,
userSearchIndexForPotentialMembers,
-} from 'lib/selectors/user-selectors';
-import { getPotentialMemberItems } from 'lib/shared/search-utils';
+} from 'lib/selectors/user-selectors.js';
+import { getPotentialMemberItems } from 'lib/shared/search-utils.js';
import {
useExistingThreadInfoFinder,
pendingThreadType,
-} from 'lib/shared/thread-utils';
-import type { ThreadInfo } from 'lib/types/thread-types';
-import type { AccountUserInfo, UserListItem } from 'lib/types/user-types';
+} from 'lib/shared/thread-utils.js';
+import type { ThreadInfo } from 'lib/types/thread-types.js';
+import type { AccountUserInfo, UserListItem } from 'lib/types/user-types.js';
-import ContentLoading from '../components/content-loading.react';
-import { InputStateContext } from '../input/input-state';
+import ContentLoading from '../components/content-loading.react.js';
+import { InputStateContext } from '../input/input-state.js';
import {
OverlayContext,
type OverlayContextType,
-} from '../navigation/overlay-context';
-import type { NavigationRoute } from '../navigation/route-names';
-import { ThreadSettingsRouteName } from '../navigation/route-names';
-import { useSelector } from '../redux/redux-utils';
-import { type Colors, useColors, useStyles } from '../themes/colors';
-import type { ChatMessageItemWithHeight } from '../types/chat-types';
-import { type MessagesMeasurer, useHeightMeasurer } from './chat-context';
-import { ChatInputBar } from './chat-input-bar.react';
-import type { ChatNavigationProp } from './chat.react';
-import MessageListThreadSearch from './message-list-thread-search.react';
-import { MessageListContextProvider } from './message-list-types';
-import MessageList from './message-list.react';
-import ParentThreadHeader from './parent-thread-header.react';
+} from '../navigation/overlay-context.js';
+import type { NavigationRoute } from '../navigation/route-names.js';
+import { ThreadSettingsRouteName } from '../navigation/route-names.js';
+import { useSelector } from '../redux/redux-utils.js';
+import { type Colors, useColors, useStyles } from '../themes/colors.js';
+import type { ChatMessageItemWithHeight } from '../types/chat-types.js';
+import { type MessagesMeasurer, useHeightMeasurer } from './chat-context.js';
+import { ChatInputBar } from './chat-input-bar.react.js';
+import type { ChatNavigationProp } from './chat.react.js';
+import MessageListThreadSearch from './message-list-thread-search.react.js';
+import { MessageListContextProvider } from './message-list-types.js';
+import MessageList from './message-list.react.js';
+import ParentThreadHeader from './parent-thread-header.react.js';
type BaseProps = {
+navigation: ChatNavigationProp<'MessageList'>,
diff --git a/native/chat/message-list-header-title.react.js b/native/chat/message-list-header-title.react.js
--- a/native/chat/message-list-header-title.react.js
+++ b/native/chat/message-list-header-title.react.js
@@ -1,6 +1,6 @@
// @flow
-import Icon from '@expo/vector-icons/Ionicons';
+import Icon from '@expo/vector-icons/Ionicons.js';
import {
HeaderTitle,
type HeaderTitleInputProps,
@@ -8,14 +8,14 @@
import * as React from 'react';
import { View, Platform } from 'react-native';
-import type { ThreadInfo } from 'lib/types/thread-types';
-import { useResolvedThreadInfo } from 'lib/utils/entity-helpers';
-import { firstLine } from 'lib/utils/string-utils';
+import type { ThreadInfo } from 'lib/types/thread-types.js';
+import { useResolvedThreadInfo } from 'lib/utils/entity-helpers.js';
+import { firstLine } from 'lib/utils/string-utils.js';
-import Button from '../components/button.react';
-import { ThreadSettingsRouteName } from '../navigation/route-names';
-import { useStyles } from '../themes/colors';
-import type { ChatNavigationProp } from './chat.react';
+import Button from '../components/button.react.js';
+import { ThreadSettingsRouteName } from '../navigation/route-names.js';
+import { useStyles } from '../themes/colors.js';
+import type { ChatNavigationProp } from './chat.react.js';
type BaseProps = {
+threadInfo: ThreadInfo,
diff --git a/native/chat/message-list-thread-search.react.js b/native/chat/message-list-thread-search.react.js
--- a/native/chat/message-list-thread-search.react.js
+++ b/native/chat/message-list-thread-search.react.js
@@ -3,13 +3,13 @@
import * as React from 'react';
import { Text, View } from 'react-native';
-import { useENSNames } from 'lib/hooks/ens-cache';
-import { notFriendNotice } from 'lib/shared/search-utils';
-import type { AccountUserInfo, UserListItem } from 'lib/types/user-types';
+import { useENSNames } from 'lib/hooks/ens-cache.js';
+import { notFriendNotice } from 'lib/shared/search-utils.js';
+import type { AccountUserInfo, UserListItem } from 'lib/types/user-types.js';
-import { createTagInput } from '../components/tag-input.react';
-import UserList from '../components/user-list.react';
-import { useStyles } from '../themes/colors';
+import { createTagInput } from '../components/tag-input.react.js';
+import UserList from '../components/user-list.react.js';
+import { useStyles } from '../themes/colors.js';
const TagInput = createTagInput<AccountUserInfo>();
diff --git a/native/chat/message-list-types.js b/native/chat/message-list-types.js
--- a/native/chat/message-list-types.js
+++ b/native/chat/message-list-types.js
@@ -4,12 +4,12 @@
import invariant from 'invariant';
import * as React from 'react';
-import type { ThreadInfo } from 'lib/types/thread-types';
-import { type UserInfo } from 'lib/types/user-types';
+import type { ThreadInfo } from 'lib/types/thread-types.js';
+import { type UserInfo } from 'lib/types/user-types.js';
-import type { MarkdownRules } from '../markdown/rules.react';
-import { useTextMessageRulesFunc } from '../markdown/rules.react';
-import { MessageListRouteName } from '../navigation/route-names';
+import type { MarkdownRules } from '../markdown/rules.react.js';
+import { useTextMessageRulesFunc } from '../markdown/rules.react.js';
+import { MessageListRouteName } from '../navigation/route-names.js';
export type MessageListParams = {
+threadInfo: ThreadInfo,
diff --git a/native/chat/message-list.react.js b/native/chat/message-list.react.js
--- a/native/chat/message-list.react.js
+++ b/native/chat/message-list.react.js
@@ -1,7 +1,7 @@
// @flow
import invariant from 'invariant';
-import _find from 'lodash/fp/find';
+import _find from 'lodash/fp/find.js';
import * as React from 'react';
import { View, TouchableWithoutFeedback } from 'react-native';
import { createSelector } from 'reselect';
@@ -11,45 +11,45 @@
fetchMessagesBeforeCursor,
fetchMostRecentMessagesActionTypes,
fetchMostRecentMessages,
-} from 'lib/actions/message-actions';
-import { registerFetchKey } from 'lib/reducers/loading-reducer';
-import { messageKey } from 'lib/shared/message-utils';
-import { useWatchThread } from 'lib/shared/thread-utils';
-import type { FetchMessageInfosPayload } from 'lib/types/message-types';
-import { type ThreadInfo, threadTypes } from 'lib/types/thread-types';
+} from 'lib/actions/message-actions.js';
+import { registerFetchKey } from 'lib/reducers/loading-reducer.js';
+import { messageKey } from 'lib/shared/message-utils.js';
+import { useWatchThread } from 'lib/shared/thread-utils.js';
+import type { FetchMessageInfosPayload } from 'lib/types/message-types.js';
+import { type ThreadInfo, threadTypes } from 'lib/types/thread-types.js';
import {
type DispatchActionPromise,
useServerCall,
useDispatchActionPromise,
-} from 'lib/utils/action-utils';
+} from 'lib/utils/action-utils.js';
-import ListLoadingIndicator from '../components/list-loading-indicator.react';
+import ListLoadingIndicator from '../components/list-loading-indicator.react.js';
import {
type KeyboardState,
KeyboardContext,
-} from '../keyboard/keyboard-state';
-import { defaultStackScreenOptions } from '../navigation/options';
+} from '../keyboard/keyboard-state.js';
+import { defaultStackScreenOptions } from '../navigation/options.js';
import {
OverlayContext,
type OverlayContextType,
-} from '../navigation/overlay-context';
-import type { NavigationRoute } from '../navigation/route-names';
-import { useSelector } from '../redux/redux-utils';
+} from '../navigation/overlay-context.js';
+import type { NavigationRoute } from '../navigation/route-names.js';
+import { useSelector } from '../redux/redux-utils.js';
import {
useStyles,
type IndicatorStyle,
useIndicatorStyle,
-} from '../themes/colors';
+} from '../themes/colors.js';
import type {
ChatMessageInfoItemWithHeight,
ChatMessageItemWithHeight,
-} from '../types/chat-types';
-import type { VerticalBounds } from '../types/layout-types';
-import type { ViewableItemsChange } from '../types/react-native';
-import ChatList from './chat-list.react';
-import type { ChatNavigationProp } from './chat.react';
-import { Message } from './message.react';
-import RelationshipPrompt from './relationship-prompt.react';
+} from '../types/chat-types.js';
+import type { VerticalBounds } from '../types/layout-types.js';
+import type { ViewableItemsChange } from '../types/react-native.js';
+import ChatList from './chat-list.react.js';
+import type { ChatNavigationProp } from './chat.react.js';
+import { Message } from './message.react.js';
+import RelationshipPrompt from './relationship-prompt.react.js';
type BaseProps = {
+threadInfo: ThreadInfo,
diff --git a/native/chat/message-preview.react.js b/native/chat/message-preview.react.js
--- a/native/chat/message-preview.react.js
+++ b/native/chat/message-preview.react.js
@@ -4,13 +4,13 @@
import * as React from 'react';
import { Text } from 'react-native';
-import { useMessagePreview } from 'lib/shared/message-utils';
-import { type MessageInfo } from 'lib/types/message-types';
-import { type ThreadInfo } from 'lib/types/thread-types';
+import { useMessagePreview } from 'lib/shared/message-utils.js';
+import { type MessageInfo } from 'lib/types/message-types.js';
+import { type ThreadInfo } from 'lib/types/thread-types.js';
-import { SingleLine } from '../components/single-line.react';
-import { getDefaultTextMessageRules } from '../markdown/rules.react';
-import { useStyles } from '../themes/colors';
+import { SingleLine } from '../components/single-line.react.js';
+import { getDefaultTextMessageRules } from '../markdown/rules.react.js';
+import { useStyles } from '../themes/colors.js';
type Props = {
+messageInfo: MessageInfo,
diff --git a/native/chat/message-reactions-modal.react.js b/native/chat/message-reactions-modal.react.js
--- a/native/chat/message-reactions-modal.react.js
+++ b/native/chat/message-reactions-modal.react.js
@@ -1,18 +1,18 @@
// @flow
-import Icon from '@expo/vector-icons/FontAwesome';
+import Icon from '@expo/vector-icons/FontAwesome.js';
import { useNavigation } from '@react-navigation/native';
import * as React from 'react';
import { View, Text, FlatList, TouchableHighlight } from 'react-native';
import { SafeAreaView } from 'react-native-safe-area-context';
-import type { MessageReactionInfo } from 'lib/selectors/chat-selectors';
-import { useMessageReactionsList } from 'lib/shared/reaction-utils';
+import type { MessageReactionInfo } from 'lib/selectors/chat-selectors.js';
+import { useMessageReactionsList } from 'lib/shared/reaction-utils.js';
-import Modal from '../components/modal.react';
-import type { RootNavigationProp } from '../navigation/root-navigator.react';
-import type { NavigationRoute } from '../navigation/route-names';
-import { useColors, useStyles } from '../themes/colors';
+import Modal from '../components/modal.react.js';
+import type { RootNavigationProp } from '../navigation/root-navigator.react.js';
+import type { NavigationRoute } from '../navigation/route-names.js';
+import { useColors, useStyles } from '../themes/colors.js';
export type MessageReactionsModalParams = {
+reactions: $ReadOnlyMap<string, MessageReactionInfo>,
diff --git a/native/chat/message-report-utils.js b/native/chat/message-report-utils.js
--- a/native/chat/message-report-utils.js
+++ b/native/chat/message-report-utils.js
@@ -6,14 +6,14 @@
import {
sendMessageReport,
sendMessageReportActionTypes,
-} from 'lib/actions/message-report-actions';
+} from 'lib/actions/message-report-actions.js';
import {
useServerCall,
useDispatchActionPromise,
-} from 'lib/utils/action-utils';
+} from 'lib/utils/action-utils.js';
-import { displayActionResultModal } from '../navigation/action-result-modal';
-import type { TooltipRoute } from '../tooltip/tooltip.react';
+import { displayActionResultModal } from '../navigation/action-result-modal.js';
+import type { TooltipRoute } from '../tooltip/tooltip.react.js';
const confirmReport = () => displayActionResultModal('reported to admin');
diff --git a/native/chat/message-store-pruner.react.js b/native/chat/message-store-pruner.react.js
--- a/native/chat/message-store-pruner.react.js
+++ b/native/chat/message-store-pruner.react.js
@@ -3,15 +3,15 @@
import * as React from 'react';
import { useDispatch } from 'react-redux';
-import { messageStorePruneActionType } from 'lib/actions/message-actions';
-import { useIsAppForegrounded } from 'lib/shared/lifecycle-utils';
+import { messageStorePruneActionType } from 'lib/actions/message-actions.js';
+import { useIsAppForegrounded } from 'lib/shared/lifecycle-utils.js';
-import { NavContext } from '../navigation/navigation-context';
-import { useSelector } from '../redux/redux-utils';
+import { NavContext } from '../navigation/navigation-context.js';
+import { useSelector } from '../redux/redux-utils.js';
import {
nextMessagePruneTimeSelector,
pruneThreadIDsSelector,
-} from '../selectors/message-selectors';
+} from '../selectors/message-selectors.js';
function MessageStorePruner(): null {
const nextMessagePruneTime = useSelector(nextMessagePruneTimeSelector);
diff --git a/native/chat/message.react.js b/native/chat/message.react.js
--- a/native/chat/message.react.js
+++ b/native/chat/message.react.js
@@ -1,6 +1,6 @@
// @flow
-import _isEqual from 'lodash/fp/isEqual';
+import _isEqual from 'lodash/fp/isEqual.js';
import * as React from 'react';
import {
LayoutAnimation,
@@ -9,21 +9,21 @@
} from 'react-native';
import shallowequal from 'shallowequal';
-import { messageKey } from 'lib/shared/message-utils';
+import { messageKey } from 'lib/shared/message-utils.js';
import {
type KeyboardState,
KeyboardContext,
-} from '../keyboard/keyboard-state';
-import type { NavigationRoute } from '../navigation/route-names';
-import type { ChatMessageInfoItemWithHeight } from '../types/chat-types';
-import { type VerticalBounds } from '../types/layout-types';
-import type { LayoutEvent } from '../types/react-native';
-import type { ChatNavigationProp } from './chat.react';
-import MultimediaMessage from './multimedia-message.react';
-import { RobotextMessage } from './robotext-message.react';
-import { TextMessage } from './text-message.react';
-import { messageItemHeight } from './utils';
+} from '../keyboard/keyboard-state.js';
+import type { NavigationRoute } from '../navigation/route-names.js';
+import type { ChatMessageInfoItemWithHeight } from '../types/chat-types.js';
+import { type VerticalBounds } from '../types/layout-types.js';
+import type { LayoutEvent } from '../types/react-native.js';
+import type { ChatNavigationProp } from './chat.react.js';
+import MultimediaMessage from './multimedia-message.react.js';
+import { RobotextMessage } from './robotext-message.react.js';
+import { TextMessage } from './text-message.react.js';
+import { messageItemHeight } from './utils.js';
type BaseProps = {
+item: ChatMessageInfoItemWithHeight,
diff --git a/native/chat/multimedia-message-multimedia.react.js b/native/chat/multimedia-message-multimedia.react.js
--- a/native/chat/multimedia-message-multimedia.react.js
+++ b/native/chat/multimedia-message-multimedia.react.js
@@ -6,29 +6,29 @@
import { View, StyleSheet } from 'react-native';
import Animated from 'react-native-reanimated';
-import { type MediaInfo } from 'lib/types/media-types';
+import { type MediaInfo } from 'lib/types/media-types.js';
-import { type PendingMultimediaUpload } from '../input/input-state';
+import { type PendingMultimediaUpload } from '../input/input-state.js';
import {
type KeyboardState,
KeyboardContext,
-} from '../keyboard/keyboard-state';
+} from '../keyboard/keyboard-state.js';
import {
OverlayContext,
type OverlayContextType,
-} from '../navigation/overlay-context';
-import { ImageModalRouteName } from '../navigation/route-names';
-import { type Colors, useColors } from '../themes/colors';
-import type { ChatMultimediaMessageInfoItem } from '../types/chat-types';
-import { type VerticalBounds } from '../types/layout-types';
-import type { LayoutCoordinates } from '../types/layout-types';
+} from '../navigation/overlay-context.js';
+import { ImageModalRouteName } from '../navigation/route-names.js';
+import { type Colors, useColors } from '../themes/colors.js';
+import type { ChatMultimediaMessageInfoItem } from '../types/chat-types.js';
+import { type VerticalBounds } from '../types/layout-types.js';
+import type { LayoutCoordinates } from '../types/layout-types.js';
import {
type ViewStyle,
type AnimatedStyleObj,
AnimatedView,
-} from '../types/styles';
-import InlineMultimedia from './inline-multimedia.react';
-import { getMediaKey } from './multimedia-message-utils';
+} from '../types/styles.js';
+import InlineMultimedia from './inline-multimedia.react.js';
+import { getMediaKey } from './multimedia-message-utils.js';
/* eslint-disable import/no-named-as-default-member */
const { Node, sub, interpolateNode, Extrapolate } = Animated;
diff --git a/native/chat/multimedia-message-tooltip-button.react.js b/native/chat/multimedia-message-tooltip-button.react.js
--- a/native/chat/multimedia-message-tooltip-button.react.js
+++ b/native/chat/multimedia-message-tooltip-button.react.js
@@ -4,23 +4,23 @@
import Animated from 'react-native-reanimated';
import EmojiPicker from 'rn-emoji-keyboard';
-import { localIDPrefix } from 'lib/shared/message-utils';
-import { useCanCreateReactionFromMessage } from 'lib/shared/reaction-utils';
-
-import type { AppNavigationProp } from '../navigation/app-navigator.react';
-import { useSelector } from '../redux/redux-utils';
-import { useTooltipActions } from '../tooltip/tooltip-hooks';
-import type { TooltipRoute } from '../tooltip/tooltip.react';
-import { TooltipInlineEngagement } from './inline-engagement.react';
-import { InnerMultimediaMessage } from './inner-multimedia-message.react';
-import { MessageHeader } from './message-header.react';
+import { localIDPrefix } from 'lib/shared/message-utils.js';
+import { useCanCreateReactionFromMessage } from 'lib/shared/reaction-utils.js';
+
+import type { AppNavigationProp } from '../navigation/app-navigator.react.js';
+import { useSelector } from '../redux/redux-utils.js';
+import { useTooltipActions } from '../tooltip/tooltip-hooks.js';
+import type { TooltipRoute } from '../tooltip/tooltip.react.js';
+import { TooltipInlineEngagement } from './inline-engagement.react.js';
+import { InnerMultimediaMessage } from './inner-multimedia-message.react.js';
+import { MessageHeader } from './message-header.react.js';
import {
useSendReaction,
useReactionSelectionPopoverPosition,
-} from './reaction-message-utils';
-import ReactionSelectionPopover from './reaction-selection-popover.react';
-import SidebarInputBarHeightMeasurer from './sidebar-input-bar-height-measurer.react';
-import { useAnimatedMessageTooltipButton } from './utils';
+} from './reaction-message-utils.js';
+import ReactionSelectionPopover from './reaction-selection-popover.react.js';
+import SidebarInputBarHeightMeasurer from './sidebar-input-bar-height-measurer.react.js';
+import { useAnimatedMessageTooltipButton } from './utils.js';
/* eslint-disable import/no-named-as-default-member */
const { Node, Extrapolate, interpolateNode } = Animated;
diff --git a/native/chat/multimedia-message-tooltip-modal.react.js b/native/chat/multimedia-message-tooltip-modal.react.js
--- a/native/chat/multimedia-message-tooltip-modal.react.js
+++ b/native/chat/multimedia-message-tooltip-modal.react.js
@@ -2,18 +2,18 @@
import * as React from 'react';
-import SWMansionIcon from '../components/swmansion-icon.react';
+import SWMansionIcon from '../components/swmansion-icon.react.js';
import {
createTooltip,
type TooltipParams,
type BaseTooltipProps,
type TooltipMenuProps,
-} from '../tooltip/tooltip.react';
-import type { ChatMultimediaMessageInfoItem } from '../types/chat-types';
-import type { VerticalBounds } from '../types/layout-types';
-import { useOnPressReport } from './message-report-utils';
-import MultimediaMessageTooltipButton from './multimedia-message-tooltip-button.react';
-import { useAnimatedNavigateToSidebar } from './sidebar-navigation';
+} from '../tooltip/tooltip.react.js';
+import type { ChatMultimediaMessageInfoItem } from '../types/chat-types.js';
+import type { VerticalBounds } from '../types/layout-types.js';
+import { useOnPressReport } from './message-report-utils.js';
+import MultimediaMessageTooltipButton from './multimedia-message-tooltip-button.react.js';
+import { useAnimatedNavigateToSidebar } from './sidebar-navigation.js';
export type MultimediaMessageTooltipModalParams = TooltipParams<{
+item: ChatMultimediaMessageInfoItem,
diff --git a/native/chat/multimedia-message-utils.js b/native/chat/multimedia-message-utils.js
--- a/native/chat/multimedia-message-utils.js
+++ b/native/chat/multimedia-message-utils.js
@@ -2,17 +2,17 @@
import invariant from 'invariant';
-import { messageKey } from 'lib/shared/message-utils';
-import type { MediaInfo } from 'lib/types/media-types';
-import type { MultimediaMessageInfo } from 'lib/types/message-types';
+import { messageKey } from 'lib/shared/message-utils.js';
+import type { MediaInfo } from 'lib/types/media-types.js';
+import type { MultimediaMessageInfo } from 'lib/types/message-types.js';
import type {
ChatMultimediaMessageInfoItem,
MultimediaContentSizes,
-} from '../types/chat-types';
-import { inlineEngagementStyle, clusterEndHeight } from './chat-constants';
-import { failedSendHeight } from './failed-send.react';
-import { authorNameHeight } from './message-header.react';
+} from '../types/chat-types.js';
+import { inlineEngagementStyle, clusterEndHeight } from './chat-constants.js';
+import { failedSendHeight } from './failed-send.react.js';
+import { authorNameHeight } from './message-header.react.js';
const spaceBetweenImages = 4;
diff --git a/native/chat/multimedia-message.react.js b/native/chat/multimedia-message.react.js
--- a/native/chat/multimedia-message.react.js
+++ b/native/chat/multimedia-message.react.js
@@ -9,29 +9,29 @@
import * as React from 'react';
import { StyleSheet, View } from 'react-native';
-import { messageKey } from 'lib/shared/message-utils';
-import { useCanCreateSidebarFromMessage } from 'lib/shared/thread-utils';
-import type { MediaInfo } from 'lib/types/media-types';
+import { messageKey } from 'lib/shared/message-utils.js';
+import { useCanCreateSidebarFromMessage } from 'lib/shared/thread-utils.js';
+import type { MediaInfo } from 'lib/types/media-types.js';
-import { ChatContext, type ChatContextType } from '../chat/chat-context';
-import { OverlayContext } from '../navigation/overlay-context';
-import type { OverlayContextType } from '../navigation/overlay-context';
+import { ChatContext, type ChatContextType } from '../chat/chat-context.js';
+import { OverlayContext } from '../navigation/overlay-context.js';
+import type { OverlayContextType } from '../navigation/overlay-context.js';
import {
ImageModalRouteName,
MultimediaMessageTooltipModalRouteName,
VideoPlaybackModalRouteName,
-} from '../navigation/route-names';
-import { fixedTooltipHeight } from '../tooltip/tooltip.react';
-import type { ChatMultimediaMessageInfoItem } from '../types/chat-types';
-import { type VerticalBounds } from '../types/layout-types';
-import type { LayoutCoordinates } from '../types/layout-types';
-import ComposedMessage from './composed-message.react';
-import { InnerMultimediaMessage } from './inner-multimedia-message.react';
+} from '../navigation/route-names.js';
+import { fixedTooltipHeight } from '../tooltip/tooltip.react.js';
+import type { ChatMultimediaMessageInfoItem } from '../types/chat-types.js';
+import { type VerticalBounds } from '../types/layout-types.js';
+import type { LayoutCoordinates } from '../types/layout-types.js';
+import ComposedMessage from './composed-message.react.js';
+import { InnerMultimediaMessage } from './inner-multimedia-message.react.js';
import {
getMediaKey,
multimediaMessageSendFailed,
-} from './multimedia-message-utils';
-import { getMessageTooltipKey } from './utils';
+} from './multimedia-message-utils.js';
+import { getMessageTooltipKey } from './utils.js';
type BaseProps = {
...React.ElementConfig<typeof View>,
diff --git a/native/chat/new-messages-pill.react.js b/native/chat/new-messages-pill.react.js
--- a/native/chat/new-messages-pill.react.js
+++ b/native/chat/new-messages-pill.react.js
@@ -1,11 +1,11 @@
// @flow
-import Icon from '@expo/vector-icons/FontAwesome';
+import Icon from '@expo/vector-icons/FontAwesome.js';
import * as React from 'react';
import { TouchableOpacity, View, Text, Platform, Animated } from 'react-native';
-import { useStyles } from '../themes/colors';
-import type { ViewStyle } from '../types/styles';
+import { useStyles } from '../themes/colors.js';
+import type { ViewStyle } from '../types/styles.js';
type Props = {
+onPress: () => mixed,
diff --git a/native/chat/parent-thread-header.react.js b/native/chat/parent-thread-header.react.js
--- a/native/chat/parent-thread-header.react.js
+++ b/native/chat/parent-thread-header.react.js
@@ -4,13 +4,13 @@
import { View, Text } from 'react-native';
import { ScrollView } from 'react-native-gesture-handler';
-import type { ThreadInfo, ThreadType } from 'lib/types/thread-types';
+import type { ThreadInfo, ThreadType } from 'lib/types/thread-types.js';
-import Button from '../components/button.react';
-import CommunityPill from '../components/community-pill.react';
-import ThreadVisibility from '../components/thread-visibility.react';
-import { useColors, useStyles } from '../themes/colors';
-import { useNavigateToThread } from './message-list-types';
+import Button from '../components/button.react.js';
+import CommunityPill from '../components/community-pill.react.js';
+import ThreadVisibility from '../components/thread-visibility.react.js';
+import { useColors, useStyles } from '../themes/colors.js';
+import { useNavigateToThread } from './message-list-types.js';
type Props = {
+parentThreadInfo: ThreadInfo,
diff --git a/native/chat/reaction-message-utils.js b/native/chat/reaction-message-utils.js
--- a/native/chat/reaction-message-utils.js
+++ b/native/chat/reaction-message-utils.js
@@ -2,24 +2,27 @@
import invariant from 'invariant';
import * as React from 'react';
-import Alert from 'react-native/Libraries/Alert/Alert';
+import Alert from 'react-native/Libraries/Alert/Alert.js';
import {
sendReactionMessage,
sendReactionMessageActionTypes,
-} from 'lib/actions/message-actions';
-import type { MessageReactionInfo } from 'lib/selectors/chat-selectors';
-import { messageTypes } from 'lib/types/message-types';
-import type { RawReactionMessageInfo } from 'lib/types/messages/reaction';
+} from 'lib/actions/message-actions.js';
+import type { MessageReactionInfo } from 'lib/selectors/chat-selectors.js';
+import { messageTypes } from 'lib/types/message-types.js';
+import type { RawReactionMessageInfo } from 'lib/types/messages/reaction.js';
import {
useDispatchActionPromise,
useServerCall,
-} from 'lib/utils/action-utils';
-import { cloneError } from 'lib/utils/errors';
-
-import { useSelector } from '../redux/redux-utils';
-import type { LayoutCoordinates, VerticalBounds } from '../types/layout-types';
-import type { ViewStyle } from '../types/styles';
+} from 'lib/utils/action-utils.js';
+import { cloneError } from 'lib/utils/errors.js';
+
+import { useSelector } from '../redux/redux-utils.js';
+import type {
+ LayoutCoordinates,
+ VerticalBounds,
+} from '../types/layout-types.js';
+import type { ViewStyle } from '../types/styles.js';
function useSendReaction(
messageID: ?string,
diff --git a/native/chat/reaction-selection-popover.react.js b/native/chat/reaction-selection-popover.react.js
--- a/native/chat/reaction-selection-popover.react.js
+++ b/native/chat/reaction-selection-popover.react.js
@@ -3,13 +3,13 @@
import * as React from 'react';
import { View, TouchableOpacity, Text } from 'react-native';
-import SWMansionIcon from '../components/swmansion-icon.react';
-import type { AppNavigationProp } from '../navigation/app-navigator.react';
-import type { TooltipModalParamList } from '../navigation/route-names';
-import { useStyles } from '../themes/colors';
-import { useTooltipActions } from '../tooltip/tooltip-hooks';
-import type { TooltipRoute } from '../tooltip/tooltip.react';
-import type { ViewStyle } from '../types/styles';
+import SWMansionIcon from '../components/swmansion-icon.react.js';
+import type { AppNavigationProp } from '../navigation/app-navigator.react.js';
+import type { TooltipModalParamList } from '../navigation/route-names.js';
+import { useStyles } from '../themes/colors.js';
+import { useTooltipActions } from '../tooltip/tooltip-hooks.js';
+import type { TooltipRoute } from '../tooltip/tooltip.react.js';
+import type { ViewStyle } from '../types/styles.js';
type Props<RouteName: $Keys<TooltipModalParamList>> = {
+navigation: AppNavigationProp<RouteName>,
diff --git a/native/chat/relationship-prompt.react.js b/native/chat/relationship-prompt.react.js
--- a/native/chat/relationship-prompt.react.js
+++ b/native/chat/relationship-prompt.react.js
@@ -1,16 +1,16 @@
// @flow
-import Icon from '@expo/vector-icons/FontAwesome5';
+import Icon from '@expo/vector-icons/FontAwesome5.js';
import * as React from 'react';
import { Alert, Text, View } from 'react-native';
-import { useRelationshipPrompt } from 'lib/hooks/relationship-prompt';
-import { userRelationshipStatus } from 'lib/types/relationship-types';
-import type { ThreadInfo } from 'lib/types/thread-types';
-import type { UserInfo } from 'lib/types/user-types';
+import { useRelationshipPrompt } from 'lib/hooks/relationship-prompt.js';
+import { userRelationshipStatus } from 'lib/types/relationship-types.js';
+import type { ThreadInfo } from 'lib/types/thread-types.js';
+import type { UserInfo } from 'lib/types/user-types.js';
-import Button from '../components/button.react';
-import { useStyles } from '../themes/colors';
+import Button from '../components/button.react.js';
+import { useStyles } from '../themes/colors.js';
type Props = {
+pendingPersonalThreadUserInfo: ?UserInfo,
diff --git a/native/chat/robotext-message-tooltip-button.react.js b/native/chat/robotext-message-tooltip-button.react.js
--- a/native/chat/robotext-message-tooltip-button.react.js
+++ b/native/chat/robotext-message-tooltip-button.react.js
@@ -4,23 +4,23 @@
import Animated from 'react-native-reanimated';
import EmojiPicker from 'rn-emoji-keyboard';
-import { localIDPrefix } from 'lib/shared/message-utils';
-import { useCanCreateReactionFromMessage } from 'lib/shared/reaction-utils';
-
-import type { AppNavigationProp } from '../navigation/app-navigator.react';
-import { useSelector } from '../redux/redux-utils';
-import { useTooltipActions } from '../tooltip/tooltip-hooks';
-import type { TooltipRoute } from '../tooltip/tooltip.react';
-import { TooltipInlineEngagement } from './inline-engagement.react';
-import { InnerRobotextMessage } from './inner-robotext-message.react';
+import { localIDPrefix } from 'lib/shared/message-utils.js';
+import { useCanCreateReactionFromMessage } from 'lib/shared/reaction-utils.js';
+
+import type { AppNavigationProp } from '../navigation/app-navigator.react.js';
+import { useSelector } from '../redux/redux-utils.js';
+import { useTooltipActions } from '../tooltip/tooltip-hooks.js';
+import type { TooltipRoute } from '../tooltip/tooltip.react.js';
+import { TooltipInlineEngagement } from './inline-engagement.react.js';
+import { InnerRobotextMessage } from './inner-robotext-message.react.js';
import {
useSendReaction,
useReactionSelectionPopoverPosition,
-} from './reaction-message-utils';
-import ReactionSelectionPopover from './reaction-selection-popover.react';
-import SidebarInputBarHeightMeasurer from './sidebar-input-bar-height-measurer.react';
-import { Timestamp } from './timestamp.react';
-import { useAnimatedMessageTooltipButton } from './utils';
+} from './reaction-message-utils.js';
+import ReactionSelectionPopover from './reaction-selection-popover.react.js';
+import SidebarInputBarHeightMeasurer from './sidebar-input-bar-height-measurer.react.js';
+import { Timestamp } from './timestamp.react.js';
+import { useAnimatedMessageTooltipButton } from './utils.js';
/* eslint-disable import/no-named-as-default-member */
const { Node, interpolateNode, Extrapolate } = Animated;
diff --git a/native/chat/robotext-message-tooltip-modal.react.js b/native/chat/robotext-message-tooltip-modal.react.js
--- a/native/chat/robotext-message-tooltip-modal.react.js
+++ b/native/chat/robotext-message-tooltip-modal.react.js
@@ -2,16 +2,16 @@
import * as React from 'react';
-import SWMansionIcon from '../components/swmansion-icon.react';
+import SWMansionIcon from '../components/swmansion-icon.react.js';
import {
createTooltip,
type TooltipParams,
type BaseTooltipProps,
type TooltipMenuProps,
-} from '../tooltip/tooltip.react';
-import type { ChatRobotextMessageInfoItemWithHeight } from '../types/chat-types';
-import RobotextMessageTooltipButton from './robotext-message-tooltip-button.react';
-import { useAnimatedNavigateToSidebar } from './sidebar-navigation';
+} from '../tooltip/tooltip.react.js';
+import type { ChatRobotextMessageInfoItemWithHeight } from '../types/chat-types.js';
+import RobotextMessageTooltipButton from './robotext-message-tooltip-button.react.js';
+import { useAnimatedNavigateToSidebar } from './sidebar-navigation.js';
export type RobotextMessageTooltipModalParams = TooltipParams<{
+item: ChatRobotextMessageInfoItemWithHeight,
diff --git a/native/chat/robotext-message.react.js b/native/chat/robotext-message.react.js
--- a/native/chat/robotext-message.react.js
+++ b/native/chat/robotext-message.react.js
@@ -4,25 +4,25 @@
import * as React from 'react';
import { View } from 'react-native';
-import { messageKey } from 'lib/shared/message-utils';
-import { useCanCreateSidebarFromMessage } from 'lib/shared/thread-utils';
-
-import { ChatContext } from '../chat/chat-context';
-import { KeyboardContext } from '../keyboard/keyboard-state';
-import { OverlayContext } from '../navigation/overlay-context';
-import { RobotextMessageTooltipModalRouteName } from '../navigation/route-names';
-import type { NavigationRoute } from '../navigation/route-names';
-import { useStyles } from '../themes/colors';
-import { fixedTooltipHeight } from '../tooltip/tooltip.react';
-import type { ChatRobotextMessageInfoItemWithHeight } from '../types/chat-types';
-import type { VerticalBounds } from '../types/layout-types';
-import { AnimatedView } from '../types/styles';
-import { inlineEngagementCenterStyle } from './chat-constants';
-import type { ChatNavigationProp } from './chat.react';
-import { InlineEngagement } from './inline-engagement.react';
-import { InnerRobotextMessage } from './inner-robotext-message.react';
-import { Timestamp } from './timestamp.react';
-import { getMessageTooltipKey, useContentAndHeaderOpacity } from './utils';
+import { messageKey } from 'lib/shared/message-utils.js';
+import { useCanCreateSidebarFromMessage } from 'lib/shared/thread-utils.js';
+
+import { ChatContext } from '../chat/chat-context.js';
+import { KeyboardContext } from '../keyboard/keyboard-state.js';
+import { OverlayContext } from '../navigation/overlay-context.js';
+import { RobotextMessageTooltipModalRouteName } from '../navigation/route-names.js';
+import type { NavigationRoute } from '../navigation/route-names.js';
+import { useStyles } from '../themes/colors.js';
+import { fixedTooltipHeight } from '../tooltip/tooltip.react.js';
+import type { ChatRobotextMessageInfoItemWithHeight } from '../types/chat-types.js';
+import type { VerticalBounds } from '../types/layout-types.js';
+import { AnimatedView } from '../types/styles.js';
+import { inlineEngagementCenterStyle } from './chat-constants.js';
+import type { ChatNavigationProp } from './chat.react.js';
+import { InlineEngagement } from './inline-engagement.react.js';
+import { InnerRobotextMessage } from './inner-robotext-message.react.js';
+import { Timestamp } from './timestamp.react.js';
+import { getMessageTooltipKey, useContentAndHeaderOpacity } from './utils.js';
type Props = {
...React.ElementConfig<typeof View>,
diff --git a/native/chat/rounded-corners.js b/native/chat/rounded-corners.js
--- a/native/chat/rounded-corners.js
+++ b/native/chat/rounded-corners.js
@@ -1,8 +1,8 @@
// @flow
-import type { Corners } from 'lib/types/media-types';
+import type { Corners } from 'lib/types/media-types.js';
-import type { ChatMessageInfoItemWithHeight } from '../types/chat-types';
+import type { ChatMessageInfoItemWithHeight } from '../types/chat-types.js';
type FilteredCorners = {
+bottomLeft: void | boolean,
diff --git a/native/chat/settings/add-users-modal.react.js b/native/chat/settings/add-users-modal.react.js
--- a/native/chat/settings/add-users-modal.react.js
+++ b/native/chat/settings/add-users-modal.react.js
@@ -7,31 +7,31 @@
import {
changeThreadSettingsActionTypes,
changeThreadSettings,
-} from 'lib/actions/thread-actions';
-import { useENSNames } from 'lib/hooks/ens-cache';
-import { createLoadingStatusSelector } from 'lib/selectors/loading-selectors';
-import { threadInfoSelector } from 'lib/selectors/thread-selectors';
+} from 'lib/actions/thread-actions.js';
+import { useENSNames } from 'lib/hooks/ens-cache.js';
+import { createLoadingStatusSelector } from 'lib/selectors/loading-selectors.js';
+import { threadInfoSelector } from 'lib/selectors/thread-selectors.js';
import {
userInfoSelectorForPotentialMembers,
userSearchIndexForPotentialMembers,
-} from 'lib/selectors/user-selectors';
-import { getPotentialMemberItems } from 'lib/shared/search-utils';
-import { threadActualMembers } from 'lib/shared/thread-utils';
-import { type ThreadInfo } from 'lib/types/thread-types';
-import { type AccountUserInfo } from 'lib/types/user-types';
+} from 'lib/selectors/user-selectors.js';
+import { getPotentialMemberItems } from 'lib/shared/search-utils.js';
+import { threadActualMembers } from 'lib/shared/thread-utils.js';
+import { type ThreadInfo } from 'lib/types/thread-types.js';
+import { type AccountUserInfo } from 'lib/types/user-types.js';
import {
useServerCall,
useDispatchActionPromise,
-} from 'lib/utils/action-utils';
+} from 'lib/utils/action-utils.js';
-import Button from '../../components/button.react';
-import Modal from '../../components/modal.react';
-import { createTagInput } from '../../components/tag-input.react';
-import UserList from '../../components/user-list.react';
-import type { RootNavigationProp } from '../../navigation/root-navigator.react';
-import type { NavigationRoute } from '../../navigation/route-names';
-import { useSelector } from '../../redux/redux-utils';
-import { useStyles } from '../../themes/colors';
+import Button from '../../components/button.react.js';
+import Modal from '../../components/modal.react.js';
+import { createTagInput } from '../../components/tag-input.react.js';
+import UserList from '../../components/user-list.react.js';
+import type { RootNavigationProp } from '../../navigation/root-navigator.react.js';
+import type { NavigationRoute } from '../../navigation/route-names.js';
+import { useSelector } from '../../redux/redux-utils.js';
+import { useStyles } from '../../themes/colors.js';
const TagInput = createTagInput<AccountUserInfo>();
diff --git a/native/chat/settings/color-selector-modal.react.js b/native/chat/settings/color-selector-modal.react.js
--- a/native/chat/settings/color-selector-modal.react.js
+++ b/native/chat/settings/color-selector-modal.react.js
@@ -1,30 +1,30 @@
// @flow
-import Icon from '@expo/vector-icons/FontAwesome';
+import Icon from '@expo/vector-icons/FontAwesome.js';
import * as React from 'react';
import { TouchableHighlight, Alert } from 'react-native';
import {
changeThreadSettingsActionTypes,
changeThreadSettings,
-} from 'lib/actions/thread-actions';
+} from 'lib/actions/thread-actions.js';
import {
type ThreadInfo,
type ChangeThreadSettingsPayload,
type UpdateThreadRequest,
-} from 'lib/types/thread-types';
-import type { DispatchActionPromise } from 'lib/utils/action-utils';
+} from 'lib/types/thread-types.js';
+import type { DispatchActionPromise } from 'lib/utils/action-utils.js';
import {
useServerCall,
useDispatchActionPromise,
-} from 'lib/utils/action-utils';
-
-import ColorSelector from '../../components/color-selector.react';
-import Modal from '../../components/modal.react';
-import type { RootNavigationProp } from '../../navigation/root-navigator.react';
-import type { NavigationRoute } from '../../navigation/route-names';
-import { useSelector } from '../../redux/redux-utils';
-import { type Colors, useStyles, useColors } from '../../themes/colors';
+} from 'lib/utils/action-utils.js';
+
+import ColorSelector from '../../components/color-selector.react.js';
+import Modal from '../../components/modal.react.js';
+import type { RootNavigationProp } from '../../navigation/root-navigator.react.js';
+import type { NavigationRoute } from '../../navigation/route-names.js';
+import { useSelector } from '../../redux/redux-utils.js';
+import { type Colors, useStyles, useColors } from '../../themes/colors.js';
export type ColorSelectorModalParams = {
+presentedFrom: string,
diff --git a/native/chat/settings/compose-subchannel-modal.react.js b/native/chat/settings/compose-subchannel-modal.react.js
--- a/native/chat/settings/compose-subchannel-modal.react.js
+++ b/native/chat/settings/compose-subchannel-modal.react.js
@@ -1,19 +1,19 @@
// @flow
-import IonIcon from '@expo/vector-icons/Ionicons';
+import IonIcon from '@expo/vector-icons/Ionicons.js';
import * as React from 'react';
import { Text } from 'react-native';
-import { threadTypeDescriptions } from 'lib/shared/thread-utils';
-import { type ThreadInfo, threadTypes } from 'lib/types/thread-types';
+import { threadTypeDescriptions } from 'lib/shared/thread-utils.js';
+import { type ThreadInfo, threadTypes } from 'lib/types/thread-types.js';
-import Button from '../../components/button.react';
-import Modal from '../../components/modal.react';
-import SWMansionIcon from '../../components/swmansion-icon.react';
-import type { RootNavigationProp } from '../../navigation/root-navigator.react';
-import type { NavigationRoute } from '../../navigation/route-names';
-import { ComposeSubchannelRouteName } from '../../navigation/route-names';
-import { type Colors, useStyles, useColors } from '../../themes/colors';
+import Button from '../../components/button.react.js';
+import Modal from '../../components/modal.react.js';
+import SWMansionIcon from '../../components/swmansion-icon.react.js';
+import type { RootNavigationProp } from '../../navigation/root-navigator.react.js';
+import type { NavigationRoute } from '../../navigation/route-names.js';
+import { ComposeSubchannelRouteName } from '../../navigation/route-names.js';
+import { type Colors, useStyles, useColors } from '../../themes/colors.js';
export type ComposeSubchannelModalParams = {
+presentedFrom: string,
diff --git a/native/chat/settings/delete-thread.react.js b/native/chat/settings/delete-thread.react.js
--- a/native/chat/settings/delete-thread.react.js
+++ b/native/chat/settings/delete-thread.react.js
@@ -14,34 +14,34 @@
import {
deleteThreadActionTypes,
deleteThread,
-} from 'lib/actions/thread-actions';
-import { createLoadingStatusSelector } from 'lib/selectors/loading-selectors';
-import { threadInfoSelector } from 'lib/selectors/thread-selectors';
-import { identifyInvalidatedThreads } from 'lib/shared/thread-utils';
-import type { LoadingStatus } from 'lib/types/loading-types';
+} from 'lib/actions/thread-actions.js';
+import { createLoadingStatusSelector } from 'lib/selectors/loading-selectors.js';
+import { threadInfoSelector } from 'lib/selectors/thread-selectors.js';
+import { identifyInvalidatedThreads } from 'lib/shared/thread-utils.js';
+import type { LoadingStatus } from 'lib/types/loading-types.js';
import type {
ThreadInfo,
ResolvedThreadInfo,
LeaveThreadPayload,
-} from 'lib/types/thread-types';
+} from 'lib/types/thread-types.js';
import {
useServerCall,
useDispatchActionPromise,
type DispatchActionPromise,
-} from 'lib/utils/action-utils';
-import { useResolvedThreadInfo } from 'lib/utils/entity-helpers';
+} from 'lib/utils/action-utils.js';
+import { useResolvedThreadInfo } from 'lib/utils/entity-helpers.js';
-import Button from '../../components/button.react';
-import { clearThreadsActionType } from '../../navigation/action-types';
+import Button from '../../components/button.react.js';
+import { clearThreadsActionType } from '../../navigation/action-types.js';
import {
NavContext,
type NavAction,
-} from '../../navigation/navigation-context';
-import type { NavigationRoute } from '../../navigation/route-names';
-import { useSelector } from '../../redux/redux-utils';
-import { type Colors, useColors, useStyles } from '../../themes/colors';
-import type { GlobalTheme } from '../../types/themes';
-import type { ChatNavigationProp } from '../chat.react';
+} from '../../navigation/navigation-context.js';
+import type { NavigationRoute } from '../../navigation/route-names.js';
+import { useSelector } from '../../redux/redux-utils.js';
+import { type Colors, useColors, useStyles } from '../../themes/colors.js';
+import type { GlobalTheme } from '../../types/themes.js';
+import type { ChatNavigationProp } from '../chat.react.js';
export type DeleteThreadParams = {
+threadInfo: ThreadInfo,
diff --git a/native/chat/settings/save-setting-button.react.js b/native/chat/settings/save-setting-button.react.js
--- a/native/chat/settings/save-setting-button.react.js
+++ b/native/chat/settings/save-setting-button.react.js
@@ -3,8 +3,8 @@
import * as React from 'react';
import { TouchableOpacity } from 'react-native';
-import SWMansionIcon from '../../components/swmansion-icon.react';
-import { useStyles } from '../../themes/colors';
+import SWMansionIcon from '../../components/swmansion-icon.react.js';
+import { useStyles } from '../../themes/colors.js';
type Props = {
+onPress: () => void,
diff --git a/native/chat/settings/thread-settings-category.react.js b/native/chat/settings/thread-settings-category.react.js
--- a/native/chat/settings/thread-settings-category.react.js
+++ b/native/chat/settings/thread-settings-category.react.js
@@ -4,7 +4,7 @@
import * as React from 'react';
import { View, Text, Platform } from 'react-native';
-import { useStyles } from '../../themes/colors';
+import { useStyles } from '../../themes/colors.js';
export type CategoryType = 'full' | 'outline' | 'unpadded';
type HeaderProps = {
diff --git a/native/chat/settings/thread-settings-child-thread.react.js b/native/chat/settings/thread-settings-child-thread.react.js
--- a/native/chat/settings/thread-settings-child-thread.react.js
+++ b/native/chat/settings/thread-settings-child-thread.react.js
@@ -3,13 +3,13 @@
import * as React from 'react';
import { View, Platform } from 'react-native';
-import type { ThreadInfo } from 'lib/types/thread-types';
+import type { ThreadInfo } from 'lib/types/thread-types.js';
-import Button from '../../components/button.react';
-import ThreadIcon from '../../components/thread-icon.react';
-import ThreadPill from '../../components/thread-pill.react';
-import { useColors, useStyles } from '../../themes/colors';
-import { useNavigateToThread } from '../message-list-types';
+import Button from '../../components/button.react.js';
+import ThreadIcon from '../../components/thread-icon.react.js';
+import ThreadPill from '../../components/thread-pill.react.js';
+import { useColors, useStyles } from '../../themes/colors.js';
+import { useNavigateToThread } from '../message-list-types.js';
type Props = {
+threadInfo: ThreadInfo,
diff --git a/native/chat/settings/thread-settings-color.react.js b/native/chat/settings/thread-settings-color.react.js
--- a/native/chat/settings/thread-settings-color.react.js
+++ b/native/chat/settings/thread-settings-color.react.js
@@ -3,17 +3,17 @@
import * as React from 'react';
import { Text, ActivityIndicator, View, Platform } from 'react-native';
-import { changeThreadSettingsActionTypes } from 'lib/actions/thread-actions';
-import { createLoadingStatusSelector } from 'lib/selectors/loading-selectors';
-import type { LoadingStatus } from 'lib/types/loading-types';
-import { type ThreadInfo } from 'lib/types/thread-types';
+import { changeThreadSettingsActionTypes } from 'lib/actions/thread-actions.js';
+import { createLoadingStatusSelector } from 'lib/selectors/loading-selectors.js';
+import type { LoadingStatus } from 'lib/types/loading-types.js';
+import { type ThreadInfo } from 'lib/types/thread-types.js';
-import ColorSplotch from '../../components/color-splotch.react';
-import EditSettingButton from '../../components/edit-setting-button.react';
-import { ColorSelectorModalRouteName } from '../../navigation/route-names';
-import { useSelector } from '../../redux/redux-utils';
-import { type Colors, useColors, useStyles } from '../../themes/colors';
-import type { ThreadSettingsNavigate } from './thread-settings.react';
+import ColorSplotch from '../../components/color-splotch.react.js';
+import EditSettingButton from '../../components/edit-setting-button.react.js';
+import { ColorSelectorModalRouteName } from '../../navigation/route-names.js';
+import { useSelector } from '../../redux/redux-utils.js';
+import { type Colors, useColors, useStyles } from '../../themes/colors.js';
+import type { ThreadSettingsNavigate } from './thread-settings.react.js';
type BaseProps = {
+threadInfo: ThreadInfo,
diff --git a/native/chat/settings/thread-settings-delete-thread.react.js b/native/chat/settings/thread-settings-delete-thread.react.js
--- a/native/chat/settings/thread-settings-delete-thread.react.js
+++ b/native/chat/settings/thread-settings-delete-thread.react.js
@@ -3,13 +3,13 @@
import * as React from 'react';
import { Text, View } from 'react-native';
-import type { ResolvedThreadInfo } from 'lib/types/thread-types';
+import type { ResolvedThreadInfo } from 'lib/types/thread-types.js';
-import Button from '../../components/button.react';
-import { DeleteThreadRouteName } from '../../navigation/route-names';
-import { useColors, useStyles } from '../../themes/colors';
-import type { ViewStyle } from '../../types/styles';
-import type { ThreadSettingsNavigate } from './thread-settings.react';
+import Button from '../../components/button.react.js';
+import { DeleteThreadRouteName } from '../../navigation/route-names.js';
+import { useColors, useStyles } from '../../themes/colors.js';
+import type { ViewStyle } from '../../types/styles.js';
+import type { ThreadSettingsNavigate } from './thread-settings.react.js';
type Props = {
+threadInfo: ResolvedThreadInfo,
diff --git a/native/chat/settings/thread-settings-description.react.js b/native/chat/settings/thread-settings-description.react.js
--- a/native/chat/settings/thread-settings-description.react.js
+++ b/native/chat/settings/thread-settings-description.react.js
@@ -13,37 +13,37 @@
import {
changeThreadSettingsActionTypes,
changeThreadSettings,
-} from 'lib/actions/thread-actions';
-import { createLoadingStatusSelector } from 'lib/selectors/loading-selectors';
-import { threadHasPermission } from 'lib/shared/thread-utils';
-import type { LoadingStatus } from 'lib/types/loading-types';
+} from 'lib/actions/thread-actions.js';
+import { createLoadingStatusSelector } from 'lib/selectors/loading-selectors.js';
+import { threadHasPermission } from 'lib/shared/thread-utils.js';
+import type { LoadingStatus } from 'lib/types/loading-types.js';
import {
type ThreadInfo,
threadPermissions,
type ChangeThreadSettingsPayload,
type UpdateThreadRequest,
-} from 'lib/types/thread-types';
+} from 'lib/types/thread-types.js';
import {
type DispatchActionPromise,
useServerCall,
useDispatchActionPromise,
-} from 'lib/utils/action-utils';
+} from 'lib/utils/action-utils.js';
-import Button from '../../components/button.react';
-import EditSettingButton from '../../components/edit-setting-button.react';
-import SWMansionIcon from '../../components/swmansion-icon.react';
-import TextInput from '../../components/text-input.react';
-import { useSelector } from '../../redux/redux-utils';
-import { type Colors, useStyles, useColors } from '../../themes/colors';
+import Button from '../../components/button.react.js';
+import EditSettingButton from '../../components/edit-setting-button.react.js';
+import SWMansionIcon from '../../components/swmansion-icon.react.js';
+import TextInput from '../../components/text-input.react.js';
+import { useSelector } from '../../redux/redux-utils.js';
+import { type Colors, useStyles, useColors } from '../../themes/colors.js';
import type {
LayoutEvent,
ContentSizeChangeEvent,
-} from '../../types/react-native';
-import SaveSettingButton from './save-setting-button.react';
+} from '../../types/react-native.js';
+import SaveSettingButton from './save-setting-button.react.js';
import {
ThreadSettingsCategoryHeader,
ThreadSettingsCategoryFooter,
-} from './thread-settings-category.react';
+} from './thread-settings-category.react.js';
type BaseProps = {
+threadInfo: ThreadInfo,
diff --git a/native/chat/settings/thread-settings-edit-relationship.react.js b/native/chat/settings/thread-settings-edit-relationship.react.js
--- a/native/chat/settings/thread-settings-edit-relationship.react.js
+++ b/native/chat/settings/thread-settings-edit-relationship.react.js
@@ -7,27 +7,27 @@
import {
updateRelationships as serverUpdateRelationships,
updateRelationshipsActionTypes,
-} from 'lib/actions/relationship-actions';
-import { useENSNames } from 'lib/hooks/ens-cache';
+} from 'lib/actions/relationship-actions.js';
+import { useENSNames } from 'lib/hooks/ens-cache.js';
import {
getRelationshipActionText,
getRelationshipDispatchAction,
-} from 'lib/shared/relationship-utils';
-import { getSingleOtherUser } from 'lib/shared/thread-utils';
+} from 'lib/shared/relationship-utils.js';
+import { getSingleOtherUser } from 'lib/shared/thread-utils.js';
import {
type RelationshipAction,
type RelationshipButton,
-} from 'lib/types/relationship-types';
-import type { ThreadInfo } from 'lib/types/thread-types';
+} from 'lib/types/relationship-types.js';
+import type { ThreadInfo } from 'lib/types/thread-types.js';
import {
useDispatchActionPromise,
useServerCall,
-} from 'lib/utils/action-utils';
+} from 'lib/utils/action-utils.js';
-import Button from '../../components/button.react';
-import { useSelector } from '../../redux/redux-utils';
-import { useStyles, useColors } from '../../themes/colors';
-import type { ViewStyle } from '../../types/styles';
+import Button from '../../components/button.react.js';
+import { useSelector } from '../../redux/redux-utils.js';
+import { useStyles, useColors } from '../../themes/colors.js';
+import type { ViewStyle } from '../../types/styles.js';
type Props = {
+threadInfo: ThreadInfo,
diff --git a/native/chat/settings/thread-settings-home-notifs.react.js b/native/chat/settings/thread-settings-home-notifs.react.js
--- a/native/chat/settings/thread-settings-home-notifs.react.js
+++ b/native/chat/settings/thread-settings-home-notifs.react.js
@@ -6,20 +6,20 @@
import {
updateSubscriptionActionTypes,
updateSubscription,
-} from 'lib/actions/user-actions';
+} from 'lib/actions/user-actions.js';
import type {
SubscriptionUpdateRequest,
SubscriptionUpdateResult,
-} from 'lib/types/subscription-types';
-import { type ThreadInfo } from 'lib/types/thread-types';
-import type { DispatchActionPromise } from 'lib/utils/action-utils';
+} from 'lib/types/subscription-types.js';
+import { type ThreadInfo } from 'lib/types/thread-types.js';
+import type { DispatchActionPromise } from 'lib/utils/action-utils.js';
import {
useServerCall,
useDispatchActionPromise,
-} from 'lib/utils/action-utils';
+} from 'lib/utils/action-utils.js';
-import { SingleLine } from '../../components/single-line.react';
-import { useStyles } from '../../themes/colors';
+import { SingleLine } from '../../components/single-line.react.js';
+import { useStyles } from '../../themes/colors.js';
type BaseProps = {
+threadInfo: ThreadInfo,
diff --git a/native/chat/settings/thread-settings-leave-thread.react.js b/native/chat/settings/thread-settings-leave-thread.react.js
--- a/native/chat/settings/thread-settings-leave-thread.react.js
+++ b/native/chat/settings/thread-settings-leave-thread.react.js
@@ -7,27 +7,27 @@
import {
leaveThreadActionTypes,
leaveThread,
-} from 'lib/actions/thread-actions';
-import { createLoadingStatusSelector } from 'lib/selectors/loading-selectors';
-import { otherUsersButNoOtherAdmins } from 'lib/selectors/thread-selectors';
-import { identifyInvalidatedThreads } from 'lib/shared/thread-utils';
-import type { LoadingStatus } from 'lib/types/loading-types';
-import type { ThreadInfo, LeaveThreadPayload } from 'lib/types/thread-types';
+} from 'lib/actions/thread-actions.js';
+import { createLoadingStatusSelector } from 'lib/selectors/loading-selectors.js';
+import { otherUsersButNoOtherAdmins } from 'lib/selectors/thread-selectors.js';
+import { identifyInvalidatedThreads } from 'lib/shared/thread-utils.js';
+import type { LoadingStatus } from 'lib/types/loading-types.js';
+import type { ThreadInfo, LeaveThreadPayload } from 'lib/types/thread-types.js';
import {
type DispatchActionPromise,
useServerCall,
useDispatchActionPromise,
-} from 'lib/utils/action-utils';
+} from 'lib/utils/action-utils.js';
-import Button from '../../components/button.react';
-import { clearThreadsActionType } from '../../navigation/action-types';
+import Button from '../../components/button.react.js';
+import { clearThreadsActionType } from '../../navigation/action-types.js';
import {
NavContext,
type NavContextType,
-} from '../../navigation/navigation-context';
-import { useSelector } from '../../redux/redux-utils';
-import { type Colors, useColors, useStyles } from '../../themes/colors';
-import type { ViewStyle } from '../../types/styles';
+} from '../../navigation/navigation-context.js';
+import { useSelector } from '../../redux/redux-utils.js';
+import { type Colors, useColors, useStyles } from '../../themes/colors.js';
+import type { ViewStyle } from '../../types/styles.js';
type BaseProps = {
+threadInfo: ThreadInfo,
diff --git a/native/chat/settings/thread-settings-list-action.react.js b/native/chat/settings/thread-settings-list-action.react.js
--- a/native/chat/settings/thread-settings-list-action.react.js
+++ b/native/chat/settings/thread-settings-list-action.react.js
@@ -1,13 +1,13 @@
// @flow
import type { IoniconsGlyphs } from '@expo/vector-icons';
-import Icon from '@expo/vector-icons/Ionicons';
+import Icon from '@expo/vector-icons/Ionicons.js';
import * as React from 'react';
import { View, Text, Platform } from 'react-native';
-import Button from '../../components/button.react';
-import { useStyles } from '../../themes/colors';
-import type { ViewStyle, TextStyle } from '../../types/styles';
+import Button from '../../components/button.react.js';
+import { useStyles } from '../../themes/colors.js';
+import type { ViewStyle, TextStyle } from '../../types/styles.js';
type ListActionProps = {
+onPress: () => void,
diff --git a/native/chat/settings/thread-settings-member-tooltip-button.react.js b/native/chat/settings/thread-settings-member-tooltip-button.react.js
--- a/native/chat/settings/thread-settings-member-tooltip-button.react.js
+++ b/native/chat/settings/thread-settings-member-tooltip-button.react.js
@@ -3,8 +3,8 @@
import * as React from 'react';
import { TouchableOpacity } from 'react-native';
-import PencilIcon from '../../components/pencil-icon.react';
-import type { AppNavigationProp } from '../../navigation/app-navigator.react';
+import PencilIcon from '../../components/pencil-icon.react.js';
+import type { AppNavigationProp } from '../../navigation/app-navigator.react.js';
type Props = {
+navigation: AppNavigationProp<'ThreadSettingsMemberTooltipModal'>,
diff --git a/native/chat/settings/thread-settings-member-tooltip-modal.react.js b/native/chat/settings/thread-settings-member-tooltip-modal.react.js
--- a/native/chat/settings/thread-settings-member-tooltip-modal.react.js
+++ b/native/chat/settings/thread-settings-member-tooltip-modal.react.js
@@ -6,18 +6,18 @@
import {
removeUsersFromThread,
changeThreadMemberRoles,
-} from 'lib/actions/thread-actions';
+} from 'lib/actions/thread-actions.js';
import {
memberIsAdmin,
removeMemberFromThread,
switchMemberAdminRoleInThread,
-} from 'lib/shared/thread-utils';
-import { stringForUser } from 'lib/shared/user-utils';
-import type { ThreadInfo, RelativeMemberInfo } from 'lib/types/thread-types';
+} from 'lib/shared/thread-utils.js';
+import { stringForUser } from 'lib/shared/user-utils.js';
+import type { ThreadInfo, RelativeMemberInfo } from 'lib/types/thread-types.js';
import {
useDispatchActionPromise,
useServerCall,
-} from 'lib/utils/action-utils';
+} from 'lib/utils/action-utils.js';
import {
createTooltip,
@@ -25,8 +25,8 @@
type TooltipRoute,
type BaseTooltipProps,
type TooltipMenuProps,
-} from '../../tooltip/tooltip.react';
-import ThreadSettingsMemberTooltipButton from './thread-settings-member-tooltip-button.react';
+} from '../../tooltip/tooltip.react.js';
+import ThreadSettingsMemberTooltipButton from './thread-settings-member-tooltip-button.react.js';
export type ThreadSettingsMemberTooltipModalParams = TooltipParams<{
+memberInfo: RelativeMemberInfo,
diff --git a/native/chat/settings/thread-settings-member.react.js b/native/chat/settings/thread-settings-member.react.js
--- a/native/chat/settings/thread-settings-member.react.js
+++ b/native/chat/settings/thread-settings-member.react.js
@@ -13,36 +13,36 @@
import {
removeUsersFromThreadActionTypes,
changeThreadMemberRolesActionTypes,
-} from 'lib/actions/thread-actions';
-import { useENSNames } from 'lib/hooks/ens-cache';
-import { createLoadingStatusSelector } from 'lib/selectors/loading-selectors';
+} from 'lib/actions/thread-actions.js';
+import { useENSNames } from 'lib/hooks/ens-cache.js';
+import { createLoadingStatusSelector } from 'lib/selectors/loading-selectors.js';
import {
memberIsAdmin,
memberHasAdminPowers,
getAvailableThreadMemberActions,
-} from 'lib/shared/thread-utils';
-import { stringForUser } from 'lib/shared/user-utils';
-import type { LoadingStatus } from 'lib/types/loading-types';
+} from 'lib/shared/thread-utils.js';
+import { stringForUser } from 'lib/shared/user-utils.js';
+import type { LoadingStatus } from 'lib/types/loading-types.js';
import {
type ThreadInfo,
type RelativeMemberInfo,
-} from 'lib/types/thread-types';
+} from 'lib/types/thread-types.js';
-import PencilIcon from '../../components/pencil-icon.react';
-import { SingleLine } from '../../components/single-line.react';
+import PencilIcon from '../../components/pencil-icon.react.js';
+import { SingleLine } from '../../components/single-line.react.js';
import {
type KeyboardState,
KeyboardContext,
-} from '../../keyboard/keyboard-state';
+} from '../../keyboard/keyboard-state.js';
import {
OverlayContext,
type OverlayContextType,
-} from '../../navigation/overlay-context';
-import { ThreadSettingsMemberTooltipModalRouteName } from '../../navigation/route-names';
-import { useSelector } from '../../redux/redux-utils';
-import { type Colors, useColors, useStyles } from '../../themes/colors';
-import type { VerticalBounds } from '../../types/layout-types';
-import type { ThreadSettingsNavigate } from './thread-settings.react';
+} from '../../navigation/overlay-context.js';
+import { ThreadSettingsMemberTooltipModalRouteName } from '../../navigation/route-names.js';
+import { useSelector } from '../../redux/redux-utils.js';
+import { type Colors, useColors, useStyles } from '../../themes/colors.js';
+import type { VerticalBounds } from '../../types/layout-types.js';
+import type { ThreadSettingsNavigate } from './thread-settings.react.js';
type BaseProps = {
+memberInfo: RelativeMemberInfo,
diff --git a/native/chat/settings/thread-settings-name.react.js b/native/chat/settings/thread-settings-name.react.js
--- a/native/chat/settings/thread-settings-name.react.js
+++ b/native/chat/settings/thread-settings-name.react.js
@@ -13,27 +13,27 @@
import {
changeThreadSettingsActionTypes,
changeThreadSettings,
-} from 'lib/actions/thread-actions';
-import { createLoadingStatusSelector } from 'lib/selectors/loading-selectors';
-import type { LoadingStatus } from 'lib/types/loading-types';
+} from 'lib/actions/thread-actions.js';
+import { createLoadingStatusSelector } from 'lib/selectors/loading-selectors.js';
+import type { LoadingStatus } from 'lib/types/loading-types.js';
import {
type ResolvedThreadInfo,
type ChangeThreadSettingsPayload,
type UpdateThreadRequest,
-} from 'lib/types/thread-types';
+} from 'lib/types/thread-types.js';
import {
type DispatchActionPromise,
useServerCall,
useDispatchActionPromise,
-} from 'lib/utils/action-utils';
-import { firstLine } from 'lib/utils/string-utils';
-
-import EditSettingButton from '../../components/edit-setting-button.react';
-import { SingleLine } from '../../components/single-line.react';
-import TextInput from '../../components/text-input.react';
-import { useSelector } from '../../redux/redux-utils';
-import { type Colors, useStyles, useColors } from '../../themes/colors';
-import SaveSettingButton from './save-setting-button.react';
+} from 'lib/utils/action-utils.js';
+import { firstLine } from 'lib/utils/string-utils.js';
+
+import EditSettingButton from '../../components/edit-setting-button.react.js';
+import { SingleLine } from '../../components/single-line.react.js';
+import TextInput from '../../components/text-input.react.js';
+import { useSelector } from '../../redux/redux-utils.js';
+import { type Colors, useStyles, useColors } from '../../themes/colors.js';
+import SaveSettingButton from './save-setting-button.react.js';
type BaseProps = {
+threadInfo: ResolvedThreadInfo,
diff --git a/native/chat/settings/thread-settings-parent.react.js b/native/chat/settings/thread-settings-parent.react.js
--- a/native/chat/settings/thread-settings-parent.react.js
+++ b/native/chat/settings/thread-settings-parent.react.js
@@ -4,12 +4,12 @@
import * as React from 'react';
import { Text, View } from 'react-native';
-import { type ThreadInfo } from 'lib/types/thread-types';
+import { type ThreadInfo } from 'lib/types/thread-types.js';
-import Button from '../../components/button.react';
-import ThreadPill from '../../components/thread-pill.react';
-import { useStyles } from '../../themes/colors';
-import { useNavigateToThread } from '../message-list-types';
+import Button from '../../components/button.react.js';
+import ThreadPill from '../../components/thread-pill.react.js';
+import { useStyles } from '../../themes/colors.js';
+import { useNavigateToThread } from '../message-list-types.js';
type Props = {
+threadInfo: ThreadInfo,
diff --git a/native/chat/settings/thread-settings-promote-sidebar.react.js b/native/chat/settings/thread-settings-promote-sidebar.react.js
--- a/native/chat/settings/thread-settings-promote-sidebar.react.js
+++ b/native/chat/settings/thread-settings-promote-sidebar.react.js
@@ -3,13 +3,13 @@
import * as React from 'react';
import { Text, ActivityIndicator, View, Alert } from 'react-native';
-import { usePromoteSidebar } from 'lib/hooks/promote-sidebar.react';
-import type { LoadingStatus } from 'lib/types/loading-types';
-import type { ThreadInfo } from 'lib/types/thread-types';
+import { usePromoteSidebar } from 'lib/hooks/promote-sidebar.react.js';
+import type { LoadingStatus } from 'lib/types/loading-types.js';
+import type { ThreadInfo } from 'lib/types/thread-types.js';
-import Button from '../../components/button.react';
-import { type Colors, useColors, useStyles } from '../../themes/colors';
-import type { ViewStyle } from '../../types/styles';
+import Button from '../../components/button.react.js';
+import { type Colors, useColors, useStyles } from '../../themes/colors.js';
+import type { ViewStyle } from '../../types/styles.js';
type BaseProps = {
+threadInfo: ThreadInfo,
diff --git a/native/chat/settings/thread-settings-push-notifs.react.js b/native/chat/settings/thread-settings-push-notifs.react.js
--- a/native/chat/settings/thread-settings-push-notifs.react.js
+++ b/native/chat/settings/thread-settings-push-notifs.react.js
@@ -2,28 +2,28 @@
import * as React from 'react';
import { View, Switch, TouchableOpacity, Platform } from 'react-native';
-import Alert from 'react-native/Libraries/Alert/Alert';
-import Linking from 'react-native/Libraries/Linking/Linking';
+import Alert from 'react-native/Libraries/Alert/Alert.js';
+import Linking from 'react-native/Libraries/Linking/Linking.js';
import {
updateSubscriptionActionTypes,
updateSubscription,
-} from 'lib/actions/user-actions';
+} from 'lib/actions/user-actions.js';
import type {
SubscriptionUpdateRequest,
SubscriptionUpdateResult,
-} from 'lib/types/subscription-types';
-import { type ThreadInfo } from 'lib/types/thread-types';
-import type { DispatchActionPromise } from 'lib/utils/action-utils';
+} from 'lib/types/subscription-types.js';
+import { type ThreadInfo } from 'lib/types/thread-types.js';
+import type { DispatchActionPromise } from 'lib/utils/action-utils.js';
import {
useServerCall,
useDispatchActionPromise,
-} from 'lib/utils/action-utils';
+} from 'lib/utils/action-utils.js';
-import { SingleLine } from '../../components/single-line.react';
-import SWMansionIcon from '../../components/swmansion-icon.react';
-import { useSelector } from '../../redux/redux-utils';
-import { useStyles } from '../../themes/colors';
+import { SingleLine } from '../../components/single-line.react.js';
+import SWMansionIcon from '../../components/swmansion-icon.react.js';
+import { useSelector } from '../../redux/redux-utils.js';
+import { useStyles } from '../../themes/colors.js';
type BaseProps = {
+threadInfo: ThreadInfo,
diff --git a/native/chat/settings/thread-settings-visibility.react.js b/native/chat/settings/thread-settings-visibility.react.js
--- a/native/chat/settings/thread-settings-visibility.react.js
+++ b/native/chat/settings/thread-settings-visibility.react.js
@@ -3,10 +3,10 @@
import * as React from 'react';
import { Text, View } from 'react-native';
-import type { ThreadInfo } from 'lib/types/thread-types';
+import type { ThreadInfo } from 'lib/types/thread-types.js';
-import ThreadVisibility from '../../components/thread-visibility.react';
-import { useStyles, useColors } from '../../themes/colors';
+import ThreadVisibility from '../../components/thread-visibility.react.js';
+import { useStyles, useColors } from '../../themes/colors.js';
type Props = {
+threadInfo: ThreadInfo,
diff --git a/native/chat/settings/thread-settings.react.js b/native/chat/settings/thread-settings.react.js
--- a/native/chat/settings/thread-settings.react.js
+++ b/native/chat/settings/thread-settings.react.js
@@ -12,86 +12,86 @@
leaveThreadActionTypes,
removeUsersFromThreadActionTypes,
changeThreadMemberRolesActionTypes,
-} from 'lib/actions/thread-actions';
-import { usePromoteSidebar } from 'lib/hooks/promote-sidebar.react';
-import { createLoadingStatusSelector } from 'lib/selectors/loading-selectors';
+} from 'lib/actions/thread-actions.js';
+import { usePromoteSidebar } from 'lib/hooks/promote-sidebar.react.js';
+import { createLoadingStatusSelector } from 'lib/selectors/loading-selectors.js';
import {
threadInfoSelector,
childThreadInfos,
-} from 'lib/selectors/thread-selectors';
-import { getAvailableRelationshipButtons } from 'lib/shared/relationship-utils';
+} from 'lib/selectors/thread-selectors.js';
+import { getAvailableRelationshipButtons } from 'lib/shared/relationship-utils.js';
import {
threadHasPermission,
viewerIsMember,
threadInChatList,
getSingleOtherUser,
threadIsChannel,
-} from 'lib/shared/thread-utils';
-import threadWatcher from 'lib/shared/thread-watcher';
-import type { RelationshipButton } from 'lib/types/relationship-types';
+} from 'lib/shared/thread-utils.js';
+import threadWatcher from 'lib/shared/thread-watcher.js';
+import type { RelationshipButton } from 'lib/types/relationship-types.js';
import {
type ThreadInfo,
type ResolvedThreadInfo,
type RelativeMemberInfo,
threadPermissions,
threadTypes,
-} from 'lib/types/thread-types';
-import type { UserInfos } from 'lib/types/user-types';
+} from 'lib/types/thread-types.js';
+import type { UserInfos } from 'lib/types/user-types.js';
import {
useResolvedThreadInfo,
useResolvedOptionalThreadInfo,
useResolvedOptionalThreadInfos,
-} from 'lib/utils/entity-helpers';
+} from 'lib/utils/entity-helpers.js';
-import ThreadAncestors from '../../components/thread-ancestors.react';
+import ThreadAncestors from '../../components/thread-ancestors.react.js';
import {
type KeyboardState,
KeyboardContext,
-} from '../../keyboard/keyboard-state';
-import { defaultStackScreenOptions } from '../../navigation/options';
+} from '../../keyboard/keyboard-state.js';
+import { defaultStackScreenOptions } from '../../navigation/options.js';
import {
OverlayContext,
type OverlayContextType,
-} from '../../navigation/overlay-context';
-import type { NavigationRoute } from '../../navigation/route-names';
+} from '../../navigation/overlay-context.js';
+import type { NavigationRoute } from '../../navigation/route-names.js';
import {
AddUsersModalRouteName,
ComposeSubchannelModalRouteName,
-} from '../../navigation/route-names';
-import type { TabNavigationProp } from '../../navigation/tab-navigator.react';
-import { useSelector } from '../../redux/redux-utils';
-import type { AppState } from '../../redux/state-types';
+} from '../../navigation/route-names.js';
+import type { TabNavigationProp } from '../../navigation/tab-navigator.react.js';
+import { useSelector } from '../../redux/redux-utils.js';
+import type { AppState } from '../../redux/state-types.js';
import {
useStyles,
type IndicatorStyle,
useIndicatorStyle,
-} from '../../themes/colors';
-import type { VerticalBounds } from '../../types/layout-types';
-import type { ViewStyle } from '../../types/styles';
-import type { ChatNavigationProp } from '../chat.react';
-import type { CategoryType } from './thread-settings-category.react';
+} from '../../themes/colors.js';
+import type { VerticalBounds } from '../../types/layout-types.js';
+import type { ViewStyle } from '../../types/styles.js';
+import type { ChatNavigationProp } from '../chat.react.js';
+import type { CategoryType } from './thread-settings-category.react.js';
import {
ThreadSettingsCategoryHeader,
ThreadSettingsCategoryFooter,
-} from './thread-settings-category.react';
-import ThreadSettingsChildThread from './thread-settings-child-thread.react';
-import ThreadSettingsColor from './thread-settings-color.react';
-import ThreadSettingsDeleteThread from './thread-settings-delete-thread.react';
-import ThreadSettingsDescription from './thread-settings-description.react';
-import ThreadSettingsEditRelationship from './thread-settings-edit-relationship.react';
-import ThreadSettingsHomeNotifs from './thread-settings-home-notifs.react';
-import ThreadSettingsLeaveThread from './thread-settings-leave-thread.react';
+} from './thread-settings-category.react.js';
+import ThreadSettingsChildThread from './thread-settings-child-thread.react.js';
+import ThreadSettingsColor from './thread-settings-color.react.js';
+import ThreadSettingsDeleteThread from './thread-settings-delete-thread.react.js';
+import ThreadSettingsDescription from './thread-settings-description.react.js';
+import ThreadSettingsEditRelationship from './thread-settings-edit-relationship.react.js';
+import ThreadSettingsHomeNotifs from './thread-settings-home-notifs.react.js';
+import ThreadSettingsLeaveThread from './thread-settings-leave-thread.react.js';
import {
ThreadSettingsSeeMore,
ThreadSettingsAddMember,
ThreadSettingsAddSubchannel,
-} from './thread-settings-list-action.react';
-import ThreadSettingsMember from './thread-settings-member.react';
-import ThreadSettingsName from './thread-settings-name.react';
-import ThreadSettingsParent from './thread-settings-parent.react';
-import ThreadSettingsPromoteSidebar from './thread-settings-promote-sidebar.react';
-import ThreadSettingsPushNotifs from './thread-settings-push-notifs.react';
-import ThreadSettingsVisibility from './thread-settings-visibility.react';
+} from './thread-settings-list-action.react.js';
+import ThreadSettingsMember from './thread-settings-member.react.js';
+import ThreadSettingsName from './thread-settings-name.react.js';
+import ThreadSettingsParent from './thread-settings-parent.react.js';
+import ThreadSettingsPromoteSidebar from './thread-settings-promote-sidebar.react.js';
+import ThreadSettingsPushNotifs from './thread-settings-push-notifs.react.js';
+import ThreadSettingsVisibility from './thread-settings-visibility.react.js';
const itemPageLength = 5;
diff --git a/native/chat/sidebar-input-bar-height-measurer.react.js b/native/chat/sidebar-input-bar-height-measurer.react.js
--- a/native/chat/sidebar-input-bar-height-measurer.react.js
+++ b/native/chat/sidebar-input-bar-height-measurer.react.js
@@ -3,11 +3,11 @@
import * as React from 'react';
import { View, StyleSheet } from 'react-native';
-import { useSelector } from '../redux/redux-utils';
-import type { ChatMessageInfoItemWithHeight } from '../types/chat-types';
-import { DummyChatInputBar } from './chat-input-bar.react';
-import { useMessageListScreenWidth } from './composed-message-width';
-import { getUnresolvedSidebarThreadInfo } from './sidebar-navigation';
+import { useSelector } from '../redux/redux-utils.js';
+import type { ChatMessageInfoItemWithHeight } from '../types/chat-types.js';
+import { DummyChatInputBar } from './chat-input-bar.react.js';
+import { useMessageListScreenWidth } from './composed-message-width.js';
+import { getUnresolvedSidebarThreadInfo } from './sidebar-navigation.js';
type Props = {
+sourceMessage: ChatMessageInfoItemWithHeight,
diff --git a/native/chat/sidebar-item.react.js b/native/chat/sidebar-item.react.js
--- a/native/chat/sidebar-item.react.js
+++ b/native/chat/sidebar-item.react.js
@@ -3,12 +3,12 @@
import * as React from 'react';
import { Text, View } from 'react-native';
-import type { SidebarInfo } from 'lib/types/thread-types';
-import { shortAbsoluteDate } from 'lib/utils/date-utils';
-import { useResolvedThreadInfo } from 'lib/utils/entity-helpers';
+import type { SidebarInfo } from 'lib/types/thread-types.js';
+import { shortAbsoluteDate } from 'lib/utils/date-utils.js';
+import { useResolvedThreadInfo } from 'lib/utils/entity-helpers.js';
-import { SingleLine } from '../components/single-line.react';
-import { useStyles } from '../themes/colors';
+import { SingleLine } from '../components/single-line.react.js';
+import { useStyles } from '../themes/colors.js';
type Props = {
+sidebarInfo: SidebarInfo,
diff --git a/native/chat/sidebar-list-modal.react.js b/native/chat/sidebar-list-modal.react.js
--- a/native/chat/sidebar-list-modal.react.js
+++ b/native/chat/sidebar-list-modal.react.js
@@ -3,17 +3,17 @@
import * as React from 'react';
import { View } from 'react-native';
-import { useSearchSidebars } from 'lib/hooks/search-threads';
-import type { ThreadInfo, SidebarInfo } from 'lib/types/thread-types';
+import { useSearchSidebars } from 'lib/hooks/search-threads.js';
+import type { ThreadInfo, SidebarInfo } from 'lib/types/thread-types.js';
-import ExtendedArrow from '../components/arrow-extended.react';
-import Arrow from '../components/arrow.react';
-import Button from '../components/button.react';
-import type { RootNavigationProp } from '../navigation/root-navigator.react';
-import type { NavigationRoute } from '../navigation/route-names';
-import { useColors, useStyles } from '../themes/colors';
-import { SidebarItem } from './sidebar-item.react';
-import ThreadListModal from './thread-list-modal.react';
+import ExtendedArrow from '../components/arrow-extended.react.js';
+import Arrow from '../components/arrow.react.js';
+import Button from '../components/button.react.js';
+import type { RootNavigationProp } from '../navigation/root-navigator.react.js';
+import type { NavigationRoute } from '../navigation/route-names.js';
+import { useColors, useStyles } from '../themes/colors.js';
+import { SidebarItem } from './sidebar-item.react.js';
+import ThreadListModal from './thread-list-modal.react.js';
export type SidebarListModalParams = {
+threadInfo: ThreadInfo,
diff --git a/native/chat/sidebar-navigation.js b/native/chat/sidebar-navigation.js
--- a/native/chat/sidebar-navigation.js
+++ b/native/chat/sidebar-navigation.js
@@ -3,19 +3,19 @@
import invariant from 'invariant';
import * as React from 'react';
-import { ENSCacheContext } from 'lib/components/ens-cache-provider.react';
+import { ENSCacheContext } from 'lib/components/ens-cache-provider.react.js';
import {
createPendingSidebar,
createUnresolvedPendingSidebar,
-} from 'lib/shared/thread-utils';
-import type { ThreadInfo } from 'lib/types/thread-types';
-import type { GetENSNames } from 'lib/utils/ens-helpers';
+} from 'lib/shared/thread-utils.js';
+import type { ThreadInfo } from 'lib/types/thread-types.js';
+import type { GetENSNames } from 'lib/utils/ens-helpers.js';
-import { getDefaultTextMessageRules } from '../markdown/rules.react';
-import { useSelector } from '../redux/redux-utils';
-import type { ChatMessageInfoItemWithHeight } from '../types/chat-types';
-import { ChatContext } from './chat-context';
-import { useNavigateToThread } from './message-list-types';
+import { getDefaultTextMessageRules } from '../markdown/rules.react.js';
+import { useSelector } from '../redux/redux-utils.js';
+import type { ChatMessageInfoItemWithHeight } from '../types/chat-types.js';
+import { ChatContext } from './chat-context.js';
+import { useNavigateToThread } from './message-list-types.js';
type GetUnresolvedSidebarThreadInfoInput = {
+sourceMessage: ChatMessageInfoItemWithHeight,
diff --git a/native/chat/subchannel-item.react.js b/native/chat/subchannel-item.react.js
--- a/native/chat/subchannel-item.react.js
+++ b/native/chat/subchannel-item.react.js
@@ -3,14 +3,14 @@
import * as React from 'react';
import { Text, View } from 'react-native';
-import type { ChatThreadItem } from 'lib/selectors/chat-selectors';
-import { shortAbsoluteDate } from 'lib/utils/date-utils';
-import { useResolvedThreadInfo } from 'lib/utils/entity-helpers';
+import type { ChatThreadItem } from 'lib/selectors/chat-selectors.js';
+import { shortAbsoluteDate } from 'lib/utils/date-utils.js';
+import { useResolvedThreadInfo } from 'lib/utils/entity-helpers.js';
-import { SingleLine } from '../components/single-line.react';
-import SWMansionIcon from '../components/swmansion-icon.react';
-import { useStyles } from '../themes/colors';
-import MessagePreview from './message-preview.react';
+import { SingleLine } from '../components/single-line.react.js';
+import SWMansionIcon from '../components/swmansion-icon.react.js';
+import { useStyles } from '../themes/colors.js';
+import MessagePreview from './message-preview.react.js';
type Props = {
+subchannelInfo: ChatThreadItem,
diff --git a/native/chat/subchannels-list-modal.react.js b/native/chat/subchannels-list-modal.react.js
--- a/native/chat/subchannels-list-modal.react.js
+++ b/native/chat/subchannels-list-modal.react.js
@@ -3,16 +3,16 @@
import * as React from 'react';
import { View } from 'react-native';
-import { useSearchSubchannels } from 'lib/hooks/search-threads';
-import type { ChatThreadItem } from 'lib/selectors/chat-selectors';
-import { type ThreadInfo } from 'lib/types/thread-types';
+import { useSearchSubchannels } from 'lib/hooks/search-threads.js';
+import type { ChatThreadItem } from 'lib/selectors/chat-selectors.js';
+import { type ThreadInfo } from 'lib/types/thread-types.js';
-import Button from '../components/button.react';
-import type { RootNavigationProp } from '../navigation/root-navigator.react';
-import type { NavigationRoute } from '../navigation/route-names';
-import { useColors, useStyles } from '../themes/colors';
-import SubchannelItem from './subchannel-item.react';
-import ThreadListModal from './thread-list-modal.react';
+import Button from '../components/button.react.js';
+import type { RootNavigationProp } from '../navigation/root-navigator.react.js';
+import type { NavigationRoute } from '../navigation/route-names.js';
+import { useColors, useStyles } from '../themes/colors.js';
+import SubchannelItem from './subchannel-item.react.js';
+import ThreadListModal from './thread-list-modal.react.js';
export type SubchannelListModalParams = {
+threadInfo: ThreadInfo,
diff --git a/native/chat/swipeable-message.react.js b/native/chat/swipeable-message.react.js
--- a/native/chat/swipeable-message.react.js
+++ b/native/chat/swipeable-message.react.js
@@ -18,10 +18,10 @@
} from 'react-native-reanimated';
import tinycolor from 'tinycolor2';
-import CommIcon from '../components/comm-icon.react';
-import { colors } from '../themes/colors';
-import type { ViewStyle } from '../types/styles';
-import { useMessageListScreenWidth } from './composed-message-width';
+import CommIcon from '../components/comm-icon.react.js';
+import { colors } from '../themes/colors.js';
+import type { ViewStyle } from '../types/styles.js';
+import { useMessageListScreenWidth } from './composed-message-width.js';
const primaryThreshold = 40;
const secondaryThreshold = 120;
diff --git a/native/chat/swipeable-thread.react.js b/native/chat/swipeable-thread.react.js
--- a/native/chat/swipeable-thread.react.js
+++ b/native/chat/swipeable-thread.react.js
@@ -1,14 +1,14 @@
// @flow
-import MaterialIcon from '@expo/vector-icons/MaterialCommunityIcons';
+import MaterialIcon from '@expo/vector-icons/MaterialCommunityIcons.js';
import { useNavigation } from '@react-navigation/native';
import * as React from 'react';
-import useToggleUnreadStatus from 'lib/hooks/toggle-unread-status';
-import type { ThreadInfo } from 'lib/types/thread-types';
+import useToggleUnreadStatus from 'lib/hooks/toggle-unread-status.js';
+import type { ThreadInfo } from 'lib/types/thread-types.js';
-import Swipeable from '../components/swipeable';
-import { useColors } from '../themes/colors';
+import Swipeable from '../components/swipeable.js';
+import { useColors } from '../themes/colors.js';
type Props = {
+threadInfo: ThreadInfo,
+mostRecentNonLocalMessage: ?string,
diff --git a/native/chat/text-message-markdown-context.js b/native/chat/text-message-markdown-context.js
--- a/native/chat/text-message-markdown-context.js
+++ b/native/chat/text-message-markdown-context.js
@@ -3,11 +3,11 @@
import * as React from 'react';
import * as SimpleMarkdown from 'simple-markdown';
-import type { ASTNode, SingleASTNode } from 'lib/shared/markdown';
-import { messageKey } from 'lib/shared/message-utils';
-import type { TextMessageInfo } from 'lib/types/messages/text';
+import type { ASTNode, SingleASTNode } from 'lib/shared/markdown.js';
+import { messageKey } from 'lib/shared/message-utils.js';
+import type { TextMessageInfo } from 'lib/types/messages/text.js';
-import { useTextMessageMarkdownRules } from '../chat/message-list-types';
+import { useTextMessageMarkdownRules } from '../chat/message-list-types.js';
export type TextMessageMarkdownContextType = {
+messageKey: string,
diff --git a/native/chat/text-message-send-failed.js b/native/chat/text-message-send-failed.js
--- a/native/chat/text-message-send-failed.js
+++ b/native/chat/text-message-send-failed.js
@@ -1,6 +1,6 @@
// @flow
-import type { ChatTextMessageInfoItemWithHeight } from '../types/chat-types';
+import type { ChatTextMessageInfoItemWithHeight } from '../types/chat-types.js';
export default function textMessageSendFailed(
item: ChatTextMessageInfoItemWithHeight,
diff --git a/native/chat/text-message-tooltip-button.react.js b/native/chat/text-message-tooltip-button.react.js
--- a/native/chat/text-message-tooltip-button.react.js
+++ b/native/chat/text-message-tooltip-button.react.js
@@ -4,25 +4,25 @@
import Animated from 'react-native-reanimated';
import EmojiPicker from 'rn-emoji-keyboard';
-import { localIDPrefix } from 'lib/shared/message-utils';
-import { useCanCreateReactionFromMessage } from 'lib/shared/reaction-utils';
-
-import type { AppNavigationProp } from '../navigation/app-navigator.react';
-import { useSelector } from '../redux/redux-utils';
-import { useTooltipActions } from '../tooltip/tooltip-hooks';
-import type { TooltipRoute } from '../tooltip/tooltip.react';
-import { TooltipInlineEngagement } from './inline-engagement.react';
-import { InnerTextMessage } from './inner-text-message.react';
-import { MessageHeader } from './message-header.react';
-import { MessageListContextProvider } from './message-list-types';
-import { MessagePressResponderContext } from './message-press-responder-context';
+import { localIDPrefix } from 'lib/shared/message-utils.js';
+import { useCanCreateReactionFromMessage } from 'lib/shared/reaction-utils.js';
+
+import type { AppNavigationProp } from '../navigation/app-navigator.react.js';
+import { useSelector } from '../redux/redux-utils.js';
+import { useTooltipActions } from '../tooltip/tooltip-hooks.js';
+import type { TooltipRoute } from '../tooltip/tooltip.react.js';
+import { TooltipInlineEngagement } from './inline-engagement.react.js';
+import { InnerTextMessage } from './inner-text-message.react.js';
+import { MessageHeader } from './message-header.react.js';
+import { MessageListContextProvider } from './message-list-types.js';
+import { MessagePressResponderContext } from './message-press-responder-context.js';
import {
useSendReaction,
useReactionSelectionPopoverPosition,
-} from './reaction-message-utils';
-import ReactionSelectionPopover from './reaction-selection-popover.react';
-import SidebarInputBarHeightMeasurer from './sidebar-input-bar-height-measurer.react';
-import { useAnimatedMessageTooltipButton } from './utils';
+} from './reaction-message-utils.js';
+import ReactionSelectionPopover from './reaction-selection-popover.react.js';
+import SidebarInputBarHeightMeasurer from './sidebar-input-bar-height-measurer.react.js';
+import { useAnimatedMessageTooltipButton } from './utils.js';
/* eslint-disable import/no-named-as-default-member */
const { Node, interpolateNode, Extrapolate } = Animated;
diff --git a/native/chat/text-message-tooltip-modal.react.js b/native/chat/text-message-tooltip-modal.react.js
--- a/native/chat/text-message-tooltip-modal.react.js
+++ b/native/chat/text-message-tooltip-modal.react.js
@@ -4,22 +4,22 @@
import invariant from 'invariant';
import * as React from 'react';
-import { createMessageReply } from 'lib/shared/message-utils';
+import { createMessageReply } from 'lib/shared/message-utils.js';
-import CommIcon from '../components/comm-icon.react';
-import SWMansionIcon from '../components/swmansion-icon.react';
-import { InputStateContext } from '../input/input-state';
-import { displayActionResultModal } from '../navigation/action-result-modal';
+import CommIcon from '../components/comm-icon.react.js';
+import SWMansionIcon from '../components/swmansion-icon.react.js';
+import { InputStateContext } from '../input/input-state.js';
+import { displayActionResultModal } from '../navigation/action-result-modal.js';
import {
createTooltip,
type TooltipParams,
type BaseTooltipProps,
type TooltipMenuProps,
-} from '../tooltip/tooltip.react';
-import type { ChatTextMessageInfoItemWithHeight } from '../types/chat-types';
-import { useOnPressReport } from './message-report-utils';
-import { useAnimatedNavigateToSidebar } from './sidebar-navigation';
-import TextMessageTooltipButton from './text-message-tooltip-button.react';
+} from '../tooltip/tooltip.react.js';
+import type { ChatTextMessageInfoItemWithHeight } from '../types/chat-types.js';
+import { useOnPressReport } from './message-report-utils.js';
+import { useAnimatedNavigateToSidebar } from './sidebar-navigation.js';
+import TextMessageTooltipButton from './text-message-tooltip-button.react.js';
export type TextMessageTooltipModalParams = TooltipParams<{
+item: ChatTextMessageInfoItemWithHeight,
diff --git a/native/chat/text-message.react.js b/native/chat/text-message.react.js
--- a/native/chat/text-message.react.js
+++ b/native/chat/text-message.react.js
@@ -4,33 +4,33 @@
import * as React from 'react';
import { View } from 'react-native';
-import { messageKey } from 'lib/shared/message-utils';
+import { messageKey } from 'lib/shared/message-utils.js';
import {
threadHasPermission,
useCanCreateSidebarFromMessage,
-} from 'lib/shared/thread-utils';
-import { threadPermissions } from 'lib/types/thread-types';
+} from 'lib/shared/thread-utils.js';
+import { threadPermissions } from 'lib/types/thread-types.js';
-import { ChatContext, type ChatContextType } from '../chat/chat-context';
-import { MarkdownContext } from '../markdown/markdown-context';
+import { ChatContext, type ChatContextType } from '../chat/chat-context.js';
+import { MarkdownContext } from '../markdown/markdown-context.js';
import {
OverlayContext,
type OverlayContextType,
-} from '../navigation/overlay-context';
-import type { NavigationRoute } from '../navigation/route-names';
-import { TextMessageTooltipModalRouteName } from '../navigation/route-names';
-import { fixedTooltipHeight } from '../tooltip/tooltip.react';
-import type { ChatTextMessageInfoItemWithHeight } from '../types/chat-types';
-import type { VerticalBounds } from '../types/layout-types';
-import type { ChatNavigationProp } from './chat.react';
-import ComposedMessage from './composed-message.react';
-import { InnerTextMessage } from './inner-text-message.react';
+} from '../navigation/overlay-context.js';
+import type { NavigationRoute } from '../navigation/route-names.js';
+import { TextMessageTooltipModalRouteName } from '../navigation/route-names.js';
+import { fixedTooltipHeight } from '../tooltip/tooltip.react.js';
+import type { ChatTextMessageInfoItemWithHeight } from '../types/chat-types.js';
+import type { VerticalBounds } from '../types/layout-types.js';
+import type { ChatNavigationProp } from './chat.react.js';
+import ComposedMessage from './composed-message.react.js';
+import { InnerTextMessage } from './inner-text-message.react.js';
import {
MessagePressResponderContext,
type MessagePressResponderContextType,
-} from './message-press-responder-context';
-import textMessageSendFailed from './text-message-send-failed';
-import { getMessageTooltipKey } from './utils';
+} from './message-press-responder-context.js';
+import textMessageSendFailed from './text-message-send-failed.js';
+import { getMessageTooltipKey } from './utils.js';
type BaseProps = {
...React.ElementConfig<typeof View>,
diff --git a/native/chat/thread-list-modal.react.js b/native/chat/thread-list-modal.react.js
--- a/native/chat/thread-list-modal.react.js
+++ b/native/chat/thread-list-modal.react.js
@@ -10,18 +10,18 @@
TouchableOpacity,
} from 'react-native';
-import type { ThreadSearchState } from 'lib/hooks/search-threads';
-import type { ChatThreadItem } from 'lib/selectors/chat-selectors';
-import type { SetState } from 'lib/types/hook-types';
-import type { ThreadInfo, SidebarInfo } from 'lib/types/thread-types';
+import type { ThreadSearchState } from 'lib/hooks/search-threads.js';
+import type { ChatThreadItem } from 'lib/selectors/chat-selectors.js';
+import type { SetState } from 'lib/types/hook-types.js';
+import type { ThreadInfo, SidebarInfo } from 'lib/types/thread-types.js';
-import Modal from '../components/modal.react';
-import Search from '../components/search.react';
-import SWMansionIcon from '../components/swmansion-icon.react';
-import ThreadPill from '../components/thread-pill.react';
-import { useIndicatorStyle, useStyles } from '../themes/colors';
-import { waitForModalInputFocus } from '../utils/timers';
-import { useNavigateToThread } from './message-list-types';
+import Modal from '../components/modal.react.js';
+import Search from '../components/search.react.js';
+import SWMansionIcon from '../components/swmansion-icon.react.js';
+import ThreadPill from '../components/thread-pill.react.js';
+import { useIndicatorStyle, useStyles } from '../themes/colors.js';
+import { waitForModalInputFocus } from '../utils/timers.js';
+import { useNavigateToThread } from './message-list-types.js';
function keyExtractor(sidebarInfo: SidebarInfo | ChatThreadItem) {
return sidebarInfo.threadInfo.id;
diff --git a/native/chat/thread-screen-pruner.react.js b/native/chat/thread-screen-pruner.react.js
--- a/native/chat/thread-screen-pruner.react.js
+++ b/native/chat/thread-screen-pruner.react.js
@@ -4,23 +4,23 @@
import * as React from 'react';
import { Alert } from 'react-native';
-import { threadIsPending } from 'lib/shared/thread-utils';
+import { threadIsPending } from 'lib/shared/thread-utils.js';
-import { clearThreadsActionType } from '../navigation/action-types';
-import { useActiveThread } from '../navigation/nav-selectors';
-import { NavContext } from '../navigation/navigation-context';
+import { clearThreadsActionType } from '../navigation/action-types.js';
+import { useActiveThread } from '../navigation/nav-selectors.js';
+import { NavContext } from '../navigation/navigation-context.js';
import {
getThreadIDFromRoute,
getChildRouteFromNavigatorRoute,
-} from '../navigation/navigation-utils';
+} from '../navigation/navigation-utils.js';
import {
AppRouteName,
ChatRouteName,
CommunityDrawerNavigatorRouteName,
TabNavigatorRouteName,
-} from '../navigation/route-names';
-import { useSelector } from '../redux/redux-utils';
-import type { AppState } from '../redux/state-types';
+} from '../navigation/route-names.js';
+import { useSelector } from '../redux/redux-utils.js';
+import type { AppState } from '../redux/state-types.js';
const ThreadScreenPruner: React.ComponentType<{}> = React.memo<{}>(
function ThreadScreenPruner() {
diff --git a/native/chat/thread-settings-button.react.js b/native/chat/thread-settings-button.react.js
--- a/native/chat/thread-settings-button.react.js
+++ b/native/chat/thread-settings-button.react.js
@@ -1,14 +1,14 @@
// @flow
-import Icon from '@expo/vector-icons/Ionicons';
+import Icon from '@expo/vector-icons/Ionicons.js';
import * as React from 'react';
-import { type ThreadInfo } from 'lib/types/thread-types';
+import { type ThreadInfo } from 'lib/types/thread-types.js';
-import Button from '../components/button.react';
-import { ThreadSettingsRouteName } from '../navigation/route-names';
-import { useStyles } from '../themes/colors';
-import type { ChatNavigationProp } from './chat.react';
+import Button from '../components/button.react.js';
+import { ThreadSettingsRouteName } from '../navigation/route-names.js';
+import { useStyles } from '../themes/colors.js';
+import type { ChatNavigationProp } from './chat.react.js';
type BaseProps = {
+threadInfo: ThreadInfo,
diff --git a/native/chat/thread-settings-header-title.react.js b/native/chat/thread-settings-header-title.react.js
--- a/native/chat/thread-settings-header-title.react.js
+++ b/native/chat/thread-settings-header-title.react.js
@@ -6,9 +6,9 @@
} from '@react-navigation/elements';
import * as React from 'react';
-import type { ThreadInfo } from 'lib/types/thread-types';
-import { useResolvedThreadInfo } from 'lib/utils/entity-helpers';
-import { firstLine } from 'lib/utils/string-utils';
+import type { ThreadInfo } from 'lib/types/thread-types.js';
+import { useResolvedThreadInfo } from 'lib/utils/entity-helpers.js';
+import { firstLine } from 'lib/utils/string-utils.js';
type Props = {
+threadInfo: ThreadInfo,
diff --git a/native/chat/timestamp.react.js b/native/chat/timestamp.react.js
--- a/native/chat/timestamp.react.js
+++ b/native/chat/timestamp.react.js
@@ -2,10 +2,10 @@
import * as React from 'react';
-import { longAbsoluteDate } from 'lib/utils/date-utils';
+import { longAbsoluteDate } from 'lib/utils/date-utils.js';
-import { SingleLine } from '../components/single-line.react';
-import { useStyles } from '../themes/colors';
+import { SingleLine } from '../components/single-line.react.js';
+import { useStyles } from '../themes/colors.js';
export type DisplayType = 'lowContrast' | 'modal';
diff --git a/native/chat/typeahead-tooltip.react.js b/native/chat/typeahead-tooltip.react.js
--- a/native/chat/typeahead-tooltip.react.js
+++ b/native/chat/typeahead-tooltip.react.js
@@ -8,11 +8,11 @@
type TypeaheadMatchedStrings,
type Selection,
getNewTextAndSelection,
-} from 'lib/shared/typeahead-utils';
-import type { RelativeMemberInfo } from 'lib/types/thread-types';
+} from 'lib/shared/typeahead-utils.js';
+import type { RelativeMemberInfo } from 'lib/types/thread-types.js';
-import Button from '../components/button.react';
-import { useStyles } from '../themes/colors';
+import Button from '../components/button.react.js';
+import { useStyles } from '../themes/colors.js';
export type TypeaheadTooltipProps = {
+text: string,
diff --git a/native/chat/utils.js b/native/chat/utils.js
--- a/native/chat/utils.js
+++ b/native/chat/utils.js
@@ -4,36 +4,39 @@
import * as React from 'react';
import Animated from 'react-native-reanimated';
-import { useMessageListData } from 'lib/selectors/chat-selectors';
-import type { ChatMessageItem } from 'lib/selectors/chat-selectors';
-import { messageKey } from 'lib/shared/message-utils';
-import { colorIsDark, viewerIsMember } from 'lib/shared/thread-utils';
-import type { ThreadInfo } from 'lib/types/thread-types';
-
-import { KeyboardContext } from '../keyboard/keyboard-state';
-import { OverlayContext } from '../navigation/overlay-context';
+import { useMessageListData } from 'lib/selectors/chat-selectors.js';
+import type { ChatMessageItem } from 'lib/selectors/chat-selectors.js';
+import { messageKey } from 'lib/shared/message-utils.js';
+import { colorIsDark, viewerIsMember } from 'lib/shared/thread-utils.js';
+import type { ThreadInfo } from 'lib/types/thread-types.js';
+
+import { KeyboardContext } from '../keyboard/keyboard-state.js';
+import { OverlayContext } from '../navigation/overlay-context.js';
import {
MultimediaMessageTooltipModalRouteName,
RobotextMessageTooltipModalRouteName,
TextMessageTooltipModalRouteName,
-} from '../navigation/route-names';
-import { useSelector } from '../redux/redux-utils';
+} from '../navigation/route-names.js';
+import { useSelector } from '../redux/redux-utils.js';
import type {
ChatMessageInfoItemWithHeight,
ChatMessageItemWithHeight,
ChatRobotextMessageInfoItemWithHeight,
ChatTextMessageInfoItemWithHeight,
-} from '../types/chat-types';
-import type { LayoutCoordinates, VerticalBounds } from '../types/layout-types';
-import type { AnimatedViewStyle } from '../types/styles';
-import { clusterEndHeight, inlineEngagementStyle } from './chat-constants';
-import { ChatContext, useHeightMeasurer } from './chat-context';
-import { failedSendHeight } from './failed-send.react';
-import { authorNameHeight } from './message-header.react';
-import { multimediaMessageItemHeight } from './multimedia-message-utils';
-import { getUnresolvedSidebarThreadInfo } from './sidebar-navigation';
-import textMessageSendFailed from './text-message-send-failed';
-import { timestampHeight } from './timestamp.react';
+} from '../types/chat-types.js';
+import type {
+ LayoutCoordinates,
+ VerticalBounds,
+} from '../types/layout-types.js';
+import type { AnimatedViewStyle } from '../types/styles.js';
+import { clusterEndHeight, inlineEngagementStyle } from './chat-constants.js';
+import { ChatContext, useHeightMeasurer } from './chat-context.js';
+import { failedSendHeight } from './failed-send.react.js';
+import { authorNameHeight } from './message-header.react.js';
+import { multimediaMessageItemHeight } from './multimedia-message-utils.js';
+import { getUnresolvedSidebarThreadInfo } from './sidebar-navigation.js';
+import textMessageSendFailed from './text-message-send-failed.js';
+import { timestampHeight } from './timestamp.react.js';
/* eslint-disable import/no-named-as-default-member */
const {
diff --git a/native/codegen/src/CodeGen.js b/native/codegen/src/CodeGen.js
--- a/native/codegen/src/CodeGen.js
+++ b/native/codegen/src/CodeGen.js
@@ -5,7 +5,7 @@
// import generators
import fs from 'fs';
import path from 'path';
-import { type SchemaType } from 'react-native-codegen/lib/CodegenSchema';
+import { type SchemaType } from 'react-native-codegen/lib/CodegenSchema.js';
import generatorCpp from 'react-native-codegen/lib/generators/modules/GenerateModuleCpp.js';
import generatorH from 'react-native-codegen/lib/generators/modules/GenerateModuleH.js';
import generatorJavaSpec from 'react-native-codegen/lib/generators/modules/GenerateModuleJavaSpec.js';
diff --git a/native/components/action-row.react.js b/native/components/action-row.react.js
--- a/native/components/action-row.react.js
+++ b/native/components/action-row.react.js
@@ -1,12 +1,12 @@
// @flow
import type { IoniconsGlyphs } from '@expo/vector-icons';
-import RawIcon from '@expo/vector-icons/Ionicons';
+import RawIcon from '@expo/vector-icons/Ionicons.js';
import * as React from 'react';
import { View, Text as RawText } from 'react-native';
-import Button from '../components/button.react';
-import { useColors, useStyles } from '../themes/colors';
+import Button from '../components/button.react.js';
+import { useColors, useStyles } from '../themes/colors.js';
type TextProps = {
+content: string,
diff --git a/native/components/button.react.js b/native/components/button.react.js
--- a/native/components/button.react.js
+++ b/native/components/button.react.js
@@ -10,7 +10,7 @@
TouchableOpacity,
} from 'react-native';
-import type { ViewStyle } from '../types/styles';
+import type { ViewStyle } from '../types/styles.js';
const ANDROID_VERSION_LOLLIPOP = 21;
diff --git a/native/components/clearable-text-input.react.ios.js b/native/components/clearable-text-input.react.ios.js
--- a/native/components/clearable-text-input.react.ios.js
+++ b/native/components/clearable-text-input.react.ios.js
@@ -4,9 +4,9 @@
import * as React from 'react';
import { TextInput as BaseTextInput, View, StyleSheet } from 'react-native';
-import type { KeyPressEvent } from '../types/react-native';
-import type { ClearableTextInputProps } from './clearable-text-input';
-import TextInput from './text-input.react';
+import type { KeyPressEvent } from '../types/react-native.js';
+import type { ClearableTextInputProps } from './clearable-text-input.js';
+import TextInput from './text-input.react.js';
type State = {
+textInputKey: number,
diff --git a/native/components/clearable-text-input.react.js b/native/components/clearable-text-input.react.js
--- a/native/components/clearable-text-input.react.js
+++ b/native/components/clearable-text-input.react.js
@@ -3,11 +3,11 @@
import * as React from 'react';
import { TextInput as BaseTextInput, View, StyleSheet } from 'react-native';
-import sleep from 'lib/utils/sleep';
+import sleep from 'lib/utils/sleep.js';
-import { waitForInteractions } from '../utils/timers';
-import type { ClearableTextInputProps } from './clearable-text-input';
-import TextInput from './text-input.react';
+import { waitForInteractions } from '../utils/timers.js';
+import type { ClearableTextInputProps } from './clearable-text-input.js';
+import TextInput from './text-input.react.js';
class ClearableTextInput extends React.PureComponent<ClearableTextInputProps> {
textInput: ?React.ElementRef<typeof BaseTextInput>;
diff --git a/native/components/color-selector-button.react.js b/native/components/color-selector-button.react.js
--- a/native/components/color-selector-button.react.js
+++ b/native/components/color-selector-button.react.js
@@ -4,9 +4,9 @@
import { TouchableOpacity, View } from 'react-native';
import tinycolor from 'tinycolor2';
-import type { SetState } from 'lib/types/hook-types';
+import type { SetState } from 'lib/types/hook-types.js';
-import { useStyles } from '../themes/colors';
+import { useStyles } from '../themes/colors.js';
type ColorSelectorButtonProps = {
+color: string,
diff --git a/native/components/color-selector.react.js b/native/components/color-selector.react.js
--- a/native/components/color-selector.react.js
+++ b/native/components/color-selector.react.js
@@ -4,10 +4,10 @@
import { Text, TouchableOpacity, View } from 'react-native';
import tinycolor from 'tinycolor2';
-import { selectedThreadColors } from 'lib/shared/thread-utils';
+import { selectedThreadColors } from 'lib/shared/thread-utils.js';
-import { useStyles } from '../themes/colors';
-import ColorSelectorButton from './color-selector-button.react';
+import { useStyles } from '../themes/colors.js';
+import ColorSelectorButton from './color-selector-button.react.js';
type ColorSelectorProps = {
+currentColor: string,
diff --git a/native/components/community-pill.react.js b/native/components/community-pill.react.js
--- a/native/components/community-pill.react.js
+++ b/native/components/community-pill.react.js
@@ -3,13 +3,13 @@
import * as React from 'react';
import { View, StyleSheet } from 'react-native';
-import { useKeyserverAdmin } from 'lib/shared/user-utils';
-import type { ThreadInfo } from 'lib/types/thread-types';
+import { useKeyserverAdmin } from 'lib/shared/user-utils.js';
+import type { ThreadInfo } from 'lib/types/thread-types.js';
-import { useColors } from '../themes/colors';
-import CommIcon from './comm-icon.react';
-import Pill from './pill.react';
-import ThreadPill from './thread-pill.react';
+import { useColors } from '../themes/colors.js';
+import CommIcon from './comm-icon.react.js';
+import Pill from './pill.react.js';
+import ThreadPill from './thread-pill.react.js';
type Props = {
+community: ThreadInfo,
diff --git a/native/components/content-loading.react.js b/native/components/content-loading.react.js
--- a/native/components/content-loading.react.js
+++ b/native/components/content-loading.react.js
@@ -3,7 +3,7 @@
import * as React from 'react';
import { View, ActivityIndicator, StyleSheet } from 'react-native';
-import type { Colors } from '../themes/colors';
+import type { Colors } from '../themes/colors.js';
type Props = {
+fillType: 'flex' | 'absolute',
diff --git a/native/components/edit-setting-button.react.js b/native/components/edit-setting-button.react.js
--- a/native/components/edit-setting-button.react.js
+++ b/native/components/edit-setting-button.react.js
@@ -3,9 +3,9 @@
import * as React from 'react';
import { TouchableOpacity, StyleSheet, Platform } from 'react-native';
-import { useColors } from '../themes/colors';
-import type { TextStyle } from '../types/styles';
-import SWMansionIcon from './swmansion-icon.react';
+import { useColors } from '../themes/colors.js';
+import type { TextStyle } from '../types/styles.js';
+import SWMansionIcon from './swmansion-icon.react.js';
type Props = {
+onPress: () => void,
diff --git a/native/components/gesture-touchable-opacity.react.js b/native/components/gesture-touchable-opacity.react.js
--- a/native/components/gesture-touchable-opacity.react.js
+++ b/native/components/gesture-touchable-opacity.react.js
@@ -9,11 +9,11 @@
} from 'react-native-gesture-handler';
import Animated, { EasingNode } from 'react-native-reanimated';
-import type { AnimatedViewStyle, ViewStyle } from '../types/styles';
+import type { AnimatedViewStyle, ViewStyle } from '../types/styles.js';
import {
runTiming,
useReanimatedValueForBoolean,
-} from '../utils/animation-utils';
+} from '../utils/animation-utils.js';
/* eslint-disable import/no-named-as-default-member */
const {
diff --git a/native/components/keyboard-avoiding-view.react.js b/native/components/keyboard-avoiding-view.react.js
--- a/native/components/keyboard-avoiding-view.react.js
+++ b/native/components/keyboard-avoiding-view.react.js
@@ -10,18 +10,18 @@
StyleSheet,
} from 'react-native';
-import type { ScreenRect } from '../keyboard/keyboard';
import {
type KeyboardState,
KeyboardContext,
-} from '../keyboard/keyboard-state';
+} from '../keyboard/keyboard-state.js';
+import type { ScreenRect } from '../keyboard/keyboard.js';
import type {
Layout,
LayoutEvent,
EventSubscription,
KeyboardEvent,
-} from '../types/react-native';
-import type { ViewStyle } from '../types/styles';
+} from '../types/react-native.js';
+import type { ViewStyle } from '../types/styles.js';
type ViewProps = React.ElementConfig<typeof View>;
type BaseProps = {
diff --git a/native/components/link-button.react.js b/native/components/link-button.react.js
--- a/native/components/link-button.react.js
+++ b/native/components/link-button.react.js
@@ -3,9 +3,9 @@
import * as React from 'react';
import { Text } from 'react-native';
-import { useStyles } from '../themes/colors';
-import type { ViewStyle } from '../types/styles';
-import Button from './button.react';
+import { useStyles } from '../themes/colors.js';
+import type { ViewStyle } from '../types/styles.js';
+import Button from './button.react.js';
type BaseProps = {
+text: string,
diff --git a/native/components/list-loading-indicator.react.js b/native/components/list-loading-indicator.react.js
--- a/native/components/list-loading-indicator.react.js
+++ b/native/components/list-loading-indicator.react.js
@@ -3,7 +3,7 @@
import * as React from 'react';
import { ActivityIndicator } from 'react-native';
-import { useStyles, useColors } from '../themes/colors';
+import { useStyles, useColors } from '../themes/colors.js';
function ListLoadingIndicator(): React.Node {
const styles = useStyles(unboundStyles);
diff --git a/native/components/modal.react.js b/native/components/modal.react.js
--- a/native/components/modal.react.js
+++ b/native/components/modal.react.js
@@ -5,9 +5,9 @@
import { View, TouchableWithoutFeedback, StyleSheet } from 'react-native';
import { SafeAreaView } from 'react-native-safe-area-context';
-import { useStyles } from '../themes/colors';
-import type { ViewStyle } from '../types/styles';
-import KeyboardAvoidingView from './keyboard-avoiding-view.react';
+import { useStyles } from '../themes/colors.js';
+import type { ViewStyle } from '../types/styles.js';
+import KeyboardAvoidingView from './keyboard-avoiding-view.react.js';
type Props = $ReadOnly<{
+children: React.Node,
diff --git a/native/components/node-height-measurer.react.js b/native/components/node-height-measurer.react.js
--- a/native/components/node-height-measurer.react.js
+++ b/native/components/node-height-measurer.react.js
@@ -5,13 +5,13 @@
import { View, StyleSheet, PixelRatio } from 'react-native';
import shallowequal from 'shallowequal';
-import type { Shape } from 'lib/types/core';
+import type { Shape } from 'lib/types/core.js';
import {
addLifecycleListener,
getCurrentLifecycleState,
-} from '../lifecycle/lifecycle';
-import type { LayoutEvent, EventSubscription } from '../types/react-native';
+} from '../lifecycle/lifecycle.js';
+import type { LayoutEvent, EventSubscription } from '../types/react-native.js';
const measureBatchSize = 50;
diff --git a/native/components/pencil-icon.react.js b/native/components/pencil-icon.react.js
--- a/native/components/pencil-icon.react.js
+++ b/native/components/pencil-icon.react.js
@@ -3,8 +3,8 @@
import * as React from 'react';
import { Platform } from 'react-native';
-import { useStyles } from '../themes/colors';
-import SWMansionIcon from './swmansion-icon.react';
+import { useStyles } from '../themes/colors.js';
+import SWMansionIcon from './swmansion-icon.react.js';
function PencilIcon(): React.Node {
const styles = useStyles(unboundStyles);
diff --git a/native/components/persisted-state-gate.js b/native/components/persisted-state-gate.js
--- a/native/components/persisted-state-gate.js
+++ b/native/components/persisted-state-gate.js
@@ -2,7 +2,7 @@
import * as React from 'react';
-import { usePersistedStateLoaded } from '../selectors/app-state-selectors';
+import { usePersistedStateLoaded } from '../selectors/app-state-selectors.js';
function PersistedStateGate(props: { +children: React.Node }): React.Node {
const persistedStateLoaded = usePersistedStateLoaded();
diff --git a/native/components/pill.react.js b/native/components/pill.react.js
--- a/native/components/pill.react.js
+++ b/native/components/pill.react.js
@@ -4,7 +4,7 @@
import { View, Text } from 'react-native';
import tinycolor from 'tinycolor2';
-import { useStyles } from '../themes/colors';
+import { useStyles } from '../themes/colors.js';
type Props = {
+label: string,
diff --git a/native/components/search.react.js b/native/components/search.react.js
--- a/native/components/search.react.js
+++ b/native/components/search.react.js
@@ -9,13 +9,13 @@
Platform,
} from 'react-native';
-import { isLoggedIn } from 'lib/selectors/user-selectors';
+import { isLoggedIn } from 'lib/selectors/user-selectors.js';
-import { useSelector } from '../redux/redux-utils';
-import { useStyles, useColors } from '../themes/colors';
-import type { ViewStyle } from '../types/styles';
-import SWMansionIcon from './swmansion-icon.react';
-import TextInput from './text-input.react';
+import { useSelector } from '../redux/redux-utils.js';
+import { useStyles, useColors } from '../themes/colors.js';
+import type { ViewStyle } from '../types/styles.js';
+import SWMansionIcon from './swmansion-icon.react.js';
+import TextInput from './text-input.react.js';
type Props = {
...React.ElementConfig<typeof BaseTextInput>,
diff --git a/native/components/selectable-text-input.js b/native/components/selectable-text-input.js
--- a/native/components/selectable-text-input.js
+++ b/native/components/selectable-text-input.js
@@ -2,10 +2,10 @@
import * as React from 'react';
-import type { Selection } from 'lib/shared/typeahead-utils';
+import type { Selection } from 'lib/shared/typeahead-utils.js';
-import type { ClearableTextInputProps } from './clearable-text-input';
-import ClearableTextInput from './clearable-text-input.react';
+import type { ClearableTextInputProps } from './clearable-text-input.js';
+import ClearableTextInput from './clearable-text-input.react.js';
export type SyncedSelectionData = {
+text: string,
diff --git a/native/components/selectable-text-input.react.ios.js b/native/components/selectable-text-input.react.ios.js
--- a/native/components/selectable-text-input.react.ios.js
+++ b/native/components/selectable-text-input.react.ios.js
@@ -1,16 +1,16 @@
// @flow
-import _debounce from 'lodash/debounce';
+import _debounce from 'lodash/debounce.js';
import * as React from 'react';
-import type { Selection } from 'lib/shared/typeahead-utils';
+import type { Selection } from 'lib/shared/typeahead-utils.js';
-import type { SelectionChangeEvent } from '../types/react-native';
-import ClearableTextInput from './clearable-text-input.react';
+import type { SelectionChangeEvent } from '../types/react-native.js';
+import ClearableTextInput from './clearable-text-input.react.js';
import type {
SelectableTextInputProps,
SelectableTextInputRef,
-} from './selectable-text-input';
+} from './selectable-text-input.js';
const SelectableTextInput = React.forwardRef(function BaseSelectableTextInput(
props,
diff --git a/native/components/selectable-text-input.react.js b/native/components/selectable-text-input.react.js
--- a/native/components/selectable-text-input.react.js
+++ b/native/components/selectable-text-input.react.js
@@ -2,12 +2,12 @@
import * as React from 'react';
-import type { SelectionChangeEvent } from '../types/react-native';
-import ClearableTextInput from './clearable-text-input.react';
+import type { SelectionChangeEvent } from '../types/react-native.js';
+import ClearableTextInput from './clearable-text-input.react.js';
import type {
SelectableTextInputProps,
SelectableTextInputRef,
-} from './selectable-text-input';
+} from './selectable-text-input.js';
const SelectableTextInput = React.forwardRef(function BaseSelectableTextInput(
props,
diff --git a/native/components/single-line.react.js b/native/components/single-line.react.js
--- a/native/components/single-line.react.js
+++ b/native/components/single-line.react.js
@@ -3,7 +3,7 @@
import * as React from 'react';
import { Text } from 'react-native';
-import { firstLine } from 'lib/utils/string-utils';
+import { firstLine } from 'lib/utils/string-utils.js';
type Props = {
...React.ElementConfig<typeof Text>,
diff --git a/native/components/swipeable.js b/native/components/swipeable.js
--- a/native/components/swipeable.js
+++ b/native/components/swipeable.js
@@ -5,8 +5,8 @@
import SwipeableComponent from 'react-native-gesture-handler/Swipeable';
import { useSelector } from 'react-redux';
-import { type Colors, useColors, useStyles } from '../themes/colors';
-import Button from './button.react';
+import { type Colors, useColors, useStyles } from '../themes/colors.js';
+import Button from './button.react.js';
type BaseProps = {
+buttonWidth: number,
diff --git a/native/components/tag-input.react.js b/native/components/tag-input.react.js
--- a/native/components/tag-input.react.js
+++ b/native/components/tag-input.react.js
@@ -13,17 +13,17 @@
Platform,
} from 'react-native';
-import type { Shape } from 'lib/types/core';
+import type { Shape } from 'lib/types/core.js';
-import { useSelector } from '../redux/redux-utils';
-import { useColors, type Colors } from '../themes/colors';
+import { useSelector } from '../redux/redux-utils.js';
+import { useColors, type Colors } from '../themes/colors.js';
import type {
LayoutEvent,
KeyPressEvent,
BlurEvent,
-} from '../types/react-native';
-import type { ViewStyle, TextStyle } from '../types/styles';
-import TextInput from './text-input.react';
+} from '../types/react-native.js';
+import type { ViewStyle, TextStyle } from '../types/styles.js';
+import TextInput from './text-input.react.js';
type DefaultProps = {
/**
diff --git a/native/components/text-input.react.js b/native/components/text-input.react.js
--- a/native/components/text-input.react.js
+++ b/native/components/text-input.react.js
@@ -3,7 +3,7 @@
import * as React from 'react';
import { TextInput } from 'react-native';
-import { useKeyboardAppearance } from '../themes/colors';
+import { useKeyboardAppearance } from '../themes/colors.js';
type Props = React.ElementConfig<typeof TextInput>;
function ForwardedTextInput(props: Props, ref): React.Node {
diff --git a/native/components/thread-ancestors-label.react.js b/native/components/thread-ancestors-label.react.js
--- a/native/components/thread-ancestors-label.react.js
+++ b/native/components/thread-ancestors-label.react.js
@@ -1,14 +1,14 @@
// @flow
-import Icon from '@expo/vector-icons/FontAwesome5';
+import Icon from '@expo/vector-icons/FontAwesome5.js';
import * as React from 'react';
import { Text, View } from 'react-native';
-import { useAncestorThreads } from 'lib/shared/ancestor-threads';
-import { type ThreadInfo } from 'lib/types/thread-types';
-import { useResolvedThreadInfos } from 'lib/utils/entity-helpers';
+import { useAncestorThreads } from 'lib/shared/ancestor-threads.js';
+import { type ThreadInfo } from 'lib/types/thread-types.js';
+import { useResolvedThreadInfos } from 'lib/utils/entity-helpers.js';
-import { useColors, useStyles } from '../themes/colors';
+import { useColors, useStyles } from '../themes/colors.js';
type Props = {
+threadInfo: ThreadInfo,
diff --git a/native/components/thread-ancestors.react.js b/native/components/thread-ancestors.react.js
--- a/native/components/thread-ancestors.react.js
+++ b/native/components/thread-ancestors.react.js
@@ -1,19 +1,19 @@
// @flow
-import Icon from '@expo/vector-icons/FontAwesome5';
+import Icon from '@expo/vector-icons/FontAwesome5.js';
import * as React from 'react';
import { View } from 'react-native';
import { ScrollView } from 'react-native-gesture-handler';
-import { ancestorThreadInfos } from 'lib/selectors/thread-selectors';
-import type { ThreadInfo } from 'lib/types/thread-types';
+import { ancestorThreadInfos } from 'lib/selectors/thread-selectors.js';
+import type { ThreadInfo } from 'lib/types/thread-types.js';
-import { useNavigateToThread } from '../chat/message-list-types';
-import { useSelector } from '../redux/redux-utils';
-import { useColors, useStyles } from '../themes/colors';
-import Button from './button.react';
-import CommunityPill from './community-pill.react';
-import ThreadPill from './thread-pill.react';
+import { useNavigateToThread } from '../chat/message-list-types.js';
+import { useSelector } from '../redux/redux-utils.js';
+import { useColors, useStyles } from '../themes/colors.js';
+import Button from './button.react.js';
+import CommunityPill from './community-pill.react.js';
+import ThreadPill from './thread-pill.react.js';
type Props = {
+threadInfo: ThreadInfo,
diff --git a/native/components/thread-icon.react.js b/native/components/thread-icon.react.js
--- a/native/components/thread-icon.react.js
+++ b/native/components/thread-icon.react.js
@@ -1,12 +1,12 @@
// @flow
-import EntypoIcon from '@expo/vector-icons/Entypo';
+import EntypoIcon from '@expo/vector-icons/Entypo.js';
import * as React from 'react';
import { StyleSheet } from 'react-native';
-import { threadTypes, type ThreadType } from 'lib/types/thread-types';
+import { threadTypes, type ThreadType } from 'lib/types/thread-types.js';
-import SWMansionIcon from './swmansion-icon.react';
+import SWMansionIcon from './swmansion-icon.react.js';
type Props = {
+threadType: ThreadType,
diff --git a/native/components/thread-list-thread.react.js b/native/components/thread-list-thread.react.js
--- a/native/components/thread-list-thread.react.js
+++ b/native/components/thread-list-thread.react.js
@@ -2,14 +2,14 @@
import * as React from 'react';
-import type { ThreadInfo, ResolvedThreadInfo } from 'lib/types/thread-types';
-import { useResolvedThreadInfo } from 'lib/utils/entity-helpers';
+import type { ThreadInfo, ResolvedThreadInfo } from 'lib/types/thread-types.js';
+import { useResolvedThreadInfo } from 'lib/utils/entity-helpers.js';
-import { type Colors, useStyles, useColors } from '../themes/colors';
-import type { ViewStyle, TextStyle } from '../types/styles';
-import Button from './button.react';
-import ColorSplotch from './color-splotch.react';
-import { SingleLine } from './single-line.react';
+import { type Colors, useStyles, useColors } from '../themes/colors.js';
+import type { ViewStyle, TextStyle } from '../types/styles.js';
+import Button from './button.react.js';
+import ColorSplotch from './color-splotch.react.js';
+import { SingleLine } from './single-line.react.js';
type SharedProps = {
+onSelect: (threadID: string) => void,
diff --git a/native/components/thread-list.react.js b/native/components/thread-list.react.js
--- a/native/components/thread-list.react.js
+++ b/native/components/thread-list.react.js
@@ -5,18 +5,18 @@
import { FlatList, TextInput } from 'react-native';
import { createSelector } from 'reselect';
-import SearchIndex from 'lib/shared/search-index';
-import type { ThreadInfo } from 'lib/types/thread-types';
+import SearchIndex from 'lib/shared/search-index.js';
+import type { ThreadInfo } from 'lib/types/thread-types.js';
import {
type IndicatorStyle,
useStyles,
useIndicatorStyle,
-} from '../themes/colors';
-import type { ViewStyle, TextStyle } from '../types/styles';
-import { waitForModalInputFocus } from '../utils/timers';
-import Search from './search.react';
-import ThreadListThread from './thread-list-thread.react';
+} from '../themes/colors.js';
+import type { ViewStyle, TextStyle } from '../types/styles.js';
+import { waitForModalInputFocus } from '../utils/timers.js';
+import Search from './search.react.js';
+import ThreadListThread from './thread-list-thread.react.js';
type BaseProps = {
+threadInfos: $ReadOnlyArray<ThreadInfo>,
diff --git a/native/components/thread-pill.react.js b/native/components/thread-pill.react.js
--- a/native/components/thread-pill.react.js
+++ b/native/components/thread-pill.react.js
@@ -2,10 +2,10 @@
import * as React from 'react';
-import type { ThreadInfo } from 'lib/types/thread-types';
-import { useResolvedThreadInfo } from 'lib/utils/entity-helpers';
+import type { ThreadInfo } from 'lib/types/thread-types.js';
+import { useResolvedThreadInfo } from 'lib/utils/entity-helpers.js';
-import Pill from './pill.react';
+import Pill from './pill.react.js';
type Props = {
+threadInfo: ThreadInfo,
diff --git a/native/components/thread-visibility.react.js b/native/components/thread-visibility.react.js
--- a/native/components/thread-visibility.react.js
+++ b/native/components/thread-visibility.react.js
@@ -4,11 +4,11 @@
import { View, StyleSheet } from 'react-native';
import tinycolor from 'tinycolor2';
-import { threadLabel } from 'lib/shared/thread-utils';
-import type { ThreadType } from 'lib/types/thread-types';
+import { threadLabel } from 'lib/shared/thread-utils.js';
+import type { ThreadType } from 'lib/types/thread-types.js';
-import Pill from './pill.react';
-import ThreadIcon from './thread-icon.react';
+import Pill from './pill.react.js';
+import ThreadIcon from './thread-icon.react.js';
type Props = {
+threadType: ThreadType,
diff --git a/native/components/unread-dot.react.js b/native/components/unread-dot.react.js
--- a/native/components/unread-dot.react.js
+++ b/native/components/unread-dot.react.js
@@ -3,8 +3,8 @@
import * as React from 'react';
import { View } from 'react-native';
-import { useColors } from '../themes/colors';
-import ColorSplotch from './color-splotch.react';
+import { useColors } from '../themes/colors.js';
+import ColorSplotch from './color-splotch.react.js';
type Props = {
+unread: ?boolean,
diff --git a/native/components/user-list-user.react.js b/native/components/user-list-user.react.js
--- a/native/components/user-list-user.react.js
+++ b/native/components/user-list-user.react.js
@@ -3,12 +3,12 @@
import * as React from 'react';
import { Text, Platform, Alert } from 'react-native';
-import type { UserListItem } from 'lib/types/user-types';
+import type { UserListItem } from 'lib/types/user-types.js';
-import { type Colors, useColors, useStyles } from '../themes/colors';
-import type { TextStyle } from '../types/styles';
-import Button from './button.react';
-import { SingleLine } from './single-line.react';
+import { type Colors, useColors, useStyles } from '../themes/colors.js';
+import type { TextStyle } from '../types/styles.js';
+import Button from './button.react.js';
+import { SingleLine } from './single-line.react.js';
// eslint-disable-next-line no-unused-vars
const getUserListItemHeight = (item: UserListItem): number => {
diff --git a/native/components/user-list.react.js b/native/components/user-list.react.js
--- a/native/components/user-list.react.js
+++ b/native/components/user-list.react.js
@@ -1,14 +1,14 @@
// @flow
-import _sum from 'lodash/fp/sum';
+import _sum from 'lodash/fp/sum.js';
import * as React from 'react';
import { FlatList } from 'react-native';
-import type { UserListItem } from 'lib/types/user-types';
+import type { UserListItem } from 'lib/types/user-types.js';
-import { type IndicatorStyle, useIndicatorStyle } from '../themes/colors';
-import type { TextStyle } from '../types/styles';
-import { UserListUser, getUserListItemHeight } from './user-list-user.react';
+import { type IndicatorStyle, useIndicatorStyle } from '../themes/colors.js';
+import type { TextStyle } from '../types/styles.js';
+import { UserListUser, getUserListItemHeight } from './user-list-user.react.js';
type BaseProps = {
+userInfos: $ReadOnlyArray<UserListItem>,
diff --git a/native/config.js b/native/config.js
--- a/native/config.js
+++ b/native/config.js
@@ -2,10 +2,10 @@
import { Platform } from 'react-native';
-import { registerConfig } from 'lib/utils/config';
+import { registerConfig } from 'lib/utils/config.js';
-import { resolveInvalidatedCookie } from './account/resolve-invalidated-cookie';
-import { persistConfig, codeVersion } from './redux/persist';
+import { resolveInvalidatedCookie } from './account/resolve-invalidated-cookie.js';
+import { persistConfig, codeVersion } from './redux/persist.js';
registerConfig({
resolveInvalidatedCookie,
diff --git a/native/connected-status-bar.react.js b/native/connected-status-bar.react.js
--- a/native/connected-status-bar.react.js
+++ b/native/connected-status-bar.react.js
@@ -3,9 +3,9 @@
import * as React from 'react';
import { StatusBar, Platform } from 'react-native';
-import { globalLoadingStatusSelector } from 'lib/selectors/loading-selectors';
+import { globalLoadingStatusSelector } from 'lib/selectors/loading-selectors.js';
-import { useSelector } from './redux/redux-utils';
+import { useSelector } from './redux/redux-utils.js';
type Props = {
+barStyle?: 'default' | 'light-content' | 'dark-content',
diff --git a/native/crash.react.js b/native/crash.react.js
--- a/native/crash.react.js
+++ b/native/crash.react.js
@@ -1,9 +1,9 @@
// @flow
-import Icon from '@expo/vector-icons/FontAwesome';
+import Icon from '@expo/vector-icons/FontAwesome.js';
import Clipboard from '@react-native-clipboard/clipboard';
import invariant from 'invariant';
-import _shuffle from 'lodash/fp/shuffle';
+import _shuffle from 'lodash/fp/shuffle.js';
import * as React from 'react';
import {
View,
@@ -15,35 +15,38 @@
} from 'react-native';
import ExitApp from 'react-native-exit-app';
-import { sendReportActionTypes, sendReport } from 'lib/actions/report-actions';
-import { logOutActionTypes, logOut } from 'lib/actions/user-actions';
-import { preRequestUserStateSelector } from 'lib/selectors/account-selectors';
-import type { LogOutResult } from 'lib/types/account-types';
-import type { ErrorData } from 'lib/types/report-types';
+import {
+ sendReportActionTypes,
+ sendReport,
+} from 'lib/actions/report-actions.js';
+import { logOutActionTypes, logOut } from 'lib/actions/user-actions.js';
+import { preRequestUserStateSelector } from 'lib/selectors/account-selectors.js';
+import type { LogOutResult } from 'lib/types/account-types.js';
+import type { ErrorData } from 'lib/types/report-types.js';
import {
type ClientReportCreationRequest,
type ReportCreationResponse,
reportTypes,
-} from 'lib/types/report-types';
-import type { PreRequestUserState } from 'lib/types/session-types';
-import { actionLogger } from 'lib/utils/action-logger';
+} from 'lib/types/report-types.js';
+import type { PreRequestUserState } from 'lib/types/session-types.js';
+import { actionLogger } from 'lib/utils/action-logger.js';
import {
type DispatchActionPromise,
useServerCall,
useDispatchActionPromise,
-} from 'lib/utils/action-utils';
-import { useIsReportEnabled } from 'lib/utils/report-utils';
+} from 'lib/utils/action-utils.js';
+import { useIsReportEnabled } from 'lib/utils/report-utils.js';
import {
sanitizeReduxReport,
type ReduxCrashReport,
-} from 'lib/utils/sanitization';
-import sleep from 'lib/utils/sleep';
+} from 'lib/utils/sanitization.js';
+import sleep from 'lib/utils/sleep.js';
-import Button from './components/button.react';
-import ConnectedStatusBar from './connected-status-bar.react';
-import { persistConfig, codeVersion } from './redux/persist';
-import { useSelector } from './redux/redux-utils';
-import { wipeAndExit } from './utils/crash-utils';
+import Button from './components/button.react.js';
+import ConnectedStatusBar from './connected-status-bar.react.js';
+import { persistConfig, codeVersion } from './redux/persist.js';
+import { useSelector } from './redux/redux-utils.js';
+import { wipeAndExit } from './utils/crash-utils.js';
const errorTitles = ['Oh no!!', 'Womp womp womp...'];
diff --git a/native/data/sqlite-data-handler.js b/native/data/sqlite-data-handler.js
--- a/native/data/sqlite-data-handler.js
+++ b/native/data/sqlite-data-handler.js
@@ -5,22 +5,22 @@
import ExitApp from 'react-native-exit-app';
import { useDispatch } from 'react-redux';
-import { setClientDBStoreActionType } from 'lib/actions/client-db-store-actions';
-import { isLoggedIn } from 'lib/selectors/user-selectors';
+import { setClientDBStoreActionType } from 'lib/actions/client-db-store-actions.js';
+import { isLoggedIn } from 'lib/selectors/user-selectors.js';
import {
logInActionSources,
type LogInActionSource,
-} from 'lib/types/account-types';
-import { fetchNewCookieFromNativeCredentials } from 'lib/utils/action-utils';
-import { getMessageForException } from 'lib/utils/errors';
-import { convertClientDBThreadInfosToRawThreadInfos } from 'lib/utils/thread-ops-utils';
+} from 'lib/types/account-types.js';
+import { fetchNewCookieFromNativeCredentials } from 'lib/utils/action-utils.js';
+import { getMessageForException } from 'lib/utils/errors.js';
+import { convertClientDBThreadInfosToRawThreadInfos } from 'lib/utils/thread-ops-utils.js';
-import { commCoreModule } from '../native-modules';
-import { setStoreLoadedActionType } from '../redux/action-types';
-import { useSelector } from '../redux/redux-utils';
-import { StaffContext } from '../staff/staff-context';
-import { isTaskCancelledError } from '../utils/error-handling';
-import { useStaffCanSee } from '../utils/staff-utils';
+import { commCoreModule } from '../native-modules.js';
+import { setStoreLoadedActionType } from '../redux/action-types.js';
+import { useSelector } from '../redux/redux-utils.js';
+import { StaffContext } from '../staff/staff-context.js';
+import { isTaskCancelledError } from '../utils/error-handling.js';
+import { useStaffCanSee } from '../utils/staff-utils.js';
function SQLiteDataHandler(): React.Node {
const storeLoaded = useSelector(state => state.storeLoaded);
diff --git a/native/error-boundary.react.js b/native/error-boundary.react.js
--- a/native/error-boundary.react.js
+++ b/native/error-boundary.react.js
@@ -2,9 +2,9 @@
import * as React from 'react';
-import type { ErrorInfo, ErrorData } from 'lib/types/report-types';
+import type { ErrorInfo, ErrorData } from 'lib/types/report-types.js';
-import Crash from './crash.react';
+import Crash from './crash.react.js';
let instance: ?ErrorBoundary = null;
const defaultHandler = global.ErrorUtils.getGlobalHandler();
diff --git a/native/index.js b/native/index.js
--- a/native/index.js
+++ b/native/index.js
@@ -8,15 +8,15 @@
// with Android 13. To avoid it we patch a react-native style, but that style
// got deprecated in React Native 0.70. For now the deprecation is limited to a
// JS runtime check, which we disable here.
-import ViewReactNativeStyleAttributes from 'react-native/Libraries/Components/View/ReactNativeStyleAttributes';
+import ViewReactNativeStyleAttributes from 'react-native/Libraries/Components/View/ReactNativeStyleAttributes.js';
ViewReactNativeStyleAttributes.scaleY = true;
-import './reactotron';
-import './config';
+import './reactotron.js';
+import './config.js';
import { AppRegistry } from 'react-native';
import { name as appName } from './app.json';
-import Root from './root.react';
+import Root from './root.react.js';
AppRegistry.registerComponent(appName, () => Root);
diff --git a/native/input/input-state-container.react.js b/native/input/input-state-container.react.js
--- a/native/input/input-state-container.react.js
+++ b/native/input/input-state-container.react.js
@@ -13,87 +13,90 @@
sendMultimediaMessage,
sendTextMessageActionTypes,
sendTextMessage,
-} from 'lib/actions/message-actions';
-import { queueReportsActionType } from 'lib/actions/report-actions';
-import { newThread } from 'lib/actions/thread-actions';
+} from 'lib/actions/message-actions.js';
+import { queueReportsActionType } from 'lib/actions/report-actions.js';
+import { newThread } from 'lib/actions/thread-actions.js';
import {
uploadMultimedia,
updateMultimediaMessageMediaActionType,
type MultimediaUploadCallbacks,
type MultimediaUploadExtras,
-} from 'lib/actions/upload-actions';
-import { pathFromURI, replaceExtension } from 'lib/media/file-utils';
-import { isLocalUploadID, getNextLocalUploadID } from 'lib/media/media-utils';
-import { videoDurationLimit } from 'lib/media/video-utils';
+} from 'lib/actions/upload-actions.js';
+import { pathFromURI, replaceExtension } from 'lib/media/file-utils.js';
+import {
+ isLocalUploadID,
+ getNextLocalUploadID,
+} from 'lib/media/media-utils.js';
+import { videoDurationLimit } from 'lib/media/video-utils.js';
import {
createLoadingStatusSelector,
combineLoadingStatuses,
-} from 'lib/selectors/loading-selectors';
+} from 'lib/selectors/loading-selectors.js';
import {
createMediaMessageInfo,
localIDPrefix,
-} from 'lib/shared/message-utils';
+} from 'lib/shared/message-utils.js';
import {
createRealThreadFromPendingThread,
threadIsPending,
-} from 'lib/shared/thread-utils';
-import type { CalendarQuery } from 'lib/types/entry-types';
+} from 'lib/shared/thread-utils.js';
+import type { CalendarQuery } from 'lib/types/entry-types.js';
import type {
UploadMultimediaResult,
Media,
NativeMediaSelection,
MediaMissionResult,
MediaMission,
-} from 'lib/types/media-types';
+} from 'lib/types/media-types.js';
import {
messageTypes,
type RawMessageInfo,
type RawMultimediaMessageInfo,
type SendMessageResult,
type SendMessagePayload,
-} from 'lib/types/message-types';
-import type { RawImagesMessageInfo } from 'lib/types/messages/images';
+} from 'lib/types/message-types.js';
+import type { RawImagesMessageInfo } from 'lib/types/messages/images.js';
import type {
MediaMessageServerDBContent,
RawMediaMessageInfo,
-} from 'lib/types/messages/media';
-import { getMediaMessageServerDBContentsFromMedia } from 'lib/types/messages/media';
-import type { RawTextMessageInfo } from 'lib/types/messages/text';
-import type { Dispatch } from 'lib/types/redux-types';
+} from 'lib/types/messages/media.js';
+import { getMediaMessageServerDBContentsFromMedia } from 'lib/types/messages/media.js';
+import type { RawTextMessageInfo } from 'lib/types/messages/text.js';
+import type { Dispatch } from 'lib/types/redux-types.js';
import {
type MediaMissionReportCreationRequest,
reportTypes,
-} from 'lib/types/report-types';
+} from 'lib/types/report-types.js';
import type {
ClientNewThreadRequest,
NewThreadResult,
ThreadInfo,
-} from 'lib/types/thread-types';
+} from 'lib/types/thread-types.js';
import {
type DispatchActionPromise,
useServerCall,
useDispatchActionPromise,
-} from 'lib/utils/action-utils';
+} from 'lib/utils/action-utils.js';
import type {
CallServerEndpointOptions,
CallServerEndpointResponse,
-} from 'lib/utils/call-server-endpoint';
-import { getConfig } from 'lib/utils/config';
-import { getMessageForException, cloneError } from 'lib/utils/errors';
-import { values } from 'lib/utils/objects';
-import { useIsReportEnabled } from 'lib/utils/report-utils';
-
-import { disposeTempFile } from '../media/file-utils';
-import { processMedia } from '../media/media-utils';
-import { displayActionResultModal } from '../navigation/action-result-modal';
-import { useCalendarQuery } from '../navigation/nav-selectors';
-import { useSelector } from '../redux/redux-utils';
-import { useStaffCanSee } from '../utils/staff-utils';
+} from 'lib/utils/call-server-endpoint.js';
+import { getConfig } from 'lib/utils/config.js';
+import { getMessageForException, cloneError } from 'lib/utils/errors.js';
+import { values } from 'lib/utils/objects.js';
+import { useIsReportEnabled } from 'lib/utils/report-utils.js';
+
+import { disposeTempFile } from '../media/file-utils.js';
+import { processMedia } from '../media/media-utils.js';
+import { displayActionResultModal } from '../navigation/action-result-modal.js';
+import { useCalendarQuery } from '../navigation/nav-selectors.js';
+import { useSelector } from '../redux/redux-utils.js';
+import { useStaffCanSee } from '../utils/staff-utils.js';
import {
InputStateContext,
type PendingMultimediaUploads,
type MultimediaProcessingStep,
-} from './input-state';
+} from './input-state.js';
type MediaIDs =
| { +type: 'photo', +localMediaID: string }
diff --git a/native/input/input-state.js b/native/input/input-state.js
--- a/native/input/input-state.js
+++ b/native/input/input-state.js
@@ -2,9 +2,9 @@
import * as React from 'react';
-import type { NativeMediaSelection } from 'lib/types/media-types';
-import type { RawTextMessageInfo } from 'lib/types/messages/text';
-import type { ThreadInfo } from 'lib/types/thread-types';
+import type { NativeMediaSelection } from 'lib/types/media-types.js';
+import type { RawTextMessageInfo } from 'lib/types/messages/text.js';
+import type { ThreadInfo } from 'lib/types/thread-types.js';
export type MultimediaProcessingStep = 'transcoding' | 'uploading';
diff --git a/native/keyboard/keyboard-input-host.react.js b/native/keyboard/keyboard-input-host.react.js
--- a/native/keyboard/keyboard-input-host.react.js
+++ b/native/keyboard/keyboard-input-host.react.js
@@ -5,15 +5,15 @@
import { TextInput } from 'react-native';
import { KeyboardAccessoryView } from 'react-native-keyboard-input';
-import type { MediaLibrarySelection } from 'lib/types/media-types';
-import type { ThreadInfo } from 'lib/types/thread-types';
+import type { MediaLibrarySelection } from 'lib/types/media-types.js';
+import type { ThreadInfo } from 'lib/types/thread-types.js';
-import { type InputState, InputStateContext } from '../input/input-state';
-import { mediaGalleryKeyboardName } from '../media/media-gallery-keyboard.react';
-import { activeMessageListSelector } from '../navigation/nav-selectors';
-import { NavContext } from '../navigation/navigation-context';
-import { useStyles } from '../themes/colors';
-import { type KeyboardState, KeyboardContext } from './keyboard-state';
+import { type InputState, InputStateContext } from '../input/input-state.js';
+import { mediaGalleryKeyboardName } from '../media/media-gallery-keyboard.react.js';
+import { activeMessageListSelector } from '../navigation/nav-selectors.js';
+import { NavContext } from '../navigation/navigation-context.js';
+import { useStyles } from '../themes/colors.js';
+import { type KeyboardState, KeyboardContext } from './keyboard-state.js';
type BaseProps = {
+textInputRef?: ?React.ElementRef<typeof TextInput>,
diff --git a/native/keyboard/keyboard-state-container.react.js b/native/keyboard/keyboard-state-container.react.js
--- a/native/keyboard/keyboard-state-container.react.js
+++ b/native/keyboard/keyboard-state-container.react.js
@@ -4,18 +4,18 @@
import { Platform } from 'react-native';
import { KeyboardUtils } from 'react-native-keyboard-input';
-import type { ThreadInfo } from 'lib/types/thread-types';
-import sleep from 'lib/utils/sleep';
+import type { ThreadInfo } from 'lib/types/thread-types.js';
+import sleep from 'lib/utils/sleep.js';
-import { tabBarAnimationDuration } from '../navigation/tab-bar.react';
-import { waitForInteractions } from '../utils/timers';
+import { tabBarAnimationDuration } from '../navigation/tab-bar.react.js';
+import { waitForInteractions } from '../utils/timers.js';
+import KeyboardInputHost from './keyboard-input-host.react.js';
+import { KeyboardContext } from './keyboard-state.js';
import {
addKeyboardShowListener,
addKeyboardDismissListener,
removeKeyboardListener,
-} from './keyboard';
-import KeyboardInputHost from './keyboard-input-host.react';
-import { KeyboardContext } from './keyboard-state';
+} from './keyboard.js';
type Props = {
+children: React.Node,
diff --git a/native/keyboard/keyboard-state.js b/native/keyboard/keyboard-state.js
--- a/native/keyboard/keyboard-state.js
+++ b/native/keyboard/keyboard-state.js
@@ -2,7 +2,7 @@
import * as React from 'react';
-import type { ThreadInfo } from 'lib/types/thread-types';
+import type { ThreadInfo } from 'lib/types/thread-types.js';
export type KeyboardState = {
+keyboardShowing: boolean,
diff --git a/native/keyboard/keyboard.js b/native/keyboard/keyboard.js
--- a/native/keyboard/keyboard.js
+++ b/native/keyboard/keyboard.js
@@ -2,7 +2,10 @@
import { Keyboard, Platform, DeviceInfo } from 'react-native';
-import type { EventSubscription, KeyboardEvent } from '../types/react-native';
+import type {
+ EventSubscription,
+ KeyboardEvent,
+} from '../types/react-native.js';
export type ScreenRect = $ReadOnly<{
screenX: number,
diff --git a/native/lifecycle/lifecycle-handler.react.js b/native/lifecycle/lifecycle-handler.react.js
--- a/native/lifecycle/lifecycle-handler.react.js
+++ b/native/lifecycle/lifecycle-handler.react.js
@@ -3,11 +3,11 @@
import * as React from 'react';
import { useSelector, useDispatch } from 'react-redux';
-import { updateLifecycleStateActionType } from 'lib/reducers/lifecycle-state-reducer';
-import type { LifecycleState } from 'lib/types/lifecycle-state-types';
+import { updateLifecycleStateActionType } from 'lib/reducers/lifecycle-state-reducer.js';
+import type { LifecycleState } from 'lib/types/lifecycle-state-types.js';
-import { appBecameInactive } from '../redux/redux-setup';
-import { addLifecycleListener } from './lifecycle';
+import { appBecameInactive } from '../redux/redux-setup.js';
+import { addLifecycleListener } from './lifecycle.js';
const LifecycleHandler: React.ComponentType<{}> = React.memo<{}>(
function LifecycleHandler() {
diff --git a/native/lifecycle/lifecycle-module.js b/native/lifecycle/lifecycle-module.js
--- a/native/lifecycle/lifecycle-module.js
+++ b/native/lifecycle/lifecycle-module.js
@@ -8,7 +8,7 @@
import invariant from 'invariant';
import { Platform } from 'react-native';
-import type { EmitterSubscription } from '../types/react-native';
+import type { EmitterSubscription } from '../types/react-native.js';
type Active = 'active';
type Background = 'background';
diff --git a/native/lifecycle/lifecycle.js b/native/lifecycle/lifecycle.js
--- a/native/lifecycle/lifecycle.js
+++ b/native/lifecycle/lifecycle.js
@@ -2,10 +2,13 @@
import { Platform, AppState as NativeAppState } from 'react-native';
-import { type LifecycleState } from 'lib/types/lifecycle-state-types';
+import { type LifecycleState } from 'lib/types/lifecycle-state-types.js';
-import type { EventSubscription } from '../types/react-native';
-import { addAndroidLifecycleListener, initialStatus } from './lifecycle-module';
+import type { EventSubscription } from '../types/react-native.js';
+import {
+ addAndroidLifecycleListener,
+ initialStatus,
+} from './lifecycle-module.js';
let currentLifecycleStatus = initialStatus;
if (Platform.OS === 'android') {
diff --git a/native/markdown/markdown-context.js b/native/markdown/markdown-context.js
--- a/native/markdown/markdown-context.js
+++ b/native/markdown/markdown-context.js
@@ -2,7 +2,7 @@
import * as React from 'react';
-import type { SetState } from 'lib/types/hook-types';
+import type { SetState } from 'lib/types/hook-types.js';
export type MarkdownContextType = {
+setLinkModalActive: SetState<{ [key: string]: boolean }>,
diff --git a/native/markdown/markdown-link.react.js b/native/markdown/markdown-link.react.js
--- a/native/markdown/markdown-link.react.js
+++ b/native/markdown/markdown-link.react.js
@@ -4,12 +4,15 @@
import * as React from 'react';
import { Text, Linking, Alert } from 'react-native';
-import { normalizeURL } from 'lib/utils/url-utils';
+import { normalizeURL } from 'lib/utils/url-utils.js';
-import { MessagePressResponderContext } from '../chat/message-press-responder-context';
-import { TextMessageMarkdownContext } from '../chat/text-message-markdown-context';
-import { MarkdownContext, type MarkdownContextType } from './markdown-context';
-import { MarkdownSpoilerContext } from './markdown-spoiler-context';
+import { MessagePressResponderContext } from '../chat/message-press-responder-context.js';
+import { TextMessageMarkdownContext } from '../chat/text-message-markdown-context.js';
+import {
+ MarkdownContext,
+ type MarkdownContextType,
+} from './markdown-context.js';
+import { MarkdownSpoilerContext } from './markdown-spoiler-context.js';
function useDisplayLinkPrompt(
inputURL: string,
diff --git a/native/markdown/markdown-paragraph.react.js b/native/markdown/markdown-paragraph.react.js
--- a/native/markdown/markdown-paragraph.react.js
+++ b/native/markdown/markdown-paragraph.react.js
@@ -3,9 +3,9 @@
import * as React from 'react';
import { Text } from 'react-native';
-import { MessagePressResponderContext } from '../chat/message-press-responder-context';
-import { TextMessageMarkdownContext } from '../chat/text-message-markdown-context';
-import type { TextStyle } from '../types/styles';
+import { MessagePressResponderContext } from '../chat/message-press-responder-context.js';
+import { TextMessageMarkdownContext } from '../chat/text-message-markdown-context.js';
+import type { TextStyle } from '../types/styles.js';
type Props = {
+style?: ?TextStyle,
diff --git a/native/markdown/markdown-spoiler.react.js b/native/markdown/markdown-spoiler.react.js
--- a/native/markdown/markdown-spoiler.react.js
+++ b/native/markdown/markdown-spoiler.react.js
@@ -4,12 +4,12 @@
import * as React from 'react';
import { Text } from 'react-native';
-import type { ReactElement } from 'lib/shared/markdown';
+import type { ReactElement } from 'lib/shared/markdown.js';
-import { TextMessageMarkdownContext } from '../chat/text-message-markdown-context';
-import { useStyles } from '../themes/colors';
-import { MarkdownContext } from './markdown-context';
-import { MarkdownSpoilerContext } from './markdown-spoiler-context';
+import { TextMessageMarkdownContext } from '../chat/text-message-markdown-context.js';
+import { useStyles } from '../themes/colors.js';
+import { MarkdownContext } from './markdown-context.js';
+import { MarkdownSpoilerContext } from './markdown-spoiler-context.js';
type MarkdownSpoilerProps = {
+spoilerIdentifier: string | number | void,
diff --git a/native/markdown/markdown.react.js b/native/markdown/markdown.react.js
--- a/native/markdown/markdown.react.js
+++ b/native/markdown/markdown.react.js
@@ -3,14 +3,14 @@
import invariant from 'invariant';
import * as React from 'react';
import { View, Text, StyleSheet } from 'react-native';
-import type { TextStyle as FlattenedTextStyle } from 'react-native/Libraries/StyleSheet/StyleSheet';
+import type { TextStyle as FlattenedTextStyle } from 'react-native/Libraries/StyleSheet/StyleSheet.js';
import * as SimpleMarkdown from 'simple-markdown';
-import { onlyEmojiRegex } from 'lib/shared/emojis';
+import { onlyEmojiRegex } from 'lib/shared/emojis.js';
-import { TextMessageMarkdownContext } from '../chat/text-message-markdown-context';
-import type { TextStyle } from '../types/styles';
-import type { MarkdownRules } from './rules.react';
+import { TextMessageMarkdownContext } from '../chat/text-message-markdown-context.js';
+import type { TextStyle } from '../types/styles.js';
+import type { MarkdownRules } from './rules.react.js';
type Props = {
+style: TextStyle,
diff --git a/native/markdown/rules.react.js b/native/markdown/rules.react.js
--- a/native/markdown/rules.react.js
+++ b/native/markdown/rules.react.js
@@ -1,20 +1,20 @@
// @flow
-import _memoize from 'lodash/memoize';
+import _memoize from 'lodash/memoize.js';
import * as React from 'react';
import { Text, View } from 'react-native';
import { createSelector } from 'reselect';
import * as SimpleMarkdown from 'simple-markdown';
-import { relativeMemberInfoSelectorForMembersOfThread } from 'lib/selectors/user-selectors';
-import * as SharedMarkdown from 'lib/shared/markdown';
-import type { RelativeMemberInfo } from 'lib/types/thread-types';
+import { relativeMemberInfoSelectorForMembersOfThread } from 'lib/selectors/user-selectors.js';
+import * as SharedMarkdown from 'lib/shared/markdown.js';
+import type { RelativeMemberInfo } from 'lib/types/thread-types.js';
-import { useSelector } from '../redux/redux-utils';
-import MarkdownLink from './markdown-link.react';
-import MarkdownParagraph from './markdown-paragraph.react';
-import MarkdownSpoiler from './markdown-spoiler.react';
-import { getMarkdownStyles } from './styles';
+import { useSelector } from '../redux/redux-utils.js';
+import MarkdownLink from './markdown-link.react.js';
+import MarkdownParagraph from './markdown-paragraph.react.js';
+import MarkdownSpoiler from './markdown-spoiler.react.js';
+import { getMarkdownStyles } from './styles.js';
export type MarkdownRules = {
+simpleMarkdownRules: SharedMarkdown.ParserRules,
diff --git a/native/markdown/styles.js b/native/markdown/styles.js
--- a/native/markdown/styles.js
+++ b/native/markdown/styles.js
@@ -1,10 +1,10 @@
// @flow
-import _memoize from 'lodash/memoize';
+import _memoize from 'lodash/memoize.js';
import { Platform } from 'react-native';
-import { getStylesForTheme } from '../themes/colors';
-import type { GlobalTheme } from '../types/themes';
+import { getStylesForTheme } from '../themes/colors.js';
+import type { GlobalTheme } from '../types/themes.js';
const unboundStyles = {
link: {
diff --git a/native/media/blob-utils.js b/native/media/blob-utils.js
--- a/native/media/blob-utils.js
+++ b/native/media/blob-utils.js
@@ -6,14 +6,14 @@
import {
fileInfoFromData,
bytesNeededForFileTypeCheck,
-} from 'lib/media/file-utils';
+} from 'lib/media/file-utils.js';
import type {
MediaMissionStep,
MediaMissionFailure,
-} from 'lib/types/media-types';
-import { getMessageForException } from 'lib/utils/errors';
+} from 'lib/types/media-types.js';
+import { getMessageForException } from 'lib/utils/errors.js';
-import { getFetchableURI } from './identifier-utils';
+import { getFetchableURI } from './identifier-utils.js';
function blobToDataURI(blob: Blob): Promise<string> {
const fileReader = new FileReader();
diff --git a/native/media/camera-modal.react.js b/native/media/camera-modal.react.js
--- a/native/media/camera-modal.react.js
+++ b/native/media/camera-modal.react.js
@@ -1,6 +1,6 @@
// @flow
-import Icon from '@expo/vector-icons/Ionicons';
+import Icon from '@expo/vector-icons/Ionicons.js';
import invariant from 'invariant';
import * as React from 'react';
import {
@@ -27,34 +27,34 @@
} from 'react-native-reanimated';
import { useDispatch } from 'react-redux';
-import { pathFromURI, filenameFromPathOrURI } from 'lib/media/file-utils';
-import { useIsAppForegrounded } from 'lib/shared/lifecycle-utils';
-import type { PhotoCapture } from 'lib/types/media-types';
-import type { Dispatch } from 'lib/types/redux-types';
-import type { ThreadInfo } from 'lib/types/thread-types';
+import { pathFromURI, filenameFromPathOrURI } from 'lib/media/file-utils.js';
+import { useIsAppForegrounded } from 'lib/shared/lifecycle-utils.js';
+import type { PhotoCapture } from 'lib/types/media-types.js';
+import type { Dispatch } from 'lib/types/redux-types.js';
+import type { ThreadInfo } from 'lib/types/thread-types.js';
-import ContentLoading from '../components/content-loading.react';
-import ConnectedStatusBar from '../connected-status-bar.react';
-import { type InputState, InputStateContext } from '../input/input-state';
-import type { AppNavigationProp } from '../navigation/app-navigator.react';
+import ContentLoading from '../components/content-loading.react.js';
+import ConnectedStatusBar from '../connected-status-bar.react.js';
+import { type InputState, InputStateContext } from '../input/input-state.js';
+import type { AppNavigationProp } from '../navigation/app-navigator.react.js';
import {
OverlayContext,
type OverlayContextType,
-} from '../navigation/overlay-context';
-import type { NavigationRoute } from '../navigation/route-names';
-import { updateDeviceCameraInfoActionType } from '../redux/action-types';
-import { type DimensionsInfo } from '../redux/dimensions-updater.react';
-import { useSelector } from '../redux/redux-utils';
-import { colors } from '../themes/colors';
-import { type DeviceCameraInfo } from '../types/camera';
-import type { NativeMethods } from '../types/react-native';
+} from '../navigation/overlay-context.js';
+import type { NavigationRoute } from '../navigation/route-names.js';
+import { updateDeviceCameraInfoActionType } from '../redux/action-types.js';
+import { type DimensionsInfo } from '../redux/dimensions-updater.react.js';
+import { useSelector } from '../redux/redux-utils.js';
+import { colors } from '../themes/colors.js';
+import { type DeviceCameraInfo } from '../types/camera.js';
+import type { NativeMethods } from '../types/react-native.js';
import {
AnimatedView,
type ViewStyle,
type AnimatedViewStyle,
-} from '../types/styles';
-import { clamp, gestureJustEnded } from '../utils/animation-utils';
-import SendMediaButton from './send-media-button.react';
+} from '../types/styles.js';
+import { clamp, gestureJustEnded } from '../utils/animation-utils.js';
+import SendMediaButton from './send-media-button.react.js';
/* eslint-disable import/no-named-as-default-member */
const {
diff --git a/native/media/ffmpeg.js b/native/media/ffmpeg.js
--- a/native/media/ffmpeg.js
+++ b/native/media/ffmpeg.js
@@ -2,12 +2,12 @@
import { RNFFmpeg, RNFFprobe, RNFFmpegConfig } from 'react-native-ffmpeg';
-import { getHasMultipleFramesProbeCommand } from 'lib/media/video-utils';
+import { getHasMultipleFramesProbeCommand } from 'lib/media/video-utils.js';
import type {
Dimensions,
FFmpegStatistics,
VideoInfo,
-} from 'lib/types/media-types';
+} from 'lib/types/media-types.js';
const maxSimultaneousCalls = {
process: 1,
diff --git a/native/media/file-utils.js b/native/media/file-utils.js
--- a/native/media/file-utils.js
+++ b/native/media/file-utils.js
@@ -11,8 +11,8 @@
pathFromURI,
fileInfoFromData,
bytesNeededForFileTypeCheck,
-} from 'lib/media/file-utils';
-import type { Shape } from 'lib/types/core';
+} from 'lib/media/file-utils.js';
+import type { Shape } from 'lib/types/core.js';
import type {
MediaMissionStep,
MediaMissionFailure,
@@ -23,11 +23,11 @@
AndroidScanFileMediaMissionStep,
FetchFileHashMediaMissionStep,
CopyFileMediaMissionStep,
-} from 'lib/types/media-types';
-import { getMessageForException } from 'lib/utils/errors';
+} from 'lib/types/media-types.js';
+import { getMessageForException } from 'lib/utils/errors.js';
-import { stringToIntArray } from './blob-utils';
-import { ffmpeg } from './ffmpeg';
+import { stringToIntArray } from './blob-utils.js';
+import { ffmpeg } from './ffmpeg.js';
const defaultInputs = Object.freeze({});
const defaultFields = Object.freeze({});
diff --git a/native/media/image-modal.react.js b/native/media/image-modal.react.js
--- a/native/media/image-modal.react.js
+++ b/native/media/image-modal.react.js
@@ -19,39 +19,39 @@
import Orientation from 'react-native-orientation-locker';
import Animated from 'react-native-reanimated';
-import { type MediaInfo, type Dimensions } from 'lib/types/media-types';
+import { type MediaInfo, type Dimensions } from 'lib/types/media-types.js';
-import SWMansionIcon from '../components/swmansion-icon.react';
-import ConnectedStatusBar from '../connected-status-bar.react';
-import { displayActionResultModal } from '../navigation/action-result-modal';
-import type { AppNavigationProp } from '../navigation/app-navigator.react';
+import SWMansionIcon from '../components/swmansion-icon.react.js';
+import ConnectedStatusBar from '../connected-status-bar.react.js';
+import { displayActionResultModal } from '../navigation/action-result-modal.js';
+import type { AppNavigationProp } from '../navigation/app-navigator.react.js';
import {
OverlayContext,
type OverlayContextType,
-} from '../navigation/overlay-context';
-import type { NavigationRoute } from '../navigation/route-names';
-import { useSelector } from '../redux/redux-utils';
+} from '../navigation/overlay-context.js';
+import type { NavigationRoute } from '../navigation/route-names.js';
+import { useSelector } from '../redux/redux-utils.js';
import {
type DerivedDimensionsInfo,
derivedDimensionsInfoSelector,
-} from '../selectors/dimensions-selectors';
-import type { ChatMultimediaMessageInfoItem } from '../types/chat-types';
+} from '../selectors/dimensions-selectors.js';
+import type { ChatMultimediaMessageInfoItem } from '../types/chat-types.js';
import {
type VerticalBounds,
type LayoutCoordinates,
-} from '../types/layout-types';
-import type { NativeMethods } from '../types/react-native';
+} from '../types/layout-types.js';
+import type { NativeMethods } from '../types/react-native.js';
import {
clamp,
gestureJustStarted,
gestureJustEnded,
runTiming,
-} from '../utils/animation-utils';
-import Multimedia from './multimedia.react';
+} from '../utils/animation-utils.js';
+import Multimedia from './multimedia.react.js';
import {
useIntentionalSaveMedia,
type IntentionalSaveMedia,
-} from './save-media';
+} from './save-media.js';
/* eslint-disable import/no-named-as-default-member */
const {
diff --git a/native/media/image-utils.js b/native/media/image-utils.js
--- a/native/media/image-utils.js
+++ b/native/media/image-utils.js
@@ -2,13 +2,13 @@
import * as ImageManipulator from 'expo-image-manipulator';
-import { getImageProcessingPlan } from 'lib/media/image-utils';
+import { getImageProcessingPlan } from 'lib/media/image-utils.js';
import type {
Dimensions,
MediaMissionStep,
MediaMissionFailure,
-} from 'lib/types/media-types';
-import { getMessageForException } from 'lib/utils/errors';
+} from 'lib/types/media-types.js';
+import { getMessageForException } from 'lib/utils/errors.js';
type ProcessImageInfo = {
uri: string,
diff --git a/native/media/media-gallery-keyboard.react.js b/native/media/media-gallery-keyboard.react.js
--- a/native/media/media-gallery-keyboard.react.js
+++ b/native/media/media-gallery-keyboard.react.js
@@ -19,21 +19,24 @@
import {
extensionFromFilename,
filenameFromPathOrURI,
-} from 'lib/media/file-utils';
-import { useIsAppForegrounded } from 'lib/shared/lifecycle-utils';
-import type { MediaLibrarySelection } from 'lib/types/media-types';
-import type { ThreadInfo } from 'lib/types/thread-types';
-
-import Button from '../components/button.react';
-import type { DimensionsInfo } from '../redux/dimensions-updater.react';
-import { store } from '../redux/redux-setup';
-import { useSelector } from '../redux/redux-utils';
-import { type Colors, useColors, useStyles } from '../themes/colors';
-import type { LayoutEvent, ViewableItemsChange } from '../types/react-native';
-import type { ViewStyle } from '../types/styles';
-import { getCompatibleMediaURI } from './identifier-utils';
-import MediaGalleryMedia from './media-gallery-media.react';
-import SendMediaButton from './send-media-button.react';
+} from 'lib/media/file-utils.js';
+import { useIsAppForegrounded } from 'lib/shared/lifecycle-utils.js';
+import type { MediaLibrarySelection } from 'lib/types/media-types.js';
+import type { ThreadInfo } from 'lib/types/thread-types.js';
+
+import Button from '../components/button.react.js';
+import type { DimensionsInfo } from '../redux/dimensions-updater.react.js';
+import { store } from '../redux/redux-setup.js';
+import { useSelector } from '../redux/redux-utils.js';
+import { type Colors, useColors, useStyles } from '../themes/colors.js';
+import type {
+ LayoutEvent,
+ ViewableItemsChange,
+} from '../types/react-native.js';
+import type { ViewStyle } from '../types/styles.js';
+import { getCompatibleMediaURI } from './identifier-utils.js';
+import MediaGalleryMedia from './media-gallery-media.react.js';
+import SendMediaButton from './send-media-button.react.js';
const animationSpec = {
duration: 400,
diff --git a/native/media/media-gallery-media.react.js b/native/media/media-gallery-media.react.js
--- a/native/media/media-gallery-media.react.js
+++ b/native/media/media-gallery-media.react.js
@@ -1,7 +1,7 @@
// @flow
-import Icon from '@expo/vector-icons/FontAwesome';
-import MaterialIcon from '@expo/vector-icons/MaterialIcons';
+import Icon from '@expo/vector-icons/FontAwesome.js';
+import MaterialIcon from '@expo/vector-icons/MaterialIcons.js';
import LottieView from 'lottie-react-native';
import * as React from 'react';
import {
@@ -18,17 +18,17 @@
} from 'react-native-reanimated';
import Video from 'react-native-video';
-import { type MediaLibrarySelection } from 'lib/types/media-types';
+import { type MediaLibrarySelection } from 'lib/types/media-types.js';
-import GestureTouchableOpacity from '../components/gesture-touchable-opacity.react';
-import { type DimensionsInfo } from '../redux/dimensions-updater.react';
-import type { AnimatedValue } from '../types/react-native';
+import GestureTouchableOpacity from '../components/gesture-touchable-opacity.react.js';
+import { type DimensionsInfo } from '../redux/dimensions-updater.react.js';
+import type { AnimatedValue } from '../types/react-native.js';
import {
AnimatedView,
AnimatedImage,
type AnimatedViewStyle,
type AnimatedStyleObj,
-} from '../types/styles';
+} from '../types/styles.js';
const animatedSpec = {
duration: 400,
diff --git a/native/media/media-utils.js b/native/media/media-utils.js
--- a/native/media/media-utils.js
+++ b/native/media/media-utils.js
@@ -3,18 +3,18 @@
import invariant from 'invariant';
import { Image } from 'react-native';
-import { pathFromURI, sanitizeFilename } from 'lib/media/file-utils';
+import { pathFromURI, sanitizeFilename } from 'lib/media/file-utils.js';
import type {
Dimensions,
MediaMissionStep,
MediaMissionFailure,
NativeMediaSelection,
-} from 'lib/types/media-types';
+} from 'lib/types/media-types.js';
-import { fetchFileInfo } from './file-utils';
-import { processImage } from './image-utils';
-import { saveMedia } from './save-media';
-import { processVideo } from './video-utils';
+import { fetchFileInfo } from './file-utils.js';
+import { processImage } from './image-utils.js';
+import { saveMedia } from './save-media.js';
+import { processVideo } from './video-utils.js';
type MediaProcessConfig = {
+hasWiFi: boolean,
diff --git a/native/media/multimedia.react.js b/native/media/multimedia.react.js
--- a/native/media/multimedia.react.js
+++ b/native/media/multimedia.react.js
@@ -4,10 +4,10 @@
import * as React from 'react';
import { View, Image, StyleSheet } from 'react-native';
-import { type MediaInfo } from 'lib/types/media-types';
+import { type MediaInfo } from 'lib/types/media-types.js';
-import { type InputState, InputStateContext } from '../input/input-state';
-import RemoteImage from './remote-image.react';
+import { type InputState, InputStateContext } from '../input/input-state.js';
+import RemoteImage from './remote-image.react.js';
type BaseProps = {
+mediaInfo: MediaInfo,
diff --git a/native/media/remote-image.react.js b/native/media/remote-image.react.js
--- a/native/media/remote-image.react.js
+++ b/native/media/remote-image.react.js
@@ -4,10 +4,10 @@
import { View, StyleSheet, ActivityIndicator } from 'react-native';
import FastImage from 'react-native-fast-image';
-import { type ConnectionStatus } from 'lib/types/socket-types';
+import { type ConnectionStatus } from 'lib/types/socket-types.js';
-import { useSelector } from '../redux/redux-utils';
-import type { ImageStyle } from '../types/styles';
+import { useSelector } from '../redux/redux-utils.js';
+import type { ImageStyle } from '../types/styles.js';
type BaseProps = {
+uri: string,
diff --git a/native/media/save-media.js b/native/media/save-media.js
--- a/native/media/save-media.js
+++ b/native/media/save-media.js
@@ -7,26 +7,26 @@
import filesystem from 'react-native-fs';
import { useDispatch } from 'react-redux';
-import { queueReportsActionType } from 'lib/actions/report-actions';
-import { readableFilename, pathFromURI } from 'lib/media/file-utils';
-import { isLocalUploadID } from 'lib/media/media-utils';
+import { queueReportsActionType } from 'lib/actions/report-actions.js';
+import { readableFilename, pathFromURI } from 'lib/media/file-utils.js';
+import { isLocalUploadID } from 'lib/media/media-utils.js';
import type {
MediaMissionStep,
MediaMissionResult,
MediaMissionFailure,
-} from 'lib/types/media-types';
+} from 'lib/types/media-types.js';
import {
reportTypes,
type MediaMissionReportCreationRequest,
-} from 'lib/types/report-types';
-import { getConfig } from 'lib/utils/config';
-import { getMessageForException } from 'lib/utils/errors';
-import { promiseAll } from 'lib/utils/promises';
-import { useIsReportEnabled } from 'lib/utils/report-utils';
-
-import { displayActionResultModal } from '../navigation/action-result-modal';
-import { requestAndroidPermission } from '../utils/android-permissions';
-import { fetchBlob } from './blob-utils';
+} from 'lib/types/report-types.js';
+import { getConfig } from 'lib/utils/config.js';
+import { getMessageForException } from 'lib/utils/errors.js';
+import { promiseAll } from 'lib/utils/promises.js';
+import { useIsReportEnabled } from 'lib/utils/report-utils.js';
+
+import { displayActionResultModal } from '../navigation/action-result-modal.js';
+import { requestAndroidPermission } from '../utils/android-permissions.js';
+import { fetchBlob } from './blob-utils.js';
import {
fetchAssetInfo,
fetchFileInfo,
@@ -36,8 +36,8 @@
fetchFileHash,
copyFile,
temporaryDirectoryPath,
-} from './file-utils';
-import { getMediaLibraryIdentifier } from './identifier-utils';
+} from './file-utils.js';
+import { getMediaLibraryIdentifier } from './identifier-utils.js';
export type IntentionalSaveMedia = (
uri: string,
diff --git a/native/media/send-media-button.react.js b/native/media/send-media-button.react.js
--- a/native/media/send-media-button.react.js
+++ b/native/media/send-media-button.react.js
@@ -1,6 +1,6 @@
// @flow
-import Icon from '@expo/vector-icons/FontAwesome';
+import Icon from '@expo/vector-icons/FontAwesome.js';
import * as React from 'react';
import {
TouchableOpacity,
@@ -11,7 +11,7 @@
Animated,
} from 'react-native';
-import type { ViewStyle } from '../types/styles';
+import type { ViewStyle } from '../types/styles.js';
type Props = {
...React.ElementConfig<typeof View>,
diff --git a/native/media/video-playback-modal.react.js b/native/media/video-playback-modal.react.js
--- a/native/media/video-playback-modal.react.js
+++ b/native/media/video-playback-modal.react.js
@@ -1,6 +1,6 @@
// @flow
-import Icon from '@expo/vector-icons/MaterialCommunityIcons';
+import Icon from '@expo/vector-icons/MaterialCommunityIcons.js';
import invariant from 'invariant';
import * as React from 'react';
import { useState } from 'react';
@@ -10,21 +10,24 @@
import Animated from 'react-native-reanimated';
import Video from 'react-native-video';
-import { useIsAppBackgroundedOrInactive } from 'lib/shared/lifecycle-utils';
-import type { MediaInfo } from 'lib/types/media-types';
-
-import ConnectedStatusBar from '../connected-status-bar.react';
-import type { AppNavigationProp } from '../navigation/app-navigator.react';
-import { OverlayContext } from '../navigation/overlay-context';
-import type { NavigationRoute } from '../navigation/route-names';
-import { useSelector } from '../redux/redux-utils';
-import { derivedDimensionsInfoSelector } from '../selectors/dimensions-selectors';
-import { useStyles } from '../themes/colors';
-import type { ChatMultimediaMessageInfoItem } from '../types/chat-types';
-import type { VerticalBounds, LayoutCoordinates } from '../types/layout-types';
-import type { NativeMethods } from '../types/react-native';
-import { gestureJustEnded, animateTowards } from '../utils/animation-utils';
-import { formatDuration } from './video-utils';
+import { useIsAppBackgroundedOrInactive } from 'lib/shared/lifecycle-utils.js';
+import type { MediaInfo } from 'lib/types/media-types.js';
+
+import ConnectedStatusBar from '../connected-status-bar.react.js';
+import type { AppNavigationProp } from '../navigation/app-navigator.react.js';
+import { OverlayContext } from '../navigation/overlay-context.js';
+import type { NavigationRoute } from '../navigation/route-names.js';
+import { useSelector } from '../redux/redux-utils.js';
+import { derivedDimensionsInfoSelector } from '../selectors/dimensions-selectors.js';
+import { useStyles } from '../themes/colors.js';
+import type { ChatMultimediaMessageInfoItem } from '../types/chat-types.js';
+import type {
+ VerticalBounds,
+ LayoutCoordinates,
+} from '../types/layout-types.js';
+import type { NativeMethods } from '../types/react-native.js';
+import { gestureJustEnded, animateTowards } from '../utils/animation-utils.js';
+import { formatDuration } from './video-utils.js';
type TouchableOpacityInstance = React.AbstractComponent<
React.ElementConfig<typeof TouchableOpacity>,
diff --git a/native/media/video-utils.js b/native/media/video-utils.js
--- a/native/media/video-utils.js
+++ b/native/media/video-utils.js
@@ -4,9 +4,9 @@
import { Platform } from 'react-native';
import filesystem from 'react-native-fs';
-import { mediaConfig, pathFromURI } from 'lib/media/file-utils';
-import { getVideoProcessingPlan } from 'lib/media/video-utils';
-import type { ProcessPlan } from 'lib/media/video-utils';
+import { mediaConfig, pathFromURI } from 'lib/media/file-utils.js';
+import { getVideoProcessingPlan } from 'lib/media/video-utils.js';
+import type { ProcessPlan } from 'lib/media/video-utils.js';
import type {
MediaMissionStep,
MediaMissionFailure,
@@ -14,11 +14,11 @@
TranscodeVideoMediaMissionStep,
VideoGenerateThumbnailMediaMissionStep,
Dimensions,
-} from 'lib/types/media-types';
-import { getMessageForException } from 'lib/utils/errors';
+} from 'lib/types/media-types.js';
+import { getMessageForException } from 'lib/utils/errors.js';
-import { ffmpeg } from './ffmpeg';
-import { temporaryDirectoryPath } from './file-utils';
+import { ffmpeg } from './ffmpeg.js';
+import { temporaryDirectoryPath } from './file-utils.js';
// These are some numbers I sorta kinda made up
// We should try to calculate them on a per-device basis
diff --git a/native/native-modules.js b/native/native-modules.js
--- a/native/native-modules.js
+++ b/native/native-modules.js
@@ -1,5 +1,5 @@
// @flow
-import type { Spec } from './schema/CommCoreModuleSchema';
+import type { Spec } from './schema/CommCoreModuleSchema.js';
export const commCoreModule: Spec = global.CommCoreModule;
diff --git a/native/navigation/action-result-modal.js b/native/navigation/action-result-modal.js
--- a/native/navigation/action-result-modal.js
+++ b/native/navigation/action-result-modal.js
@@ -3,8 +3,8 @@
import { CommonActions } from '@react-navigation/native';
import invariant from 'invariant';
-import { getGlobalNavContext } from './icky-global';
-import { ActionResultModalRouteName } from './route-names';
+import { getGlobalNavContext } from './icky-global.js';
+import { ActionResultModalRouteName } from './route-names.js';
function displayActionResultModal(message: string) {
const navContext = getGlobalNavContext();
diff --git a/native/navigation/action-result-modal.react.js b/native/navigation/action-result-modal.react.js
--- a/native/navigation/action-result-modal.react.js
+++ b/native/navigation/action-result-modal.react.js
@@ -5,11 +5,11 @@
import { View, Text } from 'react-native';
import Animated from 'react-native-reanimated';
-import { useSelector } from '../redux/redux-utils';
-import { useOverlayStyles } from '../themes/colors';
-import type { AppNavigationProp } from './app-navigator.react';
-import { OverlayContext } from './overlay-context';
-import type { NavigationRoute } from './route-names';
+import { useSelector } from '../redux/redux-utils.js';
+import { useOverlayStyles } from '../themes/colors.js';
+import type { AppNavigationProp } from './app-navigator.react.js';
+import { OverlayContext } from './overlay-context.js';
+import type { NavigationRoute } from './route-names.js';
export type ActionResultModalParams = {
+message: string,
diff --git a/native/navigation/app-navigator.react.js b/native/navigation/app-navigator.react.js
--- a/native/navigation/app-navigator.react.js
+++ b/native/navigation/app-navigator.react.js
@@ -5,28 +5,28 @@
import { useSelector } from 'react-redux';
import { PersistGate } from 'redux-persist/integration/react';
-import MultimediaMessageTooltipModal from '../chat/multimedia-message-tooltip-modal.react';
-import RobotextMessageTooltipModal from '../chat/robotext-message-tooltip-modal.react';
-import ThreadSettingsMemberTooltipModal from '../chat/settings/thread-settings-member-tooltip-modal.react';
-import TextMessageTooltipModal from '../chat/text-message-tooltip-modal.react';
-import KeyboardStateContainer from '../keyboard/keyboard-state-container.react';
-import CameraModal from '../media/camera-modal.react';
-import ImageModal from '../media/image-modal.react';
-import VideoPlaybackModal from '../media/video-playback-modal.react';
-import RelationshipListItemTooltipModal from '../profile/relationship-list-item-tooltip-modal.react';
-import PushHandler from '../push/push-handler.react';
-import { getPersistor } from '../redux/persist';
-import { RootContext } from '../root-context';
-import { useLoadCommFonts } from '../themes/fonts';
-import { waitForInteractions } from '../utils/timers';
-import ActionResultModal from './action-result-modal.react';
-import { CommunityDrawerNavigator } from './community-drawer-navigator.react';
-import { createOverlayNavigator } from './overlay-navigator.react';
+import MultimediaMessageTooltipModal from '../chat/multimedia-message-tooltip-modal.react.js';
+import RobotextMessageTooltipModal from '../chat/robotext-message-tooltip-modal.react.js';
+import ThreadSettingsMemberTooltipModal from '../chat/settings/thread-settings-member-tooltip-modal.react.js';
+import TextMessageTooltipModal from '../chat/text-message-tooltip-modal.react.js';
+import KeyboardStateContainer from '../keyboard/keyboard-state-container.react.js';
+import CameraModal from '../media/camera-modal.react.js';
+import ImageModal from '../media/image-modal.react.js';
+import VideoPlaybackModal from '../media/video-playback-modal.react.js';
+import RelationshipListItemTooltipModal from '../profile/relationship-list-item-tooltip-modal.react.js';
+import PushHandler from '../push/push-handler.react.js';
+import { getPersistor } from '../redux/persist.js';
+import { RootContext } from '../root-context.js';
+import { useLoadCommFonts } from '../themes/fonts.js';
+import { waitForInteractions } from '../utils/timers.js';
+import ActionResultModal from './action-result-modal.react.js';
+import { CommunityDrawerNavigator } from './community-drawer-navigator.react.js';
+import { createOverlayNavigator } from './overlay-navigator.react.js';
import type {
OverlayNavigationProp,
OverlayNavigationHelpers,
-} from './overlay-navigator.react';
-import type { RootNavigationProp } from './root-navigator.react';
+} from './overlay-navigator.react.js';
+import type { RootNavigationProp } from './root-navigator.react.js';
import {
ImageModalRouteName,
MultimediaMessageTooltipModalRouteName,
@@ -40,7 +40,7 @@
CommunityDrawerNavigatorRouteName,
type ScreenParamList,
type OverlayParamList,
-} from './route-names';
+} from './route-names.js';
let splashScreenHasHidden = false;
diff --git a/native/navigation/community-drawer-button.react.js b/native/navigation/community-drawer-button.react.js
--- a/native/navigation/community-drawer-button.react.js
+++ b/native/navigation/community-drawer-button.react.js
@@ -1,11 +1,11 @@
// @flow
-import Icon from '@expo/vector-icons/Feather';
+import Icon from '@expo/vector-icons/Feather.js';
import * as React from 'react';
import { TouchableOpacity } from 'react-native';
-import { useStyles } from '../themes/colors';
-import type { CommunityDrawerNavigationProp } from './community-drawer-navigator.react';
+import { useStyles } from '../themes/colors.js';
+import type { CommunityDrawerNavigationProp } from './community-drawer-navigator.react.js';
type Props = {
+navigation: CommunityDrawerNavigationProp<'TabNavigator'>,
diff --git a/native/navigation/community-drawer-content.react.js b/native/navigation/community-drawer-content.react.js
--- a/native/navigation/community-drawer-content.react.js
+++ b/native/navigation/community-drawer-content.react.js
@@ -8,19 +8,19 @@
import {
childThreadInfos,
communityThreadSelector,
-} from 'lib/selectors/thread-selectors';
-import { threadIsChannel } from 'lib/shared/thread-utils';
+} from 'lib/selectors/thread-selectors.js';
+import { threadIsChannel } from 'lib/shared/thread-utils.js';
import {
type ThreadInfo,
type ResolvedThreadInfo,
communitySubthreads,
-} from 'lib/types/thread-types';
-import { useResolvedThreadInfos } from 'lib/utils/entity-helpers';
+} from 'lib/types/thread-types.js';
+import { useResolvedThreadInfos } from 'lib/utils/entity-helpers.js';
-import { useNavigateToThread } from '../chat/message-list-types';
-import { useStyles } from '../themes/colors';
-import type { TextStyle } from '../types/styles';
-import CommunityDrawerItemCommunity from './community-drawer-item-community.react';
+import { useNavigateToThread } from '../chat/message-list-types.js';
+import { useStyles } from '../themes/colors.js';
+import type { TextStyle } from '../types/styles.js';
+import CommunityDrawerItemCommunity from './community-drawer-item-community.react.js';
const maxDepth = 2;
const safeAreaEdges = Platform.select({
diff --git a/native/navigation/community-drawer-item-community.react.js b/native/navigation/community-drawer-item-community.react.js
--- a/native/navigation/community-drawer-item-community.react.js
+++ b/native/navigation/community-drawer-item-community.react.js
@@ -3,9 +3,9 @@
import * as React from 'react';
import { View } from 'react-native';
-import { useStyles } from '../themes/colors';
-import CommunityDrawerItem from './community-drawer-item.react';
-import type { DrawerItemProps } from './community-drawer-item.react';
+import { useStyles } from '../themes/colors.js';
+import CommunityDrawerItem from './community-drawer-item.react.js';
+import type { DrawerItemProps } from './community-drawer-item.react.js';
function CommunityDrawerItemCommunity(props: DrawerItemProps): React.Node {
const styles = useStyles(unboundStyles);
diff --git a/native/navigation/community-drawer-item.react.js b/native/navigation/community-drawer-item.react.js
--- a/native/navigation/community-drawer-item.react.js
+++ b/native/navigation/community-drawer-item.react.js
@@ -3,15 +3,15 @@
import * as React from 'react';
import { View, FlatList, TouchableOpacity } from 'react-native';
-import type { ThreadInfo } from 'lib/types/thread-types';
-import { useResolvedThreadInfo } from 'lib/utils/entity-helpers';
-
-import type { MessageListParams } from '../chat/message-list-types';
-import { SingleLine } from '../components/single-line.react';
-import { useStyles } from '../themes/colors';
-import type { TextStyle } from '../types/styles';
-import { ExpandButton, ExpandButtonDisabled } from './expand-buttons.react';
-import SubchannelsButton from './subchannels-button.react';
+import type { ThreadInfo } from 'lib/types/thread-types.js';
+import { useResolvedThreadInfo } from 'lib/utils/entity-helpers.js';
+
+import type { MessageListParams } from '../chat/message-list-types.js';
+import { SingleLine } from '../components/single-line.react.js';
+import { useStyles } from '../themes/colors.js';
+import type { TextStyle } from '../types/styles.js';
+import { ExpandButton, ExpandButtonDisabled } from './expand-buttons.react.js';
+import SubchannelsButton from './subchannels-button.react.js';
export type CommunityDrawerItemData = {
+threadInfo: ThreadInfo,
diff --git a/native/navigation/community-drawer-navigator.react.js b/native/navigation/community-drawer-navigator.react.js
--- a/native/navigation/community-drawer-navigator.react.js
+++ b/native/navigation/community-drawer-navigator.react.js
@@ -8,18 +8,18 @@
import * as React from 'react';
import { View, useWindowDimensions } from 'react-native';
-import { useStyles } from '../themes/colors';
-import type { AppNavigationProp } from './app-navigator.react';
-import CommunityDrawerContent from './community-drawer-content.react';
-import { drawerSwipeEnabledSelector } from './nav-selectors';
-import { NavContext } from './navigation-context';
-import { TabNavigatorRouteName } from './route-names';
+import { useStyles } from '../themes/colors.js';
+import type { AppNavigationProp } from './app-navigator.react.js';
+import CommunityDrawerContent from './community-drawer-content.react.js';
+import { drawerSwipeEnabledSelector } from './nav-selectors.js';
+import { NavContext } from './navigation-context.js';
+import { TabNavigatorRouteName } from './route-names.js';
import type {
NavigationRoute,
ScreenParamList,
CommunityDrawerParamList,
-} from './route-names';
-import TabNavigator from './tab-navigator.react';
+} from './route-names.js';
+import TabNavigator from './tab-navigator.react.js';
const communityDrawerContent = () => <CommunityDrawerContent />;
diff --git a/native/navigation/default-state.js b/native/navigation/default-state.js
--- a/native/navigation/default-state.js
+++ b/native/navigation/default-state.js
@@ -2,8 +2,8 @@
import type { StaleNavigationState } from '@react-navigation/native';
-import type { BaseNavInfo } from 'lib/types/nav-types';
-import { fifteenDaysEarlier, fifteenDaysLater } from 'lib/utils/date-utils';
+import type { BaseNavInfo } from 'lib/types/nav-types.js';
+import { fifteenDaysEarlier, fifteenDaysLater } from 'lib/utils/date-utils.js';
import {
AppRouteName,
@@ -17,7 +17,7 @@
BackgroundChatThreadListRouteName,
AppsRouteName,
CommunityDrawerNavigatorRouteName,
-} from './route-names';
+} from './route-names.js';
export type NavInfo = $Exact<BaseNavInfo>;
diff --git a/native/navigation/disconnected-bar-visibility-handler.react.js b/native/navigation/disconnected-bar-visibility-handler.react.js
--- a/native/navigation/disconnected-bar-visibility-handler.react.js
+++ b/native/navigation/disconnected-bar-visibility-handler.react.js
@@ -1,8 +1,8 @@
// @flow
-import { useDisconnectedBarVisibilityHandler } from 'lib/hooks/disconnected-bar';
+import { useDisconnectedBarVisibilityHandler } from 'lib/hooks/disconnected-bar.js';
-import { useSelector } from '../redux/redux-utils';
+import { useSelector } from '../redux/redux-utils.js';
function DisconnectedBarVisibilityHandler(): null {
const networkConnected = useSelector(state => state.connectivity.connected);
diff --git a/native/navigation/disconnected-bar.react.js b/native/navigation/disconnected-bar.react.js
--- a/native/navigation/disconnected-bar.react.js
+++ b/native/navigation/disconnected-bar.react.js
@@ -6,9 +6,9 @@
import {
useDisconnectedBar,
useShouldShowDisconnectedBar,
-} from 'lib/hooks/disconnected-bar';
+} from 'lib/hooks/disconnected-bar.js';
-import { useStyles } from '../themes/colors';
+import { useStyles } from '../themes/colors.js';
const expandedHeight = Platform.select({
android: 29.5,
diff --git a/native/navigation/expand-buttons.react.js b/native/navigation/expand-buttons.react.js
--- a/native/navigation/expand-buttons.react.js
+++ b/native/navigation/expand-buttons.react.js
@@ -1,10 +1,10 @@
// @flow
-import Icon from '@expo/vector-icons/FontAwesome';
+import Icon from '@expo/vector-icons/FontAwesome.js';
import * as React from 'react';
import { TouchableOpacity, View } from 'react-native';
-import { useStyles } from '../themes/colors';
+import { useStyles } from '../themes/colors.js';
const iconSize = 12;
const buttonSize = 24;
diff --git a/native/navigation/header-back-button.react.js b/native/navigation/header-back-button.react.js
--- a/native/navigation/header-back-button.react.js
+++ b/native/navigation/header-back-button.react.js
@@ -3,7 +3,7 @@
import { HeaderBackButton as BaseHeaderBackButton } from '@react-navigation/elements';
import * as React from 'react';
-import { useColors } from '../themes/colors';
+import { useColors } from '../themes/colors.js';
type Props = React.ElementConfig<typeof BaseHeaderBackButton>;
function HeaderBackButton(props: Props): React.Node {
diff --git a/native/navigation/header.react.js b/native/navigation/header.react.js
--- a/native/navigation/header.react.js
+++ b/native/navigation/header.react.js
@@ -3,7 +3,7 @@
import { Header, type StackHeaderProps } from '@react-navigation/stack';
import * as React from 'react';
-import DisconnectedBar from './disconnected-bar.react';
+import DisconnectedBar from './disconnected-bar.react.js';
type Props = {
...StackHeaderProps,
diff --git a/native/navigation/icky-global.js b/native/navigation/icky-global.js
--- a/native/navigation/icky-global.js
+++ b/native/navigation/icky-global.js
@@ -1,6 +1,6 @@
// @flow
-import type { NavContextType } from './navigation-context';
+import type { NavContextType } from './navigation-context.js';
let globalNavContext: ?NavContextType = null;
diff --git a/native/navigation/modal-pruner.react.js b/native/navigation/modal-pruner.react.js
--- a/native/navigation/modal-pruner.react.js
+++ b/native/navigation/modal-pruner.react.js
@@ -10,9 +10,9 @@
import {
clearRootModalsActionType,
clearOverlayModalsActionType,
-} from './action-types';
-import type { NavContextType } from './navigation-context';
-import { AppRouteName } from './route-names';
+} from './action-types.js';
+import type { NavContextType } from './navigation-context.js';
+import { AppRouteName } from './route-names.js';
type DependencyInfo = {
status: 'missing' | 'resolved' | 'unresolved',
diff --git a/native/navigation/nav-from-redux-handler.react.js b/native/navigation/nav-from-redux-handler.react.js
--- a/native/navigation/nav-from-redux-handler.react.js
+++ b/native/navigation/nav-from-redux-handler.react.js
@@ -3,8 +3,8 @@
import * as React from 'react';
import { useSelector } from 'react-redux';
-import { setNavStateActionType } from './action-types';
-import { NavContext } from './navigation-context';
+import { setNavStateActionType } from './action-types.js';
+import { NavContext } from './navigation-context.js';
const NavFromReduxHandler: React.ComponentType<{}> = React.memo<{}>(
function NavFromReduxHandler() {
diff --git a/native/navigation/nav-selectors.js b/native/navigation/nav-selectors.js
--- a/native/navigation/nav-selectors.js
+++ b/native/navigation/nav-selectors.js
@@ -1,24 +1,24 @@
// @flow
import type { PossiblyStaleNavigationState } from '@react-navigation/native';
-import _memoize from 'lodash/memoize';
+import _memoize from 'lodash/memoize.js';
import * as React from 'react';
import { createSelector } from 'reselect';
-import { nonThreadCalendarFiltersSelector } from 'lib/selectors/calendar-filter-selectors';
-import { currentCalendarQuery } from 'lib/selectors/nav-selectors';
-import type { CalendarQuery } from 'lib/types/entry-types';
-import type { CalendarFilter } from 'lib/types/filter-types';
+import { nonThreadCalendarFiltersSelector } from 'lib/selectors/calendar-filter-selectors.js';
+import { currentCalendarQuery } from 'lib/selectors/nav-selectors.js';
+import type { CalendarQuery } from 'lib/types/entry-types.js';
+import type { CalendarFilter } from 'lib/types/filter-types.js';
-import { useSelector } from '../redux/redux-utils';
-import type { NavPlusRedux } from '../types/selector-types';
-import type { GlobalTheme } from '../types/themes';
-import type { NavContextType } from './navigation-context';
-import { NavContext } from './navigation-context';
+import { useSelector } from '../redux/redux-utils.js';
+import type { NavPlusRedux } from '../types/selector-types.js';
+import type { GlobalTheme } from '../types/themes.js';
+import type { NavContextType } from './navigation-context.js';
+import { NavContext } from './navigation-context.js';
import {
getStateFromNavigatorRoute,
getThreadIDFromRoute,
-} from './navigation-utils';
+} from './navigation-utils.js';
import {
AppRouteName,
TabNavigatorRouteName,
@@ -32,7 +32,7 @@
chatRootModals,
threadRoutes,
CommunityDrawerNavigatorRouteName,
-} from './route-names';
+} from './route-names.js';
const baseCreateIsForegroundSelector = (routeName: string) =>
createSelector(
diff --git a/native/navigation/navigation-context.js b/native/navigation/navigation-context.js
--- a/native/navigation/navigation-context.js
+++ b/native/navigation/navigation-context.js
@@ -6,9 +6,9 @@
} from '@react-navigation/native';
import * as React from 'react';
-import type { ChatRouterNavigationAction } from '../chat/chat-router';
-import type { OverlayRouterNavigationAction } from './overlay-router';
-import type { RootRouterNavigationAction } from './root-router';
+import type { ChatRouterNavigationAction } from '../chat/chat-router.js';
+import type { OverlayRouterNavigationAction } from './overlay-router.js';
+import type { RootRouterNavigationAction } from './root-router.js';
export type NavAction =
| CommonAction
diff --git a/native/navigation/navigation-handler.react.js b/native/navigation/navigation-handler.react.js
--- a/native/navigation/navigation-handler.react.js
+++ b/native/navigation/navigation-handler.react.js
@@ -2,19 +2,19 @@
import * as React from 'react';
-import { isLoggedIn } from 'lib/selectors/user-selectors';
+import { isLoggedIn } from 'lib/selectors/user-selectors.js';
-import DevTools from '../redux/dev-tools.react';
-import { useSelector } from '../redux/redux-utils';
-import type { AppState } from '../redux/state-types';
-import { usePersistedStateLoaded } from '../selectors/app-state-selectors';
-import { logInActionType, logOutActionType } from './action-types';
-import ModalPruner from './modal-pruner.react';
-import NavFromReduxHandler from './nav-from-redux-handler.react';
-import { useIsAppLoggedIn } from './nav-selectors';
-import { NavContext, type NavAction } from './navigation-context';
-import PolicyAcknowledgmentHandler from './policy-acknowledgment-handler.react';
-import ThreadScreenTracker from './thread-screen-tracker.react';
+import DevTools from '../redux/dev-tools.react.js';
+import { useSelector } from '../redux/redux-utils.js';
+import type { AppState } from '../redux/state-types.js';
+import { usePersistedStateLoaded } from '../selectors/app-state-selectors.js';
+import { logInActionType, logOutActionType } from './action-types.js';
+import ModalPruner from './modal-pruner.react.js';
+import NavFromReduxHandler from './nav-from-redux-handler.react.js';
+import { useIsAppLoggedIn } from './nav-selectors.js';
+import { NavContext, type NavAction } from './navigation-context.js';
+import PolicyAcknowledgmentHandler from './policy-acknowledgment-handler.react.js';
+import ThreadScreenTracker from './thread-screen-tracker.react.js';
const NavigationHandler: React.ComponentType<{}> = React.memo<{}>(
function NavigationHandler() {
diff --git a/native/navigation/navigation-utils.js b/native/navigation/navigation-utils.js
--- a/native/navigation/navigation-utils.js
+++ b/native/navigation/navigation-utils.js
@@ -12,7 +12,7 @@
ComposeSubchannelRouteName,
AppRouteName,
threadRoutes,
-} from './route-names';
+} from './route-names.js';
function getStateFromNavigatorRoute(
route: PossiblyStaleRoute<>,
diff --git a/native/navigation/orientation-handler.react.js b/native/navigation/orientation-handler.react.js
--- a/native/navigation/orientation-handler.react.js
+++ b/native/navigation/orientation-handler.react.js
@@ -5,10 +5,10 @@
import Orientation from 'react-native-orientation-locker';
import { useDispatch } from 'react-redux';
-import type { Dispatch } from 'lib/types/redux-types';
+import type { Dispatch } from 'lib/types/redux-types.js';
-import { updateDeviceOrientationActionType } from '../redux/action-types';
-import { useSelector } from '../redux/redux-utils';
+import { updateDeviceOrientationActionType } from '../redux/action-types.js';
+import { useSelector } from '../redux/redux-utils.js';
type Props = {
+deviceOrientation: Orientations,
diff --git a/native/navigation/overlay-navigator.react.js b/native/navigation/overlay-navigator.react.js
--- a/native/navigation/overlay-navigator.react.js
+++ b/native/navigation/overlay-navigator.react.js
@@ -21,13 +21,13 @@
import { View, StyleSheet } from 'react-native';
import Animated, { EasingNode } from 'react-native-reanimated';
-import { values } from 'lib/utils/objects';
+import { values } from 'lib/utils/objects.js';
-import { isMessageTooltipKey } from '../chat/utils';
-import { OverlayContext } from './overlay-context';
-import OverlayRouter from './overlay-router';
-import type { OverlayRouterExtraNavigationHelpers } from './overlay-router';
-import { scrollBlockingModals, TabNavigatorRouteName } from './route-names';
+import { isMessageTooltipKey } from '../chat/utils.js';
+import { OverlayContext } from './overlay-context.js';
+import OverlayRouter from './overlay-router.js';
+import type { OverlayRouterExtraNavigationHelpers } from './overlay-router.js';
+import { scrollBlockingModals, TabNavigatorRouteName } from './route-names.js';
export type OverlayNavigationHelpers<
ParamList: ParamListBase = ParamListBase,
diff --git a/native/navigation/overlay-router.js b/native/navigation/overlay-router.js
--- a/native/navigation/overlay-router.js
+++ b/native/navigation/overlay-router.js
@@ -14,8 +14,8 @@
import {
clearOverlayModalsActionType,
setRouteParamsActionType,
-} from './action-types';
-import { removeScreensFromStack } from './navigation-utils';
+} from './action-types.js';
+import { removeScreensFromStack } from './navigation-utils.js';
type ClearOverlayModalsAction = {
+type: 'CLEAR_OVERLAY_MODALS',
diff --git a/native/navigation/policy-acknowledgment-handler.react.js b/native/navigation/policy-acknowledgment-handler.react.js
--- a/native/navigation/policy-acknowledgment-handler.react.js
+++ b/native/navigation/policy-acknowledgment-handler.react.js
@@ -3,10 +3,10 @@
import { useNavigation } from '@react-navigation/native';
import * as React from 'react';
-import { policyTypes } from 'lib/facts/policies';
+import { policyTypes } from 'lib/facts/policies.js';
-import { useSelector } from '../redux/redux-utils';
-import { TermsAndPrivacyRouteName } from './route-names';
+import { useSelector } from '../redux/redux-utils.js';
+import { TermsAndPrivacyRouteName } from './route-names.js';
function PolicyAcknowledgmentHandler(): null {
const userPolicies = useSelector(state => state.userPolicies);
diff --git a/native/navigation/root-navigator.react.js b/native/navigation/root-navigator.react.js
--- a/native/navigation/root-navigator.react.js
+++ b/native/navigation/root-navigator.react.js
@@ -17,23 +17,23 @@
import { Platform } from 'react-native';
import { enableScreens } from 'react-native-screens';
-import LoggedOutModal from '../account/logged-out-modal.react';
-import TermsAndPrivacyModal from '../account/terms-and-privacy-modal.react';
-import ThreadPickerModal from '../calendar/thread-picker-modal.react';
-import ImagePasteModal from '../chat/image-paste-modal.react';
-import MessageReactionsModal from '../chat/message-reactions-modal.react';
-import AddUsersModal from '../chat/settings/add-users-modal.react';
-import ColorSelectorModal from '../chat/settings/color-selector-modal.react';
-import ComposeSubchannelModal from '../chat/settings/compose-subchannel-modal.react';
-import SidebarListModal from '../chat/sidebar-list-modal.react';
-import SubchannelsListModal from '../chat/subchannels-list-modal.react';
-import CustomServerModal from '../profile/custom-server-modal.react';
-import AppNavigator from './app-navigator.react';
-import { defaultStackScreenOptions } from './options';
-import { RootNavigatorContext } from './root-navigator-context';
+import LoggedOutModal from '../account/logged-out-modal.react.js';
+import TermsAndPrivacyModal from '../account/terms-and-privacy-modal.react.js';
+import ThreadPickerModal from '../calendar/thread-picker-modal.react.js';
+import ImagePasteModal from '../chat/image-paste-modal.react.js';
+import MessageReactionsModal from '../chat/message-reactions-modal.react.js';
+import AddUsersModal from '../chat/settings/add-users-modal.react.js';
+import ColorSelectorModal from '../chat/settings/color-selector-modal.react.js';
+import ComposeSubchannelModal from '../chat/settings/compose-subchannel-modal.react.js';
+import SidebarListModal from '../chat/sidebar-list-modal.react.js';
+import SubchannelsListModal from '../chat/subchannels-list-modal.react.js';
+import CustomServerModal from '../profile/custom-server-modal.react.js';
+import AppNavigator from './app-navigator.react.js';
+import { defaultStackScreenOptions } from './options.js';
+import { RootNavigatorContext } from './root-navigator-context.js';
import RootRouter, {
type RootRouterExtraNavigationHelpers,
-} from './root-router';
+} from './root-router.js';
import {
LoggedOutModalRouteName,
AppRouteName,
@@ -49,7 +49,7 @@
type ScreenParamList,
type RootParamList,
TermsAndPrivacyRouteName,
-} from './route-names';
+} from './route-names.js';
enableScreens();
diff --git a/native/navigation/root-router.js b/native/navigation/root-router.js
--- a/native/navigation/root-router.js
+++ b/native/navigation/root-router.js
@@ -12,21 +12,21 @@
} from '@react-navigation/native';
import { StackRouter, CommonActions } from '@react-navigation/native';
import invariant from 'invariant';
-import _isEqual from 'lodash/fp/isEqual';
+import _isEqual from 'lodash/fp/isEqual.js';
import {
logInActionType,
logOutActionType,
clearRootModalsActionType,
setNavStateActionType,
-} from './action-types';
-import { defaultNavigationState } from './default-state';
-import { removeScreensFromStack } from './navigation-utils';
+} from './action-types.js';
+import { defaultNavigationState } from './default-state.js';
+import { removeScreensFromStack } from './navigation-utils.js';
import {
accountModals,
LoggedOutModalRouteName,
AppRouteName,
-} from './route-names';
+} from './route-names.js';
type LogInAction = {
+type: 'LOG_IN',
diff --git a/native/navigation/route-names.js b/native/navigation/route-names.js
--- a/native/navigation/route-names.js
+++ b/native/navigation/route-names.js
@@ -2,29 +2,29 @@
import type { RouteProp } from '@react-navigation/native';
-import type { TermsAndPrivacyModalParams } from '../account/terms-and-privacy-modal.react';
-import type { ThreadPickerModalParams } from '../calendar/thread-picker-modal.react';
-import type { ComposeSubchannelParams } from '../chat/compose-subchannel.react';
-import type { ImagePasteModalParams } from '../chat/image-paste-modal.react';
-import type { MessageListParams } from '../chat/message-list-types';
-import type { MessageReactionsModalParams } from '../chat/message-reactions-modal.react';
-import type { MultimediaMessageTooltipModalParams } from '../chat/multimedia-message-tooltip-modal.react';
-import type { RobotextMessageTooltipModalParams } from '../chat/robotext-message-tooltip-modal.react';
-import type { AddUsersModalParams } from '../chat/settings/add-users-modal.react';
-import type { ColorSelectorModalParams } from '../chat/settings/color-selector-modal.react';
-import type { ComposeSubchannelModalParams } from '../chat/settings/compose-subchannel-modal.react';
-import type { DeleteThreadParams } from '../chat/settings/delete-thread.react';
-import type { ThreadSettingsMemberTooltipModalParams } from '../chat/settings/thread-settings-member-tooltip-modal.react';
-import type { ThreadSettingsParams } from '../chat/settings/thread-settings.react';
-import type { SidebarListModalParams } from '../chat/sidebar-list-modal.react';
-import type { SubchannelListModalParams } from '../chat/subchannels-list-modal.react';
-import type { TextMessageTooltipModalParams } from '../chat/text-message-tooltip-modal.react';
-import type { CameraModalParams } from '../media/camera-modal.react';
-import type { ImageModalParams } from '../media/image-modal.react';
-import type { VideoPlaybackModalParams } from '../media/video-playback-modal.react';
-import type { CustomServerModalParams } from '../profile/custom-server-modal.react';
-import type { RelationshipListItemTooltipModalParams } from '../profile/relationship-list-item-tooltip-modal.react';
-import type { ActionResultModalParams } from './action-result-modal.react';
+import type { TermsAndPrivacyModalParams } from '../account/terms-and-privacy-modal.react.js';
+import type { ThreadPickerModalParams } from '../calendar/thread-picker-modal.react.js';
+import type { ComposeSubchannelParams } from '../chat/compose-subchannel.react.js';
+import type { ImagePasteModalParams } from '../chat/image-paste-modal.react.js';
+import type { MessageListParams } from '../chat/message-list-types.js';
+import type { MessageReactionsModalParams } from '../chat/message-reactions-modal.react.js';
+import type { MultimediaMessageTooltipModalParams } from '../chat/multimedia-message-tooltip-modal.react.js';
+import type { RobotextMessageTooltipModalParams } from '../chat/robotext-message-tooltip-modal.react.js';
+import type { AddUsersModalParams } from '../chat/settings/add-users-modal.react.js';
+import type { ColorSelectorModalParams } from '../chat/settings/color-selector-modal.react.js';
+import type { ComposeSubchannelModalParams } from '../chat/settings/compose-subchannel-modal.react.js';
+import type { DeleteThreadParams } from '../chat/settings/delete-thread.react.js';
+import type { ThreadSettingsMemberTooltipModalParams } from '../chat/settings/thread-settings-member-tooltip-modal.react.js';
+import type { ThreadSettingsParams } from '../chat/settings/thread-settings.react.js';
+import type { SidebarListModalParams } from '../chat/sidebar-list-modal.react.js';
+import type { SubchannelListModalParams } from '../chat/subchannels-list-modal.react.js';
+import type { TextMessageTooltipModalParams } from '../chat/text-message-tooltip-modal.react.js';
+import type { CameraModalParams } from '../media/camera-modal.react.js';
+import type { ImageModalParams } from '../media/image-modal.react.js';
+import type { VideoPlaybackModalParams } from '../media/video-playback-modal.react.js';
+import type { CustomServerModalParams } from '../profile/custom-server-modal.react.js';
+import type { RelationshipListItemTooltipModalParams } from '../profile/relationship-list-item-tooltip-modal.react.js';
+import type { ActionResultModalParams } from './action-result-modal.react.js';
export const ActionResultModalRouteName = 'ActionResultModal';
export const AddUsersModalRouteName = 'AddUsersModal';
diff --git a/native/navigation/subchannels-button.react.js b/native/navigation/subchannels-button.react.js
--- a/native/navigation/subchannels-button.react.js
+++ b/native/navigation/subchannels-button.react.js
@@ -1,14 +1,14 @@
// @flow
-import Icon from '@expo/vector-icons/Feather';
+import Icon from '@expo/vector-icons/Feather.js';
import { useNavigation } from '@react-navigation/native';
import * as React from 'react';
import { TouchableOpacity, Text, View } from 'react-native';
-import type { ThreadInfo } from 'lib/types/thread-types';
+import type { ThreadInfo } from 'lib/types/thread-types.js';
-import { useStyles } from '../themes/colors';
-import { SubchannelsListModalRouteName } from './route-names';
+import { useStyles } from '../themes/colors.js';
+import { SubchannelsListModalRouteName } from './route-names.js';
type Props = {
+threadInfo: ThreadInfo,
diff --git a/native/navigation/tab-bar.react.js b/native/navigation/tab-bar.react.js
--- a/native/navigation/tab-bar.react.js
+++ b/native/navigation/tab-bar.react.js
@@ -7,10 +7,10 @@
import { useSafeArea } from 'react-native-safe-area-context';
import { useDispatch } from 'react-redux';
-import { KeyboardContext } from '../keyboard/keyboard-state';
-import { updateDimensionsActiveType } from '../redux/action-types';
-import { useSelector } from '../redux/redux-utils';
-import type { LayoutEvent } from '../types/react-native';
+import { KeyboardContext } from '../keyboard/keyboard-state.js';
+import { updateDimensionsActiveType } from '../redux/action-types.js';
+import { useSelector } from '../redux/redux-utils.js';
+import type { LayoutEvent } from '../types/react-native.js';
/* eslint-disable import/no-named-as-default-member */
const { Value, timing, interpolateNode } = Animated;
diff --git a/native/navigation/tab-navigator.react.js b/native/navigation/tab-navigator.react.js
--- a/native/navigation/tab-navigator.react.js
+++ b/native/navigation/tab-navigator.react.js
@@ -7,17 +7,17 @@
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
import * as React from 'react';
-import { unreadCount } from 'lib/selectors/thread-selectors';
+import { unreadCount } from 'lib/selectors/thread-selectors.js';
-import AppsDirectory from '../apps/apps-directory.react';
-import Calendar from '../calendar/calendar.react';
-import Chat from '../chat/chat.react';
-import SWMansionIcon from '../components/swmansion-icon.react';
-import Profile from '../profile/profile.react';
-import { useSelector } from '../redux/redux-utils';
-import { useColors } from '../themes/colors';
-import CommunityDrawerButton from './community-drawer-button.react';
-import type { CommunityDrawerNavigationProp } from './community-drawer-navigator.react';
+import AppsDirectory from '../apps/apps-directory.react.js';
+import Calendar from '../calendar/calendar.react.js';
+import Chat from '../chat/chat.react.js';
+import SWMansionIcon from '../components/swmansion-icon.react.js';
+import Profile from '../profile/profile.react.js';
+import { useSelector } from '../redux/redux-utils.js';
+import { useColors } from '../themes/colors.js';
+import CommunityDrawerButton from './community-drawer-button.react.js';
+import type { CommunityDrawerNavigationProp } from './community-drawer-navigator.react.js';
import {
CalendarRouteName,
ChatRouteName,
@@ -25,9 +25,9 @@
AppsRouteName,
type ScreenParamList,
type TabParamList,
-} from './route-names';
-import type { NavigationRoute } from './route-names';
-import { tabBar } from './tab-bar.react';
+} from './route-names.js';
+import type { NavigationRoute } from './route-names.js';
+import { tabBar } from './tab-bar.react.js';
const calendarTabOptions = {
tabBarLabel: 'Calendar',
diff --git a/native/navigation/thread-screen-tracker.react.js b/native/navigation/thread-screen-tracker.react.js
--- a/native/navigation/thread-screen-tracker.react.js
+++ b/native/navigation/thread-screen-tracker.react.js
@@ -3,8 +3,8 @@
import * as React from 'react';
import { useDispatch } from 'react-redux';
-import { updateThreadLastNavigatedActionType } from '../redux/action-types';
-import { useActiveMessageList } from './nav-selectors';
+import { updateThreadLastNavigatedActionType } from '../redux/action-types.js';
+import { useActiveMessageList } from './nav-selectors.js';
const ThreadScreenTracker: React.ComponentType<{}> = React.memo<{}>(
function ThreadScreenTracker() {
diff --git a/native/profile/appearance-preferences.react.js b/native/profile/appearance-preferences.react.js
--- a/native/profile/appearance-preferences.react.js
+++ b/native/profile/appearance-preferences.react.js
@@ -5,18 +5,18 @@
import { ScrollView } from 'react-native-gesture-handler';
import { useDispatch } from 'react-redux';
-import type { Dispatch } from 'lib/types/redux-types';
+import type { Dispatch } from 'lib/types/redux-types.js';
-import Button from '../components/button.react';
-import SWMansionIcon from '../components/swmansion-icon.react';
-import { updateThemeInfoActionType } from '../redux/action-types';
-import { useSelector } from '../redux/redux-utils';
-import { type Colors, useColors, useStyles } from '../themes/colors';
+import Button from '../components/button.react.js';
+import SWMansionIcon from '../components/swmansion-icon.react.js';
+import { updateThemeInfoActionType } from '../redux/action-types.js';
+import { useSelector } from '../redux/redux-utils.js';
+import { type Colors, useColors, useStyles } from '../themes/colors.js';
import {
type GlobalThemePreference,
type GlobalThemeInfo,
osCanTheme,
-} from '../types/themes';
+} from '../types/themes.js';
const CheckIcon = () => (
<SWMansionIcon
diff --git a/native/profile/build-info.react.js b/native/profile/build-info.react.js
--- a/native/profile/build-info.react.js
+++ b/native/profile/build-info.react.js
@@ -4,14 +4,14 @@
import { View, Text } from 'react-native';
import { ScrollView } from 'react-native-gesture-handler';
-import { persistConfig, codeVersion } from '../redux/persist';
-import { StaffContext } from '../staff/staff-context';
-import { useStyles } from '../themes/colors';
+import { persistConfig, codeVersion } from '../redux/persist.js';
+import { StaffContext } from '../staff/staff-context.js';
+import { useStyles } from '../themes/colors.js';
import {
isStaffRelease,
useIsCurrentUserStaff,
useStaffCanSee,
-} from '../utils/staff-utils';
+} from '../utils/staff-utils.js';
// eslint-disable-next-line no-unused-vars
function BuildInfo(props: { ... }): React.Node {
diff --git a/native/profile/custom-server-modal.react.js b/native/profile/custom-server-modal.react.js
--- a/native/profile/custom-server-modal.react.js
+++ b/native/profile/custom-server-modal.react.js
@@ -4,17 +4,17 @@
import { Text } from 'react-native';
import { useDispatch } from 'react-redux';
-import type { Dispatch } from 'lib/types/redux-types';
-import { setURLPrefix } from 'lib/utils/url-utils';
+import type { Dispatch } from 'lib/types/redux-types.js';
+import { setURLPrefix } from 'lib/utils/url-utils.js';
-import Button from '../components/button.react';
-import Modal from '../components/modal.react';
-import TextInput from '../components/text-input.react';
-import type { RootNavigationProp } from '../navigation/root-navigator.react';
-import type { NavigationRoute } from '../navigation/route-names';
-import { useSelector } from '../redux/redux-utils';
-import { useStyles } from '../themes/colors';
-import { setCustomServer } from '../utils/url-utils';
+import Button from '../components/button.react.js';
+import Modal from '../components/modal.react.js';
+import TextInput from '../components/text-input.react.js';
+import type { RootNavigationProp } from '../navigation/root-navigator.react.js';
+import type { NavigationRoute } from '../navigation/route-names.js';
+import { useSelector } from '../redux/redux-utils.js';
+import { useStyles } from '../themes/colors.js';
+import { setCustomServer } from '../utils/url-utils.js';
export type CustomServerModalParams = {
+presentedFrom: string,
diff --git a/native/profile/default-notifications-preferences.react.js b/native/profile/default-notifications-preferences.react.js
--- a/native/profile/default-notifications-preferences.react.js
+++ b/native/profile/default-notifications-preferences.react.js
@@ -7,27 +7,27 @@
import {
setUserSettings,
setUserSettingsActionTypes,
-} from 'lib/actions/user-actions';
-import { registerFetchKey } from 'lib/reducers/loading-reducer';
+} from 'lib/actions/user-actions.js';
+import { registerFetchKey } from 'lib/reducers/loading-reducer.js';
import {
type UpdateUserSettingsRequest,
type NotificationTypes,
type DefaultNotificationPayload,
notificationTypes,
userSettingsTypes,
-} from 'lib/types/account-types';
+} from 'lib/types/account-types.js';
import {
type DispatchActionPromise,
useServerCall,
useDispatchActionPromise,
-} from 'lib/utils/action-utils';
-
-import Action from '../components/action-row.react';
-import SWMansionIcon from '../components/swmansion-icon.react';
-import type { NavigationRoute } from '../navigation/route-names';
-import { useSelector } from '../redux/redux-utils';
-import { useStyles } from '../themes/colors';
-import type { ProfileNavigationProp } from './profile.react';
+} from 'lib/utils/action-utils.js';
+
+import Action from '../components/action-row.react.js';
+import SWMansionIcon from '../components/swmansion-icon.react.js';
+import type { NavigationRoute } from '../navigation/route-names.js';
+import { useSelector } from '../redux/redux-utils.js';
+import { useStyles } from '../themes/colors.js';
+import type { ProfileNavigationProp } from './profile.react.js';
const CheckIcon = () => (
<SWMansionIcon
diff --git a/native/profile/delete-account.react.js b/native/profile/delete-account.react.js
--- a/native/profile/delete-account.react.js
+++ b/native/profile/delete-account.react.js
@@ -14,25 +14,25 @@
import {
deleteAccountActionTypes,
deleteAccount,
-} from 'lib/actions/user-actions';
-import { preRequestUserStateSelector } from 'lib/selectors/account-selectors';
-import { createLoadingStatusSelector } from 'lib/selectors/loading-selectors';
-import { accountHasPassword } from 'lib/shared/account-utils';
-import type { LogOutResult } from 'lib/types/account-types';
-import type { LoadingStatus } from 'lib/types/loading-types';
-import type { PreRequestUserState } from 'lib/types/session-types';
-import type { DispatchActionPromise } from 'lib/utils/action-utils';
+} from 'lib/actions/user-actions.js';
+import { preRequestUserStateSelector } from 'lib/selectors/account-selectors.js';
+import { createLoadingStatusSelector } from 'lib/selectors/loading-selectors.js';
+import { accountHasPassword } from 'lib/shared/account-utils.js';
+import type { LogOutResult } from 'lib/types/account-types.js';
+import type { LoadingStatus } from 'lib/types/loading-types.js';
+import type { PreRequestUserState } from 'lib/types/session-types.js';
+import type { DispatchActionPromise } from 'lib/utils/action-utils.js';
import {
useServerCall,
useDispatchActionPromise,
-} from 'lib/utils/action-utils';
+} from 'lib/utils/action-utils.js';
-import { deleteNativeCredentialsFor } from '../account/native-credentials';
-import Button from '../components/button.react';
-import TextInput from '../components/text-input.react';
-import { useSelector } from '../redux/redux-utils';
-import { type Colors, useColors, useStyles } from '../themes/colors';
-import type { GlobalTheme } from '../types/themes';
+import { deleteNativeCredentialsFor } from '../account/native-credentials.js';
+import Button from '../components/button.react.js';
+import TextInput from '../components/text-input.react.js';
+import { useSelector } from '../redux/redux-utils.js';
+import { type Colors, useColors, useStyles } from '../themes/colors.js';
+import type { GlobalTheme } from '../types/themes.js';
type Props = {
// Redux state
diff --git a/native/profile/dev-tools.react.js b/native/profile/dev-tools.react.js
--- a/native/profile/dev-tools.react.js
+++ b/native/profile/dev-tools.react.js
@@ -6,19 +6,19 @@
import { ScrollView } from 'react-native-gesture-handler';
import { useDispatch } from 'react-redux';
-import type { Dispatch } from 'lib/types/redux-types';
-import { setURLPrefix } from 'lib/utils/url-utils';
+import type { Dispatch } from 'lib/types/redux-types.js';
+import { setURLPrefix } from 'lib/utils/url-utils.js';
-import Button from '../components/button.react';
-import SWMansionIcon from '../components/swmansion-icon.react';
-import type { NavigationRoute } from '../navigation/route-names';
-import { CustomServerModalRouteName } from '../navigation/route-names';
-import { useSelector } from '../redux/redux-utils';
-import { useColors, useStyles, type Colors } from '../themes/colors';
-import { wipeAndExit } from '../utils/crash-utils';
-import { checkForMissingNatDevHostname } from '../utils/dev-hostname';
-import { nodeServerOptions } from '../utils/url-utils';
-import type { ProfileNavigationProp } from './profile.react';
+import Button from '../components/button.react.js';
+import SWMansionIcon from '../components/swmansion-icon.react.js';
+import type { NavigationRoute } from '../navigation/route-names.js';
+import { CustomServerModalRouteName } from '../navigation/route-names.js';
+import { useSelector } from '../redux/redux-utils.js';
+import { useColors, useStyles, type Colors } from '../themes/colors.js';
+import { wipeAndExit } from '../utils/crash-utils.js';
+import { checkForMissingNatDevHostname } from '../utils/dev-hostname.js';
+import { nodeServerOptions } from '../utils/url-utils.js';
+import type { ProfileNavigationProp } from './profile.react.js';
const ServerIcon = () => (
<SWMansionIcon
diff --git a/native/profile/edit-password.react.js b/native/profile/edit-password.react.js
--- a/native/profile/edit-password.react.js
+++ b/native/profile/edit-password.react.js
@@ -15,24 +15,24 @@
import {
changeUserPasswordActionTypes,
changeUserPassword,
-} from 'lib/actions/user-actions';
-import { createLoadingStatusSelector } from 'lib/selectors/loading-selectors';
-import type { LoadingStatus } from 'lib/types/loading-types';
-import type { PasswordUpdate } from 'lib/types/user-types';
+} from 'lib/actions/user-actions.js';
+import { createLoadingStatusSelector } from 'lib/selectors/loading-selectors.js';
+import type { LoadingStatus } from 'lib/types/loading-types.js';
+import type { PasswordUpdate } from 'lib/types/user-types.js';
import {
useServerCall,
useDispatchActionPromise,
type DispatchActionPromise,
-} from 'lib/utils/action-utils';
+} from 'lib/utils/action-utils.js';
-import { setNativeCredentials } from '../account/native-credentials';
-import Button from '../components/button.react';
-import TextInput from '../components/text-input.react';
-import type { NavigationRoute } from '../navigation/route-names';
-import { useSelector } from '../redux/redux-utils';
-import { type Colors, useColors, useStyles } from '../themes/colors';
-import type { GlobalTheme } from '../types/themes';
-import type { ProfileNavigationProp } from './profile.react';
+import { setNativeCredentials } from '../account/native-credentials.js';
+import Button from '../components/button.react.js';
+import TextInput from '../components/text-input.react.js';
+import type { NavigationRoute } from '../navigation/route-names.js';
+import { useSelector } from '../redux/redux-utils.js';
+import { type Colors, useColors, useStyles } from '../themes/colors.js';
+import type { GlobalTheme } from '../types/themes.js';
+import type { ProfileNavigationProp } from './profile.react.js';
type BaseProps = {
+navigation: ProfileNavigationProp<'EditPassword'>,
diff --git a/native/profile/privacy-preferences.react.js b/native/profile/privacy-preferences.react.js
--- a/native/profile/privacy-preferences.react.js
+++ b/native/profile/privacy-preferences.react.js
@@ -4,8 +4,8 @@
import { View, Text } from 'react-native';
import { ScrollView } from 'react-native-gesture-handler';
-import { useStyles } from '../themes/colors';
-import ToggleReport from './toggle-report.react';
+import { useStyles } from '../themes/colors.js';
+import ToggleReport from './toggle-report.react.js';
// eslint-disable-next-line no-unused-vars
function PrivacyPreferences(props: { ... }): React.Node {
diff --git a/native/profile/profile-header.react.js b/native/profile/profile-header.react.js
--- a/native/profile/profile-header.react.js
+++ b/native/profile/profile-header.react.js
@@ -3,10 +3,10 @@
import type { StackHeaderProps } from '@react-navigation/stack';
import * as React from 'react';
-import Header from '../navigation/header.react';
-import { createActiveTabSelector } from '../navigation/nav-selectors';
-import { NavContext } from '../navigation/navigation-context';
-import { ProfileRouteName } from '../navigation/route-names';
+import Header from '../navigation/header.react.js';
+import { createActiveTabSelector } from '../navigation/nav-selectors.js';
+import { NavContext } from '../navigation/navigation-context.js';
+import { ProfileRouteName } from '../navigation/route-names.js';
const activeTabSelector = createActiveTabSelector(ProfileRouteName);
diff --git a/native/profile/profile-screen.react.js b/native/profile/profile-screen.react.js
--- a/native/profile/profile-screen.react.js
+++ b/native/profile/profile-screen.react.js
@@ -3,26 +3,26 @@
import * as React from 'react';
import { View, Text, Alert, Platform, ScrollView } from 'react-native';
-import { logOutActionTypes, logOut } from 'lib/actions/user-actions';
-import { useStringForUser } from 'lib/hooks/ens-cache';
-import { preRequestUserStateSelector } from 'lib/selectors/account-selectors';
-import { createLoadingStatusSelector } from 'lib/selectors/loading-selectors';
-import { accountHasPassword } from 'lib/shared/account-utils';
-import type { LogOutResult } from 'lib/types/account-types';
-import { type PreRequestUserState } from 'lib/types/session-types';
-import { type CurrentUserInfo } from 'lib/types/user-types';
+import { logOutActionTypes, logOut } from 'lib/actions/user-actions.js';
+import { useStringForUser } from 'lib/hooks/ens-cache.js';
+import { preRequestUserStateSelector } from 'lib/selectors/account-selectors.js';
+import { createLoadingStatusSelector } from 'lib/selectors/loading-selectors.js';
+import { accountHasPassword } from 'lib/shared/account-utils.js';
+import type { LogOutResult } from 'lib/types/account-types.js';
+import { type PreRequestUserState } from 'lib/types/session-types.js';
+import { type CurrentUserInfo } from 'lib/types/user-types.js';
import {
type DispatchActionPromise,
useDispatchActionPromise,
useServerCall,
-} from 'lib/utils/action-utils';
+} from 'lib/utils/action-utils.js';
-import { deleteNativeCredentialsFor } from '../account/native-credentials';
-import Action from '../components/action-row.react';
-import Button from '../components/button.react';
-import EditSettingButton from '../components/edit-setting-button.react';
-import { SingleLine } from '../components/single-line.react';
-import type { NavigationRoute } from '../navigation/route-names';
+import { deleteNativeCredentialsFor } from '../account/native-credentials.js';
+import Action from '../components/action-row.react.js';
+import Button from '../components/button.react.js';
+import EditSettingButton from '../components/edit-setting-button.react.js';
+import { SingleLine } from '../components/single-line.react.js';
+import type { NavigationRoute } from '../navigation/route-names.js';
import {
EditPasswordRouteName,
DeleteAccountRouteName,
@@ -33,11 +33,11 @@
BlockListRouteName,
PrivacyPreferencesRouteName,
DefaultNotificationsPreferencesRouteName,
-} from '../navigation/route-names';
-import { useSelector } from '../redux/redux-utils';
-import { type Colors, useColors, useStyles } from '../themes/colors';
-import { useStaffCanSee } from '../utils/staff-utils';
-import type { ProfileNavigationProp } from './profile.react';
+} from '../navigation/route-names.js';
+import { useSelector } from '../redux/redux-utils.js';
+import { type Colors, useColors, useStyles } from '../themes/colors.js';
+import { useStaffCanSee } from '../utils/staff-utils.js';
+import type { ProfileNavigationProp } from './profile.react.js';
type ProfileRowProps = {
+content: string,
diff --git a/native/profile/profile.react.js b/native/profile/profile.react.js
--- a/native/profile/profile.react.js
+++ b/native/profile/profile.react.js
@@ -9,10 +9,10 @@
import * as React from 'react';
import { View, useWindowDimensions } from 'react-native';
-import KeyboardAvoidingView from '../components/keyboard-avoiding-view.react';
-import CommunityDrawerButton from '../navigation/community-drawer-button.react';
-import type { CommunityDrawerNavigationProp } from '../navigation/community-drawer-navigator.react';
-import HeaderBackButton from '../navigation/header-back-button.react';
+import KeyboardAvoidingView from '../components/keyboard-avoiding-view.react.js';
+import CommunityDrawerButton from '../navigation/community-drawer-button.react.js';
+import type { CommunityDrawerNavigationProp } from '../navigation/community-drawer-navigator.react.js';
+import HeaderBackButton from '../navigation/header-back-button.react.js';
import {
ProfileScreenRouteName,
EditPasswordRouteName,
@@ -26,18 +26,18 @@
BlockListRouteName,
type ScreenParamList,
type ProfileParamList,
-} from '../navigation/route-names';
-import { useStyles, useColors } from '../themes/colors';
-import AppearancePreferences from './appearance-preferences.react';
-import BuildInfo from './build-info.react';
-import DefaultNotificationsPreferences from './default-notifications-preferences.react';
-import DeleteAccount from './delete-account.react';
-import DevTools from './dev-tools.react';
-import EditPassword from './edit-password.react';
-import PrivacyPreferences from './privacy-preferences.react';
-import ProfileHeader from './profile-header.react';
-import ProfileScreen from './profile-screen.react';
-import RelationshipList from './relationship-list.react';
+} from '../navigation/route-names.js';
+import { useStyles, useColors } from '../themes/colors.js';
+import AppearancePreferences from './appearance-preferences.react.js';
+import BuildInfo from './build-info.react.js';
+import DefaultNotificationsPreferences from './default-notifications-preferences.react.js';
+import DeleteAccount from './delete-account.react.js';
+import DevTools from './dev-tools.react.js';
+import EditPassword from './edit-password.react.js';
+import PrivacyPreferences from './privacy-preferences.react.js';
+import ProfileHeader from './profile-header.react.js';
+import ProfileScreen from './profile-screen.react.js';
+import RelationshipList from './relationship-list.react.js';
const header = (props: StackHeaderProps) => <ProfileHeader {...props} />;
const profileScreenOptions = { headerTitle: 'Profile' };
diff --git a/native/profile/relationship-list-item-tooltip-modal.react.js b/native/profile/relationship-list-item-tooltip-modal.react.js
--- a/native/profile/relationship-list-item-tooltip-modal.react.js
+++ b/native/profile/relationship-list-item-tooltip-modal.react.js
@@ -6,22 +6,22 @@
import {
updateRelationshipsActionTypes,
updateRelationships,
-} from 'lib/actions/relationship-actions';
-import { stringForUser } from 'lib/shared/user-utils';
-import type { RelativeUserInfo } from 'lib/types/user-types';
+} from 'lib/actions/relationship-actions.js';
+import { stringForUser } from 'lib/shared/user-utils.js';
+import type { RelativeUserInfo } from 'lib/types/user-types.js';
import {
useDispatchActionPromise,
useServerCall,
-} from 'lib/utils/action-utils';
+} from 'lib/utils/action-utils.js';
-import PencilIcon from '../components/pencil-icon.react';
-import type { AppNavigationProp } from '../navigation/app-navigator.react';
+import PencilIcon from '../components/pencil-icon.react.js';
+import type { AppNavigationProp } from '../navigation/app-navigator.react.js';
import {
createTooltip,
type TooltipParams,
type BaseTooltipProps,
type TooltipMenuProps,
-} from '../tooltip/tooltip.react';
+} from '../tooltip/tooltip.react.js';
type Action = 'unfriend' | 'unblock';
diff --git a/native/profile/relationship-list-item.react.js b/native/profile/relationship-list-item.react.js
--- a/native/profile/relationship-list-item.react.js
+++ b/native/profile/relationship-list-item.react.js
@@ -13,46 +13,46 @@
import {
updateRelationshipsActionTypes,
updateRelationships,
-} from 'lib/actions/relationship-actions';
-import { createLoadingStatusSelector } from 'lib/selectors/loading-selectors';
-import type { LoadingStatus } from 'lib/types/loading-types';
+} from 'lib/actions/relationship-actions.js';
+import { createLoadingStatusSelector } from 'lib/selectors/loading-selectors.js';
+import type { LoadingStatus } from 'lib/types/loading-types.js';
import {
type RelationshipRequest,
type RelationshipAction,
type RelationshipErrors,
userRelationshipStatus,
relationshipActions,
-} from 'lib/types/relationship-types';
+} from 'lib/types/relationship-types.js';
import type {
AccountUserInfo,
GlobalAccountUserInfo,
-} from 'lib/types/user-types';
+} from 'lib/types/user-types.js';
import {
type DispatchActionPromise,
useServerCall,
useDispatchActionPromise,
-} from 'lib/utils/action-utils';
+} from 'lib/utils/action-utils.js';
-import PencilIcon from '../components/pencil-icon.react';
-import { SingleLine } from '../components/single-line.react';
+import PencilIcon from '../components/pencil-icon.react.js';
+import { SingleLine } from '../components/single-line.react.js';
import {
type KeyboardState,
KeyboardContext,
-} from '../keyboard/keyboard-state';
+} from '../keyboard/keyboard-state.js';
import {
OverlayContext,
type OverlayContextType,
-} from '../navigation/overlay-context';
-import type { NavigationRoute } from '../navigation/route-names';
+} from '../navigation/overlay-context.js';
+import type { NavigationRoute } from '../navigation/route-names.js';
import {
RelationshipListItemTooltipModalRouteName,
FriendListRouteName,
BlockListRouteName,
-} from '../navigation/route-names';
-import { useSelector } from '../redux/redux-utils';
-import { type Colors, useColors, useStyles } from '../themes/colors';
-import type { VerticalBounds } from '../types/layout-types';
-import type { RelationshipListNavigate } from './relationship-list.react';
+} from '../navigation/route-names.js';
+import { useSelector } from '../redux/redux-utils.js';
+import { type Colors, useColors, useStyles } from '../themes/colors.js';
+import type { VerticalBounds } from '../types/layout-types.js';
+import type { RelationshipListNavigate } from './relationship-list.react.js';
type BaseProps = {
+userInfo: AccountUserInfo,
diff --git a/native/profile/relationship-list.react.js b/native/profile/relationship-list.react.js
--- a/native/profile/relationship-list.react.js
+++ b/native/profile/relationship-list.react.js
@@ -8,39 +8,42 @@
import {
updateRelationshipsActionTypes,
updateRelationships,
-} from 'lib/actions/relationship-actions';
-import { searchUsersActionTypes, searchUsers } from 'lib/actions/user-actions';
-import { useENSNames } from 'lib/hooks/ens-cache';
-import { registerFetchKey } from 'lib/reducers/loading-reducer';
-import { userRelationshipsSelector } from 'lib/selectors/relationship-selectors';
-import { userStoreSearchIndex as userStoreSearchIndexSelector } from 'lib/selectors/user-selectors';
+} from 'lib/actions/relationship-actions.js';
+import {
+ searchUsersActionTypes,
+ searchUsers,
+} from 'lib/actions/user-actions.js';
+import { useENSNames } from 'lib/hooks/ens-cache.js';
+import { registerFetchKey } from 'lib/reducers/loading-reducer.js';
+import { userRelationshipsSelector } from 'lib/selectors/relationship-selectors.js';
+import { userStoreSearchIndex as userStoreSearchIndexSelector } from 'lib/selectors/user-selectors.js';
import {
userRelationshipStatus,
relationshipActions,
-} from 'lib/types/relationship-types';
+} from 'lib/types/relationship-types.js';
import type {
GlobalAccountUserInfo,
AccountUserInfo,
-} from 'lib/types/user-types';
+} from 'lib/types/user-types.js';
import {
useServerCall,
useDispatchActionPromise,
-} from 'lib/utils/action-utils';
+} from 'lib/utils/action-utils.js';
-import LinkButton from '../components/link-button.react';
-import { createTagInput, BaseTagInput } from '../components/tag-input.react';
-import { KeyboardContext } from '../keyboard/keyboard-state';
-import { OverlayContext } from '../navigation/overlay-context';
-import type { NavigationRoute } from '../navigation/route-names';
+import LinkButton from '../components/link-button.react.js';
+import { createTagInput, BaseTagInput } from '../components/tag-input.react.js';
+import { KeyboardContext } from '../keyboard/keyboard-state.js';
+import { OverlayContext } from '../navigation/overlay-context.js';
+import type { NavigationRoute } from '../navigation/route-names.js';
import {
FriendListRouteName,
BlockListRouteName,
-} from '../navigation/route-names';
-import { useSelector } from '../redux/redux-utils';
-import { useStyles, useIndicatorStyle } from '../themes/colors';
-import type { VerticalBounds } from '../types/layout-types';
-import type { ProfileNavigationProp } from './profile.react';
-import RelationshipListItem from './relationship-list-item.react';
+} from '../navigation/route-names.js';
+import { useSelector } from '../redux/redux-utils.js';
+import { useStyles, useIndicatorStyle } from '../themes/colors.js';
+import type { VerticalBounds } from '../types/layout-types.js';
+import type { ProfileNavigationProp } from './profile.react.js';
+import RelationshipListItem from './relationship-list-item.react.js';
const TagInput = createTagInput<GlobalAccountUserInfo>();
diff --git a/native/profile/toggle-report.react.js b/native/profile/toggle-report.react.js
--- a/native/profile/toggle-report.react.js
+++ b/native/profile/toggle-report.react.js
@@ -4,9 +4,9 @@
import { Switch } from 'react-native';
import { useDispatch } from 'react-redux';
-import { updateReportsEnabledActionType } from 'lib/reducers/report-store-reducer';
-import { type SupportedReports } from 'lib/types/report-types';
-import { useIsReportEnabled } from 'lib/utils/report-utils';
+import { updateReportsEnabledActionType } from 'lib/reducers/report-store-reducer.js';
+import { type SupportedReports } from 'lib/types/report-types.js';
+import { useIsReportEnabled } from 'lib/utils/report-utils.js';
type Props = {
+reportType: SupportedReports,
diff --git a/native/push/android.js b/native/push/android.js
--- a/native/push/android.js
+++ b/native/push/android.js
@@ -2,7 +2,7 @@
import { NativeModules, NativeEventEmitter } from 'react-native';
-import { mergePrefixIntoBody } from 'lib/shared/notif-utils';
+import { mergePrefixIntoBody } from 'lib/shared/notif-utils.js';
type CommAndroidNotificationsModuleType = {
+removeAllActiveNotificationsForThread: (threadID: string) => void,
diff --git a/native/push/in-app-notif.react.js b/native/push/in-app-notif.react.js
--- a/native/push/in-app-notif.react.js
+++ b/native/push/in-app-notif.react.js
@@ -4,8 +4,8 @@
import { View, Text, StyleSheet, Platform } from 'react-native';
import { SafeAreaView } from 'react-native-safe-area-context';
-import { SingleLine } from '../components/single-line.react';
-import type { GlobalTheme } from '../types/themes';
+import { SingleLine } from '../components/single-line.react.js';
+import type { GlobalTheme } from '../types/themes.js';
const edges = ['top'];
diff --git a/native/push/ios.js b/native/push/ios.js
--- a/native/push/ios.js
+++ b/native/push/ios.js
@@ -5,7 +5,7 @@
import type {
CoreIOSNotificationData,
CoreIOSNotificationDataWithRequestIdentifier,
-} from './comm-ios-notification';
+} from './comm-ios-notification.js';
type PushPermissions = { alert?: boolean, badge?: boolean, sound?: boolean };
diff --git a/native/push/push-handler.react.js b/native/push/push-handler.react.js
--- a/native/push/push-handler.react.js
+++ b/native/push/push-handler.react.js
@@ -9,55 +9,55 @@
import {
setDeviceTokenActionTypes,
setDeviceToken,
-} from 'lib/actions/device-actions';
-import { saveMessagesActionType } from 'lib/actions/message-actions';
+} from 'lib/actions/device-actions.js';
+import { saveMessagesActionType } from 'lib/actions/message-actions.js';
import {
unreadCount,
threadInfoSelector,
-} from 'lib/selectors/thread-selectors';
-import { isLoggedIn } from 'lib/selectors/user-selectors';
-import { mergePrefixIntoBody } from 'lib/shared/notif-utils';
-import type { RawMessageInfo } from 'lib/types/message-types';
-import type { Dispatch } from 'lib/types/redux-types';
-import { type ConnectionInfo } from 'lib/types/socket-types';
-import { type ThreadInfo } from 'lib/types/thread-types';
+} from 'lib/selectors/thread-selectors.js';
+import { isLoggedIn } from 'lib/selectors/user-selectors.js';
+import { mergePrefixIntoBody } from 'lib/shared/notif-utils.js';
+import type { RawMessageInfo } from 'lib/types/message-types.js';
+import type { Dispatch } from 'lib/types/redux-types.js';
+import { type ConnectionInfo } from 'lib/types/socket-types.js';
+import { type ThreadInfo } from 'lib/types/thread-types.js';
import {
useServerCall,
useDispatchActionPromise,
type DispatchActionPromise,
-} from 'lib/utils/action-utils';
+} from 'lib/utils/action-utils.js';
import {
type MessageListParams,
useNavigateToThread,
-} from '../chat/message-list-types';
+} from '../chat/message-list-types.js';
import {
addLifecycleListener,
getCurrentLifecycleState,
-} from '../lifecycle/lifecycle';
-import { replaceWithThreadActionType } from '../navigation/action-types';
-import { activeMessageListSelector } from '../navigation/nav-selectors';
-import { NavContext } from '../navigation/navigation-context';
-import type { RootNavigationProp } from '../navigation/root-navigator.react';
-import { recordNotifPermissionAlertActionType } from '../redux/action-types';
-import { useSelector } from '../redux/redux-utils';
-import { RootContext, type RootContextType } from '../root-context';
-import type { EventSubscription } from '../types/react-native';
-import { type GlobalTheme } from '../types/themes';
-import { type NotifPermissionAlertInfo } from './alerts';
+} from '../lifecycle/lifecycle.js';
+import { replaceWithThreadActionType } from '../navigation/action-types.js';
+import { activeMessageListSelector } from '../navigation/nav-selectors.js';
+import { NavContext } from '../navigation/navigation-context.js';
+import type { RootNavigationProp } from '../navigation/root-navigator.react.js';
+import { recordNotifPermissionAlertActionType } from '../redux/action-types.js';
+import { useSelector } from '../redux/redux-utils.js';
+import { RootContext, type RootContextType } from '../root-context.js';
+import type { EventSubscription } from '../types/react-native.js';
+import { type GlobalTheme } from '../types/themes.js';
+import { type NotifPermissionAlertInfo } from './alerts.js';
import {
androidNotificationChannelID,
handleAndroidMessage,
getCommAndroidNotificationsEventEmitter,
type AndroidForegroundMessage,
CommAndroidNotifications,
-} from './android';
+} from './android.js';
import {
CommIOSNotification,
type CoreIOSNotificationData,
type CoreIOSNotificationDataWithRequestIdentifier,
-} from './comm-ios-notification';
-import InAppNotif from './in-app-notif.react';
+} from './comm-ios-notification.js';
+import InAppNotif from './in-app-notif.react.js';
import {
requestIOSPushPermissions,
iosPushPermissionResponseReceived,
diff --git a/native/reactotron.js b/native/reactotron.js
--- a/native/reactotron.js
+++ b/native/reactotron.js
@@ -2,7 +2,7 @@
import AsyncStorage from '@react-native-async-storage/async-storage';
-import { getDevServerHostname } from './utils/url-utils';
+import { getDevServerHostname } from './utils/url-utils.js';
let reactotron: any = null;
diff --git a/native/redux/action-types.js b/native/redux/action-types.js
--- a/native/redux/action-types.js
+++ b/native/redux/action-types.js
@@ -2,15 +2,15 @@
import type { Orientations } from 'react-native-orientation-locker';
-import { saveMessagesActionType } from 'lib/actions/message-actions';
-import type { Shape } from 'lib/types/core';
-import type { BaseAction } from 'lib/types/redux-types';
+import { saveMessagesActionType } from 'lib/actions/message-actions.js';
+import type { Shape } from 'lib/types/core.js';
+import type { BaseAction } from 'lib/types/redux-types.js';
-import type { DeviceCameraInfo } from '../types/camera';
-import type { ConnectivityInfo } from '../types/connectivity';
-import type { GlobalThemeInfo } from '../types/themes';
-import type { DimensionsInfo } from './dimensions-updater.react';
-import type { AppState } from './state-types';
+import type { DeviceCameraInfo } from '../types/camera.js';
+import type { ConnectivityInfo } from '../types/connectivity.js';
+import type { GlobalThemeInfo } from '../types/themes.js';
+import type { DimensionsInfo } from './dimensions-updater.react.js';
+import type { AppState } from './state-types.js';
export const resetUserStateActionType = 'RESET_USER_STATE';
export const recordNotifPermissionAlertActionType =
diff --git a/native/redux/connectivity-updater.react.js b/native/redux/connectivity-updater.react.js
--- a/native/redux/connectivity-updater.react.js
+++ b/native/redux/connectivity-updater.react.js
@@ -4,8 +4,8 @@
import * as React from 'react';
import { useDispatch } from 'react-redux';
-import { updateConnectivityActiveType } from './action-types';
-import { useSelector } from './redux-utils';
+import { updateConnectivityActiveType } from './action-types.js';
+import { useSelector } from './redux-utils.js';
export default function ConnectivityUpdater(): null {
const connectivity = useSelector(state => state.connectivity);
diff --git a/native/redux/dev-tools.js b/native/redux/dev-tools.js
--- a/native/redux/dev-tools.js
+++ b/native/redux/dev-tools.js
@@ -1,6 +1,6 @@
// @flow
-import { getDevServerHostname } from '../utils/url-utils';
+import { getDevServerHostname } from '../utils/url-utils.js';
const remoteReduxDevServerConfig = {
port: 8043,
diff --git a/native/redux/dev-tools.react.js b/native/redux/dev-tools.react.js
--- a/native/redux/dev-tools.react.js
+++ b/native/redux/dev-tools.react.js
@@ -3,12 +3,12 @@
import * as React from 'react';
import { useDispatch } from 'react-redux';
-import { actionLogger } from 'lib/utils/action-logger';
+import { actionLogger } from 'lib/utils/action-logger.js';
-import { setNavStateActionType } from '../navigation/action-types';
-import { NavContext } from '../navigation/navigation-context';
-import { setReduxStateActionType } from './action-types';
-import { useSelector } from './redux-utils';
+import { setNavStateActionType } from '../navigation/action-types.js';
+import { NavContext } from '../navigation/navigation-context.js';
+import { setReduxStateActionType } from './action-types.js';
+import { useSelector } from './redux-utils.js';
const DevTools: React.ComponentType<{}> = React.memo<{}>(function DevTools() {
const devToolsRef = React.useRef();
diff --git a/native/redux/dimensions-updater.react.js b/native/redux/dimensions-updater.react.js
--- a/native/redux/dimensions-updater.react.js
+++ b/native/redux/dimensions-updater.react.js
@@ -8,16 +8,16 @@
} from 'react-native-safe-area-context';
import { useDispatch } from 'react-redux';
-import type { Dimensions } from 'lib/types/media-types';
+import type { Dimensions } from 'lib/types/media-types.js';
import {
addKeyboardShowListener,
addKeyboardDismissListener,
removeKeyboardListener,
rnsacThinksAndroidKeyboardResizesFrame,
-} from '../keyboard/keyboard';
-import { updateDimensionsActiveType } from './action-types';
-import { useSelector } from './redux-utils';
+} from '../keyboard/keyboard.js';
+import { updateDimensionsActiveType } from './action-types.js';
+import { useSelector } from './redux-utils.js';
type BaseDimensionsInfo = {
...Dimensions,
diff --git a/native/redux/edit-thread-permission-migration.js b/native/redux/edit-thread-permission-migration.js
--- a/native/redux/edit-thread-permission-migration.js
+++ b/native/redux/edit-thread-permission-migration.js
@@ -5,8 +5,8 @@
ThreadCurrentUserInfo,
RawThreadInfo,
RoleInfo,
-} from 'lib/types/thread-types';
-import { threadTypes } from 'lib/types/thread-types';
+} from 'lib/types/thread-types.js';
+import { threadTypes } from 'lib/types/thread-types.js';
function addDetailedThreadEditPermissionsToUser<
T: MemberInfo | ThreadCurrentUserInfo,
diff --git a/native/redux/persist.js b/native/redux/persist.js
--- a/native/redux/persist.js
+++ b/native/redux/persist.js
@@ -5,35 +5,38 @@
import { Platform } from 'react-native';
import Orientation from 'react-native-orientation-locker';
import { createMigrate, createTransform } from 'redux-persist';
-import type { Transform } from 'redux-persist/es/types';
+import type { Transform } from 'redux-persist/es/types.js';
-import { highestLocalIDSelector } from 'lib/selectors/local-id-selectors';
-import { inconsistencyResponsesToReports } from 'lib/shared/report-utils';
-import { getContainingThreadID, getCommunity } from 'lib/shared/thread-utils';
-import { unshimMessageStore, unshimFunc } from 'lib/shared/unshim-utils';
-import { defaultEnabledApps } from 'lib/types/enabled-apps';
-import { defaultCalendarFilters } from 'lib/types/filter-types';
+import { highestLocalIDSelector } from 'lib/selectors/local-id-selectors.js';
+import { inconsistencyResponsesToReports } from 'lib/shared/report-utils.js';
+import {
+ getContainingThreadID,
+ getCommunity,
+} from 'lib/shared/thread-utils.js';
+import { unshimMessageStore, unshimFunc } from 'lib/shared/unshim-utils.js';
+import { defaultEnabledApps } from 'lib/types/enabled-apps.js';
+import { defaultCalendarFilters } from 'lib/types/filter-types.js';
import {
type LocalMessageInfo,
type MessageStore,
messageTypes,
type ClientDBMessageStoreOperation,
-} from 'lib/types/message-types';
-import type { ClientDBMessageInfo } from 'lib/types/message-types';
-import { defaultConnectionInfo } from 'lib/types/socket-types';
+} from 'lib/types/message-types.js';
+import type { ClientDBMessageInfo } from 'lib/types/message-types.js';
+import { defaultConnectionInfo } from 'lib/types/socket-types.js';
import {
translateClientDBMessageInfoToRawMessageInfo,
translateRawMessageInfoToClientDBMessageInfo,
-} from 'lib/utils/message-ops-utils';
-import { convertThreadStoreOperationsToClientDBOperations } from 'lib/utils/thread-ops-utils';
+} from 'lib/utils/message-ops-utils.js';
+import { convertThreadStoreOperationsToClientDBOperations } from 'lib/utils/thread-ops-utils.js';
-import { commCoreModule } from '../native-modules';
-import { defaultNotifPermissionAlertInfo } from '../push/alerts';
-import { defaultDeviceCameraInfo } from '../types/camera';
-import { defaultGlobalThemeInfo } from '../types/themes';
-import { isTaskCancelledError } from '../utils/error-handling';
-import { migrateThreadStoreForEditThreadPermissions } from './edit-thread-permission-migration';
-import type { AppState } from './state-types';
+import { commCoreModule } from '../native-modules.js';
+import { defaultNotifPermissionAlertInfo } from '../push/alerts.js';
+import { defaultDeviceCameraInfo } from '../types/camera.js';
+import { defaultGlobalThemeInfo } from '../types/themes.js';
+import { isTaskCancelledError } from '../utils/error-handling.js';
+import { migrateThreadStoreForEditThreadPermissions } from './edit-thread-permission-migration.js';
+import type { AppState } from './state-types.js';
const migrations = {
[1]: (state: AppState) => ({
diff --git a/native/redux/redux-setup.js b/native/redux/redux-setup.js
--- a/native/redux/redux-setup.js
+++ b/native/redux/redux-setup.js
@@ -7,54 +7,54 @@
import { persistStore, persistReducer } from 'redux-persist';
import thunk from 'redux-thunk';
-import { setClientDBStoreActionType } from 'lib/actions/client-db-store-actions';
-import { setDeviceTokenActionTypes } from 'lib/actions/device-actions';
-import { siweAuthActionTypes } from 'lib/actions/siwe-actions';
+import { setClientDBStoreActionType } from 'lib/actions/client-db-store-actions.js';
+import { setDeviceTokenActionTypes } from 'lib/actions/device-actions.js';
+import { siweAuthActionTypes } from 'lib/actions/siwe-actions.js';
import {
logOutActionTypes,
deleteAccountActionTypes,
logInActionTypes,
-} from 'lib/actions/user-actions';
-import baseReducer from 'lib/reducers/master-reducer';
-import { processThreadStoreOperations } from 'lib/reducers/thread-reducer';
+} from 'lib/actions/user-actions.js';
+import baseReducer from 'lib/reducers/master-reducer.js';
+import { processThreadStoreOperations } from 'lib/reducers/thread-reducer.js';
import {
invalidSessionDowngrade,
invalidSessionRecovery,
-} from 'lib/shared/account-utils';
-import { isStaff } from 'lib/shared/user-utils';
-import { defaultEnabledApps } from 'lib/types/enabled-apps';
-import { defaultCalendarFilters } from 'lib/types/filter-types';
-import type { Dispatch, BaseAction } from 'lib/types/redux-types';
-import { rehydrateActionType } from 'lib/types/redux-types';
-import type { SetSessionPayload } from 'lib/types/session-types';
+} from 'lib/shared/account-utils.js';
+import { isStaff } from 'lib/shared/user-utils.js';
+import { defaultEnabledApps } from 'lib/types/enabled-apps.js';
+import { defaultCalendarFilters } from 'lib/types/filter-types.js';
+import type { Dispatch, BaseAction } from 'lib/types/redux-types.js';
+import { rehydrateActionType } from 'lib/types/redux-types.js';
+import type { SetSessionPayload } from 'lib/types/session-types.js';
import {
defaultConnectionInfo,
incrementalStateSyncActionType,
-} from 'lib/types/socket-types';
-import type { ThreadStoreOperation } from 'lib/types/thread-types';
-import { updateTypes } from 'lib/types/update-types';
-import { reduxLoggerMiddleware } from 'lib/utils/action-logger';
-import { setNewSessionActionType } from 'lib/utils/action-utils';
-import { convertMessageStoreOperationsToClientDBOperations } from 'lib/utils/message-ops-utils';
-import { convertThreadStoreOperationsToClientDBOperations } from 'lib/utils/thread-ops-utils';
+} from 'lib/types/socket-types.js';
+import type { ThreadStoreOperation } from 'lib/types/thread-types.js';
+import { updateTypes } from 'lib/types/update-types.js';
+import { reduxLoggerMiddleware } from 'lib/utils/action-logger.js';
+import { setNewSessionActionType } from 'lib/utils/action-utils.js';
+import { convertMessageStoreOperationsToClientDBOperations } from 'lib/utils/message-ops-utils.js';
+import { convertThreadStoreOperationsToClientDBOperations } from 'lib/utils/thread-ops-utils.js';
-import { commCoreModule } from '../native-modules';
-import { defaultNavInfo } from '../navigation/default-state';
-import { getGlobalNavContext } from '../navigation/icky-global';
-import { activeMessageListSelector } from '../navigation/nav-selectors';
-import { defaultNotifPermissionAlertInfo } from '../push/alerts';
-import reactotron from '../reactotron';
-import { defaultDeviceCameraInfo } from '../types/camera';
-import { defaultConnectivityInfo } from '../types/connectivity';
-import { defaultGlobalThemeInfo } from '../types/themes';
-import { isTaskCancelledError } from '../utils/error-handling';
-import { isStaffRelease } from '../utils/staff-utils';
+import { commCoreModule } from '../native-modules.js';
+import { defaultNavInfo } from '../navigation/default-state.js';
+import { getGlobalNavContext } from '../navigation/icky-global.js';
+import { activeMessageListSelector } from '../navigation/nav-selectors.js';
+import { defaultNotifPermissionAlertInfo } from '../push/alerts.js';
+import reactotron from '../reactotron.js';
+import { defaultDeviceCameraInfo } from '../types/camera.js';
+import { defaultConnectivityInfo } from '../types/connectivity.js';
+import { defaultGlobalThemeInfo } from '../types/themes.js';
+import { isTaskCancelledError } from '../utils/error-handling.js';
+import { isStaffRelease } from '../utils/staff-utils.js';
import {
defaultURLPrefix,
natNodeServer,
setCustomServer,
getDevServerHostname,
-} from '../utils/url-utils';
+} from '../utils/url-utils.js';
import {
resetUserStateActionType,
recordNotifPermissionAlertActionType,
@@ -68,11 +68,11 @@
setReduxStateActionType,
setStoreLoadedActionType,
type Action,
-} from './action-types';
-import { remoteReduxDevServerConfig } from './dev-tools';
-import { defaultDimensionsInfo } from './dimensions-updater.react';
-import { persistConfig, setPersistor } from './persist';
-import type { AppState } from './state-types';
+} from './action-types.js';
+import { remoteReduxDevServerConfig } from './dev-tools.js';
+import { defaultDimensionsInfo } from './dimensions-updater.react.js';
+import { persistConfig, setPersistor } from './persist.js';
+import type { AppState } from './state-types.js';
const defaultState = ({
navInfo: defaultNavInfo,
diff --git a/native/redux/redux-utils.js b/native/redux/redux-utils.js
--- a/native/redux/redux-utils.js
+++ b/native/redux/redux-utils.js
@@ -2,7 +2,7 @@
import { useSelector as reactReduxUseSelector } from 'react-redux';
-import type { AppState } from './state-types';
+import type { AppState } from './state-types.js';
function useSelector<SS>(
selector: (state: AppState) => SS,
diff --git a/native/redux/state-types.js b/native/redux/state-types.js
--- a/native/redux/state-types.js
+++ b/native/redux/state-types.js
@@ -1,27 +1,27 @@
// @flow
import type { Orientations } from 'react-native-orientation-locker';
-import type { PersistState } from 'redux-persist/src/types';
+import type { PersistState } from 'redux-persist/es/types.js';
-import type { DraftStore } from 'lib/types/draft-types';
-import type { EnabledApps } from 'lib/types/enabled-apps';
-import type { EntryStore } from 'lib/types/entry-types';
-import type { CalendarFilter } from 'lib/types/filter-types';
-import type { LifecycleState } from 'lib/types/lifecycle-state-types';
-import type { LoadingStatus } from 'lib/types/loading-types';
-import type { MessageStore } from 'lib/types/message-types';
-import type { UserPolicies } from 'lib/types/policy-types';
-import type { ReportStore } from 'lib/types/report-types';
-import type { ConnectionInfo } from 'lib/types/socket-types';
-import type { ThreadStore } from 'lib/types/thread-types';
-import type { CurrentUserInfo, UserStore } from 'lib/types/user-types';
+import type { DraftStore } from 'lib/types/draft-types.js';
+import type { EnabledApps } from 'lib/types/enabled-apps.js';
+import type { EntryStore } from 'lib/types/entry-types.js';
+import type { CalendarFilter } from 'lib/types/filter-types.js';
+import type { LifecycleState } from 'lib/types/lifecycle-state-types.js';
+import type { LoadingStatus } from 'lib/types/loading-types.js';
+import type { MessageStore } from 'lib/types/message-types.js';
+import type { UserPolicies } from 'lib/types/policy-types.js';
+import type { ReportStore } from 'lib/types/report-types.js';
+import type { ConnectionInfo } from 'lib/types/socket-types.js';
+import type { ThreadStore } from 'lib/types/thread-types.js';
+import type { CurrentUserInfo, UserStore } from 'lib/types/user-types.js';
-import type { NavInfo } from '../navigation/default-state';
-import type { NotifPermissionAlertInfo } from '../push/alerts';
-import type { DeviceCameraInfo } from '../types/camera';
-import type { ConnectivityInfo } from '../types/connectivity';
-import type { GlobalThemeInfo } from '../types/themes';
-import type { DimensionsInfo } from './dimensions-updater.react';
+import type { DimensionsInfo } from './dimensions-updater.react.js';
+import type { NavInfo } from '../navigation/default-state.js';
+import type { NotifPermissionAlertInfo } from '../push/alerts.js';
+import type { DeviceCameraInfo } from '../types/camera.js';
+import type { ConnectivityInfo } from '../types/connectivity.js';
+import type { GlobalThemeInfo } from '../types/themes.js';
export type AppState = {
navInfo: NavInfo,
diff --git a/native/root.react.js b/native/root.react.js
--- a/native/root.react.js
+++ b/native/root.react.js
@@ -18,38 +18,38 @@
import { Provider } from 'react-redux';
import { PersistGate as ReduxPersistGate } from 'redux-persist/integration/react';
-import { ENSCacheProvider } from 'lib/components/ens-cache-provider.react';
-import { actionLogger } from 'lib/utils/action-logger';
+import { ENSCacheProvider } from 'lib/components/ens-cache-provider.react.js';
+import { actionLogger } from 'lib/utils/action-logger.js';
-import ChatContextProvider from './chat/chat-context-provider.react';
-import PersistedStateGate from './components/persisted-state-gate';
-import ConnectedStatusBar from './connected-status-bar.react';
-import { SQLiteDataHandler } from './data/sqlite-data-handler';
-import ErrorBoundary from './error-boundary.react';
-import InputStateContainer from './input/input-state-container.react';
-import LifecycleHandler from './lifecycle/lifecycle-handler.react';
-import MarkdownContextProvider from './markdown/markdown-context-provider.react';
-import { defaultNavigationState } from './navigation/default-state';
-import DisconnectedBarVisibilityHandler from './navigation/disconnected-bar-visibility-handler.react';
-import { setGlobalNavContext } from './navigation/icky-global';
-import { NavContext } from './navigation/navigation-context';
-import NavigationHandler from './navigation/navigation-handler.react';
-import { validNavState } from './navigation/navigation-utils';
-import OrientationHandler from './navigation/orientation-handler.react';
-import { navStateAsyncStorageKey } from './navigation/persistance';
-import RootNavigator from './navigation/root-navigator.react';
-import ConnectivityUpdater from './redux/connectivity-updater.react';
-import { DimensionsUpdater } from './redux/dimensions-updater.react';
-import { getPersistor } from './redux/persist';
-import { store } from './redux/redux-setup';
-import { useSelector } from './redux/redux-utils';
-import { RootContext } from './root-context';
-import Socket from './socket.react';
-import { StaffContextProvider } from './staff/staff-context.provider.react';
-import { useLoadCommFonts } from './themes/fonts';
-import { DarkTheme, LightTheme } from './themes/navigation';
-import ThemeHandler from './themes/theme-handler.react';
-import { provider } from './utils/ethers-utils';
+import ChatContextProvider from './chat/chat-context-provider.react.js';
+import PersistedStateGate from './components/persisted-state-gate.js';
+import ConnectedStatusBar from './connected-status-bar.react.js';
+import { SQLiteDataHandler } from './data/sqlite-data-handler.js';
+import ErrorBoundary from './error-boundary.react.js';
+import InputStateContainer from './input/input-state-container.react.js';
+import LifecycleHandler from './lifecycle/lifecycle-handler.react.js';
+import MarkdownContextProvider from './markdown/markdown-context-provider.react.js';
+import { defaultNavigationState } from './navigation/default-state.js';
+import DisconnectedBarVisibilityHandler from './navigation/disconnected-bar-visibility-handler.react.js';
+import { setGlobalNavContext } from './navigation/icky-global.js';
+import { NavContext } from './navigation/navigation-context.js';
+import NavigationHandler from './navigation/navigation-handler.react.js';
+import { validNavState } from './navigation/navigation-utils.js';
+import OrientationHandler from './navigation/orientation-handler.react.js';
+import { navStateAsyncStorageKey } from './navigation/persistance.js';
+import RootNavigator from './navigation/root-navigator.react.js';
+import ConnectivityUpdater from './redux/connectivity-updater.react.js';
+import { DimensionsUpdater } from './redux/dimensions-updater.react.js';
+import { getPersistor } from './redux/persist.js';
+import { store } from './redux/redux-setup.js';
+import { useSelector } from './redux/redux-utils.js';
+import { RootContext } from './root-context.js';
+import Socket from './socket.react.js';
+import { StaffContextProvider } from './staff/staff-context.provider.react.js';
+import { useLoadCommFonts } from './themes/fonts.js';
+import { DarkTheme, LightTheme } from './themes/navigation.js';
+import ThemeHandler from './themes/theme-handler.react.js';
+import { provider } from './utils/ethers-utils.js';
if (Platform.OS === 'android') {
UIManager.setLayoutAnimationEnabledExperimental &&
diff --git a/native/schema/CommCoreModuleSchema.js b/native/schema/CommCoreModuleSchema.js
--- a/native/schema/CommCoreModuleSchema.js
+++ b/native/schema/CommCoreModuleSchema.js
@@ -3,20 +3,20 @@
'use strict';
import { TurboModuleRegistry } from 'react-native';
-import type { TurboModule } from 'react-native/Libraries/TurboModule/RCTExport';
+import type { TurboModule } from 'react-native/Libraries/TurboModule/RCTExport.js';
import type {
ClientDBDraftInfo,
ClientDBDraftStoreOperation,
-} from 'lib/types/draft-types';
+} from 'lib/types/draft-types.js';
import type {
ClientDBMessageInfo,
ClientDBMessageStoreOperation,
-} from 'lib/types/message-types';
+} from 'lib/types/message-types.js';
import type {
ClientDBThreadInfo,
ClientDBThreadStoreOperation,
-} from 'lib/types/thread-types';
+} from 'lib/types/thread-types.js';
type ClientDBStore = {
+messages: $ReadOnlyArray<ClientDBMessageInfo>,
diff --git a/native/selectors/account-selectors.js b/native/selectors/account-selectors.js
--- a/native/selectors/account-selectors.js
+++ b/native/selectors/account-selectors.js
@@ -2,15 +2,15 @@
import { createSelector } from 'reselect';
-import { logInExtraInfoSelector } from 'lib/selectors/account-selectors';
-import type { LogInExtraInfo } from 'lib/types/account-types';
-import type { UserPolicies } from 'lib/types/policy-types';
-import { values } from 'lib/utils/objects';
+import { logInExtraInfoSelector } from 'lib/selectors/account-selectors.js';
+import type { LogInExtraInfo } from 'lib/types/account-types.js';
+import type { UserPolicies } from 'lib/types/policy-types.js';
+import { values } from 'lib/utils/objects.js';
-import { calendarActiveSelector } from '../navigation/nav-selectors';
-import type { AppState } from '../redux/state-types';
-import type { ConnectivityInfo } from '../types/connectivity';
-import type { NavPlusRedux } from '../types/selector-types';
+import { calendarActiveSelector } from '../navigation/nav-selectors.js';
+import type { AppState } from '../redux/state-types.js';
+import type { ConnectivityInfo } from '../types/connectivity.js';
+import type { NavPlusRedux } from '../types/selector-types.js';
const nativeLogInExtraInfoSelector: (
input: NavPlusRedux,
diff --git a/native/selectors/calendar-selectors.js b/native/selectors/calendar-selectors.js
--- a/native/selectors/calendar-selectors.js
+++ b/native/selectors/calendar-selectors.js
@@ -5,13 +5,13 @@
import {
currentDaysToEntries,
threadInfoSelector,
-} from 'lib/selectors/thread-selectors';
-import { isLoggedIn } from 'lib/selectors/user-selectors';
-import type { EntryInfo } from 'lib/types/entry-types';
-import type { ThreadInfo } from 'lib/types/thread-types';
-import { dateString } from 'lib/utils/date-utils';
+} from 'lib/selectors/thread-selectors.js';
+import { isLoggedIn } from 'lib/selectors/user-selectors.js';
+import type { EntryInfo } from 'lib/types/entry-types.js';
+import type { ThreadInfo } from 'lib/types/thread-types.js';
+import { dateString } from 'lib/utils/date-utils.js';
-import type { AppState } from '../redux/state-types';
+import type { AppState } from '../redux/state-types.js';
export type SectionHeaderItem = {
itemType: 'header',
diff --git a/native/selectors/dimensions-selectors.js b/native/selectors/dimensions-selectors.js
--- a/native/selectors/dimensions-selectors.js
+++ b/native/selectors/dimensions-selectors.js
@@ -2,8 +2,8 @@
import { createSelector } from 'reselect';
-import { type DimensionsInfo } from '../redux/dimensions-updater.react';
-import type { AppState } from '../redux/state-types';
+import { type DimensionsInfo } from '../redux/dimensions-updater.react.js';
+import type { AppState } from '../redux/state-types.js';
export type DerivedDimensionsInfo = {
...DimensionsInfo,
diff --git a/native/selectors/message-selectors.js b/native/selectors/message-selectors.js
--- a/native/selectors/message-selectors.js
+++ b/native/selectors/message-selectors.js
@@ -2,12 +2,12 @@
import { createSelector } from 'reselect';
-import { threadIsPending } from 'lib/shared/thread-utils';
-import type { ThreadMessageInfo } from 'lib/types/message-types';
+import { threadIsPending } from 'lib/shared/thread-utils.js';
+import type { ThreadMessageInfo } from 'lib/types/message-types.js';
-import { activeThreadSelector } from '../navigation/nav-selectors';
-import type { AppState } from '../redux/state-types';
-import type { NavPlusRedux } from '../types/selector-types';
+import { activeThreadSelector } from '../navigation/nav-selectors.js';
+import type { AppState } from '../redux/state-types.js';
+import type { NavPlusRedux } from '../types/selector-types.js';
const msInHour = 60 * 60 * 1000;
diff --git a/native/selectors/socket-selectors.js b/native/selectors/socket-selectors.js
--- a/native/selectors/socket-selectors.js
+++ b/native/selectors/socket-selectors.js
@@ -5,21 +5,21 @@
import {
getClientResponsesSelector,
sessionStateFuncSelector,
-} from 'lib/selectors/socket-selectors';
-import { createOpenSocketFunction } from 'lib/shared/socket-utils';
+} from 'lib/selectors/socket-selectors.js';
+import { createOpenSocketFunction } from 'lib/shared/socket-utils.js';
import type {
ClientServerRequest,
ClientClientResponse,
-} from 'lib/types/request-types';
+} from 'lib/types/request-types.js';
import type {
SessionIdentification,
SessionState,
-} from 'lib/types/session-types';
-import type { OneTimeKeyGenerator } from 'lib/types/socket-types';
+} from 'lib/types/session-types.js';
+import type { OneTimeKeyGenerator } from 'lib/types/socket-types.js';
-import { calendarActiveSelector } from '../navigation/nav-selectors';
-import type { AppState } from '../redux/state-types';
-import type { NavPlusRedux } from '../types/selector-types';
+import { calendarActiveSelector } from '../navigation/nav-selectors.js';
+import type { AppState } from '../redux/state-types.js';
+import type { NavPlusRedux } from '../types/selector-types.js';
const openSocketSelector: (state: AppState) => () => WebSocket = createSelector(
(state: AppState) => state.urlPrefix,
diff --git a/native/socket.react.js b/native/socket.react.js
--- a/native/socket.react.js
+++ b/native/socket.react.js
@@ -1,35 +1,35 @@
// @flow
import * as React from 'react';
-import Alert from 'react-native/Libraries/Alert/Alert';
+import Alert from 'react-native/Libraries/Alert/Alert.js';
import { useDispatch } from 'react-redux';
-import { logOut, logOutActionTypes } from 'lib/actions/user-actions';
-import { preRequestUserStateSelector } from 'lib/selectors/account-selectors';
-import { isLoggedIn } from 'lib/selectors/user-selectors';
-import { accountHasPassword } from 'lib/shared/account-utils';
-import Socket, { type BaseSocketProps } from 'lib/socket/socket.react';
-import { logInActionSources } from 'lib/types/account-types';
+import { logOut, logOutActionTypes } from 'lib/actions/user-actions.js';
+import { preRequestUserStateSelector } from 'lib/selectors/account-selectors.js';
+import { isLoggedIn } from 'lib/selectors/user-selectors.js';
+import { accountHasPassword } from 'lib/shared/account-utils.js';
+import Socket, { type BaseSocketProps } from 'lib/socket/socket.react.js';
+import { logInActionSources } from 'lib/types/account-types.js';
import {
useServerCall,
useDispatchActionPromise,
fetchNewCookieFromNativeCredentials,
-} from 'lib/utils/action-utils';
+} from 'lib/utils/action-utils.js';
-import { InputStateContext } from './input/input-state';
+import { InputStateContext } from './input/input-state.js';
import {
activeMessageListSelector,
nativeCalendarQuery,
-} from './navigation/nav-selectors';
-import { NavContext } from './navigation/navigation-context';
-import { useSelector } from './redux/redux-utils';
-import { noDataAfterPolicyAcknowledgmentSelector } from './selectors/account-selectors';
+} from './navigation/nav-selectors.js';
+import { NavContext } from './navigation/navigation-context.js';
+import { useSelector } from './redux/redux-utils.js';
+import { noDataAfterPolicyAcknowledgmentSelector } from './selectors/account-selectors.js';
import {
openSocketSelector,
sessionIdentificationSelector,
nativeGetClientResponsesSelector,
nativeSessionStateFuncSelector,
-} from './selectors/socket-selectors';
+} from './selectors/socket-selectors.js';
const NativeSocket: React.ComponentType<BaseSocketProps> = React.memo<BaseSocketProps>(
function NativeSocket(props: BaseSocketProps) {
diff --git a/native/splash.js b/native/splash.js
--- a/native/splash.js
+++ b/native/splash.js
@@ -3,9 +3,9 @@
import { Platform, PixelRatio } from 'react-native';
import { createSelector } from 'reselect';
-import type { DimensionsInfo } from './redux/dimensions-updater.react';
-import type { AppState } from './redux/state-types';
-import type { ImageStyle } from './types/styles';
+import type { DimensionsInfo } from './redux/dimensions-updater.react.js';
+import type { AppState } from './redux/state-types.js';
+import type { ImageStyle } from './types/styles.js';
const splashStyleSelector: (state: AppState) => ImageStyle = createSelector(
(state: AppState) => state.dimensions,
diff --git a/native/staff/staff-context.provider.react.js b/native/staff/staff-context.provider.react.js
--- a/native/staff/staff-context.provider.react.js
+++ b/native/staff/staff-context.provider.react.js
@@ -2,8 +2,8 @@
import * as React from 'react';
-import { useIsCurrentUserStaff } from '../utils/staff-utils';
-import { StaffContext, type StaffContextType } from './staff-context';
+import { useIsCurrentUserStaff } from '../utils/staff-utils.js';
+import { StaffContext, type StaffContextType } from './staff-context.js';
type Props = {
+children: React.Node,
diff --git a/native/themes/colors.js b/native/themes/colors.js
--- a/native/themes/colors.js
+++ b/native/themes/colors.js
@@ -4,11 +4,11 @@
import { StyleSheet } from 'react-native';
import { createSelector } from 'reselect';
-import { selectBackgroundIsDark } from '../navigation/nav-selectors';
-import { NavContext } from '../navigation/navigation-context';
-import { useSelector } from '../redux/redux-utils';
-import type { AppState } from '../redux/state-types';
-import type { GlobalTheme } from '../types/themes';
+import { selectBackgroundIsDark } from '../navigation/nav-selectors.js';
+import { NavContext } from '../navigation/navigation-context.js';
+import { useSelector } from '../redux/redux-utils.js';
+import type { AppState } from '../redux/state-types.js';
+import type { GlobalTheme } from '../types/themes.js';
const light = Object.freeze({
blockQuoteBackground: '#E0E0E0',
diff --git a/native/themes/fonts.js b/native/themes/fonts.js
--- a/native/themes/fonts.js
+++ b/native/themes/fonts.js
@@ -1,12 +1,12 @@
// @flow
-import EntypoIcon from '@expo/vector-icons/Entypo';
-import Feather from '@expo/vector-icons/Feather';
-import FontAwesome from '@expo/vector-icons/FontAwesome';
-import FontAwesome5 from '@expo/vector-icons/FontAwesome5';
-import Ionicons from '@expo/vector-icons/Ionicons';
-import MaterialCommunityIcons from '@expo/vector-icons/MaterialCommunityIcons';
-import MaterialIcon from '@expo/vector-icons/MaterialIcons';
+import EntypoIcon from '@expo/vector-icons/Entypo.js';
+import Feather from '@expo/vector-icons/Feather.js';
+import FontAwesome from '@expo/vector-icons/FontAwesome.js';
+import FontAwesome5 from '@expo/vector-icons/FontAwesome5.js';
+import Ionicons from '@expo/vector-icons/Ionicons.js';
+import MaterialCommunityIcons from '@expo/vector-icons/MaterialCommunityIcons.js';
+import MaterialIcon from '@expo/vector-icons/MaterialIcons.js';
import { useFonts } from 'expo-font';
import CommIcons from '../fonts/CommIcons.ttf';
diff --git a/native/themes/navigation.js b/native/themes/navigation.js
--- a/native/themes/navigation.js
+++ b/native/themes/navigation.js
@@ -5,7 +5,7 @@
DarkTheme as DefaultDarkTheme,
} from '@react-navigation/native';
-import { colors } from './colors';
+import { colors } from './colors.js';
const DarkTheme = {
...DefaultDarkTheme,
diff --git a/native/themes/theme-handler.react.js b/native/themes/theme-handler.react.js
--- a/native/themes/theme-handler.react.js
+++ b/native/themes/theme-handler.react.js
@@ -5,15 +5,15 @@
import { Appearance } from 'react-native';
import { useDispatch } from 'react-redux';
-import type { Shape } from 'lib/types/core';
+import type { Shape } from 'lib/types/core.js';
-import { updateThemeInfoActionType } from '../redux/action-types';
-import { useSelector } from '../redux/redux-utils';
+import { updateThemeInfoActionType } from '../redux/action-types.js';
+import { useSelector } from '../redux/redux-utils.js';
import {
type GlobalTheme,
type GlobalThemeInfo,
osCanTheme,
-} from '../types/themes';
+} from '../types/themes.js';
function ThemeHandler(): null {
const globalThemeInfo = useSelector(state => state.globalThemeInfo);
diff --git a/native/tooltip/tooltip-context.react.js b/native/tooltip/tooltip-context.react.js
--- a/native/tooltip/tooltip-context.react.js
+++ b/native/tooltip/tooltip-context.react.js
@@ -4,7 +4,7 @@
import * as React from 'react';
import { Platform, StyleSheet } from 'react-native';
-import type { TooltipItemBaseProps } from './tooltip-item.react';
+import type { TooltipItemBaseProps } from './tooltip-item.react.js';
type RegisterOptionInput = {
...TooltipItemBaseProps,
diff --git a/native/tooltip/tooltip-hooks.js b/native/tooltip/tooltip-hooks.js
--- a/native/tooltip/tooltip-hooks.js
+++ b/native/tooltip/tooltip-hooks.js
@@ -2,8 +2,8 @@
import * as React from 'react';
-import type { AppNavigationProp } from '../navigation/app-navigator.react';
-import type { TooltipModalParamList } from '../navigation/route-names';
+import type { AppNavigationProp } from '../navigation/app-navigator.react.js';
+import type { TooltipModalParamList } from '../navigation/route-names.js';
type TooltipActions = {
// Hiding will keep the Tooltip ReactNav screen open, which means that the
diff --git a/native/tooltip/tooltip-item.react.js b/native/tooltip/tooltip-item.react.js
--- a/native/tooltip/tooltip-item.react.js
+++ b/native/tooltip/tooltip-item.react.js
@@ -4,10 +4,10 @@
import * as React from 'react';
import { TouchableOpacity } from 'react-native';
-import { SingleLine } from '../components/single-line.react';
-import { useStyles } from '../themes/colors';
-import type { ViewStyle, TextStyle } from '../types/styles';
-import { TooltipContext } from './tooltip-context.react';
+import { SingleLine } from '../components/single-line.react.js';
+import { useStyles } from '../themes/colors.js';
+import type { ViewStyle, TextStyle } from '../types/styles.js';
+import { TooltipContext } from './tooltip-context.react.js';
export type TooltipItemBaseProps = {
+id: string,
diff --git a/native/tooltip/tooltip.react.js b/native/tooltip/tooltip.react.js
--- a/native/tooltip/tooltip.react.js
+++ b/native/tooltip/tooltip.react.js
@@ -12,31 +12,31 @@
} from 'react-native';
import Animated, { SlideInDown, SlideOutDown } from 'react-native-reanimated';
-import { ChatContext, type ChatContextType } from '../chat/chat-context';
-import SWMansionIcon from '../components/swmansion-icon.react';
-import type { AppNavigationProp } from '../navigation/app-navigator.react';
+import { ChatContext, type ChatContextType } from '../chat/chat-context.js';
+import SWMansionIcon from '../components/swmansion-icon.react.js';
+import type { AppNavigationProp } from '../navigation/app-navigator.react.js';
import {
OverlayContext,
type OverlayContextType,
-} from '../navigation/overlay-context';
-import type { TooltipModalParamList } from '../navigation/route-names';
-import { type DimensionsInfo } from '../redux/dimensions-updater.react';
-import { useSelector } from '../redux/redux-utils';
-import { useStyles } from '../themes/colors';
+} from '../navigation/overlay-context.js';
+import type { TooltipModalParamList } from '../navigation/route-names.js';
+import { type DimensionsInfo } from '../redux/dimensions-updater.react.js';
+import { useSelector } from '../redux/redux-utils.js';
+import { useStyles } from '../themes/colors.js';
import {
type VerticalBounds,
type LayoutCoordinates,
-} from '../types/layout-types';
-import type { LayoutEvent } from '../types/react-native';
-import { AnimatedView } from '../types/styles';
+} from '../types/layout-types.js';
+import type { LayoutEvent } from '../types/react-native.js';
+import { AnimatedView } from '../types/styles.js';
import {
TooltipContextProvider,
TooltipContext,
type TooltipContextType,
-} from './tooltip-context.react';
+} from './tooltip-context.react.js';
import BaseTooltipItem, {
type TooltipItemBaseProps,
-} from './tooltip-item.react';
+} from './tooltip-item.react.js';
/* eslint-disable import/no-named-as-default-member */
const { Value, Node, Extrapolate, add, multiply, interpolateNode } = Animated;
diff --git a/native/types/chat-types.js b/native/types/chat-types.js
--- a/native/types/chat-types.js
+++ b/native/types/chat-types.js
@@ -1,16 +1,16 @@
// @flow
-import type { MessageReactionInfo } from 'lib/selectors/chat-selectors';
+import type { MessageReactionInfo } from 'lib/selectors/chat-selectors.js';
import type {
LocalMessageInfo,
MultimediaMessageInfo,
RobotextMessageInfo,
-} from 'lib/types/message-types';
-import type { TextMessageInfo } from 'lib/types/messages/text';
-import type { ThreadInfo } from 'lib/types/thread-types';
-import type { EntityText } from 'lib/utils/entity-text';
+} from 'lib/types/message-types.js';
+import type { TextMessageInfo } from 'lib/types/messages/text.js';
+import type { ThreadInfo } from 'lib/types/thread-types.js';
+import type { EntityText } from 'lib/utils/entity-text.js';
-import type { MessagePendingUploads } from '../input/input-state';
+import type { MessagePendingUploads } from '../input/input-state.js';
export type ChatRobotextMessageInfoItemWithHeight = {
+itemType: 'message',
diff --git a/native/types/react-native.js b/native/types/react-native.js
--- a/native/types/react-native.js
+++ b/native/types/react-native.js
@@ -1,7 +1,7 @@
// @flow
-import type ReactNativeAnimatedValue from 'react-native/Libraries/Animated/nodes/AnimatedValue';
-import type { ViewToken } from 'react-native/Libraries/Lists/ViewabilityHelper';
+import type ReactNativeAnimatedValue from 'react-native/Libraries/Animated/nodes/AnimatedValue.js';
+import type { ViewToken } from 'react-native/Libraries/Lists/ViewabilityHelper.js';
export type {
Layout,
diff --git a/native/types/selector-types.js b/native/types/selector-types.js
--- a/native/types/selector-types.js
+++ b/native/types/selector-types.js
@@ -1,7 +1,7 @@
// @flow
-import type { NavContextType } from '../navigation/navigation-context';
-import type { AppState } from '../redux/state-types';
+import type { NavContextType } from '../navigation/navigation-context.js';
+import type { AppState } from '../redux/state-types.js';
export type NavPlusRedux = {
+redux: AppState,
diff --git a/native/utils/android-permissions.js b/native/utils/android-permissions.js
--- a/native/utils/android-permissions.js
+++ b/native/utils/android-permissions.js
@@ -2,8 +2,8 @@
import { PermissionsAndroid } from 'react-native';
-import { getMessageForException } from 'lib/utils/errors';
-import { promiseAll } from 'lib/utils/promises';
+import { getMessageForException } from 'lib/utils/errors.js';
+import { promiseAll } from 'lib/utils/promises.js';
const granted = new Set();
diff --git a/native/utils/animation-utils.js b/native/utils/animation-utils.js
--- a/native/utils/animation-utils.js
+++ b/native/utils/animation-utils.js
@@ -10,7 +10,7 @@
type TimingConfig,
} from 'react-native-reanimated';
-import type { Shape } from 'lib/types/core';
+import type { Shape } from 'lib/types/core.js';
/* eslint-disable import/no-named-as-default-member */
const {
diff --git a/native/utils/crash-utils.js b/native/utils/crash-utils.js
--- a/native/utils/crash-utils.js
+++ b/native/utils/crash-utils.js
@@ -3,10 +3,10 @@
import AsyncStorage from '@react-native-async-storage/async-storage';
import ExitApp from 'react-native-exit-app';
-import sleep from 'lib/utils/sleep';
+import sleep from 'lib/utils/sleep.js';
-import { navStateAsyncStorageKey } from '../navigation/persistance';
-import { getPersistor } from '../redux/persist';
+import { navStateAsyncStorageKey } from '../navigation/persistance.js';
+import { getPersistor } from '../redux/persist.js';
async function wipeAndExit() {
await Promise.all([
diff --git a/native/utils/ethers-utils.js b/native/utils/ethers-utils.js
--- a/native/utils/ethers-utils.js
+++ b/native/utils/ethers-utils.js
@@ -4,7 +4,7 @@
import { ethers } from 'ethers';
-import type { EthersProvider } from 'lib/utils/ens-cache';
+import type { EthersProvider } from 'lib/utils/ens-cache.js';
let alchemyKey;
try {
diff --git a/native/utils/staff-utils.js b/native/utils/staff-utils.js
--- a/native/utils/staff-utils.js
+++ b/native/utils/staff-utils.js
@@ -2,7 +2,7 @@
import { useSelector } from 'react-redux';
-import { isStaff } from 'lib/shared/user-utils';
+import { isStaff } from 'lib/shared/user-utils.js';
const isStaffRelease = false;
diff --git a/native/utils/typeahead-utils.js b/native/utils/typeahead-utils.js
--- a/native/utils/typeahead-utils.js
+++ b/native/utils/typeahead-utils.js
@@ -1,6 +1,6 @@
// @flow
-import { oldValidUsernameRegexString } from 'lib/shared/account-utils';
+import { oldValidUsernameRegexString } from 'lib/shared/account-utils.js';
// Native regex is a little bit different than web one as
// there are no named capturing groups yet on native.
diff --git a/native/utils/url-utils.js b/native/utils/url-utils.js
--- a/native/utils/url-utils.js
+++ b/native/utils/url-utils.js
@@ -4,7 +4,10 @@
import { Platform } from 'react-native';
import DeviceInfo from 'react-native-device-info';
-import { natDevHostname, checkForMissingNatDevHostname } from './dev-hostname';
+import {
+ natDevHostname,
+ checkForMissingNatDevHostname,
+} from './dev-hostname.js';
const localhostHostname = 'localhost';
const localhostHostnameFromAndroidEmulator = '10.0.2.2';
diff --git a/web/account/password-input.react.js b/web/account/password-input.react.js
--- a/web/account/password-input.react.js
+++ b/web/account/password-input.react.js
@@ -6,8 +6,8 @@
type Icon,
} from 'lib/components/SWMansionIcon.react.js';
-import Button from '../components/button.react';
-import Input, { type BaseInputProps } from '../modals/input.react';
+import Button from '../components/button.react.js';
+import Input, { type BaseInputProps } from '../modals/input.react.js';
import css from './password-input.css';
type PasswordInputProps = BaseInputProps;
diff --git a/web/account/siwe-button.react.js b/web/account/siwe-button.react.js
--- a/web/account/siwe-button.react.js
+++ b/web/account/siwe-button.react.js
@@ -3,7 +3,7 @@
import * as React from 'react';
import { FaEthereum } from 'react-icons/fa';
-import Button from '../components/button.react';
+import Button from '../components/button.react.js';
import css from './siwe.css';
type SIWEButtonProps = {
diff --git a/web/account/siwe-login-form.react.js b/web/account/siwe-login-form.react.js
--- a/web/account/siwe-login-form.react.js
+++ b/web/account/siwe-login-form.react.js
@@ -13,26 +13,26 @@
getSIWENonceActionTypes,
siweAuth,
siweAuthActionTypes,
-} from 'lib/actions/siwe-actions';
+} from 'lib/actions/siwe-actions.js';
import ConnectedWalletInfo from 'lib/components/connected-wallet-info.react.js';
import SWMansionIcon from 'lib/components/SWMansionIcon.react.js';
-import { createLoadingStatusSelector } from 'lib/selectors/loading-selectors';
+import { createLoadingStatusSelector } from 'lib/selectors/loading-selectors.js';
import type { LogInStartingPayload } from 'lib/types/account-types.js';
import {
useDispatchActionPromise,
useServerCall,
-} from 'lib/utils/action-utils';
+} from 'lib/utils/action-utils.js';
import {
createSIWEMessage,
getSIWEStatementForPublicKey,
siweMessageSigningExplanationStatements,
} from 'lib/utils/siwe-utils.js';
-import Button from '../components/button.react';
+import Button from '../components/button.react.js';
import OrBreak from '../components/or-break.react.js';
-import LoadingIndicator from '../loading-indicator.react';
-import { setPrimaryIdentityPublicKey } from '../redux/primary-identity-public-key-reducer';
-import { useSelector } from '../redux/redux-utils';
+import LoadingIndicator from '../loading-indicator.react.js';
+import { setPrimaryIdentityPublicKey } from '../redux/primary-identity-public-key-reducer.js';
+import { useSelector } from '../redux/redux-utils.js';
import { webLogInExtraInfoSelector } from '../selectors/account-selectors.js';
import HeaderSeparator from './header-separator.react.js';
import css from './siwe.css';
diff --git a/web/app.react.js b/web/app.react.js
--- a/web/app.react.js
+++ b/web/app.react.js
@@ -4,7 +4,7 @@
import './theme.css';
import { config as faConfig } from '@fortawesome/fontawesome-svg-core';
import classnames from 'classnames';
-import _isEqual from 'lodash/fp/isEqual';
+import _isEqual from 'lodash/fp/isEqual.js';
import * as React from 'react';
import { DndProvider } from 'react-dnd';
import { HTML5Backend } from 'react-dnd-html5-backend';
@@ -14,50 +14,50 @@
import {
fetchEntriesActionTypes,
updateCalendarQueryActionTypes,
-} from 'lib/actions/entry-actions';
+} from 'lib/actions/entry-actions.js';
import {
ModalProvider,
useModalContext,
-} from 'lib/components/modal-provider.react';
+} from 'lib/components/modal-provider.react.js';
import {
createLoadingStatusSelector,
combineLoadingStatuses,
-} from 'lib/selectors/loading-selectors';
-import { unreadCount } from 'lib/selectors/thread-selectors';
-import { isLoggedIn } from 'lib/selectors/user-selectors';
-import type { LoadingStatus } from 'lib/types/loading-types';
-import type { Dispatch } from 'lib/types/redux-types';
-import { registerConfig } from 'lib/utils/config';
+} from 'lib/selectors/loading-selectors.js';
+import { unreadCount } from 'lib/selectors/thread-selectors.js';
+import { isLoggedIn } from 'lib/selectors/user-selectors.js';
+import type { LoadingStatus } from 'lib/types/loading-types.js';
+import type { Dispatch } from 'lib/types/redux-types.js';
+import { registerConfig } from 'lib/utils/config.js';
-import AppsDirectory from './apps/apps-directory.react';
-import Calendar from './calendar/calendar.react';
-import Chat from './chat/chat.react';
-import { TooltipProvider } from './chat/tooltip-provider';
-import NavigationArrows from './components/navigation-arrows.react';
-import electron from './electron';
-import InputStateContainer from './input/input-state-container.react';
-import LoadingIndicator from './loading-indicator.react';
-import { MenuProvider } from './menu-provider.react';
-import UpdateModalHandler from './modals/update-modal.react';
-import { updateNavInfoActionType } from './redux/action-types';
-import DeviceIDUpdater from './redux/device-id-updater';
-import DisconnectedBar from './redux/disconnected-bar';
-import DisconnectedBarVisibilityHandler from './redux/disconnected-bar-visibility-handler';
-import FocusHandler from './redux/focus-handler.react';
+import AppsDirectory from './apps/apps-directory.react.js';
+import Calendar from './calendar/calendar.react.js';
+import Chat from './chat/chat.react.js';
+import { TooltipProvider } from './chat/tooltip-provider.js';
+import NavigationArrows from './components/navigation-arrows.react.js';
+import electron from './electron.js';
+import InputStateContainer from './input/input-state-container.react.js';
+import LoadingIndicator from './loading-indicator.react.js';
+import { MenuProvider } from './menu-provider.react.js';
+import UpdateModalHandler from './modals/update-modal.react.js';
+import { updateNavInfoActionType } from './redux/action-types.js';
+import DeviceIDUpdater from './redux/device-id-updater.js';
+import DisconnectedBarVisibilityHandler from './redux/disconnected-bar-visibility-handler.js';
+import DisconnectedBar from './redux/disconnected-bar.js';
+import FocusHandler from './redux/focus-handler.react.js';
import PolicyAcknowledgmentHandler from './redux/policy-acknowledgment-handler.js';
-import { useSelector } from './redux/redux-utils';
-import VisibilityHandler from './redux/visibility-handler.react';
-import history from './router-history';
-import AccountSettings from './settings/account-settings.react';
-import DangerZone from './settings/danger-zone.react';
-import LeftLayoutAside from './sidebar/left-layout-aside.react';
-import Splash from './splash/splash.react';
+import { useSelector } from './redux/redux-utils.js';
+import VisibilityHandler from './redux/visibility-handler.react.js';
+import history from './router-history.js';
+import AccountSettings from './settings/account-settings.react.js';
+import DangerZone from './settings/danger-zone.react.js';
+import LeftLayoutAside from './sidebar/left-layout-aside.react.js';
+import Splash from './splash/splash.react.js';
import './typography.css';
import css from './style.css';
-import getTitle from './title/getTitle';
-import { type NavInfo } from './types/nav-types';
-import { canonicalURLFromReduxState, navInfoFromURL } from './url-utils';
-import { WagmiENSCacheProvider, wagmiClient } from './utils/wagmi-utils';
+import getTitle from './title/getTitle.js';
+import { type NavInfo } from './types/nav-types.js';
+import { canonicalURLFromReduxState, navInfoFromURL } from './url-utils.js';
+import { WagmiENSCacheProvider, wagmiClient } from './utils/wagmi-utils.js';
// We want Webpack's css-loader and style-loader to handle the Fontawesome CSS,
// so we disable the autoAddCss logic and import the CSS file. Otherwise every
diff --git a/web/apps/app-listing.react.js b/web/apps/app-listing.react.js
--- a/web/apps/app-listing.react.js
+++ b/web/apps/app-listing.react.js
@@ -11,10 +11,10 @@
import {
disableAppActionType,
enableAppActionType,
-} from 'lib/reducers/enabled-apps-reducer';
-import type { SupportedApps } from 'lib/types/enabled-apps';
+} from 'lib/reducers/enabled-apps-reducer.js';
+import type { SupportedApps } from 'lib/types/enabled-apps.js';
-import Button from '../components/button.react';
+import Button from '../components/button.react.js';
import css from './apps.css';
type Props = {
diff --git a/web/apps/apps-directory.react.js b/web/apps/apps-directory.react.js
--- a/web/apps/apps-directory.react.js
+++ b/web/apps/apps-directory.react.js
@@ -3,7 +3,7 @@
import * as React from 'react';
import { useSelector } from 'react-redux';
-import AppListing from './app-listing.react';
+import AppListing from './app-listing.react.js';
import css from './apps.css';
const APP_DIRECTORY_DATA = [
diff --git a/web/calendar/calendar.react.js b/web/calendar/calendar.react.js
--- a/web/calendar/calendar.react.js
+++ b/web/calendar/calendar.react.js
@@ -9,39 +9,39 @@
import {
updateCalendarQueryActionTypes,
updateCalendarQuery,
-} from 'lib/actions/entry-actions';
+} from 'lib/actions/entry-actions.js';
import SWMansionIcon from 'lib/components/SWMansionIcon.react.js';
-import { currentDaysToEntries } from 'lib/selectors/thread-selectors';
-import { isLoggedIn } from 'lib/selectors/user-selectors';
+import { currentDaysToEntries } from 'lib/selectors/thread-selectors.js';
+import { isLoggedIn } from 'lib/selectors/user-selectors.js';
import {
type EntryInfo,
type CalendarQuery,
type CalendarQueryUpdateResult,
type CalendarQueryUpdateStartingPayload,
-} from 'lib/types/entry-types';
+} from 'lib/types/entry-types.js';
import {
type DispatchActionPromise,
useDispatchActionPromise,
useServerCall,
-} from 'lib/utils/action-utils';
+} from 'lib/utils/action-utils.js';
import {
getDate,
dateString,
startDateForYearAndMonth,
endDateForYearAndMonth,
-} from 'lib/utils/date-utils';
+} from 'lib/utils/date-utils.js';
-import { useSelector } from '../redux/redux-utils';
+import { useSelector } from '../redux/redux-utils.js';
import {
yearAssertingSelector,
monthAssertingSelector,
webCalendarQuery,
-} from '../selectors/nav-selectors';
-import type { NavInfo } from '../types/nav-types';
-import { canonicalURLFromReduxState } from '../url-utils';
+} from '../selectors/nav-selectors.js';
+import type { NavInfo } from '../types/nav-types.js';
+import { canonicalURLFromReduxState } from '../url-utils.js';
import css from './calendar.css';
-import Day from './day.react';
-import FilterPanel from './filter-panel.react';
+import Day from './day.react.js';
+import FilterPanel from './filter-panel.react.js';
type BaseProps = {
+url: string,
diff --git a/web/calendar/day.react.js b/web/calendar/day.react.js
--- a/web/calendar/day.react.js
+++ b/web/calendar/day.react.js
@@ -2,34 +2,34 @@
import classNames from 'classnames';
import invariant from 'invariant';
-import _some from 'lodash/fp/some';
+import _some from 'lodash/fp/some.js';
import * as React from 'react';
import { useDispatch } from 'react-redux';
import {
createLocalEntry,
createLocalEntryActionType,
-} from 'lib/actions/entry-actions';
+} from 'lib/actions/entry-actions.js';
import {
useModalContext,
type PushModal,
-} from 'lib/components/modal-provider.react';
-import { onScreenThreadInfos as onScreenThreadInfosSelector } from 'lib/selectors/thread-selectors';
-import { entryKey } from 'lib/shared/entry-utils';
-import type { EntryInfo } from 'lib/types/entry-types';
-import type { Dispatch } from 'lib/types/redux-types';
-import type { ThreadInfo } from 'lib/types/thread-types';
-import { dateString, dateFromString } from 'lib/utils/date-utils';
+} from 'lib/components/modal-provider.react.js';
+import { onScreenThreadInfos as onScreenThreadInfosSelector } from 'lib/selectors/thread-selectors.js';
+import { entryKey } from 'lib/shared/entry-utils.js';
+import type { EntryInfo } from 'lib/types/entry-types.js';
+import type { Dispatch } from 'lib/types/redux-types.js';
+import type { ThreadInfo } from 'lib/types/thread-types.js';
+import { dateString, dateFromString } from 'lib/utils/date-utils.js';
-import LogInFirstModal from '../modals/account/log-in-first-modal.react';
-import HistoryModal from '../modals/history/history-modal.react';
-import ThreadPickerModal from '../modals/threads/thread-picker-modal.react';
-import { useSelector } from '../redux/redux-utils';
-import { htmlTargetFromEvent } from '../vector-utils';
-import { AddVector, HistoryVector } from '../vectors.react';
+import LogInFirstModal from '../modals/account/log-in-first-modal.react.js';
+import HistoryModal from '../modals/history/history-modal.react.js';
+import ThreadPickerModal from '../modals/threads/thread-picker-modal.react.js';
+import { useSelector } from '../redux/redux-utils.js';
+import { htmlTargetFromEvent } from '../vector-utils.js';
+import { AddVector, HistoryVector } from '../vectors.react.js';
import css from './calendar.css';
-import type { InnerEntry } from './entry.react';
-import Entry from './entry.react';
+import type { InnerEntry } from './entry.react.js';
+import Entry from './entry.react.js';
type BaseProps = {
+dayString: string,
diff --git a/web/calendar/entry.react.js b/web/calendar/entry.react.js
--- a/web/calendar/entry.react.js
+++ b/web/calendar/entry.react.js
@@ -13,15 +13,15 @@
deleteEntryActionTypes,
deleteEntry,
concurrentModificationResetActionType,
-} from 'lib/actions/entry-actions';
+} from 'lib/actions/entry-actions.js';
import {
useModalContext,
type PushModal,
-} from 'lib/components/modal-provider.react';
-import { threadInfoSelector } from 'lib/selectors/thread-selectors';
-import { entryKey } from 'lib/shared/entry-utils';
-import { colorIsDark, threadHasPermission } from 'lib/shared/thread-utils';
-import type { Shape } from 'lib/types/core';
+} from 'lib/components/modal-provider.react.js';
+import { threadInfoSelector } from 'lib/selectors/thread-selectors.js';
+import { entryKey } from 'lib/shared/entry-utils.js';
+import { colorIsDark, threadHasPermission } from 'lib/shared/thread-utils.js';
+import type { Shape } from 'lib/types/core.js';
import {
type EntryInfo,
type CreateEntryInfo,
@@ -32,27 +32,27 @@
type DeleteEntryInfo,
type DeleteEntryResult,
type CalendarQuery,
-} from 'lib/types/entry-types';
-import type { LoadingStatus } from 'lib/types/loading-types';
-import type { Dispatch } from 'lib/types/redux-types';
-import { threadPermissions } from 'lib/types/thread-types';
-import type { ResolvedThreadInfo } from 'lib/types/thread-types';
+} from 'lib/types/entry-types.js';
+import type { LoadingStatus } from 'lib/types/loading-types.js';
+import type { Dispatch } from 'lib/types/redux-types.js';
+import { threadPermissions } from 'lib/types/thread-types.js';
+import type { ResolvedThreadInfo } from 'lib/types/thread-types.js';
import {
type DispatchActionPromise,
useServerCall,
useDispatchActionPromise,
-} from 'lib/utils/action-utils';
-import { dateString } from 'lib/utils/date-utils';
-import { useResolvedThreadInfo } from 'lib/utils/entity-helpers';
-import { ServerError } from 'lib/utils/errors';
-
-import LoadingIndicator from '../loading-indicator.react';
-import LogInFirstModal from '../modals/account/log-in-first-modal.react';
-import ConcurrentModificationModal from '../modals/concurrent-modification-modal.react';
-import HistoryModal from '../modals/history/history-modal.react';
-import { useSelector } from '../redux/redux-utils';
-import { nonThreadCalendarQuery } from '../selectors/nav-selectors';
-import { HistoryVector, DeleteVector } from '../vectors.react';
+} from 'lib/utils/action-utils.js';
+import { dateString } from 'lib/utils/date-utils.js';
+import { useResolvedThreadInfo } from 'lib/utils/entity-helpers.js';
+import { ServerError } from 'lib/utils/errors.js';
+
+import LoadingIndicator from '../loading-indicator.react.js';
+import LogInFirstModal from '../modals/account/log-in-first-modal.react.js';
+import ConcurrentModificationModal from '../modals/concurrent-modification-modal.react.js';
+import HistoryModal from '../modals/history/history-modal.react.js';
+import { useSelector } from '../redux/redux-utils.js';
+import { nonThreadCalendarQuery } from '../selectors/nav-selectors.js';
+import { HistoryVector, DeleteVector } from '../vectors.react.js';
import css from './calendar.css';
type BaseProps = {
diff --git a/web/calendar/filter-panel.react.js b/web/calendar/filter-panel.react.js
--- a/web/calendar/filter-panel.react.js
+++ b/web/calendar/filter-panel.react.js
@@ -15,28 +15,28 @@
import {
useModalContext,
type PushModal,
-} from 'lib/components/modal-provider.react';
+} from 'lib/components/modal-provider.react.js';
import {
filteredThreadIDsSelector,
includeDeletedSelector,
-} from 'lib/selectors/calendar-filter-selectors';
-import SearchIndex from 'lib/shared/search-index';
+} from 'lib/selectors/calendar-filter-selectors.js';
+import SearchIndex from 'lib/shared/search-index.js';
import {
calendarThreadFilterTypes,
type FilterThreadInfo,
updateCalendarThreadFilter,
clearCalendarThreadFilter,
setCalendarDeletedFilter,
-} from 'lib/types/filter-types';
-import type { Dispatch } from 'lib/types/redux-types';
+} from 'lib/types/filter-types.js';
+import type { Dispatch } from 'lib/types/redux-types.js';
-import ThreadSettingsModal from '../modals/threads/settings/thread-settings-modal.react';
-import { useSelector } from '../redux/redux-utils';
+import ThreadSettingsModal from '../modals/threads/settings/thread-settings-modal.react.js';
+import { useSelector } from '../redux/redux-utils.js';
import {
useFilterThreadInfos,
useFilterThreadSearchIndex,
-} from '../selectors/calendar-selectors';
-import { MagnifyingGlass } from '../vectors.react';
+} from '../selectors/calendar-selectors.js';
+import { MagnifyingGlass } from '../vectors.react.js';
import css from './filter-panel.css';
type Props = {
diff --git a/web/chat/chat-input-bar.react.js b/web/chat/chat-input-bar.react.js
--- a/web/chat/chat-input-bar.react.js
+++ b/web/chat/chat-input-bar.react.js
@@ -1,63 +1,63 @@
// @flow
import invariant from 'invariant';
-import _difference from 'lodash/fp/difference';
+import _difference from 'lodash/fp/difference.js';
import * as React from 'react';
import {
joinThreadActionTypes,
joinThread,
newThreadActionTypes,
-} from 'lib/actions/thread-actions';
+} from 'lib/actions/thread-actions.js';
import SWMansionIcon from 'lib/components/SWMansionIcon.react.js';
-import { createLoadingStatusSelector } from 'lib/selectors/loading-selectors';
+import { createLoadingStatusSelector } from 'lib/selectors/loading-selectors.js';
import {
userStoreSearchIndex,
relativeMemberInfoSelectorForMembersOfThread,
-} from 'lib/selectors/user-selectors';
-import { localIDPrefix, trimMessage } from 'lib/shared/message-utils';
+} from 'lib/selectors/user-selectors.js';
+import { localIDPrefix, trimMessage } from 'lib/shared/message-utils.js';
import {
threadHasPermission,
viewerIsMember,
threadFrozenDueToViewerBlock,
threadActualMembers,
checkIfDefaultMembersAreVoiced,
-} from 'lib/shared/thread-utils';
+} from 'lib/shared/thread-utils.js';
import {
getTypeaheadUserSuggestions,
getTypeaheadRegexMatches,
-} from 'lib/shared/typeahead-utils';
-import type { TypeaheadMatchedStrings } from 'lib/shared/typeahead-utils';
-import type { CalendarQuery } from 'lib/types/entry-types';
-import type { LoadingStatus } from 'lib/types/loading-types';
-import { messageTypes } from 'lib/types/message-types';
+} from 'lib/shared/typeahead-utils.js';
+import type { TypeaheadMatchedStrings } from 'lib/shared/typeahead-utils.js';
+import type { CalendarQuery } from 'lib/types/entry-types.js';
+import type { LoadingStatus } from 'lib/types/loading-types.js';
+import { messageTypes } from 'lib/types/message-types.js';
import {
type ThreadInfo,
threadPermissions,
type ClientThreadJoinRequest,
type ThreadJoinPayload,
-} from 'lib/types/thread-types';
-import type { RelativeMemberInfo } from 'lib/types/thread-types';
-import { type UserInfos } from 'lib/types/user-types';
+} from 'lib/types/thread-types.js';
+import type { RelativeMemberInfo } from 'lib/types/thread-types.js';
+import { type UserInfos } from 'lib/types/user-types.js';
import {
type DispatchActionPromise,
useServerCall,
useDispatchActionPromise,
-} from 'lib/utils/action-utils';
+} from 'lib/utils/action-utils.js';
-import Button from '../components/button.react';
+import Button from '../components/button.react.js';
import {
type InputState,
type PendingMultimediaUpload,
-} from '../input/input-state';
-import LoadingIndicator from '../loading-indicator.react';
-import { allowedMimeTypeString } from '../media/file-utils';
-import Multimedia from '../media/multimedia.react';
-import { useSelector } from '../redux/redux-utils';
-import { nonThreadCalendarQuery } from '../selectors/nav-selectors';
-import { webTypeaheadRegex } from '../utils/typeahead-utils';
+} from '../input/input-state.js';
+import LoadingIndicator from '../loading-indicator.react.js';
+import { allowedMimeTypeString } from '../media/file-utils.js';
+import Multimedia from '../media/multimedia.react.js';
+import { useSelector } from '../redux/redux-utils.js';
+import { nonThreadCalendarQuery } from '../selectors/nav-selectors.js';
+import { webTypeaheadRegex } from '../utils/typeahead-utils.js';
import css from './chat-input-bar.css';
-import TypeaheadTooltip from './typeahead-tooltip.react';
+import TypeaheadTooltip from './typeahead-tooltip.react.js';
type BaseProps = {
+threadInfo: ThreadInfo,
diff --git a/web/chat/chat-message-list-container.react.js b/web/chat/chat-message-list-container.react.js
--- a/web/chat/chat-message-list-container.react.js
+++ b/web/chat/chat-message-list-container.react.js
@@ -2,31 +2,31 @@
import classNames from 'classnames';
import invariant from 'invariant';
-import _isEqual from 'lodash/fp/isEqual';
+import _isEqual from 'lodash/fp/isEqual.js';
import * as React from 'react';
import { useDrop } from 'react-dnd';
import { NativeTypes } from 'react-dnd-html5-backend';
import { useDispatch } from 'react-redux';
-import { threadInfoSelector } from 'lib/selectors/thread-selectors';
-import { userInfoSelectorForPotentialMembers } from 'lib/selectors/user-selectors';
+import { threadInfoSelector } from 'lib/selectors/thread-selectors.js';
+import { userInfoSelectorForPotentialMembers } from 'lib/selectors/user-selectors.js';
import {
useWatchThread,
useExistingThreadInfoFinder,
createPendingThread,
threadIsPending,
-} from 'lib/shared/thread-utils';
-import { threadTypes } from 'lib/types/thread-types';
-import type { AccountUserInfo } from 'lib/types/user-types';
+} from 'lib/shared/thread-utils.js';
+import { threadTypes } from 'lib/types/thread-types.js';
+import type { AccountUserInfo } from 'lib/types/user-types.js';
-import { InputStateContext } from '../input/input-state';
-import { updateNavInfoActionType } from '../redux/action-types';
-import { useSelector } from '../redux/redux-utils';
-import ChatInputBar from './chat-input-bar.react';
+import { InputStateContext } from '../input/input-state.js';
+import { updateNavInfoActionType } from '../redux/action-types.js';
+import { useSelector } from '../redux/redux-utils.js';
+import ChatInputBar from './chat-input-bar.react.js';
import css from './chat-message-list-container.css';
-import ChatMessageList from './chat-message-list.react';
-import ChatThreadComposer from './chat-thread-composer.react';
-import ThreadTopBar from './thread-top-bar.react';
+import ChatMessageList from './chat-message-list.react.js';
+import ChatThreadComposer from './chat-thread-composer.react.js';
+import ThreadTopBar from './thread-top-bar.react.js';
type Props = {
+activeChatThreadID: string,
diff --git a/web/chat/chat-message-list.react.js b/web/chat/chat-message-list.react.js
--- a/web/chat/chat-message-list.react.js
+++ b/web/chat/chat-message-list.react.js
@@ -10,31 +10,31 @@
fetchMessagesBeforeCursor,
fetchMostRecentMessagesActionTypes,
fetchMostRecentMessages,
-} from 'lib/actions/message-actions';
-import { registerFetchKey } from 'lib/reducers/loading-reducer';
+} from 'lib/actions/message-actions.js';
+import { registerFetchKey } from 'lib/reducers/loading-reducer.js';
import {
type ChatMessageItem,
useMessageListData,
-} from 'lib/selectors/chat-selectors';
-import { messageKey } from 'lib/shared/message-utils';
-import { threadIsPending } from 'lib/shared/thread-utils';
-import type { FetchMessageInfosPayload } from 'lib/types/message-types';
-import { type ThreadInfo, threadTypes } from 'lib/types/thread-types';
+} from 'lib/selectors/chat-selectors.js';
+import { messageKey } from 'lib/shared/message-utils.js';
+import { threadIsPending } from 'lib/shared/thread-utils.js';
+import type { FetchMessageInfosPayload } from 'lib/types/message-types.js';
+import { type ThreadInfo, threadTypes } from 'lib/types/thread-types.js';
import {
type DispatchActionPromise,
useServerCall,
useDispatchActionPromise,
-} from 'lib/utils/action-utils';
+} from 'lib/utils/action-utils.js';
-import { type InputState, InputStateContext } from '../input/input-state';
-import LoadingIndicator from '../loading-indicator.react';
-import { useTextMessageRulesFunc } from '../markdown/rules.react';
-import { useSelector } from '../redux/redux-utils';
+import { type InputState, InputStateContext } from '../input/input-state.js';
+import LoadingIndicator from '../loading-indicator.react.js';
+import { useTextMessageRulesFunc } from '../markdown/rules.react.js';
+import { useSelector } from '../redux/redux-utils.js';
import css from './chat-message-list.css';
-import { MessageListContext } from './message-list-types';
-import Message from './message.react';
-import RelationshipPrompt from './relationship-prompt/relationship-prompt';
-import { useTooltipContext } from './tooltip-provider';
+import { MessageListContext } from './message-list-types.js';
+import Message from './message.react.js';
+import RelationshipPrompt from './relationship-prompt/relationship-prompt.js';
+import { useTooltipContext } from './tooltip-provider.js';
const browser = detectBrowser();
const supportsReverseFlex =
diff --git a/web/chat/chat-tabs.react.js b/web/chat/chat-tabs.react.js
--- a/web/chat/chat-tabs.react.js
+++ b/web/chat/chat-tabs.react.js
@@ -3,14 +3,14 @@
import invariant from 'invariant';
import * as React from 'react';
-import { unreadBackgroundCount } from 'lib/selectors/thread-selectors';
+import { unreadBackgroundCount } from 'lib/selectors/thread-selectors.js';
-import Tabs from '../components/tabs.react';
-import { useSelector } from '../redux/redux-utils';
+import Tabs from '../components/tabs.react.js';
+import { useSelector } from '../redux/redux-utils.js';
import css from './chat-tabs.css';
-import ChatThreadList from './chat-thread-list.react';
-import ChatThreadTab from './chat-thread-tab.react';
-import { ThreadListContext } from './thread-list-provider';
+import ChatThreadList from './chat-thread-list.react.js';
+import ChatThreadTab from './chat-thread-tab.react.js';
+import { ThreadListContext } from './thread-list-provider.js';
function ChatTabs(): React.Node {
let backgroundTitle = 'Background';
diff --git a/web/chat/chat-thread-ancestors.react.js b/web/chat/chat-thread-ancestors.react.js
--- a/web/chat/chat-thread-ancestors.react.js
+++ b/web/chat/chat-thread-ancestors.react.js
@@ -4,13 +4,13 @@
import * as React from 'react';
import SWMansionIcon from 'lib/components/SWMansionIcon.react.js';
-import { useAncestorThreads } from 'lib/shared/ancestor-threads';
-import { colorIsDark } from 'lib/shared/thread-utils';
-import { useKeyserverAdmin } from 'lib/shared/user-utils';
-import type { ThreadInfo } from 'lib/types/thread-types';
-import { useResolvedThreadInfo } from 'lib/utils/entity-helpers';
+import { useAncestorThreads } from 'lib/shared/ancestor-threads.js';
+import { colorIsDark } from 'lib/shared/thread-utils.js';
+import { useKeyserverAdmin } from 'lib/shared/user-utils.js';
+import type { ThreadInfo } from 'lib/types/thread-types.js';
+import { useResolvedThreadInfo } from 'lib/utils/entity-helpers.js';
-import CommIcon from '../CommIcon.react';
+import CommIcon from '../CommIcon.react.js';
import css from './chat-thread-ancestors.css';
const SHOW_SEE_FULL_STRUCTURE = false;
diff --git a/web/chat/chat-thread-composer.react.js b/web/chat/chat-thread-composer.react.js
--- a/web/chat/chat-thread-composer.react.js
+++ b/web/chat/chat-thread-composer.react.js
@@ -4,18 +4,18 @@
import { useDispatch } from 'react-redux';
import SWMansionIcon from 'lib/components/SWMansionIcon.react.js';
-import { useENSNames } from 'lib/hooks/ens-cache';
-import { userSearchIndexForPotentialMembers } from 'lib/selectors/user-selectors';
-import { getPotentialMemberItems } from 'lib/shared/search-utils';
-import { threadIsPending } from 'lib/shared/thread-utils';
-import type { AccountUserInfo, UserListItem } from 'lib/types/user-types';
-
-import Button from '../components/button.react';
-import Label from '../components/label.react';
-import Search from '../components/search.react';
-import type { InputState } from '../input/input-state';
-import { updateNavInfoActionType } from '../redux/action-types';
-import { useSelector } from '../redux/redux-utils';
+import { useENSNames } from 'lib/hooks/ens-cache.js';
+import { userSearchIndexForPotentialMembers } from 'lib/selectors/user-selectors.js';
+import { getPotentialMemberItems } from 'lib/shared/search-utils.js';
+import { threadIsPending } from 'lib/shared/thread-utils.js';
+import type { AccountUserInfo, UserListItem } from 'lib/types/user-types.js';
+
+import Button from '../components/button.react.js';
+import Label from '../components/label.react.js';
+import Search from '../components/search.react.js';
+import type { InputState } from '../input/input-state.js';
+import { updateNavInfoActionType } from '../redux/action-types.js';
+import { useSelector } from '../redux/redux-utils.js';
import css from './chat-thread-composer.css';
type Props = {
diff --git a/web/chat/chat-thread-list-item-menu.react.js b/web/chat/chat-thread-list-item-menu.react.js
--- a/web/chat/chat-thread-list-item-menu.react.js
+++ b/web/chat/chat-thread-list-item-menu.react.js
@@ -4,11 +4,11 @@
import * as React from 'react';
import SWMansionIcon from 'lib/components/SWMansionIcon.react.js';
-import useToggleUnreadStatus from 'lib/hooks/toggle-unread-status';
-import type { ThreadInfo } from 'lib/types/thread-types';
+import useToggleUnreadStatus from 'lib/hooks/toggle-unread-status.js';
+import type { ThreadInfo } from 'lib/types/thread-types.js';
-import Button from '../components/button.react';
-import { useThreadIsActive } from '../selectors/thread-selectors';
+import Button from '../components/button.react.js';
+import { useThreadIsActive } from '../selectors/thread-selectors.js';
import css from './chat-thread-list-item-menu.css';
type Props = {
diff --git a/web/chat/chat-thread-list-item.react.js b/web/chat/chat-thread-list-item.react.js
--- a/web/chat/chat-thread-list-item.react.js
+++ b/web/chat/chat-thread-list-item.react.js
@@ -4,24 +4,24 @@
import * as React from 'react';
import SWMansionIcon from 'lib/components/SWMansionIcon.react.js';
-import type { ChatThreadItem } from 'lib/selectors/chat-selectors';
-import { useAncestorThreads } from 'lib/shared/ancestor-threads';
-import { shortAbsoluteDate } from 'lib/utils/date-utils';
+import type { ChatThreadItem } from 'lib/selectors/chat-selectors.js';
+import { useAncestorThreads } from 'lib/shared/ancestor-threads.js';
+import { shortAbsoluteDate } from 'lib/utils/date-utils.js';
import {
useResolvedThreadInfo,
useResolvedThreadInfos,
-} from 'lib/utils/entity-helpers';
+} from 'lib/utils/entity-helpers.js';
-import { useSelector } from '../redux/redux-utils';
+import { useSelector } from '../redux/redux-utils.js';
import {
useOnClickThread,
useThreadIsActive,
-} from '../selectors/thread-selectors';
-import ChatThreadListItemMenu from './chat-thread-list-item-menu.react';
-import ChatThreadListSeeMoreSidebars from './chat-thread-list-see-more-sidebars.react';
-import ChatThreadListSidebar from './chat-thread-list-sidebar.react';
+} from '../selectors/thread-selectors.js';
+import ChatThreadListItemMenu from './chat-thread-list-item-menu.react.js';
+import ChatThreadListSeeMoreSidebars from './chat-thread-list-see-more-sidebars.react.js';
+import ChatThreadListSidebar from './chat-thread-list-sidebar.react.js';
import css from './chat-thread-list.css';
-import MessagePreview from './message-preview.react';
+import MessagePreview from './message-preview.react.js';
type Props = {
+item: ChatThreadItem,
diff --git a/web/chat/chat-thread-list-see-more-sidebars.react.js b/web/chat/chat-thread-list-see-more-sidebars.react.js
--- a/web/chat/chat-thread-list-see-more-sidebars.react.js
+++ b/web/chat/chat-thread-list-see-more-sidebars.react.js
@@ -4,10 +4,10 @@
import * as React from 'react';
import { IoIosMore } from 'react-icons/io';
-import { useModalContext } from 'lib/components/modal-provider.react';
-import type { ThreadInfo } from 'lib/types/thread-types';
+import { useModalContext } from 'lib/components/modal-provider.react.js';
+import type { ThreadInfo } from 'lib/types/thread-types.js';
-import SidebarsModal from '../modals/threads/sidebars/sidebars-modal.react';
+import SidebarsModal from '../modals/threads/sidebars/sidebars-modal.react.js';
import css from './chat-thread-list.css';
type Props = {
diff --git a/web/chat/chat-thread-list-sidebar.react.js b/web/chat/chat-thread-list-sidebar.react.js
--- a/web/chat/chat-thread-list-sidebar.react.js
+++ b/web/chat/chat-thread-list-sidebar.react.js
@@ -3,15 +3,15 @@
import classNames from 'classnames';
import * as React from 'react';
-import type { SidebarInfo } from 'lib/types/thread-types';
+import type { SidebarInfo } from 'lib/types/thread-types.js';
import {
useOnClickThread,
useThreadIsActive,
-} from '../selectors/thread-selectors';
-import ChatThreadListItemMenu from './chat-thread-list-item-menu.react';
+} from '../selectors/thread-selectors.js';
+import ChatThreadListItemMenu from './chat-thread-list-item-menu.react.js';
import css from './chat-thread-list.css';
-import SidebarItem from './sidebar-item.react';
+import SidebarItem from './sidebar-item.react.js';
type Props = {
+sidebarInfo: SidebarInfo,
diff --git a/web/chat/chat-thread-list.react.js b/web/chat/chat-thread-list.react.js
--- a/web/chat/chat-thread-list.react.js
+++ b/web/chat/chat-thread-list.react.js
@@ -3,16 +3,16 @@
import invariant from 'invariant';
import * as React from 'react';
-import { emptyItemText } from 'lib/shared/thread-utils';
+import { emptyItemText } from 'lib/shared/thread-utils.js';
-import BackgroundIllustration from '../assets/background-illustration.react';
-import Button from '../components/button.react';
-import Search from '../components/search.react';
-import { useSelector } from '../redux/redux-utils';
-import { useOnClickNewThread } from '../selectors/thread-selectors';
-import ChatThreadListItem from './chat-thread-list-item.react';
+import BackgroundIllustration from '../assets/background-illustration.react.js';
+import Button from '../components/button.react.js';
+import Search from '../components/search.react.js';
+import { useSelector } from '../redux/redux-utils.js';
+import { useOnClickNewThread } from '../selectors/thread-selectors.js';
+import ChatThreadListItem from './chat-thread-list-item.react.js';
import css from './chat-thread-list.css';
-import { ThreadListContext } from './thread-list-provider';
+import { ThreadListContext } from './thread-list-provider.js';
function ChatThreadList(): React.Node {
const threadListContext = React.useContext(ThreadListContext);
diff --git a/web/chat/chat.react.js b/web/chat/chat.react.js
--- a/web/chat/chat.react.js
+++ b/web/chat/chat.react.js
@@ -2,13 +2,13 @@
import * as React from 'react';
-import ThreadDraftUpdater from 'lib/components/thread-draft-updater.react';
-import { isLoggedIn } from 'lib/selectors/user-selectors';
+import ThreadDraftUpdater from 'lib/components/thread-draft-updater.react.js';
+import { isLoggedIn } from 'lib/selectors/user-selectors.js';
-import { useSelector } from '../redux/redux-utils';
-import ChatMessageListContainer from './chat-message-list-container.react';
-import ChatTabs from './chat-tabs.react';
-import { ThreadListProvider } from './thread-list-provider';
+import { useSelector } from '../redux/redux-utils.js';
+import ChatMessageListContainer from './chat-message-list-container.react.js';
+import ChatTabs from './chat-tabs.react.js';
+import { ThreadListProvider } from './thread-list-provider.js';
function Chat(): React.Node {
const loggedIn = useSelector(isLoggedIn);
diff --git a/web/chat/composed-message.react.js b/web/chat/composed-message.react.js
--- a/web/chat/composed-message.react.js
+++ b/web/chat/composed-message.react.js
@@ -8,16 +8,16 @@
XCircle as XCircleIcon,
} from 'react-feather';
-import { useStringForUser } from 'lib/hooks/ens-cache';
-import { type ChatMessageInfoItem } from 'lib/selectors/chat-selectors';
-import { assertComposableMessageType } from 'lib/types/message-types';
-import { type ThreadInfo } from 'lib/types/thread-types';
+import { useStringForUser } from 'lib/hooks/ens-cache.js';
+import { type ChatMessageInfoItem } from 'lib/selectors/chat-selectors.js';
+import { assertComposableMessageType } from 'lib/types/message-types.js';
+import { type ThreadInfo } from 'lib/types/thread-types.js';
-import { type InputState, InputStateContext } from '../input/input-state';
-import { tooltipPositions, useMessageTooltip } from '../utils/tooltip-utils';
+import { type InputState, InputStateContext } from '../input/input-state.js';
+import { tooltipPositions, useMessageTooltip } from '../utils/tooltip-utils.js';
import css from './chat-message-list.css';
-import FailedSend from './failed-send.react';
-import InlineEngagement from './inline-engagement.react';
+import FailedSend from './failed-send.react.js';
+import InlineEngagement from './inline-engagement.react.js';
const availableTooltipPositionsForViewerMessage = [
tooltipPositions.LEFT,
diff --git a/web/chat/failed-send.react.js b/web/chat/failed-send.react.js
--- a/web/chat/failed-send.react.js
+++ b/web/chat/failed-send.react.js
@@ -3,21 +3,21 @@
import invariant from 'invariant';
import * as React from 'react';
-import { type ChatMessageInfoItem } from 'lib/selectors/chat-selectors';
-import { messageID } from 'lib/shared/message-utils';
+import { type ChatMessageInfoItem } from 'lib/selectors/chat-selectors.js';
+import { messageID } from 'lib/shared/message-utils.js';
import {
messageTypes,
type RawComposableMessageInfo,
assertComposableMessageType,
-} from 'lib/types/message-types';
-import { type ThreadInfo } from 'lib/types/thread-types';
+} from 'lib/types/message-types.js';
+import { type ThreadInfo } from 'lib/types/thread-types.js';
-import Button from '../components/button.react';
-import { type InputState, InputStateContext } from '../input/input-state';
-import { useSelector } from '../redux/redux-utils';
+import Button from '../components/button.react.js';
+import { type InputState, InputStateContext } from '../input/input-state.js';
+import { useSelector } from '../redux/redux-utils.js';
import css from './chat-message-list.css';
-import multimediaMessageSendFailed from './multimedia-message-send-failed';
-import textMessageSendFailed from './text-message-send-failed';
+import multimediaMessageSendFailed from './multimedia-message-send-failed.js';
+import textMessageSendFailed from './text-message-send-failed.js';
type BaseProps = {
+item: ChatMessageInfoItem,
diff --git a/web/chat/inline-engagement.react.js b/web/chat/inline-engagement.react.js
--- a/web/chat/inline-engagement.react.js
+++ b/web/chat/inline-engagement.react.js
@@ -3,15 +3,15 @@
import classNames from 'classnames';
import * as React from 'react';
-import { useModalContext } from 'lib/components/modal-provider.react';
-import useInlineEngagementText from 'lib/hooks/inline-engagement-text.react';
-import type { MessageReactionInfo } from 'lib/selectors/chat-selectors';
-import { stringForReactionList } from 'lib/shared/reaction-utils';
-import type { ThreadInfo } from 'lib/types/thread-types';
-
-import CommIcon from '../CommIcon.react';
-import MessageReactionsModal from '../modals/chat/message-reactions-modal.react';
-import { useOnClickThread } from '../selectors/thread-selectors';
+import { useModalContext } from 'lib/components/modal-provider.react.js';
+import useInlineEngagementText from 'lib/hooks/inline-engagement-text.react.js';
+import type { MessageReactionInfo } from 'lib/selectors/chat-selectors.js';
+import { stringForReactionList } from 'lib/shared/reaction-utils.js';
+import type { ThreadInfo } from 'lib/types/thread-types.js';
+
+import CommIcon from '../CommIcon.react.js';
+import MessageReactionsModal from '../modals/chat/message-reactions-modal.react.js';
+import { useOnClickThread } from '../selectors/thread-selectors.js';
import css from './inline-engagement.css';
type Props = {
diff --git a/web/chat/message-list-types.js b/web/chat/message-list-types.js
--- a/web/chat/message-list-types.js
+++ b/web/chat/message-list-types.js
@@ -2,7 +2,7 @@
import * as React from 'react';
-import type { MarkdownRules } from '../markdown/rules.react';
+import type { MarkdownRules } from '../markdown/rules.react.js';
export type MessageListContextType = {
+getTextMessageMarkdownRules: (useDarkStyle: boolean) => MarkdownRules,
diff --git a/web/chat/message-preview.react.js b/web/chat/message-preview.react.js
--- a/web/chat/message-preview.react.js
+++ b/web/chat/message-preview.react.js
@@ -4,11 +4,11 @@
import invariant from 'invariant';
import * as React from 'react';
-import { useMessagePreview } from 'lib/shared/message-utils';
-import { type MessageInfo } from 'lib/types/message-types';
-import { type ThreadInfo } from 'lib/types/thread-types';
+import { useMessagePreview } from 'lib/shared/message-utils.js';
+import { type MessageInfo } from 'lib/types/message-types.js';
+import { type ThreadInfo } from 'lib/types/thread-types.js';
-import { getDefaultTextMessageRules } from '../markdown/rules.react';
+import { getDefaultTextMessageRules } from '../markdown/rules.react.js';
import css from './chat-thread-list.css';
type Props = {
diff --git a/web/chat/message-tooltip.react.js b/web/chat/message-tooltip.react.js
--- a/web/chat/message-tooltip.react.js
+++ b/web/chat/message-tooltip.react.js
@@ -5,20 +5,20 @@
import classNames from 'classnames';
import * as React from 'react';
-import type { ChatMessageInfoItem } from 'lib/selectors/chat-selectors';
-import { localIDPrefix } from 'lib/shared/message-utils';
-import type { ThreadInfo } from 'lib/types/thread-types';
+import type { ChatMessageInfoItem } from 'lib/selectors/chat-selectors.js';
+import { localIDPrefix } from 'lib/shared/message-utils.js';
+import type { ThreadInfo } from 'lib/types/thread-types.js';
-import { useSelector } from '../redux/redux-utils';
-import { type MessageTooltipAction } from '../utils/tooltip-utils';
+import { useSelector } from '../redux/redux-utils.js';
+import { type MessageTooltipAction } from '../utils/tooltip-utils.js';
import {
tooltipButtonStyle,
tooltipLabelStyle,
tooltipStyle,
-} from './chat-constants';
+} from './chat-constants.js';
import css from './message-tooltip.css';
-import { useSendReaction } from './reaction-message-utils';
-import { useTooltipContext } from './tooltip-provider';
+import { useSendReaction } from './reaction-message-utils.js';
+import { useTooltipContext } from './tooltip-provider.js';
type MessageTooltipProps = {
+actions: $ReadOnlyArray<MessageTooltipAction>,
diff --git a/web/chat/message.react.js b/web/chat/message.react.js
--- a/web/chat/message.react.js
+++ b/web/chat/message.react.js
@@ -3,15 +3,15 @@
import invariant from 'invariant';
import * as React from 'react';
-import { type ChatMessageInfoItem } from 'lib/selectors/chat-selectors';
-import { messageTypes } from 'lib/types/message-types';
-import { type ThreadInfo } from 'lib/types/thread-types';
-import { longAbsoluteDate } from 'lib/utils/date-utils';
+import { type ChatMessageInfoItem } from 'lib/selectors/chat-selectors.js';
+import { messageTypes } from 'lib/types/message-types.js';
+import { type ThreadInfo } from 'lib/types/thread-types.js';
+import { longAbsoluteDate } from 'lib/utils/date-utils.js';
import css from './chat-message-list.css';
-import MultimediaMessage from './multimedia-message.react';
-import RobotextMessage from './robotext-message.react';
-import TextMessage from './text-message.react';
+import MultimediaMessage from './multimedia-message.react.js';
+import RobotextMessage from './robotext-message.react.js';
+import TextMessage from './text-message.react.js';
type Props = {
+item: ChatMessageInfoItem,
diff --git a/web/chat/multimedia-message-send-failed.js b/web/chat/multimedia-message-send-failed.js
--- a/web/chat/multimedia-message-send-failed.js
+++ b/web/chat/multimedia-message-send-failed.js
@@ -2,10 +2,10 @@
import invariant from 'invariant';
-import type { ChatMessageInfoItem } from 'lib/selectors/chat-selectors';
-import { messageTypes } from 'lib/types/message-types';
+import type { ChatMessageInfoItem } from 'lib/selectors/chat-selectors.js';
+import { messageTypes } from 'lib/types/message-types.js';
-import type { InputState } from '../input/input-state';
+import type { InputState } from '../input/input-state.js';
export default function multimediaMessageSendFailed(
item: ChatMessageInfoItem,
diff --git a/web/chat/multimedia-message.react.js b/web/chat/multimedia-message.react.js
--- a/web/chat/multimedia-message.react.js
+++ b/web/chat/multimedia-message.react.js
@@ -3,15 +3,15 @@
import invariant from 'invariant';
import * as React from 'react';
-import { type ChatMessageInfoItem } from 'lib/selectors/chat-selectors';
-import { messageTypes } from 'lib/types/message-types';
-import { type ThreadInfo } from 'lib/types/thread-types';
+import { type ChatMessageInfoItem } from 'lib/selectors/chat-selectors.js';
+import { messageTypes } from 'lib/types/message-types.js';
+import { type ThreadInfo } from 'lib/types/thread-types.js';
-import { type InputState, InputStateContext } from '../input/input-state';
-import Multimedia from '../media/multimedia.react';
+import { type InputState, InputStateContext } from '../input/input-state.js';
+import Multimedia from '../media/multimedia.react.js';
import css from './chat-message-list.css';
-import ComposedMessage from './composed-message.react';
-import sendFailed from './multimedia-message-send-failed';
+import ComposedMessage from './composed-message.react.js';
+import sendFailed from './multimedia-message-send-failed.js';
type BaseProps = {
+item: ChatMessageInfoItem,
+threadInfo: ThreadInfo,
diff --git a/web/chat/position-types.js b/web/chat/position-types.js
--- a/web/chat/position-types.js
+++ b/web/chat/position-types.js
@@ -1,6 +1,6 @@
// @flow
-import { type ChatMessageInfoItem } from 'lib/selectors/chat-selectors';
+import { type ChatMessageInfoItem } from 'lib/selectors/chat-selectors.js';
export type OnMessagePositionWithContainerInfo = {
+type: 'on',
diff --git a/web/chat/reaction-message-utils.js b/web/chat/reaction-message-utils.js
--- a/web/chat/reaction-message-utils.js
+++ b/web/chat/reaction-message-utils.js
@@ -6,18 +6,18 @@
import {
sendReactionMessage,
sendReactionMessageActionTypes,
-} from 'lib/actions/message-actions';
-import { useModalContext } from 'lib/components/modal-provider.react';
-import { messageTypes } from 'lib/types/message-types';
-import type { RawReactionMessageInfo } from 'lib/types/messages/reaction';
+} from 'lib/actions/message-actions.js';
+import { useModalContext } from 'lib/components/modal-provider.react.js';
+import { messageTypes } from 'lib/types/message-types.js';
+import type { RawReactionMessageInfo } from 'lib/types/messages/reaction.js';
import {
useDispatchActionPromise,
useServerCall,
-} from 'lib/utils/action-utils';
-import { cloneError } from 'lib/utils/errors';
+} from 'lib/utils/action-utils.js';
+import { cloneError } from 'lib/utils/errors.js';
-import Alert from '../modals/alert.react';
-import { useSelector } from '../redux/redux-utils';
+import Alert from '../modals/alert.react.js';
+import { useSelector } from '../redux/redux-utils.js';
function useSendReaction(
messageID: ?string,
diff --git a/web/chat/relationship-prompt/relationship-prompt-button.js b/web/chat/relationship-prompt/relationship-prompt-button.js
--- a/web/chat/relationship-prompt/relationship-prompt-button.js
+++ b/web/chat/relationship-prompt/relationship-prompt-button.js
@@ -4,7 +4,7 @@
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import * as React from 'react';
-import Button, { type ButtonColor } from '../../components/button.react';
+import Button, { type ButtonColor } from '../../components/button.react.js';
import css from './relationship-prompt.css';
type Props = {
diff --git a/web/chat/relationship-prompt/relationship-prompt.js b/web/chat/relationship-prompt/relationship-prompt.js
--- a/web/chat/relationship-prompt/relationship-prompt.js
+++ b/web/chat/relationship-prompt/relationship-prompt.js
@@ -8,13 +8,13 @@
} from '@fortawesome/free-solid-svg-icons';
import * as React from 'react';
-import { useRelationshipPrompt } from 'lib/hooks/relationship-prompt';
-import { userRelationshipStatus } from 'lib/types/relationship-types';
-import type { ThreadInfo } from 'lib/types/thread-types';
+import { useRelationshipPrompt } from 'lib/hooks/relationship-prompt.js';
+import { userRelationshipStatus } from 'lib/types/relationship-types.js';
+import type { ThreadInfo } from 'lib/types/thread-types.js';
-import { buttonThemes } from '../../components/button.react';
-import RelationshipPromptButton from './relationship-prompt-button';
-import RelationshipPromptButtonContainer from './relationship-prompt-button-container';
+import { buttonThemes } from '../../components/button.react.js';
+import RelationshipPromptButtonContainer from './relationship-prompt-button-container.js';
+import RelationshipPromptButton from './relationship-prompt-button.js';
type Props = { +threadInfo: ThreadInfo };
diff --git a/web/chat/robotext-message.react.js b/web/chat/robotext-message.react.js
--- a/web/chat/robotext-message.react.js
+++ b/web/chat/robotext-message.react.js
@@ -4,21 +4,21 @@
import * as React from 'react';
import { useDispatch } from 'react-redux';
-import { type RobotextChatMessageInfoItem } from 'lib/selectors/chat-selectors';
-import { threadInfoSelector } from 'lib/selectors/thread-selectors';
-import type { Dispatch } from 'lib/types/redux-types';
-import { type ThreadInfo } from 'lib/types/thread-types';
+import { type RobotextChatMessageInfoItem } from 'lib/selectors/chat-selectors.js';
+import { threadInfoSelector } from 'lib/selectors/thread-selectors.js';
+import type { Dispatch } from 'lib/types/redux-types.js';
+import { type ThreadInfo } from 'lib/types/thread-types.js';
import {
entityTextToReact,
useENSNamesForEntityText,
-} from 'lib/utils/entity-text';
+} from 'lib/utils/entity-text.js';
-import Markdown from '../markdown/markdown.react';
-import { linkRules } from '../markdown/rules.react';
-import { updateNavInfoActionType } from '../redux/action-types';
-import { useSelector } from '../redux/redux-utils';
-import { tooltipPositions, useMessageTooltip } from '../utils/tooltip-utils';
-import InlineEngagement from './inline-engagement.react';
+import Markdown from '../markdown/markdown.react.js';
+import { linkRules } from '../markdown/rules.react.js';
+import { updateNavInfoActionType } from '../redux/action-types.js';
+import { useSelector } from '../redux/redux-utils.js';
+import { tooltipPositions, useMessageTooltip } from '../utils/tooltip-utils.js';
+import InlineEngagement from './inline-engagement.react.js';
import css from './robotext-message.css';
const availableTooltipPositionsForRobotext = [
diff --git a/web/chat/sidebar-item.react.js b/web/chat/sidebar-item.react.js
--- a/web/chat/sidebar-item.react.js
+++ b/web/chat/sidebar-item.react.js
@@ -3,10 +3,10 @@
import classNames from 'classnames';
import * as React from 'react';
-import type { SidebarInfo } from 'lib/types/thread-types';
-import { useResolvedThreadInfo } from 'lib/utils/entity-helpers';
+import type { SidebarInfo } from 'lib/types/thread-types.js';
+import { useResolvedThreadInfo } from 'lib/utils/entity-helpers.js';
-import { useOnClickThread } from '../selectors/thread-selectors';
+import { useOnClickThread } from '../selectors/thread-selectors.js';
import css from './chat-thread-list.css';
type Props = {
diff --git a/web/chat/text-message-send-failed.js b/web/chat/text-message-send-failed.js
--- a/web/chat/text-message-send-failed.js
+++ b/web/chat/text-message-send-failed.js
@@ -1,7 +1,7 @@
// @flow
-import type { ChatMessageInfoItem } from 'lib/selectors/chat-selectors';
-import { messageTypes } from 'lib/types/message-types';
+import type { ChatMessageInfoItem } from 'lib/selectors/chat-selectors.js';
+import { messageTypes } from 'lib/types/message-types.js';
export default function textMessageSendFailed(
item: ChatMessageInfoItem,
diff --git a/web/chat/text-message.react.js b/web/chat/text-message.react.js
--- a/web/chat/text-message.react.js
+++ b/web/chat/text-message.react.js
@@ -4,17 +4,17 @@
import invariant from 'invariant';
import * as React from 'react';
-import type { ChatMessageInfoItem } from 'lib/selectors/chat-selectors';
-import { onlyEmojiRegex } from 'lib/shared/emojis';
-import { colorIsDark } from 'lib/shared/thread-utils';
-import { messageTypes } from 'lib/types/message-types';
-import { type ThreadInfo } from 'lib/types/thread-types';
+import type { ChatMessageInfoItem } from 'lib/selectors/chat-selectors.js';
+import { onlyEmojiRegex } from 'lib/shared/emojis.js';
+import { colorIsDark } from 'lib/shared/thread-utils.js';
+import { messageTypes } from 'lib/types/message-types.js';
+import { type ThreadInfo } from 'lib/types/thread-types.js';
-import Markdown from '../markdown/markdown.react';
+import Markdown from '../markdown/markdown.react.js';
import css from './chat-message-list.css';
-import ComposedMessage from './composed-message.react';
-import { MessageListContext } from './message-list-types';
-import textMessageSendFailed from './text-message-send-failed';
+import ComposedMessage from './composed-message.react.js';
+import { MessageListContext } from './message-list-types.js';
+import textMessageSendFailed from './text-message-send-failed.js';
type Props = {
+item: ChatMessageInfoItem,
diff --git a/web/chat/thread-list-provider.js b/web/chat/thread-list-provider.js
--- a/web/chat/thread-list-provider.js
+++ b/web/chat/thread-list-provider.js
@@ -6,8 +6,8 @@
import {
type ChatThreadItem,
useFlattenedChatListData,
-} from 'lib/selectors/chat-selectors';
-import { threadInfoSelector } from 'lib/selectors/thread-selectors';
+} from 'lib/selectors/chat-selectors.js';
+import { threadInfoSelector } from 'lib/selectors/thread-selectors.js';
import {
threadInBackgroundChatList,
threadInHomeChatList,
@@ -15,14 +15,14 @@
getThreadListSearchResults,
useThreadListSearch,
threadIsPending,
-} from 'lib/shared/thread-utils';
-import { threadTypes } from 'lib/types/thread-types';
+} from 'lib/shared/thread-utils.js';
+import { threadTypes } from 'lib/types/thread-types.js';
-import { useSelector } from '../redux/redux-utils';
+import { useSelector } from '../redux/redux-utils.js';
import {
useChatThreadItem,
activeChatThreadItem as activeChatThreadItemSelector,
-} from '../selectors/chat-selectors';
+} from '../selectors/chat-selectors.js';
type ChatTabType = 'Focus' | 'Background';
type ThreadListContextType = {
diff --git a/web/chat/thread-menu.react.js b/web/chat/thread-menu.react.js
--- a/web/chat/thread-menu.react.js
+++ b/web/chat/thread-menu.react.js
@@ -5,37 +5,37 @@
import {
leaveThread,
leaveThreadActionTypes,
-} from 'lib/actions/thread-actions';
-import { useModalContext } from 'lib/components/modal-provider.react';
+} from 'lib/actions/thread-actions.js';
+import { useModalContext } from 'lib/components/modal-provider.react.js';
import SWMansionIcon from 'lib/components/SWMansionIcon.react.js';
-import { usePromoteSidebar } from 'lib/hooks/promote-sidebar.react';
-import { childThreadInfos } from 'lib/selectors/thread-selectors';
+import { usePromoteSidebar } from 'lib/hooks/promote-sidebar.react.js';
+import { childThreadInfos } from 'lib/selectors/thread-selectors.js';
import {
threadHasPermission,
viewerIsMember,
threadIsChannel,
-} from 'lib/shared/thread-utils';
+} from 'lib/shared/thread-utils.js';
import {
type ThreadInfo,
threadTypes,
threadPermissions,
-} from 'lib/types/thread-types';
+} from 'lib/types/thread-types.js';
import {
useServerCall,
useDispatchActionPromise,
-} from 'lib/utils/action-utils';
+} from 'lib/utils/action-utils.js';
-import MenuItem from '../components/menu-item.react';
-import Menu from '../components/menu.react';
-import SidebarPromoteModal from '../modals/chat/sidebar-promote-modal.react';
-import ConfirmLeaveThreadModal from '../modals/threads/confirm-leave-thread-modal.react';
-import ComposeSubchannelModal from '../modals/threads/create/compose-subchannel-modal.react';
-import ThreadMembersModal from '../modals/threads/members/members-modal.react';
-import ThreadNotificationsModal from '../modals/threads/notifications/notifications-modal.react';
-import ThreadSettingsModal from '../modals/threads/settings/thread-settings-modal.react';
-import SidebarsModal from '../modals/threads/sidebars/sidebars-modal.react';
-import SubchannelsModal from '../modals/threads/subchannels/subchannels-modal.react';
-import { useSelector } from '../redux/redux-utils';
+import MenuItem from '../components/menu-item.react.js';
+import Menu from '../components/menu.react.js';
+import SidebarPromoteModal from '../modals/chat/sidebar-promote-modal.react.js';
+import ConfirmLeaveThreadModal from '../modals/threads/confirm-leave-thread-modal.react.js';
+import ComposeSubchannelModal from '../modals/threads/create/compose-subchannel-modal.react.js';
+import ThreadMembersModal from '../modals/threads/members/members-modal.react.js';
+import ThreadNotificationsModal from '../modals/threads/notifications/notifications-modal.react.js';
+import ThreadSettingsModal from '../modals/threads/settings/thread-settings-modal.react.js';
+import SidebarsModal from '../modals/threads/sidebars/sidebars-modal.react.js';
+import SubchannelsModal from '../modals/threads/subchannels/subchannels-modal.react.js';
+import { useSelector } from '../redux/redux-utils.js';
import css from './thread-menu.css';
type ThreadMenuProps = {
diff --git a/web/chat/thread-top-bar.react.js b/web/chat/thread-top-bar.react.js
--- a/web/chat/thread-top-bar.react.js
+++ b/web/chat/thread-top-bar.react.js
@@ -2,12 +2,12 @@
import * as React from 'react';
-import { threadIsPending } from 'lib/shared/thread-utils';
-import type { ThreadInfo } from 'lib/types/thread-types';
-import { useResolvedThreadInfo } from 'lib/utils/entity-helpers';
+import { threadIsPending } from 'lib/shared/thread-utils.js';
+import type { ThreadInfo } from 'lib/types/thread-types.js';
+import { useResolvedThreadInfo } from 'lib/utils/entity-helpers.js';
-import ThreadAncestors from './chat-thread-ancestors.react';
-import ThreadMenu from './thread-menu.react';
+import ThreadAncestors from './chat-thread-ancestors.react.js';
+import ThreadMenu from './thread-menu.react.js';
import css from './thread-top-bar.css';
type threadTopBarProps = {
diff --git a/web/chat/tooltip-provider.js b/web/chat/tooltip-provider.js
--- a/web/chat/tooltip-provider.js
+++ b/web/chat/tooltip-provider.js
@@ -4,9 +4,9 @@
import invariant from 'invariant';
import * as React from 'react';
-import type { SetState } from 'lib/types/hook-types';
+import type { SetState } from 'lib/types/hook-types.js';
-import type { TooltipPositionStyle } from '../utils/tooltip-utils';
+import type { TooltipPositionStyle } from '../utils/tooltip-utils.js';
import css from './tooltip.css';
const onMouseLeaveSourceDisappearTimeoutMs = 200;
diff --git a/web/chat/typeahead-tooltip.react.js b/web/chat/typeahead-tooltip.react.js
--- a/web/chat/typeahead-tooltip.react.js
+++ b/web/chat/typeahead-tooltip.react.js
@@ -3,17 +3,17 @@
import classNames from 'classnames';
import * as React from 'react';
-import type { TypeaheadMatchedStrings } from 'lib/shared/typeahead-utils';
-import type { RelativeMemberInfo } from 'lib/types/thread-types';
-import { leastPositiveResidue } from 'lib/utils/math-utils';
+import type { TypeaheadMatchedStrings } from 'lib/shared/typeahead-utils.js';
+import type { RelativeMemberInfo } from 'lib/types/thread-types.js';
+import { leastPositiveResidue } from 'lib/utils/math-utils.js';
-import type { InputState } from '../input/input-state';
+import type { InputState } from '../input/input-state.js';
import {
getTypeaheadOverlayScroll,
getTypeaheadTooltipActions,
getTypeaheadTooltipButtons,
getTypeaheadTooltipPosition,
-} from '../utils/typeahead-utils';
+} from '../utils/typeahead-utils.js';
import css from './typeahead-tooltip.css';
export type TypeaheadTooltipProps = {
diff --git a/web/components/clear-search-button.react.js b/web/components/clear-search-button.react.js
--- a/web/components/clear-search-button.react.js
+++ b/web/components/clear-search-button.react.js
@@ -5,7 +5,7 @@
import SWMansionIcon from 'lib/components/SWMansionIcon.react.js';
-import Button from './button.react';
+import Button from './button.react.js';
import css from './search.css';
type ClearSearchButtonProps = {
diff --git a/web/components/enum-settings-option.react.js b/web/components/enum-settings-option.react.js
--- a/web/components/enum-settings-option.react.js
+++ b/web/components/enum-settings-option.react.js
@@ -3,10 +3,10 @@
import classnames from 'classnames';
import * as React from 'react';
-import Checkbox from './checkbox.react';
+import Checkbox from './checkbox.react.js';
import EnumSettingsOptionInfo from './enum-settings-option-info.react.js';
import css from './enum-settings-option.css';
-import Radio from './radio.react';
+import Radio from './radio.react.js';
const iconPositionClassnames = {
top: css.optionIconTop,
diff --git a/web/components/label.react.js b/web/components/label.react.js
--- a/web/components/label.react.js
+++ b/web/components/label.react.js
@@ -4,7 +4,7 @@
import SWMansionIcon from 'lib/components/SWMansionIcon.react.js';
-import Button from './button.react';
+import Button from './button.react.js';
import css from './label.css';
type Props = {
diff --git a/web/components/menu-item.react.js b/web/components/menu-item.react.js
--- a/web/components/menu-item.react.js
+++ b/web/components/menu-item.react.js
@@ -7,7 +7,7 @@
type Icon,
} from 'lib/components/SWMansionIcon.react.js';
-import Button from './button.react';
+import Button from './button.react.js';
import css from './menu.css';
type MenuItemProps = {
diff --git a/web/components/menu.react.js b/web/components/menu.react.js
--- a/web/components/menu.react.js
+++ b/web/components/menu.react.js
@@ -3,7 +3,7 @@
import classnames from 'classnames';
import * as React from 'react';
-import { useRenderMenu } from '../menu-provider.react';
+import { useRenderMenu } from '../menu-provider.react.js';
import css from './menu.css';
type MenuVariant = 'thread-actions' | 'member-actions';
diff --git a/web/components/search.react.js b/web/components/search.react.js
--- a/web/components/search.react.js
+++ b/web/components/search.react.js
@@ -4,7 +4,7 @@
import SWMansionIcon from 'lib/components/SWMansionIcon.react.js';
-import ClearSearchButton from './clear-search-button.react';
+import ClearSearchButton from './clear-search-button.react.js';
import css from './search.css';
type Props = {
diff --git a/web/components/stepper.react.js b/web/components/stepper.react.js
--- a/web/components/stepper.react.js
+++ b/web/components/stepper.react.js
@@ -3,8 +3,8 @@
import classnames from 'classnames';
import * as React from 'react';
-import LoadingIndicator from '../loading-indicator.react';
-import Button from './button.react';
+import LoadingIndicator from '../loading-indicator.react.js';
+import Button from './button.react.js';
import css from './stepper.css';
export type ButtonProps = {
diff --git a/web/components/tabs-header.js b/web/components/tabs-header.js
--- a/web/components/tabs-header.js
+++ b/web/components/tabs-header.js
@@ -3,7 +3,7 @@
import classnames from 'classnames';
import * as React from 'react';
-import Button from './button.react';
+import Button from './button.react.js';
import css from './tabs.css';
type Props<T: string> = {
diff --git a/web/components/tabs.react.js b/web/components/tabs.react.js
--- a/web/components/tabs.react.js
+++ b/web/components/tabs.react.js
@@ -2,7 +2,7 @@
import * as React from 'react';
-import TabsHeader from './tabs-header';
+import TabsHeader from './tabs-header.js';
import css from './tabs.css';
type TabsContainerProps<T: string> = {
diff --git a/web/electron.js b/web/electron.js
--- a/web/electron.js
+++ b/web/electron.js
@@ -1,6 +1,6 @@
// @flow
-import type { ElectronBridge } from 'lib/types/electron-types';
+import type { ElectronBridge } from 'lib/types/electron-types.js';
declare var electronContextBridge: void | ElectronBridge;
diff --git a/web/error-boundary.react.js b/web/error-boundary.react.js
--- a/web/error-boundary.react.js
+++ b/web/error-boundary.react.js
@@ -2,7 +2,7 @@
import * as React from 'react';
-import type { ErrorInfo, ErrorData } from 'lib/types/report-types';
+import type { ErrorInfo, ErrorData } from 'lib/types/report-types.js';
import css from './error-boundary.css';
diff --git a/web/input/input-state-container.react.js b/web/input/input-state-container.react.js
--- a/web/input/input-state-container.react.js
+++ b/web/input/input-state-container.react.js
@@ -2,12 +2,12 @@
import { detect as detectBrowser } from 'detect-browser';
import invariant from 'invariant';
-import _groupBy from 'lodash/fp/groupBy';
-import _keyBy from 'lodash/fp/keyBy';
-import _omit from 'lodash/fp/omit';
-import _partition from 'lodash/fp/partition';
-import _sortBy from 'lodash/fp/sortBy';
-import _memoize from 'lodash/memoize';
+import _groupBy from 'lodash/fp/groupBy.js';
+import _keyBy from 'lodash/fp/keyBy.js';
+import _omit from 'lodash/fp/omit.js';
+import _partition from 'lodash/fp/partition.js';
+import _sortBy from 'lodash/fp/sortBy.js';
+import _memoize from 'lodash/memoize.js';
import * as React from 'react';
import { useDispatch } from 'react-redux';
import { createSelector } from 'reselect';
@@ -18,74 +18,74 @@
legacySendMultimediaMessage,
sendTextMessageActionTypes,
sendTextMessage,
-} from 'lib/actions/message-actions';
-import { queueReportsActionType } from 'lib/actions/report-actions';
-import { newThread } from 'lib/actions/thread-actions';
+} from 'lib/actions/message-actions.js';
+import { queueReportsActionType } from 'lib/actions/report-actions.js';
+import { newThread } from 'lib/actions/thread-actions.js';
import {
uploadMultimedia,
updateMultimediaMessageMediaActionType,
deleteUpload,
type MultimediaUploadCallbacks,
type MultimediaUploadExtras,
-} from 'lib/actions/upload-actions';
+} from 'lib/actions/upload-actions.js';
import {
useModalContext,
type PushModal,
-} from 'lib/components/modal-provider.react';
-import { getNextLocalUploadID } from 'lib/media/media-utils';
-import { pendingToRealizedThreadIDsSelector } from 'lib/selectors/thread-selectors';
+} from 'lib/components/modal-provider.react.js';
+import { getNextLocalUploadID } from 'lib/media/media-utils.js';
+import { pendingToRealizedThreadIDsSelector } from 'lib/selectors/thread-selectors.js';
import {
createMediaMessageInfo,
localIDPrefix,
-} from 'lib/shared/message-utils';
+} from 'lib/shared/message-utils.js';
import {
createRealThreadFromPendingThread,
draftKeyFromThreadID,
threadIsPending,
-} from 'lib/shared/thread-utils';
-import type { CalendarQuery } from 'lib/types/entry-types';
+} from 'lib/shared/thread-utils.js';
+import type { CalendarQuery } from 'lib/types/entry-types.js';
import type {
UploadMultimediaResult,
MediaMissionStep,
MediaMissionFailure,
MediaMissionResult,
MediaMission,
-} from 'lib/types/media-types';
+} from 'lib/types/media-types.js';
import {
messageTypes,
type RawMessageInfo,
type RawMultimediaMessageInfo,
type SendMessageResult,
type SendMessagePayload,
-} from 'lib/types/message-types';
-import type { RawImagesMessageInfo } from 'lib/types/messages/images';
-import type { RawMediaMessageInfo } from 'lib/types/messages/media';
-import type { RawTextMessageInfo } from 'lib/types/messages/text';
-import type { Dispatch } from 'lib/types/redux-types';
-import { reportTypes } from 'lib/types/report-types';
+} from 'lib/types/message-types.js';
+import type { RawImagesMessageInfo } from 'lib/types/messages/images.js';
+import type { RawMediaMessageInfo } from 'lib/types/messages/media.js';
+import type { RawTextMessageInfo } from 'lib/types/messages/text.js';
+import type { Dispatch } from 'lib/types/redux-types.js';
+import { reportTypes } from 'lib/types/report-types.js';
import type {
ClientNewThreadRequest,
NewThreadResult,
ThreadInfo,
-} from 'lib/types/thread-types';
+} from 'lib/types/thread-types.js';
import {
type DispatchActionPromise,
useServerCall,
useDispatchActionPromise,
-} from 'lib/utils/action-utils';
-import { getConfig } from 'lib/utils/config';
-import { getMessageForException, cloneError } from 'lib/utils/errors';
-
-import { validateFile, preloadImage } from '../media/media-utils';
-import InvalidUploadModal from '../modals/chat/invalid-upload.react';
-import { useSelector } from '../redux/redux-utils';
-import { nonThreadCalendarQuery } from '../selectors/nav-selectors';
+} from 'lib/utils/action-utils.js';
+import { getConfig } from 'lib/utils/config.js';
+import { getMessageForException, cloneError } from 'lib/utils/errors.js';
+
+import { validateFile, preloadImage } from '../media/media-utils.js';
+import InvalidUploadModal from '../modals/chat/invalid-upload.react.js';
+import { useSelector } from '../redux/redux-utils.js';
+import { nonThreadCalendarQuery } from '../selectors/nav-selectors.js';
import {
type PendingMultimediaUpload,
type InputState,
type TypeaheadState,
InputStateContext,
-} from './input-state';
+} from './input-state.js';
const browser = detectBrowser();
const exifRotate =
diff --git a/web/input/input-state.js b/web/input/input-state.js
--- a/web/input/input-state.js
+++ b/web/input/input-state.js
@@ -6,9 +6,9 @@
type MediaType,
type Dimensions,
type MediaMissionStep,
-} from 'lib/types/media-types';
-import type { RawTextMessageInfo } from 'lib/types/messages/text';
-import type { ThreadInfo, RelativeMemberInfo } from 'lib/types/thread-types';
+} from 'lib/types/media-types.js';
+import type { RawTextMessageInfo } from 'lib/types/messages/text.js';
+import type { ThreadInfo, RelativeMemberInfo } from 'lib/types/thread-types.js';
export type PendingMultimediaUpload = {
localID: string,
diff --git a/web/loading-indicator.react.js b/web/loading-indicator.react.js
--- a/web/loading-indicator.react.js
+++ b/web/loading-indicator.react.js
@@ -4,7 +4,7 @@
import * as React from 'react';
import tinycolor from 'tinycolor2';
-import type { LoadingStatus } from 'lib/types/loading-types';
+import type { LoadingStatus } from 'lib/types/loading-types.js';
import css from './style.css';
diff --git a/web/markdown/markdown-spoiler.react.js b/web/markdown/markdown-spoiler.react.js
--- a/web/markdown/markdown-spoiler.react.js
+++ b/web/markdown/markdown-spoiler.react.js
@@ -2,7 +2,7 @@
import * as React from 'react';
-import type { ReactElement } from 'lib/shared/markdown';
+import type { ReactElement } from 'lib/shared/markdown.js';
import css from './markdown.css';
diff --git a/web/markdown/markdown.react.js b/web/markdown/markdown.react.js
--- a/web/markdown/markdown.react.js
+++ b/web/markdown/markdown.react.js
@@ -5,7 +5,7 @@
import * as SimpleMarkdown from 'simple-markdown';
import css from './markdown.css';
-import type { MarkdownRules } from './rules.react';
+import type { MarkdownRules } from './rules.react.js';
type Props = {
+children: string,
diff --git a/web/markdown/rules.react.js b/web/markdown/rules.react.js
--- a/web/markdown/rules.react.js
+++ b/web/markdown/rules.react.js
@@ -1,15 +1,15 @@
// @flow
-import _memoize from 'lodash/memoize';
+import _memoize from 'lodash/memoize.js';
import * as React from 'react';
import * as SimpleMarkdown from 'simple-markdown';
-import { relativeMemberInfoSelectorForMembersOfThread } from 'lib/selectors/user-selectors';
-import * as SharedMarkdown from 'lib/shared/markdown';
-import type { RelativeMemberInfo } from 'lib/types/thread-types';
+import { relativeMemberInfoSelectorForMembersOfThread } from 'lib/selectors/user-selectors.js';
+import * as SharedMarkdown from 'lib/shared/markdown.js';
+import type { RelativeMemberInfo } from 'lib/types/thread-types.js';
-import { useSelector } from '../redux/redux-utils';
-import MarkdownSpoiler from './markdown-spoiler.react';
+import { useSelector } from '../redux/redux-utils.js';
+import MarkdownSpoiler from './markdown-spoiler.react.js';
export type MarkdownRules = {
+simpleMarkdownRules: SharedMarkdown.ParserRules,
diff --git a/web/media/blob-utils.js b/web/media/blob-utils.js
--- a/web/media/blob-utils.js
+++ b/web/media/blob-utils.js
@@ -6,10 +6,10 @@
MediaType,
MediaMissionStep,
MediaMissionFailure,
-} from 'lib/types/media-types';
-import { getMessageForException } from 'lib/utils/errors';
+} from 'lib/types/media-types.js';
+import { getMessageForException } from 'lib/utils/errors.js';
-import { determineFileType } from './file-utils';
+import { determineFileType } from './file-utils.js';
function blobToArrayBuffer(blob: Blob): Promise<ArrayBuffer> {
const fileReader = new FileReader();
diff --git a/web/media/file-utils.js b/web/media/file-utils.js
--- a/web/media/file-utils.js
+++ b/web/media/file-utils.js
@@ -9,9 +9,9 @@
fileInfoFromData,
type FileDataInfo,
readableFilename,
-} from 'lib/media/file-utils';
-import type { DetermineFileTypeMediaMissionStep } from 'lib/types/media-types';
-import { getMessageForException } from 'lib/utils/errors';
+} from 'lib/media/file-utils.js';
+import type { DetermineFileTypeMediaMissionStep } from 'lib/types/media-types.js';
+import { getMessageForException } from 'lib/utils/errors.js';
function deepFileInfoFromData(data: Buffer | ArrayBuffer): FileDataInfo {
const result = fileInfoFromData(data);
diff --git a/web/media/image-utils.js b/web/media/image-utils.js
--- a/web/media/image-utils.js
+++ b/web/media/image-utils.js
@@ -2,8 +2,8 @@
import EXIF from 'exif-js';
-import type { GetOrientationMediaMissionStep } from 'lib/types/media-types';
-import { getMessageForException } from 'lib/utils/errors';
+import type { GetOrientationMediaMissionStep } from 'lib/types/media-types.js';
+import { getMessageForException } from 'lib/utils/errors.js';
function getEXIFOrientation(file: File): Promise<?number> {
return new Promise(resolve => {
diff --git a/web/media/media-utils.js b/web/media/media-utils.js
--- a/web/media/media-utils.js
+++ b/web/media/media-utils.js
@@ -5,11 +5,11 @@
Dimensions,
MediaMissionStep,
MediaMissionFailure,
-} from 'lib/types/media-types';
-import { getMessageForException } from 'lib/utils/errors';
+} from 'lib/types/media-types.js';
+import { getMessageForException } from 'lib/utils/errors.js';
-import { probeFile } from './blob-utils';
-import { getOrientation } from './image-utils';
+import { probeFile } from './blob-utils.js';
+import { getOrientation } from './image-utils.js';
async function preloadImage(
uri: string,
diff --git a/web/media/multimedia-modal.react.js b/web/media/multimedia-modal.react.js
--- a/web/media/multimedia-modal.react.js
+++ b/web/media/multimedia-modal.react.js
@@ -4,7 +4,7 @@
import * as React from 'react';
import { XCircle as XCircleIcon } from 'react-feather';
-import { useModalContext } from 'lib/components/modal-provider.react';
+import { useModalContext } from 'lib/components/modal-provider.react.js';
import css from './media.css';
diff --git a/web/media/multimedia.react.js b/web/media/multimedia.react.js
--- a/web/media/multimedia.react.js
+++ b/web/media/multimedia.react.js
@@ -13,13 +13,13 @@
import {
useModalContext,
type PushModal,
-} from 'lib/components/modal-provider.react';
-import type { MediaType } from 'lib/types/media-types';
+} from 'lib/components/modal-provider.react.js';
+import type { MediaType } from 'lib/types/media-types.js';
-import Button from '../components/button.react';
-import { type PendingMultimediaUpload } from '../input/input-state';
+import Button from '../components/button.react.js';
+import { type PendingMultimediaUpload } from '../input/input-state.js';
import css from './media.css';
-import MultimediaModal from './multimedia-modal.react';
+import MultimediaModal from './multimedia-modal.react.js';
type BaseProps = {
+uri: string,
diff --git a/web/menu-provider.react.js b/web/menu-provider.react.js
--- a/web/menu-provider.react.js
+++ b/web/menu-provider.react.js
@@ -3,7 +3,7 @@
import invariant from 'invariant';
import * as React from 'react';
-import type { SetState } from 'lib/types/hook-types';
+import type { SetState } from 'lib/types/hook-types.js';
import css from './menu.css';
diff --git a/web/modals/account/log-in-first-modal.react.js b/web/modals/account/log-in-first-modal.react.js
--- a/web/modals/account/log-in-first-modal.react.js
+++ b/web/modals/account/log-in-first-modal.react.js
@@ -5,11 +5,11 @@
import {
useModalContext,
type PushModal,
-} from 'lib/components/modal-provider.react';
+} from 'lib/components/modal-provider.react.js';
import css from '../../style.css';
-import Modal from '../modal.react';
-import LogInModal from './log-in-modal.react';
+import Modal from '../modal.react.js';
+import LogInModal from './log-in-modal.react.js';
type BaseProps = {
+inOrderTo: string,
diff --git a/web/modals/account/log-in-modal.react.js b/web/modals/account/log-in-modal.react.js
--- a/web/modals/account/log-in-modal.react.js
+++ b/web/modals/account/log-in-modal.react.js
@@ -2,10 +2,10 @@
import * as React from 'react';
-import { useModalContext } from 'lib/components/modal-provider.react';
+import { useModalContext } from 'lib/components/modal-provider.react.js';
-import LoginForm from '../../account/log-in-form.react';
-import Modal from '../modal.react';
+import LoginForm from '../../account/log-in-form.react.js';
+import Modal from '../modal.react.js';
function LoginModal(): React.Node {
const modalContext = useModalContext();
diff --git a/web/modals/alert.react.js b/web/modals/alert.react.js
--- a/web/modals/alert.react.js
+++ b/web/modals/alert.react.js
@@ -2,11 +2,11 @@
import * as React from 'react';
-import { useModalContext } from 'lib/components/modal-provider.react';
+import { useModalContext } from 'lib/components/modal-provider.react.js';
-import Button from '../components/button.react';
+import Button from '../components/button.react.js';
import css from './alert.css';
-import Modal from './modal.react';
+import Modal from './modal.react.js';
type AlertProps = {
+title: string,
diff --git a/web/modals/chat/message-reactions-modal.react.js b/web/modals/chat/message-reactions-modal.react.js
--- a/web/modals/chat/message-reactions-modal.react.js
+++ b/web/modals/chat/message-reactions-modal.react.js
@@ -2,10 +2,10 @@
import * as React from 'react';
-import type { MessageReactionInfo } from 'lib/selectors/chat-selectors';
-import { useMessageReactionsList } from 'lib/shared/reaction-utils';
+import type { MessageReactionInfo } from 'lib/selectors/chat-selectors.js';
+import { useMessageReactionsList } from 'lib/shared/reaction-utils.js';
-import Modal from '../modal.react';
+import Modal from '../modal.react.js';
import css from './message-reactions-modal.css';
type Props = {
diff --git a/web/modals/chat/sidebar-promote-modal.react.js b/web/modals/chat/sidebar-promote-modal.react.js
--- a/web/modals/chat/sidebar-promote-modal.react.js
+++ b/web/modals/chat/sidebar-promote-modal.react.js
@@ -2,11 +2,11 @@
import * as React from 'react';
-import type { ThreadInfo } from 'lib/types/thread-types';
-import { useResolvedThreadInfo } from 'lib/utils/entity-helpers';
+import type { ThreadInfo } from 'lib/types/thread-types.js';
+import { useResolvedThreadInfo } from 'lib/utils/entity-helpers.js';
-import Button from '../../components/button.react';
-import Modal from '../modal.react';
+import Button from '../../components/button.react.js';
+import Modal from '../modal.react.js';
import css from './sidebar-promote-modal.css';
type Props = {
diff --git a/web/modals/components/add-members-group.react.js b/web/modals/components/add-members-group.react.js
--- a/web/modals/components/add-members-group.react.js
+++ b/web/modals/components/add-members-group.react.js
@@ -2,9 +2,9 @@
import * as React from 'react';
-import type { UserListItem } from 'lib/types/user-types';
+import type { UserListItem } from 'lib/types/user-types.js';
-import AddMembersItem from './add-members-item.react';
+import AddMembersItem from './add-members-item.react.js';
import css from './add-members.css';
type AddMemberItemGroupProps = {
diff --git a/web/modals/components/add-members-item.react.js b/web/modals/components/add-members-item.react.js
--- a/web/modals/components/add-members-item.react.js
+++ b/web/modals/components/add-members-item.react.js
@@ -2,9 +2,9 @@
import * as React from 'react';
-import type { UserListItem } from 'lib/types/user-types';
+import type { UserListItem } from 'lib/types/user-types.js';
-import Button from '../../components/button.react';
+import Button from '../../components/button.react.js';
import css from './add-members.css';
type AddMembersItemProps = {
diff --git a/web/modals/components/add-members-list.react.js b/web/modals/components/add-members-list.react.js
--- a/web/modals/components/add-members-list.react.js
+++ b/web/modals/components/add-members-list.react.js
@@ -2,9 +2,9 @@
import * as React from 'react';
-import type { UserListItem } from 'lib/types/user-types';
+import type { UserListItem } from 'lib/types/user-types.js';
-import AddMembersItemGroup from './add-members-group.react';
+import AddMembersItemGroup from './add-members-group.react.js';
type MemberGroupItem = {
+header: ?string,
diff --git a/web/modals/concurrent-modification-modal.react.js b/web/modals/concurrent-modification-modal.react.js
--- a/web/modals/concurrent-modification-modal.react.js
+++ b/web/modals/concurrent-modification-modal.react.js
@@ -2,11 +2,11 @@
import * as React from 'react';
-import { useModalContext } from 'lib/components/modal-provider.react';
+import { useModalContext } from 'lib/components/modal-provider.react.js';
-import Button from '../components/button.react';
+import Button from '../components/button.react.js';
import css from './concurrent-modification-modal.css';
-import Modal from './modal.react';
+import Modal from './modal.react.js';
type Props = {
+onRefresh: () => void,
diff --git a/web/modals/history/history-entry.react.js b/web/modals/history/history-entry.react.js
--- a/web/modals/history/history-entry.react.js
+++ b/web/modals/history/history-entry.react.js
@@ -7,30 +7,30 @@
import {
restoreEntryActionTypes,
restoreEntry,
-} from 'lib/actions/entry-actions';
-import { useENSNames } from 'lib/hooks/ens-cache';
-import { createLoadingStatusSelector } from 'lib/selectors/loading-selectors';
-import { threadInfoSelector } from 'lib/selectors/thread-selectors';
-import { colorIsDark } from 'lib/shared/thread-utils';
+} from 'lib/actions/entry-actions.js';
+import { useENSNames } from 'lib/hooks/ens-cache.js';
+import { createLoadingStatusSelector } from 'lib/selectors/loading-selectors.js';
+import { threadInfoSelector } from 'lib/selectors/thread-selectors.js';
+import { colorIsDark } from 'lib/shared/thread-utils.js';
import {
type EntryInfo,
type RestoreEntryInfo,
type RestoreEntryResult,
type CalendarQuery,
-} from 'lib/types/entry-types';
-import type { LoadingStatus } from 'lib/types/loading-types';
-import type { ResolvedThreadInfo } from 'lib/types/thread-types';
-import type { UserInfo } from 'lib/types/user-types';
+} from 'lib/types/entry-types.js';
+import type { LoadingStatus } from 'lib/types/loading-types.js';
+import type { ResolvedThreadInfo } from 'lib/types/thread-types.js';
+import type { UserInfo } from 'lib/types/user-types.js';
import {
type DispatchActionPromise,
useDispatchActionPromise,
useServerCall,
-} from 'lib/utils/action-utils';
-import { useResolvedThreadInfo } from 'lib/utils/entity-helpers';
+} from 'lib/utils/action-utils.js';
+import { useResolvedThreadInfo } from 'lib/utils/entity-helpers.js';
-import LoadingIndicator from '../../loading-indicator.react';
-import { useSelector } from '../../redux/redux-utils';
-import { nonThreadCalendarQuery } from '../../selectors/nav-selectors';
+import LoadingIndicator from '../../loading-indicator.react.js';
+import { useSelector } from '../../redux/redux-utils.js';
+import { nonThreadCalendarQuery } from '../../selectors/nav-selectors.js';
import css from './history.css';
type BaseProps = {
diff --git a/web/modals/history/history-modal.react.js b/web/modals/history/history-modal.react.js
--- a/web/modals/history/history-modal.react.js
+++ b/web/modals/history/history-modal.react.js
@@ -2,10 +2,10 @@
import classNames from 'classnames';
import invariant from 'invariant';
-import _filter from 'lodash/fp/filter';
-import _flow from 'lodash/fp/flow';
-import _map from 'lodash/fp/map';
-import _unionBy from 'lodash/fp/unionBy';
+import _filter from 'lodash/fp/filter.js';
+import _flow from 'lodash/fp/flow.js';
+import _map from 'lodash/fp/map.js';
+import _unionBy from 'lodash/fp/unionBy.js';
import * as React from 'react';
import {
@@ -13,31 +13,34 @@
fetchEntries,
fetchRevisionsForEntryActionTypes,
fetchRevisionsForEntry,
-} from 'lib/actions/entry-actions';
-import { useModalContext } from 'lib/components/modal-provider.react';
-import { nonExcludeDeletedCalendarFiltersSelector } from 'lib/selectors/calendar-filter-selectors';
-import { createLoadingStatusSelector } from 'lib/selectors/loading-selectors';
+} from 'lib/actions/entry-actions.js';
+import { useModalContext } from 'lib/components/modal-provider.react.js';
+import { nonExcludeDeletedCalendarFiltersSelector } from 'lib/selectors/calendar-filter-selectors.js';
+import { createLoadingStatusSelector } from 'lib/selectors/loading-selectors.js';
import type {
EntryInfo,
CalendarQuery,
FetchEntryInfosResult,
-} from 'lib/types/entry-types';
-import { type CalendarFilter } from 'lib/types/filter-types';
-import type { HistoryMode, HistoryRevisionInfo } from 'lib/types/history-types';
-import type { LoadingStatus } from 'lib/types/loading-types';
+} from 'lib/types/entry-types.js';
+import { type CalendarFilter } from 'lib/types/filter-types.js';
+import type {
+ HistoryMode,
+ HistoryRevisionInfo,
+} from 'lib/types/history-types.js';
+import type { LoadingStatus } from 'lib/types/loading-types.js';
import {
type DispatchActionPromise,
useServerCall,
useDispatchActionPromise,
-} from 'lib/utils/action-utils';
-import { prettyDateWithoutDay } from 'lib/utils/date-utils';
+} from 'lib/utils/action-utils.js';
+import { prettyDateWithoutDay } from 'lib/utils/date-utils.js';
-import LoadingIndicator from '../../loading-indicator.react';
-import { useSelector } from '../../redux/redux-utils';
-import { allDaysToEntries } from '../../selectors/entry-selectors';
-import Modal from '../modal.react';
-import HistoryEntry from './history-entry.react';
-import HistoryRevision from './history-revision.react';
+import LoadingIndicator from '../../loading-indicator.react.js';
+import { useSelector } from '../../redux/redux-utils.js';
+import { allDaysToEntries } from '../../selectors/entry-selectors.js';
+import Modal from '../modal.react.js';
+import HistoryEntry from './history-entry.react.js';
+import HistoryRevision from './history-revision.react.js';
import css from './history.css';
type BaseProps = {
diff --git a/web/modals/history/history-revision.react.js b/web/modals/history/history-revision.react.js
--- a/web/modals/history/history-revision.react.js
+++ b/web/modals/history/history-revision.react.js
@@ -5,12 +5,12 @@
import * as React from 'react';
import TimeAgo from 'react-timeago';
-import { useENSNames } from 'lib/hooks/ens-cache';
-import { threadInfoSelector } from 'lib/selectors/thread-selectors';
-import { colorIsDark } from 'lib/shared/thread-utils';
-import type { HistoryRevisionInfo } from 'lib/types/history-types';
+import { useENSNames } from 'lib/hooks/ens-cache.js';
+import { threadInfoSelector } from 'lib/selectors/thread-selectors.js';
+import { colorIsDark } from 'lib/shared/thread-utils.js';
+import type { HistoryRevisionInfo } from 'lib/types/history-types.js';
-import { useSelector } from '../../redux/redux-utils';
+import { useSelector } from '../../redux/redux-utils.js';
import css from './history.css';
type Props = {
diff --git a/web/modals/modal.react.js b/web/modals/modal.react.js
--- a/web/modals/modal.react.js
+++ b/web/modals/modal.react.js
@@ -3,12 +3,12 @@
import classNames from 'classnames';
import * as React from 'react';
-import ModalOverlay from 'lib/components/modal-overlay.react';
+import ModalOverlay from 'lib/components/modal-overlay.react.js';
import SWMansionIcon, {
type Icon,
} from 'lib/components/SWMansionIcon.react.js';
-import Button from '../components/button.react';
+import Button from '../components/button.react.js';
import css from './modal.css';
export type ModalSize = 'small' | 'large' | 'fit-content';
diff --git a/web/modals/search-modal.react.js b/web/modals/search-modal.react.js
--- a/web/modals/search-modal.react.js
+++ b/web/modals/search-modal.react.js
@@ -2,8 +2,8 @@
import * as React from 'react';
-import Search from '../components/search.react';
-import Modal, { type ModalOverridableProps } from './modal.react';
+import Search from '../components/search.react.js';
+import Modal, { type ModalOverridableProps } from './modal.react.js';
import css from './search-modal.css';
type Props = {
diff --git a/web/modals/terms-and-privacy-modal.react.js b/web/modals/terms-and-privacy-modal.react.js
--- a/web/modals/terms-and-privacy-modal.react.js
+++ b/web/modals/terms-and-privacy-modal.react.js
@@ -17,7 +17,7 @@
import Button, { buttonThemes } from '../components/button.react.js';
import LoadingIndicator from '../loading-indicator.react.js';
import { useSelector } from '../redux/redux-utils.js';
-import Modal from './modal.react';
+import Modal from './modal.react.js';
import css from './terms-and-privacy-modal.css';
const loadingStatusSelector = createLoadingStatusSelector(
diff --git a/web/modals/threads/cant-leave-thread-modal.react.js b/web/modals/threads/cant-leave-thread-modal.react.js
--- a/web/modals/threads/cant-leave-thread-modal.react.js
+++ b/web/modals/threads/cant-leave-thread-modal.react.js
@@ -3,7 +3,7 @@
import * as React from 'react';
import Button from '../../components/button.react.js';
-import Modal from '../modal.react';
+import Modal from '../modal.react.js';
import css from './cant-leave-thread-modal.css';
type Props = {
diff --git a/web/modals/threads/color-selector-button.react.js b/web/modals/threads/color-selector-button.react.js
--- a/web/modals/threads/color-selector-button.react.js
+++ b/web/modals/threads/color-selector-button.react.js
@@ -4,7 +4,7 @@
import * as React from 'react';
import tinycolor from 'tinycolor2';
-import Button from '../../components/button.react';
+import Button from '../../components/button.react.js';
import css from './color-selector-button.css';
type ColorSelectorButtonProps = {
diff --git a/web/modals/threads/color-selector.react.js b/web/modals/threads/color-selector.react.js
--- a/web/modals/threads/color-selector.react.js
+++ b/web/modals/threads/color-selector.react.js
@@ -2,9 +2,9 @@
import * as React from 'react';
-import { selectedThreadColors } from 'lib/shared/thread-utils';
+import { selectedThreadColors } from 'lib/shared/thread-utils.js';
-import ColorSelectorButton from './color-selector-button.react';
+import ColorSelectorButton from './color-selector-button.react.js';
import css from './color-selector.css';
type ColorSelectorProps = {
diff --git a/web/modals/threads/confirm-leave-thread-modal.react.js b/web/modals/threads/confirm-leave-thread-modal.react.js
--- a/web/modals/threads/confirm-leave-thread-modal.react.js
+++ b/web/modals/threads/confirm-leave-thread-modal.react.js
@@ -2,11 +2,11 @@
import * as React from 'react';
-import { type ThreadInfo } from 'lib/types/thread-types';
-import { useResolvedThreadInfo } from 'lib/utils/entity-helpers';
+import { type ThreadInfo } from 'lib/types/thread-types.js';
+import { useResolvedThreadInfo } from 'lib/utils/entity-helpers.js';
-import Button, { buttonThemes } from '../../components/button.react';
-import Modal from '../modal.react';
+import Button, { buttonThemes } from '../../components/button.react.js';
+import Modal from '../modal.react.js';
import css from './confirm-leave-thread-modal.css';
type Props = {
diff --git a/web/modals/threads/create/compose-subchannel-modal.react.js b/web/modals/threads/create/compose-subchannel-modal.react.js
--- a/web/modals/threads/create/compose-subchannel-modal.react.js
+++ b/web/modals/threads/create/compose-subchannel-modal.react.js
@@ -2,25 +2,25 @@
import * as React from 'react';
import { useDispatch, useSelector } from 'react-redux';
-import { newThread, newThreadActionTypes } from 'lib/actions/thread-actions';
-import { createLoadingStatusSelector } from 'lib/selectors/loading-selectors';
-import type { ThreadInfo } from 'lib/types/thread-types';
-import { threadTypes } from 'lib/types/thread-types';
+import { newThread, newThreadActionTypes } from 'lib/actions/thread-actions.js';
+import { createLoadingStatusSelector } from 'lib/selectors/loading-selectors.js';
+import type { ThreadInfo } from 'lib/types/thread-types.js';
+import { threadTypes } from 'lib/types/thread-types.js';
import {
useDispatchActionPromise,
useServerCall,
-} from 'lib/utils/action-utils';
-import { useResolvedThreadInfo } from 'lib/utils/entity-helpers';
-import { trimText } from 'lib/utils/text-utils';
-
-import Stepper from '../../../components/stepper.react';
-import { updateNavInfoActionType } from '../../../redux/action-types';
-import { nonThreadCalendarQuery } from '../../../selectors/nav-selectors';
-import Modal from '../../modal.react';
+} from 'lib/utils/action-utils.js';
+import { useResolvedThreadInfo } from 'lib/utils/entity-helpers.js';
+import { trimText } from 'lib/utils/text-utils.js';
+
+import Stepper from '../../../components/stepper.react.js';
+import { updateNavInfoActionType } from '../../../redux/action-types.js';
+import { nonThreadCalendarQuery } from '../../../selectors/nav-selectors.js';
+import Modal from '../../modal.react.js';
import css from './compose-subchannel-modal.css';
-import SubchannelMembers from './steps/subchannel-members.react';
-import SubchannelSettings from './steps/subchannel-settings.react';
-import type { VisibilityType } from './steps/subchannel-settings.react';
+import SubchannelMembers from './steps/subchannel-members.react.js';
+import SubchannelSettings from './steps/subchannel-settings.react.js';
+import type { VisibilityType } from './steps/subchannel-settings.react.js';
type Props = {
+onClose: () => void,
diff --git a/web/modals/threads/create/steps/subchannel-members-list.react.js b/web/modals/threads/create/steps/subchannel-members-list.react.js
--- a/web/modals/threads/create/steps/subchannel-members-list.react.js
+++ b/web/modals/threads/create/steps/subchannel-members-list.react.js
@@ -3,12 +3,12 @@
import * as React from 'react';
import { useSelector } from 'react-redux';
-import { useENSNames } from 'lib/hooks/ens-cache';
-import { stringForUser } from 'lib/shared/user-utils';
-import type { ThreadInfo } from 'lib/types/thread-types';
-import type { UserListItem } from 'lib/types/user-types';
+import { useENSNames } from 'lib/hooks/ens-cache.js';
+import { stringForUser } from 'lib/shared/user-utils.js';
+import type { ThreadInfo } from 'lib/types/thread-types.js';
+import type { UserListItem } from 'lib/types/user-types.js';
-import AddMembersList from '../../../components/add-members-list.react';
+import AddMembersList from '../../../components/add-members-list.react.js';
type Props = {
+searchText: string,
diff --git a/web/modals/threads/create/steps/subchannel-members.react.js b/web/modals/threads/create/steps/subchannel-members.react.js
--- a/web/modals/threads/create/steps/subchannel-members.react.js
+++ b/web/modals/threads/create/steps/subchannel-members.react.js
@@ -3,12 +3,12 @@
import * as React from 'react';
import { useSelector } from 'react-redux';
-import { userStoreSearchIndex } from 'lib/selectors/user-selectors';
-import { useAncestorThreads } from 'lib/shared/ancestor-threads';
-import type { ThreadInfo } from 'lib/types/thread-types';
+import { userStoreSearchIndex } from 'lib/selectors/user-selectors.js';
+import { useAncestorThreads } from 'lib/shared/ancestor-threads.js';
+import type { ThreadInfo } from 'lib/types/thread-types.js';
-import Search from '../../../../components/search.react';
-import MembersList from './subchannel-members-list.react';
+import Search from '../../../../components/search.react.js';
+import MembersList from './subchannel-members-list.react.js';
import css from './subchannel-members.css';
type SubchannelMembersProps = {
diff --git a/web/modals/threads/create/steps/subchannel-settings.react.js b/web/modals/threads/create/steps/subchannel-settings.react.js
--- a/web/modals/threads/create/steps/subchannel-settings.react.js
+++ b/web/modals/threads/create/steps/subchannel-settings.react.js
@@ -3,12 +3,12 @@
import * as React from 'react';
import SWMansionIcon from 'lib/components/SWMansionIcon.react.js';
-import { threadTypeDescriptions } from 'lib/shared/thread-utils';
-import { threadTypes } from 'lib/types/thread-types';
+import { threadTypeDescriptions } from 'lib/shared/thread-utils.js';
+import { threadTypes } from 'lib/types/thread-types.js';
-import CommIcon from '../../../../CommIcon.react';
-import EnumSettingsOption from '../../../../components/enum-settings-option.react';
-import Input from '../../../input.react';
+import CommIcon from '../../../../CommIcon.react.js';
+import EnumSettingsOption from '../../../../components/enum-settings-option.react.js';
+import Input from '../../../input.react.js';
import css from './subchannel-settings.css';
const { COMMUNITY_OPEN_SUBTHREAD, COMMUNITY_SECRET_SUBTHREAD } = threadTypes;
diff --git a/web/modals/threads/members/add-members-list-content.react.js b/web/modals/threads/members/add-members-list-content.react.js
--- a/web/modals/threads/members/add-members-list-content.react.js
+++ b/web/modals/threads/members/add-members-list-content.react.js
@@ -1,12 +1,12 @@
// @flow
-import _groupBy from 'lodash/fp/groupBy';
-import _toPairs from 'lodash/fp/toPairs';
+import _groupBy from 'lodash/fp/groupBy.js';
+import _toPairs from 'lodash/fp/toPairs.js';
import * as React from 'react';
-import type { UserListItem } from 'lib/types/user-types';
+import type { UserListItem } from 'lib/types/user-types.js';
-import AddMembersList from '../../components/add-members-list.react';
+import AddMembersList from '../../components/add-members-list.react.js';
type Props = {
+userListItems: $ReadOnlyArray<UserListItem>,
diff --git a/web/modals/threads/members/add-members-modal.react.js b/web/modals/threads/members/add-members-modal.react.js
--- a/web/modals/threads/members/add-members-modal.react.js
+++ b/web/modals/threads/members/add-members-modal.react.js
@@ -5,25 +5,25 @@
import {
changeThreadSettingsActionTypes,
changeThreadSettings,
-} from 'lib/actions/thread-actions';
-import { useENSNames } from 'lib/hooks/ens-cache';
-import { threadInfoSelector } from 'lib/selectors/thread-selectors';
+} from 'lib/actions/thread-actions.js';
+import { useENSNames } from 'lib/hooks/ens-cache.js';
+import { threadInfoSelector } from 'lib/selectors/thread-selectors.js';
import {
userSearchIndexForPotentialMembers,
userInfoSelectorForPotentialMembers,
-} from 'lib/selectors/user-selectors';
-import { getPotentialMemberItems } from 'lib/shared/search-utils';
-import { threadActualMembers } from 'lib/shared/thread-utils';
+} from 'lib/selectors/user-selectors.js';
+import { getPotentialMemberItems } from 'lib/shared/search-utils.js';
+import { threadActualMembers } from 'lib/shared/thread-utils.js';
import {
useDispatchActionPromise,
useServerCall,
-} from 'lib/utils/action-utils';
+} from 'lib/utils/action-utils.js';
-import Button from '../../../components/button.react';
-import Label from '../../../components/label.react';
-import { useSelector } from '../../../redux/redux-utils';
-import SearchModal from '../../search-modal.react';
-import AddMembersListContent from './add-members-list-content.react';
+import Button from '../../../components/button.react.js';
+import Label from '../../../components/label.react.js';
+import { useSelector } from '../../../redux/redux-utils.js';
+import SearchModal from '../../search-modal.react.js';
+import AddMembersListContent from './add-members-list-content.react.js';
import css from './members-modal.css';
type ContentProps = {
diff --git a/web/modals/threads/members/member.react.js b/web/modals/threads/members/member.react.js
--- a/web/modals/threads/members/member.react.js
+++ b/web/modals/threads/members/member.react.js
@@ -6,7 +6,7 @@
import {
removeUsersFromThread,
changeThreadMemberRoles,
-} from 'lib/actions/thread-actions';
+} from 'lib/actions/thread-actions.js';
import SWMansionIcon from 'lib/components/SWMansionIcon.react.js';
import {
memberIsAdmin,
@@ -14,21 +14,21 @@
removeMemberFromThread,
switchMemberAdminRoleInThread,
getAvailableThreadMemberActions,
-} from 'lib/shared/thread-utils';
-import { stringForUser } from 'lib/shared/user-utils';
-import type { SetState } from 'lib/types/hook-types';
+} from 'lib/shared/thread-utils.js';
+import { stringForUser } from 'lib/shared/user-utils.js';
+import type { SetState } from 'lib/types/hook-types.js';
import {
type RelativeMemberInfo,
type ThreadInfo,
-} from 'lib/types/thread-types';
+} from 'lib/types/thread-types.js';
import {
useDispatchActionPromise,
useServerCall,
-} from 'lib/utils/action-utils';
+} from 'lib/utils/action-utils.js';
-import Label from '../../../components/label.react';
-import MenuItem from '../../../components/menu-item.react';
-import Menu from '../../../components/menu.react';
+import Label from '../../../components/label.react.js';
+import MenuItem from '../../../components/menu-item.react.js';
+import Menu from '../../../components/menu.react.js';
import css from './members-modal.css';
type Props = {
diff --git a/web/modals/threads/members/members-list.react.js b/web/modals/threads/members/members-list.react.js
--- a/web/modals/threads/members/members-list.react.js
+++ b/web/modals/threads/members/members-list.react.js
@@ -1,18 +1,18 @@
// @flow
import classNames from 'classnames';
-import _groupBy from 'lodash/fp/groupBy';
-import _toPairs from 'lodash/fp/toPairs';
+import _groupBy from 'lodash/fp/groupBy.js';
+import _toPairs from 'lodash/fp/toPairs.js';
import * as React from 'react';
-import { useENSNames } from 'lib/hooks/ens-cache';
-import { stringForUser } from 'lib/shared/user-utils';
+import { useENSNames } from 'lib/hooks/ens-cache.js';
+import { stringForUser } from 'lib/shared/user-utils.js';
import {
type ThreadInfo,
type RelativeMemberInfo,
-} from 'lib/types/thread-types';
+} from 'lib/types/thread-types.js';
-import ThreadMember from './member.react';
+import ThreadMember from './member.react.js';
import css from './members-modal.css';
type Props = {
diff --git a/web/modals/threads/members/members-modal.react.js b/web/modals/threads/members/members-modal.react.js
--- a/web/modals/threads/members/members-modal.react.js
+++ b/web/modals/threads/members/members-modal.react.js
@@ -2,25 +2,25 @@
import * as React from 'react';
-import { useModalContext } from 'lib/components/modal-provider.react';
-import { threadInfoSelector } from 'lib/selectors/thread-selectors';
-import { userStoreSearchIndex } from 'lib/selectors/user-selectors';
+import { useModalContext } from 'lib/components/modal-provider.react.js';
+import { threadInfoSelector } from 'lib/selectors/thread-selectors.js';
+import { userStoreSearchIndex } from 'lib/selectors/user-selectors.js';
import {
memberHasAdminPowers,
memberIsAdmin,
threadHasPermission,
-} from 'lib/shared/thread-utils';
+} from 'lib/shared/thread-utils.js';
import {
type RelativeMemberInfo,
threadPermissions,
-} from 'lib/types/thread-types';
-
-import Button from '../../../components/button.react';
-import Tabs from '../../../components/tabs.react';
-import { useSelector } from '../../../redux/redux-utils';
-import SearchModal from '../../search-modal.react';
-import AddMembersModal from './add-members-modal.react';
-import ThreadMembersList from './members-list.react';
+} from 'lib/types/thread-types.js';
+
+import Button from '../../../components/button.react.js';
+import Tabs from '../../../components/tabs.react.js';
+import { useSelector } from '../../../redux/redux-utils.js';
+import SearchModal from '../../search-modal.react.js';
+import AddMembersModal from './add-members-modal.react.js';
+import ThreadMembersList from './members-list.react.js';
import css from './members-modal.css';
type ContentProps = {
diff --git a/web/modals/threads/notifications/notifications-modal.react.js b/web/modals/threads/notifications/notifications-modal.react.js
--- a/web/modals/threads/notifications/notifications-modal.react.js
+++ b/web/modals/threads/notifications/notifications-modal.react.js
@@ -5,22 +5,22 @@
import {
updateSubscription,
updateSubscriptionActionTypes,
-} from 'lib/actions/user-actions';
-import { canPromoteSidebar } from 'lib/hooks/promote-sidebar.react';
-import { threadInfoSelector } from 'lib/selectors/thread-selectors';
-import { threadIsSidebar } from 'lib/shared/thread-utils';
+} from 'lib/actions/user-actions.js';
+import { canPromoteSidebar } from 'lib/hooks/promote-sidebar.react.js';
+import { threadInfoSelector } from 'lib/selectors/thread-selectors.js';
+import { threadIsSidebar } from 'lib/shared/thread-utils.js';
import {
useServerCall,
useDispatchActionPromise,
-} from 'lib/utils/action-utils';
+} from 'lib/utils/action-utils.js';
import AllNotifsIllustration from '../../../assets/all-notifs.react.js';
import BadgeNotifsIllustration from '../../../assets/badge-notifs.react.js';
import MutedNotifsIllustration from '../../../assets/muted-notifs.react.js';
-import Button from '../../../components/button.react';
-import EnumSettingsOption from '../../../components/enum-settings-option.react';
-import { useSelector } from '../../../redux/redux-utils';
-import Modal from '../../modal.react';
+import Button from '../../../components/button.react.js';
+import EnumSettingsOption from '../../../components/enum-settings-option.react.js';
+import { useSelector } from '../../../redux/redux-utils.js';
+import Modal from '../../modal.react.js';
import css from './notifications-modal.css';
type NotificationSettings = 'focused' | 'badge-only' | 'background';
diff --git a/web/modals/threads/settings/submit-section.react.js b/web/modals/threads/settings/submit-section.react.js
--- a/web/modals/threads/settings/submit-section.react.js
+++ b/web/modals/threads/settings/submit-section.react.js
@@ -3,8 +3,8 @@
import classnames from 'classnames';
import * as React from 'react';
-import type { ButtonProps } from '../../../components/button.react';
-import Button from '../../../components/button.react';
+import type { ButtonProps } from '../../../components/button.react.js';
+import Button from '../../../components/button.react.js';
import css from './submit-section.css';
type Props = {
diff --git a/web/modals/threads/settings/thread-settings-delete-tab.react.js b/web/modals/threads/settings/thread-settings-delete-tab.react.js
--- a/web/modals/threads/settings/thread-settings-delete-tab.react.js
+++ b/web/modals/threads/settings/thread-settings-delete-tab.react.js
@@ -5,18 +5,18 @@
import {
deleteThreadActionTypes,
deleteThread,
-} from 'lib/actions/thread-actions';
-import { useModalContext } from 'lib/components/modal-provider.react';
+} from 'lib/actions/thread-actions.js';
+import { useModalContext } from 'lib/components/modal-provider.react.js';
import SWMansionIcon from 'lib/components/SWMansionIcon.react.js';
-import { type SetState } from 'lib/types/hook-types';
-import { type ThreadInfo } from 'lib/types/thread-types';
+import { type SetState } from 'lib/types/hook-types.js';
+import { type ThreadInfo } from 'lib/types/thread-types.js';
import {
useDispatchActionPromise,
useServerCall,
-} from 'lib/utils/action-utils';
+} from 'lib/utils/action-utils.js';
-import { buttonThemes } from '../../../components/button.react';
-import SubmitSection from './submit-section.react';
+import { buttonThemes } from '../../../components/button.react.js';
+import SubmitSection from './submit-section.react.js';
import css from './thread-settings-delete-tab.css';
type ThreadSettingsDeleteTabProps = {
diff --git a/web/modals/threads/settings/thread-settings-general-tab.react.js b/web/modals/threads/settings/thread-settings-general-tab.react.js
--- a/web/modals/threads/settings/thread-settings-general-tab.react.js
+++ b/web/modals/threads/settings/thread-settings-general-tab.react.js
@@ -6,24 +6,24 @@
import {
changeThreadSettingsActionTypes,
changeThreadSettings,
-} from 'lib/actions/thread-actions';
-import { threadHasPermission } from 'lib/shared/thread-utils';
-import { type SetState } from 'lib/types/hook-types';
+} from 'lib/actions/thread-actions.js';
+import { threadHasPermission } from 'lib/shared/thread-utils.js';
+import { type SetState } from 'lib/types/hook-types.js';
import {
type ThreadInfo,
type ThreadChanges,
threadPermissions,
-} from 'lib/types/thread-types';
+} from 'lib/types/thread-types.js';
import {
useDispatchActionPromise,
useServerCall,
-} from 'lib/utils/action-utils';
-import { firstLine } from 'lib/utils/string-utils';
+} from 'lib/utils/action-utils.js';
+import { firstLine } from 'lib/utils/string-utils.js';
-import LoadingIndicator from '../../../loading-indicator.react';
-import Input from '../../input.react';
-import ColorSelector from '../color-selector.react';
-import SubmitSection from './submit-section.react';
+import LoadingIndicator from '../../../loading-indicator.react.js';
+import Input from '../../input.react.js';
+import ColorSelector from '../color-selector.react.js';
+import SubmitSection from './submit-section.react.js';
import css from './thread-settings-general-tab.css';
type ThreadSettingsGeneralTabProps = {
diff --git a/web/modals/threads/settings/thread-settings-modal.react.js b/web/modals/threads/settings/thread-settings-modal.react.js
--- a/web/modals/threads/settings/thread-settings-modal.react.js
+++ b/web/modals/threads/settings/thread-settings-modal.react.js
@@ -6,32 +6,32 @@
import {
deleteThreadActionTypes,
changeThreadSettingsActionTypes,
-} from 'lib/actions/thread-actions';
-import { useModalContext } from 'lib/components/modal-provider.react';
-import { createLoadingStatusSelector } from 'lib/selectors/loading-selectors';
-import { threadInfoSelector } from 'lib/selectors/thread-selectors';
-import { getAvailableRelationshipButtons } from 'lib/shared/relationship-utils';
+} from 'lib/actions/thread-actions.js';
+import { useModalContext } from 'lib/components/modal-provider.react.js';
+import { createLoadingStatusSelector } from 'lib/selectors/loading-selectors.js';
+import { threadInfoSelector } from 'lib/selectors/thread-selectors.js';
+import { getAvailableRelationshipButtons } from 'lib/shared/relationship-utils.js';
import {
threadHasPermission,
getSingleOtherUser,
threadUIName,
-} from 'lib/shared/thread-utils';
+} from 'lib/shared/thread-utils.js';
import {
type ThreadInfo,
threadTypes,
threadPermissions,
type ThreadChanges,
-} from 'lib/types/thread-types';
-import { useResolvedThreadInfo } from 'lib/utils/entity-helpers';
-
-import Tabs from '../../../components/tabs.react';
-import { useSelector } from '../../../redux/redux-utils';
-import Modal from '../../modal.react';
-import ThreadSettingsDeleteTab from './thread-settings-delete-tab.react';
-import ThreadSettingsGeneralTab from './thread-settings-general-tab.react';
+} from 'lib/types/thread-types.js';
+import { useResolvedThreadInfo } from 'lib/utils/entity-helpers.js';
+
+import Tabs from '../../../components/tabs.react.js';
+import { useSelector } from '../../../redux/redux-utils.js';
+import Modal from '../../modal.react.js';
+import ThreadSettingsDeleteTab from './thread-settings-delete-tab.react.js';
+import ThreadSettingsGeneralTab from './thread-settings-general-tab.react.js';
import css from './thread-settings-modal.css';
-import ThreadSettingsPrivacyTab from './thread-settings-privacy-tab.react';
-import ThreadSettingsRelationshipTab from './thread-settings-relationship-tab.react';
+import ThreadSettingsPrivacyTab from './thread-settings-privacy-tab.react.js';
+import ThreadSettingsRelationshipTab from './thread-settings-relationship-tab.react.js';
type TabType = 'general' | 'privacy' | 'delete' | 'relationship';
type BaseProps = {
diff --git a/web/modals/threads/settings/thread-settings-privacy-tab.react.js b/web/modals/threads/settings/thread-settings-privacy-tab.react.js
--- a/web/modals/threads/settings/thread-settings-privacy-tab.react.js
+++ b/web/modals/threads/settings/thread-settings-privacy-tab.react.js
@@ -5,23 +5,23 @@
import {
changeThreadSettings,
changeThreadSettingsActionTypes,
-} from 'lib/actions/thread-actions';
-import { useModalContext } from 'lib/components/modal-provider.react';
+} from 'lib/actions/thread-actions.js';
+import { useModalContext } from 'lib/components/modal-provider.react.js';
import SWMansionIcon from 'lib/components/SWMansionIcon.react.js';
-import { threadTypeDescriptions } from 'lib/shared/thread-utils';
-import { type SetState } from 'lib/types/hook-types';
+import { threadTypeDescriptions } from 'lib/shared/thread-utils.js';
+import { type SetState } from 'lib/types/hook-types.js';
import {
type ThreadInfo,
type ThreadChanges,
threadTypes,
-} from 'lib/types/thread-types';
+} from 'lib/types/thread-types.js';
import {
useDispatchActionPromise,
useServerCall,
-} from 'lib/utils/action-utils';
+} from 'lib/utils/action-utils.js';
-import EnumSettingsOption from '../../../components/enum-settings-option.react';
-import SubmitSection from './submit-section.react';
+import EnumSettingsOption from '../../../components/enum-settings-option.react.js';
+import SubmitSection from './submit-section.react.js';
import css from './thread-settings-privacy-tab.css';
const { COMMUNITY_OPEN_SUBTHREAD, COMMUNITY_SECRET_SUBTHREAD } = threadTypes;
diff --git a/web/modals/threads/settings/thread-settings-relationship-button.react.js b/web/modals/threads/settings/thread-settings-relationship-button.react.js
--- a/web/modals/threads/settings/thread-settings-relationship-button.react.js
+++ b/web/modals/threads/settings/thread-settings-relationship-button.react.js
@@ -12,25 +12,25 @@
import {
updateRelationships,
updateRelationshipsActionTypes,
-} from 'lib/actions/relationship-actions';
-import { createLoadingStatusSelector } from 'lib/selectors/loading-selectors';
+} from 'lib/actions/relationship-actions.js';
+import { createLoadingStatusSelector } from 'lib/selectors/loading-selectors.js';
import {
getRelationshipActionText,
getRelationshipDispatchAction,
-} from 'lib/shared/relationship-utils';
-import type { SetState } from 'lib/types/hook-types';
+} from 'lib/shared/relationship-utils.js';
+import type { SetState } from 'lib/types/hook-types.js';
import {
relationshipButtons,
type RelationshipButton,
-} from 'lib/types/relationship-types';
-import type { UserInfo } from 'lib/types/user-types';
+} from 'lib/types/relationship-types.js';
+import type { UserInfo } from 'lib/types/user-types.js';
import {
useDispatchActionPromise,
useServerCall,
-} from 'lib/utils/action-utils';
+} from 'lib/utils/action-utils.js';
-import Button, { buttonThemes } from '../../../components/button.react';
-import { useSelector } from '../../../redux/redux-utils';
+import Button, { buttonThemes } from '../../../components/button.react.js';
+import { useSelector } from '../../../redux/redux-utils.js';
import css from './thread-settings-relationship-tab.css';
const loadingStatusSelector = createLoadingStatusSelector(
diff --git a/web/modals/threads/settings/thread-settings-relationship-tab.react.js b/web/modals/threads/settings/thread-settings-relationship-tab.react.js
--- a/web/modals/threads/settings/thread-settings-relationship-tab.react.js
+++ b/web/modals/threads/settings/thread-settings-relationship-tab.react.js
@@ -2,12 +2,12 @@
import * as React from 'react';
-import { useENSNames } from 'lib/hooks/ens-cache';
-import { type SetState } from 'lib/types/hook-types';
-import { type RelationshipButton } from 'lib/types/relationship-types';
-import type { UserInfo } from 'lib/types/user-types';
+import { useENSNames } from 'lib/hooks/ens-cache.js';
+import { type SetState } from 'lib/types/hook-types.js';
+import { type RelationshipButton } from 'lib/types/relationship-types.js';
+import type { UserInfo } from 'lib/types/user-types.js';
-import ThreadSettingsRelationshipButton from './thread-settings-relationship-button.react';
+import ThreadSettingsRelationshipButton from './thread-settings-relationship-button.react.js';
import css from './thread-settings-relationship-tab.css';
type Props = {
diff --git a/web/modals/threads/sidebars/sidebar-list.react.js b/web/modals/threads/sidebars/sidebar-list.react.js
--- a/web/modals/threads/sidebars/sidebar-list.react.js
+++ b/web/modals/threads/sidebars/sidebar-list.react.js
@@ -2,9 +2,9 @@
import * as React from 'react';
-import type { ChatThreadItem } from 'lib/selectors/chat-selectors';
+import type { ChatThreadItem } from 'lib/selectors/chat-selectors.js';
-import Sidebar from './sidebar.react';
+import Sidebar from './sidebar.react.js';
import css from './sidebars-modal.css';
type Props = {
diff --git a/web/modals/threads/sidebars/sidebar.react.js b/web/modals/threads/sidebars/sidebar.react.js
--- a/web/modals/threads/sidebars/sidebar.react.js
+++ b/web/modals/threads/sidebars/sidebar.react.js
@@ -3,15 +3,15 @@
import classNames from 'classnames';
import * as React from 'react';
-import { useModalContext } from 'lib/components/modal-provider.react';
-import type { ChatThreadItem } from 'lib/selectors/chat-selectors';
-import { useMessagePreview } from 'lib/shared/message-utils';
-import { shortAbsoluteDate } from 'lib/utils/date-utils';
-import { useResolvedThreadInfo } from 'lib/utils/entity-helpers';
+import { useModalContext } from 'lib/components/modal-provider.react.js';
+import type { ChatThreadItem } from 'lib/selectors/chat-selectors.js';
+import { useMessagePreview } from 'lib/shared/message-utils.js';
+import { shortAbsoluteDate } from 'lib/utils/date-utils.js';
+import { useResolvedThreadInfo } from 'lib/utils/entity-helpers.js';
-import Button from '../../../components/button.react';
-import { getDefaultTextMessageRules } from '../../../markdown/rules.react';
-import { useOnClickThread } from '../../../selectors/thread-selectors';
+import Button from '../../../components/button.react.js';
+import { getDefaultTextMessageRules } from '../../../markdown/rules.react.js';
+import { useOnClickThread } from '../../../selectors/thread-selectors.js';
import css from './sidebars-modal.css';
type Props = {
diff --git a/web/modals/threads/sidebars/sidebars-modal.react.js b/web/modals/threads/sidebars/sidebars-modal.react.js
--- a/web/modals/threads/sidebars/sidebars-modal.react.js
+++ b/web/modals/threads/sidebars/sidebars-modal.react.js
@@ -2,12 +2,12 @@
import * as React from 'react';
-import { useFilteredChildThreads } from 'lib/hooks/child-threads';
-import { threadInChatList, threadIsSidebar } from 'lib/shared/thread-utils';
+import { useFilteredChildThreads } from 'lib/hooks/child-threads.js';
+import { threadInChatList, threadIsSidebar } from 'lib/shared/thread-utils.js';
-import Tabs from '../../../components/tabs.react';
-import SearchModal from '../../search-modal.react';
-import SidebarList from './sidebar-list.react';
+import Tabs from '../../../components/tabs.react.js';
+import SearchModal from '../../search-modal.react.js';
+import SidebarList from './sidebar-list.react.js';
import css from './sidebars-modal.css';
type SidebarTab = 'All Threads' | 'My Threads';
diff --git a/web/modals/threads/subchannels/subchannel.react.js b/web/modals/threads/subchannels/subchannel.react.js
--- a/web/modals/threads/subchannels/subchannel.react.js
+++ b/web/modals/threads/subchannels/subchannel.react.js
@@ -3,16 +3,16 @@
import classNames from 'classnames';
import * as React from 'react';
-import { useModalContext } from 'lib/components/modal-provider.react';
+import { useModalContext } from 'lib/components/modal-provider.react.js';
import SWMansionIcon from 'lib/components/SWMansionIcon.react.js';
-import { type ChatThreadItem } from 'lib/selectors/chat-selectors';
-import { useMessagePreview } from 'lib/shared/message-utils';
-import { shortAbsoluteDate } from 'lib/utils/date-utils';
-import { useResolvedThreadInfo } from 'lib/utils/entity-helpers';
+import { type ChatThreadItem } from 'lib/selectors/chat-selectors.js';
+import { useMessagePreview } from 'lib/shared/message-utils.js';
+import { shortAbsoluteDate } from 'lib/utils/date-utils.js';
+import { useResolvedThreadInfo } from 'lib/utils/entity-helpers.js';
-import Button from '../../../components/button.react';
-import { getDefaultTextMessageRules } from '../../../markdown/rules.react';
-import { useOnClickThread } from '../../../selectors/thread-selectors';
+import Button from '../../../components/button.react.js';
+import { getDefaultTextMessageRules } from '../../../markdown/rules.react.js';
+import { useOnClickThread } from '../../../selectors/thread-selectors.js';
import css from './subchannels-modal.css';
type Props = {
diff --git a/web/modals/threads/subchannels/subchannels-modal.react.js b/web/modals/threads/subchannels/subchannels-modal.react.js
--- a/web/modals/threads/subchannels/subchannels-modal.react.js
+++ b/web/modals/threads/subchannels/subchannels-modal.react.js
@@ -2,11 +2,11 @@
import * as React from 'react';
-import { useFilteredChildThreads } from 'lib/hooks/child-threads';
-import { threadIsChannel } from 'lib/shared/thread-utils';
+import { useFilteredChildThreads } from 'lib/hooks/child-threads.js';
+import { threadIsChannel } from 'lib/shared/thread-utils.js';
-import SearchModal from '../../search-modal.react';
-import Subchannel from './subchannel.react';
+import SearchModal from '../../search-modal.react.js';
+import Subchannel from './subchannel.react.js';
import css from './subchannels-modal.css';
type ContentProps = {
diff --git a/web/modals/threads/thread-picker-modal.react.js b/web/modals/threads/thread-picker-modal.react.js
--- a/web/modals/threads/thread-picker-modal.react.js
+++ b/web/modals/threads/thread-picker-modal.react.js
@@ -4,15 +4,15 @@
import * as React from 'react';
import { createSelector } from 'reselect';
-import { useGlobalThreadSearchIndex } from 'lib/selectors/nav-selectors';
-import { onScreenEntryEditableThreadInfos } from 'lib/selectors/thread-selectors';
-import type { ThreadInfo } from 'lib/types/thread-types';
-import { useResolvedThreadInfo } from 'lib/utils/entity-helpers';
-
-import Button from '../../components/button.react';
-import Search from '../../components/search.react';
-import { useSelector } from '../../redux/redux-utils';
-import Modal, { type ModalOverridableProps } from '../modal.react';
+import { useGlobalThreadSearchIndex } from 'lib/selectors/nav-selectors.js';
+import { onScreenEntryEditableThreadInfos } from 'lib/selectors/thread-selectors.js';
+import type { ThreadInfo } from 'lib/types/thread-types.js';
+import { useResolvedThreadInfo } from 'lib/utils/entity-helpers.js';
+
+import Button from '../../components/button.react.js';
+import Search from '../../components/search.react.js';
+import { useSelector } from '../../redux/redux-utils.js';
+import Modal, { type ModalOverridableProps } from '../modal.react.js';
import css from './thread-picker-modal.css';
type OptionProps = {
diff --git a/web/modals/update-modal.react.js b/web/modals/update-modal.react.js
--- a/web/modals/update-modal.react.js
+++ b/web/modals/update-modal.react.js
@@ -2,11 +2,11 @@
import * as React from 'react';
-import { useModalContext } from 'lib/components/modal-provider.react';
+import { useModalContext } from 'lib/components/modal-provider.react.js';
-import Button from '../components/button.react';
-import electron from '../electron';
-import Modal from './modal.react';
+import Button from '../components/button.react.js';
+import electron from '../electron.js';
+import Modal from './modal.react.js';
import css from './update-modal.css';
type Props = {
diff --git a/web/redux/device-id-reducer.js b/web/redux/device-id-reducer.js
--- a/web/redux/device-id-reducer.js
+++ b/web/redux/device-id-reducer.js
@@ -6,9 +6,9 @@
} from 'lib/actions/user-actions.js';
import { setNewSessionActionType } from 'lib/utils/action-utils.js';
-import type { Action } from '../redux/redux-setup';
-import { deviceIDFormatRegex } from '../utils/device-id';
-import { setDeviceIDActionType } from './action-types';
+import type { Action } from '../redux/redux-setup.js';
+import { deviceIDFormatRegex } from '../utils/device-id.js';
+import { setDeviceIDActionType } from './action-types.js';
export function reduceDeviceID(state: ?string, action: Action): ?string {
if (action.type === setDeviceIDActionType) {
diff --git a/web/redux/device-id-updater.js b/web/redux/device-id-updater.js
--- a/web/redux/device-id-updater.js
+++ b/web/redux/device-id-updater.js
@@ -2,8 +2,8 @@
import * as React from 'react';
import { useDispatch, useSelector } from 'react-redux';
-import { generateDeviceID, deviceTypes } from '../utils/device-id';
-import { setDeviceIDActionType } from './action-types';
+import { generateDeviceID, deviceTypes } from '../utils/device-id.js';
+import { setDeviceIDActionType } from './action-types.js';
function DeviceIDUpdater(): null {
const dispatch = useDispatch();
diff --git a/web/redux/disconnected-bar-visibility-handler.js b/web/redux/disconnected-bar-visibility-handler.js
--- a/web/redux/disconnected-bar-visibility-handler.js
+++ b/web/redux/disconnected-bar-visibility-handler.js
@@ -2,7 +2,7 @@
import * as React from 'react';
-import { useDisconnectedBarVisibilityHandler } from 'lib/hooks/disconnected-bar';
+import { useDisconnectedBarVisibilityHandler } from 'lib/hooks/disconnected-bar.js';
function useNetworkConnected() {
const [networkConnected, setNetworkConnected] = React.useState(true);
diff --git a/web/redux/disconnected-bar.js b/web/redux/disconnected-bar.js
--- a/web/redux/disconnected-bar.js
+++ b/web/redux/disconnected-bar.js
@@ -6,7 +6,7 @@
import {
useShouldShowDisconnectedBar,
useDisconnectedBar,
-} from 'lib/hooks/disconnected-bar';
+} from 'lib/hooks/disconnected-bar.js';
import css from './disconnected-bar.css';
diff --git a/web/redux/focus-handler.react.js b/web/redux/focus-handler.react.js
--- a/web/redux/focus-handler.react.js
+++ b/web/redux/focus-handler.react.js
@@ -3,8 +3,8 @@
import * as React from 'react';
import { useDispatch } from 'react-redux';
-import { updateWindowActiveActionType } from './action-types';
-import { useSelector } from './redux-utils';
+import { updateWindowActiveActionType } from './action-types.js';
+import { useSelector } from './redux-utils.js';
function FocusHandler(): React.Node {
const [focused, setFocused] = React.useState(
diff --git a/web/redux/nav-reducer.js b/web/redux/nav-reducer.js
--- a/web/redux/nav-reducer.js
+++ b/web/redux/nav-reducer.js
@@ -1,12 +1,12 @@
// @flow
-import { pendingToRealizedThreadIDsSelector } from 'lib/selectors/thread-selectors';
-import { threadIsPending } from 'lib/shared/thread-utils';
-import type { RawThreadInfo } from 'lib/types/thread-types';
+import { pendingToRealizedThreadIDsSelector } from 'lib/selectors/thread-selectors.js';
+import { threadIsPending } from 'lib/shared/thread-utils.js';
+import type { RawThreadInfo } from 'lib/types/thread-types.js';
-import { updateNavInfoActionType } from '../redux/action-types';
-import type { Action } from '../redux/redux-setup';
-import { type NavInfo } from '../types/nav-types';
+import { updateNavInfoActionType } from '../redux/action-types.js';
+import type { Action } from '../redux/redux-setup.js';
+import { type NavInfo } from '../types/nav-types.js';
export default function reduceNavInfo(
oldState: NavInfo,
diff --git a/web/redux/primary-identity-public-key-reducer.js b/web/redux/primary-identity-public-key-reducer.js
--- a/web/redux/primary-identity-public-key-reducer.js
+++ b/web/redux/primary-identity-public-key-reducer.js
@@ -3,7 +3,7 @@
import {
logOutActionTypes,
deleteAccountActionTypes,
-} from 'lib/actions/user-actions';
+} from 'lib/actions/user-actions.js';
import { setNewSessionActionType } from 'lib/utils/action-utils.js';
import type { Action } from './redux-setup.js';
diff --git a/web/redux/redux-setup.js b/web/redux/redux-setup.js
--- a/web/redux/redux-setup.js
+++ b/web/redux/redux-setup.js
@@ -1,47 +1,47 @@
// @flow
import invariant from 'invariant';
-import type { PersistState } from 'redux-persist/src/types';
+import type { PersistState } from 'redux-persist/es/types.js';
import {
logOutActionTypes,
deleteAccountActionTypes,
-} from 'lib/actions/user-actions';
-import baseReducer from 'lib/reducers/master-reducer';
-import { mostRecentlyReadThreadSelector } from 'lib/selectors/thread-selectors';
-import { isLoggedIn } from 'lib/selectors/user-selectors';
-import { invalidSessionDowngrade } from 'lib/shared/account-utils';
-import type { Shape } from 'lib/types/core';
-import type { DraftStore } from 'lib/types/draft-types';
-import type { EnabledApps } from 'lib/types/enabled-apps';
-import type { EntryStore } from 'lib/types/entry-types';
-import type { CalendarFilter } from 'lib/types/filter-types';
-import type { LifecycleState } from 'lib/types/lifecycle-state-types';
-import type { LoadingStatus } from 'lib/types/loading-types';
-import type { MessageStore } from 'lib/types/message-types';
+} from 'lib/actions/user-actions.js';
+import baseReducer from 'lib/reducers/master-reducer.js';
+import { mostRecentlyReadThreadSelector } from 'lib/selectors/thread-selectors.js';
+import { isLoggedIn } from 'lib/selectors/user-selectors.js';
+import { invalidSessionDowngrade } from 'lib/shared/account-utils.js';
+import type { Shape } from 'lib/types/core.js';
+import type { DraftStore } from 'lib/types/draft-types.js';
+import type { EnabledApps } from 'lib/types/enabled-apps.js';
+import type { EntryStore } from 'lib/types/entry-types.js';
+import type { CalendarFilter } from 'lib/types/filter-types.js';
+import type { LifecycleState } from 'lib/types/lifecycle-state-types.js';
+import type { LoadingStatus } from 'lib/types/loading-types.js';
+import type { MessageStore } from 'lib/types/message-types.js';
import type { UserPolicies } from 'lib/types/policy-types.js';
-import type { BaseAction } from 'lib/types/redux-types';
-import type { ReportStore } from 'lib/types/report-types';
-import type { ConnectionInfo } from 'lib/types/socket-types';
-import type { ThreadStore } from 'lib/types/thread-types';
-import type { CurrentUserInfo, UserStore } from 'lib/types/user-types';
-import { setNewSessionActionType } from 'lib/utils/action-utils';
+import type { BaseAction } from 'lib/types/redux-types.js';
+import type { ReportStore } from 'lib/types/report-types.js';
+import type { ConnectionInfo } from 'lib/types/socket-types.js';
+import type { ThreadStore } from 'lib/types/thread-types.js';
+import type { CurrentUserInfo, UserStore } from 'lib/types/user-types.js';
+import { setNewSessionActionType } from 'lib/utils/action-utils.js';
-import { activeThreadSelector } from '../selectors/nav-selectors';
-import { type NavInfo } from '../types/nav-types';
import {
updateWindowActiveActionType,
setDeviceIDActionType,
updateNavInfoActionType,
updateWindowDimensionsActionType,
-} from './action-types';
-import { reduceDeviceID } from './device-id-reducer';
-import reduceNavInfo from './nav-reducer';
+} from './action-types.js';
+import { reduceDeviceID } from './device-id-reducer.js';
+import reduceNavInfo from './nav-reducer.js';
import {
reducePrimaryIdentityPublicKey,
setPrimaryIdentityPublicKey,
-} from './primary-identity-public-key-reducer';
-import { getVisibility } from './visibility';
+} from './primary-identity-public-key-reducer.js';
+import { getVisibility } from './visibility.js';
+import { activeThreadSelector } from '../selectors/nav-selectors.js';
+import { type NavInfo } from '../types/nav-types.js';
export type WindowDimensions = { width: number, height: number };
export type AppState = {
diff --git a/web/redux/redux-utils.js b/web/redux/redux-utils.js
--- a/web/redux/redux-utils.js
+++ b/web/redux/redux-utils.js
@@ -2,7 +2,7 @@
import { useSelector as reactReduxUseSelector } from 'react-redux';
-import type { AppState } from './redux-setup';
+import type { AppState } from './redux-setup.js';
function useSelector<SS>(
selector: (state: AppState) => SS,
diff --git a/web/redux/visibility-handler.react.js b/web/redux/visibility-handler.react.js
--- a/web/redux/visibility-handler.react.js
+++ b/web/redux/visibility-handler.react.js
@@ -3,10 +3,10 @@
import * as React from 'react';
import { useDispatch } from 'react-redux';
-import { updateLifecycleStateActionType } from 'lib/reducers/lifecycle-state-reducer';
-import { useIsAppForegrounded } from 'lib/shared/lifecycle-utils';
+import { updateLifecycleStateActionType } from 'lib/reducers/lifecycle-state-reducer.js';
+import { useIsAppForegrounded } from 'lib/shared/lifecycle-utils.js';
-import { useVisibility } from './visibility';
+import { useVisibility } from './visibility.js';
function VisibilityHandler(): React.Node {
const visibility = useVisibility();
diff --git a/web/root.js b/web/root.js
--- a/web/root.js
+++ b/web/root.js
@@ -4,21 +4,21 @@
import { Provider } from 'react-redux';
import { Router, Route } from 'react-router';
import { createStore, applyMiddleware, type Store } from 'redux';
-import { composeWithDevTools } from 'redux-devtools-extension/logOnlyInProduction';
+import { composeWithDevTools } from 'redux-devtools-extension/logOnlyInProduction.js';
import { persistReducer, persistStore } from 'redux-persist';
import { PersistGate } from 'redux-persist/integration/react';
import storage from 'redux-persist/lib/storage';
import thunk from 'redux-thunk';
-import { reduxLoggerMiddleware } from 'lib/utils/action-logger';
+import { reduxLoggerMiddleware } from 'lib/utils/action-logger.js';
-import App from './app.react';
-import ErrorBoundary from './error-boundary.react';
-import Loading from './loading.react';
-import { reducer } from './redux/redux-setup';
-import type { AppState, Action } from './redux/redux-setup';
-import history from './router-history';
-import Socket from './socket.react';
+import App from './app.react.js';
+import ErrorBoundary from './error-boundary.react.js';
+import Loading from './loading.react.js';
+import { reducer } from './redux/redux-setup.js';
+import type { AppState, Action } from './redux/redux-setup.js';
+import history from './router-history.js';
+import Socket from './socket.react.js';
const persistConfig = {
key: 'root',
diff --git a/web/script.js b/web/script.js
--- a/web/script.js
+++ b/web/script.js
@@ -6,7 +6,7 @@
import React from 'react';
import { hydrateRoot } from 'react-dom/client';
-import Root from './root';
+import Root from './root.js';
const root = document.getElementById('react-root');
invariant(root, "cannot find id='react-root' element!");
diff --git a/web/selectors/account-selectors.js b/web/selectors/account-selectors.js
--- a/web/selectors/account-selectors.js
+++ b/web/selectors/account-selectors.js
@@ -2,10 +2,10 @@
import { createSelector } from 'reselect';
-import { logInExtraInfoSelector } from 'lib/selectors/account-selectors';
-import type { LogInExtraInfo } from 'lib/types/account-types';
+import { logInExtraInfoSelector } from 'lib/selectors/account-selectors.js';
+import type { LogInExtraInfo } from 'lib/types/account-types.js';
-import type { AppState } from '../redux/redux-setup';
+import type { AppState } from '../redux/redux-setup.js';
const webLogInExtraInfoSelector: (
state: AppState,
diff --git a/web/selectors/calendar-selectors.js b/web/selectors/calendar-selectors.js
--- a/web/selectors/calendar-selectors.js
+++ b/web/selectors/calendar-selectors.js
@@ -3,11 +3,11 @@
import {
useFilterThreadInfos as baseUseFilterThreadInfos,
useFilterThreadSearchIndex as baseUseFilterThreadSearchIndex,
-} from 'lib/selectors/calendar-selectors';
-import type SearchIndex from 'lib/shared/search-index';
-import type { FilterThreadInfo } from 'lib/types/filter-types';
+} from 'lib/selectors/calendar-selectors.js';
+import type SearchIndex from 'lib/shared/search-index.js';
+import type { FilterThreadInfo } from 'lib/types/filter-types.js';
-import { useSelector } from '../redux/redux-utils';
+import { useSelector } from '../redux/redux-utils.js';
function useFilterThreadInfos(): $ReadOnlyArray<FilterThreadInfo> {
const calendarActive = useSelector(state => state.navInfo.tab === 'calendar');
diff --git a/web/selectors/chat-selectors.js b/web/selectors/chat-selectors.js
--- a/web/selectors/chat-selectors.js
+++ b/web/selectors/chat-selectors.js
@@ -7,17 +7,17 @@
messageInfoSelector,
type ChatThreadItem,
createChatThreadItem,
-} from 'lib/selectors/chat-selectors';
+} from 'lib/selectors/chat-selectors.js';
import {
threadInfoSelector,
sidebarInfoSelector,
-} from 'lib/selectors/thread-selectors';
-import { threadIsPending } from 'lib/shared/thread-utils';
-import type { MessageStore, MessageInfo } from 'lib/types/message-types';
-import type { ThreadInfo, SidebarInfo } from 'lib/types/thread-types';
+} from 'lib/selectors/thread-selectors.js';
+import { threadIsPending } from 'lib/shared/thread-utils.js';
+import type { MessageStore, MessageInfo } from 'lib/types/message-types.js';
+import type { ThreadInfo, SidebarInfo } from 'lib/types/thread-types.js';
-import type { AppState } from '../redux/redux-setup';
-import { useSelector } from '../redux/redux-utils';
+import type { AppState } from '../redux/redux-setup.js';
+import { useSelector } from '../redux/redux-utils.js';
const activeChatThreadItem: (
state: AppState,
diff --git a/web/selectors/entry-selectors.js b/web/selectors/entry-selectors.js
--- a/web/selectors/entry-selectors.js
+++ b/web/selectors/entry-selectors.js
@@ -1,15 +1,15 @@
// @flow
-import _compact from 'lodash/fp/compact';
-import _flow from 'lodash/fp/flow';
-import _map from 'lodash/fp/map';
-import _mapValues from 'lodash/fp/mapValues';
+import _compact from 'lodash/fp/compact.js';
+import _flow from 'lodash/fp/flow.js';
+import _map from 'lodash/fp/map.js';
+import _mapValues from 'lodash/fp/mapValues.js';
import { createSelector } from 'reselect';
-import { entryInfoSelector } from 'lib/selectors/thread-selectors';
-import type { EntryInfo } from 'lib/types/entry-types';
+import { entryInfoSelector } from 'lib/selectors/thread-selectors.js';
+import type { EntryInfo } from 'lib/types/entry-types.js';
-import type { AppState } from '../redux/redux-setup';
+import type { AppState } from '../redux/redux-setup.js';
const allDaysToEntries: (
state: AppState,
diff --git a/web/selectors/nav-selectors.js b/web/selectors/nav-selectors.js
--- a/web/selectors/nav-selectors.js
+++ b/web/selectors/nav-selectors.js
@@ -3,16 +3,16 @@
import invariant from 'invariant';
import { createSelector } from 'reselect';
-import { nonThreadCalendarFiltersSelector } from 'lib/selectors/calendar-filter-selectors';
-import { currentCalendarQuery } from 'lib/selectors/nav-selectors';
-import type { CalendarQuery } from 'lib/types/entry-types';
-import type { CalendarFilter } from 'lib/types/filter-types';
+import { nonThreadCalendarFiltersSelector } from 'lib/selectors/calendar-filter-selectors.js';
+import { currentCalendarQuery } from 'lib/selectors/nav-selectors.js';
+import type { CalendarQuery } from 'lib/types/entry-types.js';
+import type { CalendarFilter } from 'lib/types/filter-types.js';
-import type { AppState } from '../redux/redux-setup';
+import type { AppState } from '../redux/redux-setup.js';
import {
type NavigationTab,
type NavigationSettingsSection,
-} from '../types/nav-types';
+} from '../types/nav-types.js';
const dateExtractionRegex = /^([0-9]{4})-([0-9]{2})-[0-9]{2}$/;
diff --git a/web/selectors/socket-selectors.js b/web/selectors/socket-selectors.js
--- a/web/selectors/socket-selectors.js
+++ b/web/selectors/socket-selectors.js
@@ -5,19 +5,19 @@
import {
getClientResponsesSelector,
sessionStateFuncSelector,
-} from 'lib/selectors/socket-selectors';
-import { createOpenSocketFunction } from 'lib/shared/socket-utils';
+} from 'lib/selectors/socket-selectors.js';
+import { createOpenSocketFunction } from 'lib/shared/socket-utils.js';
import type {
ClientServerRequest,
ClientClientResponse,
-} from 'lib/types/request-types';
+} from 'lib/types/request-types.js';
import type {
SessionIdentification,
SessionState,
-} from 'lib/types/session-types';
-import type { OneTimeKeyGenerator } from 'lib/types/socket-types';
+} from 'lib/types/session-types.js';
+import type { OneTimeKeyGenerator } from 'lib/types/socket-types.js';
-import type { AppState } from '../redux/redux-setup';
+import type { AppState } from '../redux/redux-setup.js';
const openSocketSelector: (state: AppState) => () => WebSocket = createSelector(
(state: AppState) => state.baseHref,
diff --git a/web/selectors/thread-selectors.js b/web/selectors/thread-selectors.js
--- a/web/selectors/thread-selectors.js
+++ b/web/selectors/thread-selectors.js
@@ -4,17 +4,17 @@
import * as React from 'react';
import { useDispatch } from 'react-redux';
-import { ENSCacheContext } from 'lib/components/ens-cache-provider.react';
-import { createPendingSidebar } from 'lib/shared/thread-utils';
+import { ENSCacheContext } from 'lib/components/ens-cache-provider.react.js';
+import { createPendingSidebar } from 'lib/shared/thread-utils.js';
import type {
ComposableMessageInfo,
RobotextMessageInfo,
-} from 'lib/types/message-types';
-import type { ThreadInfo } from 'lib/types/thread-types';
+} from 'lib/types/message-types.js';
+import type { ThreadInfo } from 'lib/types/thread-types.js';
-import { getDefaultTextMessageRules } from '../markdown/rules.react';
-import { updateNavInfoActionType } from '../redux/action-types';
-import { useSelector } from '../redux/redux-utils';
+import { getDefaultTextMessageRules } from '../markdown/rules.react.js';
+import { updateNavInfoActionType } from '../redux/action-types.js';
+import { useSelector } from '../redux/redux-utils.js';
function useOnClickThread(
thread: ?ThreadInfo,
diff --git a/web/settings/account-delete-modal.react.js b/web/settings/account-delete-modal.react.js
--- a/web/settings/account-delete-modal.react.js
+++ b/web/settings/account-delete-modal.react.js
@@ -6,24 +6,24 @@
import {
deleteAccount,
deleteAccountActionTypes,
-} from 'lib/actions/user-actions';
-import { useModalContext } from 'lib/components/modal-provider.react';
+} from 'lib/actions/user-actions.js';
+import { useModalContext } from 'lib/components/modal-provider.react.js';
import SWMansionIcon from 'lib/components/SWMansionIcon.react.js';
-import { preRequestUserStateSelector } from 'lib/selectors/account-selectors';
-import { createLoadingStatusSelector } from 'lib/selectors/loading-selectors';
+import { preRequestUserStateSelector } from 'lib/selectors/account-selectors.js';
+import { createLoadingStatusSelector } from 'lib/selectors/loading-selectors.js';
import { accountHasPassword } from 'lib/shared/account-utils.js';
-import type { LogOutResult } from 'lib/types/account-types';
-import type { PreRequestUserState } from 'lib/types/session-types';
-import type { DispatchActionPromise } from 'lib/utils/action-utils';
+import type { LogOutResult } from 'lib/types/account-types.js';
+import type { PreRequestUserState } from 'lib/types/session-types.js';
+import type { DispatchActionPromise } from 'lib/utils/action-utils.js';
import {
useDispatchActionPromise,
useServerCall,
-} from 'lib/utils/action-utils';
+} from 'lib/utils/action-utils.js';
-import Button, { buttonThemes } from '../components/button.react';
-import Input from '../modals/input.react';
-import Modal from '../modals/modal.react';
-import { useSelector } from '../redux/redux-utils';
+import Button, { buttonThemes } from '../components/button.react.js';
+import Input from '../modals/input.react.js';
+import Modal from '../modals/modal.react.js';
+import { useSelector } from '../redux/redux-utils.js';
import css from './account-delete-modal.css';
type Props = {
diff --git a/web/settings/account-settings.react.js b/web/settings/account-settings.react.js
--- a/web/settings/account-settings.react.js
+++ b/web/settings/account-settings.react.js
@@ -2,23 +2,23 @@
import * as React from 'react';
-import { logOut, logOutActionTypes } from 'lib/actions/user-actions';
-import { useModalContext } from 'lib/components/modal-provider.react';
+import { logOut, logOutActionTypes } from 'lib/actions/user-actions.js';
+import { useModalContext } from 'lib/components/modal-provider.react.js';
import SWMansionIcon from 'lib/components/SWMansionIcon.react.js';
-import { useStringForUser } from 'lib/hooks/ens-cache';
-import { preRequestUserStateSelector } from 'lib/selectors/account-selectors';
+import { useStringForUser } from 'lib/hooks/ens-cache.js';
+import { preRequestUserStateSelector } from 'lib/selectors/account-selectors.js';
import { accountHasPassword } from 'lib/shared/account-utils.js';
import {
useDispatchActionPromise,
useServerCall,
-} from 'lib/utils/action-utils';
+} from 'lib/utils/action-utils.js';
-import Button from '../components/button.react';
-import { useSelector } from '../redux/redux-utils';
+import Button from '../components/button.react.js';
+import { useSelector } from '../redux/redux-utils.js';
import css from './account-settings.css';
-import PasswordChangeModal from './password-change-modal';
-import BlockListModal from './relationship/block-list-modal.react';
-import FriendListModal from './relationship/friend-list-modal.react';
+import PasswordChangeModal from './password-change-modal.js';
+import BlockListModal from './relationship/block-list-modal.react.js';
+import FriendListModal from './relationship/friend-list-modal.react.js';
function AccountSettings(): React.Node {
const sendLogoutRequest = useServerCall(logOut);
diff --git a/web/settings/danger-zone.react.js b/web/settings/danger-zone.react.js
--- a/web/settings/danger-zone.react.js
+++ b/web/settings/danger-zone.react.js
@@ -2,10 +2,10 @@
import * as React from 'react';
-import { useModalContext } from 'lib/components/modal-provider.react';
+import { useModalContext } from 'lib/components/modal-provider.react.js';
-import Button, { buttonThemes } from '../components/button.react';
-import AccountDeleteModal from './account-delete-modal.react';
+import Button, { buttonThemes } from '../components/button.react.js';
+import AccountDeleteModal from './account-delete-modal.react.js';
import css from './danger-zone.css';
function DangerZone(): React.Node {
diff --git a/web/settings/password-change-modal.js b/web/settings/password-change-modal.js
--- a/web/settings/password-change-modal.js
+++ b/web/settings/password-change-modal.js
@@ -6,21 +6,21 @@
import {
changeUserPasswordActionTypes,
changeUserPassword,
-} from 'lib/actions/user-actions';
-import { useModalContext } from 'lib/components/modal-provider.react';
-import { useStringForUser } from 'lib/hooks/ens-cache';
-import { createLoadingStatusSelector } from 'lib/selectors/loading-selectors';
-import { type PasswordUpdate } from 'lib/types/user-types';
+} from 'lib/actions/user-actions.js';
+import { useModalContext } from 'lib/components/modal-provider.react.js';
+import { useStringForUser } from 'lib/hooks/ens-cache.js';
+import { createLoadingStatusSelector } from 'lib/selectors/loading-selectors.js';
+import { type PasswordUpdate } from 'lib/types/user-types.js';
import {
type DispatchActionPromise,
useDispatchActionPromise,
useServerCall,
-} from 'lib/utils/action-utils';
+} from 'lib/utils/action-utils.js';
-import Button from '../components/button.react';
-import Input from '../modals/input.react';
-import Modal from '../modals/modal.react';
-import { useSelector } from '../redux/redux-utils';
+import Button from '../components/button.react.js';
+import Input from '../modals/input.react.js';
+import Modal from '../modals/modal.react.js';
+import { useSelector } from '../redux/redux-utils.js';
import css from './password-change-modal.css';
type Props = {
diff --git a/web/settings/relationship/add-friends-modal.react.js b/web/settings/relationship/add-friends-modal.react.js
--- a/web/settings/relationship/add-friends-modal.react.js
+++ b/web/settings/relationship/add-friends-modal.react.js
@@ -7,7 +7,7 @@
userRelationshipStatus,
} from 'lib/types/relationship-types.js';
-import AddUsersListModal from './add-users-list-modal.react';
+import AddUsersListModal from './add-users-list-modal.react.js';
const excludedStatuses = new Set([
userRelationshipStatus.FRIEND,
diff --git a/web/settings/relationship/add-users-list-item.react.js b/web/settings/relationship/add-users-list-item.react.js
--- a/web/settings/relationship/add-users-list-item.react.js
+++ b/web/settings/relationship/add-users-list-item.react.js
@@ -4,7 +4,7 @@
import type { AccountUserInfo } from 'lib/types/user-types.js';
-import Button from '../../components/button.react';
+import Button from '../../components/button.react.js';
import css from './add-users-list.css';
type Props = {
diff --git a/web/settings/relationship/add-users-list-modal.react.js b/web/settings/relationship/add-users-list-modal.react.js
--- a/web/settings/relationship/add-users-list-modal.react.js
+++ b/web/settings/relationship/add-users-list-modal.react.js
@@ -8,7 +8,7 @@
} from 'lib/types/relationship-types.js';
import type { ButtonColor } from '../../components/button.react.js';
-import SearchModal from '../../modals/search-modal.react';
+import SearchModal from '../../modals/search-modal.react.js';
import AddUsersList from './add-users-list.react.js';
type Props = {
diff --git a/web/settings/relationship/add-users-list.react.js b/web/settings/relationship/add-users-list.react.js
--- a/web/settings/relationship/add-users-list.react.js
+++ b/web/settings/relationship/add-users-list.react.js
@@ -7,7 +7,7 @@
updateRelationshipsActionTypes,
} from 'lib/actions/relationship-actions.js';
import { searchUsers } from 'lib/actions/user-actions.js';
-import { useENSNames } from 'lib/hooks/ens-cache';
+import { useENSNames } from 'lib/hooks/ens-cache.js';
import { createLoadingStatusSelector } from 'lib/selectors/loading-selectors.js';
import { userStoreSearchIndex as userStoreSearchIndexSelector } from 'lib/selectors/user-selectors.js';
import type {
diff --git a/web/settings/relationship/block-list-modal.react.js b/web/settings/relationship/block-list-modal.react.js
--- a/web/settings/relationship/block-list-modal.react.js
+++ b/web/settings/relationship/block-list-modal.react.js
@@ -2,13 +2,13 @@
import * as React from 'react';
-import { useModalContext } from 'lib/components/modal-provider.react';
-import { userRelationshipStatus } from 'lib/types/relationship-types';
-import type { AccountUserInfo } from 'lib/types/user-types';
+import { useModalContext } from 'lib/components/modal-provider.react.js';
+import { userRelationshipStatus } from 'lib/types/relationship-types.js';
+import type { AccountUserInfo } from 'lib/types/user-types.js';
-import BlockListRow from './block-list-row.react';
-import BlockUsersModal from './block-users-modal.react';
-import UserListModal from './user-list-modal.react';
+import BlockListRow from './block-list-row.react.js';
+import BlockUsersModal from './block-users-modal.react.js';
+import UserListModal from './user-list-modal.react.js';
function filterUser(userInfo: AccountUserInfo) {
return (
diff --git a/web/settings/relationship/block-list-row.react.js b/web/settings/relationship/block-list-row.react.js
--- a/web/settings/relationship/block-list-row.react.js
+++ b/web/settings/relationship/block-list-row.react.js
@@ -3,12 +3,12 @@
import * as React from 'react';
import SWMansionIcon from 'lib/components/SWMansionIcon.react.js';
-import { useRelationshipCallbacks } from 'lib/hooks/relationship-prompt';
+import { useRelationshipCallbacks } from 'lib/hooks/relationship-prompt.js';
-import MenuItem from '../../components/menu-item.react';
-import Menu from '../../components/menu.react';
+import MenuItem from '../../components/menu-item.react.js';
+import Menu from '../../components/menu.react.js';
import css from './user-list-row.css';
-import type { UserRowProps } from './user-list.react';
+import type { UserRowProps } from './user-list.react.js';
function BlockListRow(props: UserRowProps): React.Node {
const { userInfo, onMenuVisibilityChange } = props;
diff --git a/web/settings/relationship/block-users-modal.react.js b/web/settings/relationship/block-users-modal.react.js
--- a/web/settings/relationship/block-users-modal.react.js
+++ b/web/settings/relationship/block-users-modal.react.js
@@ -9,7 +9,7 @@
userRelationshipStatus,
} from 'lib/types/relationship-types.js';
-import { buttonThemes } from '../../components/button.react';
+import { buttonThemes } from '../../components/button.react.js';
import AddUsersListModal from './add-users-list-modal.react.js';
const excludedStatuses = new Set([
diff --git a/web/settings/relationship/friend-list-modal.react.js b/web/settings/relationship/friend-list-modal.react.js
--- a/web/settings/relationship/friend-list-modal.react.js
+++ b/web/settings/relationship/friend-list-modal.react.js
@@ -2,13 +2,13 @@
import * as React from 'react';
-import { useModalContext } from 'lib/components/modal-provider.react';
-import { userRelationshipStatus } from 'lib/types/relationship-types';
-import type { AccountUserInfo } from 'lib/types/user-types';
+import { useModalContext } from 'lib/components/modal-provider.react.js';
+import { userRelationshipStatus } from 'lib/types/relationship-types.js';
+import type { AccountUserInfo } from 'lib/types/user-types.js';
-import AddFriendsModal from './add-friends-modal.react';
-import FriendListRow from './friend-list-row.react';
-import UserListModal from './user-list-modal.react';
+import AddFriendsModal from './add-friends-modal.react.js';
+import FriendListRow from './friend-list-row.react.js';
+import UserListModal from './user-list-modal.react.js';
const relationships = [
userRelationshipStatus.REQUEST_RECEIVED,
diff --git a/web/settings/relationship/friend-list-row.react.js b/web/settings/relationship/friend-list-row.react.js
--- a/web/settings/relationship/friend-list-row.react.js
+++ b/web/settings/relationship/friend-list-row.react.js
@@ -3,14 +3,14 @@
import * as React from 'react';
import SWMansionIcon from 'lib/components/SWMansionIcon.react.js';
-import { useRelationshipCallbacks } from 'lib/hooks/relationship-prompt';
-import { userRelationshipStatus } from 'lib/types/relationship-types';
+import { useRelationshipCallbacks } from 'lib/hooks/relationship-prompt.js';
+import { userRelationshipStatus } from 'lib/types/relationship-types.js';
-import Button from '../../components/button.react';
-import MenuItem from '../../components/menu-item.react';
-import Menu from '../../components/menu.react';
+import Button from '../../components/button.react.js';
+import MenuItem from '../../components/menu-item.react.js';
+import Menu from '../../components/menu.react.js';
import css from './user-list-row.css';
-import type { UserRowProps } from './user-list.react';
+import type { UserRowProps } from './user-list.react.js';
const dangerButtonColor = {
color: 'var(--btn-bg-danger)',
diff --git a/web/settings/relationship/user-list-modal.react.js b/web/settings/relationship/user-list-modal.react.js
--- a/web/settings/relationship/user-list-modal.react.js
+++ b/web/settings/relationship/user-list-modal.react.js
@@ -2,12 +2,12 @@
import * as React from 'react';
-import type { AccountUserInfo } from 'lib/types/user-types';
+import type { AccountUserInfo } from 'lib/types/user-types.js';
import Button from '../../components/button.react.js';
-import SearchModal from '../../modals/search-modal.react';
+import SearchModal from '../../modals/search-modal.react.js';
import css from './user-list.css';
-import { UserList, type UserRowProps } from './user-list.react';
+import { UserList, type UserRowProps } from './user-list.react.js';
type Props = {
+onClose: () => void,
diff --git a/web/settings/relationship/user-list.react.js b/web/settings/relationship/user-list.react.js
--- a/web/settings/relationship/user-list.react.js
+++ b/web/settings/relationship/user-list.react.js
@@ -3,11 +3,11 @@
import classNames from 'classnames';
import * as React from 'react';
-import { useENSNames } from 'lib/hooks/ens-cache';
-import { userStoreSearchIndex as userStoreSearchIndexSelector } from 'lib/selectors/user-selectors';
-import type { AccountUserInfo } from 'lib/types/user-types';
+import { useENSNames } from 'lib/hooks/ens-cache.js';
+import { userStoreSearchIndex as userStoreSearchIndexSelector } from 'lib/selectors/user-selectors.js';
+import type { AccountUserInfo } from 'lib/types/user-types.js';
-import { useSelector } from '../../redux/redux-utils';
+import { useSelector } from '../../redux/redux-utils.js';
import css from './user-list.css';
export type UserRowProps = {
diff --git a/web/sidebar/app-switcher.react.js b/web/sidebar/app-switcher.react.js
--- a/web/sidebar/app-switcher.react.js
+++ b/web/sidebar/app-switcher.react.js
@@ -7,13 +7,13 @@
import {
mostRecentlyReadThreadSelector,
unreadCount,
-} from 'lib/selectors/thread-selectors';
+} from 'lib/selectors/thread-selectors.js';
-import { updateNavInfoActionType } from '../redux/action-types';
-import { useSelector } from '../redux/redux-utils';
+import { updateNavInfoActionType } from '../redux/action-types.js';
+import { useSelector } from '../redux/redux-utils.js';
import { navTabSelector } from '../selectors/nav-selectors.js';
import css from './left-layout-aside.css';
-import NavigationPanel from './navigation-panel.react';
+import NavigationPanel from './navigation-panel.react.js';
function AppSwitcher(): React.Node {
const activeChatThreadID = useSelector(
diff --git a/web/sidebar/left-layout-aside.react.js b/web/sidebar/left-layout-aside.react.js
--- a/web/sidebar/left-layout-aside.react.js
+++ b/web/sidebar/left-layout-aside.react.js
@@ -2,11 +2,11 @@
import * as React from 'react';
-import { useSelector } from '../redux/redux-utils';
-import AppSwitcher from './app-switcher.react';
-import CommunityPicker from './community-picker.react';
+import { useSelector } from '../redux/redux-utils.js';
+import AppSwitcher from './app-switcher.react.js';
+import CommunityPicker from './community-picker.react.js';
import css from './left-layout-aside.css';
-import SettingsSwitcher from './settings-switcher.react';
+import SettingsSwitcher from './settings-switcher.react.js';
function LeftLayoutAside(): React.Node {
const navInfo = useSelector(state => state.navInfo);
diff --git a/web/sidebar/navigation-panel.react.js b/web/sidebar/navigation-panel.react.js
--- a/web/sidebar/navigation-panel.react.js
+++ b/web/sidebar/navigation-panel.react.js
@@ -4,7 +4,7 @@
import * as React from 'react';
import type { AppState } from '../redux/redux-setup.js';
-import { useSelector } from '../redux/redux-utils';
+import { useSelector } from '../redux/redux-utils.js';
import css from './left-layout-aside.css';
type NavigationPanelItemProps = {
diff --git a/web/sidebar/settings-switcher.react.js b/web/sidebar/settings-switcher.react.js
--- a/web/sidebar/settings-switcher.react.js
+++ b/web/sidebar/settings-switcher.react.js
@@ -3,10 +3,10 @@
import * as React from 'react';
import { useDispatch } from 'react-redux';
-import { updateNavInfoActionType } from '../redux/action-types';
+import { updateNavInfoActionType } from '../redux/action-types.js';
import { navSettingsSectionSelector } from '../selectors/nav-selectors.js';
import css from './left-layout-aside.css';
-import NavigationPanel from './navigation-panel.react';
+import NavigationPanel from './navigation-panel.react.js';
function SettingsSwitcher(): React.Node {
const dispatch = useDispatch();
diff --git a/web/socket.react.js b/web/socket.react.js
--- a/web/socket.react.js
+++ b/web/socket.react.js
@@ -3,25 +3,25 @@
import * as React from 'react';
import { useDispatch } from 'react-redux';
-import { logOut } from 'lib/actions/user-actions';
-import { preRequestUserStateSelector } from 'lib/selectors/account-selectors';
-import Socket, { type BaseSocketProps } from 'lib/socket/socket.react';
+import { logOut } from 'lib/actions/user-actions.js';
+import { preRequestUserStateSelector } from 'lib/selectors/account-selectors.js';
+import Socket, { type BaseSocketProps } from 'lib/socket/socket.react.js';
import {
useServerCall,
useDispatchActionPromise,
-} from 'lib/utils/action-utils';
+} from 'lib/utils/action-utils.js';
-import { useSelector } from './redux/redux-utils';
+import { useSelector } from './redux/redux-utils.js';
import {
activeThreadSelector,
webCalendarQuery,
-} from './selectors/nav-selectors';
+} from './selectors/nav-selectors.js';
import {
openSocketSelector,
sessionIdentificationSelector,
webGetClientResponsesSelector,
webSessionStateFuncSelector,
-} from './selectors/socket-selectors';
+} from './selectors/socket-selectors.js';
const WebSocket: React.ComponentType<BaseSocketProps> = React.memo<BaseSocketProps>(
function WebSocket(props) {
diff --git a/web/splash/splash.react.js b/web/splash/splash.react.js
--- a/web/splash/splash.react.js
+++ b/web/splash/splash.react.js
@@ -1,10 +1,10 @@
// @flow
import { darkTheme, RainbowKitProvider } from '@rainbow-me/rainbowkit';
-import _merge from 'lodash/fp/merge';
+import _merge from 'lodash/fp/merge.js';
import * as React from 'react';
-import LoginForm from '../account/log-in-form.react';
+import LoginForm from '../account/log-in-form.react.js';
import { wagmiChains } from '../utils/wagmi-utils.js';
import css from './splash.css';
diff --git a/web/types/nav-types.js b/web/types/nav-types.js
--- a/web/types/nav-types.js
+++ b/web/types/nav-types.js
@@ -1,7 +1,7 @@
// @flow
-import type { BaseNavInfo } from 'lib/types/nav-types';
-import type { ThreadInfo } from 'lib/types/thread-types';
+import type { BaseNavInfo } from 'lib/types/nav-types.js';
+import type { ThreadInfo } from 'lib/types/thread-types.js';
export type NavigationTab = 'calendar' | 'chat' | 'apps' | 'settings';
diff --git a/web/url-utils.js b/web/url-utils.js
--- a/web/url-utils.js
+++ b/web/url-utils.js
@@ -5,11 +5,11 @@
import {
startDateForYearAndMonth,
endDateForYearAndMonth,
-} from 'lib/utils/date-utils';
-import { infoFromURL } from 'lib/utils/url-utils';
+} from 'lib/utils/date-utils.js';
+import { infoFromURL } from 'lib/utils/url-utils.js';
-import { yearExtractor, monthExtractor } from './selectors/nav-selectors';
-import type { NavInfo } from './types/nav-types';
+import { yearExtractor, monthExtractor } from './selectors/nav-selectors.js';
+import type { NavInfo } from './types/nav-types.js';
function canonicalURLFromReduxState(
navInfo: NavInfo,
diff --git a/web/utils/device-id.js b/web/utils/device-id.js
--- a/web/utils/device-id.js
+++ b/web/utils/device-id.js
@@ -2,7 +2,7 @@
import invariant from 'invariant';
-import { generateRandomString } from './text-utils';
+import { generateRandomString } from './text-utils.js';
const deviceTypes = Object.freeze({
KEYSERVER: 0,
diff --git a/web/utils/device-id.test.js b/web/utils/device-id.test.js
--- a/web/utils/device-id.test.js
+++ b/web/utils/device-id.test.js
@@ -5,7 +5,7 @@
deviceIDCharLength,
deviceTypes,
deviceIDFormatRegex,
-} from './device-id';
+} from './device-id.js';
describe('generateDeviceID', () => {
it(
diff --git a/web/utils/text-utils.test.js b/web/utils/text-utils.test.js
--- a/web/utils/text-utils.test.js
+++ b/web/utils/text-utils.test.js
@@ -1,6 +1,6 @@
// @flow
-import { generateRandomString } from './text-utils';
+import { generateRandomString } from './text-utils.js';
describe('generateRandomString', () => {
it('should return an empty string when passed length = 0', () => {
diff --git a/web/utils/tooltip-utils.js b/web/utils/tooltip-utils.js
--- a/web/utils/tooltip-utils.js
+++ b/web/utils/tooltip-utils.js
@@ -1,36 +1,39 @@
// @flow
import invariant from 'invariant';
-import _debounce from 'lodash/debounce';
+import _debounce from 'lodash/debounce.js';
import * as React from 'react';
-import type { ChatMessageInfoItem } from 'lib/selectors/chat-selectors';
-import { createMessageReply } from 'lib/shared/message-utils';
-import { useCanCreateReactionFromMessage } from 'lib/shared/reaction-utils';
+import type { ChatMessageInfoItem } from 'lib/selectors/chat-selectors.js';
+import { createMessageReply } from 'lib/shared/message-utils.js';
+import { useCanCreateReactionFromMessage } from 'lib/shared/reaction-utils.js';
import {
threadHasPermission,
useSidebarExistsOrCanBeCreated,
-} from 'lib/shared/thread-utils';
-import { isComposableMessageType, messageTypes } from 'lib/types/message-types';
-import type { ThreadInfo } from 'lib/types/thread-types';
-import { threadPermissions } from 'lib/types/thread-types';
-import { longAbsoluteDate } from 'lib/utils/date-utils';
+} from 'lib/shared/thread-utils.js';
+import {
+ isComposableMessageType,
+ messageTypes,
+} from 'lib/types/message-types.js';
+import type { ThreadInfo } from 'lib/types/thread-types.js';
+import { threadPermissions } from 'lib/types/thread-types.js';
+import { longAbsoluteDate } from 'lib/utils/date-utils.js';
import {
tooltipButtonStyle,
tooltipLabelStyle,
tooltipStyle,
-} from '../chat/chat-constants';
-import MessageTooltip from '../chat/message-tooltip.react';
-import type { PositionInfo } from '../chat/position-types';
-import { useTooltipContext } from '../chat/tooltip-provider';
-import CommIcon from '../CommIcon.react';
-import { InputStateContext } from '../input/input-state';
+} from '../chat/chat-constants.js';
+import MessageTooltip from '../chat/message-tooltip.react.js';
+import type { PositionInfo } from '../chat/position-types.js';
+import { useTooltipContext } from '../chat/tooltip-provider.js';
+import CommIcon from '../CommIcon.react.js';
+import { InputStateContext } from '../input/input-state.js';
import {
useOnClickPendingSidebar,
useOnClickThread,
-} from '../selectors/thread-selectors';
-import { calculateMaxTextWidth } from '../utils/text-utils';
+} from '../selectors/thread-selectors.js';
+import { calculateMaxTextWidth } from '../utils/text-utils.js';
export const tooltipPositions = Object.freeze({
LEFT: 'left',
diff --git a/web/utils/tooltip-utils.test.js b/web/utils/tooltip-utils.test.js
--- a/web/utils/tooltip-utils.test.js
+++ b/web/utils/tooltip-utils.test.js
@@ -1,7 +1,7 @@
// @flow
-import type { PositionInfo } from '../chat/position-types';
-import { findTooltipPosition, tooltipPositions } from './tooltip-utils';
+import type { PositionInfo } from '../chat/position-types.js';
+import { findTooltipPosition, tooltipPositions } from './tooltip-utils.js';
const QHDWindow = {
width: 2560,
diff --git a/web/utils/typeahead-utils.js b/web/utils/typeahead-utils.js
--- a/web/utils/typeahead-utils.js
+++ b/web/utils/typeahead-utils.js
@@ -3,15 +3,15 @@
import classNames from 'classnames';
import * as React from 'react';
-import { oldValidUsernameRegexString } from 'lib/shared/account-utils';
-import { getNewTextAndSelection } from 'lib/shared/typeahead-utils';
-import { stringForUserExplicit } from 'lib/shared/user-utils';
-import type { SetState } from 'lib/types/hook-types';
-import type { RelativeMemberInfo } from 'lib/types/thread-types';
+import { oldValidUsernameRegexString } from 'lib/shared/account-utils.js';
+import { getNewTextAndSelection } from 'lib/shared/typeahead-utils.js';
+import { stringForUserExplicit } from 'lib/shared/user-utils.js';
+import type { SetState } from 'lib/types/hook-types.js';
+import type { RelativeMemberInfo } from 'lib/types/thread-types.js';
-import { typeaheadStyle } from '../chat/chat-constants';
+import { typeaheadStyle } from '../chat/chat-constants.js';
import css from '../chat/typeahead-tooltip.css';
-import Button from '../components/button.react';
+import Button from '../components/button.react.js';
const webTypeaheadRegex: RegExp = new RegExp(
`(?<textPrefix>(?:^(?:.|\n)*\\s+)|^)@(?<username>${oldValidUsernameRegexString})?$`,
diff --git a/web/utils/typeahead-utils.test.js b/web/utils/typeahead-utils.test.js
--- a/web/utils/typeahead-utils.test.js
+++ b/web/utils/typeahead-utils.test.js
@@ -1,7 +1,7 @@
// @flow
-import { typeaheadStyle } from '../chat/chat-constants';
-import { getTypeaheadOverlayScroll } from './typeahead-utils';
+import { typeaheadStyle } from '../chat/chat-constants.js';
+import { getTypeaheadOverlayScroll } from './typeahead-utils.js';
describe('getTypeaheadOverlayScroll', () => {
it(
diff --git a/web/utils/wagmi-utils.js b/web/utils/wagmi-utils.js
--- a/web/utils/wagmi-utils.js
+++ b/web/utils/wagmi-utils.js
@@ -4,8 +4,11 @@
import * as React from 'react';
import { useProvider } from 'wagmi';
-import { ENSCacheProvider } from 'lib/components/ens-cache-provider.react';
-import { configureWagmiChains, createWagmiClient } from 'lib/utils/wagmi-utils';
+import { ENSCacheProvider } from 'lib/components/ens-cache-provider.react.js';
+import {
+ configureWagmiChains,
+ createWagmiClient,
+} from 'lib/utils/wagmi-utils.js';
const { chains, provider } = configureWagmiChains(process.env.COMM_ALCHEMY_KEY);
const connectors = connectorsForWallets([

File Metadata

Mime Type
text/plain
Expires
Tue, Dec 9, 3:14 PM (17 m, 40 s)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
5854920
Default Alt Text
D6692.1765293242.diff (905 KB)

Event Timeline