parent
3afc068a02
commit
e51fc5a585
8 changed files with 202 additions and 2 deletions
|
@ -125,7 +125,7 @@ function EmojiVerificationContent({ data, requestClose }) {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="emoji-verification__content">
|
<div className="emoji-verification__content">
|
||||||
<Text>Click accept to start the verification process</Text>
|
<Text>Click accept to start the verification process.</Text>
|
||||||
<div className="emoji-verification__buttons">
|
<div className="emoji-verification__buttons">
|
||||||
{
|
{
|
||||||
process
|
process
|
||||||
|
|
155
src/app/organisms/join-alias/JoinAlias.jsx
Normal file
155
src/app/organisms/join-alias/JoinAlias.jsx
Normal file
|
@ -0,0 +1,155 @@
|
||||||
|
import React, { useState, useEffect } from 'react';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import './JoinAlias.scss';
|
||||||
|
|
||||||
|
import initMatrix from '../../../client/initMatrix';
|
||||||
|
import cons from '../../../client/state/cons';
|
||||||
|
import navigation from '../../../client/state/navigation';
|
||||||
|
import { join } from '../../../client/action/room';
|
||||||
|
import { selectRoom, selectSpace } from '../../../client/action/navigation';
|
||||||
|
|
||||||
|
import Text from '../../atoms/text/Text';
|
||||||
|
import IconButton from '../../atoms/button/IconButton';
|
||||||
|
import Button from '../../atoms/button/Button';
|
||||||
|
import Input from '../../atoms/input/Input';
|
||||||
|
import Spinner from '../../atoms/spinner/Spinner';
|
||||||
|
import Dialog from '../../molecules/dialog/Dialog';
|
||||||
|
|
||||||
|
import CrossIC from '../../../../public/res/ic/outlined/cross.svg';
|
||||||
|
|
||||||
|
import { useStore } from '../../hooks/useStore';
|
||||||
|
|
||||||
|
const ALIAS_OR_ID_REG = /^[#|!].+:.+\..+$/;
|
||||||
|
|
||||||
|
function JoinAliasContent({ term, requestClose }) {
|
||||||
|
const [process, setProcess] = useState(false);
|
||||||
|
const [error, setError] = useState(undefined);
|
||||||
|
const [lastJoinId, setLastJoinId] = useState(undefined);
|
||||||
|
|
||||||
|
const mx = initMatrix.matrixClient;
|
||||||
|
const mountStore = useStore();
|
||||||
|
|
||||||
|
const openRoom = (roomId) => {
|
||||||
|
const room = mx.getRoom(roomId);
|
||||||
|
if (!room) return;
|
||||||
|
if (room.isSpaceRoom()) selectSpace(roomId);
|
||||||
|
else selectRoom(roomId);
|
||||||
|
requestClose();
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const handleJoin = (roomId) => {
|
||||||
|
if (lastJoinId !== roomId) return;
|
||||||
|
openRoom(roomId);
|
||||||
|
};
|
||||||
|
initMatrix.roomList.on(cons.events.roomList.ROOM_JOINED, handleJoin);
|
||||||
|
return () => {
|
||||||
|
initMatrix.roomList.removeListener(cons.events.roomList.ROOM_JOINED, handleJoin);
|
||||||
|
};
|
||||||
|
}, [lastJoinId]);
|
||||||
|
|
||||||
|
const handleSubmit = async (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
mountStore.setItem(true);
|
||||||
|
const alias = e.target.alias.value;
|
||||||
|
if (alias?.trim() === '') return;
|
||||||
|
if (alias.match(ALIAS_OR_ID_REG) === null) {
|
||||||
|
setError('Invalid address.');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
setProcess('Looking for address...');
|
||||||
|
setError(undefined);
|
||||||
|
let via;
|
||||||
|
if (alias.startsWith('#')) {
|
||||||
|
try {
|
||||||
|
const aliasData = await mx.resolveRoomAlias(alias);
|
||||||
|
via = aliasData?.servers || [];
|
||||||
|
if (mountStore.getItem()) {
|
||||||
|
setProcess(`Joining ${alias}...`);
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
if (!mountStore.getItem()) return;
|
||||||
|
setProcess(false);
|
||||||
|
setError(`Unable to find room/space with ${alias}. Either room/space is private or doesn't exist.`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
const roomId = await join(alias, false, via);
|
||||||
|
if (!mountStore.getItem()) return;
|
||||||
|
setLastJoinId(roomId);
|
||||||
|
openRoom(roomId);
|
||||||
|
} catch {
|
||||||
|
if (!mountStore.getItem()) return;
|
||||||
|
setProcess(false);
|
||||||
|
setError(`Unable to join ${alias}. Either room/space is private or doesn't exist.`);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<form className="join-alias" onSubmit={handleSubmit}>
|
||||||
|
<Input
|
||||||
|
label="Address"
|
||||||
|
value={term}
|
||||||
|
name="alias"
|
||||||
|
required
|
||||||
|
/>
|
||||||
|
{error && <Text className="join-alias__error" variant="b3">{error}</Text>}
|
||||||
|
<div className="join-alias__btn">
|
||||||
|
{
|
||||||
|
process
|
||||||
|
? (
|
||||||
|
<>
|
||||||
|
<Spinner size="small" />
|
||||||
|
<Text>{process}</Text>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
: <Button variant="primary" type="submit">Join</Button>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
JoinAliasContent.defaultProps = {
|
||||||
|
term: undefined,
|
||||||
|
};
|
||||||
|
JoinAliasContent.propTypes = {
|
||||||
|
term: PropTypes.string,
|
||||||
|
requestClose: PropTypes.func.isRequired,
|
||||||
|
};
|
||||||
|
|
||||||
|
function useWindowToggle() {
|
||||||
|
const [data, setData] = useState(null);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const handleOpen = (term) => {
|
||||||
|
setData({ term });
|
||||||
|
};
|
||||||
|
navigation.on(cons.events.navigation.JOIN_ALIAS_OPENED, handleOpen);
|
||||||
|
return () => {
|
||||||
|
navigation.removeListener(cons.events.navigation.JOIN_ALIAS_OPENED, handleOpen);
|
||||||
|
};
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const onRequestClose = () => setData(null);
|
||||||
|
|
||||||
|
return [data, onRequestClose];
|
||||||
|
}
|
||||||
|
|
||||||
|
function JoinAlias() {
|
||||||
|
const [data, requestClose] = useWindowToggle();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Dialog
|
||||||
|
isOpen={data !== null}
|
||||||
|
title={(
|
||||||
|
<Text variant="s1" weight="medium" primary>Join with address</Text>
|
||||||
|
)}
|
||||||
|
contentOptions={<IconButton src={CrossIC} onClick={requestClose} tooltip="Close" />}
|
||||||
|
onRequestClose={requestClose}
|
||||||
|
>
|
||||||
|
{ data ? <JoinAliasContent term={data.term} requestClose={requestClose} /> : <div /> }
|
||||||
|
</Dialog>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default JoinAlias;
|
20
src/app/organisms/join-alias/JoinAlias.scss
Normal file
20
src/app/organisms/join-alias/JoinAlias.scss
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
@use '../../partials/dir';
|
||||||
|
|
||||||
|
.join-alias {
|
||||||
|
padding: var(--sp-normal);
|
||||||
|
@include dir.side(padding, var(--sp-normal), var(--sp-extra-tight));
|
||||||
|
|
||||||
|
& > *:not(:first-child) {
|
||||||
|
margin-top: var(--sp-normal);
|
||||||
|
}
|
||||||
|
|
||||||
|
&__error {
|
||||||
|
color: var(--tc-danger-high);
|
||||||
|
margin-top: var(--sp-extra-tight) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__btn {
|
||||||
|
display: flex;
|
||||||
|
gap: var(--sp-normal);
|
||||||
|
}
|
||||||
|
}
|
|
@ -7,7 +7,7 @@ import { twemojify } from '../../../util/twemojify';
|
||||||
import initMatrix from '../../../client/initMatrix';
|
import initMatrix from '../../../client/initMatrix';
|
||||||
import cons from '../../../client/state/cons';
|
import cons from '../../../client/state/cons';
|
||||||
import {
|
import {
|
||||||
openPublicRooms, openCreateRoom, openSpaceManage,
|
openPublicRooms, openCreateRoom, openSpaceManage, openJoinAlias,
|
||||||
openSpaceAddExisting, openInviteUser, openReusableContextMenu,
|
openSpaceAddExisting, openInviteUser, openReusableContextMenu,
|
||||||
} from '../../../client/action/navigation';
|
} from '../../../client/action/navigation';
|
||||||
import { getEventCords } from '../../../util/common';
|
import { getEventCords } from '../../../util/common';
|
||||||
|
@ -60,6 +60,14 @@ export function HomeSpaceOptions({ spaceId, afterOptionSelect }) {
|
||||||
Join public room
|
Join public room
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
)}
|
)}
|
||||||
|
{ !spaceId && (
|
||||||
|
<MenuItem
|
||||||
|
iconSrc={PlusIC}
|
||||||
|
onClick={() => { afterOptionSelect(); openJoinAlias(); }}
|
||||||
|
>
|
||||||
|
Join with address
|
||||||
|
</MenuItem>
|
||||||
|
)}
|
||||||
{ spaceId && (
|
{ spaceId && (
|
||||||
<MenuItem
|
<MenuItem
|
||||||
iconSrc={PlusIC}
|
iconSrc={PlusIC}
|
||||||
|
|
|
@ -7,6 +7,7 @@ import SpaceAddExisting from '../../molecules/space-add-existing/SpaceAddExistin
|
||||||
import Search from '../search/Search';
|
import Search from '../search/Search';
|
||||||
import ViewSource from '../view-source/ViewSource';
|
import ViewSource from '../view-source/ViewSource';
|
||||||
import CreateRoom from '../create-room/CreateRoom';
|
import CreateRoom from '../create-room/CreateRoom';
|
||||||
|
import JoinAlias from '../join-alias/JoinAlias';
|
||||||
import EmojiVerification from '../emoji-verification/EmojiVerification';
|
import EmojiVerification from '../emoji-verification/EmojiVerification';
|
||||||
|
|
||||||
import ReusableDialog from '../../molecules/dialog/ReusableDialog';
|
import ReusableDialog from '../../molecules/dialog/ReusableDialog';
|
||||||
|
@ -19,6 +20,7 @@ function Dialogs() {
|
||||||
<ProfileViewer />
|
<ProfileViewer />
|
||||||
<ShortcutSpaces />
|
<ShortcutSpaces />
|
||||||
<CreateRoom />
|
<CreateRoom />
|
||||||
|
<JoinAlias />
|
||||||
<SpaceAddExisting />
|
<SpaceAddExisting />
|
||||||
<Search />
|
<Search />
|
||||||
<EmojiVerification />
|
<EmojiVerification />
|
||||||
|
|
|
@ -86,6 +86,13 @@ export function openCreateRoom(isSpace = false, parentId = null) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function openJoinAlias(term) {
|
||||||
|
appDispatcher.dispatch({
|
||||||
|
type: cons.actions.navigation.OPEN_JOIN_ALIAS,
|
||||||
|
term,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
export function openInviteUser(roomId, searchTerm) {
|
export function openInviteUser(roomId, searchTerm) {
|
||||||
appDispatcher.dispatch({
|
appDispatcher.dispatch({
|
||||||
type: cons.actions.navigation.OPEN_INVITE_USER,
|
type: cons.actions.navigation.OPEN_INVITE_USER,
|
||||||
|
|
|
@ -38,6 +38,7 @@ const cons = {
|
||||||
OPEN_INVITE_LIST: 'OPEN_INVITE_LIST',
|
OPEN_INVITE_LIST: 'OPEN_INVITE_LIST',
|
||||||
OPEN_PUBLIC_ROOMS: 'OPEN_PUBLIC_ROOMS',
|
OPEN_PUBLIC_ROOMS: 'OPEN_PUBLIC_ROOMS',
|
||||||
OPEN_CREATE_ROOM: 'OPEN_CREATE_ROOM',
|
OPEN_CREATE_ROOM: 'OPEN_CREATE_ROOM',
|
||||||
|
OPEN_JOIN_ALIAS: 'OPEN_JOIN_ALIAS',
|
||||||
OPEN_INVITE_USER: 'OPEN_INVITE_USER',
|
OPEN_INVITE_USER: 'OPEN_INVITE_USER',
|
||||||
OPEN_PROFILE_VIEWER: 'OPEN_PROFILE_VIEWER',
|
OPEN_PROFILE_VIEWER: 'OPEN_PROFILE_VIEWER',
|
||||||
OPEN_SETTINGS: 'OPEN_SETTINGS',
|
OPEN_SETTINGS: 'OPEN_SETTINGS',
|
||||||
|
@ -86,6 +87,7 @@ const cons = {
|
||||||
INVITE_LIST_OPENED: 'INVITE_LIST_OPENED',
|
INVITE_LIST_OPENED: 'INVITE_LIST_OPENED',
|
||||||
PUBLIC_ROOMS_OPENED: 'PUBLIC_ROOMS_OPENED',
|
PUBLIC_ROOMS_OPENED: 'PUBLIC_ROOMS_OPENED',
|
||||||
CREATE_ROOM_OPENED: 'CREATE_ROOM_OPENED',
|
CREATE_ROOM_OPENED: 'CREATE_ROOM_OPENED',
|
||||||
|
JOIN_ALIAS_OPENED: 'JOIN_ALIAS_OPENED',
|
||||||
INVITE_USER_OPENED: 'INVITE_USER_OPENED',
|
INVITE_USER_OPENED: 'INVITE_USER_OPENED',
|
||||||
SETTINGS_OPENED: 'SETTINGS_OPENED',
|
SETTINGS_OPENED: 'SETTINGS_OPENED',
|
||||||
PROFILE_VIEWER_OPENED: 'PROFILE_VIEWER_OPENED',
|
PROFILE_VIEWER_OPENED: 'PROFILE_VIEWER_OPENED',
|
||||||
|
|
|
@ -122,6 +122,12 @@ class Navigation extends EventEmitter {
|
||||||
action.parentId,
|
action.parentId,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
[cons.actions.navigation.OPEN_JOIN_ALIAS]: () => {
|
||||||
|
this.emit(
|
||||||
|
cons.events.navigation.JOIN_ALIAS_OPENED,
|
||||||
|
action.term,
|
||||||
|
);
|
||||||
|
},
|
||||||
[cons.actions.navigation.OPEN_INVITE_USER]: () => {
|
[cons.actions.navigation.OPEN_INVITE_USER]: () => {
|
||||||
this.emit(cons.events.navigation.INVITE_USER_OPENED, action.roomId, action.searchTerm);
|
this.emit(cons.events.navigation.INVITE_USER_OPENED, action.roomId, action.searchTerm);
|
||||||
},
|
},
|
||||||
|
|
Loading…
Reference in a new issue