Actions: TypeScript

Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
settings-alert
marcin mikołajczak 2022-06-19 22:54:20 +02:00
rodzic 313bdd1980
commit f3b0230480
2 zmienionych plików z 150 dodań i 110 usunięć

Wyświetl plik

@ -1,4 +1,4 @@
import { Map as ImmutableMap } from 'immutable';
import { List as ImmutableList, Map as ImmutableMap } from 'immutable';
import { v4 as uuidv4 } from 'uuid';
import { getSettings, changeSetting } from 'soapbox/actions/settings';
@ -6,47 +6,49 @@ import { getFeatures } from 'soapbox/utils/features';
import api, { getLinks } from '../api';
export const CHATS_FETCH_REQUEST = 'CHATS_FETCH_REQUEST';
export const CHATS_FETCH_SUCCESS = 'CHATS_FETCH_SUCCESS';
export const CHATS_FETCH_FAIL = 'CHATS_FETCH_FAIL';
import type { History } from 'history';
import type { AppDispatch, RootState } from 'soapbox/store';
export const CHATS_EXPAND_REQUEST = 'CHATS_EXPAND_REQUEST';
export const CHATS_EXPAND_SUCCESS = 'CHATS_EXPAND_SUCCESS';
export const CHATS_EXPAND_FAIL = 'CHATS_EXPAND_FAIL';
const CHATS_FETCH_REQUEST = 'CHATS_FETCH_REQUEST';
const CHATS_FETCH_SUCCESS = 'CHATS_FETCH_SUCCESS';
const CHATS_FETCH_FAIL = 'CHATS_FETCH_FAIL';
export const CHAT_MESSAGES_FETCH_REQUEST = 'CHAT_MESSAGES_FETCH_REQUEST';
export const CHAT_MESSAGES_FETCH_SUCCESS = 'CHAT_MESSAGES_FETCH_SUCCESS';
export const CHAT_MESSAGES_FETCH_FAIL = 'CHAT_MESSAGES_FETCH_FAIL';
const CHATS_EXPAND_REQUEST = 'CHATS_EXPAND_REQUEST';
const CHATS_EXPAND_SUCCESS = 'CHATS_EXPAND_SUCCESS';
const CHATS_EXPAND_FAIL = 'CHATS_EXPAND_FAIL';
export const CHAT_MESSAGE_SEND_REQUEST = 'CHAT_MESSAGE_SEND_REQUEST';
export const CHAT_MESSAGE_SEND_SUCCESS = 'CHAT_MESSAGE_SEND_SUCCESS';
export const CHAT_MESSAGE_SEND_FAIL = 'CHAT_MESSAGE_SEND_FAIL';
const CHAT_MESSAGES_FETCH_REQUEST = 'CHAT_MESSAGES_FETCH_REQUEST';
const CHAT_MESSAGES_FETCH_SUCCESS = 'CHAT_MESSAGES_FETCH_SUCCESS';
const CHAT_MESSAGES_FETCH_FAIL = 'CHAT_MESSAGES_FETCH_FAIL';
export const CHAT_FETCH_REQUEST = 'CHAT_FETCH_REQUEST';
export const CHAT_FETCH_SUCCESS = 'CHAT_FETCH_SUCCESS';
export const CHAT_FETCH_FAIL = 'CHAT_FETCH_FAIL';
const CHAT_MESSAGE_SEND_REQUEST = 'CHAT_MESSAGE_SEND_REQUEST';
const CHAT_MESSAGE_SEND_SUCCESS = 'CHAT_MESSAGE_SEND_SUCCESS';
const CHAT_MESSAGE_SEND_FAIL = 'CHAT_MESSAGE_SEND_FAIL';
export const CHAT_READ_REQUEST = 'CHAT_READ_REQUEST';
export const CHAT_READ_SUCCESS = 'CHAT_READ_SUCCESS';
export const CHAT_READ_FAIL = 'CHAT_READ_FAIL';
const CHAT_FETCH_REQUEST = 'CHAT_FETCH_REQUEST';
const CHAT_FETCH_SUCCESS = 'CHAT_FETCH_SUCCESS';
const CHAT_FETCH_FAIL = 'CHAT_FETCH_FAIL';
export const CHAT_MESSAGE_DELETE_REQUEST = 'CHAT_MESSAGE_DELETE_REQUEST';
export const CHAT_MESSAGE_DELETE_SUCCESS = 'CHAT_MESSAGE_DELETE_SUCCESS';
export const CHAT_MESSAGE_DELETE_FAIL = 'CHAT_MESSAGE_DELETE_FAIL';
const CHAT_READ_REQUEST = 'CHAT_READ_REQUEST';
const CHAT_READ_SUCCESS = 'CHAT_READ_SUCCESS';
const CHAT_READ_FAIL = 'CHAT_READ_FAIL';
export function fetchChatsV1() {
return (dispatch, getState) =>
const CHAT_MESSAGE_DELETE_REQUEST = 'CHAT_MESSAGE_DELETE_REQUEST';
const CHAT_MESSAGE_DELETE_SUCCESS = 'CHAT_MESSAGE_DELETE_SUCCESS';
const CHAT_MESSAGE_DELETE_FAIL = 'CHAT_MESSAGE_DELETE_FAIL';
const fetchChatsV1 = () =>
(dispatch: AppDispatch, getState: () => RootState) =>
api(getState).get('/api/v1/pleroma/chats').then((response) => {
dispatch({ type: CHATS_FETCH_SUCCESS, chats: response.data });
}).catch(error => {
dispatch({ type: CHATS_FETCH_FAIL, error });
});
}
export function fetchChatsV2() {
return (dispatch, getState) =>
const fetchChatsV2 = () =>
(dispatch: AppDispatch, getState: () => RootState) =>
api(getState).get('/api/v2/pleroma/chats').then((response) => {
let next = getLinks(response).refs.find(link => link.rel === 'next');
let next: { uri: string } | undefined = getLinks(response).refs.find(link => link.rel === 'next');
if (!next && response.data.length) {
next = { uri: `/api/v2/pleroma/chats?max_id=${response.data[response.data.length - 1].id}&offset=0` };
@ -56,10 +58,9 @@ export function fetchChatsV2() {
}).catch(error => {
dispatch({ type: CHATS_FETCH_FAIL, error });
});
}
export function fetchChats() {
return (dispatch, getState) => {
const fetchChats = () =>
(dispatch: AppDispatch, getState: () => RootState) => {
const state = getState();
const { instance } = state;
const features = getFeatures(instance);
@ -71,11 +72,10 @@ export function fetchChats() {
return dispatch(fetchChatsV1());
}
};
}
export function expandChats() {
return (dispatch, getState) => {
const url = getState().getIn(['chats', 'next']);
const expandChats = () =>
(dispatch: AppDispatch, getState: () => RootState) => {
const url = getState().chats.next;
if (url === null) {
return;
@ -90,10 +90,9 @@ export function expandChats() {
dispatch({ type: CHATS_EXPAND_FAIL, error });
});
};
}
export function fetchChatMessages(chatId, maxId = null) {
return (dispatch, getState) => {
const fetchChatMessages = (chatId: string, maxId: string | null = null) =>
(dispatch: AppDispatch, getState: () => RootState) => {
dispatch({ type: CHAT_MESSAGES_FETCH_REQUEST, chatId, maxId });
return api(getState).get(`/api/v1/pleroma/chats/${chatId}/messages`, { params: { max_id: maxId } }).then(({ data }) => {
dispatch({ type: CHAT_MESSAGES_FETCH_SUCCESS, chatId, maxId, chatMessages: data });
@ -101,12 +100,11 @@ export function fetchChatMessages(chatId, maxId = null) {
dispatch({ type: CHAT_MESSAGES_FETCH_FAIL, chatId, maxId, error });
});
};
}
export function sendChatMessage(chatId, params) {
return (dispatch, getState) => {
const sendChatMessage = (chatId: string, params: Record<string, any>) =>
(dispatch: AppDispatch, getState: () => RootState) => {
const uuid = `末_${Date.now()}_${uuidv4()}`;
const me = getState().get('me');
const me = getState().me;
dispatch({ type: CHAT_MESSAGE_SEND_REQUEST, chatId, params, uuid, me });
return api(getState).post(`/api/v1/pleroma/chats/${chatId}/messages`, params).then(({ data }) => {
dispatch({ type: CHAT_MESSAGE_SEND_SUCCESS, chatId, chatMessage: data, uuid });
@ -114,28 +112,26 @@ export function sendChatMessage(chatId, params) {
dispatch({ type: CHAT_MESSAGE_SEND_FAIL, chatId, error, uuid });
});
};
}
export function openChat(chatId) {
return (dispatch, getState) => {
const openChat = (chatId: string) =>
(dispatch: AppDispatch, getState: () => RootState) => {
const state = getState();
const panes = getSettings(state).getIn(['chats', 'panes']);
const panes = getSettings(state).getIn(['chats', 'panes']) as ImmutableList<ImmutableMap<string, any>>;
const idx = panes.findIndex(pane => pane.get('chat_id') === chatId);
dispatch(markChatRead(chatId));
if (idx > -1) {
return dispatch(changeSetting(['chats', 'panes', idx, 'state'], 'open'));
return dispatch(changeSetting(['chats', 'panes', idx as any, 'state'], 'open'));
} else {
const newPane = ImmutableMap({ chat_id: chatId, state: 'open' });
return dispatch(changeSetting(['chats', 'panes'], panes.push(newPane)));
}
};
}
export function closeChat(chatId) {
return (dispatch, getState) => {
const panes = getSettings(getState()).getIn(['chats', 'panes']);
const closeChat = (chatId: string) =>
(dispatch: AppDispatch, getState: () => RootState) => {
const panes = getSettings(getState()).getIn(['chats', 'panes']) as ImmutableList<ImmutableMap<string, any>>;
const idx = panes.findIndex(pane => pane.get('chat_id') === chatId);
if (idx > -1) {
@ -144,33 +140,30 @@ export function closeChat(chatId) {
return false;
}
};
}
export function toggleChat(chatId) {
return (dispatch, getState) => {
const panes = getSettings(getState()).getIn(['chats', 'panes']);
const [idx, pane] = panes.findEntry(pane => pane.get('chat_id') === chatId);
const toggleChat = (chatId: string) =>
(dispatch: AppDispatch, getState: () => RootState) => {
const panes = getSettings(getState()).getIn(['chats', 'panes']) as ImmutableList<ImmutableMap<string, any>>;
const [idx, pane] = panes.findEntry(pane => pane.get('chat_id') === chatId)!;
if (idx > -1) {
const state = pane.get('state') === 'minimized' ? 'open' : 'minimized';
if (state === 'open') dispatch(markChatRead(chatId));
return dispatch(changeSetting(['chats', 'panes', idx, 'state'], state));
return dispatch(changeSetting(['chats', 'panes', idx as any, 'state'], state));
} else {
return false;
}
};
}
export function toggleMainWindow() {
return (dispatch, getState) => {
const main = getSettings(getState()).getIn(['chats', 'mainWindow']);
const toggleMainWindow = () =>
(dispatch: AppDispatch, getState: () => RootState) => {
const main = getSettings(getState()).getIn(['chats', 'mainWindow']) as 'minimized' | 'open';
const state = main === 'minimized' ? 'open' : 'minimized';
return dispatch(changeSetting(['chats', 'mainWindow'], state));
};
}
export function fetchChat(chatId) {
return (dispatch, getState) => {
const fetchChat = (chatId: string) =>
(dispatch: AppDispatch, getState: () => RootState) => {
dispatch({ type: CHAT_FETCH_REQUEST, chatId });
return api(getState).get(`/api/v1/pleroma/chats/${chatId}`).then(({ data }) => {
dispatch({ type: CHAT_FETCH_SUCCESS, chat: data });
@ -178,10 +171,9 @@ export function fetchChat(chatId) {
dispatch({ type: CHAT_FETCH_FAIL, chatId, error });
});
};
}
export function startChat(accountId) {
return (dispatch, getState) => {
const startChat = (accountId: string) =>
(dispatch: AppDispatch, getState: () => RootState) => {
dispatch({ type: CHAT_FETCH_REQUEST, accountId });
return api(getState).post(`/api/v1/pleroma/chats/by-account-id/${accountId}`).then(({ data }) => {
dispatch({ type: CHAT_FETCH_SUCCESS, chat: data });
@ -190,12 +182,11 @@ export function startChat(accountId) {
dispatch({ type: CHAT_FETCH_FAIL, accountId, error });
});
};
}
export function markChatRead(chatId, lastReadId) {
return (dispatch, getState) => {
const chat = getState().getIn(['chats', 'items', chatId]);
if (!lastReadId) lastReadId = chat.get('last_message');
const markChatRead = (chatId: string, lastReadId?: string | null) =>
(dispatch: AppDispatch, getState: () => RootState) => {
const chat = getState().chats.items.get(chatId)!;
if (!lastReadId) lastReadId = chat.last_message;
if (chat.get('unread') < 1) return;
if (!lastReadId) return;
@ -207,10 +198,9 @@ export function markChatRead(chatId, lastReadId) {
dispatch({ type: CHAT_READ_FAIL, chatId, error, lastReadId });
});
};
}
export function deleteChatMessage(chatId, messageId) {
return (dispatch, getState) => {
const deleteChatMessage = (chatId: string, messageId: string) =>
(dispatch: AppDispatch, getState: () => RootState) => {
dispatch({ type: CHAT_MESSAGE_DELETE_REQUEST, chatId, messageId });
api(getState).delete(`/api/v1/pleroma/chats/${chatId}/messages/${messageId}`).then(({ data }) => {
dispatch({ type: CHAT_MESSAGE_DELETE_SUCCESS, chatId, messageId, chatMessage: data });
@ -218,13 +208,12 @@ export function deleteChatMessage(chatId, messageId) {
dispatch({ type: CHAT_MESSAGE_DELETE_FAIL, chatId, messageId, error });
});
};
}
/** Start a chat and launch it in the UI */
export function launchChat(accountId, router, forceNavigate = false) {
const isMobile = width => width <= 1190;
const launchChat = (accountId: string, router: History, forceNavigate = false) => {
const isMobile = (width: number) => width <= 1190;
return (dispatch, getState) => {
return (dispatch: AppDispatch) => {
// TODO: make this faster
return dispatch(startChat(accountId)).then(chat => {
if (forceNavigate || isMobile(window.innerWidth)) {
@ -234,4 +223,43 @@ export function launchChat(accountId, router, forceNavigate = false) {
}
});
};
}
};
export {
CHATS_FETCH_REQUEST,
CHATS_FETCH_SUCCESS,
CHATS_FETCH_FAIL,
CHATS_EXPAND_REQUEST,
CHATS_EXPAND_SUCCESS,
CHATS_EXPAND_FAIL,
CHAT_MESSAGES_FETCH_REQUEST,
CHAT_MESSAGES_FETCH_SUCCESS,
CHAT_MESSAGES_FETCH_FAIL,
CHAT_MESSAGE_SEND_REQUEST,
CHAT_MESSAGE_SEND_SUCCESS,
CHAT_MESSAGE_SEND_FAIL,
CHAT_FETCH_REQUEST,
CHAT_FETCH_SUCCESS,
CHAT_FETCH_FAIL,
CHAT_READ_REQUEST,
CHAT_READ_SUCCESS,
CHAT_READ_FAIL,
CHAT_MESSAGE_DELETE_REQUEST,
CHAT_MESSAGE_DELETE_SUCCESS,
CHAT_MESSAGE_DELETE_FAIL,
fetchChatsV1,
fetchChatsV2,
fetchChats,
expandChats,
fetchChatMessages,
sendChatMessage,
openChat,
closeChat,
toggleChat,
toggleMainWindow,
fetchChat,
startChat,
markChatRead,
deleteChatMessage,
launchChat,
};

Wyświetl plik

@ -1,46 +1,49 @@
import { getSettings } from '../settings';
export const ACCOUNT_IMPORT = 'ACCOUNT_IMPORT';
export const ACCOUNTS_IMPORT = 'ACCOUNTS_IMPORT';
export const STATUS_IMPORT = 'STATUS_IMPORT';
export const STATUSES_IMPORT = 'STATUSES_IMPORT';
export const POLLS_IMPORT = 'POLLS_IMPORT';
export const ACCOUNT_FETCH_FAIL_FOR_USERNAME_LOOKUP = 'ACCOUNT_FETCH_FAIL_FOR_USERNAME_LOOKUP';
import type { AppDispatch, RootState } from 'soapbox/store';
import type { APIEntity } from 'soapbox/types/entities';
export function importAccount(account) {
const ACCOUNT_IMPORT = 'ACCOUNT_IMPORT';
const ACCOUNTS_IMPORT = 'ACCOUNTS_IMPORT';
const STATUS_IMPORT = 'STATUS_IMPORT';
const STATUSES_IMPORT = 'STATUSES_IMPORT';
const POLLS_IMPORT = 'POLLS_IMPORT';
const ACCOUNT_FETCH_FAIL_FOR_USERNAME_LOOKUP = 'ACCOUNT_FETCH_FAIL_FOR_USERNAME_LOOKUP';
export function importAccount(account: APIEntity) {
return { type: ACCOUNT_IMPORT, account };
}
export function importAccounts(accounts) {
export function importAccounts(accounts: APIEntity[]) {
return { type: ACCOUNTS_IMPORT, accounts };
}
export function importStatus(status, idempotencyKey) {
return (dispatch, getState) => {
export function importStatus(status: APIEntity, idempotencyKey?: string) {
return (dispatch: AppDispatch, getState: () => RootState) => {
const expandSpoilers = getSettings(getState()).get('expandSpoilers');
return dispatch({ type: STATUS_IMPORT, status, idempotencyKey, expandSpoilers });
};
}
export function importStatuses(statuses) {
return (dispatch, getState) => {
export function importStatuses(statuses: APIEntity[]) {
return (dispatch: AppDispatch, getState: () => RootState) => {
const expandSpoilers = getSettings(getState()).get('expandSpoilers');
return dispatch({ type: STATUSES_IMPORT, statuses, expandSpoilers });
};
}
export function importPolls(polls) {
export function importPolls(polls: APIEntity[]) {
return { type: POLLS_IMPORT, polls };
}
export function importFetchedAccount(account) {
export function importFetchedAccount(account: APIEntity) {
return importFetchedAccounts([account]);
}
export function importFetchedAccounts(accounts) {
const normalAccounts = [];
export function importFetchedAccounts(accounts: APIEntity[]) {
const normalAccounts: APIEntity[] = [];
function processAccount(account) {
const processAccount = (account: APIEntity) => {
if (!account.id) return;
normalAccounts.push(account);
@ -48,15 +51,15 @@ export function importFetchedAccounts(accounts) {
if (account.moved) {
processAccount(account.moved);
}
}
};
accounts.forEach(processAccount);
return importAccounts(normalAccounts);
}
export function importFetchedStatus(status, idempotencyKey) {
return (dispatch, getState) => {
export function importFetchedStatus(status: APIEntity, idempotencyKey?: string) {
return (dispatch: AppDispatch) => {
// Skip broken statuses
if (isBroken(status)) return;
@ -95,7 +98,7 @@ export function importFetchedStatus(status, idempotencyKey) {
// Sometimes Pleroma can return an empty account,
// or a repost can appear of a deleted account. Skip these statuses.
const isBroken = status => {
const isBroken = (status: APIEntity) => {
try {
// Skip empty accounts
// https://gitlab.com/soapbox-pub/soapbox-fe/-/issues/424
@ -109,13 +112,13 @@ const isBroken = status => {
}
};
export function importFetchedStatuses(statuses) {
return (dispatch, getState) => {
const accounts = [];
const normalStatuses = [];
const polls = [];
export function importFetchedStatuses(statuses: APIEntity[]) {
return (dispatch: AppDispatch, getState: () => RootState) => {
const accounts: APIEntity[] = [];
const normalStatuses: APIEntity[] = [];
const polls: APIEntity[] = [];
function processStatus(status) {
function processStatus(status: APIEntity) {
// Skip broken statuses
if (isBroken(status)) return;
@ -148,12 +151,21 @@ export function importFetchedStatuses(statuses) {
};
}
export function importFetchedPoll(poll) {
return dispatch => {
export function importFetchedPoll(poll: APIEntity) {
return (dispatch: AppDispatch) => {
dispatch(importPolls([poll]));
};
}
export function importErrorWhileFetchingAccountByUsername(username) {
export function importErrorWhileFetchingAccountByUsername(username: string) {
return { type: ACCOUNT_FETCH_FAIL_FOR_USERNAME_LOOKUP, username };
}
export {
ACCOUNT_IMPORT,
ACCOUNTS_IMPORT,
STATUS_IMPORT,
STATUSES_IMPORT,
POLLS_IMPORT,
ACCOUNT_FETCH_FAIL_FOR_USERNAME_LOOKUP,
};