import initMatrix from '../../../client/initMatrix';
import cons from '../../../client/state/cons';
import navigation from '../../../client/state/navigation';
-import { joinRuleToIconSrc } from '../../../util/matrixUtil';
+import { joinRuleToIconSrc, getIdServer, genRoomVia } from '../../../util/matrixUtil';
import { Debounce } from '../../../util/common';
import Text from '../../atoms/text/Text';
import CrossIC from '../../../../public/res/ic/outlined/cross.svg';
import SearchIC from '../../../../public/res/ic/outlined/search.svg';
+import { useStore } from '../../hooks/useStore';
+
function SpaceAddExistingContent({ roomId }) {
+ const mountStore = useStore(roomId);
const [debounce] = useState(new Debounce());
const [process, setProcess] = useState(null);
const [selected, setSelected] = useState([]);
const handleAdd = async () => {
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 (
const WELL_KNOWN_URI = '/.well-known/matrix/client';
-async function getBaseUrl(servername) {
+export async function getBaseUrl(servername) {
let protocol = 'https://';
if (servername.match(/^https?:\/\//) !== null) protocol = '';
const serverDiscoveryUrl = `${protocol}${servername}${WELL_KNOWN_URI}`;
}
}
-function getUsername(userId) {
+export function getUsername(userId) {
const mx = initMatrix.matrixClient;
const user = mx.getUser(userId);
if (user === null) return userId;
return username;
}
-function getUsernameOfRoomMember(roomMember) {
+export function getUsernameOfRoomMember(roomMember) {
return roomMember.name || roomMember.userId;
}
-async function isRoomAliasAvailable(alias) {
+export async function isRoomAliasAvailable(alias) {
try {
const result = await initMatrix.matrixClient.resolveRoomAlias(alias);
if (result.room_id) return false;
}
}
-function getPowerLabel(powerLevel) {
+export function getPowerLabel(powerLevel) {
if (powerLevel > 9000) return 'Goku';
if (powerLevel > 100) return 'Founder';
if (powerLevel === 100) return 'Admin';
return null;
}
-function parseReply(rawBody) {
+export function parseReply(rawBody) {
if (rawBody?.indexOf('>') !== 0) return null;
let body = rawBody.slice(rawBody.indexOf('<') + 1);
const user = body.slice(0, body.indexOf('>'));
};
}
-function hasDMWith(userId) {
+export function hasDMWith(userId) {
const mx = initMatrix.matrixClient;
const directIds = [...initMatrix.roomList.directs];
});
}
-function joinRuleToIconSrc(joinRule, isSpace) {
+export function joinRuleToIconSrc(joinRule, isSpace) {
return ({
restricted: () => (isSpace ? SpaceIC : HashIC),
invite: () => (isSpace ? SpaceLockIC : HashLockIC),
}[joinRule]?.() || null);
}
-export {
- getBaseUrl, getUsername, getUsernameOfRoomMember,
- isRoomAliasAvailable, getPowerLabel, parseReply,
- hasDMWith, joinRuleToIconSrc,
-};
+// NOTE: it gives userId with minimum power level 50;
+function getHighestPowerUserId(room) {
+ const userIdToPower = room.currentState.getStateEvents('m.room.power_levels', '')?.getContent().users;
+ 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));
+}