From b97518d6005c724249dade48b2c2f07afe986719 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?marcin=20miko=C5=82ajczak?= Date: Wed, 7 Sep 2022 21:24:10 +0200 Subject: [PATCH] Join state optimistic responses MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: marcin mikołajczak --- app/soapbox/actions/events.ts | 26 ++++++++++++-------------- app/soapbox/reducers/statuses.ts | 16 +++++++++++++--- app/soapbox/reducers/user_lists.ts | 17 ++++++++++++++++- 3 files changed, 41 insertions(+), 18 deletions(-) diff --git a/app/soapbox/actions/events.ts b/app/soapbox/actions/events.ts index 6413fe268..ac2d1fda2 100644 --- a/app/soapbox/actions/events.ts +++ b/app/soapbox/actions/events.ts @@ -158,25 +158,22 @@ const uploadEventBanner = (file: File, intl: IntlShape) => const uploadEventBannerRequest = () => ({ type: EVENT_BANNER_UPLOAD_REQUEST, - skipLoading: true, }); const uploadEventBannerProgress = (loaded: number) => ({ type: EVENT_BANNER_UPLOAD_PROGRESS, - loaded: loaded, + loaded, }); const uploadEventBannerSuccess = (media: APIEntity, file: File) => ({ type: EVENT_BANNER_UPLOAD_SUCCESS, - media: media, + media, file, - skipLoading: true, }); const uploadEventBannerFail = (error: AxiosError | true) => ({ type: EVENT_BANNER_UPLOAD_FAIL, - error: error, - skipLoading: true, + error, }); const undoUploadEventBanner = () => ({ @@ -228,12 +225,12 @@ const submitEventRequest = () => ({ const submitEventSuccess = (status: APIEntity) => ({ type: EVENT_SUBMIT_SUCCESS, - status: status, + status, }); const submitEventFail = (error: AxiosError) => ({ type: EVENT_SUBMIT_FAIL, - error: error, + error, }); const joinEvent = (id: string, participationMessage?: string) => @@ -253,7 +250,7 @@ const joinEvent = (id: string, participationMessage?: string) => `/@${data.account.acct}/events/${data.id}`, )); }).catch(function(error) { - dispatch(joinEventFail(error)); + dispatch(joinEventFail(error, status?.event?.join_state || null)); }); }; @@ -263,12 +260,13 @@ const joinEventRequest = () => ({ const joinEventSuccess = (status: APIEntity) => ({ type: EVENT_JOIN_SUCCESS, - status: status, + status, }); -const joinEventFail = (error: AxiosError) => ({ +const joinEventFail = (error: AxiosError, previousState: string | null) => ({ type: EVENT_JOIN_FAIL, - error: error, + error, + previousState, }); const leaveEvent = (id: string) => @@ -293,12 +291,12 @@ const leaveEventRequest = () => ({ const leaveEventSuccess = (status: APIEntity) => ({ type: EVENT_LEAVE_SUCCESS, - status: status, + status, }); const leaveEventFail = (error: AxiosError) => ({ type: EVENT_LEAVE_FAIL, - error: error, + error, }); export { diff --git a/app/soapbox/reducers/statuses.ts b/app/soapbox/reducers/statuses.ts index 49c946aa0..0d8b1c6ad 100644 --- a/app/soapbox/reducers/statuses.ts +++ b/app/soapbox/reducers/statuses.ts @@ -7,10 +7,13 @@ import { simulateEmojiReact, simulateUnEmojiReact } from 'soapbox/utils/emoji_re import { stripCompatibilityFeatures, unescapeHTML } from 'soapbox/utils/html'; import { makeEmojiMap, normalizeId } from 'soapbox/utils/normalizers'; +import { EMOJI_REACT_REQUEST, UNEMOJI_REACT_REQUEST } from '../actions/emoji_reacts'; import { - EMOJI_REACT_REQUEST, - UNEMOJI_REACT_REQUEST, -} from '../actions/emoji_reacts'; + EVENT_JOIN_REQUEST, + EVENT_JOIN_FAIL, + EVENT_LEAVE_REQUEST, + EVENT_LEAVE_FAIL, +} from '../actions/events'; import { STATUS_IMPORT, STATUSES_IMPORT } from '../actions/importer'; import { REBLOG_REQUEST, @@ -257,6 +260,13 @@ export default function statuses(state = initialState, action: AnyAction): State return incrementReplyCount(state, action.params); case TIMELINE_DELETE: return deleteStatus(state, action.id, action.references); + case EVENT_JOIN_REQUEST: + return state.setIn([action.status.get('id'), 'event', 'join_state'], 'pending'); + case EVENT_JOIN_FAIL: + case EVENT_LEAVE_REQUEST: + return state.setIn([action.status.get('id'), 'event', 'join_state'], null); + case EVENT_LEAVE_FAIL: + return state.setIn([action.status.get('id'), 'event', 'join_state'], action.previousState); default: return state; } diff --git a/app/soapbox/reducers/user_lists.ts b/app/soapbox/reducers/user_lists.ts index fc86cceb2..c6527222f 100644 --- a/app/soapbox/reducers/user_lists.ts +++ b/app/soapbox/reducers/user_lists.ts @@ -72,6 +72,17 @@ const ReactionListRecord = ImmutableRecord({ isLoading: false, }); +export const ParticipationRequestRecord = ImmutableRecord({ + account: '', + participation_message: null as string | null, +}); + +const ParticipationRequestListRecord = ImmutableRecord({ + next: null as string | null, + items: ImmutableOrderedSet(), + isLoading: false, +}); + export const ReducerRecord = ImmutableRecord({ followers: ImmutableMap(), following: ImmutableMap(), @@ -87,14 +98,18 @@ export const ReducerRecord = ImmutableRecord({ pinned: ImmutableMap(), birthday_reminders: ImmutableMap(), familiar_followers: ImmutableMap(), + event_participations: ImmutableMap(), + event_participation_requests: ImmutableMap(), }); type State = ReturnType; export type List = ReturnType; type Reaction = ReturnType; type ReactionList = ReturnType; +type ParticipationRequest = ReturnType; +type ParticipationRequestList = ReturnType; type Items = ImmutableOrderedSet; -type NestedListPath = ['followers' | 'following' | 'reblogged_by' | 'favourited_by' | 'reactions' | 'groups' | 'groups_removed_accounts' | 'pinned' | 'birthday_reminders' | 'familiar_followers', string]; +type NestedListPath = ['followers' | 'following' | 'reblogged_by' | 'favourited_by' | 'reactions' | 'groups' | 'groups_removed_accounts' | 'pinned' | 'birthday_reminders' | 'familiar_followers' | 'event_participations' | 'event_participation_requests', string]; type ListPath = ['follow_requests' | 'blocks' | 'mutes' | 'directory']; const normalizeList = (state: State, path: NestedListPath | ListPath, accounts: APIEntity[], next?: string | null) => {