import { AddLinkEventTracker, ILinkEventTracker, RemoveLinkEventTracker } from '@nitrots/nitro-renderer'; import { FC, useCallback, useEffect, useState } from 'react'; import { NitroCardContentView, NitroCardHeaderView, NitroCardTabsItemView, NitroCardTabsView, NitroCardView } from '../../common'; import { useHasPermission } from '../../hooks'; import { useFurniEditor } from '../../hooks/furni-editor'; import { FurniEditorEditView } from './views/FurniEditorEditView'; import { FurniEditorSearchView } from './views/FurniEditorSearchView'; const TAB_SEARCH = 0; const TAB_EDIT = 1; export const FurniEditorView: FC<{}> = () => { const [ isVisible, setIsVisible ] = useState(false); const [ activeTab, setActiveTab ] = useState(TAB_SEARCH); const { items, total, page, loading, error, clearError, selectedItem, setSelectedItem, furniDataEntry, interactions, searchItems, loadDetail, loadBySpriteId, updateItem, deleteItem, loadInteractions, updateFurnidata, revertFurnidata, importText, importResult } = useFurniEditor(); const isMod = useHasPermission('acc_catalogfurni'); // Auto-switch to edit tab when an item is selected useEffect(() => { if(selectedItem) setActiveTab(TAB_EDIT); }, [ selectedItem ]); useEffect(() => { if(!isMod) return; const linkTracker: ILinkEventTracker = { linkReceived: (url: string) => { const parts = url.split('/'); if(parts.length < 2) return; switch(parts[1]) { case 'show': setIsVisible(true); return; case 'hide': setIsVisible(false); return; case 'toggle': setIsVisible(prev => !prev); return; } }, eventUrlPrefix: 'furni-editor/' }; AddLinkEventTracker(linkTracker); return () => RemoveLinkEventTracker(linkTracker); }, [ isMod ]); useEffect(() => { if(isVisible) loadInteractions(); }, [ isVisible ]); // Escape to close useEffect(() => { if(!isVisible) return; const handler = (e: KeyboardEvent) => { if(e.key === 'Escape') setIsVisible(false); }; window.addEventListener('keydown', handler); return () => window.removeEventListener('keydown', handler); }, [ isVisible ]); useEffect(() => { if(!isMod) return; const handler = (e: CustomEvent<{ spriteId: number }>) => { const { spriteId } = e.detail; setIsVisible(true); loadBySpriteId(spriteId); }; window.addEventListener('furni-editor:open', handler); return () => window.removeEventListener('furni-editor:open', handler); }, [ isMod, loadBySpriteId ]); const handleSelect = useCallback((id: number) => { loadDetail(id); }, [ loadDetail ]); const handleBack = useCallback(() => { setSelectedItem(null); setActiveTab(TAB_SEARCH); }, [ setSelectedItem ]); const handleClose = useCallback(() => { setIsVisible(false); }, []); if(!isVisible || !isMod) return null; return ( setActiveTab(TAB_SEARCH) }> Search selectedItem && setActiveTab(TAB_EDIT) }> Edit { error &&
{ error } x
} { activeTab === TAB_SEARCH && } { activeTab === TAB_EDIT && selectedItem && }
); };