From d2f86f92fd11a220399d726f7f5f7a8375737619 Mon Sep 17 00:00:00 2001 From: MyNameIsBatman Date: Mon, 21 Jun 2021 07:21:25 -0300 Subject: [PATCH 1/2] Initial commit --- src/events/mod-tools/ModToolsEvent.ts | 8 +++ src/views/mod-tools/ModToolsView.tsx | 59 +++++++++++++++++++ src/views/mod-tools/ModToolsView.types.ts | 2 + .../mod-tools/context/ModToolsContext.tsx | 14 +++++ .../context/ModToolsContext.types.ts | 13 ++++ .../mod-tools/reducers/ModToolsReducer.tsx | 30 ++++++++++ 6 files changed, 126 insertions(+) create mode 100644 src/events/mod-tools/ModToolsEvent.ts create mode 100644 src/views/mod-tools/ModToolsView.tsx create mode 100644 src/views/mod-tools/ModToolsView.types.ts create mode 100644 src/views/mod-tools/context/ModToolsContext.tsx create mode 100644 src/views/mod-tools/context/ModToolsContext.types.ts create mode 100644 src/views/mod-tools/reducers/ModToolsReducer.tsx diff --git a/src/events/mod-tools/ModToolsEvent.ts b/src/events/mod-tools/ModToolsEvent.ts new file mode 100644 index 00000000..dec4fdb8 --- /dev/null +++ b/src/events/mod-tools/ModToolsEvent.ts @@ -0,0 +1,8 @@ +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'; +} diff --git a/src/views/mod-tools/ModToolsView.tsx b/src/views/mod-tools/ModToolsView.tsx new file mode 100644 index 00000000..aefe75f5 --- /dev/null +++ b/src/views/mod-tools/ModToolsView.tsx @@ -0,0 +1,59 @@ +import { FC, useCallback, useEffect, useReducer, useState } from 'react'; +import { ModToolsEvent } from '../../events/mod-tools/ModToolsEvent'; +import { useUiEvent } from '../../hooks/events/ui/ui-event'; +import { NitroCardContentView, NitroCardTabsView, NitroCardView } from '../../layout'; +import { NitroCardSimpleHeaderView } from '../../layout/card/simple-header'; +import { LocalizeText } from '../../utils/LocalizeText'; +import { ModToolsContextProvider } from './context/ModToolsContext'; +import { ModToolsViewProps } from './ModToolsView.types'; +import { initialModTools, ModToolsReducer } from './reducers/ModToolsReducer'; + +export const ModToolsView: FC = props => +{ + const [ isVisible, setIsVisible ] = useState(false); + const [ modToolsState, dispatchModToolsState ] = useReducer(ModToolsReducer, initialModTools); + + 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; + } + }, []); + + useUiEvent(ModToolsEvent.SHOW_MOD_TOOLS, onModToolsEvent); + useUiEvent(ModToolsEvent.HIDE_MOD_TOOLS, onModToolsEvent); + useUiEvent(ModToolsEvent.TOGGLE_MOD_TOOLS, onModToolsEvent); + + useEffect(() => + { + if(!isVisible) return; + }, [ isVisible ]); + + return ( + + { isVisible && + + setIsVisible(false) } /> + + + +
+
+
+
+
+
+
+
} +
+ ); +} diff --git a/src/views/mod-tools/ModToolsView.types.ts b/src/views/mod-tools/ModToolsView.types.ts new file mode 100644 index 00000000..3aa7691f --- /dev/null +++ b/src/views/mod-tools/ModToolsView.types.ts @@ -0,0 +1,2 @@ +export interface ModToolsViewProps +{} diff --git a/src/views/mod-tools/context/ModToolsContext.tsx b/src/views/mod-tools/context/ModToolsContext.tsx new file mode 100644 index 00000000..97873603 --- /dev/null +++ b/src/views/mod-tools/context/ModToolsContext.tsx @@ -0,0 +1,14 @@ +import { createContext, FC, useContext } from 'react'; +import { IModToolsContext, ModToolsContextProps } from './ModToolsContext.types'; + +const ModToolsContext = createContext({ + modToolsState: null, + dispatchModToolsState: null +}); + +export const ModToolsContextProvider: FC = props => +{ + return { props.children } +} + +export const useModToolsContext = () => useContext(ModToolsContext); diff --git a/src/views/mod-tools/context/ModToolsContext.types.ts b/src/views/mod-tools/context/ModToolsContext.types.ts new file mode 100644 index 00000000..46c6a9b8 --- /dev/null +++ b/src/views/mod-tools/context/ModToolsContext.types.ts @@ -0,0 +1,13 @@ +import { Dispatch, ProviderProps } from 'react'; +import { IModToolsAction, IModToolsState } from '../reducers/ModToolsReducer'; + +export interface IModToolsContext +{ + modToolsState: IModToolsState; + dispatchModToolsState: Dispatch; +} + +export interface ModToolsContextProps extends ProviderProps +{ + +} diff --git a/src/views/mod-tools/reducers/ModToolsReducer.tsx b/src/views/mod-tools/reducers/ModToolsReducer.tsx new file mode 100644 index 00000000..cc09498c --- /dev/null +++ b/src/views/mod-tools/reducers/ModToolsReducer.tsx @@ -0,0 +1,30 @@ +import { Reducer } from 'react'; + +export interface IModToolsState +{ + +} + +export interface IModToolsAction +{ + type: string; + payload: { + } +} + +export class ModToolsActions +{ + +} + +export const initialModTools: IModToolsState = { +} + +export const ModToolsReducer: Reducer = (state, action) => +{ + switch(action.type) + { + default: + return state; + } +} From 6f4839dd6e2f5b3c5bffa2ba088c96226f1832e0 Mon Sep 17 00:00:00 2001 From: MyNameIsBatman Date: Tue, 22 Jun 2021 08:10:01 -0300 Subject: [PATCH 2/2] DONT USE IT --- src/events/mod-tools/ModToolsEvent.ts | 2 + .../mod-tools/ModToolsOpenRoomInfoEvent.ts | 18 ++ .../mod-tools/ModToolsSelectUserEvent.ts | 25 +++ .../NitroCardSimpleHeaderView.scss | 2 + .../NitroCardSimpleHeaderView.tsx | 2 - src/views/Styles.scss | 1 + src/views/main/MainView.tsx | 2 + src/views/mod-tools/ModToolsView.scss | 6 + src/views/mod-tools/ModToolsView.tsx | 156 ++++++++++++++++-- .../mod-tools/reducers/ModToolsReducer.tsx | 39 ++++- .../views/chatlog/ModToolsChatlogView.scss | 26 +++ .../views/chatlog/ModToolsChatlogView.tsx | 85 ++++++++++ .../chatlog/ModToolsChatlogView.types.ts | 5 + .../views/room/ModToolsRoomView.scss | 3 + .../mod-tools/views/room/ModToolsRoomView.tsx | 105 ++++++++++++ .../views/room/ModToolsRoomView.types.ts | 5 + .../views/tickets/ModToolsTicketsView.tsx | 16 ++ .../tickets/ModToolsTicketsView.types.ts | 2 + .../mod-tools/views/user/ModToolsUserView.tsx | 16 ++ .../views/user/ModToolsUserView.types.ts | 2 + src/views/room/RoomView.tsx | 15 +- src/views/toolbar/ToolbarView.tsx | 7 + src/views/toolbar/ToolbarView.types.ts | 1 + 23 files changed, 518 insertions(+), 23 deletions(-) create mode 100644 src/events/mod-tools/ModToolsOpenRoomInfoEvent.ts create mode 100644 src/events/mod-tools/ModToolsSelectUserEvent.ts create mode 100644 src/views/mod-tools/ModToolsView.scss create mode 100644 src/views/mod-tools/views/chatlog/ModToolsChatlogView.scss create mode 100644 src/views/mod-tools/views/chatlog/ModToolsChatlogView.tsx create mode 100644 src/views/mod-tools/views/chatlog/ModToolsChatlogView.types.ts create mode 100644 src/views/mod-tools/views/room/ModToolsRoomView.scss create mode 100644 src/views/mod-tools/views/room/ModToolsRoomView.tsx create mode 100644 src/views/mod-tools/views/room/ModToolsRoomView.types.ts create mode 100644 src/views/mod-tools/views/tickets/ModToolsTicketsView.tsx create mode 100644 src/views/mod-tools/views/tickets/ModToolsTicketsView.types.ts create mode 100644 src/views/mod-tools/views/user/ModToolsUserView.tsx create mode 100644 src/views/mod-tools/views/user/ModToolsUserView.types.ts diff --git a/src/events/mod-tools/ModToolsEvent.ts b/src/events/mod-tools/ModToolsEvent.ts index dec4fdb8..fca082ec 100644 --- a/src/events/mod-tools/ModToolsEvent.ts +++ b/src/events/mod-tools/ModToolsEvent.ts @@ -5,4 +5,6 @@ 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'; } diff --git a/src/events/mod-tools/ModToolsOpenRoomInfoEvent.ts b/src/events/mod-tools/ModToolsOpenRoomInfoEvent.ts new file mode 100644 index 00000000..24465610 --- /dev/null +++ b/src/events/mod-tools/ModToolsOpenRoomInfoEvent.ts @@ -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; + } +} diff --git a/src/events/mod-tools/ModToolsSelectUserEvent.ts b/src/events/mod-tools/ModToolsSelectUserEvent.ts new file mode 100644 index 00000000..148ffe28 --- /dev/null +++ b/src/events/mod-tools/ModToolsSelectUserEvent.ts @@ -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; + } +} diff --git a/src/layout/card/simple-header/NitroCardSimpleHeaderView.scss b/src/layout/card/simple-header/NitroCardSimpleHeaderView.scss index 4b1439a6..47c578b5 100644 --- a/src/layout/card/simple-header/NitroCardSimpleHeaderView.scss +++ b/src/layout/card/simple-header/NitroCardSimpleHeaderView.scss @@ -5,4 +5,6 @@ .bg-tertiary-split { border: 2px solid darken($quaternary,4); box-shadow:0 0 0 2px $white; + margin-left: 24px; + margin-right: 24px; } diff --git a/src/layout/card/simple-header/NitroCardSimpleHeaderView.tsx b/src/layout/card/simple-header/NitroCardSimpleHeaderView.tsx index d71306b3..e7d0d79f 100644 --- a/src/layout/card/simple-header/NitroCardSimpleHeaderView.tsx +++ b/src/layout/card/simple-header/NitroCardSimpleHeaderView.tsx @@ -7,11 +7,9 @@ export const NitroCardSimpleHeaderView: FC = pro return (
-
{ headerText }
-
diff --git a/src/views/Styles.scss b/src/views/Styles.scss index 657a17c8..f43f2f31 100644 --- a/src/views/Styles.scss +++ b/src/views/Styles.scss @@ -20,3 +20,4 @@ @import './room-host/RoomHostView'; @import './room-previewer/RoomPreviewerView'; @import './toolbar/ToolbarView'; +@import './mod-tools/ModToolsView'; diff --git a/src/views/main/MainView.tsx b/src/views/main/MainView.tsx index ecf77d91..feb9cf6f 100644 --- a/src/views/main/MainView.tsx +++ b/src/views/main/MainView.tsx @@ -8,6 +8,7 @@ import { CatalogView } from '../catalog/CatalogView'; import { FriendListView } from '../friend-list/FriendListView'; import { HotelView } from '../hotel-view/HotelView'; import { InventoryView } from '../inventory/InventoryView'; +import { ModToolsView } from '../mod-tools/ModToolsView'; import { NavigatorView } from '../navigator/NavigatorView'; import { RightSideView } from '../right-side/RightSideView'; import { RoomHostView } from '../room-host/RoomHostView'; @@ -45,6 +46,7 @@ export function MainView(props: MainViewProps): JSX.Element return (
{ landingViewVisible && } + diff --git a/src/views/mod-tools/ModToolsView.scss b/src/views/mod-tools/ModToolsView.scss new file mode 100644 index 00000000..9f5554e9 --- /dev/null +++ b/src/views/mod-tools/ModToolsView.scss @@ -0,0 +1,6 @@ +.nitro-mod-tools { + width: 200px; +} + +@import './views/chatlog/ModToolsChatlogView'; +@import './views/room/ModToolsRoomView'; diff --git a/src/views/mod-tools/ModToolsView.tsx b/src/views/mod-tools/ModToolsView.tsx index aefe75f5..0b2a49c3 100644 --- a/src/views/mod-tools/ModToolsView.tsx +++ b/src/views/mod-tools/ModToolsView.tsx @@ -1,18 +1,28 @@ +import { RoomEngineEvent } from 'nitro-renderer'; import { FC, useCallback, useEffect, useReducer, useState } from 'react'; import { ModToolsEvent } from '../../events/mod-tools/ModToolsEvent'; -import { useUiEvent } from '../../hooks/events/ui/ui-event'; -import { NitroCardContentView, NitroCardTabsView, NitroCardView } from '../../layout'; +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, NitroCardView } from '../../layout'; import { NitroCardSimpleHeaderView } from '../../layout/card/simple-header'; -import { LocalizeText } from '../../utils/LocalizeText'; import { ModToolsContextProvider } from './context/ModToolsContext'; import { ModToolsViewProps } from './ModToolsView.types'; -import { initialModTools, ModToolsReducer } from './reducers/ModToolsReducer'; +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 = 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) @@ -26,12 +36,123 @@ export const ModToolsView: FC = props => 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(() => { @@ -42,18 +163,21 @@ export const ModToolsView: FC = props => { isVisible && - setIsVisible(false) } /> - - - -
-
-
-
-
-
+ setIsVisible(false) } /> + + + + +
} + { openRooms && openRooms.map(roomId => + { + return handleClick('close_room', roomId.toString()) } />; + }) } + + { isUserVisible && } + { isTicketsVisible && }
); } diff --git a/src/views/mod-tools/reducers/ModToolsReducer.tsx b/src/views/mod-tools/reducers/ModToolsReducer.tsx index cc09498c..955d70b9 100644 --- a/src/views/mod-tools/reducers/ModToolsReducer.tsx +++ b/src/views/mod-tools/reducers/ModToolsReducer.tsx @@ -2,28 +2,61 @@ 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 = (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; } diff --git a/src/views/mod-tools/views/chatlog/ModToolsChatlogView.scss b/src/views/mod-tools/views/chatlog/ModToolsChatlogView.scss new file mode 100644 index 00000000..7a2ddc8a --- /dev/null +++ b/src/views/mod-tools/views/chatlog/ModToolsChatlogView.scss @@ -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; + } + } + } +} diff --git a/src/views/mod-tools/views/chatlog/ModToolsChatlogView.tsx b/src/views/mod-tools/views/chatlog/ModToolsChatlogView.tsx new file mode 100644 index 00000000..d34f1dd5 --- /dev/null +++ b/src/views/mod-tools/views/chatlog/ModToolsChatlogView.tsx @@ -0,0 +1,85 @@ +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, NitroCardView } from '../../../../layout'; +import { NitroCardSimpleHeaderView } from '../../../../layout/card/simple-header'; +import { ModToolsChatlogViewProps } from './ModToolsChatlogView.types'; + +export const ModToolsChatlogView: FC = props => +{ + const { roomId = null, onCloseClick = null } = props; + + const [ roomName, setRoomName ] = useState(null); + const [ messages, setMessages ] = useState(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 ( + + handleClick('close') } /> + +
+ + +
+
+ { messages && + + + + + + + + + { messages.map((message, index) => + { + return + + + + ; + }) } + +
TimeUserMessage
{ message.timestamp }{ message.userName }{ message.message }
} +
+
+
+ ); +} diff --git a/src/views/mod-tools/views/chatlog/ModToolsChatlogView.types.ts b/src/views/mod-tools/views/chatlog/ModToolsChatlogView.types.ts new file mode 100644 index 00000000..0589cd02 --- /dev/null +++ b/src/views/mod-tools/views/chatlog/ModToolsChatlogView.types.ts @@ -0,0 +1,5 @@ +export interface ModToolsChatlogViewProps +{ + roomId: number; + onCloseClick: () => void; +} diff --git a/src/views/mod-tools/views/room/ModToolsRoomView.scss b/src/views/mod-tools/views/room/ModToolsRoomView.scss new file mode 100644 index 00000000..55ed938a --- /dev/null +++ b/src/views/mod-tools/views/room/ModToolsRoomView.scss @@ -0,0 +1,3 @@ +.nitro-mod-tools-room { + width: 240px; +} diff --git a/src/views/mod-tools/views/room/ModToolsRoomView.tsx b/src/views/mod-tools/views/room/ModToolsRoomView.tsx new file mode 100644 index 00000000..ad66e311 --- /dev/null +++ b/src/views/mod-tools/views/room/ModToolsRoomView.tsx @@ -0,0 +1,105 @@ +import { ModtoolRequestRoomInfoComposer, ModtoolRoomInfoEvent } from 'nitro-renderer'; +import { FC, useCallback, useEffect, useState } from 'react'; +import { CreateMessageHook, SendMessageHook } from '../../../../hooks/messages'; +import { NitroCardContentView, NitroCardView } from '../../../../layout'; +import { NitroCardSimpleHeaderView } from '../../../../layout/card/simple-header'; +import { ModToolsRoomViewProps } from './ModToolsRoomView.types'; + +export const ModToolsRoomView: FC = 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 ( + + handleClick('close') } /> + +
+
+ Room Owner: { ownerName } +
+ +
+
+
+ Users in room: { usersInRoom } +
+ +
+
+
+ Owner in room: { ownerInRoom ? 'Yes' : 'No' } +
+ +
+
+
+ + +
+
+ + +
+
+ + +
+
+ +
+ + +
+
+
+ ); +} diff --git a/src/views/mod-tools/views/room/ModToolsRoomView.types.ts b/src/views/mod-tools/views/room/ModToolsRoomView.types.ts new file mode 100644 index 00000000..d096fcbe --- /dev/null +++ b/src/views/mod-tools/views/room/ModToolsRoomView.types.ts @@ -0,0 +1,5 @@ +export interface ModToolsRoomViewProps +{ + roomId: number; + onCloseClick: () => void; +} diff --git a/src/views/mod-tools/views/tickets/ModToolsTicketsView.tsx b/src/views/mod-tools/views/tickets/ModToolsTicketsView.tsx new file mode 100644 index 00000000..966b2b7d --- /dev/null +++ b/src/views/mod-tools/views/tickets/ModToolsTicketsView.tsx @@ -0,0 +1,16 @@ +import { FC } from 'react'; +import { NitroCardContentView, NitroCardView } from '../../../../layout'; +import { NitroCardSimpleHeaderView } from '../../../../layout/card/simple-header'; +import { ModToolsTicketsViewProps } from './ModToolsTicketsView.types'; + +export const ModToolsTicketsView: FC = props => +{ + return ( + + {} } /> + + + + + ); +} diff --git a/src/views/mod-tools/views/tickets/ModToolsTicketsView.types.ts b/src/views/mod-tools/views/tickets/ModToolsTicketsView.types.ts new file mode 100644 index 00000000..a8713d1f --- /dev/null +++ b/src/views/mod-tools/views/tickets/ModToolsTicketsView.types.ts @@ -0,0 +1,2 @@ +export interface ModToolsTicketsViewProps +{} diff --git a/src/views/mod-tools/views/user/ModToolsUserView.tsx b/src/views/mod-tools/views/user/ModToolsUserView.tsx new file mode 100644 index 00000000..34086081 --- /dev/null +++ b/src/views/mod-tools/views/user/ModToolsUserView.tsx @@ -0,0 +1,16 @@ +import { FC } from 'react'; +import { NitroCardContentView, NitroCardView } from '../../../../layout'; +import { NitroCardSimpleHeaderView } from '../../../../layout/card/simple-header'; +import { ModToolsUserViewProps } from './ModToolsUserView.types'; + +export const ModToolsUserView: FC = props => +{ + return ( + + {} } /> + + + + + ); +} diff --git a/src/views/mod-tools/views/user/ModToolsUserView.types.ts b/src/views/mod-tools/views/user/ModToolsUserView.types.ts new file mode 100644 index 00000000..55b9477c --- /dev/null +++ b/src/views/mod-tools/views/user/ModToolsUserView.types.ts @@ -0,0 +1,2 @@ +export interface ModToolsUserViewProps +{} diff --git a/src/views/room/RoomView.tsx b/src/views/room/RoomView.tsx index 19500aff..6fcf2ee8 100644 --- a/src/views/room/RoomView.tsx +++ b/src/views/room/RoomView.tsx @@ -1,4 +1,4 @@ -import { EventDispatcher, Nitro, RoomEngineEvent, RoomEngineObjectEvent, RoomGeometry, RoomId, RoomObjectCategory, RoomObjectOperationType, RoomVariableEnum, Vector3d } from 'nitro-renderer'; +import { EventDispatcher, Nitro, RoomEngineEvent, RoomEngineObjectEvent, RoomGeometry, RoomId, RoomObjectCategory, RoomObjectOperationType, RoomObjectType, RoomVariableEnum, Vector3d } from 'nitro-renderer'; import { FC, useCallback, useEffect, useState } from 'react'; import { createPortal } from 'react-dom'; import { CanManipulateFurniture, IsFurnitureSelectionDisabled, ProcessRoomObjectOperation } from '../../api'; @@ -6,7 +6,8 @@ import { DispatchMouseEvent } from '../../api/nitro/room/DispatchMouseEvent'; import { WindowResizeEvent } from '../../api/nitro/room/DispatchResizeEvent'; import { DispatchTouchEvent } from '../../api/nitro/room/DispatchTouchEvent'; import { GetRoomEngine } from '../../api/nitro/room/GetRoomEngine'; -import { useRoomEngineEvent } from '../../hooks/events'; +import { ModToolsSelectUserEvent } from '../../events/mod-tools/ModToolsSelectUserEvent'; +import { dispatchUiEvent, useRoomEngineEvent } from '../../hooks/events'; import { RoomContextProvider } from './context/RoomContext'; import { RoomWidgetRoomEngineUpdateEvent, RoomWidgetRoomObjectUpdateEvent } from './events'; import { IRoomWidgetHandlerManager, RoomWidgetHandlerManager, RoomWidgetInfostandHandler } from './handlers'; @@ -123,6 +124,16 @@ export const RoomView: FC = props => { case RoomEngineObjectEvent.SELECTED: if(!IsFurnitureSelectionDisabled(event)) updateEvent = new RoomWidgetRoomObjectUpdateEvent(RoomWidgetRoomObjectUpdateEvent.OBJECT_SELECTED, objectId, category, event.roomId); + + if(category === RoomObjectCategory.UNIT) + { + const user = roomSession.userDataManager.getUserDataByIndex(objectId); + + if(user && user.type === RoomObjectType.USER) + { + dispatchUiEvent(new ModToolsSelectUserEvent(user.webID, user.name)); + } + } break; case RoomEngineObjectEvent.DESELECTED: updateEvent = new RoomWidgetRoomObjectUpdateEvent(RoomWidgetRoomObjectUpdateEvent.OBJECT_DESELECTED, objectId, category, event.roomId); diff --git a/src/views/toolbar/ToolbarView.tsx b/src/views/toolbar/ToolbarView.tsx index f58c6327..05bf9446 100644 --- a/src/views/toolbar/ToolbarView.tsx +++ b/src/views/toolbar/ToolbarView.tsx @@ -2,6 +2,7 @@ import { UserInfoEvent } from 'nitro-renderer/src/nitro/communication/messages/i import { UserInfoDataParser } from 'nitro-renderer/src/nitro/communication/messages/parser/user/data/UserInfoDataParser'; import { FC, useCallback, useState } from 'react'; import { AvatarEditorEvent, CatalogEvent, FriendListEvent, InventoryEvent, NavigatorEvent, RoomWidgetCameraEvent } from '../../events'; +import { ModToolsEvent } from '../../events/mod-tools/ModToolsEvent'; import { dispatchUiEvent } from '../../hooks/events/ui/ui-event'; import { CreateMessageHook } from '../../hooks/messages/message-event'; import { TransitionAnimation } from '../../layout/transitions/TransitionAnimation'; @@ -51,6 +52,9 @@ export const ToolbarView: FC = props => dispatchUiEvent(new AvatarEditorEvent(AvatarEditorEvent.TOGGLE_EDITOR)); setMeExpanded(false); return; + case ToolbarViewItems.MOD_TOOLS_ITEM: + dispatchUiEvent(new ModToolsEvent(ModToolsEvent.TOGGLE_MOD_TOOLS)); + return; } }, []); @@ -108,6 +112,9 @@ export const ToolbarView: FC = props =>
handleToolbarItemClick(ToolbarViewItems.CAMERA_ITEM) }>
) } +
handleToolbarItemClick(ToolbarViewItems.MOD_TOOLS_ITEM) }> + +
diff --git a/src/views/toolbar/ToolbarView.types.ts b/src/views/toolbar/ToolbarView.types.ts index 6c280e6c..d9ab106a 100644 --- a/src/views/toolbar/ToolbarView.types.ts +++ b/src/views/toolbar/ToolbarView.types.ts @@ -11,4 +11,5 @@ export class ToolbarViewItems public static FRIEND_LIST_ITEM: string = 'TVI_FRIEND_LIST_ITEM'; public static CLOTHING_ITEM: string = 'TVI_CLOTHING_ITEM'; public static CAMERA_ITEM: string = 'TVI_CAMERA_ITEM'; + public static MOD_TOOLS_ITEM: string = 'TVI_MOD_TOOLS_ITEM'; }