Update chooser widget

This commit is contained in:
Bill 2022-02-25 19:31:26 -05:00
parent d54ea63f8b
commit da810998c5
6 changed files with 58 additions and 62 deletions

View File

@ -71,6 +71,9 @@ $room-info-width: 325px;
$nitro-mod-tools-width: 175px; $nitro-mod-tools-width: 175px;
$nitro-chooser-width: 200px;
$nitro-chooser-height: 200px;
.nitro-app { .nitro-app {
width: 100%; width: 100%;
height: 100%; height: 100%;

View File

@ -1,16 +1,4 @@
.nitro-chooser-widget { .nitro-chooser-widget {
width: $nitro-chooser-width;
height: $nitro-chooser-height;
.chooser-container {
min-height: 150px;
.list-item {
color: black;
overflow: hidden;
&.selected {
background-color: cadetblue;
}
}
}
} }

View File

@ -2,16 +2,24 @@ import { FC, useCallback, useMemo, useState } from 'react';
import { AutoSizer, List, ListRowProps, ListRowRenderer } from 'react-virtualized'; import { AutoSizer, List, ListRowProps, ListRowRenderer } from 'react-virtualized';
import { RoomObjectItem, RoomWidgetRoomObjectMessage } from '../../../../api'; import { RoomObjectItem, RoomWidgetRoomObjectMessage } from '../../../../api';
import { LocalizeText } from '../../../../api/utils'; import { LocalizeText } from '../../../../api/utils';
import { Column, Flex, Text } from '../../../../common';
import { NitroCardContentView, NitroCardHeaderView, NitroCardView } from '../../../../layout'; import { NitroCardContentView, NitroCardHeaderView, NitroCardView } from '../../../../layout';
import { useRoomContext } from '../../context/RoomContext'; import { useRoomContext } from '../../context/RoomContext';
import { ChooserWidgetViewProps } from './ChooserWidgetView.type';
interface ChooserWidgetViewProps
{
title: string;
items: RoomObjectItem[];
displayItemId: boolean;
onCloseClick: () => void;
}
export const ChooserWidgetView: FC<ChooserWidgetViewProps> = props => export const ChooserWidgetView: FC<ChooserWidgetViewProps> = props =>
{ {
const { title = null, items = null, displayItemId = false, onCloseClick = null } = props; const { title = null, items = null, displayItemId = false, onCloseClick = null } = props;
const [ selectedItem, setSelectedItem ] = useState<RoomObjectItem>(null); const [ selectedItem, setSelectedItem ] = useState<RoomObjectItem>(null);
const [ searchValue, setSearchValue ] = useState(''); const [ searchValue, setSearchValue ] = useState('');
const { eventDispatcher = null, widgetHandler = null } = useRoomContext(); const { widgetHandler = null } = useRoomContext();
const filteredItems = useMemo(() => const filteredItems = useMemo(() =>
{ {
@ -21,15 +29,13 @@ export const ChooserWidgetView: FC<ChooserWidgetViewProps> = props =>
const value = searchValue.toLocaleLowerCase(); const value = searchValue.toLocaleLowerCase();
return items.filter(item => return items.filter(item => item.name.toLocaleLowerCase().includes(value));
{
return item.name.toLocaleLowerCase().includes(value);
});
}, [ items, searchValue ]); }, [ items, searchValue ]);
const onItemClick = useCallback((item: RoomObjectItem) => const onItemClick = useCallback((item: RoomObjectItem) =>
{ {
setSelectedItem(item); setSelectedItem(item);
widgetHandler.processWidgetMessage(new RoomWidgetRoomObjectMessage(RoomWidgetRoomObjectMessage.SELECT_OBJECT, item.id, item.category)); widgetHandler.processWidgetMessage(new RoomWidgetRoomObjectMessage(RoomWidgetRoomObjectMessage.SELECT_OBJECT, item.id, item.category));
}, [ widgetHandler, setSelectedItem]); }, [ widgetHandler, setSelectedItem]);
@ -38,24 +44,20 @@ export const ChooserWidgetView: FC<ChooserWidgetViewProps> = props =>
const item = filteredItems[props.index]; const item = filteredItems[props.index];
return ( return (
<div key={ props.key } className={ 'list-item' + ((selectedItem === item) ? ' selected' : '') } style={ props.style } onClick={ () => onItemClick(item) }> <Flex key={ props.key } alignItems="center" position="absolute" className={ 'rounded px-1' + ((selectedItem === item) ? ' bg-muted' : '') } pointer style={ props.style } onClick={ event => onItemClick(item) }>
{ item.name } { displayItemId && (' - ' + item.id) } <Text truncate>{ item.name } { displayItemId && (' - ' + item.id) }</Text>
</div> </Flex>
); );
} }
return ( return (
<NitroCardView className="nitro-chooser-widget"> <NitroCardView className="nitro-chooser-widget">
<NitroCardHeaderView headerText={ title } onCloseClick={ onCloseClick } /> <NitroCardHeaderView headerText={ title } onCloseClick={ onCloseClick } />
<NitroCardContentView> <NitroCardContentView overflow="hidden">
<div className="d-flex mb-1">
<div className="d-flex flex-grow-1 me-1">
<input type="text" className="form-control form-control-sm" placeholder={ LocalizeText('generic.search') } value={searchValue} onChange={event => setSearchValue(event.target.value)} /> <input type="text" className="form-control form-control-sm" placeholder={ LocalizeText('generic.search') } value={searchValue} onChange={event => setSearchValue(event.target.value)} />
</div> <Column fullHeight overflow="auto">
</div> <AutoSizer defaultWidth={ 0 } defaultHeight={ 0 }>
<div className="row w-100 h-100 chooser-container"> { ({ width, height }) =>
<AutoSizer defaultWidth={150} defaultHeight={150}>
{({ height, width }) =>
{ {
return (<List return (<List
width={ width } width={ width }
@ -65,7 +67,7 @@ export const ChooserWidgetView: FC<ChooserWidgetViewProps> = props =>
rowRenderer={ rowRenderer } />) rowRenderer={ rowRenderer } />)
} } } }
</AutoSizer> </AutoSizer>
</div> </Column>
</NitroCardContentView> </NitroCardContentView>
</NitroCardView> </NitroCardView>
); );

View File

@ -1,9 +0,0 @@
import { RoomObjectItem } from '../../../../api';
export interface ChooserWidgetViewProps
{
title: string;
items: RoomObjectItem[];
displayItemId: boolean;
onCloseClick: () => void;
}

View File

@ -1,6 +1,6 @@
import { FC, useCallback, useState } from 'react'; import { FC, useCallback, useState } from 'react';
import { LocalizeText, RoomObjectItem, RoomWidgetChooserContentEvent, RoomWidgetRequestWidgetMessage, RoomWidgetUpdateRoomObjectEvent } from '../../../../api'; import { LocalizeText, RoomObjectItem, RoomWidgetChooserContentEvent, RoomWidgetRequestWidgetMessage, RoomWidgetUpdateRoomObjectEvent } from '../../../../api';
import { CreateEventDispatcherHook } from '../../../../hooks'; import { BatchUpdates, CreateEventDispatcherHook } from '../../../../hooks';
import { useRoomContext } from '../../context/RoomContext'; import { useRoomContext } from '../../context/RoomContext';
import { ChooserWidgetView } from './ChooserWidgetView'; import { ChooserWidgetView } from './ChooserWidgetView';
@ -20,13 +20,16 @@ export const FurniChooserWidgetView: FC<{}> = props =>
if(prevValue) clearTimeout(prevValue); if(prevValue) clearTimeout(prevValue);
return setTimeout(() => widgetHandler.processWidgetMessage(new RoomWidgetRequestWidgetMessage(RoomWidgetRequestWidgetMessage.FURNI_CHOOSER)), 100); return setTimeout(() => widgetHandler.processWidgetMessage(new RoomWidgetRequestWidgetMessage(RoomWidgetRequestWidgetMessage.FURNI_CHOOSER)), 100);
}) });
}, [ isVisible, widgetHandler ]); }, [ isVisible, widgetHandler ]);
const onRoomWidgetChooserContentEvent = useCallback((event: RoomWidgetChooserContentEvent) => const onRoomWidgetChooserContentEvent = useCallback((event: RoomWidgetChooserContentEvent) =>
{
BatchUpdates(() =>
{ {
setItems(event.items); setItems(event.items);
setIsVisible(true); setIsVisible(true);
});
}, []); }, []);
CreateEventDispatcherHook(RoomWidgetChooserContentEvent.FURNI_CHOOSER_CONTENT, eventDispatcher, onRoomWidgetChooserContentEvent); CreateEventDispatcherHook(RoomWidgetChooserContentEvent.FURNI_CHOOSER_CONTENT, eventDispatcher, onRoomWidgetChooserContentEvent);
@ -48,12 +51,15 @@ export const FurniChooserWidgetView: FC<{}> = props =>
CreateEventDispatcherHook(RoomWidgetUpdateRoomObjectEvent.FURNI_REMOVED, eventDispatcher, onRoomWidgetRoomObjectUpdateEvent); CreateEventDispatcherHook(RoomWidgetUpdateRoomObjectEvent.FURNI_REMOVED, eventDispatcher, onRoomWidgetRoomObjectUpdateEvent);
const close = useCallback(() => const close = useCallback(() =>
{
BatchUpdates(() =>
{ {
setIsVisible(false); setIsVisible(false);
setItems(null); setItems(null);
});
}, []); }, []);
if(!isVisible) return null; if(!items) return null;
return <ChooserWidgetView title={ LocalizeText('widget.chooser.furni.title') } displayItemId={ true } items={ items } onCloseClick={ close } />; return <ChooserWidgetView title={ LocalizeText('widget.chooser.furni.title') } displayItemId={ true } items={ items } onCloseClick={ close } />;
} }

