import React, { useState, useEffect } from 'react'; import PropTypes from 'prop-types'; import './SpaceAddExisting.scss'; import { twemojify } from '../../../util/twemojify'; import initMatrix from '../../../client/initMatrix'; import cons from '../../../client/state/cons'; import navigation from '../../../client/state/navigation'; import { joinRuleToIconSrc, getIdServer, genRoomVia } from '../../../util/matrixUtil'; import { Debounce } from '../../../util/common'; import Text from '../../atoms/text/Text'; import RawIcon from '../../atoms/system-icons/RawIcon'; import Button from '../../atoms/button/Button'; import IconButton from '../../atoms/button/IconButton'; import Checkbox from '../../atoms/button/Checkbox'; import Input from '../../atoms/input/Input'; import Spinner from '../../atoms/spinner/Spinner'; import RoomSelector from '../room-selector/RoomSelector'; import Dialog from '../dialog/Dialog'; 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 [allRoomIds, setAllRoomIds] = useState([]); const [selected, setSelected] = useState([]); const [searchIds, setSearchIds] = useState(null); const mx = initMatrix.matrixClient; const { spaces, rooms, directs, roomIdToParents, } = initMatrix.roomList; useEffect(() => { const allIds = [...spaces, ...rooms, ...directs].filter((rId) => ( rId !== roomId && !roomIdToParents.get(rId)?.has(roomId) )); setAllRoomIds(allIds); }, [roomId]); const toggleSelection = (rId) => { if (process !== null) return; const newSelected = [...selected]; const selectedIndex = newSelected.indexOf(rId); if (selectedIndex > -1) { newSelected.splice(selectedIndex, 1); setSelected(newSelected); return; } newSelected.push(rId); setSelected(newSelected); }; 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; const allIds = [...spaces, ...rooms, ...directs].filter((rId) => ( rId !== roomId && !roomIdToParents.get(rId)?.has(roomId) && !selected.includes(rId) )); setAllRoomIds(allIds); setProcess(null); setSelected([]); }; const handleSearch = (ev) => { const term = ev.target.value.toLocaleLowerCase().replaceAll(' ', ''); if (term === '') { setSearchIds(null); return; } debounce._(() => { const searchedIds = allRoomIds.filter((rId) => { let name = mx.getRoom(rId)?.name; if (!name) return false; name = name.normalize('NFKC') .toLocaleLowerCase() .replaceAll(' ', ''); return name.includes(term); }); setSearchIds(searchedIds); }, 200)(); }; const handleSearchClear = (ev) => { const btn = ev.currentTarget; btn.parentElement.searchInput.value = ''; setSearchIds(null); }; return ( <>
{searchIds?.length === 0 &&