Convert notification requests actions and reducers to Typescript (#31866)
This commit is contained in:
parent
d5cf27e667
commit
c0eda832f3
12 changed files with 585 additions and 492 deletions
|
@ -1,114 +0,0 @@
|
|||
import { Map as ImmutableMap, List as ImmutableList, fromJS } from 'immutable';
|
||||
|
||||
import { blockAccountSuccess, muteAccountSuccess } from 'mastodon/actions/accounts';
|
||||
import {
|
||||
NOTIFICATION_REQUESTS_EXPAND_REQUEST,
|
||||
NOTIFICATION_REQUESTS_EXPAND_SUCCESS,
|
||||
NOTIFICATION_REQUESTS_EXPAND_FAIL,
|
||||
NOTIFICATION_REQUESTS_FETCH_REQUEST,
|
||||
NOTIFICATION_REQUESTS_FETCH_SUCCESS,
|
||||
NOTIFICATION_REQUESTS_FETCH_FAIL,
|
||||
NOTIFICATION_REQUEST_FETCH_REQUEST,
|
||||
NOTIFICATION_REQUEST_FETCH_SUCCESS,
|
||||
NOTIFICATION_REQUEST_FETCH_FAIL,
|
||||
NOTIFICATION_REQUEST_ACCEPT_REQUEST,
|
||||
NOTIFICATION_REQUEST_DISMISS_REQUEST,
|
||||
NOTIFICATION_REQUESTS_ACCEPT_REQUEST,
|
||||
NOTIFICATION_REQUESTS_DISMISS_REQUEST,
|
||||
NOTIFICATIONS_FOR_REQUEST_FETCH_REQUEST,
|
||||
NOTIFICATIONS_FOR_REQUEST_FETCH_SUCCESS,
|
||||
NOTIFICATIONS_FOR_REQUEST_FETCH_FAIL,
|
||||
NOTIFICATIONS_FOR_REQUEST_EXPAND_REQUEST,
|
||||
NOTIFICATIONS_FOR_REQUEST_EXPAND_SUCCESS,
|
||||
NOTIFICATIONS_FOR_REQUEST_EXPAND_FAIL,
|
||||
} from 'mastodon/actions/notifications';
|
||||
|
||||
import { notificationToMap } from './notifications';
|
||||
|
||||
const initialState = ImmutableMap({
|
||||
items: ImmutableList(),
|
||||
isLoading: false,
|
||||
next: null,
|
||||
current: ImmutableMap({
|
||||
isLoading: false,
|
||||
item: null,
|
||||
removed: false,
|
||||
notifications: ImmutableMap({
|
||||
items: ImmutableList(),
|
||||
isLoading: false,
|
||||
next: null,
|
||||
}),
|
||||
}),
|
||||
});
|
||||
|
||||
const normalizeRequest = request => fromJS({
|
||||
...request,
|
||||
account: request.account.id,
|
||||
});
|
||||
|
||||
const removeRequest = (state, id) => {
|
||||
if (state.getIn(['current', 'item', 'id']) === id) {
|
||||
state = state.setIn(['current', 'removed'], true);
|
||||
}
|
||||
|
||||
return state.update('items', list => list.filterNot(item => item.get('id') === id));
|
||||
};
|
||||
|
||||
const removeRequestByAccount = (state, account_id) => {
|
||||
if (state.getIn(['current', 'item', 'account']) === account_id) {
|
||||
state = state.setIn(['current', 'removed'], true);
|
||||
}
|
||||
|
||||
return state.update('items', list => list.filterNot(item => item.get('account') === account_id));
|
||||
};
|
||||
|
||||
export const notificationRequestsReducer = (state = initialState, action) => {
|
||||
switch(action.type) {
|
||||
case NOTIFICATION_REQUESTS_FETCH_SUCCESS:
|
||||
return state.withMutations(map => {
|
||||
map.update('items', list => ImmutableList(action.requests.map(normalizeRequest)).concat(list));
|
||||
map.set('isLoading', false);
|
||||
map.update('next', next => next ?? action.next);
|
||||
});
|
||||
case NOTIFICATION_REQUESTS_EXPAND_SUCCESS:
|
||||
return state.withMutations(map => {
|
||||
map.update('items', list => list.concat(ImmutableList(action.requests.map(normalizeRequest))));
|
||||
map.set('isLoading', false);
|
||||
map.set('next', action.next);
|
||||
});
|
||||
case NOTIFICATION_REQUESTS_EXPAND_REQUEST:
|
||||
case NOTIFICATION_REQUESTS_FETCH_REQUEST:
|
||||
return state.set('isLoading', true);
|
||||
case NOTIFICATION_REQUESTS_EXPAND_FAIL:
|
||||
case NOTIFICATION_REQUESTS_FETCH_FAIL:
|
||||
return state.set('isLoading', false);
|
||||
case NOTIFICATION_REQUEST_ACCEPT_REQUEST:
|
||||
case NOTIFICATION_REQUEST_DISMISS_REQUEST:
|
||||
return removeRequest(state, action.id);
|
||||
case NOTIFICATION_REQUESTS_ACCEPT_REQUEST:
|
||||
case NOTIFICATION_REQUESTS_DISMISS_REQUEST:
|
||||
return action.ids.reduce((state, id) => removeRequest(state, id), state);
|
||||
case blockAccountSuccess.type:
|
||||
return removeRequestByAccount(state, action.payload.relationship.id);
|
||||
case muteAccountSuccess.type:
|
||||
return action.payload.relationship.muting_notifications ? removeRequestByAccount(state, action.payload.relationship.id) : state;
|
||||
case NOTIFICATION_REQUEST_FETCH_REQUEST:
|
||||
return state.set('current', initialState.get('current').set('isLoading', true));
|
||||
case NOTIFICATION_REQUEST_FETCH_SUCCESS:
|
||||
return state.update('current', map => map.set('isLoading', false).set('item', normalizeRequest(action.request)));
|
||||
case NOTIFICATION_REQUEST_FETCH_FAIL:
|
||||
return state.update('current', map => map.set('isLoading', false));
|
||||
case NOTIFICATIONS_FOR_REQUEST_FETCH_REQUEST:
|
||||
case NOTIFICATIONS_FOR_REQUEST_EXPAND_REQUEST:
|
||||
return state.setIn(['current', 'notifications', 'isLoading'], true);
|
||||
case NOTIFICATIONS_FOR_REQUEST_FETCH_SUCCESS:
|
||||
return state.updateIn(['current', 'notifications'], map => map.set('isLoading', false).update('items', list => ImmutableList(action.notifications.map(notificationToMap)).concat(list)).update('next', next => next ?? action.next));
|
||||
case NOTIFICATIONS_FOR_REQUEST_EXPAND_SUCCESS:
|
||||
return state.updateIn(['current', 'notifications'], map => map.set('isLoading', false).update('items', list => list.concat(ImmutableList(action.notifications.map(notificationToMap)))).set('next', action.next));
|
||||
case NOTIFICATIONS_FOR_REQUEST_FETCH_FAIL:
|
||||
case NOTIFICATIONS_FOR_REQUEST_EXPAND_FAIL:
|
||||
return state.setIn(['current', 'notifications', 'isLoading'], false);
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
};
|
182
app/javascript/mastodon/reducers/notification_requests.ts
Normal file
182
app/javascript/mastodon/reducers/notification_requests.ts
Normal file
|
@ -0,0 +1,182 @@
|
|||
import { createReducer, isAnyOf } from '@reduxjs/toolkit';
|
||||
|
||||
import {
|
||||
blockAccountSuccess,
|
||||
muteAccountSuccess,
|
||||
} from 'mastodon/actions/accounts';
|
||||
import {
|
||||
fetchNotificationRequests,
|
||||
expandNotificationRequests,
|
||||
fetchNotificationRequest,
|
||||
fetchNotificationsForRequest,
|
||||
expandNotificationsForRequest,
|
||||
acceptNotificationRequest,
|
||||
dismissNotificationRequest,
|
||||
acceptNotificationRequests,
|
||||
dismissNotificationRequests,
|
||||
} from 'mastodon/actions/notification_requests';
|
||||
import type { NotificationRequest } from 'mastodon/models/notification_request';
|
||||
import { createNotificationRequestFromJSON } from 'mastodon/models/notification_request';
|
||||
|
||||
import { notificationToMap } from './notifications';
|
||||
|
||||
interface NotificationsListState {
|
||||
items: unknown[]; // TODO
|
||||
isLoading: boolean;
|
||||
next: string | null;
|
||||
}
|
||||
|
||||
interface CurrentNotificationRequestState {
|
||||
item: NotificationRequest | null;
|
||||
isLoading: boolean;
|
||||
removed: boolean;
|
||||
notifications: NotificationsListState;
|
||||
}
|
||||
|
||||
interface NotificationRequestsState {
|
||||
items: NotificationRequest[];
|
||||
isLoading: boolean;
|
||||
next: string | null;
|
||||
current: CurrentNotificationRequestState;
|
||||
}
|
||||
|
||||
const initialState: NotificationRequestsState = {
|
||||
items: [],
|
||||
isLoading: false,
|
||||
next: null,
|
||||
current: {
|
||||
item: null,
|
||||
isLoading: false,
|
||||
removed: false,
|
||||
notifications: {
|
||||
isLoading: false,
|
||||
items: [],
|
||||
next: null,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const removeRequest = (state: NotificationRequestsState, id: string) => {
|
||||
if (state.current.item?.id === id) {
|
||||
state.current.removed = true;
|
||||
}
|
||||
|
||||
state.items = state.items.filter((item) => item.id !== id);
|
||||
};
|
||||
|
||||
const removeRequestByAccount = (
|
||||
state: NotificationRequestsState,
|
||||
account_id: string,
|
||||
) => {
|
||||
if (state.current.item?.account_id === account_id) {
|
||||
state.current.removed = true;
|
||||
}
|
||||
|
||||
state.items = state.items.filter((item) => item.account_id !== account_id);
|
||||
};
|
||||
|
||||
export const notificationRequestsReducer =
|
||||
createReducer<NotificationRequestsState>(initialState, (builder) => {
|
||||
builder
|
||||
.addCase(fetchNotificationRequests.fulfilled, (state, action) => {
|
||||
state.items = action.payload.requests
|
||||
.map(createNotificationRequestFromJSON)
|
||||
.concat(state.items);
|
||||
state.isLoading = false;
|
||||
state.next ??= action.payload.next ?? null;
|
||||
})
|
||||
.addCase(expandNotificationRequests.fulfilled, (state, action) => {
|
||||
state.items = state.items.concat(
|
||||
action.payload.requests.map(createNotificationRequestFromJSON),
|
||||
);
|
||||
state.isLoading = false;
|
||||
state.next = action.payload.next ?? null;
|
||||
})
|
||||
.addCase(blockAccountSuccess, (state, action) => {
|
||||
removeRequestByAccount(state, action.payload.relationship.id);
|
||||
})
|
||||
.addCase(muteAccountSuccess, (state, action) => {
|
||||
if (action.payload.relationship.muting_notifications)
|
||||
removeRequestByAccount(state, action.payload.relationship.id);
|
||||
})
|
||||
.addCase(fetchNotificationRequest.pending, (state) => {
|
||||
state.current = { ...initialState.current, isLoading: true };
|
||||
})
|
||||
.addCase(fetchNotificationRequest.rejected, (state) => {
|
||||
state.current.isLoading = false;
|
||||
})
|
||||
.addCase(fetchNotificationRequest.fulfilled, (state, action) => {
|
||||
state.current.isLoading = false;
|
||||
state.current.item = createNotificationRequestFromJSON(action.payload);
|
||||
})
|
||||
.addCase(fetchNotificationsForRequest.fulfilled, (state, action) => {
|
||||
state.current.notifications.isLoading = false;
|
||||
state.current.notifications.items.unshift(
|
||||
...action.payload.notifications.map(notificationToMap),
|
||||
);
|
||||
state.current.notifications.next ??= action.payload.next ?? null;
|
||||
})
|
||||
.addCase(expandNotificationsForRequest.fulfilled, (state, action) => {
|
||||
state.current.notifications.isLoading = false;
|
||||
state.current.notifications.items.push(
|
||||
...action.payload.notifications.map(notificationToMap),
|
||||
);
|
||||
state.current.notifications.next = action.payload.next ?? null;
|
||||
})
|
||||
.addMatcher(
|
||||
isAnyOf(
|
||||
fetchNotificationRequests.pending,
|
||||
expandNotificationRequests.pending,
|
||||
),
|
||||
(state) => {
|
||||
state.isLoading = true;
|
||||
},
|
||||
)
|
||||
.addMatcher(
|
||||
isAnyOf(
|
||||
fetchNotificationRequests.rejected,
|
||||
expandNotificationRequests.rejected,
|
||||
),
|
||||
(state) => {
|
||||
state.isLoading = false;
|
||||
},
|
||||
)
|
||||
.addMatcher(
|
||||
isAnyOf(
|
||||
acceptNotificationRequest.pending,
|
||||
dismissNotificationRequest.pending,
|
||||
),
|
||||
(state, action) => {
|
||||
removeRequest(state, action.meta.arg.id);
|
||||
},
|
||||
)
|
||||
.addMatcher(
|
||||
isAnyOf(
|
||||
acceptNotificationRequests.pending,
|
||||
dismissNotificationRequests.pending,
|
||||
),
|
||||
(state, action) => {
|
||||
action.meta.arg.ids.forEach((id) => {
|
||||
removeRequest(state, id);
|
||||
});
|
||||
},
|
||||
)
|
||||
.addMatcher(
|
||||
isAnyOf(
|
||||
fetchNotificationsForRequest.pending,
|
||||
expandNotificationsForRequest.pending,
|
||||
),
|
||||
(state) => {
|
||||
state.current.notifications.isLoading = true;
|
||||
},
|
||||
)
|
||||
.addMatcher(
|
||||
isAnyOf(
|
||||
fetchNotificationsForRequest.rejected,
|
||||
expandNotificationsForRequest.rejected,
|
||||
),
|
||||
(state) => {
|
||||
state.current.notifications.isLoading = false;
|
||||
},
|
||||
);
|
||||
});
|
Loading…
Add table
Add a link
Reference in a new issue