import React, { useState, useEffect } from 'react'; import PropTypes from 'prop-types'; import './RoomSearch.scss'; import dateFormat from 'dateformat'; import initMatrix from '../../../client/initMatrix'; import cons from '../../../client/state/cons'; import { selectRoom } from '../../../client/action/navigation'; import Text from '../../atoms/text/Text'; import RawIcon from '../../atoms/system-icons/RawIcon'; import Button from '../../atoms/button/Button'; import Input from '../../atoms/input/Input'; import Spinner from '../../atoms/spinner/Spinner'; import { MenuHeader } from '../../atoms/context-menu/ContextMenu'; import { Message } from '../message/Message'; import SearchIC from '../../../../public/res/ic/outlined/search.svg'; import { useStore } from '../../hooks/useStore'; const roomIdToBackup = new Map(); function useRoomSearch(roomId) { const [searchData, setSearchData] = useState(roomIdToBackup.get(roomId) ?? null); const [status, setStatus] = useState({ type: cons.status.PRE_FLIGHT, term: null, }); const mountStore = useStore(roomId); const mx = initMatrix.matrixClient; useEffect(() => mountStore.setItem(true), [roomId]); useEffect(() => { if (searchData?.results?.length > 0) { roomIdToBackup.set(roomId, searchData); } else { roomIdToBackup.delete(roomId); } }, [searchData]); const search = async (term) => { setSearchData(null); if (term === '') { setStatus({ type: cons.status.PRE_FLIGHT, term: null }); return; } setStatus({ type: cons.status.IN_FLIGHT, term }); const body = { search_categories: { room_events: { search_term: term, filter: { limit: 10, rooms: [roomId], }, order_by: 'recent', event_context: { before_limit: 0, after_limit: 0, include_profile: true, }, }, }, }; try { const res = await mx.search({ body }); const data = mx.processRoomEventsSearch({ _query: body, results: [], highlights: [], }, res); if (!mountStore.getItem()) return; setStatus({ type: cons.status.SUCCESS, term }); setSearchData(data); if (!mountStore.getItem()) return; } catch (error) { setSearchData(null); setStatus({ type: cons.status.ERROR, term }); } }; const paginate = async () => { if (searchData === null) return; const term = searchData._query.search_categories.room_events.search_term; setStatus({ type: cons.status.IN_FLIGHT, term }); try { const data = await mx.backPaginateRoomEventsSearch(searchData); if (!mountStore.getItem()) return; setStatus({ type: cons.status.SUCCESS, term }); setSearchData(data); } catch (error) { if (!mountStore.getItem()) return; setSearchData(null); setStatus({ type: cons.status.ERROR, term }); } }; return [searchData, search, paginate, status]; } function RoomSearch({ roomId }) { const [searchData, search, paginate, status] = useRoomSearch(roomId); const mx = initMatrix.matrixClient; const isRoomEncrypted = mx.isRoomEncrypted(roomId); const searchTerm = searchData?._query.search_categories.room_events.search_term ?? ''; const handleSearch = (e) => { e.preventDefault(); if (isRoomEncrypted) return; const searchTermInput = e.target.elements['room-search-input']; const term = searchTermInput.value.trim(); search(term); }; const renderTimeline = (timeline) => (