import toast from 'soapbox/toast'; import { isLoggedIn } from 'soapbox/utils/auth'; import api from '../api'; import { importFetchedAccounts } from './importer'; import type { AxiosError } from 'axios'; import type { AppDispatch, RootState } from 'soapbox/store'; import type { APIEntity } from 'soapbox/types/entities'; const LIST_FETCH_REQUEST = 'LIST_FETCH_REQUEST'; const LIST_FETCH_SUCCESS = 'LIST_FETCH_SUCCESS'; const LIST_FETCH_FAIL = 'LIST_FETCH_FAIL'; const LISTS_FETCH_REQUEST = 'LISTS_FETCH_REQUEST'; const LISTS_FETCH_SUCCESS = 'LISTS_FETCH_SUCCESS'; const LISTS_FETCH_FAIL = 'LISTS_FETCH_FAIL'; const LIST_EDITOR_TITLE_CHANGE = 'LIST_EDITOR_TITLE_CHANGE'; const LIST_EDITOR_RESET = 'LIST_EDITOR_RESET'; const LIST_EDITOR_SETUP = 'LIST_EDITOR_SETUP'; const LIST_CREATE_REQUEST = 'LIST_CREATE_REQUEST'; const LIST_CREATE_SUCCESS = 'LIST_CREATE_SUCCESS'; const LIST_CREATE_FAIL = 'LIST_CREATE_FAIL'; const LIST_UPDATE_REQUEST = 'LIST_UPDATE_REQUEST'; const LIST_UPDATE_SUCCESS = 'LIST_UPDATE_SUCCESS'; const LIST_UPDATE_FAIL = 'LIST_UPDATE_FAIL'; const LIST_DELETE_REQUEST = 'LIST_DELETE_REQUEST'; const LIST_DELETE_SUCCESS = 'LIST_DELETE_SUCCESS'; const LIST_DELETE_FAIL = 'LIST_DELETE_FAIL'; const LIST_ACCOUNTS_FETCH_REQUEST = 'LIST_ACCOUNTS_FETCH_REQUEST'; const LIST_ACCOUNTS_FETCH_SUCCESS = 'LIST_ACCOUNTS_FETCH_SUCCESS'; const LIST_ACCOUNTS_FETCH_FAIL = 'LIST_ACCOUNTS_FETCH_FAIL'; const LIST_EDITOR_SUGGESTIONS_CHANGE = 'LIST_EDITOR_SUGGESTIONS_CHANGE'; const LIST_EDITOR_SUGGESTIONS_READY = 'LIST_EDITOR_SUGGESTIONS_READY'; const LIST_EDITOR_SUGGESTIONS_CLEAR = 'LIST_EDITOR_SUGGESTIONS_CLEAR'; const LIST_EDITOR_ADD_REQUEST = 'LIST_EDITOR_ADD_REQUEST'; const LIST_EDITOR_ADD_SUCCESS = 'LIST_EDITOR_ADD_SUCCESS'; const LIST_EDITOR_ADD_FAIL = 'LIST_EDITOR_ADD_FAIL'; const LIST_EDITOR_REMOVE_REQUEST = 'LIST_EDITOR_REMOVE_REQUEST'; const LIST_EDITOR_REMOVE_SUCCESS = 'LIST_EDITOR_REMOVE_SUCCESS'; const LIST_EDITOR_REMOVE_FAIL = 'LIST_EDITOR_REMOVE_FAIL'; const LIST_ADDER_RESET = 'LIST_ADDER_RESET'; const LIST_ADDER_SETUP = 'LIST_ADDER_SETUP'; const LIST_ADDER_LISTS_FETCH_REQUEST = 'LIST_ADDER_LISTS_FETCH_REQUEST'; const LIST_ADDER_LISTS_FETCH_SUCCESS = 'LIST_ADDER_LISTS_FETCH_SUCCESS'; const LIST_ADDER_LISTS_FETCH_FAIL = 'LIST_ADDER_LISTS_FETCH_FAIL'; const fetchList = (id: string | number) => (dispatch: AppDispatch, getState: () => RootState) => { if (!isLoggedIn(getState)) return; if (getState().lists.get(String(id))) { return; } dispatch(fetchListRequest(id)); api(getState).get(`/api/v1/lists/${id}`) .then(({ data }) => dispatch(fetchListSuccess(data))) .catch(err => dispatch(fetchListFail(id, err))); }; const fetchListRequest = (id: string | number) => ({ type: LIST_FETCH_REQUEST, id, }); const fetchListSuccess = (list: APIEntity) => ({ type: LIST_FETCH_SUCCESS, list, }); const fetchListFail = (id: string | number, error: AxiosError) => ({ type: LIST_FETCH_FAIL, id, error, }); const fetchLists = () => (dispatch: AppDispatch, getState: () => RootState) => { if (!isLoggedIn(getState)) return; dispatch(fetchListsRequest()); api(getState).get('/api/v1/lists') .then(({ data }) => dispatch(fetchListsSuccess(data))) .catch(err => dispatch(fetchListsFail(err))); }; const fetchListsRequest = () => ({ type: LISTS_FETCH_REQUEST, }); const fetchListsSuccess = (lists: APIEntity[]) => ({ type: LISTS_FETCH_SUCCESS, lists, }); const fetchListsFail = (error: AxiosError) => ({ type: LISTS_FETCH_FAIL, error, }); const submitListEditor = (shouldReset?: boolean) => (dispatch: AppDispatch, getState: () => RootState) => { const listId = getState().listEditor.listId!; const title = getState().listEditor.title; if (listId === null) { dispatch(createList(title, shouldReset)); } else { dispatch(updateList(listId, title, shouldReset)); } }; const setupListEditor = (listId: string | number) => (dispatch: AppDispatch, getState: () => RootState) => { dispatch({ type: LIST_EDITOR_SETUP, list: getState().lists.get(String(listId)), }); dispatch(fetchListAccounts(listId)); }; const changeListEditorTitle = (value: string) => ({ type: LIST_EDITOR_TITLE_CHANGE, value, }); const createList = (title: string, shouldReset?: boolean) => (dispatch: AppDispatch, getState: () => RootState) => { if (!isLoggedIn(getState)) return; dispatch(createListRequest()); api(getState).post('/api/v1/lists', { title }).then(({ data }) => { dispatch(createListSuccess(data)); if (shouldReset) { dispatch(resetListEditor()); } }).catch(err => dispatch(createListFail(err))); }; const createListRequest = () => ({ type: LIST_CREATE_REQUEST, }); const createListSuccess = (list: APIEntity) => ({ type: LIST_CREATE_SUCCESS, list, }); const createListFail = (error: AxiosError) => ({ type: LIST_CREATE_FAIL, error, }); const updateList = (id: string | number, title: string, shouldReset?: boolean) => (dispatch: AppDispatch, getState: () => RootState) => { if (!isLoggedIn(getState)) return; dispatch(updateListRequest(id)); api(getState).put(`/api/v1/lists/${id}`, { title }).then(({ data }) => { dispatch(updateListSuccess(data)); if (shouldReset) { dispatch(resetListEditor()); } }).catch(err => dispatch(updateListFail(id, err))); }; const updateListRequest = (id: string | number) => ({ type: LIST_UPDATE_REQUEST, id, }); const updateListSuccess = (list: APIEntity) => ({ type: LIST_UPDATE_SUCCESS, list, }); const updateListFail = (id: string | number, error: AxiosError) => ({ type: LIST_UPDATE_FAIL, id, error, }); const resetListEditor = () => ({ type: LIST_EDITOR_RESET, }); const deleteList = (id: string | number) => (dispatch: AppDispatch, getState: () => RootState) => { if (!isLoggedIn(getState)) return; dispatch(deleteListRequest(id)); api(getState).delete(`/api/v1/lists/${id}`) .then(() => dispatch(deleteListSuccess(id))) .catch(err => dispatch(deleteListFail(id, err))); }; const deleteListRequest = (id: string | number) => ({ type: LIST_DELETE_REQUEST, id, }); const deleteListSuccess = (id: string | number) => ({ type: LIST_DELETE_SUCCESS, id, }); const deleteListFail = (id: string | number, error: AxiosError) => ({ type: LIST_DELETE_FAIL, id, error, }); const fetchListAccounts = (listId: string | number) => (dispatch: AppDispatch, getState: () => RootState) => { if (!isLoggedIn(getState)) return; dispatch(fetchListAccountsRequest(listId)); api(getState).get(`/api/v1/lists/${listId}/accounts`, { params: { limit: 0 } }).then(({ data }) => { dispatch(importFetchedAccounts(data)); dispatch(fetchListAccountsSuccess(listId, data, null)); }).catch(err => dispatch(fetchListAccountsFail(listId, err))); }; const fetchListAccountsRequest = (id: string | number) => ({ type: LIST_ACCOUNTS_FETCH_REQUEST, id, }); const fetchListAccountsSuccess = (id: string | number, accounts: APIEntity[], next: string | null) => ({ type: LIST_ACCOUNTS_FETCH_SUCCESS, id, accounts, next, }); const fetchListAccountsFail = (id: string | number, error: AxiosError) => ({ type: LIST_ACCOUNTS_FETCH_FAIL, id, error, }); const fetchListSuggestions = (q: string) => (dispatch: AppDispatch, getState: () => RootState) => { if (!isLoggedIn(getState)) return; const params = { q, resolve: false, limit: 4, following: true, }; api(getState).get('/api/v1/accounts/search', { params }).then(({ data }) => { dispatch(importFetchedAccounts(data)); dispatch(fetchListSuggestionsReady(q, data)); }).catch(error => toast.showAlertForError(error)); }; const fetchListSuggestionsReady = (query: string, accounts: APIEntity[]) => ({ type: LIST_EDITOR_SUGGESTIONS_READY, query, accounts, }); const clearListSuggestions = () => ({ type: LIST_EDITOR_SUGGESTIONS_CLEAR, }); const changeListSuggestions = (value: string) => ({ type: LIST_EDITOR_SUGGESTIONS_CHANGE, value, }); const addToListEditor = (accountId: string) => (dispatch: AppDispatch, getState: () => RootState) => { dispatch(addToList(getState().listEditor.listId!, accountId)); }; const addToList = (listId: string | number, accountId: string) => (dispatch: AppDispatch, getState: () => RootState) => { if (!isLoggedIn(getState)) return; dispatch(addToListRequest(listId, accountId)); api(getState).post(`/api/v1/lists/${listId}/accounts`, { account_ids: [accountId] }) .then(() => dispatch(addToListSuccess(listId, accountId))) .catch(err => dispatch(addToListFail(listId, accountId, err))); }; const addToListRequest = (listId: string | number, accountId: string) => ({ type: LIST_EDITOR_ADD_REQUEST, listId, accountId, }); const addToListSuccess = (listId: string | number, accountId: string) => ({ type: LIST_EDITOR_ADD_SUCCESS, listId, accountId, }); const addToListFail = (listId: string | number, accountId: string, error: APIEntity) => ({ type: LIST_EDITOR_ADD_FAIL, listId, accountId, error, }); const removeFromListEditor = (accountId: string) => (dispatch: AppDispatch, getState: () => RootState) => { dispatch(removeFromList(getState().listEditor.listId!, accountId)); }; const removeFromList = (listId: string | number, accountId: string) => (dispatch: AppDispatch, getState: () => RootState) => { if (!isLoggedIn(getState)) return; dispatch(removeFromListRequest(listId, accountId)); api(getState).delete(`/api/v1/lists/${listId}/accounts`, { params: { account_ids: [accountId] } }) .then(() => dispatch(removeFromListSuccess(listId, accountId))) .catch(err => dispatch(removeFromListFail(listId, accountId, err))); }; const removeFromListRequest = (listId: string | number, accountId: string) => ({ type: LIST_EDITOR_REMOVE_REQUEST, listId, accountId, }); const removeFromListSuccess = (listId: string | number, accountId: string) => ({ type: LIST_EDITOR_REMOVE_SUCCESS, listId, accountId, }); const removeFromListFail = (listId: string | number, accountId: string, error: AxiosError) => ({ type: LIST_EDITOR_REMOVE_FAIL, listId, accountId, error, }); const resetListAdder = () => ({ type: LIST_ADDER_RESET, }); const setupListAdder = (accountId: string) => (dispatch: AppDispatch, getState: () => RootState) => { dispatch({ type: LIST_ADDER_SETUP, account: getState().accounts.get(accountId), }); dispatch(fetchLists()); dispatch(fetchAccountLists(accountId)); }; const fetchAccountLists = (accountId: string) => (dispatch: AppDispatch, getState: () => RootState) => { if (!isLoggedIn(getState)) return; dispatch(fetchAccountListsRequest(accountId)); api(getState).get(`/api/v1/accounts/${accountId}/lists`) .then(({ data }) => dispatch(fetchAccountListsSuccess(accountId, data))) .catch(err => dispatch(fetchAccountListsFail(accountId, err))); }; const fetchAccountListsRequest = (id: string) => ({ type: LIST_ADDER_LISTS_FETCH_REQUEST, id, }); const fetchAccountListsSuccess = (id: string, lists: APIEntity[]) => ({ type: LIST_ADDER_LISTS_FETCH_SUCCESS, id, lists, }); const fetchAccountListsFail = (id: string, err: AxiosError) => ({ type: LIST_ADDER_LISTS_FETCH_FAIL, id, err, }); const addToListAdder = (listId: string | number) => (dispatch: AppDispatch, getState: () => RootState) => { dispatch(addToList(listId, getState().listAdder.accountId!)); }; const removeFromListAdder = (listId: string | number) => (dispatch: AppDispatch, getState: () => RootState) => { dispatch(removeFromList(listId, getState().listAdder.accountId!)); }; export { LIST_FETCH_REQUEST, LIST_FETCH_SUCCESS, LIST_FETCH_FAIL, LISTS_FETCH_REQUEST, LISTS_FETCH_SUCCESS, LISTS_FETCH_FAIL, LIST_EDITOR_TITLE_CHANGE, LIST_EDITOR_RESET, LIST_EDITOR_SETUP, LIST_CREATE_REQUEST, LIST_CREATE_SUCCESS, LIST_CREATE_FAIL, LIST_UPDATE_REQUEST, LIST_UPDATE_SUCCESS, LIST_UPDATE_FAIL, LIST_DELETE_REQUEST, LIST_DELETE_SUCCESS, LIST_DELETE_FAIL, LIST_ACCOUNTS_FETCH_REQUEST, LIST_ACCOUNTS_FETCH_SUCCESS, LIST_ACCOUNTS_FETCH_FAIL, LIST_EDITOR_SUGGESTIONS_CHANGE, LIST_EDITOR_SUGGESTIONS_READY, LIST_EDITOR_SUGGESTIONS_CLEAR, LIST_EDITOR_ADD_REQUEST, LIST_EDITOR_ADD_SUCCESS, LIST_EDITOR_ADD_FAIL, LIST_EDITOR_REMOVE_REQUEST, LIST_EDITOR_REMOVE_SUCCESS, LIST_EDITOR_REMOVE_FAIL, LIST_ADDER_RESET, LIST_ADDER_SETUP, LIST_ADDER_LISTS_FETCH_REQUEST, LIST_ADDER_LISTS_FETCH_SUCCESS, LIST_ADDER_LISTS_FETCH_FAIL, fetchList, fetchListRequest, fetchListSuccess, fetchListFail, fetchLists, fetchListsRequest, fetchListsSuccess, fetchListsFail, submitListEditor, setupListEditor, changeListEditorTitle, createList, createListRequest, createListSuccess, createListFail, updateList, updateListRequest, updateListSuccess, updateListFail, resetListEditor, deleteList, deleteListRequest, deleteListSuccess, deleteListFail, fetchListAccounts, fetchListAccountsRequest, fetchListAccountsSuccess, fetchListAccountsFail, fetchListSuggestions, fetchListSuggestionsReady, clearListSuggestions, changeListSuggestions, addToListEditor, addToList, addToListRequest, addToListSuccess, addToListFail, removeFromListEditor, removeFromList, removeFromListRequest, removeFromListSuccess, removeFromListFail, resetListAdder, setupListAdder, fetchAccountLists, fetchAccountListsRequest, fetchAccountListsSuccess, fetchAccountListsFail, addToListAdder, removeFromListAdder, };