mirror of
https://github.com/ProtonMail/WebClients.git
synced 2026-01-16 23:12:49 +00:00
Remove isDeepEqual and import directly from Lodash
This commit is contained in:
parent
3f39b5966c
commit
ea85ff5585
52 changed files with 82 additions and 76 deletions
|
|
@ -2,6 +2,7 @@ import type { MutableRefObject, ReactNode, RefObject } from 'react';
|
|||
import { createContext, useCallback, useContext, useEffect, useRef, useState } from 'react';
|
||||
import { flushSync } from 'react-dom';
|
||||
|
||||
import isDeepEqual from 'lodash/isEqual';
|
||||
import merge from 'lodash/merge';
|
||||
|
||||
import type { ChallengeRef, ChallengeResult } from '@proton/components/containers/challenge/interface';
|
||||
|
|
@ -19,7 +20,6 @@ import {
|
|||
usernameLengthValidator,
|
||||
usernameStartCharacterValidator,
|
||||
} from '@proton/shared/lib/helpers/formValidators';
|
||||
import isDeepEqual from '@proton/shared/lib/helpers/isDeepEqual';
|
||||
import isTruthy from '@proton/utils/isTruthy';
|
||||
import noop from '@proton/utils/noop';
|
||||
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ import type { ComponentProps, Dispatch, MutableRefObject, ReactNode, SetStateAct
|
|||
import { Fragment, useEffect, useImperativeHandle, useMemo, useRef, useState } from 'react';
|
||||
import { Link, useHistory } from 'react-router-dom';
|
||||
|
||||
import isDeepEqual from 'lodash/isEqual';
|
||||
import { c } from 'ttag';
|
||||
|
||||
import { Button } from '@proton/atoms/Button/Button';
|
||||
|
|
@ -69,7 +70,6 @@ import { getSilentApi } from '@proton/shared/lib/api/helpers/customConfig';
|
|||
import { TelemetryAccountSignupEvents } from '@proton/shared/lib/api/telemetry';
|
||||
import type { ActiveSession } from '@proton/shared/lib/authentication/persistedSessionHelper';
|
||||
import { APPS, BRAND_NAME, DRIVE_APP_NAME, PASS_APP_NAME, SSO_PATHS } from '@proton/shared/lib/constants';
|
||||
import isDeepEqual from '@proton/shared/lib/helpers/isDeepEqual';
|
||||
import { getPrivacyPolicyURL } from '@proton/shared/lib/helpers/url';
|
||||
import type { Api, VPNServersCountData } from '@proton/shared/lib/interfaces';
|
||||
import { Audience } from '@proton/shared/lib/interfaces';
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
import isDeepEqual from 'lodash/isEqual';
|
||||
|
||||
import { canBuyPassLifetime } from '@proton/components/containers/payments/subscription/subscriptionEligbility';
|
||||
import {
|
||||
type ADDON_NAMES,
|
||||
|
|
@ -52,7 +54,6 @@ import { partnerWhitelist } from '@proton/shared/lib/api/partner';
|
|||
import type { ResumedSessionResult } from '@proton/shared/lib/authentication/persistedSessionHelper';
|
||||
import type { APP_NAMES } from '@proton/shared/lib/constants';
|
||||
import { APPS } from '@proton/shared/lib/constants';
|
||||
import isDeepEqual from '@proton/shared/lib/helpers/isDeepEqual';
|
||||
import type { Api, Organization, User } from '@proton/shared/lib/interfaces';
|
||||
import { Audience } from '@proton/shared/lib/interfaces';
|
||||
import { getOrganization } from '@proton/shared/lib/organization/api';
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import type { Dispatch, ReactElement, ReactNode, SetStateAction } from 'react';
|
||||
import { Fragment, useEffect, useRef, useState } from 'react';
|
||||
|
||||
import isDeepEqual from 'lodash/isEqual';
|
||||
import { c, msgid } from 'ttag';
|
||||
|
||||
import { Button } from '@proton/atoms/Button/Button';
|
||||
|
|
@ -81,7 +82,6 @@ import {
|
|||
VPN_CONNECTIONS,
|
||||
VPN_SHORT_APP_NAME,
|
||||
} from '@proton/shared/lib/constants';
|
||||
import isDeepEqual from '@proton/shared/lib/helpers/isDeepEqual';
|
||||
import { captureMessage } from '@proton/shared/lib/helpers/sentry';
|
||||
import { getSentryError } from '@proton/shared/lib/keys';
|
||||
import { generatePassword } from '@proton/shared/lib/password';
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import type { Dispatch, ReactElement, ReactNode, SetStateAction } from 'react';
|
||||
import { Fragment, useEffect, useRef, useState } from 'react';
|
||||
|
||||
import isDeepEqual from 'lodash/isEqual';
|
||||
import { c, msgid } from 'ttag';
|
||||
|
||||
import { Button } from '@proton/atoms/Button/Button';
|
||||
|
|
@ -81,7 +82,6 @@ import {
|
|||
VPN_CONNECTIONS,
|
||||
VPN_SHORT_APP_NAME,
|
||||
} from '@proton/shared/lib/constants';
|
||||
import isDeepEqual from '@proton/shared/lib/helpers/isDeepEqual';
|
||||
import { captureMessage } from '@proton/shared/lib/helpers/sentry';
|
||||
import { getSentryError } from '@proton/shared/lib/keys';
|
||||
import { generatePassword } from '@proton/shared/lib/password';
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import { useLocation } from 'react-router-dom';
|
||||
|
||||
import isDeepEqual from 'lodash/isEqual';
|
||||
import { c } from 'ttag';
|
||||
|
||||
import { orderAddresses } from '@proton/account/addresses/actions';
|
||||
|
|
@ -10,7 +11,6 @@ import SelectTwo from '@proton/components/components/selectTwo/SelectTwo';
|
|||
import { getStatus } from '@proton/components/containers/addresses/helper';
|
||||
import { useLoading } from '@proton/hooks/index';
|
||||
import { useDispatch } from '@proton/redux-shared-store/sharedProvider';
|
||||
import isDeepEqual from '@proton/shared/lib/helpers/isDeepEqual';
|
||||
import type { Address } from '@proton/shared/lib/interfaces';
|
||||
import { getIsNonDefault, sortAddresses } from '@proton/shared/lib/mail/addresses';
|
||||
import { isMailVersionOlderThan } from '@proton/shared/lib/mobile/isMailVersionOlderThan';
|
||||
|
|
|
|||
|
|
@ -1,10 +1,11 @@
|
|||
import isDeepEqual from 'lodash/isEqual';
|
||||
|
||||
import { ICAL_METHOD } from '@proton/shared/lib/calendar/constants';
|
||||
import { getBase64SharedSessionKey } from '@proton/shared/lib/calendar/crypto/keys/helpers';
|
||||
import { getSupportedStringValue } from '@proton/shared/lib/calendar/icsSurgery/vcal';
|
||||
import { getInviteVeventWithUpdatedParstats } from '@proton/shared/lib/calendar/mailIntegration/invite';
|
||||
import { getPropertyTzid } from '@proton/shared/lib/calendar/vcalHelper';
|
||||
import { getIsAllDay } from '@proton/shared/lib/calendar/veventHelper';
|
||||
import isDeepEqual from '@proton/shared/lib/helpers/isDeepEqual';
|
||||
import { omit } from '@proton/shared/lib/helpers/object';
|
||||
import type { RequireSome } from '@proton/shared/lib/interfaces';
|
||||
import type { SyncMultipleApiResponse, VcalVeventComponent } from '@proton/shared/lib/interfaces/calendar';
|
||||
|
|
|
|||
|
|
@ -68,6 +68,7 @@
|
|||
"history": "^4.10.1",
|
||||
"idb": "^8.0.3",
|
||||
"idb-keyval": "^6.2.2",
|
||||
"lodash": "^4.17.21",
|
||||
"mime-types": "^2.1.35",
|
||||
"react": "^18.3.1",
|
||||
"react-dom": "^18.3.1",
|
||||
|
|
@ -90,6 +91,7 @@
|
|||
"@testing-library/react": "^15.0.7",
|
||||
"@testing-library/react-hooks": "^8.0.1",
|
||||
"@testing-library/user-event": "^14.6.1",
|
||||
"@types/lodash": "^4.17.21",
|
||||
"@types/mime-types": "^2.1.4",
|
||||
"@types/react": "^18.3.27",
|
||||
"@types/react-dom": "^18.3.7",
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import { useEffect, useRef, useState } from 'react';
|
||||
|
||||
import isEqual from 'lodash/isEqual';
|
||||
import { c } from 'ttag';
|
||||
|
||||
import { useSubscription } from '@proton/account/subscription/hooks';
|
||||
|
|
@ -25,7 +26,6 @@ import {
|
|||
sendRequestCollapsibleSidebarReport,
|
||||
useLeftSidebarButton,
|
||||
} from '@proton/shared/lib/helpers/collapsibleSidebar';
|
||||
import isEqual from '@proton/shared/lib/helpers/isDeepEqual';
|
||||
import { getCanAddStorage } from '@proton/shared/lib/user/storage';
|
||||
import clsx from '@proton/utils/clsx';
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import { useEffect, useRef, useState } from 'react';
|
||||
|
||||
import isEqual from 'lodash/isEqual';
|
||||
import { c } from 'ttag';
|
||||
import { useShallow } from 'zustand/react/shallow';
|
||||
|
||||
|
|
@ -26,7 +27,6 @@ import {
|
|||
sendRequestCollapsibleSidebarReport,
|
||||
useLeftSidebarButton,
|
||||
} from '@proton/shared/lib/helpers/collapsibleSidebar';
|
||||
import isEqual from '@proton/shared/lib/helpers/isDeepEqual';
|
||||
import { getCanAddStorage } from '@proton/shared/lib/user/storage';
|
||||
import clsx from '@proton/utils/clsx';
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import { useCallback, useEffect, useState } from 'react';
|
||||
|
||||
import isEqual from '@proton/shared/lib/helpers/isDeepEqual';
|
||||
import isEqual from 'lodash/isEqual';
|
||||
|
||||
import { getItem, removeItem, setItem } from '@proton/shared/lib/helpers/storage';
|
||||
import { VolumeType } from '@proton/shared/lib/interfaces/drive/volume';
|
||||
|
||||
|
|
|
|||
|
|
@ -55,14 +55,14 @@ import { waitForSpace } from './spaces';
|
|||
|
||||
function* saveDirtyConversation(serializedConversation: SerializedConversation): SagaIterator {
|
||||
console.log('Saga triggered: saveDirtyConversation', serializedConversation);
|
||||
|
||||
|
||||
// Check if this is a ghost conversation - if so, skip saving to IndexedDB
|
||||
const conversation: Conversation | undefined = yield select(selectConversationById(serializedConversation.id));
|
||||
if (conversation?.ghost) {
|
||||
console.log('saveDirtyConversation: Ghost conversation detected, skipping IndexedDB persistence');
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
const dbApi: DbApi = yield getContext('dbApi');
|
||||
yield call([dbApi, dbApi.updateConversation], serializedConversation, {
|
||||
dirty: true,
|
||||
|
|
@ -265,7 +265,7 @@ export function* pushConversation({ payload }: { payload: PushConversationReques
|
|||
const type: ResourceType = 'conversation';
|
||||
const { id: localId } = payload;
|
||||
const priority = payload.priority || 'urgent';
|
||||
|
||||
|
||||
// Check if phantom chat mode is enabled - if so, skip remote persistence
|
||||
const isGhostChatMode: boolean = yield select((state: LumoState) => state.ghostChat?.isGhostChatMode || false);
|
||||
if (isGhostChatMode) {
|
||||
|
|
|
|||
|
|
@ -47,14 +47,14 @@ import { waitForSpace } from './spaces';
|
|||
|
||||
export function* saveDirtyMessage(serializedMessage: SerializedMessage): SagaIterator {
|
||||
console.log('Saga triggered: saveDirtyMessage', serializedMessage);
|
||||
|
||||
|
||||
// Check if this message belongs to a ghost conversation - if so, skip saving to IndexedDB
|
||||
const conversation: Conversation | undefined = yield select(selectConversationById(serializedMessage.conversationId));
|
||||
if (conversation?.ghost) {
|
||||
console.log('saveDirtyMessage: Message belongs to ghost conversation, skipping IndexedDB persistence');
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
const dbApi: DbApi = yield getContext('dbApi');
|
||||
yield call([dbApi, dbApi.updateMessage], serializedMessage, {
|
||||
dirty: true,
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import type { ChangeEvent } from 'react';
|
||||
import { useEffect, useMemo, useState } from 'react';
|
||||
|
||||
import isDeepEqual from 'lodash/isEqual';
|
||||
import { c } from 'ttag';
|
||||
|
||||
import { useUser } from '@proton/account/user/hooks';
|
||||
|
|
@ -22,7 +23,6 @@ import { isCustomLabel } from '@proton/mail/helpers/location';
|
|||
import { getRandomAccentColor } from '@proton/shared/lib/colors';
|
||||
import { LABEL_TYPE, MAILBOX_LABEL_IDS, MAIL_UPSELL_PATHS } from '@proton/shared/lib/constants';
|
||||
import { hasReachedLabelLimit } from '@proton/shared/lib/helpers/folder';
|
||||
import isDeepEqual from '@proton/shared/lib/helpers/isDeepEqual';
|
||||
import { normalize } from '@proton/shared/lib/helpers/string';
|
||||
import type { Label } from '@proton/shared/lib/interfaces/Label';
|
||||
import clsx from '@proton/utils/clsx';
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import { useHistory } from 'react-router-dom';
|
|||
|
||||
import { add, fromUnixTime, getUnixTime, isAfter, isBefore, isEqual, sub } from 'date-fns';
|
||||
import type { History } from 'history';
|
||||
import isDeepEqual from 'lodash/isEqual';
|
||||
import { c } from 'ttag';
|
||||
|
||||
import { useAddresses } from '@proton/account/addresses/hooks';
|
||||
|
|
@ -17,7 +18,6 @@ import { getHumanLabelID } from '@proton/mail/helpers/location';
|
|||
import { useMailSettings } from '@proton/mail/store/mailSettings/hooks';
|
||||
import { MAILBOX_LABEL_IDS } from '@proton/shared/lib/constants';
|
||||
import { validateEmailAddress } from '@proton/shared/lib/helpers/email';
|
||||
import isDeepEqual from '@proton/shared/lib/helpers/isDeepEqual';
|
||||
import { omit } from '@proton/shared/lib/helpers/object';
|
||||
import { changeSearchParams, getSearchParams } from '@proton/shared/lib/helpers/url';
|
||||
import type { Recipient } from '@proton/shared/lib/interfaces/Address';
|
||||
|
|
|
|||
|
|
@ -1,11 +1,12 @@
|
|||
import { useCallback, useEffect, useMemo, useRef } from 'react';
|
||||
import { useHistory, useLocation } from 'react-router-dom';
|
||||
|
||||
import isDeepEqual from 'lodash/isEqual';
|
||||
|
||||
import { useConversationCounts, useGetConversationCounts, useGetMessageCounts, useMessageCounts } from '@proton/mail';
|
||||
import { useFolders, useLabels } from '@proton/mail/store/labels/hooks';
|
||||
import { CacheType } from '@proton/redux-utilities';
|
||||
import { MAILBOX_LABEL_IDS } from '@proton/shared/lib/constants';
|
||||
import isDeepEqual from '@proton/shared/lib/helpers/isDeepEqual';
|
||||
import { omit } from '@proton/shared/lib/helpers/object';
|
||||
import { captureMessage } from '@proton/shared/lib/helpers/sentry';
|
||||
import type { Label, MailSettings } from '@proton/shared/lib/interfaces';
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
import type { MutableRefObject } from 'react';
|
||||
import { useCallback, useEffect, useRef, useState } from 'react';
|
||||
|
||||
import isEqual from '@proton/shared/lib/helpers/isDeepEqual';
|
||||
import isEqual from 'lodash/isEqual';
|
||||
|
||||
import type { Filter, Sort } from '@proton/shared/lib/mail/search';
|
||||
|
||||
export interface MailboxFocusProps {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import type { DependencyList } from 'react';
|
||||
import { useMemo, useRef } from 'react';
|
||||
|
||||
import isDeepEqual from '@proton/shared/lib/helpers/isDeepEqual';
|
||||
import isDeepEqual from 'lodash/isEqual';
|
||||
|
||||
/**
|
||||
* Special performance oriented useMemo which will store the previous value,
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
import type { PayloadAction } from '@reduxjs/toolkit';
|
||||
import type { Draft } from 'immer';
|
||||
import isDeepEqual from 'lodash/isEqual';
|
||||
|
||||
import { safeDecreaseCount, safeIncreaseCount } from '@proton/redux-utilities';
|
||||
import isDeepEqual from '@proton/shared/lib/helpers/isDeepEqual';
|
||||
import { toMap } from '@proton/shared/lib/helpers/object';
|
||||
import type { Folder, Label } from '@proton/shared/lib/interfaces';
|
||||
import type { Message, MessageMetadata } from '@proton/shared/lib/interfaces/mail/Message';
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
import isDeepEqual from 'lodash/isEqual';
|
||||
|
||||
import { getConversation, queryConversations } from '@proton/shared/lib/api/conversations';
|
||||
import type { MailboxItemsQueryParams } from '@proton/shared/lib/api/mailbox';
|
||||
import { getMessage, queryMessageMetadata } from '@proton/shared/lib/api/messages';
|
||||
import isDeepEqual from '@proton/shared/lib/helpers/isDeepEqual';
|
||||
import { omit, pick } from '@proton/shared/lib/helpers/object';
|
||||
import type { Api } from '@proton/shared/lib/interfaces';
|
||||
import { CUSTOM_VIEWS_LABELS } from '@proton/shared/lib/mail/constants';
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import { flushSync } from 'react-dom';
|
||||
|
||||
import type { History, LocationDescriptorObject } from 'history';
|
||||
import isDeepEqual from 'lodash/isEqual';
|
||||
import type { ServiceWorkerClient } from 'proton-pass-web/app/ServiceWorker/client/client';
|
||||
import { store } from 'proton-pass-web/app/Store/store';
|
||||
import { B2BEvents } from 'proton-pass-web/lib/b2b';
|
||||
|
|
@ -51,7 +52,6 @@ import {
|
|||
} from '@proton/shared/lib/authentication/pathnameHelper';
|
||||
import { APPS } from '@proton/shared/lib/constants';
|
||||
import { stringToUint8Array } from '@proton/shared/lib/helpers/encoding';
|
||||
import isDeepEqual from '@proton/shared/lib/helpers/isDeepEqual';
|
||||
import { omit } from '@proton/shared/lib/helpers/object';
|
||||
import { wait } from '@proton/shared/lib/helpers/promise';
|
||||
import { setUID as setSentryUID } from '@proton/shared/lib/helpers/sentry';
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
import { useEffect } from 'react';
|
||||
|
||||
import isDeepEqual from 'lodash/isEqual';
|
||||
|
||||
import usePrevious from '@proton/hooks/usePrevious';
|
||||
import isDeepEqual from '@proton/shared/lib/helpers/isDeepEqual';
|
||||
|
||||
export const useItemEffect = <T>(effect: (item: T) => void | (() => void), items: T[], otherDeps?: any[]) => {
|
||||
const previous = usePrevious(items);
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
import { useEffect, useState } from 'react';
|
||||
|
||||
import isDeepEqual from 'lodash/isEqual';
|
||||
|
||||
import usePrevious from '@proton/hooks/usePrevious';
|
||||
import isDeepEqual from '@proton/shared/lib/helpers/isDeepEqual';
|
||||
|
||||
export const useAsyncValue = <T extends unknown>(promise: Promise<T>, dv: T) => {
|
||||
const [v, s] = useState(dv);
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
import isDeepEqual from 'lodash/isEqual';
|
||||
|
||||
import { CryptoProxy } from '@proton/crypto';
|
||||
import type { SharedStartListening } from '@proton/redux-shared-store-types';
|
||||
import { CacheType } from '@proton/redux-utilities';
|
||||
import isDeepEqual from '@proton/shared/lib/helpers/isDeepEqual';
|
||||
import type { Address, DecryptedAddressKey, DecryptedKey, Key } from '@proton/shared/lib/interfaces';
|
||||
import noop from '@proton/utils/noop';
|
||||
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
import { createSlice } from '@reduxjs/toolkit';
|
||||
import isDeepEqual from 'lodash/isEqual';
|
||||
|
||||
import type { ProtonThunkArguments } from '@proton/redux-shared-store-types';
|
||||
import { createAsyncModelThunk, handleAsyncModel, previousSelector } from '@proton/redux-utilities';
|
||||
import { getIsMissingScopeError } from '@proton/shared/lib/api/helpers/apiErrorHelper';
|
||||
import { getOrganizationKeys } from '@proton/shared/lib/api/organization';
|
||||
import isDeepEqual from '@proton/shared/lib/helpers/isDeepEqual';
|
||||
import type { CachedOrganizationKey, Organization, OrganizationKey, UserModel } from '@proton/shared/lib/interfaces';
|
||||
import type { CachedOrganizationKey, Organization, OrganizationKey, UserModel } from '@proton/shared/lib/interfaces';
|
||||
import { getCachedOrganizationKey } from '@proton/shared/lib/keys';
|
||||
|
||||
import type { AddressKeysState } from '../addressKeys';
|
||||
|
|
@ -20,12 +20,7 @@ import { type UserKeysState, userKeysThunk } from '../userKeys';
|
|||
const name = 'organizationKey' as const;
|
||||
|
||||
export interface OrganizationKeyState
|
||||
extends UserState,
|
||||
OrganizationState,
|
||||
UserKeysState,
|
||||
AddressesState,
|
||||
AddressKeysState,
|
||||
MembersState {
|
||||
extends UserState, OrganizationState, UserKeysState, AddressesState, AddressKeysState, MembersState {
|
||||
[name]: ModelState<CachedOrganizationKey>;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,9 +1,10 @@
|
|||
import type { FormEvent } from 'react';
|
||||
import { useMemo, useState } from 'react';
|
||||
|
||||
import isDeepEqual from 'lodash/isEqual';
|
||||
|
||||
import { getMailMappingErrors } from '@proton/activation/src/helpers/getMailMappingErrors';
|
||||
import { useFolders, useLabels } from '@proton/mail';
|
||||
import isDeepEqual from '@proton/shared/lib/helpers/isDeepEqual';
|
||||
|
||||
import type { FolderMapItem, MailImportFields } from './CustomizeMailImportModal.interface';
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import { useMemo, useState } from 'react';
|
||||
|
||||
import cloneDeep from 'lodash/cloneDeep';
|
||||
import isDeepEqual from 'lodash/isEqual';
|
||||
|
||||
import { GMAIL_CATEGORIES, IMAPS } from '@proton/activation/src/constants';
|
||||
import type { MailImportFolder } from '@proton/activation/src/helpers/MailImportFoldersParser/MailImportFoldersParser';
|
||||
|
|
@ -17,7 +18,6 @@ import {
|
|||
import { selectImapDraftMailImport } from '@proton/activation/src/logic/draft/imapDraft/imapDraft.selector';
|
||||
import { useEasySwitchDispatch, useEasySwitchSelector } from '@proton/activation/src/logic/store';
|
||||
import { useFolders, useLabels } from '@proton/mail';
|
||||
import isDeepEqual from '@proton/shared/lib/helpers/isDeepEqual';
|
||||
import type { Address, Label, UserModel } from '@proton/shared/lib/interfaces';
|
||||
|
||||
import type { MailImportFields } from '../../../CustomizeMailImportModal/CustomizeMailImportModal.interface';
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
import isDeepEqual from 'lodash/isEqual';
|
||||
import { c } from 'ttag';
|
||||
|
||||
import { startImportTask } from '@proton/activation/src/api';
|
||||
|
|
@ -12,7 +13,6 @@ import { createCalendar, updateCalendarUserSettings } from '@proton/shared/lib/a
|
|||
import { setupCalendarKey } from '@proton/shared/lib/calendar/crypto/keys/setupCalendarKeys';
|
||||
import { getRandomAccentColor } from '@proton/shared/lib/colors';
|
||||
import { getTimezone } from '@proton/shared/lib/date/timezone';
|
||||
import isDeepEqual from '@proton/shared/lib/helpers/isDeepEqual';
|
||||
import { captureMessage } from '@proton/shared/lib/helpers/sentry';
|
||||
import type { Address, Api } from '@proton/shared/lib/interfaces';
|
||||
import type { Calendar } from '@proton/shared/lib/interfaces/calendar';
|
||||
|
|
|
|||
|
|
@ -3,8 +3,7 @@ import { useCallback, useLayoutEffect, useMemo, useRef, useState } from 'react';
|
|||
|
||||
import type { Placement, Strategy, VirtualElement } from '@floating-ui/dom';
|
||||
import { autoUpdate, computePosition, flip, hide, offset, shift, size } from '@floating-ui/dom';
|
||||
|
||||
import isDeepEqual from '@proton/shared/lib/helpers/isDeepEqual';
|
||||
import isDeepEqual from 'lodash/isEqual';
|
||||
|
||||
import type { PopperArrow, PopperPlacement, PopperPosition } from './interface';
|
||||
import { allPopperPlacements, arrowOffset, getClickRect, getFallbackPlacements, rtlPlacement } from './utils';
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import { useCallback, useEffect, useState } from 'react';
|
||||
|
||||
import isDeepEqual from 'lodash/isEqual';
|
||||
import { c, msgid } from 'ttag';
|
||||
|
||||
import { orderAddresses } from '@proton/account/addresses/actions';
|
||||
|
|
@ -39,7 +40,6 @@ import {
|
|||
} from '@proton/shared/lib/constants';
|
||||
import { getIsBYOEOnlyAccount } from '@proton/shared/lib/helpers/address';
|
||||
import { textToClipboard } from '@proton/shared/lib/helpers/browser';
|
||||
import isDeepEqual from '@proton/shared/lib/helpers/isDeepEqual';
|
||||
import { getUpsellRef } from '@proton/shared/lib/helpers/upsell';
|
||||
import { getKnowledgeBaseUrl } from '@proton/shared/lib/helpers/url';
|
||||
import type { Address, CachedOrganizationKey, Member, UserModel } from '@proton/shared/lib/interfaces';
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
import { type ReactNode, useEffect, useRef, useState } from 'react';
|
||||
|
||||
import isDeepEqual from 'lodash/isEqual';
|
||||
|
||||
import { type ApiStatusState, apiStatusActions, defaultApiStatus } from '@proton/account/apiStatus';
|
||||
import { selectUser } from '@proton/account/user';
|
||||
import useAuthentication from '@proton/components/hooks/useAuthentication';
|
||||
|
|
@ -8,7 +10,6 @@ import useNotifications from '@proton/components/hooks/useNotifications';
|
|||
import { useDispatch, useStore } from '@proton/redux-shared-store/sharedProvider';
|
||||
import type { ApiListenerCallback, ApiWithListener } from '@proton/shared/lib/api/createApi';
|
||||
import { handleInvalidSession } from '@proton/shared/lib/authentication/logout';
|
||||
import isDeepEqual from '@proton/shared/lib/helpers/isDeepEqual';
|
||||
|
||||
import ApiModals from './ApiModals';
|
||||
import ApiContext from './apiContext';
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import type { ChangeEvent, FormEvent, ReactNode } from 'react';
|
||||
import { useEffect, useMemo, useState } from 'react';
|
||||
|
||||
import isDeepEqual from 'lodash/isEqual';
|
||||
import { c } from 'ttag';
|
||||
|
||||
import { useUser } from '@proton/account/user/hooks';
|
||||
|
|
@ -22,7 +23,6 @@ import {
|
|||
hasReachedContactGroupMembersLimit,
|
||||
} from '@proton/shared/lib/contacts/helpers/contactGroup';
|
||||
import { validateEmailAddress } from '@proton/shared/lib/helpers/email';
|
||||
import isDeepEqual from '@proton/shared/lib/helpers/isDeepEqual';
|
||||
import { normalize } from '@proton/shared/lib/helpers/string';
|
||||
import type { ContactEmail, ContactGroup } from '@proton/shared/lib/interfaces/contacts/Contact';
|
||||
import clsx from '@proton/utils/clsx';
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import React, { useEffect, useMemo, useState } from 'react';
|
||||
|
||||
import isDeepEqual from 'lodash/isEqual';
|
||||
import { c } from 'ttag';
|
||||
|
||||
import Form from '@proton/components/components/form/Form';
|
||||
|
|
@ -19,7 +20,6 @@ import { useFolders, useLabels } from '@proton/mail';
|
|||
import { addFilter, updateFilter } from '@proton/mail/store/filters/actions';
|
||||
import { useFilters } from '@proton/mail/store/filters/hooks';
|
||||
import { applyFilters } from '@proton/shared/lib/api/filters';
|
||||
import isDeepEqual from '@proton/shared/lib/helpers/isDeepEqual';
|
||||
import { AUTO_REPLY_CHARACTER_COUNT_LIMIT } from '@proton/shared/lib/mail/constants';
|
||||
import { removeImagesFromContent } from '@proton/shared/lib/sanitize/purify';
|
||||
import generateUID from '@proton/utils/generateUID';
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import isDeepEqual from '@proton/shared/lib/helpers/isDeepEqual';
|
||||
import isDeepEqual from 'lodash/isEqual';
|
||||
|
||||
import { toMap } from '@proton/shared/lib/helpers/object';
|
||||
import { fromSieveTree, toSieveTree } from '@proton/sieve';
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import { useEffect, useState } from 'react';
|
||||
|
||||
import isDeepEqual from 'lodash/isEqual';
|
||||
import { c } from 'ttag';
|
||||
|
||||
import { useUser } from '@proton/account/user/hooks';
|
||||
|
|
@ -21,7 +22,6 @@ import { CacheType } from '@proton/redux-utilities';
|
|||
import { orderLabels } from '@proton/shared/lib/api/labels';
|
||||
import { MAIL_UPSELL_PATHS } from '@proton/shared/lib/constants';
|
||||
import { hasReachedLabelLimit } from '@proton/shared/lib/helpers/folder';
|
||||
import isDeepEqual from '@proton/shared/lib/helpers/isDeepEqual';
|
||||
import type { Label } from '@proton/shared/lib/interfaces';
|
||||
import move from '@proton/utils/move';
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +1,9 @@
|
|||
import type { ReactNode, Reducer } from 'react';
|
||||
import { useEffect, useReducer, useState } from 'react';
|
||||
|
||||
import isDeepEqual from 'lodash/isEqual';
|
||||
|
||||
import useInstance from '@proton/hooks/useInstance';
|
||||
import isDeepEqual from '@proton/shared/lib/helpers/isDeepEqual';
|
||||
|
||||
import NotificationsChildrenContext from './childrenContext';
|
||||
import type { Notification, NotificationOffset } from './interfaces';
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import type { FormEvent, ReactNode, RefObject } from 'react';
|
||||
import { useEffect, useMemo, useRef, useState } from 'react';
|
||||
|
||||
import isEqual from 'lodash/isEqual';
|
||||
import { c } from 'ttag';
|
||||
|
||||
import { useUser } from '@proton/account/user/hooks';
|
||||
|
|
@ -93,7 +94,6 @@ import type { ProductParam } from '@proton/shared/lib/apps/product';
|
|||
import { getShouldCalendarPreventSubscripitionChange } from '@proton/shared/lib/calendar/plans';
|
||||
import { APPS, type APP_NAMES } from '@proton/shared/lib/constants';
|
||||
import { API_CUSTOM_ERROR_CODES } from '@proton/shared/lib/errors';
|
||||
import isEqual from '@proton/shared/lib/helpers/isDeepEqual';
|
||||
import { captureMessage } from '@proton/shared/lib/helpers/sentry';
|
||||
import type { Organization, RequireOnly, UserModel } from '@proton/shared/lib/interfaces';
|
||||
import { getSentryError } from '@proton/shared/lib/keys';
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
import type { ReactNode } from 'react';
|
||||
import { createContext, useCallback, useContext, useEffect, useLayoutEffect, useMemo, useState } from 'react';
|
||||
|
||||
import isDeepEqual from 'lodash/isEqual';
|
||||
|
||||
import type { APP_NAMES } from '@proton/shared/lib/constants';
|
||||
import { APPS } from '@proton/shared/lib/constants';
|
||||
import {
|
||||
|
|
@ -13,7 +15,6 @@ import { clearBit, hasBit, setBit } from '@proton/shared/lib/helpers/bitset';
|
|||
import { getCookie, setCookie } from '@proton/shared/lib/helpers/cookies';
|
||||
import { isElectronMail, isElectronOnSupportedApps } from '@proton/shared/lib/helpers/desktop';
|
||||
import { updateElectronThemeModeClassnames } from '@proton/shared/lib/helpers/initElectronClassnames';
|
||||
import isDeepEqual from '@proton/shared/lib/helpers/isDeepEqual';
|
||||
import createListeners from '@proton/shared/lib/helpers/listeners';
|
||||
import { getSecondLevelDomain } from '@proton/shared/lib/helpers/url';
|
||||
import {
|
||||
|
|
|
|||
|
|
@ -1,8 +1,9 @@
|
|||
import type { DependencyList, RefObject } from 'react';
|
||||
import { useRef } from 'react';
|
||||
|
||||
import isDeepEqual from 'lodash/isEqual';
|
||||
|
||||
import { isMac } from '@proton/shared/lib/helpers/browser';
|
||||
import isDeepEqual from '@proton/shared/lib/helpers/isDeepEqual';
|
||||
import type { KeyboardKeyType } from '@proton/shared/lib/interfaces';
|
||||
import { KeyboardKey } from '@proton/shared/lib/interfaces';
|
||||
import isTruthy from '@proton/utils/isTruthy';
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import { useCallback, useEffect, useState } from 'react';
|
||||
|
||||
import isEqual from '@proton/shared/lib/helpers/isDeepEqual';
|
||||
import isEqual from 'lodash/isEqual';
|
||||
|
||||
import { getItem, removeItem, setItem } from '@proton/shared/lib/helpers/storage';
|
||||
import { VolumeType } from '@proton/shared/lib/interfaces/drive/volume';
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import { useEffect, useMemo, useRef } from 'react';
|
||||
|
||||
import type { IDBPDatabase } from 'idb';
|
||||
import isDeepEqual from 'lodash/isEqual';
|
||||
import { c } from 'ttag';
|
||||
|
||||
import { useUser } from '@proton/account/user/hooks';
|
||||
|
|
@ -13,7 +14,6 @@ import { storeESUserChoiceInboxDesktop } from '@proton/shared/lib/desktop/encryp
|
|||
import { hasBit } from '@proton/shared/lib/helpers/bitset';
|
||||
import { isFirefox } from '@proton/shared/lib/helpers/browser';
|
||||
import { isElectronApp } from '@proton/shared/lib/helpers/desktop';
|
||||
import isDeepEqual from '@proton/shared/lib/helpers/isDeepEqual';
|
||||
import { wait } from '@proton/shared/lib/helpers/promise';
|
||||
|
||||
import {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import isDeepEqual from 'lodash/isEqual';
|
||||
|
||||
import type { ItemContent, ItemExtraField, ItemRevision, ItemType, Metadata } from '@proton/pass/types';
|
||||
import isDeepEqual from '@proton/shared/lib/helpers/isDeepEqual';
|
||||
|
||||
type Diff<T extends object> = Partial<Record<keyof T, boolean>>;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
import type { Selector } from '@reduxjs/toolkit';
|
||||
|
||||
import isDeepEqual from '@proton/shared/lib/helpers/isDeepEqual';
|
||||
import isDeepEqual from 'lodash/isEqual';
|
||||
|
||||
import type {
|
||||
MaybeOptimisticStateObject,
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import type { Selector } from '@reduxjs/toolkit';
|
||||
|
||||
import isDeepEqual from '@proton/shared/lib/helpers/isDeepEqual';
|
||||
import isDeepEqual from 'lodash/isEqual';
|
||||
|
||||
import type {
|
||||
MaybeOptimisticStateObject,
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
import isDeepEqual from 'lodash/isEqual';
|
||||
import type { Reducer } from 'redux';
|
||||
|
||||
import {
|
||||
|
|
@ -12,25 +13,14 @@ import {
|
|||
userEvent,
|
||||
userRefresh,
|
||||
} from '@proton/pass/store/actions';
|
||||
import {
|
||||
confirmPendingAuthDevice,
|
||||
getAuthDevices,
|
||||
rejectPendingAuthDevice,
|
||||
} from '@proton/pass/store/actions/creators/sso';
|
||||
import type {
|
||||
BitField,
|
||||
MaybeNull,
|
||||
PassPlanResponse,
|
||||
RequiredNonNull,
|
||||
UserMonitorStatusResponse,
|
||||
} from '@proton/pass/types';
|
||||
import { confirmPendingAuthDevice, getAuthDevices, rejectPendingAuthDevice } from '@proton/pass/store/actions/creators/sso';
|
||||
import type { BitField, MaybeNull, PassPlanResponse, RequiredNonNull, UserMonitorStatusResponse } from '@proton/pass/types';
|
||||
import { EventActions } from '@proton/pass/types';
|
||||
import type { PassFeature } from '@proton/pass/types/api/features';
|
||||
import { or } from '@proton/pass/utils/fp/predicates';
|
||||
import { objectDelete } from '@proton/pass/utils/object/delete';
|
||||
import { merge, partialMerge } from '@proton/pass/utils/object/merge';
|
||||
import { SETTINGS_PROTON_SENTINEL_STATE } from '@proton/shared/lib/constants';
|
||||
import isDeepEqual from '@proton/shared/lib/helpers/isDeepEqual';
|
||||
import updateCollection from '@proton/shared/lib/helpers/updateCollection';
|
||||
import type { Address, SETTINGS_PASSWORD_MODE, SETTINGS_STATUS, User } from '@proton/shared/lib/interfaces';
|
||||
import type { AuthDeviceOutput } from '@proton/shared/lib/keys/device';
|
||||
|
|
@ -119,8 +109,7 @@ const reducer: Reducer<UserState> = (state = getInitialState(), action) => {
|
|||
: state.userSettings;
|
||||
|
||||
const addresses = Addresses.reduce(
|
||||
(acc, { Action, ID, Address }) =>
|
||||
Action === EventActions.DELETE ? objectDelete(acc, ID) : merge(acc, { [ID]: Address }),
|
||||
(acc, { Action, ID, Address }) => (Action === EventActions.DELETE ? objectDelete(acc, ID) : merge(acc, { [ID]: Address })),
|
||||
state.addresses
|
||||
);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
import { addWeeks, fromUnixTime, isAfter, isBefore, subWeeks } from 'date-fns';
|
||||
import isDeepEqual from 'lodash/isEqual';
|
||||
|
||||
import type { ProductParam } from '@proton/shared/lib/apps/product';
|
||||
import { APPS } from '@proton/shared/lib/constants';
|
||||
import { hasBit } from '@proton/shared/lib/helpers/bitset';
|
||||
import isDeepEqual from '@proton/shared/lib/helpers/isDeepEqual';
|
||||
import { Audience, type Organization, type UserModel } from '@proton/shared/lib/interfaces';
|
||||
|
||||
import {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import isEqual from '@proton/shared/lib/helpers/isDeepEqual';
|
||||
import isEqual from 'lodash/isEqual';
|
||||
|
||||
import isFunction from '@proton/utils/isFunction';
|
||||
import isTruthy from '@proton/utils/isTruthy';
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +1,9 @@
|
|||
import isDeepEqual from 'lodash/isEqual';
|
||||
|
||||
import shallowEqual from '@proton/utils/shallowEqual';
|
||||
|
||||
import { isSameDay } from '../../date-fns-utc';
|
||||
import { toUTCDate } from '../../date/timezone';
|
||||
import isDeepEqual from '../../helpers/isDeepEqual';
|
||||
import { omit } from '../../helpers/object';
|
||||
import type {
|
||||
VcalDateOrDateTimeValue,
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import isDeepEqual from 'lodash/isEqual';
|
||||
import { addLocale as ttagAddLocale, useLocale as ttagUseLocale } from 'ttag';
|
||||
|
||||
import isDeepEqual from '@proton/shared/lib/helpers/isDeepEqual';
|
||||
import { pick } from '@proton/shared/lib/helpers/object';
|
||||
|
||||
import { DEFAULT_LOCALE } from '../constants';
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
import { useCallback, useEffect } from 'react';
|
||||
|
||||
import { createSelector } from '@reduxjs/toolkit';
|
||||
import isEqual from 'lodash/isEqual';
|
||||
|
||||
import usePrevious from '@proton/hooks/usePrevious';
|
||||
import { baseUseSelector } from '@proton/react-redux-store';
|
||||
import { createHooks } from '@proton/redux-utilities';
|
||||
import isEqual from '@proton/shared/lib/helpers/isDeepEqual';
|
||||
import { pick } from '@proton/shared/lib/helpers/object';
|
||||
|
||||
import { apiWalletTransactionDataThunk, selectApiWalletTransactionData } from '../slices';
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import isDeepEqual from 'lodash/isEqual';
|
||||
|
||||
import { CacheType } from '@proton/redux-utilities';
|
||||
import { MINUTE } from '@proton/shared/lib/constants';
|
||||
import isDeepEqual from '@proton/shared/lib/helpers/isDeepEqual';
|
||||
import { wait } from '@proton/shared/lib/helpers/promise';
|
||||
|
||||
import { selectExchangeRate } from '../slices';
|
||||
|
|
|
|||
|
|
@ -37931,6 +37931,7 @@ __metadata:
|
|||
"@testing-library/react": "npm:^15.0.7"
|
||||
"@testing-library/react-hooks": "npm:^8.0.1"
|
||||
"@testing-library/user-event": "npm:^14.6.1"
|
||||
"@types/lodash": "npm:^4.17.21"
|
||||
"@types/mime-types": "npm:^2.1.4"
|
||||
"@types/react": "npm:^18.3.27"
|
||||
"@types/react-dom": "npm:^18.3.7"
|
||||
|
|
@ -37955,6 +37956,7 @@ __metadata:
|
|||
jest: "npm:^30.2.0"
|
||||
jest-junit: "npm:^16.0.0"
|
||||
jest-when: "npm:3.7.0"
|
||||
lodash: "npm:^4.17.21"
|
||||
mime-types: "npm:^2.1.35"
|
||||
path-browserify: "npm:^1.0.1"
|
||||
prettier: "npm:^3.7.4"
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue