diff --git a/packages/pl-fe/src/features/aliases/index.tsx b/packages/pl-fe/src/features/aliases/index.tsx
index d786abfc6..98a95687c 100644
--- a/packages/pl-fe/src/features/aliases/index.tsx
+++ b/packages/pl-fe/src/features/aliases/index.tsx
@@ -59,7 +59,7 @@ const Aliases = () => {
{
- loaded && searchAccountIds.size === 0 ? (
+ loaded && searchAccountIds.length === 0 ? (
diff --git a/packages/pl-fe/src/features/auth-login/components/captcha.tsx b/packages/pl-fe/src/features/auth-login/components/captcha.tsx
index add7cb36a..56c465596 100644
--- a/packages/pl-fe/src/features/auth-login/components/captcha.tsx
+++ b/packages/pl-fe/src/features/auth-login/components/captcha.tsx
@@ -1,4 +1,3 @@
-import { Map as ImmutableMap } from 'immutable';
import React, { useState, useEffect } from 'react';
import { useIntl, defineMessages, FormattedMessage } from 'react-intl';
@@ -19,7 +18,7 @@ interface ICaptchaField {
name?: string;
value: string;
onChange?: React.ChangeEventHandler;
- onFetch?: (captcha: ImmutableMap) => void;
+ onFetch?: (captcha: Record) => void;
onFetchFail?: (error: Error) => void;
onClick?: React.MouseEventHandler;
refreshInterval?: number;
@@ -38,12 +37,11 @@ const CaptchaField: React.FC = ({
}) => {
const dispatch = useAppDispatch();
- const [captcha, setCaptcha] = useState(ImmutableMap());
+ const [captcha, setCaptcha] = useState>({});
const [refresh, setRefresh] = useState(undefined);
const getCaptcha = () => {
- dispatch(fetchCaptcha()).then((response) => {
- const captcha = ImmutableMap(response);
+ dispatch(fetchCaptcha()).then((captcha) => {
setCaptcha(captcha);
onFetch(captcha);
}).catch((error: Error) => {
@@ -98,7 +96,7 @@ const CaptchaField: React.FC = ({
};
interface INativeCaptchaField {
- captcha: ImmutableMap;
+ captcha: Record;
onChange: React.ChangeEventHandler;
onClick: React.MouseEventHandler;
name?: string;
@@ -111,7 +109,7 @@ const NativeCaptchaField: React.FC = ({ captcha, onChange,
return (
-
+
= ({ inviteToken }) => {
refreshCaptcha();
};
- const onFetchCaptcha = (captcha: ImmutableMap) => {
+ const onFetchCaptcha = (captcha: Record) => {
setCaptchaLoading(false);
setParams(params => ({
...params,
- captcha_token: captcha.get('token'),
- captcha_answer_data: captcha.get('answer_data'),
+ captcha_token: captcha.token,
+ captcha_answer_data: captcha.answer_data,
}));
};
diff --git a/packages/pl-fe/src/features/crypto-donate/utils/manifest-map.ts b/packages/pl-fe/src/features/crypto-donate/utils/manifest-map.ts
index 239e373f2..ff767d412 100644
--- a/packages/pl-fe/src/features/crypto-donate/utils/manifest-map.ts
+++ b/packages/pl-fe/src/features/crypto-donate/utils/manifest-map.ts
@@ -2,12 +2,10 @@
// See: https://github.com/spothq/cryptocurrency-icons/blob/master/manifest.json
import manifest from 'cryptocurrency-icons/manifest.json';
-import { List as ImmutableList, Map as ImmutableMap, fromJS } from 'immutable';
-const manifestMap = (fromJS(manifest) as ImmutableList>).reduce(
- (acc: ImmutableMap>, entry: ImmutableMap) =>
- acc.set(entry.get('symbol')!.toLowerCase(), entry),
- ImmutableMap(),
-).toJS();
+const manifestMap = manifest.reduce((acc: Record, entry) => {
+ acc[entry.symbol.toLowerCase()] = entry;
+ return acc;
+}, {});
export { manifestMap as default };
diff --git a/packages/pl-fe/src/features/federation-restrictions/index.tsx b/packages/pl-fe/src/features/federation-restrictions/index.tsx
index 4fa825e32..45d72076b 100644
--- a/packages/pl-fe/src/features/federation-restrictions/index.tsx
+++ b/packages/pl-fe/src/features/federation-restrictions/index.tsx
@@ -11,8 +11,6 @@ import { federationRestrictionsDisclosed } from 'pl-fe/utils/state';
import RestrictedInstance from './components/restricted-instance';
-import type { OrderedSet as ImmutableOrderedSet } from 'immutable';
-
const messages = defineMessages({
heading: { id: 'column.federation_restrictions', defaultMessage: 'Federation Restrictions' },
boxTitle: { id: 'federation_restrictions.explanation_box.title', defaultMessage: 'Instance-specific policies' },
@@ -27,7 +25,7 @@ const FederationRestrictions = () => {
const getHosts = useCallback(makeGetHosts(), []);
- const hosts = useAppSelector((state) => getHosts(state)) as ImmutableOrderedSet;
+ const hosts = useAppSelector((state) => getHosts(state));
const disclosed = useAppSelector((state) => federationRestrictionsDisclosed(state));
const [explanationBoxExpanded, setExplanationBoxExpanded] = useState(true);
diff --git a/packages/pl-fe/src/features/notifications/index.tsx b/packages/pl-fe/src/features/notifications/index.tsx
index 4b682d0b8..dcb5ef7fa 100644
--- a/packages/pl-fe/src/features/notifications/index.tsx
+++ b/packages/pl-fe/src/features/notifications/index.tsx
@@ -1,5 +1,4 @@
import clsx from 'clsx';
-import { List as ImmutableList } from 'immutable';
import debounce from 'lodash/debounce';
import React, { useCallback, useEffect, useRef } from 'react';
import { defineMessages, FormattedMessage, useIntl } from 'react-intl';
@@ -31,8 +30,8 @@ const messages = defineMessages({
});
const getNotifications = createSelector([
- (state: RootState) => state.notifications.items.toList(),
-], (notifications) => notifications.filter(item => item !== null));
+ (state: RootState) => state.notifications.items.toArray(),
+], (notifications) => notifications.map(([_, notification]) => notification).filter(item => item !== null));
const Notifications = () => {
const dispatch = useAppDispatch();
@@ -47,7 +46,7 @@ const Notifications = () => {
const hasMore = useAppSelector(state => state.notifications.hasMore);
const totalQueuedNotificationsCount = useAppSelector(state => state.notifications.totalQueuedNotificationsCount || 0);
- const scrollableContentRef = useRef | null>(null);
+ const scrollableContentRef = useRef | null>(null);
// const handleLoadGap = (maxId) => {
// dispatch(expandNotifications({ maxId }));
@@ -105,7 +104,7 @@ const Notifications = () => {
?
: ;
- let scrollableContent: ImmutableList | null = null;
+ let scrollableContent: Array | null = null;
const filterBarContainer = showFilterBar
? ()
@@ -113,7 +112,7 @@ const Notifications = () => {
if (isLoading && scrollableContentRef.current) {
scrollableContent = scrollableContentRef.current;
- } else if (notifications.size > 0 || hasMore) {
+ } else if (notifications.length > 0 || hasMore) {
scrollableContent = notifications.map((item) => (
{
const scrollContainer = (
{
onLoadMore={handleLoadOlder}
onScroll={handleScroll}
listClassName={clsx('divide-y divide-solid divide-gray-200 black:divide-gray-800 dark:divide-primary-800', {
- 'animate-pulse': notifications.size === 0,
+ 'animate-pulse': notifications.length === 0,
})}
>
{scrollableContent!}
diff --git a/packages/pl-fe/src/features/placeholder/components/placeholder-media-gallery.tsx b/packages/pl-fe/src/features/placeholder/components/placeholder-media-gallery.tsx
index b221b3697..e720ce80c 100644
--- a/packages/pl-fe/src/features/placeholder/components/placeholder-media-gallery.tsx
+++ b/packages/pl-fe/src/features/placeholder/components/placeholder-media-gallery.tsx
@@ -1,4 +1,3 @@
-import { Record as ImmutableRecord } from 'immutable';
import { MediaAttachment } from 'pl-api';
import React, { useState } from 'react';
@@ -7,12 +6,12 @@ interface IPlaceholderMediaGallery {
defaultWidth?: number;
}
-const SizeData = ImmutableRecord({
- style: {} as React.CSSProperties,
- itemsDimensions: [] as Record[],
- size: 1 as number,
- width: 0 as number,
-});
+interface SizeData {
+ style: React.CSSProperties;
+ itemsDimensions: Record[];
+ size: number;
+ width: number;
+}
const PlaceholderMediaGallery: React.FC = ({ media, defaultWidth }) => {
const [width, setWidth] = useState(defaultWidth);
@@ -23,7 +22,7 @@ const PlaceholderMediaGallery: React.FC = ({ media, de
}
};
- const getSizeData = (size: number) => {
+ const getSizeData = (size: number): SizeData => {
const style: React.CSSProperties = {};
let itemsDimensions: Record[] = [];
@@ -59,12 +58,12 @@ const PlaceholderMediaGallery: React.FC = ({ media, de
];
}
- return SizeData({
+ return {
style,
itemsDimensions,
size,
- width,
- });
+ width: width || 0,
+ };
};
const renderItem = (dimensions: Record, i: number) => {
diff --git a/packages/pl-fe/src/features/preferences/index.tsx b/packages/pl-fe/src/features/preferences/index.tsx
index 1d63cff63..7fdb36aaa 100644
--- a/packages/pl-fe/src/features/preferences/index.tsx
+++ b/packages/pl-fe/src/features/preferences/index.tsx
@@ -1,4 +1,3 @@
-import { Set as ImmutableSet } from 'immutable';
import React from 'react';
import { defineMessages, FormattedMessage, useIntl } from 'react-intl';
@@ -106,7 +105,7 @@ const Preferences = () => {
};
const onSelectMultiple = (selectedList: string[], path: string[]) => {
- dispatch(changeSetting(path, ImmutableSet(selectedList.sort((a, b) => a.localeCompare(b))), { showAlert: true }));
+ dispatch(changeSetting(path, selectedList.toSorted((a, b) => a.localeCompare(b)), { showAlert: true }));
};
const onToggleChange = (key: string[], checked: boolean) => {
diff --git a/packages/pl-fe/src/features/ui/components/modals/list-editor-modal/index.tsx b/packages/pl-fe/src/features/ui/components/modals/list-editor-modal/index.tsx
index 1e79a4a4b..15bac48cf 100644
--- a/packages/pl-fe/src/features/ui/components/modals/list-editor-modal/index.tsx
+++ b/packages/pl-fe/src/features/ui/components/modals/list-editor-modal/index.tsx
@@ -54,7 +54,7 @@ const ListEditorModal: React.FC = ({ list
- {accountIds.size > 0 && (
+ {accountIds.length > 0 && (
diff --git a/packages/pl-fe/src/reducers/aliases.ts b/packages/pl-fe/src/reducers/aliases.ts
index 1b2051320..b1395aaa9 100644
--- a/packages/pl-fe/src/reducers/aliases.ts
+++ b/packages/pl-fe/src/reducers/aliases.ts
@@ -1,4 +1,4 @@
-import { List as ImmutableList, Record as ImmutableRecord } from 'immutable';
+import { create } from 'mutative';
import {
ALIASES_SUGGESTIONS_READY,
@@ -8,37 +8,52 @@ import {
AliasesAction,
} from '../actions/aliases';
-const ReducerRecord = ImmutableRecord({
- aliases: ImmutableRecord({
- items: ImmutableList(),
+interface State {
+ aliases: {
+ items: Array;
+ loaded: boolean;
+ };
+ suggestions: {
+ items: Array;
+ value: string;
+ loaded: boolean;
+ };
+}
+
+const initialState: State = {
+ aliases: {
+ items: [],
loaded: false,
- })(),
- suggestions: ImmutableRecord({
- items: ImmutableList(),
+ },
+ suggestions: {
+ items: [],
value: '',
loaded: false,
- })(),
-});
+ },
+};
-const aliasesReducer = (state = ReducerRecord(), action: AliasesAction) => {
+const aliasesReducer = (state = initialState, action: AliasesAction): State => {
switch (action.type) {
case ALIASES_FETCH_SUCCESS:
- return state
- .setIn(['aliases', 'items'], action.value);
+ return create(state, (draft) => {
+ draft.aliases.items = action.value;
+ });
case ALIASES_SUGGESTIONS_CHANGE:
- return state
- .setIn(['suggestions', 'value'], action.value)
- .setIn(['suggestions', 'loaded'], false);
+ return create(state, (draft) => {
+ draft.suggestions.value = action.value;
+ draft.suggestions.loaded = false;
+ });
case ALIASES_SUGGESTIONS_READY:
- return state
- .setIn(['suggestions', 'items'], ImmutableList(action.accounts.map((item) => item.id)))
- .setIn(['suggestions', 'loaded'], true);
+ return create(state, (draft) => {
+ draft.suggestions.items = action.accounts.map((item) => item.id);
+ draft.suggestions.loaded = true;
+ });
case ALIASES_SUGGESTIONS_CLEAR:
- return state.update('suggestions', suggestions => suggestions.withMutations(map => {
- map.set('items', ImmutableList());
- map.set('value', '');
- map.set('loaded', false);
- }));
+ return create(state, (draft) => {
+ draft.suggestions.items = [];
+ draft.suggestions.value = '';
+ draft.suggestions.loaded = false;
+ });
default:
return state;
}
diff --git a/packages/pl-fe/src/reducers/list-adder.ts b/packages/pl-fe/src/reducers/list-adder.ts
index 7716f4db0..e69b87baf 100644
--- a/packages/pl-fe/src/reducers/list-adder.ts
+++ b/packages/pl-fe/src/reducers/list-adder.ts
@@ -1,4 +1,4 @@
-import { List as ImmutableList, Record as ImmutableRecord } from 'immutable';
+import { create } from 'mutative';
import {
LIST_ADDER_RESET,
@@ -12,42 +12,54 @@ import {
import type { AnyAction } from 'redux';
-const ListsRecord = ImmutableRecord({
- items: ImmutableList(),
- loaded: false,
- isLoading: false,
-});
+interface State {
+ accountId: string | null;
+ lists: {
+ items: Array;
+ loaded: boolean;
+ isLoading: boolean;
+ };
+}
-const ReducerRecord = ImmutableRecord({
- accountId: null as string | null,
+const initialState: State = {
+ accountId: null,
+ lists: {
+ items: [],
+ loaded: false,
+ isLoading: false,
+ },
+};
- lists: ListsRecord(),
-});
-
-type State = ReturnType;
-
-const listAdderReducer = (state: State = ReducerRecord(), action: AnyAction) => {
+const listAdderReducer = (state: State = initialState, action: AnyAction): State => {
switch (action.type) {
case LIST_ADDER_RESET:
- return ReducerRecord();
+ return initialState;
case LIST_ADDER_SETUP:
- return state.withMutations(map => {
- map.set('accountId', action.account.id);
+ return create(state, (draft) => {
+ draft.accountId = action.account.id;
});
case LIST_ADDER_LISTS_FETCH_REQUEST:
- return state.setIn(['lists', 'isLoading'], true);
+ return create(state, (draft) => {
+ draft.lists.isLoading = true;
+ });
case LIST_ADDER_LISTS_FETCH_FAIL:
- return state.setIn(['lists', 'isLoading'], false);
+ return create(state, (draft) => {
+ draft.lists.isLoading = false;
+ });
case LIST_ADDER_LISTS_FETCH_SUCCESS:
- return state.update('lists', lists => lists.withMutations(map => {
- map.set('isLoading', false);
- map.set('loaded', true);
- map.set('items', ImmutableList(action.lists.map((item: { id: string }) => item.id)));
- }));
+ return create(state, (draft) => {
+ draft.lists.isLoading = false;
+ draft.lists.loaded = true;
+ draft.lists.items = action.lists.map((item: { id: string }) => item.id);
+ });
case LIST_EDITOR_ADD_SUCCESS:
- return state.updateIn(['lists', 'items'], list => (list as ImmutableList).unshift(action.listId));
+ return create(state, (draft) => {
+ draft.lists.items = [action.listId, ...draft.lists.items];
+ });
case LIST_EDITOR_REMOVE_SUCCESS:
- return state.updateIn(['lists', 'items'], list => (list as ImmutableList).filterNot(item => item === action.listId));
+ return create(state, (draft) => {
+ draft.lists.items = draft.lists.items.filter(id => id !== action.listId);
+ });
default:
return state;
}
diff --git a/packages/pl-fe/src/reducers/list-editor.ts b/packages/pl-fe/src/reducers/list-editor.ts
index a8f1ac6de..8a9a21997 100644
--- a/packages/pl-fe/src/reducers/list-editor.ts
+++ b/packages/pl-fe/src/reducers/list-editor.ts
@@ -1,4 +1,4 @@
-import { List as ImmutableList, Record as ImmutableRecord } from 'immutable';
+import { create } from 'mutative';
import {
LIST_CREATE_REQUEST,
@@ -22,83 +22,109 @@ import {
import type { AnyAction } from 'redux';
-const AccountsRecord = ImmutableRecord({
- items: ImmutableList(),
- loaded: false,
- isLoading: false,
-});
+interface State {
+ listId: string | null;
+ isSubmitting: boolean;
+ isChanged: boolean;
+ title: string;
-const SuggestionsRecord = ImmutableRecord({
- value: '',
- items: ImmutableList(),
-});
+ accounts: {
+ items: Array;
+ loaded: boolean;
+ isLoading: boolean;
+ };
-const ReducerRecord = ImmutableRecord({
- listId: null as string | null,
+ suggestions: {
+ value: string;
+ items: Array;
+ };
+}
+
+const initialState: State = {
+ listId: null,
isSubmitting: false,
isChanged: false,
title: '',
- accounts: AccountsRecord(),
+ accounts: {
+ items: [],
+ loaded: false,
+ isLoading: false,
+ },
- suggestions: SuggestionsRecord(),
-});
+ suggestions: {
+ value: '',
+ items: [],
+ },
+};
-type State = ReturnType;
-
-const listEditorReducer = (state: State = ReducerRecord(), action: AnyAction) => {
+const listEditorReducer = (state: State = initialState, action: AnyAction): State => {
switch (action.type) {
case LIST_EDITOR_RESET:
- return ReducerRecord();
+ return initialState;
case LIST_EDITOR_SETUP:
- return state.withMutations(map => {
- map.set('listId', action.list.id);
- map.set('title', action.list.title);
- map.set('isSubmitting', false);
+ return create(state, (draft) => {
+ draft.listId = action.list.id;
+ draft.title = action.list.title;
+ draft.isSubmitting = false;
});
case LIST_EDITOR_TITLE_CHANGE:
- return state.withMutations(map => {
- map.set('title', action.value);
- map.set('isChanged', true);
+ return create(state, (draft) => {
+ draft.title = action.value;
+ draft.isChanged = true;
});
case LIST_CREATE_REQUEST:
case LIST_UPDATE_REQUEST:
- return state.withMutations(map => {
- map.set('isSubmitting', true);
- map.set('isChanged', false);
+ return create(state, (draft) => {
+ draft.isSubmitting = true;
+ draft.isChanged = false;
});
case LIST_CREATE_FAIL:
case LIST_UPDATE_FAIL:
- return state.set('isSubmitting', false);
+ return create(state, (draft) => {
+ draft.isSubmitting = false;
+ });
case LIST_CREATE_SUCCESS:
case LIST_UPDATE_SUCCESS:
- return state.withMutations(map => {
- map.set('isSubmitting', false);
- map.set('listId', action.list.id);
+ return create(state, (draft) => {
+ draft.isSubmitting = false;
+ draft.listId = action.list.id;
});
case LIST_ACCOUNTS_FETCH_REQUEST:
- return state.setIn(['accounts', 'isLoading'], true);
+ return create(state, (draft) => {
+ draft.accounts.isLoading = true;
+ });
case LIST_ACCOUNTS_FETCH_FAIL:
- return state.setIn(['accounts', 'isLoading'], false);
+ return create(state, (draft) => {
+ draft.accounts.isLoading = false;
+ });
case LIST_ACCOUNTS_FETCH_SUCCESS:
- return state.update('accounts', accounts => accounts.withMutations(map => {
- map.set('isLoading', false);
- map.set('loaded', true);
- map.set('items', ImmutableList(action.accounts.map((item: { id: string }) => item.id)));
- }));
+ return create(state, (draft) => {
+ draft.accounts.isLoading = false;
+ draft.accounts.loaded = true;
+ draft.accounts.items = action.accounts.map((item: { id: string }) => item.id);
+ });
case LIST_EDITOR_SUGGESTIONS_CHANGE:
- return state.setIn(['suggestions', 'value'], action.value);
+ return create(state, (draft) => {
+ draft.suggestions.value = action.value;
+ });
case LIST_EDITOR_SUGGESTIONS_READY:
- return state.setIn(['suggestions', 'items'], ImmutableList(action.accounts.map((item: { id: string }) => item.id)));
+ return create(state, (draft) => {
+ draft.suggestions.items = action.accounts.map((item: { id: string }) => item.id);
+ });
case LIST_EDITOR_SUGGESTIONS_CLEAR:
- return state.update('suggestions', suggestions => suggestions.withMutations(map => {
- map.set('items', ImmutableList());
- map.set('value', '');
- }));
+ return create(state, (draft) => {
+ draft.suggestions.items = [];
+ draft.suggestions.value = '';
+ });
case LIST_EDITOR_ADD_SUCCESS:
- return state.updateIn(['accounts', 'items'], list => (list as ImmutableList).unshift(action.accountId));
+ return create(state, (draft) => {
+ draft.accounts.items = [action.accountId, ...draft.accounts.items];
+ });
case LIST_EDITOR_REMOVE_SUCCESS:
- return state.updateIn(['accounts', 'items'], list => (list as ImmutableList).filterNot((item) => item === action.accountId));
+ return create(state, (draft) => {
+ draft.accounts.items = draft.accounts.items.filter(id => id !== action.accoundId);
+ });
default:
return state;
}
diff --git a/packages/pl-fe/src/selectors/index.ts b/packages/pl-fe/src/selectors/index.ts
index 40f3d5da5..67ce403e8 100644
--- a/packages/pl-fe/src/selectors/index.ts
+++ b/packages/pl-fe/src/selectors/index.ts
@@ -1,4 +1,3 @@
-import { OrderedSet as ImmutableOrderedSet } from 'immutable';
import { createSelector } from 'reselect';
// import { getLocale } from 'pl-fe/actions/settings';
@@ -262,14 +261,11 @@ const makeGetReport = () => {
const getAuthUserIds = createSelector(
[(state: RootState) => state.auth.users],
- authUsers => authUsers.reduce((userIds: ImmutableOrderedSet, authUser) => {
- try {
- const userId = authUser.id;
- return validId(userId) ? userIds.add(userId) : userIds;
- } catch {
- return userIds;
- }
- }, ImmutableOrderedSet()));
+ authUsers => authUsers.reduce((userIds: Array, authUser) => {
+ const userId = authUser?.id;
+ if (validId(userId)) userIds.push(userId);
+ return userIds;
+ }, []));
const makeGetOtherAccounts = () => createSelector([
(state: RootState) => state.entities[Entities.ACCOUNTS]?.store as EntityStore,
@@ -314,9 +310,7 @@ const makeGetHosts = () =>
createSelector([getSimplePolicy], (simplePolicy) => {
const { accept, reject_deletes, report_removal, ...rest } = simplePolicy;
- return Object.values(rest)
- .reduce((acc, hosts) => acc.union(hosts), ImmutableOrderedSet())
- .sort();
+ return [...new Set(Object.values(rest).reduce((acc, hosts) => (acc.push(...hosts), acc), []))].toSorted();
});
interface RemoteInstance {
diff --git a/packages/pl-fe/src/utils/auth.ts b/packages/pl-fe/src/utils/auth.ts
index d2de057b2..d5b3d68f0 100644
--- a/packages/pl-fe/src/utils/auth.ts
+++ b/packages/pl-fe/src/utils/auth.ts
@@ -1,5 +1,3 @@
-import { List as ImmutableList } from 'immutable';
-
import { selectAccount, selectOwnAccount } from 'pl-fe/selectors';
import type { RootState } from 'pl-fe/store';
@@ -43,19 +41,19 @@ const getAccessToken = (state: RootState) => {
const getAuthUserId = (state: RootState) => {
const me = state.auth.me;
- return ImmutableList([
+ return [
state.auth.users.get(me!)?.id,
me,
- ].filter(id => id)).find(validId);
+ ].filter(id => id).find(validId);
};
const getAuthUserUrl = (state: RootState) => {
const me = state.auth.me;
- return ImmutableList([
+ return [
state.auth.users.get(me!)?.url,
me,
- ].filter(url => url)).find(isURL);
+ ].filter(url => url).find(isURL);
};
/** Get the VAPID public key. */
diff --git a/packages/pl-fe/src/utils/badges.ts b/packages/pl-fe/src/utils/badges.ts
index 5b512ed0b..f1bcd8312 100644
--- a/packages/pl-fe/src/utils/badges.ts
+++ b/packages/pl-fe/src/utils/badges.ts
@@ -1,5 +1,3 @@
-import { OrderedSet as ImmutableOrderedSet } from 'immutable';
-
import type { Account } from 'pl-fe/normalizers/account';
/** Convert a plain tag into a badge. */
@@ -17,15 +15,10 @@ interface TagDiff {
}
/** Returns the differences between two sets of tags. */
-const getTagDiff = (oldTags: string[], newTags: string[]): TagDiff => {
- const o = ImmutableOrderedSet(oldTags);
- const n = ImmutableOrderedSet(newTags);
-
- return {
- added: n.subtract(o).toArray(),
- removed: o.subtract(n).toArray(),
- };
-};
+const getTagDiff = (oldTags: string[], newTags: string[]): TagDiff => ({
+ added: newTags.filter(tag => !oldTags.includes(tag)),
+ removed: oldTags.filter(tag => !newTags.includes(tag)),
+});
/** Returns only tags which are badges. */
const filterBadges = (tags: string[]): string[] => tags.filter(tag => tag.startsWith('badge:'));