diff --git a/src/redux/messages/api.ts b/src/redux/messages/api.ts index ff69487d..2e224ab3 100644 --- a/src/redux/messages/api.ts +++ b/src/redux/messages/api.ts @@ -1,48 +1,29 @@ -import { IMessage, IResultWithStatus } from '~/redux/types'; -import { api, configWithToken, errorMiddleware, resultMiddleware } from '~/utils/api'; +import { api, cleanResult } from '~/utils/api'; import { API } from '~/constants/api'; +import { + ApiDeleteMessageRequest, + ApiDeleteMessageResult, + ApiGetUserMessagesRequest, + ApiGetUserMessagesResponse, + ApiSendMessageRequest, + ApiSendMessageResult, +} from '~/redux/messages/types'; -export const apiMessagesGetUserMessages = ({ - access, - username, - after, - before, -}: { - access: string; - username: string; - after?: string; - before?: string; -}): Promise> => +export const apiGetUserMessages = ({ username, after, before }: ApiGetUserMessagesRequest) => api - .get(API.USER.MESSAGES(username), configWithToken(access, { params: { after, before } })) - .then(resultMiddleware) - .catch(errorMiddleware); + .get(API.USER.MESSAGES(username), { + params: { after, before }, + }) + .then(cleanResult); -export const apiMessagesSendMessage = ({ - access, - username, - message, -}): Promise> => +export const apiSendMessage = ({ username, message }: ApiSendMessageRequest) => api - .post(API.USER.MESSAGE_SEND(username), { message }, configWithToken(access)) - .then(resultMiddleware) - .catch(errorMiddleware); + .post(API.USER.MESSAGE_SEND(username), { message }) + .then(cleanResult); -export const apiMessagesDeleteMessage = ({ - access, - username, - id, - is_locked, -}: { - access: string; - username: string; - id: number; - is_locked: boolean; -}): Promise> => +export const apiDeleteMessage = ({ username, id, is_locked }: ApiDeleteMessageRequest) => api - .delete( - API.USER.MESSAGE_DELETE(username, id), - configWithToken(access, { params: { is_locked } }) - ) - .then(resultMiddleware) - .catch(errorMiddleware); + .delete(API.USER.MESSAGE_DELETE(username, id), { + params: { is_locked }, + }) + .then(cleanResult); diff --git a/src/redux/messages/sagas.ts b/src/redux/messages/sagas.ts index cbce096d..3f9d8bfc 100644 --- a/src/redux/messages/sagas.ts +++ b/src/redux/messages/sagas.ts @@ -5,14 +5,9 @@ import { selectAuthProfileUsername, selectAuthUpdates, } from '~/redux/auth/selectors'; -import { - apiMessagesDeleteMessage, - apiMessagesGetUserMessages, - apiMessagesSendMessage, -} from '~/redux/messages/api'; +import { apiDeleteMessage, apiGetUserMessages, apiSendMessage } from '~/redux/messages/api'; import { ERRORS } from '~/constants/errors'; import { IMessageNotification, Unwrap } from '~/redux/types'; -import { wrap } from '~/redux/auth/sagas'; import { messagesDeleteMessage, messagesGetMessages, @@ -25,185 +20,188 @@ import { selectMessages } from '~/redux/messages/selectors'; import { sortCreatedAtDesc } from '~/utils/date'; function* getMessages({ username }: ReturnType) { - const { messages }: ReturnType = yield select(selectMessages); + try { + const { messages }: ReturnType = yield select(selectMessages); - yield put( - messagesSet({ - is_loading_messages: true, - messages: - messages && - messages.length > 0 && - (messages[0].to.username === username || messages[0].from.username === username) - ? messages - : [], - }) - ); - - const { error, data }: Unwrap = yield call( - wrap, - apiMessagesGetUserMessages, - { username } - ); - - if (error || !data.messages) { - return yield put( + yield put( messagesSet({ - is_loading_messages: false, - error: ERRORS.EMPTY_RESPONSE, + is_loading_messages: true, + messages: + messages && + messages.length > 0 && + (messages[0].to.username === username || messages[0].from.username === username) + ? messages + : [], }) ); - } - yield put(messagesSet({ is_loading_messages: false, messages: data.messages })); + const data: Unwrap = yield call(apiGetUserMessages, { + username, + }); - const { notifications }: ReturnType = yield select(selectAuthUpdates); + yield put(messagesSet({ is_loading_messages: false, messages: data.messages })); - // clear viewed message from notifcation list - const filtered = notifications.filter( - notification => - notification.type !== 'message' || - (notification as IMessageNotification).content.from.username !== username - ); + const { notifications }: ReturnType = yield select(selectAuthUpdates); - if (filtered.length !== notifications.length) { - yield put(authSetUpdates({ notifications: filtered })); + // clear viewed message from notifcation list + const filtered = notifications.filter( + notification => + notification.type !== 'message' || + (notification as IMessageNotification)?.content?.from?.username !== username + ); + + if (filtered.length !== notifications.length) { + yield put(authSetUpdates({ notifications: filtered })); + } + } catch (error) { + messagesSet({ + error: error || ERRORS.EMPTY_RESPONSE, + }); + } finally { + yield put( + messagesSet({ + is_loading_messages: false, + }) + ); } } function* sendMessage({ message, onSuccess }: ReturnType) { - const username: ReturnType = yield select( - selectAuthProfileUsername - ); + try { + const username: ReturnType = yield select( + selectAuthProfileUsername + ); - if (!username) return; + if (!username) return; - yield put(messagesSet({ is_sending_messages: true, error: null })); + yield put(messagesSet({ is_sending_messages: true, error: '' })); - const { error, data }: Unwrap = yield call( - wrap, - apiMessagesSendMessage, - { + const data: Unwrap = yield call(apiSendMessage, { username, message, + }); + + const { user }: ReturnType = yield select(selectAuthProfile); + + if (user?.username !== username) { + return yield put(messagesSet({ is_sending_messages: false })); } - ); - if (error || !data.message) { - return yield put( - messagesSet({ - is_sending_messages: false, - error: error || ERRORS.EMPTY_RESPONSE, - }) - ); - } + const { messages }: ReturnType = yield select(selectMessages); - const { user }: ReturnType = yield select(selectAuthProfile); + if (message.id && message.id > 0) { + // modified + yield put( + messagesSet({ + is_sending_messages: false, + messages: messages.map(item => (item.id === message.id ? data.message : item)), + }) + ); + } else { + // created + yield put( + messagesSet({ + is_sending_messages: false, + messages: [data.message, ...messages], + }) + ); + } - if (user.username !== username) { - return yield put(messagesSet({ is_sending_messages: false })); - } - - const { messages }: ReturnType = yield select(selectMessages); - - if (message.id > 0) { - // modified + onSuccess(); + } catch (error) { + messagesSet({ + error: error || ERRORS.EMPTY_RESPONSE, + }); + } finally { yield put( messagesSet({ - is_sending_messages: false, - messages: messages.map(item => (item.id === message.id ? data.message : item)), - }) - ); - } else { - // created - yield put( - messagesSet({ - is_sending_messages: false, - messages: [data.message, ...messages], + is_loading_messages: false, }) ); } - - onSuccess(); } function* deleteMessage({ id, is_locked }: ReturnType) { - const username: ReturnType = yield select( - selectAuthProfileUsername - ); + try { + const username: ReturnType = yield select( + selectAuthProfileUsername + ); - if (!username) return; + if (!username) return; - yield put(messagesSet({ is_sending_messages: true, error: null })); + yield put(messagesSet({ is_sending_messages: true, error: '' })); - const { error, data }: Unwrap = yield call( - wrap, - apiMessagesDeleteMessage, - { + const data: Unwrap = yield call(apiDeleteMessage, { username, id, is_locked, - } - ); + }); - if (error || !data.message) { - return yield put( + const currentUsername: ReturnType = yield select( + selectAuthProfileUsername + ); + + if (currentUsername !== username) { + return yield put(messagesSet({ is_sending_messages: false })); + } + + const { messages }: ReturnType = yield select(selectMessages); + + yield put( messagesSet({ is_sending_messages: false, + messages: messages.map(item => (item.id === id ? data.message : item)), + }) + ); + } catch (error) { + messagesSet({ + error: error || ERRORS.EMPTY_RESPONSE, + }); + } finally { + yield put( + messagesSet({ + is_loading_messages: false, }) ); } - - const currentUsername: ReturnType = yield select( - selectAuthProfileUsername - ); - - if (currentUsername !== username) { - return yield put(messagesSet({ is_sending_messages: false })); - } - - const { messages }: ReturnType = yield select(selectMessages); - - yield put( - messagesSet({ - is_sending_messages: false, - messages: messages.map(item => (item.id === id ? data.message : item)), - }) - ); } function* refreshMessages({}: ReturnType) { - const username: ReturnType = yield select( - selectAuthProfileUsername - ); + try { + const username: ReturnType = yield select( + selectAuthProfileUsername + ); - if (!username) return; + if (!username) return; - const { messages }: ReturnType = yield select(selectMessages); + const { messages }: ReturnType = yield select(selectMessages); - yield put(messagesSet({ is_loading_messages: true })); + yield put(messagesSet({ is_loading_messages: true })); - const after = messages.length > 0 ? messages[0].created_at : undefined; + const after = messages.length > 0 ? messages[0].created_at : undefined; - const { data, error }: Unwrap = yield call( - wrap, - apiMessagesGetUserMessages, - { username, after } - ); + const data: Unwrap = yield call(apiGetUserMessages, { + username, + after, + }); - yield put(messagesSet({ is_loading_messages: false })); + yield put(messagesSet({ is_loading_messages: false })); - if (error) { - return yield put( + if (!data.messages || !data.messages.length) return; + + const newMessages = [...data.messages, ...messages].sort(sortCreatedAtDesc); + yield put(messagesSet({ messages: newMessages })); + } catch (error) { + messagesSet({ + error: error || ERRORS.EMPTY_RESPONSE, + }); + } finally { + yield put( messagesSet({ - error: error || ERRORS.EMPTY_RESPONSE, + is_loading_messages: false, }) ); } - - if (!data.messages || !data.messages.length) return; - - const newMessages = [...data.messages, ...messages].sort(sortCreatedAtDesc); - yield put(messagesSet({ messages: newMessages })); } export default function*() { diff --git a/src/redux/messages/types.ts b/src/redux/messages/types.ts new file mode 100644 index 00000000..519e7057 --- /dev/null +++ b/src/redux/messages/types.ts @@ -0,0 +1,26 @@ +import { IMessage } from '~/redux/types'; + +export type ApiGetUserMessagesRequest = { + username: string; + after?: string; + before?: string; +}; +export type ApiGetUserMessagesResponse = { messages: IMessage[] }; + +export type ApiSendMessageRequest = { + username: string; + message: Partial; +}; +export type ApiSendMessageResult = { + message: IMessage; +}; + +export type ApiDeleteMessageRequest = { + username: string; + id: number; + is_locked: boolean; +}; + +export type ApiDeleteMessageResult = { + message: IMessage; +};