Added RoomOptions component (#25)
This commit is contained in:
parent
652f8227b5
commit
80551124f1
11 changed files with 322 additions and 3 deletions
12
public/res/ic/outlined/bell-off.svg
Normal file
12
public/res/ic/outlined/bell-off.svg
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Generator: Adobe Illustrator 18.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||||
|
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||||
|
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||||
|
viewBox="0 0 24 24" enable-background="new 0 0 24 24" xml:space="preserve">
|
||||||
|
<g>
|
||||||
|
<path d="M12,22c1.1,0,2-0.9,2-2h-4C10,21.1,10.9,22,12,22z"/>
|
||||||
|
<path d="M20.1,18.1L20.1,18.1L16,14L9.2,7.2L7.8,5.8L5.9,3.9L4.5,5.3l2.1,2.1C6.2,8.2,6,9.1,6,10v6H4v2h13.2l1.5,1.5L20.1,18.1z
|
||||||
|
M8,16v-6c0-0.4,0.1-0.7,0.1-1l7,7H8z"/>
|
||||||
|
<path d="M12,6c2.2,0,4,1.8,4,4v1.2l2,2V10c0-3-2.2-5.4-5-5.9V3h-2v1.1c-0.6,0.1-1.1,0.3-1.6,0.5L11,6.1C11.3,6.1,11.6,6,12,6z"/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 810 B |
13
public/res/ic/outlined/bell-ping.svg
Normal file
13
public/res/ic/outlined/bell-ping.svg
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Generator: Adobe Illustrator 18.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||||
|
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||||
|
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||||
|
viewBox="0 0 24 24" enable-background="new 0 0 24 24" xml:space="preserve">
|
||||||
|
<g>
|
||||||
|
<circle cx="17" cy="8" r="3"/>
|
||||||
|
<path d="M12,22c1.1,0,2-0.9,2-2h-4C10,21.1,10.9,22,12,22z"/>
|
||||||
|
<path d="M18,12.9C17.7,13,17.3,13,17,13s-0.7,0-1-0.1V16H8v-6c0-2.2,1.8-4,4-4c0.1,0,0.3,0,0.4,0c0.3-0.7,0.7-1.3,1.3-1.8
|
||||||
|
c-0.2-0.1-0.5-0.1-0.7-0.2V3h-2v1.1C8.2,4.6,6,7,6,10v6H4v2h16v-2h-2V12.9z"/>
|
||||||
|
<path d="M6.3,4.3L4.9,2.9C3.1,4.7,2,7.2,2,10h2C4,7.8,4.9,5.8,6.3,4.3z"/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 819 B |
12
public/res/ic/outlined/bell-ring.svg
Normal file
12
public/res/ic/outlined/bell-ring.svg
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Generator: Adobe Illustrator 18.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||||
|
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||||
|
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||||
|
viewBox="0 0 24 24" enable-background="new 0 0 24 24" xml:space="preserve">
|
||||||
|
<g>
|
||||||
|
<path d="M12,22c1.1,0,2-0.9,2-2h-4C10,21.1,10.9,22,12,22z"/>
|
||||||
|
<path d="M18,10c0-3-2.2-5.4-5-5.9V3h-2v1.1C8.2,4.6,6,7,6,10v6H4v2h16v-2h-2V10z M16,16H8v-6c0-2.2,1.8-4,4-4s4,1.8,4,4V16z"/>
|
||||||
|
<path d="M6.3,4.3L4.9,2.9C3.1,4.7,2,7.2,2,10h2C4,7.8,4.9,5.8,6.3,4.3z"/>
|
||||||
|
<path d="M19.1,2.9l-1.4,1.4C19.1,5.8,20,7.8,20,10h2C22,7.2,20.9,4.7,19.1,2.9z"/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 796 B |
|
@ -4,8 +4,7 @@
|
||||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||||
viewBox="0 0 24 24" enable-background="new 0 0 24 24" xml:space="preserve">
|
viewBox="0 0 24 24" enable-background="new 0 0 24 24" xml:space="preserve">
|
||||||
<g>
|
<g>
|
||||||
<path d="M12,4c2.8,0,5,2.2,5,5v4v0.8l0.6,0.6l0.6,0.6H5.8l0.6-0.6L7,13.8V13V9C7,6.2,9.2,4,12,4 M12,2C8.1,2,5,5.1,5,9v4l-2,2v2h18
|
<path d="M12,22c1.1,0,2-0.9,2-2h-4C10,21.1,10.9,22,12,22z"/>
|
||||||
v-2l-2-2V9C19,5.1,15.9,2,12,2L12,2z"/>
|
<path d="M18,16v-6c0-3-2.2-5.4-5-5.9V3h-2v1.1C8.2,4.6,6,7,6,10v6H4v2h16v-2H18z M16,16H8v-6c0-2.2,1.8-4,4-4s4,1.8,4,4V16z"/>
|
||||||
<path d="M9,19c0,1.7,1.3,3,3,3s3-1.3,3-3H9z"/>
|
|
||||||
</g>
|
</g>
|
||||||
</svg>
|
</svg>
|
||||||
|
|
Before Width: | Height: | Size: 671 B After Width: | Height: | Size: 640 B |
229
src/app/organisms/room-optons/RoomOptions.jsx
Normal file
229
src/app/organisms/room-optons/RoomOptions.jsx
Normal file
|
@ -0,0 +1,229 @@
|
||||||
|
import React, { useState, useEffect, useRef } from 'react';
|
||||||
|
import './RoomOptions.scss';
|
||||||
|
|
||||||
|
import initMatrix from '../../../client/initMatrix';
|
||||||
|
import cons from '../../../client/state/cons';
|
||||||
|
import navigation from '../../../client/state/navigation';
|
||||||
|
import { openInviteUser } from '../../../client/action/navigation';
|
||||||
|
import * as roomActions from '../../../client/action/room';
|
||||||
|
|
||||||
|
import ContextMenu, { MenuHeader, MenuItem } from '../../atoms/context-menu/ContextMenu';
|
||||||
|
|
||||||
|
import BellIC from '../../../../public/res/ic/outlined/bell.svg';
|
||||||
|
import BellRingIC from '../../../../public/res/ic/outlined/bell-ring.svg';
|
||||||
|
import BellPingIC from '../../../../public/res/ic/outlined/bell-ping.svg';
|
||||||
|
import BellOffIC from '../../../../public/res/ic/outlined/bell-off.svg';
|
||||||
|
import AddUserIC from '../../../../public/res/ic/outlined/add-user.svg';
|
||||||
|
import LeaveArrowIC from '../../../../public/res/ic/outlined/leave-arrow.svg';
|
||||||
|
|
||||||
|
function getNotifState(roomId) {
|
||||||
|
const mx = initMatrix.matrixClient;
|
||||||
|
const pushRule = mx.getRoomPushRule('global', roomId);
|
||||||
|
|
||||||
|
if (typeof pushRule === 'undefined') {
|
||||||
|
const overridePushRules = mx.getAccountData('m.push_rules')?.getContent()?.global?.override;
|
||||||
|
if (typeof overridePushRules === 'undefined') return 0;
|
||||||
|
|
||||||
|
const isMuteOverride = overridePushRules.find((rule) => (
|
||||||
|
rule.rule_id === roomId
|
||||||
|
&& rule.actions[0] === 'dont_notify'
|
||||||
|
&& rule.conditions[0].kind === 'event_match'
|
||||||
|
));
|
||||||
|
|
||||||
|
return isMuteOverride ? cons.notifs.MUTE : cons.notifs.DEFAULT;
|
||||||
|
}
|
||||||
|
if (pushRule.actions[0] === 'notify') return cons.notifs.ALL_MESSAGES;
|
||||||
|
return cons.notifs.MENTIONS_AND_KEYWORDS;
|
||||||
|
}
|
||||||
|
|
||||||
|
function setRoomNotifMute(roomId) {
|
||||||
|
const mx = initMatrix.matrixClient;
|
||||||
|
const roomPushRule = mx.getRoomPushRule('global', roomId);
|
||||||
|
|
||||||
|
const promises = [];
|
||||||
|
if (roomPushRule) {
|
||||||
|
promises.push(mx.deletePushRule('global', 'room', roomPushRule.rule_id));
|
||||||
|
}
|
||||||
|
|
||||||
|
promises.push(mx.addPushRule('global', 'override', roomId, {
|
||||||
|
conditions: [
|
||||||
|
{
|
||||||
|
kind: 'event_match',
|
||||||
|
key: 'room_id',
|
||||||
|
pattern: roomId,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
actions: [
|
||||||
|
'dont_notify',
|
||||||
|
],
|
||||||
|
}));
|
||||||
|
|
||||||
|
return Promise.all(promises);
|
||||||
|
}
|
||||||
|
|
||||||
|
function setRoomNotifsState(newState, roomId) {
|
||||||
|
const mx = initMatrix.matrixClient;
|
||||||
|
const promises = [];
|
||||||
|
|
||||||
|
const oldState = getNotifState(roomId);
|
||||||
|
if (oldState === cons.notifs.MUTE) {
|
||||||
|
promises.push(mx.deletePushRule('global', 'override', roomId));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (newState === cons.notifs.DEFAULT) {
|
||||||
|
const roomPushRule = mx.getRoomPushRule('global', roomId);
|
||||||
|
if (roomPushRule) {
|
||||||
|
promises.push(mx.deletePushRule('global', 'room', roomPushRule.rule_id));
|
||||||
|
}
|
||||||
|
return Promise.all(promises);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (newState === cons.notifs.MENTIONS_AND_KEYWORDS) {
|
||||||
|
promises.push(mx.addPushRule('global', 'room', roomId, {
|
||||||
|
actions: [
|
||||||
|
'dont_notify',
|
||||||
|
],
|
||||||
|
}));
|
||||||
|
promises.push(mx.setPushRuleEnabled('global', 'room', roomId, true));
|
||||||
|
return Promise.all(promises);
|
||||||
|
}
|
||||||
|
|
||||||
|
// cons.notifs.ALL_MESSAGES
|
||||||
|
promises.push(mx.addPushRule('global', 'room', roomId, {
|
||||||
|
actions: [
|
||||||
|
'notify',
|
||||||
|
{
|
||||||
|
set_tweak: 'sound',
|
||||||
|
value: 'default',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}));
|
||||||
|
|
||||||
|
promises.push(mx.setPushRuleEnabled('global', 'room', roomId, true));
|
||||||
|
|
||||||
|
return Promise.all(promises);
|
||||||
|
}
|
||||||
|
|
||||||
|
function setRoomNotifPushRule(notifState, roomId) {
|
||||||
|
if (notifState === cons.notifs.MUTE) {
|
||||||
|
setRoomNotifMute(roomId);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
setRoomNotifsState(notifState, roomId);
|
||||||
|
}
|
||||||
|
|
||||||
|
let isRoomOptionVisible = false;
|
||||||
|
let roomId = null;
|
||||||
|
function RoomOptions() {
|
||||||
|
const openerRef = useRef(null);
|
||||||
|
const [notifState, setNotifState] = useState(cons.notifs.DEFAULT);
|
||||||
|
|
||||||
|
function openRoomOptions(cords, rId) {
|
||||||
|
if (roomId !== null || isRoomOptionVisible) {
|
||||||
|
roomId = null;
|
||||||
|
if (cords.detail === 0) openerRef.current.click();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
openerRef.current.style.transform = `translate(${cords.x}px, ${cords.y}px)`;
|
||||||
|
roomId = rId;
|
||||||
|
setNotifState(getNotifState(roomId));
|
||||||
|
openerRef.current.click();
|
||||||
|
}
|
||||||
|
|
||||||
|
function afterRoomOptionsToggle(isVisible) {
|
||||||
|
isRoomOptionVisible = isVisible;
|
||||||
|
if (!isVisible) {
|
||||||
|
setTimeout(() => {
|
||||||
|
if (!isRoomOptionVisible) roomId = null;
|
||||||
|
}, 500);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
navigation.on(cons.events.navigation.ROOMOPTIONS_OPENED, openRoomOptions);
|
||||||
|
return () => {
|
||||||
|
navigation.on(cons.events.navigation.ROOMOPTIONS_OPENED, openRoomOptions);
|
||||||
|
};
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const handleInviteClick = () => openInviteUser(roomId);
|
||||||
|
const handleLeaveClick = () => {
|
||||||
|
if (confirm('Are you really want to leave this room?')) roomActions.leave(roomId);
|
||||||
|
};
|
||||||
|
|
||||||
|
function setNotif(nState, currentNState) {
|
||||||
|
if (nState === currentNState) return;
|
||||||
|
setRoomNotifPushRule(nState, roomId);
|
||||||
|
setNotifState(nState);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ContextMenu
|
||||||
|
afterToggle={afterRoomOptionsToggle}
|
||||||
|
maxWidth={298}
|
||||||
|
content={(toggleMenu) => (
|
||||||
|
<>
|
||||||
|
<MenuHeader>{`Options for ${initMatrix.matrixClient.getRoom(roomId)?.name}`}</MenuHeader>
|
||||||
|
<MenuItem
|
||||||
|
iconSrc={AddUserIC}
|
||||||
|
onClick={() => {
|
||||||
|
handleInviteClick(); toggleMenu();
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Invite
|
||||||
|
</MenuItem>
|
||||||
|
<MenuItem iconSrc={LeaveArrowIC} variant="danger" onClick={handleLeaveClick}>Leave</MenuItem>
|
||||||
|
<MenuHeader>Notification</MenuHeader>
|
||||||
|
<MenuItem
|
||||||
|
variant={notifState === cons.notifs.DEFAULT ? 'positive' : 'surface'}
|
||||||
|
iconSrc={BellIC}
|
||||||
|
onClick={() => setNotif(cons.notifs.DEFAULT, notifState)}
|
||||||
|
>
|
||||||
|
Default
|
||||||
|
</MenuItem>
|
||||||
|
<MenuItem
|
||||||
|
variant={notifState === cons.notifs.ALL_MESSAGES ? 'positive' : 'surface'}
|
||||||
|
iconSrc={BellRingIC}
|
||||||
|
onClick={() => setNotif(cons.notifs.ALL_MESSAGES, notifState)}
|
||||||
|
>
|
||||||
|
All messages
|
||||||
|
</MenuItem>
|
||||||
|
<MenuItem
|
||||||
|
variant={notifState === cons.notifs.MENTIONS_AND_KEYWORDS ? 'positive' : 'surface'}
|
||||||
|
iconSrc={BellPingIC}
|
||||||
|
onClick={() => setNotif(cons.notifs.MENTIONS_AND_KEYWORDS, notifState)}
|
||||||
|
>
|
||||||
|
Mentions & Keywords
|
||||||
|
</MenuItem>
|
||||||
|
<MenuItem
|
||||||
|
variant={notifState === cons.notifs.MUTE ? 'positive' : 'surface'}
|
||||||
|
iconSrc={BellOffIC}
|
||||||
|
onClick={() => setNotif(cons.notifs.MUTE, notifState)}
|
||||||
|
>
|
||||||
|
Mute
|
||||||
|
</MenuItem>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
render={(toggleMenu) => (
|
||||||
|
<input
|
||||||
|
ref={openerRef}
|
||||||
|
onClick={toggleMenu}
|
||||||
|
type="button"
|
||||||
|
style={{
|
||||||
|
width: '32px',
|
||||||
|
height: '32px',
|
||||||
|
backgroundColor: 'transparent',
|
||||||
|
position: 'absolute',
|
||||||
|
top: 0,
|
||||||
|
left: 0,
|
||||||
|
padding: 0,
|
||||||
|
border: 'none',
|
||||||
|
visibility: 'hidden',
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default RoomOptions;
|
20
src/app/organisms/room-optons/RoomOptions.scss
Normal file
20
src/app/organisms/room-optons/RoomOptions.scss
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
.context-menu__item {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.context-menu__item .btn-positive::before {
|
||||||
|
content: '';
|
||||||
|
display: inline-block;
|
||||||
|
width: 3px;
|
||||||
|
height: 12px;
|
||||||
|
background: var(--bg-positive);
|
||||||
|
border-radius: 0 4px 4px 0;
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
|
||||||
|
[dir=rtl] & {
|
||||||
|
left: unset;
|
||||||
|
right: 0;
|
||||||
|
border-radius: 4px 0 0 4px;
|
||||||
|
}
|
||||||
|
}
|
|
@ -77,6 +77,14 @@ function openReadReceipts(roomId, eventId) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function openRoomOptions(cords, roomId) {
|
||||||
|
appDispatcher.dispatch({
|
||||||
|
type: cons.actions.navigation.OPEN_ROOMOPTIONS,
|
||||||
|
cords,
|
||||||
|
roomId,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
export {
|
export {
|
||||||
selectTab,
|
selectTab,
|
||||||
selectSpace,
|
selectSpace,
|
||||||
|
@ -89,4 +97,5 @@ export {
|
||||||
openSettings,
|
openSettings,
|
||||||
openEmojiBoard,
|
openEmojiBoard,
|
||||||
openReadReceipts,
|
openReadReceipts,
|
||||||
|
openRoomOptions,
|
||||||
};
|
};
|
||||||
|
|
|
@ -386,6 +386,7 @@ class RoomList extends EventEmitter {
|
||||||
|
|
||||||
const lastTimelineEvent = room.timeline[room.timeline.length - 1];
|
const lastTimelineEvent = room.timeline[room.timeline.length - 1];
|
||||||
if (lastTimelineEvent.getId() !== event.getId()) return;
|
if (lastTimelineEvent.getId() !== event.getId()) return;
|
||||||
|
if (event.getSender() === this.matrixClient.getUserId()) return;
|
||||||
this.emit(cons.events.roomList.EVENT_ARRIVED, room.roomId);
|
this.emit(cons.events.roomList.EVENT_ARRIVED, room.roomId);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,12 @@ const cons = {
|
||||||
HOME: 'home',
|
HOME: 'home',
|
||||||
DIRECTS: 'dm',
|
DIRECTS: 'dm',
|
||||||
},
|
},
|
||||||
|
notifs: {
|
||||||
|
DEFAULT: 'default',
|
||||||
|
ALL_MESSAGES: 'all_messages',
|
||||||
|
MENTIONS_AND_KEYWORDS: 'mentions_and_keywords',
|
||||||
|
MUTE: 'mute',
|
||||||
|
},
|
||||||
actions: {
|
actions: {
|
||||||
navigation: {
|
navigation: {
|
||||||
SELECT_TAB: 'SELECT_TAB',
|
SELECT_TAB: 'SELECT_TAB',
|
||||||
|
@ -24,6 +30,7 @@ const cons = {
|
||||||
OPEN_SETTINGS: 'OPEN_SETTINGS',
|
OPEN_SETTINGS: 'OPEN_SETTINGS',
|
||||||
OPEN_EMOJIBOARD: 'OPEN_EMOJIBOARD',
|
OPEN_EMOJIBOARD: 'OPEN_EMOJIBOARD',
|
||||||
OPEN_READRECEIPTS: 'OPEN_READRECEIPTS',
|
OPEN_READRECEIPTS: 'OPEN_READRECEIPTS',
|
||||||
|
OPEN_ROOMOPTIONS: 'OPEN_ROOMOPTIONS',
|
||||||
},
|
},
|
||||||
room: {
|
room: {
|
||||||
JOIN: 'JOIN',
|
JOIN: 'JOIN',
|
||||||
|
@ -52,6 +59,7 @@ const cons = {
|
||||||
SETTINGS_OPENED: 'SETTINGS_OPENED',
|
SETTINGS_OPENED: 'SETTINGS_OPENED',
|
||||||
EMOJIBOARD_OPENED: 'EMOJIBOARD_OPENED',
|
EMOJIBOARD_OPENED: 'EMOJIBOARD_OPENED',
|
||||||
READRECEIPTS_OPENED: 'READRECEIPTS_OPENED',
|
READRECEIPTS_OPENED: 'READRECEIPTS_OPENED',
|
||||||
|
ROOMOPTIONS_OPENED: 'ROOMOPTIONS_OPENED',
|
||||||
},
|
},
|
||||||
roomList: {
|
roomList: {
|
||||||
ROOMLIST_UPDATED: 'ROOMLIST_UPDATED',
|
ROOMLIST_UPDATED: 'ROOMLIST_UPDATED',
|
||||||
|
|
|
@ -85,6 +85,13 @@ class Navigation extends EventEmitter {
|
||||||
action.eventId,
|
action.eventId,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
[cons.actions.navigation.OPEN_ROOMOPTIONS]: () => {
|
||||||
|
this.emit(
|
||||||
|
cons.events.navigation.ROOMOPTIONS_OPENED,
|
||||||
|
action.cords,
|
||||||
|
action.roomId,
|
||||||
|
);
|
||||||
|
},
|
||||||
};
|
};
|
||||||
actions[action.type]?.();
|
actions[action.type]?.();
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,3 +19,12 @@ export function isNotInSameDay(dt2, dt1) {
|
||||||
|| dt2.getYear() !== dt1.getYear()
|
|| dt2.getYear() !== dt1.getYear()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getEventCords(ev) {
|
||||||
|
const boxInfo = ev.target.getBoundingClientRect();
|
||||||
|
return {
|
||||||
|
x: boxInfo.x,
|
||||||
|
y: boxInfo.y,
|
||||||
|
detail: ev.detail,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue