Add AvatarEditorView

This commit is contained in:
Bill 2021-05-12 05:23:15 -04:00
parent 5c73d8d459
commit 2736f262ac
15 changed files with 158 additions and 11 deletions

View File

@ -0,0 +1,8 @@
import { NitroEvent } from 'nitro-renderer';
export class AvatarEditorEvent extends NitroEvent
{
public static SHOW_EDITOR: string = 'AEE_SHOW_EDITOR';
public static HIDE_EDITOR: string = 'AEE_HIDE_EDITOR';
public static TOGGLE_EDITOR: string = 'AEE_TOGGLE_EDITOR';
}

View File

@ -0,0 +1 @@
export * from './AvatarEditorEvent';

View File

@ -1,3 +1,4 @@
export * from './avatar-editor';
export * from './catalog'; export * from './catalog';
export * from './friend-list'; export * from './friend-list';
export * from './inventory'; export * from './inventory';

View File

@ -1,3 +1,4 @@
@import './avatar-editor/AvatarEditorView';
@import './avatar-image/AvatarImage'; @import './avatar-image/AvatarImage';
@import './badge-image/BadgeImage'; @import './badge-image/BadgeImage';
@import './catalog/CatalogView'; @import './catalog/CatalogView';

View File

@ -0,0 +1,8 @@
.nitro-avatar-editor {
width: 550px;
.content-area {
height: 300px;
max-height: 300px;
}
}

View File

@ -0,0 +1,59 @@
import { FC, useCallback, useEffect, useReducer, useState } from 'react';
import { AvatarEditorEvent } from '../../events/avatar-editor';
import { useUiEvent } from '../../hooks/events/ui/ui-event';
import { NitroCardContentView, NitroCardHeaderView, NitroCardTabsView, NitroCardView } from '../../layout';
import { LocalizeText } from '../../utils/LocalizeText';
import { AvatarEditorViewProps } from './AvatarEditorView.types';
import { AvatarEditorContextProvider } from './context/AvatarEditorContext';
import { AvatarEditorReducer, initialAvatarEditor } from './reducers/AvatarEditorReducer';
export const AvatarEditorView: FC<AvatarEditorViewProps> = props =>
{
const [ isVisible, setIsVisible ] = useState(false);
const [ avatarEditorState, dispatchAvatarEditorState ] = useReducer(AvatarEditorReducer, initialAvatarEditor);
const { } = avatarEditorState;
const onAvatarEditorEvent = useCallback((event: AvatarEditorEvent) =>
{
switch(event.type)
{
case AvatarEditorEvent.SHOW_EDITOR:
setIsVisible(true);
return;
case AvatarEditorEvent.HIDE_EDITOR:
setIsVisible(false);
return;
case AvatarEditorEvent.TOGGLE_EDITOR:
setIsVisible(value => !value);
return;
}
}, []);
useUiEvent(AvatarEditorEvent.SHOW_EDITOR, onAvatarEditorEvent);
useUiEvent(AvatarEditorEvent.HIDE_EDITOR, onAvatarEditorEvent);
useUiEvent(AvatarEditorEvent.TOGGLE_EDITOR, onAvatarEditorEvent);
useEffect(() =>
{
if(!isVisible) return;
}, [ isVisible ]);
return (
<AvatarEditorContextProvider value={ { avatarEditorState, dispatchAvatarEditorState } }>
{ isVisible &&
<NitroCardView className="nitro-avatar-editor">
<NitroCardHeaderView headerText={ LocalizeText('avatareditor.title') } onCloseClick={ event => setIsVisible(false) } />
<NitroCardTabsView>
</NitroCardTabsView>
<NitroCardContentView>
<div className="row h-100">
<div className="col-3">
</div>
<div className="col">
</div>
</div>
</NitroCardContentView>
</NitroCardView> }
</AvatarEditorContextProvider>
);
}

View File

@ -0,0 +1,4 @@
export interface AvatarEditorViewProps
{
}

