added support for alias search in public channels
This commit is contained in:
parent
4ec770da63
commit
6586f933ff
3 changed files with 117 additions and 19 deletions
|
@ -20,6 +20,70 @@ import HashSearchIC from '../../../../public/res/ic/outlined/hash-search.svg';
|
||||||
|
|
||||||
const SEARCH_LIMIT = 20;
|
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 (
|
||||||
|
<div className="try-join-with-alias">
|
||||||
|
{status.roomId === null && !status.isJoining && status.error === null && (
|
||||||
|
<Button onClick={() => joinWithAlias()}>{`Try joining ${alias}`}</Button>
|
||||||
|
)}
|
||||||
|
{status.isJoining && (
|
||||||
|
<>
|
||||||
|
<Spinner size="small" />
|
||||||
|
<Text>{`Joining ${alias}...`}</Text>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
{status.roomId !== null && (
|
||||||
|
<Button onClick={() => { onRequestClose(); selectRoom(status.roomId); }}>Open</Button>
|
||||||
|
)}
|
||||||
|
{status.error !== null && <Text variant="b2"><span style={{ color: 'var(--bg-danger)' }}>{status.error}</span></Text>}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
TryJoinWithAlias.propTypes = {
|
||||||
|
alias: PropTypes.string.isRequired,
|
||||||
|
onRequestClose: PropTypes.func.isRequired,
|
||||||
|
};
|
||||||
|
|
||||||
function PublicChannels({ isOpen, onRequestClose }) {
|
function PublicChannels({ isOpen, onRequestClose }) {
|
||||||
const [isSearching, updateIsSearching] = useState(false);
|
const [isSearching, updateIsSearching] = useState(false);
|
||||||
const [isViewMore, updateIsViewMore] = useState(false);
|
const [isViewMore, updateIsViewMore] = useState(false);
|
||||||
|
@ -33,8 +97,13 @@ function PublicChannels({ isOpen, onRequestClose }) {
|
||||||
const userId = initMatrix.matrixClient.getUserId();
|
const userId = initMatrix.matrixClient.getUserId();
|
||||||
|
|
||||||
async function searchChannels(viewMore) {
|
async function searchChannels(viewMore) {
|
||||||
let inputHs = hsRef?.current?.value;
|
|
||||||
let inputChannelName = channelNameRef?.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 inputHs !== 'string') inputHs = userId.slice(userId.indexOf(':') + 1);
|
||||||
if (typeof inputChannelName !== 'string') inputChannelName = '';
|
if (typeof inputChannelName !== 'string') inputChannelName = '';
|
||||||
|
@ -68,6 +137,12 @@ function PublicChannels({ isOpen, onRequestClose }) {
|
||||||
updateNextBatch(result.next_batch);
|
updateNextBatch(result.next_batch);
|
||||||
updateIsSearching(false);
|
updateIsSearching(false);
|
||||||
updateIsViewMore(false);
|
updateIsViewMore(false);
|
||||||
|
if (totalChannels.length === 0) {
|
||||||
|
updateSearchQuery({
|
||||||
|
error: `No result found for "${inputChannelName}" on ${inputHs}`,
|
||||||
|
alias: isInputAlias ? inputChannelName : null,
|
||||||
|
});
|
||||||
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
updatePublicChannels([]);
|
updatePublicChannels([]);
|
||||||
updateSearchQuery({ error: 'Something went wrong!' });
|
updateSearchQuery({ error: 'Something went wrong!' });
|
||||||
|
@ -139,7 +214,7 @@ function PublicChannels({ isOpen, onRequestClose }) {
|
||||||
<div className="public-channels">
|
<div className="public-channels">
|
||||||
<form className="public-channels__form" onSubmit={(e) => { e.preventDefault(); searchChannels(); }}>
|
<form className="public-channels__form" onSubmit={(e) => { e.preventDefault(); searchChannels(); }}>
|
||||||
<div className="public-channels__input-wrapper">
|
<div className="public-channels__input-wrapper">
|
||||||
<Input forwardRef={channelNameRef} label="Channel name" />
|
<Input forwardRef={channelNameRef} label="Channel name or alias" />
|
||||||
<Input forwardRef={hsRef} value={userId.slice(userId.indexOf(':') + 1)} label="Homeserver" required />
|
<Input forwardRef={hsRef} value={userId.slice(userId.indexOf(':') + 1)} label="Homeserver" required />
|
||||||
</div>
|
</div>
|
||||||
<Button disabled={isSearching} iconSrc={HashSearchIC} variant="primary" type="submit">Search</Button>
|
<Button disabled={isSearching} iconSrc={HashSearchIC} variant="primary" type="submit">Search</Button>
|
||||||
|
@ -169,9 +244,14 @@ function PublicChannels({ isOpen, onRequestClose }) {
|
||||||
: <Text variant="b2">{`Search result for "${searchQuery.name}" on ${searchQuery.homeserver}.`}</Text>
|
: <Text variant="b2">{`Search result for "${searchQuery.name}" on ${searchQuery.homeserver}.`}</Text>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
{
|
{ searchQuery.error && (
|
||||||
searchQuery.error && <Text className="public-channels__search-error" variant="b2">{searchQuery.error}</Text>
|
<>
|
||||||
}
|
<Text className="public-channels__search-error" variant="b2">{searchQuery.error}</Text>
|
||||||
|
{searchQuery.alias !== null && (
|
||||||
|
<TryJoinWithAlias onRequestClose={onRequestClose} alias={searchQuery.alias} />
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
{ publicChannels.length !== 0 && (
|
{ publicChannels.length !== 0 && (
|
||||||
<div className="public-channels__content">
|
<div className="public-channels__content">
|
||||||
|
|
|
@ -55,6 +55,10 @@
|
||||||
& .donut-spinner {
|
& .donut-spinner {
|
||||||
margin: 0 var(--sp-tight);
|
margin: 0 var(--sp-tight);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.try-join-with-alias {
|
||||||
|
margin-top: var(--sp-normal);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
&__search-error {
|
&__search-error {
|
||||||
color: var(--bg-danger);
|
color: var(--bg-danger);
|
||||||
|
@ -85,3 +89,12 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.try-join-with-alias {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
& >.text:nth-child(2) {
|
||||||
|
margin: 0 var(--sp-normal);
|
||||||
|
}
|
||||||
|
}
|
|
@ -83,20 +83,24 @@ function guessDMRoomTargetId(room, myUserId) {
|
||||||
* @param {string} roomId
|
* @param {string} roomId
|
||||||
* @param {boolean} isDM
|
* @param {boolean} isDM
|
||||||
*/
|
*/
|
||||||
function join(roomId, isDM) {
|
async function join(roomIdOrAlias, isDM) {
|
||||||
const mx = initMatrix.matrixClient;
|
const mx = initMatrix.matrixClient;
|
||||||
mx.joinRoom(roomId)
|
try {
|
||||||
.then(async () => {
|
const resultRoom = await mx.joinRoom(roomIdOrAlias);
|
||||||
|
|
||||||
if (isDM) {
|
if (isDM) {
|
||||||
const targetUserId = guessDMRoomTargetId(mx.getRoom(roomId), mx.getUserId());
|
const targetUserId = guessDMRoomTargetId(mx.getRoom(resultRoom.roomId), mx.getUserId());
|
||||||
await addRoomToMDirect(roomId, targetUserId);
|
await addRoomToMDirect(resultRoom.roomId, targetUserId);
|
||||||
}
|
}
|
||||||
appDispatcher.dispatch({
|
appDispatcher.dispatch({
|
||||||
type: cons.actions.room.JOIN,
|
type: cons.actions.room.JOIN,
|
||||||
roomId,
|
roomId: resultRoom.roomId,
|
||||||
isDM,
|
isDM,
|
||||||
});
|
});
|
||||||
}).catch();
|
return resultRoom.roomId;
|
||||||
|
} catch (e) {
|
||||||
|
throw new Error(e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -104,8 +108,9 @@ function join(roomId, isDM) {
|
||||||
* @param {string} roomId
|
* @param {string} roomId
|
||||||
* @param {boolean} isDM
|
* @param {boolean} isDM
|
||||||
*/
|
*/
|
||||||
function leave(roomId, isDM) {
|
function leave(roomId) {
|
||||||
const mx = initMatrix.matrixClient;
|
const mx = initMatrix.matrixClient;
|
||||||
|
const isDM = initMatrix.roomList.directs.has(roomId);
|
||||||
mx.leave(roomId)
|
mx.leave(roomId)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
appDispatcher.dispatch({
|
appDispatcher.dispatch({
|
||||||
|
|
Loading…
Reference in a new issue