Replace confirm and prompt with custom dialogs (#500)

This commit is contained in:
Ajay Bura 2022-04-25 20:21:21 +05:30 committed by GitHub
parent 3da9b70632
commit d760be58c3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
14 changed files with 232 additions and 50 deletions

View file

@ -0,0 +1,58 @@
import React from 'react';
import PropTypes from 'prop-types';
import './ConfirmDialog.scss';
import { openReusableDialog } from '../../../client/action/navigation';
import Text from '../../atoms/text/Text';
import Button from '../../atoms/button/Button';
function ConfirmDialog({
desc, actionTitle, actionType, onComplete,
}) {
return (
<div className="confirm-dialog">
<Text>{desc}</Text>
<div className="confirm-dialog__btn">
<Button variant={actionType} onClick={() => onComplete(true)}>{actionTitle}</Button>
<Button onClick={() => onComplete(false)}>Cancel</Button>
</div>
</div>
);
}
ConfirmDialog.propTypes = {
desc: PropTypes.string.isRequired,
actionTitle: PropTypes.string.isRequired,
actionType: PropTypes.oneOf(['primary', 'positive', 'danger', 'caution']).isRequired,
onComplete: PropTypes.func.isRequired,
};
/**
* @param {string} title title of confirm dialog
* @param {string} desc description of confirm dialog
* @param {string} actionTitle title of main action to take
* @param {'primary' | 'positive' | 'danger' | 'caution'} actionType type of action. default=primary
* @return {Promise<boolean>} does it get's confirmed or not
*/
// eslint-disable-next-line import/prefer-default-export
export const confirmDialog = (title, desc, actionTitle, actionType = 'primary') => new Promise((resolve) => {
let isCompleted = false;
openReusableDialog(
<Text variant="s1" weight="medium">{title}</Text>,
(requestClose) => (
<ConfirmDialog
desc={desc}
actionTitle={actionTitle}
actionType={actionType}
onComplete={(isConfirmed) => {
isCompleted = true;
resolve(isConfirmed);
requestClose();
}}
/>
),
() => {
if (!isCompleted) resolve(false);
},
);
});

View file

@ -0,0 +1,11 @@
.confirm-dialog {
padding: var(--sp-normal);
& > .text {
padding-bottom: var(--sp-normal);
}
&__btn {
display: flex;
gap: var(--sp-normal);
}
}

View file

@ -36,6 +36,8 @@ import TickMarkIC from '../../../../public/res/ic/outlined/tick-mark.svg';
import CmdIC from '../../../../public/res/ic/outlined/cmd.svg';
import BinIC from '../../../../public/res/ic/outlined/bin.svg';
import { confirmDialog } from '../confirm-dialog/ConfirmDialog';
function PlaceholderMessage() {
return (
<div className="ph-msg">
@ -546,10 +548,15 @@ const MessageOptions = React.memo(({
<MenuItem
variant="danger"
iconSrc={BinIC}
onClick={() => {
if (window.confirm('Are you sure that you want to delete this event?')) {
redactEvent(roomId, mEvent.getId());
}
onClick={async () => {
const isConfirmed = await confirmDialog(
'Delete message',
'Are you sure that you want to delete this message?',
'Delete',
'danger',
);
if (!isConfirmed) return;
redactEvent(roomId, mEvent.getId());
}}
>
Delete

View file

@ -8,6 +8,8 @@ import Text from '../../atoms/text/Text';
import Toggle from '../../atoms/button/Toggle';
import SettingTile from '../setting-tile/SettingTile';
import { confirmDialog } from '../confirm-dialog/ConfirmDialog';
function RoomEncryption({ roomId }) {
const mx = initMatrix.matrixClient;
const room = mx.getRoom(roomId);
@ -15,17 +17,20 @@ function RoomEncryption({ roomId }) {
const [isEncrypted, setIsEncrypted] = useState(encryptionEvents.length > 0);
const canEnableEncryption = room.currentState.maySendStateEvent('m.room.encryption', mx.getUserId());
const handleEncryptionEnable = () => {
const handleEncryptionEnable = async () => {
const joinRule = room.getJoinRule();
const confirmMsg1 = 'It is not recommended to add encryption in public room. Anyone can find and join public rooms, so anyone can read messages in them.';
const confirmMsg2 = 'Once enabled, encryption for a room cannot be disabled. Messages sent in an encrypted room cannot be seen by the server, only by the participants of the room. Enabling encryption may prevent many bots and bridges from working correctly';
if (joinRule === 'public' ? confirm(confirmMsg1) : true) {
if (confirm(confirmMsg2)) {
setIsEncrypted(true);
mx.sendStateEvent(roomId, 'm.room.encryption', {
algorithm: 'm.megolm.v1.aes-sha2',
});
}
const isConfirmed1 = (joinRule === 'public')
? await confirmDialog('Enable encryption', confirmMsg1, 'Continue', 'caution')
: true;
if (!isConfirmed1) return;
if (await confirmDialog('Enable encryption', confirmMsg2, 'Enable', 'caution')) {
setIsEncrypted(true);
mx.sendStateEvent(roomId, 'm.room.encryption', {
algorithm: 'm.megolm.v1.aes-sha2',
});
}
};

View file

@ -4,7 +4,7 @@ import PropTypes from 'prop-types';
import { twemojify } from '../../../util/twemojify';
import initMatrix from '../../../client/initMatrix';
import { openInviteUser, openNavigation } from '../../../client/action/navigation';
import { openInviteUser } from '../../../client/action/navigation';
import * as roomActions from '../../../client/action/room';
import { markAsRead } from '../../../client/action/notifications';
@ -15,6 +15,8 @@ import TickMarkIC from '../../../../public/res/ic/outlined/tick-mark.svg';
import AddUserIC from '../../../../public/res/ic/outlined/add-user.svg';
import LeaveArrowIC from '../../../../public/res/ic/outlined/leave-arrow.svg';
import { confirmDialog } from '../confirm-dialog/ConfirmDialog';
function RoomOptions({ roomId, afterOptionSelect }) {
const mx = initMatrix.matrixClient;
const room = mx.getRoom(roomId);
@ -29,12 +31,16 @@ function RoomOptions({ roomId, afterOptionSelect }) {
openInviteUser(roomId);
afterOptionSelect();
};
const handleLeaveClick = () => {
if (confirm('Are you sure that you want to leave this room?')) {
roomActions.leave(roomId);
afterOptionSelect();
openNavigation();
}
const handleLeaveClick = async () => {
afterOptionSelect();
const isConfirmed = await confirmDialog(
'Leave room',
`Are you sure that you want to leave "${room.name}" room?`,
'Leave',
'danger',
);
if (!isConfirmed) return;
roomActions.leave(roomId);
};
return (

View file

@ -19,6 +19,7 @@ import PencilIC from '../../../../public/res/ic/outlined/pencil.svg';
import { useStore } from '../../hooks/useStore';
import { useForceUpdate } from '../../hooks/useForceUpdate';
import { confirmDialog } from '../confirm-dialog/ConfirmDialog';
function RoomProfile({ roomId }) {
const isMountStore = useStore();
@ -117,7 +118,13 @@ function RoomProfile({ roomId }) {
const handleAvatarUpload = async (url) => {
if (url === null) {
if (confirm('Are you sure that you want to remove room avatar?')) {
const isConfirmed = await confirmDialog(
'Remove avatar',
'Are you sure that you want to remove room avatar?',
'Remove',
'caution',
);
if (isConfirmed) {
await mx.sendStateEvent(roomId, 'm.room.avatar', { url }, '');
}
} else await mx.sendStateEvent(roomId, 'm.room.avatar', { url }, '');

View file

@ -24,6 +24,8 @@ import LeaveArrowIC from '../../../../public/res/ic/outlined/leave-arrow.svg';
import PinIC from '../../../../public/res/ic/outlined/pin.svg';
import PinFilledIC from '../../../../public/res/ic/filled/pin.svg';
import { confirmDialog } from '../confirm-dialog/ConfirmDialog';
function SpaceOptions({ roomId, afterOptionSelect }) {
const mx = initMatrix.matrixClient;
const room = mx.getRoom(roomId);
@ -54,11 +56,16 @@ function SpaceOptions({ roomId, afterOptionSelect }) {
afterOptionSelect();
};
const handleLeaveClick = () => {
if (confirm('Are you sure that you want to leave this space?')) {
leave(roomId);
afterOptionSelect();
}
const handleLeaveClick = async () => {
afterOptionSelect();
const isConfirmed = await confirmDialog(
'Leave space',
`Are you sure that you want to leave "${room.name}" space?`,
'Leave',
'danger',
);
if (!isConfirmed) return;
leave(roomId);
};
return (