View File

@ -0,0 +1,14 @@
import { createContext, FC, useContext } from 'react';
import { AvatarEditorContextProps, IAvatarEditorContext } from './AvatarEditorContext.types';
const AvatarEditorContext = createContext<IAvatarEditorContext>({
avatarEditorState: null,
dispatchAvatarEditorState: null
});
export const AvatarEditorContextProvider: FC<AvatarEditorContextProps> = props =>
{
return <AvatarEditorContext.Provider value={ props.value }>{ props.children }</AvatarEditorContext.Provider>
}
export const useAvatarEditorContext = () => useContext(AvatarEditorContext);

View File

@ -0,0 +1,13 @@
import { Dispatch, ProviderProps } from 'react';
import { IAvatarEditorAction, IAvatarEditorState } from '../reducers/AvatarEditorReducer';
export interface IAvatarEditorContext
{
avatarEditorState: IAvatarEditorState;
dispatchAvatarEditorState: Dispatch<IAvatarEditorAction>;
}
export interface AvatarEditorContextProps extends ProviderProps<IAvatarEditorContext>
{
}

View File

@ -0,0 +1,30 @@
import { Reducer } from 'react';
export interface IAvatarEditorState
{
}
export interface IAvatarEditorAction
{
type: string;
payload: {
}
}
export class AvatarEditorActions
{
}
export const initialAvatarEditor: IAvatarEditorState = {
}
export const AvatarEditorReducer: Reducer<IAvatarEditorState, IAvatarEditorAction> = (state, action) =>
{
switch(action.type)
{
default:
return state;
}
}

View File

@ -3,6 +3,7 @@ import { useCallback, useEffect, useState } from 'react';
import { useRoomSessionManagerEvent } from '../../hooks/events/nitro/session/room-session-manager-event'; import { useRoomSessionManagerEvent } from '../../hooks/events/nitro/session/room-session-manager-event';
import { TransitionAnimation } from '../../transitions/TransitionAnimation'; import { TransitionAnimation } from '../../transitions/TransitionAnimation';
import { TransitionAnimationTypes } from '../../transitions/TransitionAnimation.types'; import { TransitionAnimationTypes } from '../../transitions/TransitionAnimation.types';
import { AvatarEditorView } from '../avatar-editor/AvatarEditorView';
import { CatalogView } from '../catalog/CatalogView'; import { CatalogView } from '../catalog/CatalogView';
import { FriendListView } from '../friend-list/FriendListView'; import { FriendListView } from '../friend-list/FriendListView';
import { HotelView } from '../hotel-view/HotelView'; import { HotelView } from '../hotel-view/HotelView';
@ -48,6 +49,7 @@ export function MainView(props: MainViewProps): JSX.Element
<TransitionAnimation className="nitro-toolbar-container" type={ TransitionAnimationTypes.FADE_UP } inProp={ isReady } timeout={ 300 }> <TransitionAnimation className="nitro-toolbar-container" type={ TransitionAnimationTypes.FADE_UP } inProp={ isReady } timeout={ 300 }>
<ToolbarView isInRoom={ !landingViewVisible } /> <ToolbarView isInRoom={ !landingViewVisible } />
</TransitionAnimation> </TransitionAnimation>
<AvatarEditorView />
<NavigatorView /> <NavigatorView />
<InventoryView /> <InventoryView />
<CatalogView /> <CatalogView />

View File

