diff --git a/app/soapbox/actions/__tests__/blocks.test.ts b/app/soapbox/actions/__tests__/blocks.test.ts index eedf17c30c..2d48320071 100644 --- a/app/soapbox/actions/__tests__/blocks.test.ts +++ b/app/soapbox/actions/__tests__/blocks.test.ts @@ -1,4 +1,4 @@ -import { Map as ImmutableMap } from 'immutable'; +import { Record as ImmutableRecord } from 'immutable'; import { __stub } from 'soapbox/api'; import { mockStore } from 'soapbox/jest/test-helpers'; @@ -113,7 +113,7 @@ describe('expandBlocks()', () => { beforeEach(() => { const state = rootReducer(undefined, {}) .set('me', '1234') - .set('user_lists', ImmutableMap({ blocks: { next: null } })); + .set('user_lists', ImmutableRecord({ blocks: { next: null } })()); store = mockStore(state); }); @@ -129,7 +129,7 @@ describe('expandBlocks()', () => { beforeEach(() => { const state = rootReducer(undefined, {}) .set('me', '1234') - .set('user_lists', ImmutableMap({ blocks: { next: 'example' } })); + .set('user_lists', ImmutableRecord({ blocks: { next: 'example' } })()); store = mockStore(state); }); diff --git a/app/soapbox/actions/accounts.ts b/app/soapbox/actions/accounts.ts index e5a92fae95..60cb6bbe62 100644 --- a/app/soapbox/actions/accounts.ts +++ b/app/soapbox/actions/accounts.ts @@ -410,7 +410,6 @@ const unmuteAccountFail = (error: AxiosError) => ({ error, }); - const subscribeAccount = (id: string, notifications?: boolean) => (dispatch: AppDispatch, getState: () => RootState) => { if (!isLoggedIn(getState)) return null; @@ -465,7 +464,6 @@ const unsubscribeAccountFail = (error: AxiosError) => ({ error, }); - const removeFromFollowers = (id: string) => (dispatch: AppDispatch, getState: () => RootState) => { if (!isLoggedIn(getState)) return; @@ -532,7 +530,7 @@ const expandFollowers = (id: string) => (dispatch: AppDispatch, getState: () => RootState) => { if (!isLoggedIn(getState)) return; - const url = getState().user_lists.getIn(['followers', id, 'next']); + const url = getState().user_lists.followers.get(id)?.next as string; if (url === null) { return; @@ -606,7 +604,7 @@ const expandFollowing = (id: string) => (dispatch: AppDispatch, getState: () => RootState) => { if (!isLoggedIn(getState)) return; - const url = getState().user_lists.getIn(['following', id, 'next']); + const url = getState().user_lists.following.get(id)!.next; if (url === null) { return; @@ -713,7 +711,7 @@ const expandFollowRequests = () => (dispatch: AppDispatch, getState: () => RootState) => { if (!isLoggedIn(getState)) return; - const url = getState().user_lists.getIn(['follow_requests', 'next']); + const url = getState().user_lists.follow_requests.next; if (url === null) { return; @@ -771,7 +769,6 @@ const authorizeFollowRequestFail = (id: string, error: AxiosError) => ({ error, }); - const rejectFollowRequest = (id: string) => (dispatch: AppDispatch, getState: () => RootState) => { if (!isLoggedIn(getState)) return; diff --git a/app/soapbox/actions/auth.ts b/app/soapbox/actions/auth.ts index 54473346ca..40532a5824 100644 --- a/app/soapbox/actions/auth.ts +++ b/app/soapbox/actions/auth.ts @@ -269,7 +269,6 @@ export const fetchOwnAccounts = () => }); }; - export const register = (params: Record) => (dispatch: AppDispatch) => { params.fullname = params.username; diff --git a/app/soapbox/actions/blocks.ts b/app/soapbox/actions/blocks.ts index 629be6f903..d3f6258843 100644 --- a/app/soapbox/actions/blocks.ts +++ b/app/soapbox/actions/blocks.ts @@ -58,7 +58,7 @@ const expandBlocks = () => (dispatch: React.Dispatch, getState: () => if (!isLoggedIn(getState)) return null; const nextLinkName = getNextLinkName(getState); - const url = getState().user_lists.getIn(['blocks', 'next']); + const url = getState().user_lists.blocks.next; if (url === null) { return null; diff --git a/app/soapbox/actions/compose.ts b/app/soapbox/actions/compose.ts index 721e6bad1d..d37330d289 100644 --- a/app/soapbox/actions/compose.ts +++ b/app/soapbox/actions/compose.ts @@ -285,7 +285,7 @@ const submitCompose = (routerHistory: History, force = false) => }; dispatch(createStatus(params, idempotencyKey, statusId)).then(function(data) { - if (!statusId && data.visibility === 'direct' && getState().conversations.get('mounted') <= 0 && routerHistory) { + if (!statusId && data.visibility === 'direct' && getState().conversations.mounted <= 0 && routerHistory) { routerHistory.push('/messages'); } handleComposeSubmit(dispatch, getState, data, status); diff --git a/app/soapbox/actions/conversations.ts b/app/soapbox/actions/conversations.ts index a56e02d6f1..73507e3892 100644 --- a/app/soapbox/actions/conversations.ts +++ b/app/soapbox/actions/conversations.ts @@ -49,7 +49,7 @@ const expandConversations = ({ maxId }: Record = {}) => (dispatch: const params: Record = { max_id: maxId }; if (!maxId) { - params.since_id = getState().conversations.getIn(['items', 0, 'id']); + params.since_id = getState().conversations.items.getIn([0, 'id']); } const isLoadingRecent = !!params.since_id; diff --git a/app/soapbox/actions/directory.ts b/app/soapbox/actions/directory.ts index 98e2dc2b21..37ddcfdfa4 100644 --- a/app/soapbox/actions/directory.ts +++ b/app/soapbox/actions/directory.ts @@ -44,7 +44,7 @@ const expandDirectory = (params: Record) => (dispatch: AppDispatch, getState: () => RootState) => { dispatch(expandDirectoryRequest()); - const loadedItems = getState().user_lists.getIn(['directory', 'items']).size; + const loadedItems = getState().user_lists.directory.items.size; api(getState).get('/api/v1/directory', { params: { ...params, offset: loadedItems, limit: 20 } }).then(({ data }) => { dispatch(importFetchedAccounts(data)); diff --git a/app/soapbox/actions/filters.ts b/app/soapbox/actions/filters.ts index 16bb23951b..61b4e9b631 100644 --- a/app/soapbox/actions/filters.ts +++ b/app/soapbox/actions/filters.ts @@ -65,7 +65,6 @@ const createFilter = (phrase: string, expires_at: string, context: Array }); }; - const deleteFilter = (id: string) => (dispatch: AppDispatch, getState: () => RootState) => { dispatch({ type: FILTERS_DELETE_REQUEST }); diff --git a/app/soapbox/actions/groups.ts b/app/soapbox/actions/groups.ts index a6443758a0..808cc3204e 100644 --- a/app/soapbox/actions/groups.ts +++ b/app/soapbox/actions/groups.ts @@ -253,7 +253,7 @@ const expandMembers = (id: string) => (dispatch: AppDispatch, getState: () => RootState) => { if (!isLoggedIn(getState)) return; - const url = getState().user_lists.getIn(['groups', id, 'next']); + const url = getState().user_lists.groups.get(id)!.next; if (url === null) { return; @@ -329,7 +329,7 @@ const expandRemovedAccounts = (id: string) => (dispatch: AppDispatch, getState: () => RootState) => { if (!isLoggedIn(getState)) return; - const url = getState().user_lists.getIn(['groups_removed_accounts', id, 'next']); + const url = getState().user_lists.groups_removed_accounts.get(id)!.next; if (url === null) { return; diff --git a/app/soapbox/actions/media.ts b/app/soapbox/actions/media.ts index 1a63d87d56..15c637c350 100644 --- a/app/soapbox/actions/media.ts +++ b/app/soapbox/actions/media.ts @@ -22,14 +22,12 @@ const uploadMediaV1 = (data: FormData, onUploadProgress = noOp) => onUploadProgress: onUploadProgress, }); - const uploadMediaV2 = (data: FormData, onUploadProgress = noOp) => (dispatch: any, getState: () => RootState) => api(getState).post('/api/v2/media', data, { onUploadProgress: onUploadProgress, }); - const uploadMedia = (data: FormData, onUploadProgress = noOp) => (dispatch: AppDispatch, getState: () => RootState) => { const state = getState(); diff --git a/app/soapbox/actions/moderation.tsx b/app/soapbox/actions/moderation.tsx index 946157071e..69342277b1 100644 --- a/app/soapbox/actions/moderation.tsx +++ b/app/soapbox/actions/moderation.tsx @@ -162,7 +162,6 @@ const deleteStatusModal = (intl: IntlShape, statusId: string, afterConfirm = () })); }; - export { deactivateUserModal, deleteUserModal, diff --git a/app/soapbox/actions/mutes.ts b/app/soapbox/actions/mutes.ts index 0ec7d147b8..050a513f03 100644 --- a/app/soapbox/actions/mutes.ts +++ b/app/soapbox/actions/mutes.ts @@ -57,7 +57,7 @@ const expandMutes = () => if (!isLoggedIn(getState)) return; const nextLinkName = getNextLinkName(getState); - const url = getState().user_lists.getIn(['mutes', 'next']); + const url = getState().user_lists.mutes.next; if (url === null) { return; diff --git a/app/soapbox/actions/push_notifications/registerer.ts b/app/soapbox/actions/push_notifications/registerer.ts index b8d12caa4a..893814b025 100644 --- a/app/soapbox/actions/push_notifications/registerer.ts +++ b/app/soapbox/actions/push_notifications/registerer.ts @@ -38,7 +38,7 @@ const unsubscribe = ({ registration, subscription }: { const sendSubscriptionToBackend = (subscription: PushSubscription, me: Me) => (dispatch: AppDispatch, getState: () => RootState) => { - const alerts = getState().push_notifications.get('alerts').toJS(); + const alerts = getState().push_notifications.alerts.toJS(); const params = { subscription, data: { alerts } }; if (me) { @@ -82,7 +82,7 @@ const register = () => // We have a subscription, check if it is still valid const currentServerKey = (new Uint8Array(subscription.options.applicationServerKey!)).toString(); const subscriptionServerKey = urlBase64ToUint8Array(vapidKey).toString(); - const serverEndpoint = getState().push_notifications.getIn(['subscription', 'endpoint']); + const serverEndpoint = getState().push_notifications.subscription?.endpoint; // If the VAPID public key did not change and the endpoint corresponds // to the endpoint saved in the backend, the subscription is valid @@ -136,7 +136,7 @@ const register = () => const saveSettings = () => (dispatch: AppDispatch, getState: () => RootState) => { const state = getState().push_notifications; - const alerts = state.get('alerts'); + const alerts = state.alerts; const data = { alerts }; const me = getState().me; diff --git a/app/soapbox/actions/statuses.ts b/app/soapbox/actions/statuses.ts index f0a6aad150..5cf5344465 100644 --- a/app/soapbox/actions/statuses.ts +++ b/app/soapbox/actions/statuses.ts @@ -242,7 +242,6 @@ const fetchStatusWithContext = (id: string) => } }; - const muteStatus = (id: string) => (dispatch: AppDispatch, getState: () => RootState) => { if (!isLoggedIn(getState)) return; diff --git a/app/soapbox/actions/timelines.ts b/app/soapbox/actions/timelines.ts index ec8615def8..5d7fac2c43 100644 --- a/app/soapbox/actions/timelines.ts +++ b/app/soapbox/actions/timelines.ts @@ -82,7 +82,7 @@ const updateTimelineQueue = (timeline: string, statusId: string, accept: ((statu const dequeueTimeline = (timelineId: string, expandFunc?: (lastStatusId: string) => void, optionalExpandArgs?: any) => (dispatch: AppDispatch, getState: () => RootState) => { const state = getState(); - const queuedCount = state.timelines.getIn([timelineId, 'totalQueuedItemsCount'], 0); + const queuedCount = state.timelines.get(timelineId)?.totalQueuedItemsCount || 0; if (queuedCount <= 0) return; @@ -136,16 +136,16 @@ const parseTags = (tags: Record = {}, mode: 'any' | 'all' | 'none const expandTimeline = (timelineId: string, path: string, params: Record = {}, done = noOp) => (dispatch: AppDispatch, getState: () => RootState) => { - const timeline = getState().timelines.get(timelineId) || ImmutableMap(); + const timeline = getState().timelines.get(timelineId) || {} as Record; const isLoadingMore = !!params.max_id; - if (timeline.get('isLoading')) { + if (timeline.isLoading) { done(); return dispatch(noOpAsync()); } - if (!params.max_id && !params.pinned && timeline.get('items', ImmutableOrderedSet()).size > 0) { - params.since_id = timeline.getIn(['items', 0]); + if (!params.max_id && !params.pinned && (timeline.items || ImmutableOrderedSet()).size > 0) { + params.since_id = timeline.items || 0; } const isLoadingRecent = !!params.since_id; diff --git a/app/soapbox/actions/verification.ts b/app/soapbox/actions/verification.ts index bc8db0189d..ce3d270090 100644 --- a/app/soapbox/actions/verification.ts +++ b/app/soapbox/actions/verification.ts @@ -59,7 +59,6 @@ const removeStoredVerification = () => { localStorage.removeItem(LOCAL_STORAGE_VERIFICATION_KEY); }; - /** * Fetch and return the Registration token for Pepe. */ @@ -207,7 +206,6 @@ const fetchRegistrationToken = () => return null; } - return api(getState).post('/api/v1/pepe/registrations') .then(response => { updateStorage({ token: response.data.access_token }); diff --git a/app/soapbox/components/birthday-panel.tsx b/app/soapbox/components/birthday-panel.tsx index 6008cb423e..2cc1393571 100644 --- a/app/soapbox/components/birthday-panel.tsx +++ b/app/soapbox/components/birthday-panel.tsx @@ -15,7 +15,7 @@ interface IBirthdayPanel { const BirthdayPanel = ({ limit }: IBirthdayPanel) => { const dispatch = useDispatch(); - const birthdays: ImmutableOrderedSet = useAppSelector(state => state.user_lists.getIn(['birthday_reminders', state.me], ImmutableOrderedSet())); + const birthdays: ImmutableOrderedSet = useAppSelector(state => state.user_lists.birthday_reminders.get(state.me as string)?.items || ImmutableOrderedSet()); const birthdaysToRender = birthdays.slice(0, limit); React.useEffect(() => { diff --git a/app/soapbox/components/error_boundary.tsx b/app/soapbox/components/error_boundary.tsx index 6df25cb9dc..c1025d4653 100644 --- a/app/soapbox/components/error_boundary.tsx +++ b/app/soapbox/components/error_boundary.tsx @@ -171,7 +171,6 @@ class ErrorBoundary extends React.PureComponent { /> )} - {browser && ( diff --git a/app/soapbox/components/sidebar-navigation.tsx b/app/soapbox/components/sidebar-navigation.tsx index 5b8c792307..f4cf64e49f 100644 --- a/app/soapbox/components/sidebar-navigation.tsx +++ b/app/soapbox/components/sidebar-navigation.tsx @@ -1,4 +1,3 @@ -import { OrderedSet as ImmutableOrderedSet } from 'immutable'; import React from 'react'; import { FormattedMessage } from 'react-intl'; @@ -19,7 +18,7 @@ const SidebarNavigation = () => { const account = useOwnAccount(); const notificationCount = useAppSelector((state) => state.notifications.get('unread')); const chatsCount = useAppSelector((state) => state.chats.items.reduce((acc, curr) => acc + Math.min(curr.unread || 0, 1), 0)); - const followRequestsCount = useAppSelector((state) => state.user_lists.getIn(['follow_requests', 'items'], ImmutableOrderedSet()).count()); + const followRequestsCount = useAppSelector((state) => state.user_lists.follow_requests.items.count()); const dashboardCount = useAppSelector((state) => state.admin.openReports.count() + state.admin.awaitingApproval.count()); const features = getFeatures(instance); diff --git a/app/soapbox/components/ui/modal/modal.tsx b/app/soapbox/components/ui/modal/modal.tsx index 3b2ba89e97..3987d6afe9 100644 --- a/app/soapbox/components/ui/modal/modal.tsx +++ b/app/soapbox/components/ui/modal/modal.tsx @@ -50,7 +50,7 @@ interface IModal { /** Don't focus the "confirm" button on mount. */ skipFocus?: boolean, /** Title text for the modal. */ - title: React.ReactNode, + title?: React.ReactNode, width?: Widths, } @@ -86,28 +86,32 @@ const Modal: React.FC = ({
-
-

- {title} -

+ {title && ( +
+

+ {title} +

- {onClose && ( - - )} -
+ {onClose && ( + + )} +
+ )} -
- {children} -
+ {title ? ( +
+ {children} +
+ ) : children}
@@ -124,7 +128,6 @@ const Modal: React.FC = ({ )}
-
{secondaryAction && (
- {accountIds.map((accountId: string) => )} + {accountIds.map((accountId) => )}
diff --git a/app/soapbox/features/follow_requests/index.tsx b/app/soapbox/features/follow_requests/index.tsx index 3c1d647eda..eed1a8e1f9 100644 --- a/app/soapbox/features/follow_requests/index.tsx +++ b/app/soapbox/features/follow_requests/index.tsx @@ -24,8 +24,8 @@ const FollowRequests: React.FC = () => { const dispatch = useDispatch(); const intl = useIntl(); - const accountIds = useAppSelector((state) => state.user_lists.getIn(['follow_requests', 'items'])); - const hasMore = useAppSelector((state) => !!state.user_lists.getIn(['follow_requests', 'next'])); + const accountIds = useAppSelector((state) => state.user_lists.follow_requests.items); + const hasMore = useAppSelector((state) => !!state.user_lists.follow_requests.next); React.useEffect(() => { dispatch(fetchFollowRequests()); diff --git a/app/soapbox/features/followers/index.js b/app/soapbox/features/followers/index.js index e728ebddfa..7a77e46a57 100644 Binary files a/app/soapbox/features/followers/index.js and b/app/soapbox/features/followers/index.js differ diff --git a/app/soapbox/features/following/index.js b/app/soapbox/features/following/index.js index 532a7d2c54..2f654fc5b1 100644 Binary files a/app/soapbox/features/following/index.js and b/app/soapbox/features/following/index.js differ diff --git a/app/soapbox/features/groups/members/index.js b/app/soapbox/features/groups/members/index.js index a7b56aeb17..1e9e39a4de 100644 Binary files a/app/soapbox/features/groups/members/index.js and b/app/soapbox/features/groups/members/index.js differ diff --git a/app/soapbox/features/groups/removed_accounts/index.js b/app/soapbox/features/groups/removed_accounts/index.js index cc7e1111de..e5d0dae411 100644 Binary files a/app/soapbox/features/groups/removed_accounts/index.js and b/app/soapbox/features/groups/removed_accounts/index.js differ diff --git a/app/soapbox/features/home_timeline/index.tsx b/app/soapbox/features/home_timeline/index.tsx index 99ed0d5696..ad3ee672d9 100644 --- a/app/soapbox/features/home_timeline/index.tsx +++ b/app/soapbox/features/home_timeline/index.tsx @@ -16,7 +16,7 @@ const HomeTimeline: React.FC = () => { const dispatch = useAppDispatch(); const polling = useRef(null); - const isPartial = useAppSelector(state => state.timelines.getIn(['home', 'isPartial']) === true); + const isPartial = useAppSelector(state => state.timelines.get('home')?.isPartial === true); const siteTitle = useAppSelector(state => state.instance.title); const handleLoadMore = (maxId: string) => { diff --git a/app/soapbox/features/list_timeline/index.tsx b/app/soapbox/features/list_timeline/index.tsx index 42b8d6fe49..f9d1e6f245 100644 --- a/app/soapbox/features/list_timeline/index.tsx +++ b/app/soapbox/features/list_timeline/index.tsx @@ -26,7 +26,7 @@ const ListTimeline: React.FC = () => { // const history = useHistory(); const list = useAppSelector((state) => state.lists.get(id)); - // const hasUnread = useAppSelector((state) => state.timelines.getIn([`list:${props.params.id}`, 'unread']) > 0); + // const hasUnread = useAppSelector((state) => state.timelines.get(`list:${props.params.id}`)?.unread > 0); useEffect(() => { dispatch(fetchList(id)); diff --git a/app/soapbox/features/mutes/index.tsx b/app/soapbox/features/mutes/index.tsx index d564c68e7d..caf15ca267 100644 --- a/app/soapbox/features/mutes/index.tsx +++ b/app/soapbox/features/mutes/index.tsx @@ -21,8 +21,8 @@ const Mutes: React.FC = () => { const dispatch = useDispatch(); const intl = useIntl(); - const accountIds = useAppSelector((state) => state.user_lists.getIn(['mutes', 'items'])); - const hasMore = useAppSelector((state) => !!state.user_lists.getIn(['mutes', 'next'])); + const accountIds = useAppSelector((state) => state.user_lists.mutes.items); + const hasMore = useAppSelector((state) => !!state.user_lists.mutes.next); React.useEffect(() => { dispatch(fetchMutes()); @@ -47,7 +47,7 @@ const Mutes: React.FC = () => { emptyMessage={emptyMessage} itemClassName='pb-4' > - {accountIds.map((id: string) => + {accountIds.map((id) => , )} diff --git a/app/soapbox/features/onboarding/steps/suggested-accounts-step.tsx b/app/soapbox/features/onboarding/steps/suggested-accounts-step.tsx index 0b09ca4c1b..6b52270c5c 100644 --- a/app/soapbox/features/onboarding/steps/suggested-accounts-step.tsx +++ b/app/soapbox/features/onboarding/steps/suggested-accounts-step.tsx @@ -91,8 +91,6 @@ const SuggestedAccountsStep = ({ onNext }: { onNext: () => void }) => {
- -