mirror of
https://github.com/muerwre/vault-frontend.git
synced 2025-04-25 04:46:40 +07:00
getting messages diff
This commit is contained in:
parent
e1117a0d91
commit
d935e9de42
8 changed files with 87 additions and 17 deletions
|
@ -26,7 +26,7 @@ type IProps = ReturnType<typeof mapStateToProps> &
|
||||||
};
|
};
|
||||||
|
|
||||||
const MessageFormUnconnected: FC<IProps> = ({
|
const MessageFormUnconnected: FC<IProps> = ({
|
||||||
messages: { is_sending_messages, is_loading_messages, messages_error },
|
messages: { is_sending_messages, is_loading_messages, error },
|
||||||
messagesSendMessage,
|
messagesSendMessage,
|
||||||
|
|
||||||
id = 0,
|
id = 0,
|
||||||
|
@ -57,8 +57,8 @@ const MessageFormUnconnected: FC<IProps> = ({
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.wrap}>
|
<div className={styles.wrap}>
|
||||||
{messages_error && <div className={styles.error}>{ERROR_LITERAL[messages_error]}</div>}
|
{error && <div className={styles.error}>{ERROR_LITERAL[error]}</div>}
|
||||||
{is_loading_messages && !messages_error && (
|
{is_loading_messages && !error && (
|
||||||
<Group className={styles.loader} horizontal>
|
<Group className={styles.loader} horizontal>
|
||||||
<LoaderCircle size={20} />
|
<LoaderCircle size={20} />
|
||||||
<div>Обновляем</div>
|
<div>Обновляем</div>
|
||||||
|
|
|
@ -16,6 +16,7 @@ const mapStateToProps = state => ({
|
||||||
|
|
||||||
const mapDispatchToProps = {
|
const mapDispatchToProps = {
|
||||||
messagesGetMessages: AUTH_ACTIONS.messagesGetMessages,
|
messagesGetMessages: AUTH_ACTIONS.messagesGetMessages,
|
||||||
|
messagesRefreshMessages: AUTH_ACTIONS.messagesRefreshMessages,
|
||||||
messagesDeleteMessage: AUTH_ACTIONS.messagesDeleteMessage,
|
messagesDeleteMessage: AUTH_ACTIONS.messagesDeleteMessage,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -27,6 +28,7 @@ const ProfileMessagesUnconnected: FC<IProps> = ({
|
||||||
user: { id },
|
user: { id },
|
||||||
messagesGetMessages,
|
messagesGetMessages,
|
||||||
messagesDeleteMessage,
|
messagesDeleteMessage,
|
||||||
|
messagesRefreshMessages,
|
||||||
}) => {
|
}) => {
|
||||||
const wasAtBottom = useRef(true);
|
const wasAtBottom = useRef(true);
|
||||||
const [wrap, setWrap] = useState<HTMLDivElement>(null);
|
const [wrap, setWrap] = useState<HTMLDivElement>(null);
|
||||||
|
@ -48,13 +50,10 @@ const ProfileMessagesUnconnected: FC<IProps> = ({
|
||||||
}, [profile.user]);
|
}, [profile.user]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (profile.is_loading || !profile.user || !profile.user.username || messages.messages_error)
|
const timer = setInterval(messagesRefreshMessages, 20000);
|
||||||
return;
|
|
||||||
|
|
||||||
const timer = setTimeout(() => messagesGetMessages(profile.user.username), 20000);
|
|
||||||
|
|
||||||
return () => clearTimeout(timer);
|
return () => clearTimeout(timer);
|
||||||
}, [profile.user, messages.messages]);
|
}, [messagesRefreshMessages]);
|
||||||
|
|
||||||
const storeRef = useCallback(
|
const storeRef = useCallback(
|
||||||
(div: HTMLDivElement) => {
|
(div: HTMLDivElement) => {
|
||||||
|
|
|
@ -7,6 +7,15 @@ export const messagesGetMessages = (username: string) => ({
|
||||||
username,
|
username,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export const messagesRefreshMessages = () => ({
|
||||||
|
type: MESSAGES_ACTIONS.REFRESH_MESSAGES,
|
||||||
|
});
|
||||||
|
|
||||||
|
export const messagesLoadMoreMessages = (username: string) => ({
|
||||||
|
type: MESSAGES_ACTIONS.LOAD_MORE,
|
||||||
|
username,
|
||||||
|
});
|
||||||
|
|
||||||
export const messagesSendMessage = (message: Partial<IMessage>, onSuccess) => ({
|
export const messagesSendMessage = (message: Partial<IMessage>, onSuccess) => ({
|
||||||
type: MESSAGES_ACTIONS.SEND_MESSAGE,
|
type: MESSAGES_ACTIONS.SEND_MESSAGE,
|
||||||
message,
|
message,
|
||||||
|
|
|
@ -5,9 +5,16 @@ import { API } from '~/constants/api';
|
||||||
export const apiMessagesGetUserMessages = ({
|
export const apiMessagesGetUserMessages = ({
|
||||||
access,
|
access,
|
||||||
username,
|
username,
|
||||||
|
after,
|
||||||
|
before,
|
||||||
|
}: {
|
||||||
|
access: string;
|
||||||
|
username: string;
|
||||||
|
after?: string;
|
||||||
|
before?: string;
|
||||||
}): Promise<IResultWithStatus<{ messages: IMessage[] }>> =>
|
}): Promise<IResultWithStatus<{ messages: IMessage[] }>> =>
|
||||||
api
|
api
|
||||||
.get(API.USER.MESSAGES(username), configWithToken(access))
|
.get(API.USER.MESSAGES(username), configWithToken(access, { params: { after, before } }))
|
||||||
.then(resultMiddleware)
|
.then(resultMiddleware)
|
||||||
.catch(errorMiddleware);
|
.catch(errorMiddleware);
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,8 @@ const p = 'MESSAGES.';
|
||||||
export const MESSAGES_ACTIONS = {
|
export const MESSAGES_ACTIONS = {
|
||||||
SET_MESSAGES: `${p}SET_MESSAGES`,
|
SET_MESSAGES: `${p}SET_MESSAGES`,
|
||||||
GET_MESSAGES: `${p}GET_MESSAGES`,
|
GET_MESSAGES: `${p}GET_MESSAGES`,
|
||||||
|
REFRESH_MESSAGES: `${p}REFRESH_MESSAGES`,
|
||||||
|
LOAD_MORE: `${p}LOAD_MORE`,
|
||||||
SEND_MESSAGE: `${p}SEND_MESSAGE`,
|
SEND_MESSAGE: `${p}SEND_MESSAGE`,
|
||||||
DELETE_MESSAGE: `${p}DELETE_MESSAGE`,
|
DELETE_MESSAGE: `${p}DELETE_MESSAGE`,
|
||||||
};
|
};
|
||||||
|
|
|
@ -6,13 +6,13 @@ export interface IMessagesState {
|
||||||
is_loading_messages: boolean;
|
is_loading_messages: boolean;
|
||||||
is_sending_messages: boolean;
|
is_sending_messages: boolean;
|
||||||
messages: IMessage[];
|
messages: IMessage[];
|
||||||
messages_error: string;
|
error: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
const INITIAL_STATE: IMessagesState = {
|
const INITIAL_STATE: IMessagesState = {
|
||||||
is_loading_messages: true,
|
is_loading_messages: true,
|
||||||
is_sending_messages: false,
|
is_sending_messages: false,
|
||||||
messages_error: null,
|
error: null,
|
||||||
messages: [],
|
messages: [],
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -16,11 +16,13 @@ import { reqWrapper } from '~/redux/auth/sagas';
|
||||||
import {
|
import {
|
||||||
messagesDeleteMessage,
|
messagesDeleteMessage,
|
||||||
messagesGetMessages,
|
messagesGetMessages,
|
||||||
|
messagesRefreshMessages,
|
||||||
messagesSendMessage,
|
messagesSendMessage,
|
||||||
messagesSet,
|
messagesSet,
|
||||||
} from '~/redux/messages/actions';
|
} from '~/redux/messages/actions';
|
||||||
import { MESSAGES_ACTIONS } from '~/redux/messages/constants';
|
import { MESSAGES_ACTIONS } from '~/redux/messages/constants';
|
||||||
import { selectMessages } from '~/redux/messages/selectors';
|
import { selectMessages } from '~/redux/messages/selectors';
|
||||||
|
import { sortCreatedAtDesc } from '~/utils/date';
|
||||||
|
|
||||||
function* getMessages({ username }: ReturnType<typeof messagesGetMessages>) {
|
function* getMessages({ username }: ReturnType<typeof messagesGetMessages>) {
|
||||||
const { messages }: ReturnType<typeof selectMessages> = yield select(selectMessages);
|
const { messages }: ReturnType<typeof selectMessages> = yield select(selectMessages);
|
||||||
|
@ -37,20 +39,27 @@ function* getMessages({ username }: ReturnType<typeof messagesGetMessages>) {
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
const { error, data } = yield call(reqWrapper, apiMessagesGetUserMessages, { username });
|
const {
|
||||||
|
error,
|
||||||
|
data,
|
||||||
|
}: Unwrap<ReturnType<typeof apiMessagesGetUserMessages>> = yield call(
|
||||||
|
reqWrapper,
|
||||||
|
apiMessagesGetUserMessages,
|
||||||
|
{ username }
|
||||||
|
);
|
||||||
|
|
||||||
if (error || !data.messages) {
|
if (error || !data.messages) {
|
||||||
return yield put(
|
return yield put(
|
||||||
messagesSet({
|
messagesSet({
|
||||||
is_loading_messages: false,
|
is_loading_messages: false,
|
||||||
messages_error: ERRORS.EMPTY_RESPONSE,
|
error: ERRORS.EMPTY_RESPONSE,
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
yield put(messagesSet({ is_loading_messages: false, messages: data.messages }));
|
yield put(messagesSet({ is_loading_messages: false, messages: data.messages }));
|
||||||
|
|
||||||
const { notifications } = yield select(selectAuthUpdates);
|
const { notifications }: ReturnType<typeof selectAuthUpdates> = yield select(selectAuthUpdates);
|
||||||
|
|
||||||
// clear viewed message from notifcation list
|
// clear viewed message from notifcation list
|
||||||
const filtered = notifications.filter(
|
const filtered = notifications.filter(
|
||||||
|
@ -71,7 +80,7 @@ function* sendMessage({ message, onSuccess }: ReturnType<typeof messagesSendMess
|
||||||
|
|
||||||
if (!username) return;
|
if (!username) return;
|
||||||
|
|
||||||
yield put(messagesSet({ is_sending_messages: true, messages_error: null }));
|
yield put(messagesSet({ is_sending_messages: true, error: null }));
|
||||||
|
|
||||||
const { error, data }: Unwrap<ReturnType<typeof apiMessagesSendMessage>> = yield call(
|
const { error, data }: Unwrap<ReturnType<typeof apiMessagesSendMessage>> = yield call(
|
||||||
reqWrapper,
|
reqWrapper,
|
||||||
|
@ -86,7 +95,7 @@ function* sendMessage({ message, onSuccess }: ReturnType<typeof messagesSendMess
|
||||||
return yield put(
|
return yield put(
|
||||||
messagesSet({
|
messagesSet({
|
||||||
is_sending_messages: false,
|
is_sending_messages: false,
|
||||||
messages_error: error || ERRORS.EMPTY_RESPONSE,
|
error: error || ERRORS.EMPTY_RESPONSE,
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -127,7 +136,7 @@ function* deleteMessage({ id, is_locked }: ReturnType<typeof messagesDeleteMessa
|
||||||
|
|
||||||
if (!username) return;
|
if (!username) return;
|
||||||
|
|
||||||
yield put(messagesSet({ is_sending_messages: true, messages_error: null }));
|
yield put(messagesSet({ is_sending_messages: true, error: null }));
|
||||||
|
|
||||||
const { error, data }: Unwrap<ReturnType<typeof apiMessagesDeleteMessage>> = yield call(
|
const { error, data }: Unwrap<ReturnType<typeof apiMessagesDeleteMessage>> = yield call(
|
||||||
reqWrapper,
|
reqWrapper,
|
||||||
|
@ -165,8 +174,47 @@ function* deleteMessage({ id, is_locked }: ReturnType<typeof messagesDeleteMessa
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function* refreshMessages({}: ReturnType<typeof messagesRefreshMessages>) {
|
||||||
|
const username: ReturnType<typeof selectAuthProfileUsername> = yield select(
|
||||||
|
selectAuthProfileUsername
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!username) return;
|
||||||
|
|
||||||
|
const { messages }: ReturnType<typeof selectMessages> = yield select(selectMessages);
|
||||||
|
|
||||||
|
yield put(messagesSet({ is_loading_messages: true }));
|
||||||
|
|
||||||
|
const after = messages.length > 0 ? messages[0].created_at : undefined;
|
||||||
|
|
||||||
|
const {
|
||||||
|
data,
|
||||||
|
error,
|
||||||
|
}: Unwrap<ReturnType<typeof apiMessagesGetUserMessages>> = yield call(
|
||||||
|
reqWrapper,
|
||||||
|
apiMessagesGetUserMessages,
|
||||||
|
{ username, after }
|
||||||
|
);
|
||||||
|
|
||||||
|
yield put(messagesSet({ is_loading_messages: false }));
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
return yield put(
|
||||||
|
messagesSet({
|
||||||
|
error: error || ERRORS.EMPTY_RESPONSE,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!data.messages || !data.messages.length) return;
|
||||||
|
|
||||||
|
const newMessages = [...data.messages, ...messages].sort(sortCreatedAtDesc);
|
||||||
|
yield put(messagesSet({ messages: newMessages }));
|
||||||
|
}
|
||||||
|
|
||||||
export default function*() {
|
export default function*() {
|
||||||
yield takeLatest(MESSAGES_ACTIONS.GET_MESSAGES, getMessages);
|
yield takeLatest(MESSAGES_ACTIONS.GET_MESSAGES, getMessages);
|
||||||
yield takeLatest(MESSAGES_ACTIONS.SEND_MESSAGE, sendMessage);
|
yield takeLatest(MESSAGES_ACTIONS.SEND_MESSAGE, sendMessage);
|
||||||
yield takeLatest(MESSAGES_ACTIONS.DELETE_MESSAGE, deleteMessage);
|
yield takeLatest(MESSAGES_ACTIONS.DELETE_MESSAGE, deleteMessage);
|
||||||
|
yield takeLatest(MESSAGES_ACTIONS.REFRESH_MESSAGES, refreshMessages);
|
||||||
}
|
}
|
||||||
|
|
5
src/utils/date.ts
Normal file
5
src/utils/date.ts
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
export const sortCreatedAtAsc = (a, b) =>
|
||||||
|
new Date(a.created_at).getTime() - new Date(b.created_at).getTime();
|
||||||
|
|
||||||
|
export const sortCreatedAtDesc = (a, b) =>
|
||||||
|
new Date(b.created_at).getTime() - new Date(a.created_at).getTime();
|
Loading…
Add table
Add a link
Reference in a new issue