diff --git a/src/app/organisms/public-channels/PublicChannels.jsx b/src/app/organisms/public-channels/PublicChannels.jsx
index 6527798..2f02ba0 100644
--- a/src/app/organisms/public-channels/PublicChannels.jsx
+++ b/src/app/organisms/public-channels/PublicChannels.jsx
@@ -20,6 +20,70 @@ import HashSearchIC from '../../../../public/res/ic/outlined/hash-search.svg';
const SEARCH_LIMIT = 20;
+function TryJoinWithAlias({ alias, onRequestClose }) {
+ const [status, setStatus] = useState({
+ isJoining: false,
+ error: null,
+ roomId: null,
+ tempRoomId: null,
+ });
+ function handleOnRoomAdded(roomId) {
+ if (status.tempRoomId !== null && status.tempRoomId !== roomId) return;
+ setStatus({
+ isJoining: false, error: null, roomId, tempRoomId: null,
+ });
+ }
+
+ useEffect(() => {
+ initMatrix.roomList.on(cons.events.roomList.ROOM_JOINED, handleOnRoomAdded);
+ return () => {
+ initMatrix.roomList.removeListener(cons.events.roomList.ROOM_JOINED, handleOnRoomAdded);
+ };
+ }, [status]);
+
+ async function joinWithAlias() {
+ setStatus({
+ isJoining: true, error: null, roomId: null, tempRoomId: null,
+ });
+ try {
+ const roomId = await roomActions.join(alias, false);
+ setStatus({
+ isJoining: true, error: null, roomId: null, tempRoomId: roomId,
+ });
+ } catch (e) {
+ setStatus({
+ isJoining: false,
+ error: `Unable to join ${alias}. Either room is private or doesn't exist.`,
+ roomId: null,
+ tempRoomId: null,
+ });
+ }
+ }
+
+ return (
+
+ {status.roomId === null && !status.isJoining && status.error === null && (
+
+ )}
+ {status.isJoining && (
+ <>
+
+ {`Joining ${alias}...`}
+ >
+ )}
+ {status.roomId !== null && (
+
+ )}
+ {status.error !== null && {status.error}}
+
+ );
+}
+
+TryJoinWithAlias.propTypes = {
+ alias: PropTypes.string.isRequired,
+ onRequestClose: PropTypes.func.isRequired,
+};
+
function PublicChannels({ isOpen, onRequestClose }) {
const [isSearching, updateIsSearching] = useState(false);
const [isViewMore, updateIsViewMore] = useState(false);
@@ -33,8 +97,13 @@ function PublicChannels({ isOpen, onRequestClose }) {
const userId = initMatrix.matrixClient.getUserId();
async function searchChannels(viewMore) {
- let inputHs = hsRef?.current?.value;
let inputChannelName = channelNameRef?.current?.value;
+ let isInputAlias = false;
+ if (typeof inputChannelName === 'string') {
+ isInputAlias = inputChannelName[0] === '#' && inputChannelName.indexOf(':') > 1;
+ }
+ const hsFromAlias = (isInputAlias) ? inputChannelName.slice(inputChannelName.indexOf(':') + 1) : null;
+ let inputHs = hsFromAlias || hsRef?.current?.value;
if (typeof inputHs !== 'string') inputHs = userId.slice(userId.indexOf(':') + 1);
if (typeof inputChannelName !== 'string') inputChannelName = '';
@@ -68,6 +137,12 @@ function PublicChannels({ isOpen, onRequestClose }) {
updateNextBatch(result.next_batch);
updateIsSearching(false);
updateIsViewMore(false);
+ if (totalChannels.length === 0) {
+ updateSearchQuery({
+ error: `No result found for "${inputChannelName}" on ${inputHs}`,
+ alias: isInputAlias ? inputChannelName : null,
+ });
+ }
} catch (e) {
updatePublicChannels([]);
updateSearchQuery({ error: 'Something went wrong!' });
@@ -139,7 +214,7 @@ function PublicChannels({ isOpen, onRequestClose }) {
{ publicChannels.length !== 0 && (
diff --git a/src/app/organisms/public-channels/PublicChannels.scss b/src/app/organisms/public-channels/PublicChannels.scss
index 21309ab..3eef310 100644
--- a/src/app/organisms/public-channels/PublicChannels.scss
+++ b/src/app/organisms/public-channels/PublicChannels.scss
@@ -55,6 +55,10 @@
& .donut-spinner {
margin: 0 var(--sp-tight);
}
+
+ .try-join-with-alias {
+ margin-top: var(--sp-normal);
+ }
}
&__search-error {
color: var(--bg-danger);
@@ -84,4 +88,13 @@
right: var(--sp-normal);
}
}
+}
+
+.try-join-with-alias {
+ display: flex;
+ align-items: center;
+
+ & >.text:nth-child(2) {
+ margin: 0 var(--sp-normal);
+ }
}
\ No newline at end of file
diff --git a/src/client/action/room.js b/src/client/action/room.js
index f6a9bab..e18f197 100644
--- a/src/client/action/room.js
+++ b/src/client/action/room.js
@@ -83,20 +83,24 @@ function guessDMRoomTargetId(room, myUserId) {
* @param {string} roomId
* @param {boolean} isDM
*/
-function join(roomId, isDM) {
+async function join(roomIdOrAlias, isDM) {
const mx = initMatrix.matrixClient;
- mx.joinRoom(roomId)
- .then(async () => {
- if (isDM) {
- const targetUserId = guessDMRoomTargetId(mx.getRoom(roomId), mx.getUserId());
- await addRoomToMDirect(roomId, targetUserId);
- }
- appDispatcher.dispatch({
- type: cons.actions.room.JOIN,
- roomId,
- isDM,
- });
- }).catch();
+ try {
+ const resultRoom = await mx.joinRoom(roomIdOrAlias);
+
+ if (isDM) {
+ const targetUserId = guessDMRoomTargetId(mx.getRoom(resultRoom.roomId), mx.getUserId());
+ await addRoomToMDirect(resultRoom.roomId, targetUserId);
+ }
+ appDispatcher.dispatch({
+ type: cons.actions.room.JOIN,
+ roomId: resultRoom.roomId,
+ isDM,
+ });
+ return resultRoom.roomId;
+ } catch (e) {
+ throw new Error(e);
+ }
}
/**
@@ -104,8 +108,9 @@ function join(roomId, isDM) {
* @param {string} roomId
* @param {boolean} isDM
*/
-function leave(roomId, isDM) {
+function leave(roomId) {
const mx = initMatrix.matrixClient;
+ const isDM = initMatrix.roomList.directs.has(roomId);
mx.leave(roomId)
.then(() => {
appDispatcher.dispatch({