Frontend: Consistent Message Edited Indicator

This commit is contained in:
ADAMJR 2021-11-03 22:53:29 +00:00
parent 0641cf2e53
commit a415224678
5 changed files with 46 additions and 11 deletions

View File

@ -1,14 +1,16 @@
import MessageBox from '../message-box';
import defaultPatterns from '../../../types/patterns';
import { FunctionComponent } from 'react';
import { useSelector } from 'react-redux';
import { useDispatch, useSelector } from 'react-redux';
import striptags from 'striptags';
import { previewImage } from '../../../store/ui';
interface MessageContentProps {
message: Entity.Message;
}
const MessageContent: FunctionComponent<MessageContentProps> = ({ message }) => {
const dispatch = useDispatch();
const editingMessageId = useSelector((s: Store.AppState) => s.ui.editingMessageId);
const patterns = {
@ -48,13 +50,23 @@ const MessageContent: FunctionComponent<MessageContentProps> = ({ message }) =>
`<img src="${process.env.REACT_APP_CDN_URL}${imageURL}"`).join(''));
const messageHTML =
`${message.content && format(striptags(message.content))}` +
`${message.attachmentURLs?.map(imageURL =>
`<img
style="max-width: 512px"
class="my-2 cursor-pointer"
src="${process.env.REACT_APP_CDN_URL}${imageURL}" />`).join('')
}`;
((message.content) ? format(striptags(message.content)) : '') +
((message.updatedAt && message.content) ?
`<span
class="select-none muted edited text-xs ml-1"
title="${message.updatedAt}">(edited)</span>` : '');
const Attachments = () => (
<>
{message.attachmentURLs?.map(imageURL =>
<img
key={imageURL}
style={{ maxWidth: '512px' }}
className="my-2 cursor-pointer"
onClick={() => dispatch(previewImage(imageURL))}
src={process.env.REACT_APP_CDN_URL + imageURL} />)}
</>
);
return (editingMessageId === message.id)
? <MessageBox
@ -66,9 +78,9 @@ const MessageContent: FunctionComponent<MessageContentProps> = ({ message }) =>
className="normal whitespace-pre-wrap">
<div
dangerouslySetInnerHTML={{ __html: messageHTML }}
className="float-left overflow-auto"
className="overflow-auto"
style={{ maxWidth: '100%' }} />
{message.updatedAt && <span className="select-none muted edited text-xs ml-1">(edited)</span>}
<Attachments />
</div>
</div>;
}

View File

@ -0,0 +1,15 @@
import { useSelector } from 'react-redux';
import Modal from './modal';
const CreateInvite: React.FunctionComponent = () => {
const resource = useSelector((s: Store.AppState) => s.ui.activeResource);
return (resource) ? (
<Modal typeName={'ImagePreview'} className="p-5">
<img src={resource} />
<a className="-mt-2" href={resource} target="_blank">View Original</a>
</Modal>
) : null;
}
export default CreateInvite;

View File

@ -28,7 +28,7 @@ const Modal: React.FunctionComponent<ModalProps> = ({ className, typeName, size,
className={classNames(
`bg-bg-primary overflow-auto fixed outline-none`,
className,
sizeClass[size ?? 'sm']
sizeClass[size ?? 'sm'],
)}
appElement={document.querySelector('#root')!}
isOpen={openModal === typeName}

View File

@ -13,6 +13,9 @@ const slice = createSlice({
delete state.editingMessageId;
},
// only 1 invite is created -> to save data, and stop spam
focusedResource: (state, { payload }) => {
state.activeResource = payload;
},
focusedInvite: (state, { payload }) => {
state.activeInvite = payload;
},
@ -66,6 +69,10 @@ export const openUserProfile = (user: Entity.User) => (dispatch) => {
dispatch(actions.focusedUser(user));
dispatch(actions.openedModal('UserProfile'));
}
export const previewImage = (url: string) => (dispatch) => {
dispatch(actions.focusedResource(url));
dispatch(actions.openedModal('ImagePreview'));
}
export const openDialog = (dialog: Dialog) => () => events.emit('dialog', dialog);

1
types/store.d.ts vendored
View File

@ -39,6 +39,7 @@ declare namespace Store {
openDropdown?: string;
openModal?: string;
activeChannel?: Entity.Channel;
activeResource?: string;
activeGuild?: Entity.Guild;
activeInvite?: Entity.Invite;
activeUser?: Entity.User;