Convert `disconnectTimeline` and `timelineDelete` actions to Typescript (#30777)

pull/30779/head
Renaud Chaput 2024-06-20 13:56:52 +02:00 committed by GitHub
parent 27529247b2
commit 1c65932776
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 65 additions and 49 deletions

View File

@ -77,7 +77,7 @@ export const connectTimelineStream = (timelineId, channelName, params = {}, opti
}, },
onDisconnect() { onDisconnect() {
dispatch(disconnectTimeline(timelineId)); dispatch(disconnectTimeline({ timeline: timelineId }));
if (options.fallback) { if (options.fallback) {
// @ts-expect-error // @ts-expect-error

View File

@ -6,9 +6,11 @@ import { usePendingItems as preferPendingItems } from 'mastodon/initial_state';
import { importFetchedStatus, importFetchedStatuses } from './importer'; import { importFetchedStatus, importFetchedStatuses } from './importer';
import { submitMarkers } from './markers'; import { submitMarkers } from './markers';
import {timelineDelete} from './timelines_typed';
export { disconnectTimeline } from './timelines_typed';
export const TIMELINE_UPDATE = 'TIMELINE_UPDATE'; export const TIMELINE_UPDATE = 'TIMELINE_UPDATE';
export const TIMELINE_DELETE = 'TIMELINE_DELETE';
export const TIMELINE_CLEAR = 'TIMELINE_CLEAR'; export const TIMELINE_CLEAR = 'TIMELINE_CLEAR';
export const TIMELINE_EXPAND_REQUEST = 'TIMELINE_EXPAND_REQUEST'; export const TIMELINE_EXPAND_REQUEST = 'TIMELINE_EXPAND_REQUEST';
@ -17,7 +19,6 @@ export const TIMELINE_EXPAND_FAIL = 'TIMELINE_EXPAND_FAIL';
export const TIMELINE_SCROLL_TOP = 'TIMELINE_SCROLL_TOP'; export const TIMELINE_SCROLL_TOP = 'TIMELINE_SCROLL_TOP';
export const TIMELINE_LOAD_PENDING = 'TIMELINE_LOAD_PENDING'; export const TIMELINE_LOAD_PENDING = 'TIMELINE_LOAD_PENDING';
export const TIMELINE_DISCONNECT = 'TIMELINE_DISCONNECT';
export const TIMELINE_CONNECT = 'TIMELINE_CONNECT'; export const TIMELINE_CONNECT = 'TIMELINE_CONNECT';
export const TIMELINE_MARK_AS_PARTIAL = 'TIMELINE_MARK_AS_PARTIAL'; export const TIMELINE_MARK_AS_PARTIAL = 'TIMELINE_MARK_AS_PARTIAL';
@ -62,16 +63,10 @@ export function updateTimeline(timeline, status, accept) {
export function deleteFromTimelines(id) { export function deleteFromTimelines(id) {
return (dispatch, getState) => { return (dispatch, getState) => {
const accountId = getState().getIn(['statuses', id, 'account']); const accountId = getState().getIn(['statuses', id, 'account']);
const references = getState().get('statuses').filter(status => status.get('reblog') === id).map(status => status.get('id')); const references = getState().get('statuses').filter(status => status.get('reblog') === id).map(status => status.get('id')).toJSON();
const reblogOf = getState().getIn(['statuses', id, 'reblog'], null); const reblogOf = getState().getIn(['statuses', id, 'reblog'], null);
dispatch({ dispatch(timelineDelete(id, accountId, references, reblogOf));
type: TIMELINE_DELETE,
id,
accountId,
references,
reblogOf,
});
}; };
} }
@ -225,12 +220,6 @@ export function connectTimeline(timeline) {
}; };
} }
export const disconnectTimeline = timeline => ({
type: TIMELINE_DISCONNECT,
timeline,
usePendingItems: preferPendingItems,
});
export const markAsPartial = timeline => ({ export const markAsPartial = timeline => ({
type: TIMELINE_MARK_AS_PARTIAL, type: TIMELINE_MARK_AS_PARTIAL,
timeline, timeline,

View File

@ -0,0 +1,20 @@
import { createAction } from '@reduxjs/toolkit';
import { usePendingItems as preferPendingItems } from 'mastodon/initial_state';
export const disconnectTimeline = createAction(
'timeline/disconnect',
({ timeline }: { timeline: string }) => ({
payload: {
timeline,
usePendingItems: preferPendingItems,
},
}),
);
export const timelineDelete = createAction<{
statusId: string;
accountId: string;
references: string[];
reblogOf: string | null;
}>('timelines/delete');

View File

@ -133,7 +133,7 @@ class AccountTimeline extends ImmutablePureComponent {
} }
if (prevProps.accountId === me && accountId !== me) { if (prevProps.accountId === me && accountId !== me) {
dispatch(disconnectTimeline(`account:${me}`)); dispatch(disconnectTimeline({ timeline: `account:${me}` }));
} }
} }
@ -141,7 +141,7 @@ class AccountTimeline extends ImmutablePureComponent {
const { dispatch, accountId } = this.props; const { dispatch, accountId } = this.props;
if (accountId === me) { if (accountId === me) {
dispatch(disconnectTimeline(`account:${me}`)); dispatch(disconnectTimeline({ timeline: `account:${me}` }));
} }
} }

View File

@ -1,5 +1,7 @@
import { Map as ImmutableMap, List as ImmutableList, OrderedSet as ImmutableOrderedSet, fromJS } from 'immutable'; import { Map as ImmutableMap, List as ImmutableList, OrderedSet as ImmutableOrderedSet, fromJS } from 'immutable';
import { timelineDelete } from 'mastodon/actions/timelines_typed';
import { import {
COMPOSE_MOUNT, COMPOSE_MOUNT,
COMPOSE_UNMOUNT, COMPOSE_UNMOUNT,
@ -51,7 +53,6 @@ import {
} from '../actions/compose'; } from '../actions/compose';
import { REDRAFT } from '../actions/statuses'; import { REDRAFT } from '../actions/statuses';
import { STORE_HYDRATE } from '../actions/store'; import { STORE_HYDRATE } from '../actions/store';
import { TIMELINE_DELETE } from '../actions/timelines';
import { me } from '../initial_state'; import { me } from '../initial_state';
import { unescapeHTML } from '../utils/html'; import { unescapeHTML } from '../utils/html';
import { uuid } from '../uuid'; import { uuid } from '../uuid';
@ -446,10 +447,10 @@ export default function compose(state = initialState, action) {
return updateSuggestionTags(state, action.token); return updateSuggestionTags(state, action.token);
case COMPOSE_TAG_HISTORY_UPDATE: case COMPOSE_TAG_HISTORY_UPDATE:
return state.set('tagHistory', fromJS(action.tags)); return state.set('tagHistory', fromJS(action.tags));
case TIMELINE_DELETE: case timelineDelete.type:
if (action.id === state.get('in_reply_to')) { if (action.payload.statusId === state.get('in_reply_to')) {
return state.set('in_reply_to', null); return state.set('in_reply_to', null);
} else if (action.id === state.get('id')) { } else if (action.payload.statusId === state.get('id')) {
return state.set('id', null); return state.set('id', null);
} else { } else {
return state; return state;

View File

@ -1,11 +1,13 @@
import { Map as ImmutableMap, List as ImmutableList } from 'immutable'; import { Map as ImmutableMap, List as ImmutableList } from 'immutable';
import { timelineDelete } from 'mastodon/actions/timelines_typed';
import { import {
blockAccountSuccess, blockAccountSuccess,
muteAccountSuccess, muteAccountSuccess,
} from '../actions/accounts'; } from '../actions/accounts';
import { CONTEXT_FETCH_SUCCESS } from '../actions/statuses'; import { CONTEXT_FETCH_SUCCESS } from '../actions/statuses';
import { TIMELINE_DELETE, TIMELINE_UPDATE } from '../actions/timelines'; import { TIMELINE_UPDATE } from '../actions/timelines';
import { compareId } from '../compare_id'; import { compareId } from '../compare_id';
const initialState = ImmutableMap({ const initialState = ImmutableMap({
@ -97,8 +99,8 @@ export default function replies(state = initialState, action) {
return filterContexts(state, action.payload.relationship, action.payload.statuses); return filterContexts(state, action.payload.relationship, action.payload.statuses);
case CONTEXT_FETCH_SUCCESS: case CONTEXT_FETCH_SUCCESS:
return normalizeContext(state, action.id, action.ancestors, action.descendants); return normalizeContext(state, action.id, action.ancestors, action.descendants);
case TIMELINE_DELETE: case timelineDelete.type:
return deleteFromContexts(state, [action.id]); return deleteFromContexts(state, [action.payload.statusId]);
case TIMELINE_UPDATE: case TIMELINE_UPDATE:
return updateContext(state, action.status); return updateContext(state, action.status);
default: default:

View File

@ -1,10 +1,11 @@
import type { Reducer } from '@reduxjs/toolkit'; import type { Reducer } from '@reduxjs/toolkit';
import { Record as ImmutableRecord, Stack } from 'immutable'; import { Record as ImmutableRecord, Stack } from 'immutable';
import { timelineDelete } from 'mastodon/actions/timelines_typed';
import { COMPOSE_UPLOAD_CHANGE_SUCCESS } from '../actions/compose'; import { COMPOSE_UPLOAD_CHANGE_SUCCESS } from '../actions/compose';
import type { ModalType } from '../actions/modal'; import type { ModalType } from '../actions/modal';
import { openModal, closeModal } from '../actions/modal'; import { openModal, closeModal } from '../actions/modal';
import { TIMELINE_DELETE } from '../actions/timelines';
export type ModalProps = Record<string, unknown>; export type ModalProps = Record<string, unknown>;
interface Modal { interface Modal {
@ -72,10 +73,10 @@ export const modalReducer: Reducer<State> = (state = initialState, action) => {
// TODO: type those actions // TODO: type those actions
else if (action.type === COMPOSE_UPLOAD_CHANGE_SUCCESS) else if (action.type === COMPOSE_UPLOAD_CHANGE_SUCCESS)
return popModal(state, { modalType: 'FOCAL_POINT', ignoreFocus: false }); return popModal(state, { modalType: 'FOCAL_POINT', ignoreFocus: false });
else if (action.type === TIMELINE_DELETE) else if (timelineDelete.match(action))
return state.update('stack', (stack) => return state.update('stack', (stack) =>
stack.filterNot( stack.filterNot(
(modal) => modal.get('modalProps').statusId === action.id, (modal) => modal.get('modalProps').statusId === action.payload.statusId,
), ),
); );
else return state; else return state;

View File

@ -1,6 +1,7 @@
import { fromJS, Map as ImmutableMap, List as ImmutableList } from 'immutable'; import { fromJS, Map as ImmutableMap, List as ImmutableList } from 'immutable';
import { blockDomainSuccess } from 'mastodon/actions/domain_blocks'; import { blockDomainSuccess } from 'mastodon/actions/domain_blocks';
import { timelineDelete } from 'mastodon/actions/timelines_typed';
import { import {
authorizeFollowRequestSuccess, authorizeFollowRequestSuccess,
@ -30,7 +31,7 @@ import {
NOTIFICATIONS_SET_BROWSER_SUPPORT, NOTIFICATIONS_SET_BROWSER_SUPPORT,
NOTIFICATIONS_SET_BROWSER_PERMISSION, NOTIFICATIONS_SET_BROWSER_PERMISSION,
} from '../actions/notifications'; } from '../actions/notifications';
import { TIMELINE_DELETE, TIMELINE_DISCONNECT } from '../actions/timelines'; import { disconnectTimeline } from '../actions/timelines';
import { compareId } from '../compare_id'; import { compareId } from '../compare_id';
const initialState = ImmutableMap({ const initialState = ImmutableMap({
@ -291,11 +292,11 @@ export default function notifications(state = initialState, action) {
return filterNotifications(state, [action.payload.id], 'follow_request'); return filterNotifications(state, [action.payload.id], 'follow_request');
case NOTIFICATIONS_CLEAR: case NOTIFICATIONS_CLEAR:
return state.set('items', ImmutableList()).set('pendingItems', ImmutableList()).set('hasMore', false); return state.set('items', ImmutableList()).set('pendingItems', ImmutableList()).set('hasMore', false);
case TIMELINE_DELETE: case timelineDelete.type:
return deleteByStatus(state, action.id); return deleteByStatus(state, action.payload.statusId);
case TIMELINE_DISCONNECT: case disconnectTimeline.type:
return action.timeline === 'home' ? return action.payload.timeline === 'home' ?
state.update(action.usePendingItems ? 'pendingItems' : 'items', items => items.first() ? items.unshift(null) : items) : state.update(action.payload.usePendingItems ? 'pendingItems' : 'items', items => items.first() ? items.unshift(null) : items) :
state; state;
case NOTIFICATIONS_MARK_AS_READ: case NOTIFICATIONS_MARK_AS_READ:
const lastNotification = state.get('items').find(item => item !== null); const lastNotification = state.get('items').find(item => item !== null);

View File

@ -4,8 +4,7 @@ import {
deployPictureInPictureAction, deployPictureInPictureAction,
removePictureInPicture, removePictureInPicture,
} from 'mastodon/actions/picture_in_picture'; } from 'mastodon/actions/picture_in_picture';
import { timelineDelete } from 'mastodon/actions/timelines_typed';
import { TIMELINE_DELETE } from '../actions/timelines';
export interface PIPMediaProps { export interface PIPMediaProps {
src: string; src: string;
@ -49,8 +48,9 @@ export const pictureInPictureReducer: Reducer<PIPState> = (
...action.payload.props, ...action.payload.props,
}; };
else if (removePictureInPicture.match(action)) return initialState; else if (removePictureInPicture.match(action)) return initialState;
else if (action.type === TIMELINE_DELETE) else if (timelineDelete.match(action))
if (state.type && state.statusId === action.id) return initialState; if (state.type && state.statusId === action.payload.statusId)
return initialState;
return state; return state;
}; };

View File

@ -1,5 +1,7 @@
import { Map as ImmutableMap, fromJS } from 'immutable'; import { Map as ImmutableMap, fromJS } from 'immutable';
import { timelineDelete } from 'mastodon/actions/timelines_typed';
import { STATUS_IMPORT, STATUSES_IMPORT } from '../actions/importer'; import { STATUS_IMPORT, STATUSES_IMPORT } from '../actions/importer';
import { normalizeStatusTranslation } from '../actions/importer/normalizer'; import { normalizeStatusTranslation } from '../actions/importer/normalizer';
import { import {
@ -27,7 +29,6 @@ import {
STATUS_FETCH_REQUEST, STATUS_FETCH_REQUEST,
STATUS_FETCH_FAIL, STATUS_FETCH_FAIL,
} from '../actions/statuses'; } from '../actions/statuses';
import { TIMELINE_DELETE } from '../actions/timelines';
const importStatus = (state, status) => state.set(status.id, fromJS(status)); const importStatus = (state, status) => state.set(status.id, fromJS(status));
@ -114,8 +115,8 @@ export default function statuses(state = initialState, action) {
}); });
case STATUS_COLLAPSE: case STATUS_COLLAPSE:
return state.setIn([action.id, 'collapsed'], action.isCollapsed); return state.setIn([action.id, 'collapsed'], action.isCollapsed);
case TIMELINE_DELETE: case timelineDelete.type:
return deleteStatus(state, action.id, action.references); return deleteStatus(state, action.payload.statusId, action.payload.references);
case STATUS_TRANSLATE_SUCCESS: case STATUS_TRANSLATE_SUCCESS:
return statusTranslateSuccess(state, action.id, action.translation); return statusTranslateSuccess(state, action.id, action.translation);
case STATUS_TRANSLATE_UNDO: case STATUS_TRANSLATE_UNDO:

View File

@ -1,5 +1,7 @@
import { Map as ImmutableMap, List as ImmutableList, OrderedSet as ImmutableOrderedSet, fromJS } from 'immutable'; import { Map as ImmutableMap, List as ImmutableList, OrderedSet as ImmutableOrderedSet, fromJS } from 'immutable';
import { timelineDelete } from 'mastodon/actions/timelines_typed';
import { import {
blockAccountSuccess, blockAccountSuccess,
muteAccountSuccess, muteAccountSuccess,
@ -7,19 +9,18 @@ import {
} from '../actions/accounts'; } from '../actions/accounts';
import { import {
TIMELINE_UPDATE, TIMELINE_UPDATE,
TIMELINE_DELETE,
TIMELINE_CLEAR, TIMELINE_CLEAR,
TIMELINE_EXPAND_SUCCESS, TIMELINE_EXPAND_SUCCESS,
TIMELINE_EXPAND_REQUEST, TIMELINE_EXPAND_REQUEST,
TIMELINE_EXPAND_FAIL, TIMELINE_EXPAND_FAIL,
TIMELINE_SCROLL_TOP, TIMELINE_SCROLL_TOP,
TIMELINE_CONNECT, TIMELINE_CONNECT,
TIMELINE_DISCONNECT,
TIMELINE_LOAD_PENDING, TIMELINE_LOAD_PENDING,
TIMELINE_MARK_AS_PARTIAL, TIMELINE_MARK_AS_PARTIAL,
TIMELINE_INSERT, TIMELINE_INSERT,
TIMELINE_GAP, TIMELINE_GAP,
TIMELINE_SUGGESTIONS, TIMELINE_SUGGESTIONS,
disconnectTimeline,
} from '../actions/timelines'; } from '../actions/timelines';
import { compareId } from '../compare_id'; import { compareId } from '../compare_id';
@ -201,8 +202,8 @@ export default function timelines(state = initialState, action) {
return expandNormalizedTimeline(state, action.timeline, fromJS(action.statuses), action.next, action.partial, action.isLoadingRecent, action.usePendingItems); return expandNormalizedTimeline(state, action.timeline, fromJS(action.statuses), action.next, action.partial, action.isLoadingRecent, action.usePendingItems);
case TIMELINE_UPDATE: case TIMELINE_UPDATE:
return updateTimeline(state, action.timeline, fromJS(action.status), action.usePendingItems); return updateTimeline(state, action.timeline, fromJS(action.status), action.usePendingItems);
case TIMELINE_DELETE: case timelineDelete.type:
return deleteStatus(state, action.id, action.references, action.reblogOf); return deleteStatus(state, action.payload.statusId, action.payload.references, action.payload.reblogOf);
case TIMELINE_CLEAR: case TIMELINE_CLEAR:
return clearTimeline(state, action.timeline); return clearTimeline(state, action.timeline);
case blockAccountSuccess.type: case blockAccountSuccess.type:
@ -214,11 +215,11 @@ export default function timelines(state = initialState, action) {
return updateTop(state, action.timeline, action.top); return updateTop(state, action.timeline, action.top);
case TIMELINE_CONNECT: case TIMELINE_CONNECT:
return state.update(action.timeline, initialTimeline, map => reconnectTimeline(map, action.usePendingItems)); return state.update(action.timeline, initialTimeline, map => reconnectTimeline(map, action.usePendingItems));
case TIMELINE_DISCONNECT: case disconnectTimeline.type:
return state.update( return state.update(
action.timeline, action.payload.timeline,
initialTimeline, initialTimeline,
map => map.set('online', false).update(action.usePendingItems ? 'pendingItems' : 'items', items => items.first() ? items.unshift(TIMELINE_GAP) : items), map => map.set('online', false).update(action.payload.usePendingItems ? 'pendingItems' : 'items', items => items.first() ? items.unshift(TIMELINE_GAP) : items),
); );
case TIMELINE_MARK_AS_PARTIAL: case TIMELINE_MARK_AS_PARTIAL:
return state.update( return state.update(