@ -1,7 +1,7 @@
import { UserInfoEvent } from 'nitro-renderer/src/nitro/communication/messages/incoming/user/data/UserInfoEvent'; import { UserInfoEvent } from 'nitro-renderer/src/nitro/communication/messages/incoming/user/data/UserInfoEvent';
import { UserInfoDataParser } from 'nitro-renderer/src/nitro/communication/messages/parser/user/data/UserInfoDataParser'; import { UserInfoDataParser } from 'nitro-renderer/src/nitro/communication/messages/parser/user/data/UserInfoDataParser';
import { MouseEvent, useCallback, useState } from 'react'; import { useCallback, useState } from 'react';
import { CatalogEvent, FriendListEvent, InventoryEvent, NavigatorEvent } from '../../events'; import { AvatarEditorEvent, CatalogEvent, FriendListEvent, InventoryEvent, NavigatorEvent } from '../../events';
import { dispatchUiEvent } from '../../hooks/events/ui/ui-event'; import { dispatchUiEvent } from '../../hooks/events/ui/ui-event';
import { CreateMessageHook } from '../../hooks/messages/message-event'; import { CreateMessageHook } from '../../hooks/messages/message-event';
import { TransitionAnimation } from '../../transitions/TransitionAnimation'; import { TransitionAnimation } from '../../transitions/TransitionAnimation';
@ -28,7 +28,7 @@ export function ToolbarView(props: ToolbarViewProps): JSX.Element
setUserInfo(parser.userInfo); setUserInfo(parser.userInfo);
}, []); }, []);
function handleToolbarItemClick(event: MouseEvent, item: string): void const handleToolbarItemClick = useCallback((item: string) =>
{ {
switch(item) switch(item)
{ {
@ -44,8 +44,11 @@ export function ToolbarView(props: ToolbarViewProps): JSX.Element
case ToolbarViewItems.FRIEND_LIST_ITEM: case ToolbarViewItems.FRIEND_LIST_ITEM:
dispatchUiEvent(new CatalogEvent(FriendListEvent.TOGGLE_FRIEND_LIST)); dispatchUiEvent(new CatalogEvent(FriendListEvent.TOGGLE_FRIEND_LIST));
return; return;
case ToolbarViewItems.CLOTHING_ITEM:
dispatchUiEvent(new AvatarEditorEvent(AvatarEditorEvent.TOGGLE_EDITOR));
return;
} }
} }, []);
function toggleMeToolbar(): void function toggleMeToolbar(): void
{ {
@ -60,7 +63,7 @@ export function ToolbarView(props: ToolbarViewProps): JSX.Element
return ( return (
<> <>
<TransitionAnimation type={ TransitionAnimationTypes.FADE_IN } inProp={ isMeExpanded } timeout={ 300 }> <TransitionAnimation type={ TransitionAnimationTypes.FADE_IN } inProp={ isMeExpanded } timeout={ 300 }>
<ToolbarMeView setMeExpanded={ setMeExpanded } /> <ToolbarMeView setMeExpanded={ setMeExpanded } handleToolbarItemClick={ handleToolbarItemClick } />
</TransitionAnimation> </TransitionAnimation>
<div className="d-flex nitro-toolbar py-1 px-3"> <div className="d-flex nitro-toolbar py-1 px-3">
<div className="navigation-items navigation-avatar pe-1 me-2"> <div className="navigation-items navigation-avatar pe-1 me-2">
@ -81,18 +84,18 @@ export function ToolbarView(props: ToolbarViewProps): JSX.Element
<div className="navigation-item"> <div className="navigation-item">
<i className="icon icon-house"></i> <i className="icon icon-house"></i>
</div>) } </div>) }
<div className="navigation-item" onClick={ event => handleToolbarItemClick(event, ToolbarViewItems.NAVIGATOR_ITEM) }> <div className="navigation-item" onClick={ event => handleToolbarItemClick(ToolbarViewItems.NAVIGATOR_ITEM) }>
<i className="icon icon-rooms"></i> <i className="icon icon-rooms"></i>
</div> </div>
<div className="navigation-item" onClick={ event => handleToolbarItemClick(event, ToolbarViewItems.CATALOG_ITEM) }> <div className="navigation-item" onClick={ event => handleToolbarItemClick(ToolbarViewItems.CATALOG_ITEM) }>
<i className="icon icon-catalog"></i> <i className="icon icon-catalog"></i>
</div> </div>
<div className="navigation-item" onClick={ event => handleToolbarItemClick(event, ToolbarViewItems.INVENTORY_ITEM) }> <div className="navigation-item" onClick={ event => handleToolbarItemClick(ToolbarViewItems.INVENTORY_ITEM) }>
<i className="icon icon-inventory"></i> <i className="icon icon-inventory"></i>
{ (unseenInventoryCount > 0) && ( { (unseenInventoryCount > 0) && (
<div className="position-absolute bg-danger px-1 py-0 rounded shadow count">{ unseenInventoryCount }</div>) } <div className="position-absolute bg-danger px-1 py-0 rounded shadow count">{ unseenInventoryCount }</div>) }
</div> </div>
<div className="navigation-item" onClick={ event => handleToolbarItemClick(event, ToolbarViewItems.FRIEND_LIST_ITEM) }> <div className="navigation-item" onClick={ event => handleToolbarItemClick(ToolbarViewItems.FRIEND_LIST_ITEM) }>
<i className="icon icon-friendall"></i> <i className="icon icon-friendall"></i>
{ (unseenFriendListCount > 0) && ( { (unseenFriendListCount > 0) && (
<div className="position-absolute bg-danger px-1 py-0 rounded shadow count">{ unseenFriendListCount }</div>) } <div className="position-absolute bg-danger px-1 py-0 rounded shadow count">{ unseenFriendListCount }</div>) }

View File

@ -9,4 +9,5 @@ export class ToolbarViewItems
public static INVENTORY_ITEM: string = 'TVI_INVENTORY_ITEM'; public static INVENTORY_ITEM: string = 'TVI_INVENTORY_ITEM';
public static CATALOG_ITEM: string = 'TVI_CATALOG_ITEM'; public static CATALOG_ITEM: string = 'TVI_CATALOG_ITEM';
public static FRIEND_LIST_ITEM: string = 'TVI_FRIEND_LIST_ITEM'; public static FRIEND_LIST_ITEM: string = 'TVI_FRIEND_LIST_ITEM';
public static CLOTHING_ITEM: string = 'TVI_CLOTHING_ITEM';
} }

View File

@ -1,10 +1,11 @@
import { MouseEventType } from 'nitro-renderer'; import { MouseEventType } from 'nitro-renderer';
import { useEffect, useRef } from 'react'; import { useEffect, useRef } from 'react';
import { ToolbarViewItems } from '../ToolbarView.types';
import { ToolbarMeViewProps } from './ToolbarMeView.types'; import { ToolbarMeViewProps } from './ToolbarMeView.types';
export function ToolbarMeView(props: ToolbarMeViewProps): JSX.Element export function ToolbarMeView(props: ToolbarMeViewProps): JSX.Element
{ {
const { setMeExpanded = null } = props; const { setMeExpanded = null, handleToolbarItemClick = null } = props;
const elementRef = useRef<HTMLDivElement>(); const elementRef = useRef<HTMLDivElement>();
@ -46,7 +47,7 @@ export function ToolbarMeView(props: ToolbarMeViewProps): JSX.Element
<div className="navigation-item"> <div className="navigation-item">
<i className="icon icon-me-rooms"></i> <i className="icon icon-me-rooms"></i>
</div> </div>
<div className="navigation-item"> <div className="navigation-item" onClick={ event => handleToolbarItemClick(ToolbarViewItems.CLOTHING_ITEM) }>
<i className="icon icon-me-clothing"></i> <i className="icon icon-me-clothing"></i>
</div> </div>
<div className="navigation-item"> <div className="navigation-item">

View File

@ -3,4 +3,5 @@ import { Dispatch, SetStateAction } from 'react';
export interface ToolbarMeViewProps export interface ToolbarMeViewProps
{ {
setMeExpanded: Dispatch<SetStateAction<boolean>>; setMeExpanded: Dispatch<SetStateAction<boolean>>;
handleToolbarItemClick: (item: string) => void;
} }