View File

@ -1,6 +1,6 @@
import { FC, useCallback, useState } from 'react'; import { FC, useCallback, useState } from 'react';
import { LocalizeText, RoomObjectItem, RoomWidgetChooserContentEvent, RoomWidgetRequestWidgetMessage, RoomWidgetUpdateRoomObjectEvent } from '../../../../api'; import { LocalizeText, RoomObjectItem, RoomWidgetChooserContentEvent, RoomWidgetRequestWidgetMessage, RoomWidgetUpdateRoomObjectEvent } from '../../../../api';
import { CreateEventDispatcherHook } from '../../../../hooks'; import { BatchUpdates, CreateEventDispatcherHook } from '../../../../hooks';
import { useRoomContext } from '../../context/RoomContext'; import { useRoomContext } from '../../context/RoomContext';
import { ChooserWidgetView } from './ChooserWidgetView'; import { ChooserWidgetView } from './ChooserWidgetView';
@ -24,9 +24,12 @@ export const UserChooserWidgetView: FC<{}> = props =>
}, [ isVisible, widgetHandler ]); }, [ isVisible, widgetHandler ]);
const onRoomWidgetChooserContentEvent = useCallback((event: RoomWidgetChooserContentEvent) => const onRoomWidgetChooserContentEvent = useCallback((event: RoomWidgetChooserContentEvent) =>
{
BatchUpdates(() =>
{ {
setItems(event.items); setItems(event.items);
setIsVisible(true); setIsVisible(true);
});
}, []); }, []);
CreateEventDispatcherHook(RoomWidgetChooserContentEvent.USER_CHOOSER_CONTENT, eventDispatcher, onRoomWidgetChooserContentEvent); CreateEventDispatcherHook(RoomWidgetChooserContentEvent.USER_CHOOSER_CONTENT, eventDispatcher, onRoomWidgetChooserContentEvent);
@ -48,9 +51,12 @@ export const UserChooserWidgetView: FC<{}> = props =>
CreateEventDispatcherHook(RoomWidgetUpdateRoomObjectEvent.USER_REMOVED, eventDispatcher, onRoomWidgetRoomObjectUpdateEvent); CreateEventDispatcherHook(RoomWidgetUpdateRoomObjectEvent.USER_REMOVED, eventDispatcher, onRoomWidgetRoomObjectUpdateEvent);
const close = useCallback(() => const close = useCallback(() =>
{
BatchUpdates(() =>
{ {
setIsVisible(false); setIsVisible(false);
setItems(null); setItems(null);
});
}, []); }, []);
if(!isVisible) return null; if(!isVisible) return null;