Add Timezone sharing
Allows users to share their timezone
This commit is contained in:
parent
ac155bbf4c
commit
91e6205f49
4 changed files with 159 additions and 0 deletions
55
src/app/molecules/room-timezone/RoomTimezone.jsx
Normal file
55
src/app/molecules/room-timezone/RoomTimezone.jsx
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
import React, { useState, useEffect, useCallback } from 'react';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
|
||||||
|
import initMatrix from '../../../client/initMatrix';
|
||||||
|
import Button from '../../atoms/button/Button';
|
||||||
|
import Text from '../../atoms/text/Text';
|
||||||
|
|
||||||
|
import './RoomTimezone.scss';
|
||||||
|
|
||||||
|
function RoomTimezone({ roomId }) {
|
||||||
|
const mx = initMatrix.matrixClient;
|
||||||
|
const room = mx.getRoom(roomId);
|
||||||
|
const userId = mx.getUserId();
|
||||||
|
|
||||||
|
const currentTimezone = room.currentState.getStateEvents('in.cinny.share_timezone', userId)?.event?.content?.user_timezone;
|
||||||
|
|
||||||
|
const [timezone, setTimezone] = useState(currentTimezone);
|
||||||
|
|
||||||
|
const clearTimezone = () => {
|
||||||
|
mx.sendStateEvent(roomId, 'in.cinny.share_timezone', { }, userId);
|
||||||
|
setTimezone(null);
|
||||||
|
};
|
||||||
|
|
||||||
|
const shareTimezone = () => {
|
||||||
|
const userTimezone = Intl.DateTimeFormat().resolvedOptions().timeZone;
|
||||||
|
setTimezone(userTimezone);
|
||||||
|
mx.sendStateEvent(roomId, 'in.cinny.share_timezone', { user_timezone: userTimezone }, userId);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="room-timezone__content">
|
||||||
|
<Text className="room-timezone__message">Share your timezone</Text>
|
||||||
|
<Text className="room-timezone__message" variant="b3">
|
||||||
|
Sharing your timezone will allow other users in this room to see your local time.
|
||||||
|
Keep in mind that sharing your timezone will share your approximate location.
|
||||||
|
</Text>
|
||||||
|
<Text className="room-timezone__message" variant="b2">
|
||||||
|
{timezone ? `Currently shared timezone: ${timezone}` : 'You are not currently sharing a timezone'}
|
||||||
|
</Text>
|
||||||
|
<Button onClick={() => shareTimezone()} variant={timezone ? 'surface' : 'danger'}>
|
||||||
|
{timezone ? 'Update Timezone' : 'Share Timezone'}
|
||||||
|
</Button>
|
||||||
|
|
||||||
|
<Button onClick={() => clearTimezone()} disabled={!timezone}>
|
||||||
|
Clear Shared Timezone
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
RoomTimezone.propTypes = {
|
||||||
|
roomId: PropTypes.string.isRequired,
|
||||||
|
};
|
||||||
|
|
||||||
|
export default RoomTimezone;
|
84
src/app/molecules/room-timezone/RoomTimezone.scss
Normal file
84
src/app/molecules/room-timezone/RoomTimezone.scss
Normal file
|
@ -0,0 +1,84 @@
|
||||||
|
@use '../../partials/flex';
|
||||||
|
@use '../../partials/dir';
|
||||||
|
@use '../../partials/text';
|
||||||
|
|
||||||
|
.room-timezone {
|
||||||
|
&__message,
|
||||||
|
& .setting-tile {
|
||||||
|
margin: var(--sp-tight) var(--sp-normal);
|
||||||
|
}
|
||||||
|
& .setting-tile {
|
||||||
|
margin-bottom: var(--sp-loose);
|
||||||
|
}
|
||||||
|
|
||||||
|
&__alias-item {
|
||||||
|
padding: var(--sp-extra-tight) var(--sp-normal);
|
||||||
|
@extend .cp-fx__row--s-c;
|
||||||
|
&.checkbox {
|
||||||
|
@include dir.side(margin, 0 , var(--sp-tight));
|
||||||
|
}
|
||||||
|
& .text {
|
||||||
|
@extend .cp-fx__item-one;
|
||||||
|
@extend .cp-txt__ellipsis;
|
||||||
|
color: var(--tc-surface-high);
|
||||||
|
span {
|
||||||
|
margin: 0 var(--sp-extra-tight);
|
||||||
|
padding: 0 var(--sp-ultra-tight);
|
||||||
|
color: var(--bg-surface);
|
||||||
|
background-color: var(--tc-surface-low);
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&__item-btns {
|
||||||
|
@include dir.side(margin, 48px, 0);
|
||||||
|
& button {
|
||||||
|
padding: var(--sp-ultra-tight) var(--sp-tight);
|
||||||
|
margin-bottom: var(--sp-tight);
|
||||||
|
@include dir.side(margin, 0, var(--sp-tight));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__content {
|
||||||
|
margin-bottom: var(--sp-normal);
|
||||||
|
|
||||||
|
& .checkbox {
|
||||||
|
@include dir.side(margin, 0, var(--sp-tight));
|
||||||
|
min-width: 20px;
|
||||||
|
}
|
||||||
|
& > button {
|
||||||
|
margin: 0 var(--sp-normal);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__form {
|
||||||
|
padding: var(--sp-normal);
|
||||||
|
padding-top: 0;
|
||||||
|
display: flex;
|
||||||
|
&-label {
|
||||||
|
padding: var(--sp-normal) var(--sp-normal) var(--sp-ultra-tight);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__input-wrapper {
|
||||||
|
display: flex;
|
||||||
|
@extend .cp-fx__item-one;
|
||||||
|
@include dir.side(margin, 0, var(--sp-tight));
|
||||||
|
|
||||||
|
& .input-container {
|
||||||
|
@extend .cp-fx__item-one;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__input-status {
|
||||||
|
padding: 0 var(--sp-normal);
|
||||||
|
}
|
||||||
|
&__valid {
|
||||||
|
color: var(--tc-positive-high);
|
||||||
|
padding-bottom: var(--sp-normal);
|
||||||
|
}
|
||||||
|
&__invalid {
|
||||||
|
color: var(--tc-danger-high);
|
||||||
|
padding-bottom: var(--sp-normal);
|
||||||
|
}
|
||||||
|
}
|
|
@ -39,6 +39,7 @@ import ChevronTopIC from '../../../../public/res/ic/outlined/chevron-top.svg';
|
||||||
|
|
||||||
import { useForceUpdate } from '../../hooks/useForceUpdate';
|
import { useForceUpdate } from '../../hooks/useForceUpdate';
|
||||||
import { confirmDialog } from '../../molecules/confirm-dialog/ConfirmDialog';
|
import { confirmDialog } from '../../molecules/confirm-dialog/ConfirmDialog';
|
||||||
|
import RoomTimezone from '../../molecules/room-timezone/RoomTimezone';
|
||||||
|
|
||||||
const tabText = {
|
const tabText = {
|
||||||
GENERAL: 'General',
|
GENERAL: 'General',
|
||||||
|
@ -120,6 +121,10 @@ function GeneralSettings({ roomId }) {
|
||||||
<MenuHeader>Room addresses</MenuHeader>
|
<MenuHeader>Room addresses</MenuHeader>
|
||||||
<RoomAliases roomId={roomId} />
|
<RoomAliases roomId={roomId} />
|
||||||
</div>
|
</div>
|
||||||
|
<div className="room-settings__card">
|
||||||
|
<MenuHeader>Timezones</MenuHeader>
|
||||||
|
<RoomTimezone roomId={roomId} />
|
||||||
|
</div>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,6 +36,7 @@ function RoomViewHeader({ roomId }) {
|
||||||
let avatarSrc = mx.getRoom(roomId).getAvatarUrl(mx.baseUrl, 36, 36, 'crop');
|
let avatarSrc = mx.getRoom(roomId).getAvatarUrl(mx.baseUrl, 36, 36, 'crop');
|
||||||
avatarSrc = isDM ? mx.getRoom(roomId).getAvatarFallbackMember()?.getAvatarUrl(mx.baseUrl, 36, 36, 'crop') : avatarSrc;
|
avatarSrc = isDM ? mx.getRoom(roomId).getAvatarFallbackMember()?.getAvatarUrl(mx.baseUrl, 36, 36, 'crop') : avatarSrc;
|
||||||
const roomName = mx.getRoom(roomId).name;
|
const roomName = mx.getRoom(roomId).name;
|
||||||
|
let partnerLocalTime = null;
|
||||||
|
|
||||||
const roomHeaderBtnRef = useRef(null);
|
const roomHeaderBtnRef = useRef(null);
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
@ -72,6 +73,19 @@ function RoomViewHeader({ roomId }) {
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (isDM) {
|
||||||
|
const room = mx.getRoom(roomId);
|
||||||
|
const partner = room.getAvatarFallbackMember();
|
||||||
|
const timezone = room.currentState.getStateEvents('in.cinny.share_timezone', partner.userId)?.event?.content?.user_timezone;
|
||||||
|
const date = new Date();
|
||||||
|
|
||||||
|
try {
|
||||||
|
partnerLocalTime = date.toLocaleTimeString([], { timeZone: timezone, hour: '2-digit', minute: '2-digit' });
|
||||||
|
} catch {
|
||||||
|
partnerLocalTime = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Header>
|
<Header>
|
||||||
<IconButton
|
<IconButton
|
||||||
|
@ -93,6 +107,7 @@ function RoomViewHeader({ roomId }) {
|
||||||
</TitleWrapper>
|
</TitleWrapper>
|
||||||
<RawIcon src={ChevronBottomIC} />
|
<RawIcon src={ChevronBottomIC} />
|
||||||
</button>
|
</button>
|
||||||
|
<Text>{partnerLocalTime}</Text>
|
||||||
<IconButton onClick={() => toggleRoomSettings(tabText.SEARCH)} tooltip="Search" src={SearchIC} />
|
<IconButton onClick={() => toggleRoomSettings(tabText.SEARCH)} tooltip="Search" src={SearchIC} />
|
||||||
<IconButton className="room-header__drawer-btn" onClick={togglePeopleDrawer} tooltip="People" src={UserIC} />
|
<IconButton className="room-header__drawer-btn" onClick={togglePeopleDrawer} tooltip="People" src={UserIC} />
|
||||||
<IconButton className="room-header__members-btn" onClick={() => toggleRoomSettings(tabText.MEMBERS)} tooltip="Members" src={UserIC} />
|
<IconButton className="room-header__members-btn" onClick={() => toggleRoomSettings(tabText.MEMBERS)} tooltip="Members" src={UserIC} />
|
||||||
|
|
Loading…
Reference in a new issue