From 8529bf64ad4d6ae8df37fe295fc530e22ae6e912 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?marcin=20miko=C5=82ajczak?= Date: Tue, 26 Nov 2024 14:08:26 +0100 Subject: [PATCH] pl-fe: types MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: marcin mikołajczak --- packages/pl-fe/src/actions/events.ts | 4 +- packages/pl-fe/src/actions/statuses.ts | 45 +++++++++++-------- packages/pl-fe/src/actions/timelines.ts | 6 +-- packages/pl-fe/src/reducers/contexts.ts | 17 +++---- .../pl-fe/src/reducers/pending-statuses.ts | 4 +- .../pl-fe/src/reducers/scheduled-statuses.ts | 5 +-- packages/pl-fe/src/reducers/statuses.ts | 21 +++++---- packages/pl-fe/src/reducers/timelines.ts | 25 +++++------ 8 files changed, 64 insertions(+), 63 deletions(-) diff --git a/packages/pl-fe/src/actions/events.ts b/packages/pl-fe/src/actions/events.ts index b2c19481d..206361afb 100644 --- a/packages/pl-fe/src/actions/events.ts +++ b/packages/pl-fe/src/actions/events.ts @@ -179,7 +179,7 @@ const joinEventSuccess = (statusId: string) => ({ statusId, }); -const joinEventFail = (error: unknown, statusId: string, previousState: string | null) => ({ +const joinEventFail = (error: unknown, statusId: string, previousState: Exclude['join_state'] | null) => ({ type: EVENT_JOIN_FAIL, error, statusId, @@ -214,7 +214,7 @@ const leaveEventSuccess = (statusId: string) => ({ statusId, }); -const leaveEventFail = (error: unknown, statusId: string, previousState: string | null) => ({ +const leaveEventFail = (error: unknown, statusId: string, previousState: Exclude['join_state'] | null) => ({ type: EVENT_LEAVE_FAIL, statusId, error, diff --git a/packages/pl-fe/src/actions/statuses.ts b/packages/pl-fe/src/actions/statuses.ts index 5f63737da..491d1aaeb 100644 --- a/packages/pl-fe/src/actions/statuses.ts +++ b/packages/pl-fe/src/actions/statuses.ts @@ -99,20 +99,20 @@ const editStatus = (statusId: string) => (dispatch: AppDispatch, getState: () => const status = state.statuses[statusId]!; const poll = status.poll_id ? state.polls[status.poll_id] : undefined; - dispatch({ type: STATUS_FETCH_SOURCE_REQUEST }); + dispatch({ type: STATUS_FETCH_SOURCE_REQUEST }); return getClient(state).statuses.getStatusSource(statusId).then(response => { - dispatch({ type: STATUS_FETCH_SOURCE_SUCCESS }); + dispatch({ type: STATUS_FETCH_SOURCE_SUCCESS }); dispatch(setComposeToStatus(status, poll, response.text, response.spoiler_text, response.content_type, false)); useModalsStore.getState().openModal('COMPOSE'); }).catch(error => { - dispatch({ type: STATUS_FETCH_SOURCE_FAIL, error }); + dispatch({ type: STATUS_FETCH_SOURCE_FAIL, error }); }); }; const fetchStatus = (statusId: string, intl?: IntlShape) => (dispatch: AppDispatch, getState: () => RootState) => { - dispatch({ type: STATUS_FETCH_REQUEST, statusId }); + dispatch({ type: STATUS_FETCH_REQUEST, statusId }); const params = intl && useSettingsStore.getState().settings.autoTranslate ? { language: intl.locale, @@ -120,10 +120,10 @@ const fetchStatus = (statusId: string, intl?: IntlShape) => return getClient(getState()).statuses.getStatus(statusId, params).then(status => { dispatch(importEntities({ statuses: [status] })); - dispatch({ type: STATUS_FETCH_SUCCESS, status }); + dispatch({ type: STATUS_FETCH_SUCCESS, status }); return status; }).catch(error => { - dispatch({ type: STATUS_FETCH_FAIL, statusId, error, skipAlert: true }); + dispatch({ type: STATUS_FETCH_FAIL, statusId, error, skipAlert: true }); }); }; @@ -136,10 +136,10 @@ const deleteStatus = (statusId: string, withRedraft = false) => const status = state.statuses[statusId]!; const poll = status.poll_id ? state.polls[status.poll_id] : undefined; - dispatch({ type: STATUS_DELETE_REQUEST, params: status }); + dispatch({ type: STATUS_DELETE_REQUEST, params: status }); return getClient(state).statuses.deleteStatus(statusId).then(response => { - dispatch({ type: STATUS_DELETE_SUCCESS, statusId }); + dispatch({ type: STATUS_DELETE_SUCCESS, statusId }); dispatch(deleteFromTimelines(statusId)); if (withRedraft) { @@ -148,7 +148,7 @@ const deleteStatus = (statusId: string, withRedraft = false) => } }) .catch(error => { - dispatch({ type: STATUS_DELETE_FAIL, params: status, error }); + dispatch({ type: STATUS_DELETE_FAIL, params: status, error }); }); }; @@ -157,7 +157,7 @@ const updateStatus = (status: BaseStatus) => (dispatch: AppDispatch) => const fetchContext = (statusId: string, intl?: IntlShape) => (dispatch: AppDispatch, getState: () => RootState) => { - dispatch({ type: CONTEXT_FETCH_REQUEST, statusId }); + dispatch({ type: CONTEXT_FETCH_REQUEST, statusId }); const params = intl && useSettingsStore.getState().settings.autoTranslate ? { language: intl.locale, @@ -167,14 +167,14 @@ const fetchContext = (statusId: string, intl?: IntlShape) => const { ancestors, descendants } = context; const statuses = ancestors.concat(descendants); dispatch(importEntities({ statuses })); - dispatch({ type: CONTEXT_FETCH_SUCCESS, statusId, ancestors, descendants }); + dispatch({ type: CONTEXT_FETCH_SUCCESS, statusId, ancestors, descendants }); return context; }).catch(error => { if (error.response?.status === 404) { dispatch(deleteFromTimelines(statusId)); } - dispatch({ type: CONTEXT_FETCH_FAIL, statusId, error, skipAlert: true }); + dispatch({ type: CONTEXT_FETCH_FAIL, statusId, error, skipAlert: true }); }); }; @@ -319,13 +319,13 @@ const translateStatus = (statusId: string, targetLanguage: string, lazy?: boolea handleTranslateMany(); } else { return client.statuses.translateStatus(statusId, targetLanguage).then(response => { - dispatch({ + dispatch({ type: STATUS_TRANSLATE_SUCCESS, statusId, translation: response, }); }).catch(error => { - dispatch({ + dispatch({ type: STATUS_TRANSLATE_FAIL, statusId, error, @@ -354,11 +354,18 @@ type StatusesAction = | { type: typeof STATUS_CREATE_REQUEST; params: CreateStatusParams; idempotencyKey: string; editing: boolean } | { type: typeof STATUS_CREATE_SUCCESS; status: BaseStatus | ScheduledStatus; params: CreateStatusParams; idempotencyKey: string; editing: boolean } | { type: typeof STATUS_CREATE_FAIL; error: unknown; params: CreateStatusParams; idempotencyKey: string; editing: boolean } -// editStatus, -// fetchStatus, -// deleteStatus, -// updateStatus, -// fetchContext, + | { type: typeof STATUS_FETCH_SOURCE_REQUEST } + | { type: typeof STATUS_FETCH_SOURCE_SUCCESS } + | { type: typeof STATUS_FETCH_SOURCE_FAIL; error: unknown } + | { type: typeof STATUS_FETCH_REQUEST; statusId: string } + | { type: typeof STATUS_FETCH_SUCCESS; status: BaseStatus } + | { type: typeof STATUS_FETCH_FAIL; statusId: string; error: unknown; skipAlert: true } + | { type: typeof STATUS_DELETE_REQUEST; params: Pick } + | { type: typeof STATUS_DELETE_SUCCESS; statusId: string } + | { type: typeof STATUS_DELETE_FAIL; params: Pick; error: unknown } + | { type: typeof CONTEXT_FETCH_REQUEST; statusId: string } + | { type: typeof CONTEXT_FETCH_SUCCESS; statusId: string; ancestors: Array; descendants: Array } + | { type: typeof CONTEXT_FETCH_FAIL; statusId: string; error: unknown; skipAlert: true } | { type: typeof STATUS_MUTE_REQUEST; statusId: string } | { type: typeof STATUS_MUTE_SUCCESS; statusId: string } | { type: typeof STATUS_MUTE_FAIL; statusId: string; error: unknown } diff --git a/packages/pl-fe/src/actions/timelines.ts b/packages/pl-fe/src/actions/timelines.ts index 487039ff7..275c38453 100644 --- a/packages/pl-fe/src/actions/timelines.ts +++ b/packages/pl-fe/src/actions/timelines.ts @@ -114,16 +114,16 @@ interface TimelineDeleteAction { type: typeof TIMELINE_DELETE; statusId: string; accountId: string; - references: Record; + references: Array<[string, string]>; reblogOf: string | null; } const deleteFromTimelines = (statusId: string) => (dispatch: AppDispatch, getState: () => RootState) => { const accountId = getState().statuses[statusId]?.account?.id!; - const references = Object.fromEntries(Object.entries(getState().statuses) + const references: Array<[string, string]> = Object.entries(getState().statuses) .filter(([key, status]) => [key, status.reblog_id === statusId]) - .map(([key, status]) => [key, [status.id, status.account_id] as const])); + .map(([key, status]) => [key, status.account_id]); const reblogOf = getState().statuses[statusId]?.reblog_id || null; dispatch({ diff --git a/packages/pl-fe/src/reducers/contexts.ts b/packages/pl-fe/src/reducers/contexts.ts index 6e4b4d676..b1be3388c 100644 --- a/packages/pl-fe/src/reducers/contexts.ts +++ b/packages/pl-fe/src/reducers/contexts.ts @@ -12,7 +12,6 @@ import { import { TIMELINE_DELETE, type TimelineAction } from '../actions/timelines'; import type { Status } from 'pl-api'; -import type { AnyAction } from 'redux'; interface State { inReplyTos: Record; @@ -36,7 +35,7 @@ const importStatus = (state: State, status: Pick, idempotencyKey: string) => { +const importPendingStatus = (state: State, inReplyToId: string | null | undefined, idempotencyKey: string) => { const id = `末pending-${idempotencyKey}`; - const { in_reply_to_id } = params; - return importStatus(state, { id, in_reply_to_id }); + return importStatus(state, { id, in_reply_to_id: inReplyToId || null }); }; /** Delete a pending status from the reducer. */ -const deletePendingStatus = (state: State, params: Pick, idempotencyKey: string) => { +const deletePendingStatus = (state: State, inReplyToId: string | null | undefined, idempotencyKey: string) => { const id = `末pending-${idempotencyKey}`; - const { in_reply_to_id: inReplyToId } = params; delete state.inReplyTos[id]; @@ -171,7 +168,7 @@ const deletePendingStatus = (state: State, params: Pick { +const replies = (state = initialState, action: AccountsAction | ImporterAction | StatusesAction | TimelineAction): State => { switch (action.type) { case ACCOUNT_BLOCK_SUCCESS: case ACCOUNT_MUTE_SUCCESS: @@ -181,9 +178,9 @@ const replies = (state = initialState, action: AccountsAction | AnyAction | Impo case TIMELINE_DELETE: return create(state, (draft) => deleteStatuses(draft, [action.statusId])); case STATUS_CREATE_REQUEST: - return create(state, (draft) => importPendingStatus(draft, action.params, action.idempotencyKey)); + return create(state, (draft) => importPendingStatus(draft, action.params.in_reply_to_id, action.idempotencyKey)); case STATUS_CREATE_SUCCESS: - return create(state, (draft) => deletePendingStatus(draft, action.status, action.idempotencyKey)); + return create(state, (draft) => deletePendingStatus(draft, 'in_reply_to_id' in action.status ? action.status.in_reply_to_id : null, action.idempotencyKey)); case STATUS_IMPORT: return create(state, (draft) => importStatus(draft, action.status, action.idempotencyKey)); case STATUSES_IMPORT: diff --git a/packages/pl-fe/src/reducers/pending-statuses.ts b/packages/pl-fe/src/reducers/pending-statuses.ts index 249078de1..416b91d5a 100644 --- a/packages/pl-fe/src/reducers/pending-statuses.ts +++ b/packages/pl-fe/src/reducers/pending-statuses.ts @@ -5,10 +5,10 @@ import { STATUS_CREATE_FAIL, STATUS_CREATE_REQUEST, STATUS_CREATE_SUCCESS, + type StatusesAction, } from 'pl-fe/actions/statuses'; import type { StatusVisibility } from 'pl-fe/normalizers/status'; -import type { AnyAction } from 'redux'; interface PendingStatus { content_type: string; @@ -49,7 +49,7 @@ const deleteStatus = (state: State, idempotencyKey: string) => { delete state[idempotencyKey]; }; -const pending_statuses = (state = initialState, action: AnyAction): State => { +const pending_statuses = (state = initialState, action: StatusesAction): State => { switch (action.type) { case STATUS_CREATE_REQUEST: if (action.editing) return state; diff --git a/packages/pl-fe/src/reducers/scheduled-statuses.ts b/packages/pl-fe/src/reducers/scheduled-statuses.ts index 8bc7d3ccb..705d2eb60 100644 --- a/packages/pl-fe/src/reducers/scheduled-statuses.ts +++ b/packages/pl-fe/src/reducers/scheduled-statuses.ts @@ -7,10 +7,9 @@ import { SCHEDULED_STATUS_CANCEL_SUCCESS, type ScheduledStatusesAction, } from 'pl-fe/actions/scheduled-statuses'; -import { STATUS_CREATE_SUCCESS } from 'pl-fe/actions/statuses'; +import { STATUS_CREATE_SUCCESS, type StatusesAction } from 'pl-fe/actions/statuses'; import type { Status, ScheduledStatus } from 'pl-api'; -import type { AnyAction } from 'redux'; type State = Record; @@ -29,7 +28,7 @@ const deleteStatus = (state: State, statusId: string) => { delete state[statusId]; }; -const scheduled_statuses = (state: State = initialState, action: AnyAction | ImporterAction | ScheduledStatusesAction) => { +const scheduled_statuses = (state: State = initialState, action: ImporterAction | ScheduledStatusesAction | StatusesAction) => { switch (action.type) { case STATUS_IMPORT: case STATUS_CREATE_SUCCESS: diff --git a/packages/pl-fe/src/reducers/statuses.ts b/packages/pl-fe/src/reducers/statuses.ts index cd5e28227..95c4e5f78 100644 --- a/packages/pl-fe/src/reducers/statuses.ts +++ b/packages/pl-fe/src/reducers/statuses.ts @@ -52,8 +52,7 @@ import { } from '../actions/statuses'; import { TIMELINE_DELETE, type TimelineAction } from '../actions/timelines'; -import type { Status as BaseStatus, Translation } from 'pl-api'; -import type { AnyAction } from 'redux'; +import type { Status as BaseStatus, CreateStatusParams, Translation } from 'pl-api'; type State = Record; @@ -91,7 +90,7 @@ const importStatuses = (state: State, statuses: Array) =>{ statuses.forEach(status => importStatus(state, status)); }; -const deleteStatus = (state: State, statusId: string, references: Array) => { +const deleteStatus = (state: State, statusId: string, references: Array<[string, string]>) => { references.forEach(ref => { deleteStatus(state, ref[0], []); }); @@ -99,28 +98,28 @@ const deleteStatus = (state: State, statusId: string, references: Array) delete state[statusId]; }; -const incrementReplyCount = (state: State, { in_reply_to_id, quote }: BaseStatus) => { +const incrementReplyCount = (state: State, { in_reply_to_id, quote_id }: Pick) => { if (in_reply_to_id && state[in_reply_to_id]) { const parent = state[in_reply_to_id]; parent.replies_count = (typeof parent.replies_count === 'number' ? parent.replies_count : 0) + 1; } - if (quote?.id && state[quote.id]) { - const parent = state[quote.id]; + if (quote_id && state[quote_id]) { + const parent = state[quote_id]; parent.quotes_count = (typeof parent.quotes_count === 'number' ? parent.quotes_count : 0) + 1; } return state; }; -const decrementReplyCount = (state: State, { in_reply_to_id, quote }: BaseStatus) => { +const decrementReplyCount = (state: State, { in_reply_to_id, quote_id }: Pick) => { if (in_reply_to_id && state[in_reply_to_id]) { const parent = state[in_reply_to_id]; parent.replies_count = Math.max(0, parent.replies_count - 1); } - if (quote?.id) { - const parent = state[quote.id]; + if (quote_id) { + const parent = state[quote_id]; parent.quotes_count = Math.max(0, parent.quotes_count - 1); } @@ -177,7 +176,7 @@ const deleteTranslation = (state: State, statusId: string) => { const initialState: State = {}; -const statuses = (state = initialState, action: AnyAction | EmojiReactsAction | EventsAction | ImporterAction | InteractionsAction | StatusesAction | TimelineAction): State => { +const statuses = (state = initialState, action: EmojiReactsAction | EventsAction | ImporterAction | InteractionsAction | StatusesAction | TimelineAction): State => { switch (action.type) { case STATUS_IMPORT: return create(state, (draft) => importStatus(draft, action.status)); @@ -317,7 +316,7 @@ const statuses = (state = initialState, action: AnyAction | EmojiReactsAction | } }); case STATUS_TRANSLATE_SUCCESS: - return create(state, (draft) => importTranslation(draft, action.statusId, action.translation)); + return action.statusId !== null ? create(state, (draft) => importTranslation(draft, action.statusId!, action.translation)) : state; case STATUS_TRANSLATE_FAIL: return create(state, (draft) => { const status = draft[action.statusId]; diff --git a/packages/pl-fe/src/reducers/timelines.ts b/packages/pl-fe/src/reducers/timelines.ts index 19bc6289f..465709a77 100644 --- a/packages/pl-fe/src/reducers/timelines.ts +++ b/packages/pl-fe/src/reducers/timelines.ts @@ -19,10 +19,9 @@ import { type TimelineAction, } from '../actions/timelines'; -import type { PaginatedResponse, Status as BaseStatus, Relationship } from 'pl-api'; +import type { PaginatedResponse, Status as BaseStatus, Relationship, CreateStatusParams } from 'pl-api'; import type { ImportPosition } from 'pl-fe/entity-store/types'; import type { Status } from 'pl-fe/normalizers/status'; -import type { AnyAction } from 'redux'; const TRUNCATE_LIMIT = 40; const TRUNCATE_SIZE = 20; @@ -159,14 +158,14 @@ const updateTimelineQueue = (state: State, timelineId: string, statusId: string) }); }; -const shouldDelete = (timelineId: string, excludeAccount?: string) => { +const shouldDelete = (timelineId: string, excludeAccount: string | null) => { if (!excludeAccount) return true; if (timelineId === `account:${excludeAccount}`) return false; if (timelineId.startsWith(`account:${excludeAccount}:`)) return false; return true; }; -const deleteStatus = (state: State, statusId: string, references: Array, excludeAccount?: string) => { +const deleteStatus = (state: State, statusId: string, references: Array<[string]> | Array<[string, string]>, excludeAccount: string | null) => { for (const timelineId in state) { if (shouldDelete(timelineId, excludeAccount)) { state[timelineId].items = state[timelineId].items.filter(id => id !== statusId); @@ -176,7 +175,7 @@ const deleteStatus = (state: State, statusId: string, references: Array, // Remove reblogs of deleted status references.forEach(ref => { - deleteStatus(state, ref, [], excludeAccount); + deleteStatus(state, ref[0], [], excludeAccount); }); }; @@ -195,10 +194,10 @@ const isReblogOf = (reblog: Pick, status: Pick>, status: Pick, -) => ( +): Array<[string]> => ( Object.values(statuses) .filter(reblog => isReblogOf(reblog, status)) - .map(status => status.id) + .map(status => [status.id]) ); // const filterTimeline = (state: State, timelineId: string, relationship: APIEntity, statuses: ImmutableList>) => @@ -238,10 +237,10 @@ const timelineDequeue = (state: State, timelineId: string) => { // timeline.set('items', addStatusId(items, null)); // })); -const getTimelinesForStatus = (status: Pick) => { +const getTimelinesForStatus = (status: Pick | Pick) => { switch (status.visibility) { case 'group': - return [`group:${status.group?.id}`]; + return [`group:${'group' in status && status.group?.id}`]; case 'direct': return ['direct']; case 'public': @@ -260,7 +259,7 @@ const replaceId = (ids: Array, oldId: string, newId: string) => { } }; -const importPendingStatus = (state: State, params: BaseStatus, idempotencyKey: string) => { +const importPendingStatus = (state: State, params: CreateStatusParams, idempotencyKey: string) => { const statusId = `末pending-${idempotencyKey}`; const timelineIds = getTimelinesForStatus(params); @@ -295,14 +294,14 @@ const handleExpandFail = (state: State, timelineId: string) => { setFailed(state, timelineId, true); }; -const timelines = (state: State = initialState, action: AccountsAction | AnyAction | InteractionsAction | StatusesAction | TimelineAction): State => { +const timelines = (state: State = initialState, action: AccountsAction | InteractionsAction | StatusesAction | TimelineAction): State => { switch (action.type) { case STATUS_CREATE_REQUEST: if (action.params.scheduled_at) return state; return create(state, (draft) => importPendingStatus(draft, action.params, action.idempotencyKey)); case STATUS_CREATE_SUCCESS: - if (action.status.scheduled_at || action.editing) return state; - return create(state, (draft) => importStatus(draft, action.status, action.idempotencyKey)); + if ('params' in action.status || action.editing) return state; + return create(state, (draft) => importStatus(draft, action.status as BaseStatus, action.idempotencyKey)); case TIMELINE_EXPAND_REQUEST: return create(state, (draft) => setLoading(draft, action.timeline, true)); case TIMELINE_EXPAND_FAIL: