Refactor server reducer into TypeScript (#39089)

This commit is contained in:
Eugen Rochko authored and GitHub committed 2026-05-20 14:06:38 +00:00
1 parent f5b57e8ba7
commit 076c8ec51e
26 files changed
+390 -304

No files matched your search

+2 -2
View File
@@ -30,7 +30,7 @@ import { pollsReducer } from './polls';
import push_notifications from './push_notifications';
import { relationshipsReducer } from './relationships';
import { searchReducer } from './search';
import server from './server';
import { serverReducer } from './server';
import settings from './settings';
import { sliceReducers } from './slices';
import status_lists from './status_lists';
@@ -58,7 +58,7 @@ const reducers = {
relationships: relationshipsReducer,
settings,
push_notifications,
server,
server: serverReducer,
contexts: contextsReducer,
compose: composeReducer,
search: searchReducer,
@@ -1,63 +0,0 @@
import { Map as ImmutableMap, List as ImmutableList, fromJS } from 'immutable';
import {
SERVER_FETCH_REQUEST,
SERVER_FETCH_SUCCESS,
SERVER_FETCH_FAIL,
SERVER_TRANSLATION_LANGUAGES_FETCH_REQUEST,
SERVER_TRANSLATION_LANGUAGES_FETCH_SUCCESS,
SERVER_TRANSLATION_LANGUAGES_FETCH_FAIL,
EXTENDED_DESCRIPTION_REQUEST,
EXTENDED_DESCRIPTION_SUCCESS,
EXTENDED_DESCRIPTION_FAIL,
SERVER_DOMAIN_BLOCKS_FETCH_REQUEST,
SERVER_DOMAIN_BLOCKS_FETCH_SUCCESS,
SERVER_DOMAIN_BLOCKS_FETCH_FAIL,
} from 'mastodon/actions/server';
const initialState = ImmutableMap({
server: ImmutableMap({
isLoading: false,
}),
extendedDescription: ImmutableMap({
isLoading: false,
}),
domainBlocks: ImmutableMap({
isLoading: false,
isAvailable: true,
items: ImmutableList(),
}),
});
export default function server(state = initialState, action) {
switch (action.type) {
case SERVER_FETCH_REQUEST:
return state.setIn(['server', 'isLoading'], true);
case SERVER_FETCH_SUCCESS:
return state.set('server', fromJS(action.server)).setIn(['server', 'isLoading'], false);
case SERVER_FETCH_FAIL:
return state.setIn(['server', 'isLoading'], false);
case SERVER_TRANSLATION_LANGUAGES_FETCH_REQUEST:
return state.setIn(['translationLanguages', 'isLoading'], true);
case SERVER_TRANSLATION_LANGUAGES_FETCH_SUCCESS:
return state.setIn(['translationLanguages', 'items'], fromJS(action.translationLanguages)).setIn(['translationLanguages', 'isLoading'], false);
case SERVER_TRANSLATION_LANGUAGES_FETCH_FAIL:
return state.setIn(['translationLanguages', 'isLoading'], false);
case EXTENDED_DESCRIPTION_REQUEST:
return state.setIn(['extendedDescription', 'isLoading'], true);
case EXTENDED_DESCRIPTION_SUCCESS:
return state.set('extendedDescription', fromJS(action.description)).setIn(['extendedDescription', 'isLoading'], false);
case EXTENDED_DESCRIPTION_FAIL:
return state.setIn(['extendedDescription', 'isLoading'], false);
case SERVER_DOMAIN_BLOCKS_FETCH_REQUEST:
return state.setIn(['domainBlocks', 'isLoading'], true);
case SERVER_DOMAIN_BLOCKS_FETCH_SUCCESS:
return state.setIn(['domainBlocks', 'items'], fromJS(action.blocks)).setIn(['domainBlocks', 'isLoading'], false).setIn(['domainBlocks', 'isAvailable'], action.isAvailable);
case SERVER_DOMAIN_BLOCKS_FETCH_FAIL:
return state.setIn(['domainBlocks', 'isLoading'], false);
default:
return state;
}
}
+127
View File
@@ -0,0 +1,127 @@
import { createReducer } from '@reduxjs/toolkit';
import {
fetchServer,
fetchServerTranslationLanguages,
fetchExtendedDescription,
fetchDomainBlocks,
} from 'mastodon/actions/server';
import type {
Server,
ExtendedDescription,
DomainBlock,
} from 'mastodon/models/server';
import {
createServerFromServerJSON,
createExtendedDescriptionFromServerJSON,
createDomainBlockFromServerJSON,
} from 'mastodon/models/server';
interface State {
server: {
isLoading: boolean;
item?: Server;
};
extendedDescription: {
isLoading: boolean;
item?: ExtendedDescription;
};
translationLanguages: {
isLoading: boolean;
item?: Record<string, string[]>;
};
domainBlocks: {
isLoading: boolean;
isAvailable: boolean;
items: DomainBlock[];
};
}
const initialState: State = {
server: {
isLoading: false,
item: undefined,
},
extendedDescription: {
isLoading: false,
item: undefined,
},
translationLanguages: {
isLoading: false,
item: undefined,
},
domainBlocks: {
isLoading: false,
isAvailable: true,
items: [],
},
};
export const serverReducer = createReducer(initialState, (builder) => {
builder.addCase(fetchServer.pending, (state) => {
state.server.isLoading = true;
});
builder.addCase(fetchServer.fulfilled, (state, action) => {
state.server.item = createServerFromServerJSON(action.payload);
state.server.isLoading = false;
});
builder.addCase(fetchServer.rejected, (state) => {
state.server.isLoading = false;
});
builder.addCase(fetchExtendedDescription.pending, (state) => {
state.extendedDescription.isLoading = true;
});
builder.addCase(fetchExtendedDescription.fulfilled, (state, action) => {
state.extendedDescription.item = createExtendedDescriptionFromServerJSON(
action.payload,
);
state.extendedDescription.isLoading = false;
});
builder.addCase(fetchExtendedDescription.rejected, (state) => {
state.extendedDescription.isLoading = false;
});
builder.addCase(fetchServerTranslationLanguages.pending, (state) => {
state.translationLanguages.isLoading = true;
});
builder.addCase(
fetchServerTranslationLanguages.fulfilled,
(state, action) => {
state.translationLanguages.item = action.payload;
state.translationLanguages.isLoading = false;
},
);
builder.addCase(fetchServerTranslationLanguages.rejected, (state) => {
state.translationLanguages.isLoading = false;
});
builder.addCase(fetchDomainBlocks.pending, (state) => {
state.domainBlocks.isLoading = true;
});
builder.addCase(fetchDomainBlocks.fulfilled, (state, action) => {
state.domainBlocks.items = action.payload.map((obj) =>
createDomainBlockFromServerJSON(obj),
);
state.domainBlocks.isLoading = false;
state.domainBlocks.isAvailable = true;
});
builder.addCase(fetchDomainBlocks.rejected, (state) => {
state.domainBlocks.isLoading = false;
state.domainBlocks.isAvailable = false;
});
});
@@ -282,12 +282,8 @@ export const updateField = createAppAsyncThunk(
throw new Error('Profile fields not found');
}
const maxFields = getState().server.getIn([
'server',
'configuration',
'accounts',
'max_fields',
]) as number | undefined;
const maxFields =
getState().server.server.item?.configuration.accounts.max_profile_fields;
if (maxFields && fields.length >= maxFields && !arg.id) {
throw new Error('Maximum number of profile fields reached');
}