import { FurniturePickupAllComposer, GetSessionDataManager } from '@nitrots/nitro-renderer'; import { FC, useEffect, useMemo, useState } from 'react'; import { LocalizeText, RoomObjectItem, SendMessageComposer, chooserSelectionVisualizer } from '../../../../api'; import { Button, Flex, InfiniteScroll, NitroCardContentView, NitroCardHeaderView, NitroCardView, Text } from '../../../../common'; import { NitroInput, classNames } from '../../../../layout'; const LIMIT_FURNI_PICKALL = 100; interface ChooserWidgetViewProps { title: string; items: RoomObjectItem[]; selectItem: (item: RoomObjectItem) => void; onClose: () => void; pickallFurni?: boolean; type?: 'furni' | 'users'; } export const ChooserWidgetView: FC = props => { const { title = null, items = [], selectItem = null, onClose = null, pickallFurni = false, type = 'furni' } = props; const [ selectedItems, setSelectedItems ] = useState([]); const [ searchValue, setSearchValue ] = useState(''); const [ checkAll, setCheckAll ] = useState(false); const [ checkedIds, setCheckedIds ] = useState([]); const canSeeId = GetSessionDataManager().isModerator; const ownerNames = useMemo(() => { const names = Array.from(new Set(items.map(item => item.ownerName || 'Unknown'))); return names.sort(); }, [ items ]); const [ selectedFilter, setSelectedFilter ] = useState(() => { if(pickallFurni) return 'all'; return ownerNames.length > 0 ? ownerNames[0] : ''; }); useEffect(() => { if(!pickallFurni && ownerNames.length > 0 && !selectedFilter) setSelectedFilter(ownerNames[0]); }, [ pickallFurni, ownerNames, selectedFilter ]); const checkedId = (id?: number) => { if(id) { if(isChecked(id)) setCheckedIds(checkedIds.filter(x => x !== id)); else if(checkedIds.length < LIMIT_FURNI_PICKALL) setCheckedIds([ ...checkedIds, id ]); } else { setCheckAll(value => !value); if(!checkAll) { const allItems = filteredItems.slice(0, LIMIT_FURNI_PICKALL); setCheckedIds(allItems.map(x => x.id)); setSelectedItems(allItems); } else { setCheckedIds([]); setSelectedItems([]); chooserSelectionVisualizer.clearAll(); } } } const isChecked = (id: number) => checkedIds.includes(id); const onClickPickAll = () => { SendMessageComposer(new FurniturePickupAllComposer(...checkedIds)); setCheckedIds([]); setCheckAll(false); chooserSelectionVisualizer.clearAll(); setSelectedItems([]); } const filteredItems = useMemo(() => { const value = searchValue.toLocaleLowerCase(); return items .filter(item => { const matchesSearch = item.name?.toLocaleLowerCase().includes(value); const matchesFilter = !pickallFurni ? (selectedFilter ? item.ownerName === selectedFilter : true) : (selectedFilter === 'all' || item.ownerName === selectedFilter); return matchesSearch && matchesFilter; }) .sort((a, b) => a.name.localeCompare(b.name)); }, [ items, searchValue, selectedFilter, pickallFurni ]); useEffect(() => { if(selectedItems.length === 0) return; selectItem(selectedItems[selectedItems.length - 1]); chooserSelectionVisualizer.clearAll(); selectedItems.forEach(item => { if(item.id && item.category) chooserSelectionVisualizer.show(item.id, item.category); }); }, [ selectedItems, selectItem ]); const toggleItemSelection = (item: RoomObjectItem) => { setSelectedItems(prev => { if(prev.some(selected => selected.id === item.id)) { chooserSelectionVisualizer.hide(item.id, item.category); return prev.filter(selected => selected.id !== item.id); } else { return [ ...prev, item ]; } }); }; const handleClose = () => { chooserSelectionVisualizer.clearAll(); setSelectedItems([]); onClose(); }; return ( setSearchValue(event.target.value) } /> { pickallFurni && ( )} { pickallFurni && ( checkedId() } /> { LocalizeText('widget.chooser.checkall') } )} ( item.id === row.id) && 'bg-muted') } pointer onClick={ () => { toggleItemSelection(row); if(pickallFurni) checkedId(row.id); } } > { pickallFurni && ( checkedId(row.id) } onClick={ e => { e.stopPropagation(); toggleItemSelection(row); } } /> )} { row.name }{ canSeeId && (' - ' + row.id) } { type === 'furni' && row.ownerName && row.ownerName !== '-' && ` (Owner: ${row.ownerName})` } )} /> { pickallFurni && ( )} ); };