import React, { useState, useEffect, useRef } from 'react';
import PropTypes from 'prop-types';
import './InviteUser.scss';
import initMatrix from '../../../client/initMatrix';
import cons from '../../../client/state/cons';
import * as roomActions from '../../../client/action/room';
import { selectRoom } from '../../../client/action/navigation';
import Text from '../../atoms/text/Text';
import Button from '../../atoms/button/Button';
import IconButton from '../../atoms/button/IconButton';
import Spinner from '../../atoms/spinner/Spinner';
import Input from '../../atoms/input/Input';
import PopupWindow from '../../molecules/popup-window/PopupWindow';
import ChannelTile from '../../molecules/channel-tile/ChannelTile';
import CrossIC from '../../../../public/res/ic/outlined/cross.svg';
import UserIC from '../../../../public/res/ic/outlined/user.svg';
function InviteUser({
isOpen, roomId, searchTerm, onRequestClose,
}) {
const [isSearching, updateIsSearching] = useState(false);
const [searchQuery, updateSearchQuery] = useState({});
const [users, updateUsers] = useState([]);
const [procUsers, updateProcUsers] = useState(new Set()); // proc stands for processing.
const [procUserError, updateUserProcError] = useState(new Map());
const [createdDM, updateCreatedDM] = useState(new Map());
const [roomIdToUserId, updateRoomIdToUserId] = useState(new Map());
const [invitedUserIds, updateInvitedUserIds] = useState(new Set());
const usernameRef = useRef(null);
const mx = initMatrix.matrixClient;
function getMapCopy(myMap) {
const newMap = new Map();
myMap.forEach((data, key) => {
newMap.set(key, data);
});
return newMap;
}
function addUserToProc(userId) {
procUsers.add(userId);
updateProcUsers(new Set(Array.from(procUsers)));
}
function deleteUserFromProc(userId) {
procUsers.delete(userId);
updateProcUsers(new Set(Array.from(procUsers)));
}
function onDMCreated(newRoomId) {
const myDMPartnerId = roomIdToUserId.get(newRoomId);
if (typeof myDMPartnerId === 'undefined') return;
createdDM.set(myDMPartnerId, newRoomId);
roomIdToUserId.delete(newRoomId);
deleteUserFromProc(myDMPartnerId);
updateCreatedDM(getMapCopy(createdDM));
updateRoomIdToUserId(getMapCopy(roomIdToUserId));
}
async function searchUser(username) {
const inputUsername = username.trim();
if (isSearching || inputUsername === '' || inputUsername === searchQuery.username) return;
const isInputUserId = inputUsername[0] === '@' && inputUsername.indexOf(':') > 1;
updateIsSearching(true);
updateSearchQuery({ username: inputUsername });
if (isInputUserId) {
try {
const result = await mx.getProfileInfo(inputUsername);
updateUsers([{
user_id: inputUsername,
display_name: result.displayname,
avatar_url: result.avatar_url,
}]);
} catch (e) {
updateSearchQuery({ error: `${inputUsername} not found!` });
}
} else {
try {
const result = await mx.searchUserDirectory({
term: inputUsername,
limit: 20,
});
if (result.results.length === 0) {
updateSearchQuery({ error: `No matches found for "${inputUsername}"!` });
updateIsSearching(false);
return;
}
updateUsers(result.results);
} catch (e) {
updateSearchQuery({ error: 'Something went wrong!' });
}
}
updateIsSearching(false);
}
async function createDM(userId) {
if (mx.getUserId() === userId) return;
try {
addUserToProc(userId);
procUserError.delete(userId);
updateUserProcError(getMapCopy(procUserError));
const result = await roomActions.create({
isPublic: false,
isEncrypted: true,
isDirect: true,
invite: [userId],
});
roomIdToUserId.set(result.room_id, userId);
updateRoomIdToUserId(getMapCopy(roomIdToUserId));
} catch (e) {
deleteUserFromProc(userId);
if (typeof e.message === 'string') procUserError.set(userId, e.message);
else procUserError.set(userId, 'Something went wrong!');
updateUserProcError(getMapCopy(procUserError));
}
}
async function inviteToRoom(userId) {
if (typeof roomId === 'undefined') return;
try {
addUserToProc(userId);
procUserError.delete(userId);
updateUserProcError(getMapCopy(procUserError));
await roomActions.invite(roomId, userId);
invitedUserIds.add(userId);
updateInvitedUserIds(new Set(Array.from(invitedUserIds)));
deleteUserFromProc(userId);
} catch (e) {
deleteUserFromProc(userId);
if (typeof e.message === 'string') procUserError.set(userId, e.message);
else procUserError.set(userId, 'Something went wrong!');
updateUserProcError(getMapCopy(procUserError));
}
}
function renderUserList() {
const renderOptions = (userId) => {
const messageJSX = (message, isPositive) =>