mirror of
https://github.com/billsonnn/nitro-react.git
synced 2024-11-27 08:00:51 +01:00
Merge branch 'feature/mod-tools' into dev
This commit is contained in:
commit
e2cc64fe6d
10
src/events/mod-tools/ModToolsEvent.ts
Normal file
10
src/events/mod-tools/ModToolsEvent.ts
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
import { NitroEvent } from 'nitro-renderer';
|
||||||
|
|
||||||
|
export class ModToolsEvent extends NitroEvent
|
||||||
|
{
|
||||||
|
public static SHOW_MOD_TOOLS: string = 'MTE_SHOW_MOD_TOOLS';
|
||||||
|
public static HIDE_MOD_TOOLS: string = 'MTE_HIDE_MOD_TOOLS';
|
||||||
|
public static TOGGLE_MOD_TOOLS: string = 'MTE_TOGGLE_MOD_TOOLS';
|
||||||
|
public static SELECT_USER: string = 'MTE_SELECT_USER';
|
||||||
|
public static OPEN_ROOM_INFO: string = 'MTE_OPEN_ROOM_INFO';
|
||||||
|
}
|
18
src/events/mod-tools/ModToolsOpenRoomInfoEvent.ts
Normal file
18
src/events/mod-tools/ModToolsOpenRoomInfoEvent.ts
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
import { ModToolsEvent } from './ModToolsEvent';
|
||||||
|
|
||||||
|
export class ModToolsOpenRoomInfoEvent extends ModToolsEvent
|
||||||
|
{
|
||||||
|
private _roomId: number;
|
||||||
|
|
||||||
|
constructor(roomId: number)
|
||||||
|
{
|
||||||
|
super(ModToolsEvent.OPEN_ROOM_INFO);
|
||||||
|
|
||||||
|
this._roomId = roomId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get roomId(): number
|
||||||
|
{
|
||||||
|
return this._roomId;
|
||||||
|
}
|
||||||
|
}
|
25
src/events/mod-tools/ModToolsSelectUserEvent.ts
Normal file
25
src/events/mod-tools/ModToolsSelectUserEvent.ts
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
import { ModToolsEvent } from './ModToolsEvent';
|
||||||
|
|
||||||
|
export class ModToolsSelectUserEvent extends ModToolsEvent
|
||||||
|
{
|
||||||
|
private _webID: number;
|
||||||
|
private _name: string;
|
||||||
|
|
||||||
|
constructor(webID: number, name: string)
|
||||||
|
{
|
||||||
|
super(ModToolsEvent.SELECT_USER);
|
||||||
|
|
||||||
|
this._webID = webID;
|
||||||
|
this._name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get webID(): number
|
||||||
|
{
|
||||||
|
return this._webID;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get name(): string
|
||||||
|
{
|
||||||
|
return this._name;
|
||||||
|
}
|
||||||
|
}
|
@ -15,3 +15,4 @@
|
|||||||
@import './room-host/RoomHostView';
|
@import './room-host/RoomHostView';
|
||||||
@import './toolbar/ToolbarView';
|
@import './toolbar/ToolbarView';
|
||||||
@import './wired/WiredView';
|
@import './wired/WiredView';
|
||||||
|
@import './mod-tools/ModToolsView';
|
||||||
|
@ -6,6 +6,7 @@ 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';
|
||||||
import { InventoryView } from '../inventory/InventoryView';
|
import { InventoryView } from '../inventory/InventoryView';
|
||||||
|
import { ModToolsView } from '../mod-tools/ModToolsView';
|
||||||
import { NavigatorView } from '../navigator/NavigatorView';
|
import { NavigatorView } from '../navigator/NavigatorView';
|
||||||
import { NotificationCenterView } from '../notification-center/NotificationCenterView';
|
import { NotificationCenterView } from '../notification-center/NotificationCenterView';
|
||||||
import { RightSideView } from '../right-side/RightSideView';
|
import { RightSideView } from '../right-side/RightSideView';
|
||||||
@ -46,6 +47,7 @@ export const MainView: FC<MainViewProps> = props =>
|
|||||||
<div className="nitro-main">
|
<div className="nitro-main">
|
||||||
{ landingViewVisible && <HotelView /> }
|
{ landingViewVisible && <HotelView /> }
|
||||||
<ToolbarView isInRoom={ !landingViewVisible } />
|
<ToolbarView isInRoom={ !landingViewVisible } />
|
||||||
|
<ModToolsView />
|
||||||
<RoomHostView />
|
<RoomHostView />
|
||||||
<WiredView />
|
<WiredView />
|
||||||
<AvatarEditorView />
|
<AvatarEditorView />
|
||||||
|
6
src/views/mod-tools/ModToolsView.scss
Normal file
6
src/views/mod-tools/ModToolsView.scss
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
.nitro-mod-tools {
|
||||||
|
width: 200px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@import './views/chatlog/ModToolsChatlogView';
|
||||||
|
@import './views/room/ModToolsRoomView';
|
182
src/views/mod-tools/ModToolsView.tsx
Normal file
182
src/views/mod-tools/ModToolsView.tsx
Normal file
@ -0,0 +1,182 @@
|
|||||||
|
import { RoomEngineEvent } from 'nitro-renderer';
|
||||||
|
import { FC, useCallback, useEffect, useReducer, useState } from 'react';
|
||||||
|
import { ModToolsEvent } from '../../events/mod-tools/ModToolsEvent';
|
||||||
|
import { ModToolsOpenRoomInfoEvent } from '../../events/mod-tools/ModToolsOpenRoomInfoEvent';
|
||||||
|
import { ModToolsSelectUserEvent } from '../../events/mod-tools/ModToolsSelectUserEvent';
|
||||||
|
import { useRoomEngineEvent } from '../../hooks/events';
|
||||||
|
import { dispatchUiEvent, useUiEvent } from '../../hooks/events/ui/ui-event';
|
||||||
|
import { NitroCardContentView, NitroCardHeaderView, NitroCardView } from '../../layout';
|
||||||
|
import { ModToolsContextProvider } from './context/ModToolsContext';
|
||||||
|
import { ModToolsViewProps } from './ModToolsView.types';
|
||||||
|
import { initialModTools, ModToolsActions, ModToolsReducer } from './reducers/ModToolsReducer';
|
||||||
|
import { ModToolsRoomView } from './views/room/ModToolsRoomView';
|
||||||
|
import { ModToolsTicketsView } from './views/tickets/ModToolsTicketsView';
|
||||||
|
import { ModToolsUserView } from './views/user/ModToolsUserView';
|
||||||
|
|
||||||
|
export const ModToolsView: FC<ModToolsViewProps> = props =>
|
||||||
|
{
|
||||||
|
const [ isVisible, setIsVisible ] = useState(false);
|
||||||
|
const [ modToolsState, dispatchModToolsState ] = useReducer(ModToolsReducer, initialModTools);
|
||||||
|
const { currentRoomId = null, selectedUser = null, openRooms = null, openChatlogs = null } = modToolsState;
|
||||||
|
|
||||||
|
const [ isUserVisible, setIsUserVisible ] = useState(false);
|
||||||
|
const [ isTicketsVisible, setIsTicketsVisible ] = useState(false);
|
||||||
|
|
||||||
|
const onModToolsEvent = useCallback((event: ModToolsEvent) =>
|
||||||
|
{
|
||||||
|
switch(event.type)
|
||||||
|
{
|
||||||
|
case ModToolsEvent.SHOW_MOD_TOOLS:
|
||||||
|
setIsVisible(true);
|
||||||
|
return;
|
||||||
|
case ModToolsEvent.HIDE_MOD_TOOLS:
|
||||||
|
setIsVisible(false);
|
||||||
|
return;
|
||||||
|
case ModToolsEvent.TOGGLE_MOD_TOOLS:
|
||||||
|
setIsVisible(value => !value);
|
||||||
|
return;
|
||||||
|
case ModToolsEvent.SELECT_USER: {
|
||||||
|
const castedEvent = (event as ModToolsSelectUserEvent);
|
||||||
|
|
||||||
|
dispatchModToolsState({
|
||||||
|
type: ModToolsActions.SET_SELECTED_USER,
|
||||||
|
payload: {
|
||||||
|
selectedUser: {
|
||||||
|
webID: castedEvent.webID,
|
||||||
|
name: castedEvent.name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
case ModToolsEvent.OPEN_ROOM_INFO: {
|
||||||
|
const castedEvent = (event as ModToolsOpenRoomInfoEvent);
|
||||||
|
|
||||||
|
if(openRooms && openRooms.includes(castedEvent.roomId)) return;
|
||||||
|
|
||||||
|
dispatchModToolsState({
|
||||||
|
type: ModToolsActions.SET_OPEN_ROOMS,
|
||||||
|
payload: {
|
||||||
|
openRooms: [...openRooms, castedEvent.roomId]
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, [ dispatchModToolsState, setIsVisible, openRooms ]);
|
||||||
|
|
||||||
|
useUiEvent(ModToolsEvent.SHOW_MOD_TOOLS, onModToolsEvent);
|
||||||
|
useUiEvent(ModToolsEvent.HIDE_MOD_TOOLS, onModToolsEvent);
|
||||||
|
useUiEvent(ModToolsEvent.TOGGLE_MOD_TOOLS, onModToolsEvent);
|
||||||
|
useUiEvent(ModToolsEvent.SELECT_USER, onModToolsEvent);
|
||||||
|
useUiEvent(ModToolsEvent.OPEN_ROOM_INFO, onModToolsEvent);
|
||||||
|
|
||||||
|
const onRoomEngineEvent = useCallback((event: RoomEngineEvent) =>
|
||||||
|
{
|
||||||
|
switch(event.type)
|
||||||
|
{
|
||||||
|
case RoomEngineEvent.INITIALIZED:
|
||||||
|
dispatchModToolsState({
|
||||||
|
type: ModToolsActions.SET_CURRENT_ROOM_ID,
|
||||||
|
payload: {
|
||||||
|
currentRoomId: event.roomId
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
case RoomEngineEvent.DISPOSED:
|
||||||
|
dispatchModToolsState({
|
||||||
|
type: ModToolsActions.SET_CURRENT_ROOM_ID,
|
||||||
|
payload: {
|
||||||
|
currentRoomId: null
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}, [ dispatchModToolsState ]);
|
||||||
|
|
||||||
|
useRoomEngineEvent(RoomEngineEvent.INITIALIZED, onRoomEngineEvent);
|
||||||
|
useRoomEngineEvent(RoomEngineEvent.DISPOSED, onRoomEngineEvent);
|
||||||
|
|
||||||
|
const handleClick = useCallback((action: string, value?: string) =>
|
||||||
|
{
|
||||||
|
if(!action) return;
|
||||||
|
|
||||||
|
switch(action)
|
||||||
|
{
|
||||||
|
case 'toggle_room': {
|
||||||
|
if(!openRooms)
|
||||||
|
{
|
||||||
|
dispatchUiEvent(new ModToolsOpenRoomInfoEvent(currentRoomId));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const itemIndex = openRooms.indexOf(currentRoomId);
|
||||||
|
|
||||||
|
if(itemIndex > -1)
|
||||||
|
{
|
||||||
|
handleClick('close_room', currentRoomId.toString());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dispatchUiEvent(new ModToolsOpenRoomInfoEvent(currentRoomId));
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
case 'close_room': {
|
||||||
|
const itemIndex = openRooms.indexOf(Number(value));
|
||||||
|
|
||||||
|
const clone = Array.from(openRooms);
|
||||||
|
clone.splice(itemIndex, 1);
|
||||||
|
|
||||||
|
dispatchModToolsState({
|
||||||
|
type: ModToolsActions.SET_OPEN_ROOMS,
|
||||||
|
payload: {
|
||||||
|
openRooms: clone
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
case 'close_chatlog': {
|
||||||
|
const itemIndex = openChatlogs.indexOf(Number(value));
|
||||||
|
|
||||||
|
const clone = Array.from(openChatlogs);
|
||||||
|
clone.splice(itemIndex, 1);
|
||||||
|
|
||||||
|
dispatchModToolsState({
|
||||||
|
type: ModToolsActions.SET_OPEN_CHATLOGS,
|
||||||
|
payload: {
|
||||||
|
openChatlogs: clone
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, [ dispatchModToolsState, openRooms, openChatlogs, currentRoomId ]);
|
||||||
|
|
||||||
|
useEffect(() =>
|
||||||
|
{
|
||||||
|
if(!isVisible) return;
|
||||||
|
}, [ isVisible ]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ModToolsContextProvider value={ { modToolsState, dispatchModToolsState } }>
|
||||||
|
{ isVisible &&
|
||||||
|
<NitroCardView className="nitro-mod-tools" simple={ true }>
|
||||||
|
<NitroCardHeaderView headerText={ "Mod Tools" } onCloseClick={ event => setIsVisible(false) } />
|
||||||
|
<NitroCardContentView className="text-black">
|
||||||
|
<button className="btn btn-primary w-100 mb-2" onClick={ () => handleClick('toggle_room') } disabled={ !currentRoomId }><i className="fas fa-home"></i> Room Tool</button>
|
||||||
|
<button className="btn btn-primary w-100 mb-2" onClick={ () => {} } disabled={ !currentRoomId }><i className="fas fa-comments"></i> Chatlog Tool</button>
|
||||||
|
<button className="btn btn-primary w-100 mb-2" onClick={ () => setIsUserVisible(value => !value) } disabled={ !selectedUser }><i className="fas fa-user"></i> User: { selectedUser ? selectedUser.name : '' }</button>
|
||||||
|
<button className="btn btn-primary w-100" onClick={ () => setIsTicketsVisible(value => !value) }><i className="fas fa-exclamation-circle"></i> Report Tool</button>
|
||||||
|
</NitroCardContentView>
|
||||||
|
</NitroCardView> }
|
||||||
|
{ openRooms && openRooms.map(roomId =>
|
||||||
|
{
|
||||||
|
return <ModToolsRoomView key={ roomId } roomId={ roomId } onCloseClick={ () => handleClick('close_room', roomId.toString()) } />;
|
||||||
|
}) }
|
||||||
|
|
||||||
|
{ isUserVisible && <ModToolsUserView /> }
|
||||||
|
{ isTicketsVisible && <ModToolsTicketsView /> }
|
||||||
|
</ModToolsContextProvider>
|
||||||
|
);
|
||||||
|
}
|
2
src/views/mod-tools/ModToolsView.types.ts
Normal file
2
src/views/mod-tools/ModToolsView.types.ts
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
export interface ModToolsViewProps
|
||||||
|
{}
|
14
src/views/mod-tools/context/ModToolsContext.tsx
Normal file
14
src/views/mod-tools/context/ModToolsContext.tsx
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
import { createContext, FC, useContext } from 'react';
|
||||||
|
import { IModToolsContext, ModToolsContextProps } from './ModToolsContext.types';
|
||||||
|
|
||||||
|
const ModToolsContext = createContext<IModToolsContext>({
|
||||||
|
modToolsState: null,
|
||||||
|
dispatchModToolsState: null
|
||||||
|
});
|
||||||
|
|
||||||
|
export const ModToolsContextProvider: FC<ModToolsContextProps> = props =>
|
||||||
|
{
|
||||||
|
return <ModToolsContext.Provider value={ props.value }>{ props.children }</ModToolsContext.Provider>
|
||||||
|
}
|
||||||
|
|
||||||
|
export const useModToolsContext = () => useContext(ModToolsContext);
|
13
src/views/mod-tools/context/ModToolsContext.types.ts
Normal file
13
src/views/mod-tools/context/ModToolsContext.types.ts
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
import { Dispatch, ProviderProps } from 'react';
|
||||||
|
import { IModToolsAction, IModToolsState } from '../reducers/ModToolsReducer';
|
||||||
|
|
||||||
|
export interface IModToolsContext
|
||||||
|
{
|
||||||
|
modToolsState: IModToolsState;
|
||||||
|
dispatchModToolsState: Dispatch<IModToolsAction>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ModToolsContextProps extends ProviderProps<IModToolsContext>
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
63
src/views/mod-tools/reducers/ModToolsReducer.tsx
Normal file
63
src/views/mod-tools/reducers/ModToolsReducer.tsx
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
import { Reducer } from 'react';
|
||||||
|
|
||||||
|
export interface IModToolsState
|
||||||
|
{
|
||||||
|
selectedUser: {webID: number, name: string};
|
||||||
|
currentRoomId: number;
|
||||||
|
openRooms: number[];
|
||||||
|
openChatlogs: number[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IModToolsAction
|
||||||
|
{
|
||||||
|
type: string;
|
||||||
|
payload: {
|
||||||
|
selectedUser?: {webID: number, name: string};
|
||||||
|
currentRoomId?: number;
|
||||||
|
openRooms?: number[];
|
||||||
|
openChatlogs?: number[];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class ModToolsActions
|
||||||
|
{
|
||||||
|
public static SET_SELECTED_USER: string = 'MTA_SET_SELECTED_USER';
|
||||||
|
public static SET_CURRENT_ROOM_ID: string = 'MTA_SET_CURRENT_ROOM_ID';
|
||||||
|
public static SET_OPEN_ROOMS: string = 'MTA_SET_OPEN_ROOMS';
|
||||||
|
public static SET_OPEN_CHATLOGS: string = 'MTA_SET_OPEN_CHATLOGS';
|
||||||
|
public static RESET_STATE: string = 'MTA_RESET_STATE';
|
||||||
|
}
|
||||||
|
|
||||||
|
export const initialModTools: IModToolsState = {
|
||||||
|
selectedUser: null,
|
||||||
|
currentRoomId: null,
|
||||||
|
openRooms: null,
|
||||||
|
openChatlogs: null
|
||||||
|
};
|
||||||
|
|
||||||
|
export const ModToolsReducer: Reducer<IModToolsState, IModToolsAction> = (state, action) =>
|
||||||
|
{
|
||||||
|
switch(action.type)
|
||||||
|
{
|
||||||
|
case ModToolsActions.SET_SELECTED_USER: {
|
||||||
|
const selectedUser = (action.payload.selectedUser || state.selectedUser || null);
|
||||||
|
|
||||||
|
return { ...state, selectedUser };
|
||||||
|
}
|
||||||
|
case ModToolsActions.SET_CURRENT_ROOM_ID: {
|
||||||
|
const currentRoomId = (action.payload.currentRoomId || state.currentRoomId || null);
|
||||||
|
|
||||||
|
return { ...state, currentRoomId };
|
||||||
|
}
|
||||||
|
case ModToolsActions.SET_OPEN_ROOMS: {
|
||||||
|
const openRooms = (action.payload.openRooms || state.openRooms || null);
|
||||||
|
|
||||||
|
return { ...state, openRooms };
|
||||||
|
}
|
||||||
|
case ModToolsActions.RESET_STATE: {
|
||||||
|
return { ...initialModTools };
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
}
|
26
src/views/mod-tools/views/chatlog/ModToolsChatlogView.scss
Normal file
26
src/views/mod-tools/views/chatlog/ModToolsChatlogView.scss
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
.nitro-mod-tools-chatlog {
|
||||||
|
width: 480px;
|
||||||
|
|
||||||
|
.chatlog-messages {
|
||||||
|
height: 300px;
|
||||||
|
max-height: 300px;
|
||||||
|
|
||||||
|
.table {
|
||||||
|
color: $black;
|
||||||
|
|
||||||
|
> :not(caption) > * > * {
|
||||||
|
box-shadow: none;
|
||||||
|
border-bottom: 1px solid rgba(0, 0, 0, .2);
|
||||||
|
}
|
||||||
|
|
||||||
|
&.table-striped > tbody > tr:nth-of-type(odd) {
|
||||||
|
color: $black;
|
||||||
|
background: rgba(0, 0, 0, .05);
|
||||||
|
}
|
||||||
|
|
||||||
|
td {
|
||||||
|
padding: 0px 5px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
84
src/views/mod-tools/views/chatlog/ModToolsChatlogView.tsx
Normal file
84
src/views/mod-tools/views/chatlog/ModToolsChatlogView.tsx
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
import { ModtoolRequestRoomChatlogComposer, ModtoolRoomChatlogEvent, ModtoolRoomChatlogLine } from 'nitro-renderer';
|
||||||
|
import { FC, useCallback, useEffect, useState } from 'react';
|
||||||
|
import { TryVisitRoom } from '../../../../api/navigator/TryVisitRoom';
|
||||||
|
import { CreateMessageHook, SendMessageHook } from '../../../../hooks/messages';
|
||||||
|
import { NitroCardContentView, NitroCardHeaderView, NitroCardView } from '../../../../layout';
|
||||||
|
import { ModToolsChatlogViewProps } from './ModToolsChatlogView.types';
|
||||||
|
|
||||||
|
export const ModToolsChatlogView: FC<ModToolsChatlogViewProps> = props =>
|
||||||
|
{
|
||||||
|
const { roomId = null, onCloseClick = null } = props;
|
||||||
|
|
||||||
|
const [ roomName, setRoomName ] = useState(null);
|
||||||
|
const [ messages, setMessages ] = useState<ModtoolRoomChatlogLine[]>(null);
|
||||||
|
const [ loadedRoomId, setLoadedRoomId ] = useState(null);
|
||||||
|
|
||||||
|
const [ messagesRequested, setMessagesRequested ] = useState(false);
|
||||||
|
|
||||||
|
useEffect(() =>
|
||||||
|
{
|
||||||
|
if(messagesRequested) return;
|
||||||
|
|
||||||
|
SendMessageHook(new ModtoolRequestRoomChatlogComposer(roomId));
|
||||||
|
setMessagesRequested(true);
|
||||||
|
}, [ roomId, messagesRequested, setMessagesRequested ]);
|
||||||
|
|
||||||
|
const onModtoolRoomChatlogEvent = useCallback((event: ModtoolRoomChatlogEvent) =>
|
||||||
|
{
|
||||||
|
const parser = event.getParser();
|
||||||
|
|
||||||
|
setRoomName(parser.name);
|
||||||
|
setMessages(parser.chatlogs);
|
||||||
|
setLoadedRoomId(parser.id);
|
||||||
|
}, [ setRoomName, setMessages ]);
|
||||||
|
|
||||||
|
CreateMessageHook(ModtoolRoomChatlogEvent, onModtoolRoomChatlogEvent);
|
||||||
|
|
||||||
|
const handleClick = useCallback((action: string, value?: string) =>
|
||||||
|
{
|
||||||
|
if(!action) return;
|
||||||
|
|
||||||
|
switch(action)
|
||||||
|
{
|
||||||
|
case 'close':
|
||||||
|
onCloseClick();
|
||||||
|
return;
|
||||||
|
case 'visit_room':
|
||||||
|
TryVisitRoom(loadedRoomId);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}, [ onCloseClick, loadedRoomId ]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<NitroCardView className="nitro-mod-tools-chatlog" simple={ true }>
|
||||||
|
<NitroCardHeaderView headerText={ 'Room Chatlog' + (roomName ? ': ' + roomName : '') } onCloseClick={ event => handleClick('close') } />
|
||||||
|
<NitroCardContentView className="text-black h-100">
|
||||||
|
<div className="w-100 d-flex justify-content-end">
|
||||||
|
<button className="btn btn-sm btn-primary me-2" onClick={ event => handleClick('visit_room') }>Visit Room</button>
|
||||||
|
<button className="btn btn-sm btn-primary">Room Tools</button>
|
||||||
|
</div>
|
||||||
|
<div className="chatlog-messages overflow-auto">
|
||||||
|
{ messages && <table className="table table-striped">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th className="text-center">Time</th>
|
||||||
|
<th className="text-center">User</th>
|
||||||
|
<th>Message</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{ messages.map((message, index) =>
|
||||||
|
{
|
||||||
|
return <tr key={ index }>
|
||||||
|
<td className="text-center">{ message.timestamp }</td>
|
||||||
|
<td className="text-center"><a href="#" className="fw-bold">{ message.userName }</a></td>
|
||||||
|
<td className="word-break">{ message.message }</td>
|
||||||
|
</tr>;
|
||||||
|
}) }
|
||||||
|
</tbody>
|
||||||
|
</table> }
|
||||||
|
</div>
|
||||||
|
</NitroCardContentView>
|
||||||
|
</NitroCardView>
|
||||||
|
);
|
||||||
|
}
|
@ -0,0 +1,5 @@
|
|||||||
|
export interface ModToolsChatlogViewProps
|
||||||
|
{
|
||||||
|
roomId: number;
|
||||||
|
onCloseClick: () => void;
|
||||||
|
}
|
3
src/views/mod-tools/views/room/ModToolsRoomView.scss
Normal file
3
src/views/mod-tools/views/room/ModToolsRoomView.scss
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
.nitro-mod-tools-room {
|
||||||
|
width: 240px;
|
||||||
|
}
|
104
src/views/mod-tools/views/room/ModToolsRoomView.tsx
Normal file
104
src/views/mod-tools/views/room/ModToolsRoomView.tsx
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
import { ModtoolRequestRoomInfoComposer, ModtoolRoomInfoEvent } from 'nitro-renderer';
|
||||||
|
import { FC, useCallback, useEffect, useState } from 'react';
|
||||||
|
import { CreateMessageHook, SendMessageHook } from '../../../../hooks/messages';
|
||||||
|
import { NitroCardContentView, NitroCardHeaderView, NitroCardView } from '../../../../layout';
|
||||||
|
import { ModToolsRoomViewProps } from './ModToolsRoomView.types';
|
||||||
|
|
||||||
|
export const ModToolsRoomView: FC<ModToolsRoomViewProps> = props =>
|
||||||
|
{
|
||||||
|
const { roomId = null, onCloseClick = null } = props;
|
||||||
|
|
||||||
|
const [ infoRequested, setInfoRequested ] = useState(false);
|
||||||
|
const [ loadedRoomId, setLoadedRoomId ] = useState(null);
|
||||||
|
|
||||||
|
const [ name, setName ] = useState(null);
|
||||||
|
const [ ownerId, setOwnerId ] = useState(null);
|
||||||
|
const [ ownerName, setOwnerName ] = useState(null);
|
||||||
|
const [ ownerInRoom, setOwnerInRoom ] = useState(false);
|
||||||
|
const [ usersInRoom, setUsersInRoom ] = useState(0);
|
||||||
|
|
||||||
|
useEffect(() =>
|
||||||
|
{
|
||||||
|
if(infoRequested) return;
|
||||||
|
|
||||||
|
SendMessageHook(new ModtoolRequestRoomInfoComposer(roomId));
|
||||||
|
setInfoRequested(true);
|
||||||
|
}, [ roomId, infoRequested, setInfoRequested ]);
|
||||||
|
|
||||||
|
const onModtoolRoomInfoEvent = useCallback((event: ModtoolRoomInfoEvent) =>
|
||||||
|
{
|
||||||
|
const parser = event.getParser();
|
||||||
|
|
||||||
|
setLoadedRoomId(parser.id);
|
||||||
|
setName(parser.name);
|
||||||
|
setOwnerId(parser.ownerId);
|
||||||
|
setOwnerName(parser.ownerName);
|
||||||
|
setOwnerInRoom(parser.ownerInRoom);
|
||||||
|
setUsersInRoom(parser.playerAmount);
|
||||||
|
}, [ setLoadedRoomId, setName, setOwnerId, setOwnerName, setOwnerInRoom, setUsersInRoom ]);
|
||||||
|
|
||||||
|
CreateMessageHook(ModtoolRoomInfoEvent, onModtoolRoomInfoEvent);
|
||||||
|
|
||||||
|
const handleClick = useCallback((action: string, value?: string) =>
|
||||||
|
{
|
||||||
|
if(!action) return;
|
||||||
|
|
||||||
|
switch(action)
|
||||||
|
{
|
||||||
|
case 'close':
|
||||||
|
onCloseClick();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}, [ onCloseClick ]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<NitroCardView className="nitro-mod-tools-room" simple={ true }>
|
||||||
|
<NitroCardHeaderView headerText={ 'Room Info' + (name ? ': ' + name : '') } onCloseClick={ event => handleClick('close') } />
|
||||||
|
<NitroCardContentView className="text-black">
|
||||||
|
<div className="d-flex justify-content-between align-items-center mb-1">
|
||||||
|
<div>
|
||||||
|
<b>Room Owner:</b> <a href="#" className="fw-bold">{ ownerName }</a>
|
||||||
|
</div>
|
||||||
|
<button className="btn btn-sm btn-primary">Visit Room</button>
|
||||||
|
</div>
|
||||||
|
<div className="d-flex justify-content-between align-items-center mb-1">
|
||||||
|
<div>
|
||||||
|
<b>Users in room:</b> { usersInRoom }
|
||||||
|
</div>
|
||||||
|
<button className="btn btn-sm btn-primary">Chatlog</button>
|
||||||
|
</div>
|
||||||
|
<div className="d-flex justify-content-between align-items-center mb-2">
|
||||||
|
<div>
|
||||||
|
<b>Owner in room:</b> { ownerInRoom ? 'Yes' : 'No' }
|
||||||
|
</div>
|
||||||
|
<button className="btn btn-sm btn-primary">Edit in HK</button>
|
||||||
|
</div>
|
||||||
|
<div className="bg-muted rounded py-1 px-2 mb-2">
|
||||||
|
<div className="form-check">
|
||||||
|
<input className="form-check-input" type="checkbox" id="kickUsers" />
|
||||||
|
<label className="form-check-label" htmlFor="kickUsers">
|
||||||
|
Kick users out of the room
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div className="form-check">
|
||||||
|
<input className="form-check-input" type="checkbox" id="lockRoom" />
|
||||||
|
<label className="form-check-label" htmlFor="lockRoom">
|
||||||
|
Change room lock to doorbell
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div className="form-check">
|
||||||
|
<input className="form-check-input" type="checkbox" id="lockRoom" />
|
||||||
|
<label className="form-check-label" htmlFor="lockRoom">
|
||||||
|
Change room name to "Inappro- priate to Hotel Management"
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<textarea className="form-control mb-2" placeholder="Type a mandatory message to the users in this text box..."></textarea>
|
||||||
|
<div className="d-flex justify-content-between">
|
||||||
|
<button className="btn btn-danger w-100 me-2">Send Caution</button>
|
||||||
|
<button className="btn btn-success w-100">Send Alert only</button>
|
||||||
|
</div>
|
||||||
|
</NitroCardContentView>
|
||||||
|
</NitroCardView>
|
||||||
|
);
|
||||||
|
}
|
5
src/views/mod-tools/views/room/ModToolsRoomView.types.ts
Normal file
5
src/views/mod-tools/views/room/ModToolsRoomView.types.ts
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
export interface ModToolsRoomViewProps
|
||||||
|
{
|
||||||
|
roomId: number;
|
||||||
|
onCloseClick: () => void;
|
||||||
|
}
|
15
src/views/mod-tools/views/tickets/ModToolsTicketsView.tsx
Normal file
15
src/views/mod-tools/views/tickets/ModToolsTicketsView.tsx
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
import { FC } from 'react';
|
||||||
|
import { NitroCardContentView, NitroCardHeaderView, NitroCardView } from '../../../../layout';
|
||||||
|
import { ModToolsTicketsViewProps } from './ModToolsTicketsView.types';
|
||||||
|
|
||||||
|
export const ModToolsTicketsView: FC<ModToolsTicketsViewProps> = props =>
|
||||||
|
{
|
||||||
|
return (
|
||||||
|
<NitroCardView className="nitro-mod-tools-tickets" simple={ true }>
|
||||||
|
<NitroCardHeaderView headerText={ "Tickets" } onCloseClick={ event => {} } />
|
||||||
|
<NitroCardContentView className="text-black">
|
||||||
|
|
||||||
|
</NitroCardContentView>
|
||||||
|
</NitroCardView>
|
||||||
|
);
|
||||||
|
}
|
@ -0,0 +1,2 @@
|
|||||||
|
export interface ModToolsTicketsViewProps
|
||||||
|
{}
|
15
src/views/mod-tools/views/user/ModToolsUserView.tsx
Normal file
15
src/views/mod-tools/views/user/ModToolsUserView.tsx
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
import { FC } from 'react';
|
||||||
|
import { NitroCardContentView, NitroCardHeaderView, NitroCardView } from '../../../../layout';
|
||||||
|
import { ModToolsUserViewProps } from './ModToolsUserView.types';
|
||||||
|
|
||||||
|
export const ModToolsUserView: FC<ModToolsUserViewProps> = props =>
|
||||||
|
{
|
||||||
|
return (
|
||||||
|
<NitroCardView className="nitro-mod-tools-user" simple={ true }>
|
||||||
|
<NitroCardHeaderView headerText={ "User Info" } onCloseClick={ event => {} } />
|
||||||
|
<NitroCardContentView className="text-black">
|
||||||
|
|
||||||
|
</NitroCardContentView>
|
||||||
|
</NitroCardView>
|
||||||
|
);
|
||||||
|
}
|
2
src/views/mod-tools/views/user/ModToolsUserView.types.ts
Normal file
2
src/views/mod-tools/views/user/ModToolsUserView.types.ts
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
export interface ModToolsUserViewProps
|
||||||
|
{}
|
@ -1,8 +1,8 @@
|
|||||||
import { Dispose, DropBounce, EaseOut, JumpBy, Motions, NitroToolbarAnimateIconEvent, Queue, UserFigureEvent, Wait } from 'nitro-renderer';
|
import { Dispose, DropBounce, EaseOut, JumpBy, Motions, NitroToolbarAnimateIconEvent, Queue, UserFigureEvent, UserInfoDataParser, UserInfoEvent, Wait } from 'nitro-renderer';
|
||||||
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 { FC, useCallback, useState } from 'react';
|
import { FC, useCallback, useState } from 'react';
|
||||||
import { AvatarEditorEvent, CatalogEvent, FriendListEvent, InventoryEvent, NavigatorEvent, RoomWidgetCameraEvent, UnseenItemTrackerUpdateEvent } from '../../events';
|
import { AvatarEditorEvent, CatalogEvent, FriendListEvent, InventoryEvent, NavigatorEvent, RoomWidgetCameraEvent } from '../../events';
|
||||||
|
import { UnseenItemTrackerUpdateEvent } from '../../events/inventory/UnseenItemTrackerUpdateEvent';
|
||||||
|
import { ModToolsEvent } from '../../events/mod-tools/ModToolsEvent';
|
||||||
import { useRoomEngineEvent } from '../../hooks';
|
import { useRoomEngineEvent } from '../../hooks';
|
||||||
import { dispatchUiEvent, useUiEvent } from '../../hooks/events/ui/ui-event';
|
import { dispatchUiEvent, useUiEvent } from '../../hooks/events/ui/ui-event';
|
||||||
import { CreateMessageHook } from '../../hooks/messages/message-event';
|
import { CreateMessageHook } from '../../hooks/messages/message-event';
|
||||||
@ -114,6 +114,9 @@ export const ToolbarView: FC<ToolbarViewProps> = props =>
|
|||||||
dispatchUiEvent(new AvatarEditorEvent(AvatarEditorEvent.TOGGLE_EDITOR));
|
dispatchUiEvent(new AvatarEditorEvent(AvatarEditorEvent.TOGGLE_EDITOR));
|
||||||
setMeExpanded(false);
|
setMeExpanded(false);
|
||||||
return;
|
return;
|
||||||
|
case ToolbarViewItems.MOD_TOOLS_ITEM:
|
||||||
|
dispatchUiEvent(new ModToolsEvent(ModToolsEvent.TOGGLE_MOD_TOOLS));
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
@ -160,13 +163,21 @@ export const ToolbarView: FC<ToolbarViewProps> = props =>
|
|||||||
</div>
|
</div>
|
||||||
{ isInRoom && (
|
{ isInRoom && (
|
||||||
<div className="navigation-item" onClick={ event => handleToolbarItemClick(ToolbarViewItems.CAMERA_ITEM) }>
|
<div className="navigation-item" onClick={ event => handleToolbarItemClick(ToolbarViewItems.CAMERA_ITEM) }>
|
||||||
<i className="icon icon-camera"></i>
|
<i className="icon icon-camera"></i>
|
||||||
</div>) }
|
</div>) }
|
||||||
</div>
|
</div>
|
||||||
<div id="toolbar-chat-input-container" className="d-flex align-items-center" />
|
<div id="toolbar-chat-input-container" className="d-flex align-items-center" />
|
||||||
</div>
|
</div>
|
||||||
<div className="d-flex toolbar-right-side">
|
<div className="d-flex toolbar-right-side">
|
||||||
<div id="toolbar-friend-bar-container" />
|
<div id="toolbar-friend-bar-container" />
|
||||||
|
<div className="navigation-item" onClick={ event => handleToolbarItemClick(ToolbarViewItems.FRIEND_LIST_ITEM) }>
|
||||||
|
<i className="icon icon-friendall"></i>
|
||||||
|
{ (unseenFriendListCount > 0) && (
|
||||||
|
<div className="position-absolute bg-danger px-1 py-0 rounded shadow count">{ unseenFriendListCount }</div>) }
|
||||||
|
</div>
|
||||||
|
<div className="navigation-item" onClick={ event => handleToolbarItemClick(ToolbarViewItems.MOD_TOOLS_ITEM) }>
|
||||||
|
<i className="icon icon-modtools"></i>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -11,4 +11,5 @@ export class ToolbarViewItems
|
|||||||
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';
|
public static CLOTHING_ITEM: string = 'TVI_CLOTHING_ITEM';
|
||||||
public static CAMERA_ITEM: string = 'TVI_CAMERA_ITEM';
|
public static CAMERA_ITEM: string = 'TVI_CAMERA_ITEM';
|
||||||
|
public static MOD_TOOLS_ITEM: string = 'TVI_MOD_TOOLS_ITEM';
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user