Add option to add existing room in space

Signed-off-by: Ajay Bura <ajbura@gmail.com>
This commit is contained in:
Ajay Bura 2022-02-23 19:30:48 +05:30
parent 2308578622
commit 6c4085398e
2 changed files with 92 additions and 14 deletions

View file

@ -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 navigation from '../../../client/state/navigation'; import navigation from '../../../client/state/navigation';
import { joinRuleToIconSrc } from '../../../util/matrixUtil'; import { joinRuleToIconSrc, getIdServer, genRoomVia } from '../../../util/matrixUtil';
import { Debounce } from '../../../util/common'; import { Debounce } from '../../../util/common';
import Text from '../../atoms/text/Text'; import Text from '../../atoms/text/Text';
@ -23,7 +23,10 @@ import Dialog from '../dialog/Dialog';
import CrossIC from '../../../../public/res/ic/outlined/cross.svg'; import CrossIC from '../../../../public/res/ic/outlined/cross.svg';
import SearchIC from '../../../../public/res/ic/outlined/search.svg'; import SearchIC from '../../../../public/res/ic/outlined/search.svg';
import { useStore } from '../../hooks/useStore';
function SpaceAddExistingContent({ roomId }) { function SpaceAddExistingContent({ roomId }) {
const mountStore = useStore(roomId);
const [debounce] = useState(new Debounce()); const [debounce] = useState(new Debounce());
const [process, setProcess] = useState(null); const [process, setProcess] = useState(null);
const [selected, setSelected] = useState([]); const [selected, setSelected] = useState([]);
@ -75,6 +78,26 @@ function SpaceAddExistingContent({ roomId }) {
const handleAdd = async () => { const handleAdd = async () => {
setProcess(`Adding ${selected.length} items...`); setProcess(`Adding ${selected.length} items...`);
const promises = selected.map((rId) => {
const room = mx.getRoom(rId);
const via = genRoomVia(room);
if (via.length === 0) {
via.push(getIdServer(rId));
}
return mx.sendStateEvent(roomId, 'm.space.child', {
auto_join: false,
suggested: false,
via,
}, rId);
});
mountStore.setItem(true);
await Promise.allSettled(promises);
if (mountStore.getItem() !== true) return;
setSelected([]);
setProcess(null);
}; };
return ( return (

View file

@ -9,7 +9,7 @@ import SpaceLockIC from '../../public/res/ic/outlined/space-lock.svg';
const WELL_KNOWN_URI = '/.well-known/matrix/client'; const WELL_KNOWN_URI = '/.well-known/matrix/client';
async function getBaseUrl(servername) { export async function getBaseUrl(servername) {
let protocol = 'https://'; let protocol = 'https://';
if (servername.match(/^https?:\/\//) !== null) protocol = ''; if (servername.match(/^https?:\/\//) !== null) protocol = '';
const serverDiscoveryUrl = `${protocol}${servername}${WELL_KNOWN_URI}`; const serverDiscoveryUrl = `${protocol}${servername}${WELL_KNOWN_URI}`;
@ -24,7 +24,7 @@ async function getBaseUrl(servername) {
} }
} }
function getUsername(userId) { export function getUsername(userId) {
const mx = initMatrix.matrixClient; const mx = initMatrix.matrixClient;
const user = mx.getUser(userId); const user = mx.getUser(userId);
if (user === null) return userId; if (user === null) return userId;
@ -35,11 +35,11 @@ function getUsername(userId) {
return username; return username;
} }
function getUsernameOfRoomMember(roomMember) { export function getUsernameOfRoomMember(roomMember) {
return roomMember.name || roomMember.userId; return roomMember.name || roomMember.userId;
} }
async function isRoomAliasAvailable(alias) { export async function isRoomAliasAvailable(alias) {
try { try {
const result = await initMatrix.matrixClient.resolveRoomAlias(alias); const result = await initMatrix.matrixClient.resolveRoomAlias(alias);
if (result.room_id) return false; if (result.room_id) return false;
@ -50,7 +50,7 @@ async function isRoomAliasAvailable(alias) {
} }
} }
function getPowerLabel(powerLevel) { export function getPowerLabel(powerLevel) {
if (powerLevel > 9000) return 'Goku'; if (powerLevel > 9000) return 'Goku';
if (powerLevel > 100) return 'Founder'; if (powerLevel > 100) return 'Founder';
if (powerLevel === 100) return 'Admin'; if (powerLevel === 100) return 'Admin';
@ -58,7 +58,7 @@ function getPowerLabel(powerLevel) {
return null; return null;
} }
function parseReply(rawBody) { export function parseReply(rawBody) {
if (rawBody?.indexOf('>') !== 0) return null; if (rawBody?.indexOf('>') !== 0) return null;
let body = rawBody.slice(rawBody.indexOf('<') + 1); let body = rawBody.slice(rawBody.indexOf('<') + 1);
const user = body.slice(0, body.indexOf('>')); const user = body.slice(0, body.indexOf('>'));
@ -79,7 +79,7 @@ function parseReply(rawBody) {
}; };
} }
function hasDMWith(userId) { export function hasDMWith(userId) {
const mx = initMatrix.matrixClient; const mx = initMatrix.matrixClient;
const directIds = [...initMatrix.roomList.directs]; const directIds = [...initMatrix.roomList.directs];
@ -93,7 +93,7 @@ function hasDMWith(userId) {
}); });
} }
function joinRuleToIconSrc(joinRule, isSpace) { export function joinRuleToIconSrc(joinRule, isSpace) {
return ({ return ({
restricted: () => (isSpace ? SpaceIC : HashIC), restricted: () => (isSpace ? SpaceIC : HashIC),
invite: () => (isSpace ? SpaceLockIC : HashLockIC), invite: () => (isSpace ? SpaceLockIC : HashLockIC),
@ -101,8 +101,63 @@ function joinRuleToIconSrc(joinRule, isSpace) {
}[joinRule]?.() || null); }[joinRule]?.() || null);
} }
export { // NOTE: it gives userId with minimum power level 50;
getBaseUrl, getUsername, getUsernameOfRoomMember, function getHighestPowerUserId(room) {
isRoomAliasAvailable, getPowerLabel, parseReply, const userIdToPower = room.currentState.getStateEvents('m.room.power_levels', '')?.getContent().users;
hasDMWith, joinRuleToIconSrc, let powerUserId = null;
}; if (!userIdToPower) return powerUserId;
Object.keys(userIdToPower).forEach((userId) => {
if (userIdToPower[userId] < 50) return;
if (powerUserId === null) {
powerUserId = userId;
return;
}
if (userIdToPower[userId] > userIdToPower[powerUserId]) {
powerUserId = userId;
}
});
return powerUserId;
}
export function getIdServer(userId) {
const idParts = userId.split(':');
return idParts[1];
}
export function getServerToPopulation(room) {
const members = room.getMembers();
const serverToPop = {};
members?.forEach((member) => {
const { userId } = member;
const server = getIdServer(userId);
const serverPop = serverToPop[server];
if (serverPop === undefined) {
serverToPop[server] = 1;
return;
}
serverToPop[server] = serverPop + 1;
});
return serverToPop;
}
export function genRoomVia(room) {
const via = [];
const userId = getHighestPowerUserId(room);
if (userId) {
const server = getIdServer(userId);
if (server) via.push(server);
}
const serverToPop = getServerToPopulation(room);
const sortedServers = Object.keys(serverToPop).sort(
(svrA, svrB) => serverToPop[svrB] - serverToPop[svrA],
);
const mostPop3 = sortedServers.slice(0, 3);
if (via.length === 0) return mostPop3;
if (mostPop3.includes(via[0])) {
mostPop3.splice(mostPop3.indexOf(via[0]), 1);
}
return via.concat(mostPop3.slice(0, 2));
}