From 8aa7279e7cab4ab60e1db13e00c712f22014178e Mon Sep 17 00:00:00 2001 From: Bill Date: Sun, 20 Feb 2022 23:28:21 -0500 Subject: [PATCH] Update mod tools layout --- src/App.scss | 2 + src/assets/styles/bootstrap/_variables.scss | 2 +- src/assets/styles/utils.scss | 7 + src/components/mod-tools/ModToolsContext.tsx | 20 ++ .../mod-tools/ModToolsMessageHandler.tsx | 2 +- src/components/mod-tools/ModToolsView.scss | 96 ++++++++- src/components/mod-tools/ModToolsView.tsx | 34 +-- .../mod-tools/context/ModToolsContext.tsx | 14 -- .../context/ModToolsContext.types.ts | 13 -- .../mod-tools/views/chatlog/ChatlogView.scss | 40 ---- .../mod-tools/views/chatlog/ChatlogView.tsx | 168 ++++++++------- .../views/chatlog/ChatlogView.types.ts | 6 - .../ModToolsChatlogView.tsx | 39 ++-- .../mod-tools/views/room/ModToolsRoomView.tsx | 128 +++++++++++ .../room-chatlog/ModToolsChatlogView.types.ts | 5 - .../room/room-tools/ModToolsRoomView.scss | 8 - .../room/room-tools/ModToolsRoomView.tsx | 120 ----------- .../room/room-tools/ModToolsRoomView.types.ts | 5 - .../{issue-info => }/CfhChatlogView.tsx | 13 +- .../views/tickets/ModToolsIssueInfoView.tsx | 99 +++++++++ .../views/tickets/ModToolsMyIssuesTabView.tsx | 49 +++++ .../tickets/ModToolsOpenIssuesTabView.tsx | 44 ++++ .../tickets/ModToolsPickedIssuesTabView.tsx | 39 ++++ .../views/tickets/ModToolsTicketView.scss | 11 - .../views/tickets/ModToolsTicketsView.tsx | 48 ++--- .../tickets/ModToolsTicketsView.types.ts | 4 - .../issue-info/CfhChatlogView.types.ts | 5 - .../tickets/issue-info/IssueInfoView.tsx | 72 ------- .../tickets/issue-info/IssueInfoView.types.ts | 5 - .../my-issues/ModToolsMyIssuesTabView.tsx | 45 ---- .../ModToolsMyIssuesTabView.types.ts | 7 - .../open-issues/ModToolsOpenIssuesTabView.tsx | 42 ---- .../ModToolsOpenIssuesTabView.types.ts | 6 - .../ModToolsPickedIssuesTabView.tsx | 35 --- .../ModToolsPickedIssuesTabView.types.ts | 6 - .../ModToolsUserChatlogView.tsx | 45 ++-- .../views/user/ModToolsUserModActionView.tsx | 182 ++++++++++++++++ .../views/user/ModToolsUserRoomVisitsView.tsx | 85 ++++++++ .../user/ModToolsUserSendMessageView.tsx | 46 ++++ .../user/{user-info => }/ModToolsUserView.tsx | 73 ++++--- .../ModToolsUserChatlogView.types.ts | 5 - .../user/user-info/ModToolsUserView.scss | 23 -- .../user/user-info/ModToolsUserView.types.ts | 5 - .../ModToolsUserModActionView.tsx | 202 ------------------ .../ModToolsUserModActionView.types.ts | 7 - .../ModToolsUserRoomVisitsView.scss | 14 -- .../ModToolsUserRoomVisitsView.tsx | 69 ------ .../ModToolsUserRoomVisitsView.types.ts | 6 - .../ModToolsSendUserMessage.types.ts | 7 - .../ModToolsSendUserMessageView.tsx | 44 ---- src/index.scss | 1 + 51 files changed, 1025 insertions(+), 1028 deletions(-) create mode 100644 src/components/mod-tools/ModToolsContext.tsx delete mode 100644 src/components/mod-tools/context/ModToolsContext.tsx delete mode 100644 src/components/mod-tools/context/ModToolsContext.types.ts delete mode 100644 src/components/mod-tools/views/chatlog/ChatlogView.scss delete mode 100644 src/components/mod-tools/views/chatlog/ChatlogView.types.ts rename src/components/mod-tools/views/room/{room-chatlog => }/ModToolsChatlogView.tsx (59%) create mode 100644 src/components/mod-tools/views/room/ModToolsRoomView.tsx delete mode 100644 src/components/mod-tools/views/room/room-chatlog/ModToolsChatlogView.types.ts delete mode 100644 src/components/mod-tools/views/room/room-tools/ModToolsRoomView.scss delete mode 100644 src/components/mod-tools/views/room/room-tools/ModToolsRoomView.tsx delete mode 100644 src/components/mod-tools/views/room/room-tools/ModToolsRoomView.types.ts rename src/components/mod-tools/views/tickets/{issue-info => }/CfhChatlogView.tsx (88%) create mode 100644 src/components/mod-tools/views/tickets/ModToolsIssueInfoView.tsx create mode 100644 src/components/mod-tools/views/tickets/ModToolsMyIssuesTabView.tsx create mode 100644 src/components/mod-tools/views/tickets/ModToolsOpenIssuesTabView.tsx create mode 100644 src/components/mod-tools/views/tickets/ModToolsPickedIssuesTabView.tsx delete mode 100644 src/components/mod-tools/views/tickets/ModToolsTicketView.scss delete mode 100644 src/components/mod-tools/views/tickets/ModToolsTicketsView.types.ts delete mode 100644 src/components/mod-tools/views/tickets/issue-info/CfhChatlogView.types.ts delete mode 100644 src/components/mod-tools/views/tickets/issue-info/IssueInfoView.tsx delete mode 100644 src/components/mod-tools/views/tickets/issue-info/IssueInfoView.types.ts delete mode 100644 src/components/mod-tools/views/tickets/my-issues/ModToolsMyIssuesTabView.tsx delete mode 100644 src/components/mod-tools/views/tickets/my-issues/ModToolsMyIssuesTabView.types.ts delete mode 100644 src/components/mod-tools/views/tickets/open-issues/ModToolsOpenIssuesTabView.tsx delete mode 100644 src/components/mod-tools/views/tickets/open-issues/ModToolsOpenIssuesTabView.types.ts delete mode 100644 src/components/mod-tools/views/tickets/picked-issues/ModToolsPickedIssuesTabView.tsx delete mode 100644 src/components/mod-tools/views/tickets/picked-issues/ModToolsPickedIssuesTabView.types.ts rename src/components/mod-tools/views/user/{user-chatlog => }/ModToolsUserChatlogView.tsx (50%) create mode 100644 src/components/mod-tools/views/user/ModToolsUserModActionView.tsx create mode 100644 src/components/mod-tools/views/user/ModToolsUserRoomVisitsView.tsx create mode 100644 src/components/mod-tools/views/user/ModToolsUserSendMessageView.tsx rename src/components/mod-tools/views/user/{user-info => }/ModToolsUserView.tsx (72%) delete mode 100644 src/components/mod-tools/views/user/user-chatlog/ModToolsUserChatlogView.types.ts delete mode 100644 src/components/mod-tools/views/user/user-info/ModToolsUserView.scss delete mode 100644 src/components/mod-tools/views/user/user-info/ModToolsUserView.types.ts delete mode 100644 src/components/mod-tools/views/user/user-mod-action/ModToolsUserModActionView.tsx delete mode 100644 src/components/mod-tools/views/user/user-mod-action/ModToolsUserModActionView.types.ts delete mode 100644 src/components/mod-tools/views/user/user-room-visits/ModToolsUserRoomVisitsView.scss delete mode 100644 src/components/mod-tools/views/user/user-room-visits/ModToolsUserRoomVisitsView.tsx delete mode 100644 src/components/mod-tools/views/user/user-room-visits/ModToolsUserRoomVisitsView.types.ts delete mode 100644 src/components/mod-tools/views/user/user-sendmessage/ModToolsSendUserMessage.types.ts delete mode 100644 src/components/mod-tools/views/user/user-sendmessage/ModToolsSendUserMessageView.tsx diff --git a/src/App.scss b/src/App.scss index f612bddd..547c02c4 100644 --- a/src/App.scss +++ b/src/App.scss @@ -69,6 +69,8 @@ $camera-checkout-width: 350px; $room-info-width: 325px; +$nitro-mod-tools-width: 175px; + .nitro-app { width: 100%; height: 100%; diff --git a/src/assets/styles/bootstrap/_variables.scss b/src/assets/styles/bootstrap/_variables.scss index 6062e840..1fe7c21c 100644 --- a/src/assets/styles/bootstrap/_variables.scss +++ b/src/assets/styles/bootstrap/_variables.scss @@ -732,7 +732,7 @@ $table-cell-padding-x-sm: .25rem !default; $table-cell-vertical-align: top !default; -$table-color: $body-color !default; +$table-color: $black !default; $table-bg: transparent !default; $table-accent-bg: transparent !default; diff --git a/src/assets/styles/utils.scss b/src/assets/styles/utils.scss index c22e7cd2..029f054e 100644 --- a/src/assets/styles/utils.scss +++ b/src/assets/styles/utils.scss @@ -90,3 +90,10 @@ ul { .flex-basis-max-content { flex-basis: max-content; } + +.striped-children { + + > :nth-child(1) { + background-color: $table-striped-bg; + } +} diff --git a/src/components/mod-tools/ModToolsContext.tsx b/src/components/mod-tools/ModToolsContext.tsx new file mode 100644 index 00000000..1ab06b4c --- /dev/null +++ b/src/components/mod-tools/ModToolsContext.tsx @@ -0,0 +1,20 @@ +import { createContext, Dispatch, FC, ProviderProps, useContext } from 'react'; +import { IModToolsAction, IModToolsState } from './reducers/ModToolsReducer'; + +export interface IModToolsContext +{ + modToolsState: IModToolsState; + dispatchModToolsState: Dispatch; +} + +const ModToolsContext = createContext({ + modToolsState: null, + dispatchModToolsState: null +}); + +export const ModToolsContextProvider: FC> = props => +{ + return { props.children } +} + +export const useModToolsContext = () => useContext(ModToolsContext); diff --git a/src/components/mod-tools/ModToolsMessageHandler.tsx b/src/components/mod-tools/ModToolsMessageHandler.tsx index 1bd3aee3..82820610 100644 --- a/src/components/mod-tools/ModToolsMessageHandler.tsx +++ b/src/components/mod-tools/ModToolsMessageHandler.tsx @@ -10,7 +10,7 @@ import { CreateMessageHook, useRoomEngineEvent, useUiEvent } from '../../hooks'; import { NotificationAlertType } from '../../views/notification-center/common/NotificationAlertType'; import { NotificationUtilities } from '../../views/notification-center/common/NotificationUtilities'; import { SetCfhCategories } from './common/GetCFHCategories'; -import { useModToolsContext } from './context/ModToolsContext'; +import { useModToolsContext } from './ModToolsContext'; import { ModToolsActions } from './reducers/ModToolsReducer'; export const ModToolsMessageHandler: FC<{}> = props => diff --git a/src/components/mod-tools/ModToolsView.scss b/src/components/mod-tools/ModToolsView.scss index e8fb9e18..ac9a58da 100644 --- a/src/components/mod-tools/ModToolsView.scss +++ b/src/components/mod-tools/ModToolsView.scss @@ -1,9 +1,93 @@ .nitro-mod-tools { - width: 200px; + width: $nitro-mod-tools-width; } -@import './views/room/room-tools/ModToolsRoomView'; -@import './views/chatlog/ChatlogView'; -@import './views/user/user-info/ModToolsUserView'; -@import './views/user/user-room-visits/ModToolsUserRoomVisitsView'; -@import './views/tickets/ModToolsTicketView'; +.nitro-mod-tools-room { + width: 240px; + + .username { + color: #1E7295; + text-decoration: underline; + } +} + +.nitro-mod-tools-user { + width: 350px; + height: 370px; + + .username { + color: #1E7295; + text-decoration: underline; + } + + .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); + } + } +} + +.nitro-mod-tools-user-visits { + min-width: 300px; + + .user-visits { + min-height: 200px; + + .roomvisits-container { + div.room-visit { + } + } + + } +} + +.nitro-mod-tools-chatlog { + width: 400px; +} + +.nitro-mod-tools-user-visits { + width: 250px; +} + +.nitro-mod-tools-tickets { + width: 400px; + height: 200px; +} + +.nitro-mod-tools-handle-issue { + width: 400px; +} + +.nitro-mod-tools-chatlog, +.nitro-mod-tools-user-visits { + + .log-container { + min-height: 200px; + + .log-entry-container { + + .log-entry { + + &.highlighted { + border: 1px solid $red; + } + } + + &.highlighted { + border: 1px solid $red; + } + } + + &:first-child { + padding-top: 0; + } + } +} diff --git a/src/components/mod-tools/ModToolsView.tsx b/src/components/mod-tools/ModToolsView.tsx index 2084278d..3991c705 100644 --- a/src/components/mod-tools/ModToolsView.tsx +++ b/src/components/mod-tools/ModToolsView.tsx @@ -1,6 +1,8 @@ +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { RoomEngineObjectEvent, RoomObjectCategory } from '@nitrots/nitro-renderer'; import { FC, useCallback, useReducer, useState } from 'react'; import { GetRoomSession } from '../../api'; +import { Button } from '../../common'; import { ModToolsEvent } from '../../events/mod-tools/ModToolsEvent'; import { ModToolsOpenRoomChatlogEvent } from '../../events/mod-tools/ModToolsOpenRoomChatlogEvent'; import { ModToolsOpenRoomInfoEvent } from '../../events/mod-tools/ModToolsOpenRoomInfoEvent'; @@ -8,23 +10,23 @@ import { ModToolsOpenUserInfoEvent } from '../../events/mod-tools/ModToolsOpenUs 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 { ModToolsContextProvider } from './ModToolsContext'; import { ModToolsMessageHandler } from './ModToolsMessageHandler'; import { initialModTools, ModToolsActions, ModToolsReducer } from './reducers/ModToolsReducer'; import { ISelectedUser } from './utils/ISelectedUser'; -import { ModToolsChatlogView } from './views/room/room-chatlog/ModToolsChatlogView'; -import { ModToolsRoomView } from './views/room/room-tools/ModToolsRoomView'; +import { ModToolsChatlogView } from './views/room/ModToolsChatlogView'; +import { ModToolsRoomView } from './views/room/ModToolsRoomView'; import { ModToolsTicketsView } from './views/tickets/ModToolsTicketsView'; -import { ModToolsUserChatlogView } from './views/user/user-chatlog/ModToolsUserChatlogView'; -import { ModToolsUserView } from './views/user/user-info/ModToolsUserView'; +import { ModToolsUserChatlogView } from './views/user/ModToolsUserChatlogView'; +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, openRooms = null, openRoomChatlogs = null, openUserChatlogs = null, openUserInfo = null } = modToolsState; const [ selectedUser, setSelectedUser] = useState(null); const [ isTicketsVisible, setIsTicketsVisible ] = useState(false); + const [ modToolsState, dispatchModToolsState ] = useReducer(ModToolsReducer, initialModTools); + const { currentRoomId = null, openRooms = null, openRoomChatlogs = null, openUserChatlogs = null, openUserInfo = null } = modToolsState; const onModToolsEvent = useCallback((event: ModToolsEvent) => { @@ -190,11 +192,19 @@ export const ModToolsView: FC<{}> = props => { isVisible && setIsVisible(false) } /> - - - - - + + + + + } { openRooms && openRooms.map(roomId => diff --git a/src/components/mod-tools/context/ModToolsContext.tsx b/src/components/mod-tools/context/ModToolsContext.tsx deleted file mode 100644 index 97873603..00000000 --- a/src/components/mod-tools/context/ModToolsContext.tsx +++ /dev/null @@ -1,14 +0,0 @@ -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/components/mod-tools/context/ModToolsContext.types.ts b/src/components/mod-tools/context/ModToolsContext.types.ts deleted file mode 100644 index 46c6a9b8..00000000 --- a/src/components/mod-tools/context/ModToolsContext.types.ts +++ /dev/null @@ -1,13 +0,0 @@ -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/components/mod-tools/views/chatlog/ChatlogView.scss b/src/components/mod-tools/views/chatlog/ChatlogView.scss deleted file mode 100644 index 5d5f7d04..00000000 --- a/src/components/mod-tools/views/chatlog/ChatlogView.scss +++ /dev/null @@ -1,40 +0,0 @@ -.chatlog-messages { - color: $black; - min-width: 400px; - - $username-col-width: 100px; - - .username-label { - width: $username-col-width; - } - - .chatlog { - min-height: 200px; - - .chatlog-container { - color: $black; - - div.chatlog-entry { - border-bottom: 1px solid rgba(0, 0, 0, 0.2); - .username { - color: #1E7295; - text-decoration: underline; - width: $username-col-width; - } - - &.highlighted { - border: 1px solid $red; - } - - .message { - word-break: break-all; - } - } - - .room-info { - border-bottom: 1px solid rgba(0, 0, 0, 0.2); - background: rgba(0, 0, 0, .05); - } - } - } -} diff --git a/src/components/mod-tools/views/chatlog/ChatlogView.tsx b/src/components/mod-tools/views/chatlog/ChatlogView.tsx index c2394526..b6887dec 100644 --- a/src/components/mod-tools/views/chatlog/ChatlogView.tsx +++ b/src/components/mod-tools/views/chatlog/ChatlogView.tsx @@ -1,82 +1,87 @@ -import { ChatlineData, ChatRecordData, UserProfileComposer } from '@nitrots/nitro-renderer'; -import { FC, useCallback } from 'react'; -import { AutoSizer, CellMeasurer, CellMeasurerCache, List, ListRowProps, ListRowRenderer } from 'react-virtualized'; +import { ChatRecordData, UserProfileComposer } from '@nitrots/nitro-renderer'; +import { CSSProperties, FC, Key, useCallback } from 'react'; +import { AutoSizer, CellMeasurer, CellMeasurerCache, List, ListRowProps } from 'react-virtualized'; import { TryVisitRoom } from '../../../../api'; +import { Base, Button, Column, Flex, Grid, Text } from '../../../../common'; import { ModToolsOpenRoomInfoEvent } from '../../../../events/mod-tools/ModToolsOpenRoomInfoEvent'; import { dispatchUiEvent, SendMessageHook } from '../../../../hooks'; -import { ChatlogViewProps } from './ChatlogView.types'; + +interface ChatlogViewProps +{ + records: ChatRecordData[]; +} export const ChatlogView: FC = props => { const { records = null } = props; - const simpleRowRenderer: ListRowRenderer = (props: ListRowProps) => + const rowRenderer = (props: ListRowProps) => { - const item = records[0].chatlog[props.index]; + let chatlogEntry = records[0].chatlog[props.index]; return ( -
-
{item.timestamp}
-
SendMessageHook(new UserProfileComposer(item.userId))}>{item.userName}
-
{item.message}
-
+ + { chatlogEntry.timestamp } + SendMessageHook(new UserProfileComposer(chatlogEntry.userId)) }>{ chatlogEntry.userName } + { chatlogEntry.message } +
); }; - const advancedRowRenderer: ListRowRenderer = (props: ListRowProps) => + const advancedRowRenderer = (props: ListRowProps) => { - let chatlogEntry: ChatlineData; - let currentRecord: ChatRecordData; + let chatlogEntry = null; + let currentRecord: ChatRecordData = null; let isRoomInfo = false; - let totalIndex = 0; + for(let i = 0; i < records.length; i++) { currentRecord = records[i]; totalIndex++; // row for room info - totalIndex = totalIndex + currentRecord.chatlog.length; + totalIndex = (totalIndex + currentRecord.chatlog.length); - if(props.index > (totalIndex - 1)) - { - continue; // it is not in current one - } + if(props.index > (totalIndex - 1)) continue; - if( (props.index + 1) === (totalIndex - currentRecord.chatlog.length)) + if((props.index + 1) === (totalIndex - currentRecord.chatlog.length)) { isRoomInfo = true; + break; } - const index = props.index - (totalIndex - currentRecord.chatlog.length); + + const index = (props.index - (totalIndex - currentRecord.chatlog.length)); + chatlogEntry = currentRecord.chatlog[index]; + break; } return ( - {isRoomInfo && } - {!isRoomInfo && -
-
{chatlogEntry.timestamp}
-
SendMessageHook(new UserProfileComposer(chatlogEntry.userId))}>{chatlogEntry.userName}
-
{chatlogEntry.message}
-
- } - + { (isRoomInfo && currentRecord) && + } + { !isRoomInfo && + + { chatlogEntry.timestamp } + SendMessageHook(new UserProfileComposer(chatlogEntry.userId)) }>{ chatlogEntry.userName } + { chatlogEntry.message } + }
); } @@ -94,57 +99,60 @@ export const ChatlogView: FC = props => return count; }, [records]); + const RoomInfo = (props: { roomId: number, roomName: string, uniqueKey: Key, style: CSSProperties }) => + { + return ( + + + Room name: + { props.roomName } + + + + + + + ); + } + const cache = new CellMeasurerCache({ defaultHeight: 25, fixedWidth: true }); - const RoomInfo = useCallback(({ roomId, roomName, uniqueKey, style }) => - { - return ( -
-
Room: {roomName}
- - -
- ); - }, []); - return ( <> - { - (records && records.length) && - <> - {(records.length === 1) && } -
-
-
Time
-
User
-
Message
-
-
- - {({ height, width }) => + { (records && (records.length === 1)) && + } + + + + Time + User + Message + + + { (records && (records.length > 0)) && + + + { ({ height, width }) => { cache.clearAll(); return ( 1 ? getNumRowsForAdvanced() : records[0].chatlog.length} - rowHeight={cache.rowHeight} - className={'chatlog-container'} - rowRenderer={records.length > 1 ? advancedRowRenderer : simpleRowRenderer} - deferredMeasurementCache={cache} /> - ) - } - } - -
-
- - } + width={ width } + height={ height } + rowCount={ (records.length > 1) ? getNumRowsForAdvanced() : records[0].chatlog.length } + rowHeight={ cache.rowHeight } + className={ 'log-entry-container' } + rowRenderer={ (records.length > 1) ? advancedRowRenderer : rowRenderer } + deferredMeasurementCache={ cache } /> + ); + } } + + } + ); } diff --git a/src/components/mod-tools/views/chatlog/ChatlogView.types.ts b/src/components/mod-tools/views/chatlog/ChatlogView.types.ts deleted file mode 100644 index f307109f..00000000 --- a/src/components/mod-tools/views/chatlog/ChatlogView.types.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { ChatRecordData } from '@nitrots/nitro-renderer'; - -export interface ChatlogViewProps -{ - records: ChatRecordData[]; -} diff --git a/src/components/mod-tools/views/room/room-chatlog/ModToolsChatlogView.tsx b/src/components/mod-tools/views/room/ModToolsChatlogView.tsx similarity index 59% rename from src/components/mod-tools/views/room/room-chatlog/ModToolsChatlogView.tsx rename to src/components/mod-tools/views/room/ModToolsChatlogView.tsx index 96d11aba..b42dafa9 100644 --- a/src/components/mod-tools/views/room/room-chatlog/ModToolsChatlogView.tsx +++ b/src/components/mod-tools/views/room/ModToolsChatlogView.tsx @@ -1,20 +1,19 @@ import { ChatRecordData, GetRoomChatlogMessageComposer, RoomChatlogEvent } from '@nitrots/nitro-renderer'; import { FC, useCallback, useEffect, useState } from 'react'; -import { CreateMessageHook, SendMessageHook } from '../../../../../hooks/messages'; -import { NitroCardContentView, NitroCardHeaderView, NitroCardView } from '../../../../../layout'; -import { ChatlogView } from '../../chatlog/ChatlogView'; -import { ModToolsChatlogViewProps } from './ModToolsChatlogView.types'; +import { CreateMessageHook, SendMessageHook } from '../../../../hooks/messages'; +import { NitroCardContentView, NitroCardHeaderView, NitroCardView } from '../../../../layout'; +import { ChatlogView } from '../chatlog/ChatlogView'; + +interface ModToolsChatlogViewProps +{ + roomId: number; + onCloseClick: () => void; +} export const ModToolsChatlogView: FC = props => { const { roomId = null, onCloseClick = null } = props; - - const [roomChatlog, setRoomChatlog] = useState(null); - - useEffect(() => - { - SendMessageHook(new GetRoomChatlogMessageComposer(roomId)); - }, [roomId]); + const [ roomChatlog, setRoomChatlog ] = useState(null); const onModtoolRoomChatlogEvent = useCallback((event: RoomChatlogEvent) => { @@ -23,17 +22,23 @@ export const ModToolsChatlogView: FC = props => if(!parser || parser.data.roomId !== roomId) return; setRoomChatlog(parser.data); - }, [roomId, setRoomChatlog]); + }, [ roomId ]); CreateMessageHook(RoomChatlogEvent, onModtoolRoomChatlogEvent); + useEffect(() => + { + SendMessageHook(new GetRoomChatlogMessageComposer(roomId)); + }, [ roomId ]); + + if(!roomChatlog) return null; + return ( - - onCloseClick()} /> + + - {roomChatlog && - - } + { roomChatlog && + } ); diff --git a/src/components/mod-tools/views/room/ModToolsRoomView.tsx b/src/components/mod-tools/views/room/ModToolsRoomView.tsx new file mode 100644 index 00000000..97a22c8c --- /dev/null +++ b/src/components/mod-tools/views/room/ModToolsRoomView.tsx @@ -0,0 +1,128 @@ +import { GetModeratorRoomInfoMessageComposer, ModerateRoomMessageComposer, ModeratorActionMessageComposer, ModeratorRoomInfoEvent } from '@nitrots/nitro-renderer'; +import { FC, useCallback, useEffect, useState } from 'react'; +import { TryVisitRoom } from '../../../../api'; +import { Button, Column, Flex, Text } from '../../../../common'; +import { ModToolsOpenRoomChatlogEvent } from '../../../../events/mod-tools/ModToolsOpenRoomChatlogEvent'; +import { BatchUpdates, dispatchUiEvent } from '../../../../hooks'; +import { CreateMessageHook, SendMessageHook } from '../../../../hooks/messages'; +import { NitroCardContentView, NitroCardHeaderView, NitroCardView } from '../../../../layout'; + +interface ModToolsRoomViewProps +{ + roomId: number; + onCloseClick: () => void; +} + +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); + + //form data + const [ kickUsers, setKickUsers ] = useState(false); + const [ lockRoom, setLockRoom ] = useState(false); + const [ changeRoomName, setChangeRoomName ] = useState(false); + const [ message, setMessage ] = useState(''); + + const onModtoolRoomInfoEvent = useCallback((event: ModeratorRoomInfoEvent) => + { + const parser = event.getParser(); + + if(!parser || parser.data.flatId !== roomId) return; + + BatchUpdates(() => + { + setLoadedRoomId(parser.data.flatId); + setName(parser.data.room.name); + setOwnerId(parser.data.ownerId); + setOwnerName(parser.data.ownerName); + setOwnerInRoom(parser.data.ownerInRoom); + setUsersInRoom(parser.data.userCount); + }); + }, [ roomId ]); + + CreateMessageHook(ModeratorRoomInfoEvent, onModtoolRoomInfoEvent); + + const handleClick = useCallback((action: string, value?: string) => + { + if(!action) return; + + switch(action) + { + case 'alert_only': + if(message.trim().length === 0) return; + + SendMessageHook(new ModeratorActionMessageComposer(ModeratorActionMessageComposer.ACTION_ALERT, message, '')); + return; + case 'send_message': + if(message.trim().length === 0) return; + + SendMessageHook(new ModeratorActionMessageComposer(ModeratorActionMessageComposer.ACTION_MESSAGE, message, '')); + SendMessageHook(new ModerateRoomMessageComposer(roomId, lockRoom ? 1 : 0, changeRoomName ? 1 : 0, kickUsers ? 1 : 0)) + return; + } + }, [ changeRoomName, kickUsers, lockRoom, message, roomId ]); + + useEffect(() => + { + if(infoRequested) return; + + SendMessageHook(new GetModeratorRoomInfoMessageComposer(roomId)); + setInfoRequested(true); + }, [ roomId, infoRequested, setInfoRequested ]); + + return ( + + onCloseClick() } /> + + + + + Room Owner: + { ownerName } + + + Users in room: + { usersInRoom } + + + Owner in room: + { ownerInRoom ? 'Yes' : 'No' } + + + + + + + + + + setKickUsers(event.target.checked) } /> + Kick everyone out + + + setLockRoom(event.target.checked) } /> + Enable the doorbell + + + setChangeRoomName(event.target.checked) }/> + Change room name + + + + + + + + + + ); +} diff --git a/src/components/mod-tools/views/room/room-chatlog/ModToolsChatlogView.types.ts b/src/components/mod-tools/views/room/room-chatlog/ModToolsChatlogView.types.ts deleted file mode 100644 index 0589cd02..00000000 --- a/src/components/mod-tools/views/room/room-chatlog/ModToolsChatlogView.types.ts +++ /dev/null @@ -1,5 +0,0 @@ -export interface ModToolsChatlogViewProps -{ - roomId: number; - onCloseClick: () => void; -} diff --git a/src/components/mod-tools/views/room/room-tools/ModToolsRoomView.scss b/src/components/mod-tools/views/room/room-tools/ModToolsRoomView.scss deleted file mode 100644 index 4faa2b33..00000000 --- a/src/components/mod-tools/views/room/room-tools/ModToolsRoomView.scss +++ /dev/null @@ -1,8 +0,0 @@ -.nitro-mod-tools-room { - width: 240px; - - .username { - color: #1E7295; - text-decoration: underline; - } -} diff --git a/src/components/mod-tools/views/room/room-tools/ModToolsRoomView.tsx b/src/components/mod-tools/views/room/room-tools/ModToolsRoomView.tsx deleted file mode 100644 index 3f40c1c6..00000000 --- a/src/components/mod-tools/views/room/room-tools/ModToolsRoomView.tsx +++ /dev/null @@ -1,120 +0,0 @@ -import { GetModeratorRoomInfoMessageComposer, ModerateRoomMessageComposer, ModeratorActionMessageComposer, ModeratorRoomInfoEvent } from '@nitrots/nitro-renderer'; -import { FC, useCallback, useEffect, useState } from 'react'; -import { TryVisitRoom } from '../../../../../api'; -import { ModToolsOpenRoomChatlogEvent } from '../../../../../events/mod-tools/ModToolsOpenRoomChatlogEvent'; -import { dispatchUiEvent } from '../../../../../hooks'; -import { CreateMessageHook, SendMessageHook } from '../../../../../hooks/messages'; -import { NitroCardContentView, NitroCardHeaderView, NitroCardView } from '../../../../../layout'; -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); - - //form data - const [kickUsers, setKickUsers] = useState(false); - const [lockRoom, setLockRoom] = useState(false); - const [changeRoomName, setChangeRoomName] = useState(false); - const [message, setMessage] = useState(''); - - useEffect(() => - { - if(infoRequested) return; - - SendMessageHook(new GetModeratorRoomInfoMessageComposer(roomId)); - setInfoRequested(true); - }, [ roomId, infoRequested, setInfoRequested ]); - - const onModtoolRoomInfoEvent = useCallback((event: ModeratorRoomInfoEvent) => - { - const parser = event.getParser(); - - if(!parser || parser.data.flatId !== roomId) return; - - setLoadedRoomId(parser.data.flatId); - setName(parser.data.room.name); - setOwnerId(parser.data.ownerId); - setOwnerName(parser.data.ownerName); - setOwnerInRoom(parser.data.ownerInRoom); - setUsersInRoom(parser.data.userCount); - }, [ setLoadedRoomId, setName, setOwnerId, setOwnerName, setOwnerInRoom, setUsersInRoom, roomId ]); - - CreateMessageHook(ModeratorRoomInfoEvent, onModtoolRoomInfoEvent); - - const handleClick = useCallback((action: string, value?: string) => - { - if(!action) return; - - switch(action) - { - case 'alert_only': - if(message.trim().length === 0) return; - SendMessageHook(new ModeratorActionMessageComposer(ModeratorActionMessageComposer.ACTION_ALERT, message, '')); - return; - case 'send_message': - if(message.trim().length === 0) return; - SendMessageHook(new ModeratorActionMessageComposer(ModeratorActionMessageComposer.ACTION_MESSAGE, message, '')); - SendMessageHook(new ModerateRoomMessageComposer(roomId, lockRoom ? 1 : 0, changeRoomName ? 1 : 0, kickUsers ? 1 : 0)) - return; - } - }, [changeRoomName, kickUsers, lockRoom, message, roomId]); - - return ( - - onCloseClick() } /> - -
-
- Room Owner: { ownerName } -
- -
-
-
- Users in room: { usersInRoom } -
- -
-
-
- Owner in room: { ownerInRoom ? 'Yes' : 'No' } -
-
-
-
- setKickUsers(e.target.checked)}/> - -
-
- setLockRoom(e.target.checked)}/> - -
-
- setChangeRoomName(e.target.checked)}/> - -
-
- -
- - -
-
-
- ); -} diff --git a/src/components/mod-tools/views/room/room-tools/ModToolsRoomView.types.ts b/src/components/mod-tools/views/room/room-tools/ModToolsRoomView.types.ts deleted file mode 100644 index d096fcbe..00000000 --- a/src/components/mod-tools/views/room/room-tools/ModToolsRoomView.types.ts +++ /dev/null @@ -1,5 +0,0 @@ -export interface ModToolsRoomViewProps -{ - roomId: number; - onCloseClick: () => void; -} diff --git a/src/components/mod-tools/views/tickets/issue-info/CfhChatlogView.tsx b/src/components/mod-tools/views/tickets/CfhChatlogView.tsx similarity index 88% rename from src/components/mod-tools/views/tickets/issue-info/CfhChatlogView.tsx rename to src/components/mod-tools/views/tickets/CfhChatlogView.tsx index fdb4c28e..de2bba64 100644 --- a/src/components/mod-tools/views/tickets/issue-info/CfhChatlogView.tsx +++ b/src/components/mod-tools/views/tickets/CfhChatlogView.tsx @@ -1,9 +1,14 @@ import { CfhChatlogData, CfhChatlogEvent, GetCfhChatlogMessageComposer } from '@nitrots/nitro-renderer'; import { FC, useCallback, useEffect, useState } from 'react'; -import { CreateMessageHook, SendMessageHook } from '../../../../../hooks'; -import { NitroCardContentView, NitroCardHeaderView, NitroCardView } from '../../../../../layout'; -import { ChatlogView } from '../../chatlog/ChatlogView'; -import { CfhChatlogViewProps } from './CfhChatlogView.types'; +import { CreateMessageHook, SendMessageHook } from '../../../../hooks'; +import { NitroCardContentView, NitroCardHeaderView, NitroCardView } from '../../../../layout'; +import { ChatlogView } from '../chatlog/ChatlogView'; + +interface CfhChatlogViewProps +{ + issueId: number; + onCloseClick(): void; +} export const CfhChatlogView: FC = props => { diff --git a/src/components/mod-tools/views/tickets/ModToolsIssueInfoView.tsx b/src/components/mod-tools/views/tickets/ModToolsIssueInfoView.tsx new file mode 100644 index 00000000..6fa92c1e --- /dev/null +++ b/src/components/mod-tools/views/tickets/ModToolsIssueInfoView.tsx @@ -0,0 +1,99 @@ +import { CloseIssuesMessageComposer, ReleaseIssuesMessageComposer } from '@nitrots/nitro-renderer'; +import { FC, useMemo, useState } from 'react'; +import { LocalizeText } from '../../../../api'; +import { Button, Column, Grid, Text } from '../../../../common'; +import { ModToolsOpenUserInfoEvent } from '../../../../events/mod-tools/ModToolsOpenUserInfoEvent'; +import { dispatchUiEvent, SendMessageHook } from '../../../../hooks'; +import { NitroCardContentView, NitroCardHeaderView, NitroCardView } from '../../../../layout'; +import { getSourceName } from '../../common/IssueCategoryNames'; +import { useModToolsContext } from '../../ModToolsContext'; +import { CfhChatlogView } from './CfhChatlogView'; + +interface IssueInfoViewProps +{ + issueId: number; + onIssueInfoClosed(issueId: number): void; +} + +export const ModToolsIssueInfoView: FC = props => +{ + const { issueId = null, onIssueInfoClosed = null } = props; + const { modToolsState = null } = useModToolsContext(); + const { tickets = null } = modToolsState; + const [ cfhChatlogOpen, setcfhChatlogOpen ] = useState(false); + + const ticket = useMemo(() => + { + if(!tickets || !tickets.length) return null; + + return tickets.find(issue => issue.issueId === issueId); + }, [ issueId, tickets ]); + + const releaseIssue = (issueId: number) => + { + SendMessageHook(new ReleaseIssuesMessageComposer([ issueId ])); + + onIssueInfoClosed(issueId); + } + + const closeIssue = (resolutionType: number) => + { + SendMessageHook(new CloseIssuesMessageComposer([ issueId ], resolutionType)); + + onIssueInfoClosed(issueId) + } + + const openUserInfo = (userId: number) => dispatchUiEvent(new ModToolsOpenUserInfoEvent(userId)); + + return ( + <> + + onIssueInfoClosed(issueId)} /> + + Issue Information + + + + + + + + + + + + + + + + + + + + + + + + + +
Source{ getSourceName(ticket.categoryId) }
Category{ LocalizeText('help.cfh.topic.' + ticket.reportedCategoryId) }
Description{ ticket.message }
Caller + openUserInfo(ticket.reporterUserId) }>{ ticket.reporterUserName } +
Reported User + openUserInfo(ticket.reportedUserId) }>{ ticket.reportedUserName } +
+
+ + + + + + + +
+
+
+ { cfhChatlogOpen && + setcfhChatlogOpen(false) }/> } + + ); +} diff --git a/src/components/mod-tools/views/tickets/ModToolsMyIssuesTabView.tsx b/src/components/mod-tools/views/tickets/ModToolsMyIssuesTabView.tsx new file mode 100644 index 00000000..bba92740 --- /dev/null +++ b/src/components/mod-tools/views/tickets/ModToolsMyIssuesTabView.tsx @@ -0,0 +1,49 @@ +import { IssueMessageData, ReleaseIssuesMessageComposer } from '@nitrots/nitro-renderer'; +import { FC } from 'react'; +import { Base, Button, Column, Grid } from '../../../../common'; +import { SendMessageHook } from '../../../../hooks'; + +interface ModToolsMyIssuesTabViewProps +{ + myIssues: IssueMessageData[]; + onIssueHandleClick(issueId: number): void; +} + +export const ModToolsMyIssuesTabView: FC = props => +{ + const { myIssues = null, onIssueHandleClick = null } = props; + + const onReleaseIssue = (issueId: number) => SendMessageHook(new ReleaseIssuesMessageComposer([issueId])); + + return ( + + + + Type + Room/Player + Opened + + + + + + { myIssues && (myIssues.length > 0) && myIssues.map(issue => + { + return ( + + { issue.categoryId } + { issue.reportedUserName } + { new Date(Date.now() - issue.issueAgeInMilliseconds).toLocaleTimeString() } + + + + + + + + ); + }) } + + + ); +} diff --git a/src/components/mod-tools/views/tickets/ModToolsOpenIssuesTabView.tsx b/src/components/mod-tools/views/tickets/ModToolsOpenIssuesTabView.tsx new file mode 100644 index 00000000..1d980631 --- /dev/null +++ b/src/components/mod-tools/views/tickets/ModToolsOpenIssuesTabView.tsx @@ -0,0 +1,44 @@ +import { IssueMessageData, PickIssuesMessageComposer } from '@nitrots/nitro-renderer'; +import { FC } from 'react'; +import { Base, Button, Column, Grid } from '../../../../common'; +import { SendMessageHook } from '../../../../hooks'; + +interface ModToolsOpenIssuesTabViewProps +{ + openIssues: IssueMessageData[]; +} + +export const ModToolsOpenIssuesTabView: FC = props => +{ + const { openIssues = null } = props; + + const onPickIssue = (issueId: number) => SendMessageHook(new PickIssuesMessageComposer([issueId], false, 0, 'pick issue button')); + + return ( + + + + Type + Room/Player + Opened + + + + + { openIssues && (openIssues.length > 0) && openIssues.map(issue => + { + return ( + + { issue.categoryId } + { issue.reportedUserName } + { new Date(Date.now() - issue.issueAgeInMilliseconds).toLocaleTimeString() } + + + + + ); + }) } + + + ); +} diff --git a/src/components/mod-tools/views/tickets/ModToolsPickedIssuesTabView.tsx b/src/components/mod-tools/views/tickets/ModToolsPickedIssuesTabView.tsx new file mode 100644 index 00000000..6f155971 --- /dev/null +++ b/src/components/mod-tools/views/tickets/ModToolsPickedIssuesTabView.tsx @@ -0,0 +1,39 @@ +import { IssueMessageData } from '@nitrots/nitro-renderer'; +import { FC } from 'react'; +import { Base, Column, Grid } from '../../../../common'; + +interface ModToolsPickedIssuesTabViewProps +{ + pickedIssues: IssueMessageData[]; +} + +export const ModToolsPickedIssuesTabView: FC = props => +{ + const { pickedIssues = null } = props; + + return ( + + + + Type + Room/Player + Opened + Picker + + + + { pickedIssues && (pickedIssues.length > 0) && pickedIssues.map(issue => + { + return ( + + { issue.categoryId } + { issue.reportedUserName } + { new Date(Date.now() - issue.issueAgeInMilliseconds).toLocaleTimeString() } + { issue.pickerUserName } + + ); + }) } + + + ); +} diff --git a/src/components/mod-tools/views/tickets/ModToolsTicketView.scss b/src/components/mod-tools/views/tickets/ModToolsTicketView.scss deleted file mode 100644 index f2459483..00000000 --- a/src/components/mod-tools/views/tickets/ModToolsTicketView.scss +++ /dev/null @@ -1,11 +0,0 @@ -.nitro-mod-tools-tickets -{ - width: 400px; - height: 200px; -} - -.nitro-mod-tools-handle-issue -{ - width: 400px; - height: 300px; -} diff --git a/src/components/mod-tools/views/tickets/ModToolsTicketsView.tsx b/src/components/mod-tools/views/tickets/ModToolsTicketsView.tsx index e2ccea90..e6b91996 100644 --- a/src/components/mod-tools/views/tickets/ModToolsTicketsView.tsx +++ b/src/components/mod-tools/views/tickets/ModToolsTicketsView.tsx @@ -2,12 +2,16 @@ import { IssueMessageData } from '@nitrots/nitro-renderer'; import { FC, useCallback, useMemo, useState } from 'react'; import { GetSessionDataManager } from '../../../../api'; import { NitroCardContentView, NitroCardHeaderView, NitroCardTabsItemView, NitroCardTabsView, NitroCardView } from '../../../../layout'; -import { useModToolsContext } from '../../context/ModToolsContext'; -import { IssueInfoView } from './issue-info/IssueInfoView'; -import { ModToolsTicketsViewProps } from './ModToolsTicketsView.types'; -import { ModToolsMyIssuesTabView } from './my-issues/ModToolsMyIssuesTabView'; -import { ModToolsOpenIssuesTabView } from './open-issues/ModToolsOpenIssuesTabView'; -import { ModToolsPickedIssuesTabView } from './picked-issues/ModToolsPickedIssuesTabView'; +import { useModToolsContext } from '../../ModToolsContext'; +import { ModToolsIssueInfoView } from './ModToolsIssueInfoView'; +import { ModToolsMyIssuesTabView } from './ModToolsMyIssuesTabView'; +import { ModToolsOpenIssuesTabView } from './ModToolsOpenIssuesTabView'; +import { ModToolsPickedIssuesTabView } from './ModToolsPickedIssuesTabView'; + +interface ModToolsTicketsViewProps +{ + onCloseClick: () => void; +} const TABS: string[] = [ 'Open Issues', @@ -82,25 +86,21 @@ export const ModToolsTicketsView: FC = props => return ( <> - - - - - { TABS.map((tab, index) => - { - return ( setCurrentTab(index) }> - { tab } - ); - }) } - -
+ + + + { TABS.map((tab, index) => + { + return ( setCurrentTab(index) }> + { tab } + ); + }) } + + -
-
-
- { - issueInfoWindows && issueInfoWindows.map(issueId => ) - } + +
+ { issueInfoWindows && (issueInfoWindows.length > 0) && issueInfoWindows.map(issueId => ) } ); } diff --git a/src/components/mod-tools/views/tickets/ModToolsTicketsView.types.ts b/src/components/mod-tools/views/tickets/ModToolsTicketsView.types.ts deleted file mode 100644 index 16495592..00000000 --- a/src/components/mod-tools/views/tickets/ModToolsTicketsView.types.ts +++ /dev/null @@ -1,4 +0,0 @@ -export interface ModToolsTicketsViewProps -{ - onCloseClick: () => void; -} diff --git a/src/components/mod-tools/views/tickets/issue-info/CfhChatlogView.types.ts b/src/components/mod-tools/views/tickets/issue-info/CfhChatlogView.types.ts deleted file mode 100644 index c40c18ad..00000000 --- a/src/components/mod-tools/views/tickets/issue-info/CfhChatlogView.types.ts +++ /dev/null @@ -1,5 +0,0 @@ -export interface CfhChatlogViewProps -{ - issueId: number; - onCloseClick(): void; -} diff --git a/src/components/mod-tools/views/tickets/issue-info/IssueInfoView.tsx b/src/components/mod-tools/views/tickets/issue-info/IssueInfoView.tsx deleted file mode 100644 index 8030cc7f..00000000 --- a/src/components/mod-tools/views/tickets/issue-info/IssueInfoView.tsx +++ /dev/null @@ -1,72 +0,0 @@ -import { CloseIssuesMessageComposer, ReleaseIssuesMessageComposer } from '@nitrots/nitro-renderer'; -import { FC, useCallback, useMemo, useState } from 'react'; -import { LocalizeText } from '../../../../../api'; -import { ModToolsOpenUserInfoEvent } from '../../../../../events/mod-tools/ModToolsOpenUserInfoEvent'; -import { dispatchUiEvent, SendMessageHook } from '../../../../../hooks'; -import { NitroCardContentView, NitroCardHeaderView, NitroCardView } from '../../../../../layout'; -import { getSourceName } from '../../../common/IssueCategoryNames'; -import { useModToolsContext } from '../../../context/ModToolsContext'; -import { CfhChatlogView } from './CfhChatlogView'; -import { IssueInfoViewProps } from './IssueInfoView.types'; - -export const IssueInfoView: FC = props => -{ - const { issueId = null, onIssueInfoClosed = null } = props; - const { modToolsState = null } = useModToolsContext(); - const { tickets= null } = modToolsState; - const [ cfhChatlogOpen, setcfhChatlogOpen ] = useState(false); - - const ticket = useMemo(() => - { - return tickets.find( issue => issue.issueId === issueId); - }, [issueId, tickets]); - - const onReleaseIssue = useCallback((issueId: number) => - { - SendMessageHook(new ReleaseIssuesMessageComposer([issueId])); - onIssueInfoClosed(issueId); - }, [onIssueInfoClosed]); - - const openUserInfo = useCallback((userId: number) => - { - dispatchUiEvent(new ModToolsOpenUserInfoEvent(userId)); - }, []); - - const closeIssue = useCallback((resolutionType: number) => - { - SendMessageHook(new CloseIssuesMessageComposer([issueId], resolutionType)); - onIssueInfoClosed(issueId) - }, [issueId, onIssueInfoClosed]); - - return ( - <> - - onIssueInfoClosed(issueId)} /> - -
-
-

Issue Information

-
Source: {getSourceName(ticket.categoryId)}
-
Category: {LocalizeText('help.cfh.topic.' + ticket.reportedCategoryId)}
-
Description: {ticket.message}
-
Caller:
-
Reported User:
-
-
-
- -
-
- - - - -
-
-
-
-
- { cfhChatlogOpen && setcfhChatlogOpen(false) }/>} - - ); -} diff --git a/src/components/mod-tools/views/tickets/issue-info/IssueInfoView.types.ts b/src/components/mod-tools/views/tickets/issue-info/IssueInfoView.types.ts deleted file mode 100644 index 1b28d803..00000000 --- a/src/components/mod-tools/views/tickets/issue-info/IssueInfoView.types.ts +++ /dev/null @@ -1,5 +0,0 @@ -export interface IssueInfoViewProps -{ - issueId: number; - onIssueInfoClosed(issueId: number): void; -} diff --git a/src/components/mod-tools/views/tickets/my-issues/ModToolsMyIssuesTabView.tsx b/src/components/mod-tools/views/tickets/my-issues/ModToolsMyIssuesTabView.tsx deleted file mode 100644 index 1a3fcde3..00000000 --- a/src/components/mod-tools/views/tickets/my-issues/ModToolsMyIssuesTabView.tsx +++ /dev/null @@ -1,45 +0,0 @@ -import { ReleaseIssuesMessageComposer } from '@nitrots/nitro-renderer'; -import { FC, useCallback } from 'react'; -import { SendMessageHook } from '../../../../../hooks'; -import { ModToolsMyIssuesTabViewProps } from './ModToolsMyIssuesTabView.types'; - -export const ModToolsMyIssuesTabView: FC = props => -{ - const { myIssues = null, onIssueHandleClick = null } = props; - - - const onReleaseIssue = useCallback((issueId: number) => - { - SendMessageHook(new ReleaseIssuesMessageComposer([issueId])); - }, []); - - return ( - <> - - - - - - - - - - - - {myIssues.map(issue => - { - return ( - - - - - - - ) - }) - } - -
TypeRoom/PlayerOpened
{issue.categoryId}{issue.reportedUserName}{new Date(Date.now() - issue.issueAgeInMilliseconds).toLocaleTimeString()}
- - ); -} diff --git a/src/components/mod-tools/views/tickets/my-issues/ModToolsMyIssuesTabView.types.ts b/src/components/mod-tools/views/tickets/my-issues/ModToolsMyIssuesTabView.types.ts deleted file mode 100644 index 6d03fbf8..00000000 --- a/src/components/mod-tools/views/tickets/my-issues/ModToolsMyIssuesTabView.types.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { IssueMessageData } from '@nitrots/nitro-renderer'; - -export interface ModToolsMyIssuesTabViewProps -{ - myIssues: IssueMessageData[]; - onIssueHandleClick(issueId: number): void; -} diff --git a/src/components/mod-tools/views/tickets/open-issues/ModToolsOpenIssuesTabView.tsx b/src/components/mod-tools/views/tickets/open-issues/ModToolsOpenIssuesTabView.tsx deleted file mode 100644 index 4f8bb6d6..00000000 --- a/src/components/mod-tools/views/tickets/open-issues/ModToolsOpenIssuesTabView.tsx +++ /dev/null @@ -1,42 +0,0 @@ -import { PickIssuesMessageComposer } from '@nitrots/nitro-renderer'; -import { FC, useCallback } from 'react'; -import { SendMessageHook } from '../../../../../hooks'; -import { ModToolsOpenIssuesTabViewProps } from './ModToolsOpenIssuesTabView.types'; - -export const ModToolsOpenIssuesTabView: FC = props => -{ - const { openIssues = null } = props; - - const onPickIssue = useCallback((issueId: number) => - { - SendMessageHook(new PickIssuesMessageComposer([issueId], false, 0, 'pick issue button')); - }, []); - - return ( - <> - - - - - - - - - - - {openIssues.map(issue => - { - return ( - - - - - - ) - }) - } - -
TypeRoom/PlayerOpened
{issue.categoryId}{issue.reportedUserName}{new Date(Date.now() - issue.issueAgeInMilliseconds).toLocaleTimeString()}
- - ); -} diff --git a/src/components/mod-tools/views/tickets/open-issues/ModToolsOpenIssuesTabView.types.ts b/src/components/mod-tools/views/tickets/open-issues/ModToolsOpenIssuesTabView.types.ts deleted file mode 100644 index 45a80d7d..00000000 --- a/src/components/mod-tools/views/tickets/open-issues/ModToolsOpenIssuesTabView.types.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { IssueMessageData } from '@nitrots/nitro-renderer'; - -export interface ModToolsOpenIssuesTabViewProps -{ - openIssues: IssueMessageData[]; -} diff --git a/src/components/mod-tools/views/tickets/picked-issues/ModToolsPickedIssuesTabView.tsx b/src/components/mod-tools/views/tickets/picked-issues/ModToolsPickedIssuesTabView.tsx deleted file mode 100644 index 988a0fd9..00000000 --- a/src/components/mod-tools/views/tickets/picked-issues/ModToolsPickedIssuesTabView.tsx +++ /dev/null @@ -1,35 +0,0 @@ -import { FC } from 'react'; -import { ModToolsPickedIssuesTabViewProps } from './ModToolsPickedIssuesTabView.types'; - -export const ModToolsPickedIssuesTabView: FC = props => -{ - const { pickedIssues = null } = props; - - return ( - <> - - - - - - - - - - - {pickedIssues.map(issue => - { - return ( - - - - - - ) - }) - } - -
TypeRoom/PlayerOpenedPicker
{issue.categoryId}{issue.reportedUserName}{new Date(Date.now() - issue.issueAgeInMilliseconds).toLocaleTimeString()}{issue.pickerUserName}
- - ); -} diff --git a/src/components/mod-tools/views/tickets/picked-issues/ModToolsPickedIssuesTabView.types.ts b/src/components/mod-tools/views/tickets/picked-issues/ModToolsPickedIssuesTabView.types.ts deleted file mode 100644 index c69b1772..00000000 --- a/src/components/mod-tools/views/tickets/picked-issues/ModToolsPickedIssuesTabView.types.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { IssueMessageData } from '@nitrots/nitro-renderer'; - -export interface ModToolsPickedIssuesTabViewProps -{ - pickedIssues: IssueMessageData[]; -} diff --git a/src/components/mod-tools/views/user/user-chatlog/ModToolsUserChatlogView.tsx b/src/components/mod-tools/views/user/ModToolsUserChatlogView.tsx similarity index 50% rename from src/components/mod-tools/views/user/user-chatlog/ModToolsUserChatlogView.tsx rename to src/components/mod-tools/views/user/ModToolsUserChatlogView.tsx index 705cc690..6a4f9d8a 100644 --- a/src/components/mod-tools/views/user/user-chatlog/ModToolsUserChatlogView.tsx +++ b/src/components/mod-tools/views/user/ModToolsUserChatlogView.tsx @@ -1,20 +1,20 @@ import { ChatRecordData, GetUserChatlogMessageComposer, UserChatlogEvent } from '@nitrots/nitro-renderer'; import { FC, useCallback, useEffect, useState } from 'react'; -import { CreateMessageHook, SendMessageHook } from '../../../../../hooks'; -import { NitroCardContentView, NitroCardHeaderView, NitroCardView } from '../../../../../layout'; -import { ChatlogView } from '../../chatlog/ChatlogView'; -import { ModToolsUserChatlogViewProps } from './ModToolsUserChatlogView.types'; +import { BatchUpdates, CreateMessageHook, SendMessageHook } from '../../../../hooks'; +import { NitroCardContentView, NitroCardHeaderView, NitroCardView } from '../../../../layout'; +import { ChatlogView } from '../chatlog/ChatlogView'; + +interface ModToolsUserChatlogViewProps +{ + userId: number; + onCloseClick: () => void; +} export const ModToolsUserChatlogView: FC = props => { const { userId = null, onCloseClick = null } = props; - const [userChatlog, setUserChatlog] = useState(null); - const [username, setUsername] = useState(null); - - useEffect(() => - { - SendMessageHook(new GetUserChatlogMessageComposer(userId)); - }, [userId]); + const [ userChatlog, setUserChatlog ] = useState(null); + const [ username, setUsername ] = useState(null); const onModtoolUserChatlogEvent = useCallback((event: UserChatlogEvent) => { @@ -22,19 +22,26 @@ export const ModToolsUserChatlogView: FC = props = if(!parser || parser.data.userId !== userId) return; - setUsername(parser.data.username); - setUserChatlog(parser.data.roomChatlogs); - }, [setUsername, setUserChatlog, userId]); + BatchUpdates(() => + { + setUsername(parser.data.username); + setUserChatlog(parser.data.roomChatlogs); + }); + }, [ userId ]); CreateMessageHook(UserChatlogEvent, onModtoolUserChatlogEvent); + useEffect(() => + { + SendMessageHook(new GetUserChatlogMessageComposer(userId)); + }, [ userId ]); + return ( - - onCloseClick()} /> + + - {userChatlog && - - } + { userChatlog && + } ); diff --git a/src/components/mod-tools/views/user/ModToolsUserModActionView.tsx b/src/components/mod-tools/views/user/ModToolsUserModActionView.tsx new file mode 100644 index 00000000..ba291fe4 --- /dev/null +++ b/src/components/mod-tools/views/user/ModToolsUserModActionView.tsx @@ -0,0 +1,182 @@ +import { CallForHelpTopicData, DefaultSanctionMessageComposer, ModAlertMessageComposer, ModBanMessageComposer, ModKickMessageComposer, ModMessageMessageComposer, ModMuteMessageComposer, ModTradingLockMessageComposer } from '@nitrots/nitro-renderer'; +import { FC, useMemo, useState } from 'react'; +import { LocalizeText } from '../../../../api'; +import { Button, Column, Flex, Text } from '../../../../common'; +import { SendMessageHook } from '../../../../hooks'; +import { NitroCardContentView, NitroCardHeaderView, NitroCardView } from '../../../../layout'; +import { NotificationAlertType } from '../../../../views/notification-center/common/NotificationAlertType'; +import { NotificationUtilities } from '../../../../views/notification-center/common/NotificationUtilities'; +import { useModToolsContext } from '../../ModToolsContext'; +import { ISelectedUser } from '../../utils/ISelectedUser'; +import { ModActionDefinition } from '../../utils/ModActionDefinition'; + +interface ModToolsUserModActionViewProps +{ + user: ISelectedUser; + onCloseClick: () => void; +} + +const MOD_ACTION_DEFINITIONS = [ + new ModActionDefinition(1, 'Alert', ModActionDefinition.ALERT, 1, 0), + new ModActionDefinition(2, 'Mute 1h', ModActionDefinition.MUTE, 2, 0), + new ModActionDefinition(4, 'Ban 7 days', ModActionDefinition.BAN, 4, 0), + new ModActionDefinition(3, 'Ban 18h', ModActionDefinition.BAN, 3, 0), + new ModActionDefinition(5, 'Ban 30 days (step 1)', ModActionDefinition.BAN, 5, 0), + new ModActionDefinition(7, 'Ban 30 days (step 2)', ModActionDefinition.BAN, 7, 0), + new ModActionDefinition(6, 'Ban 100 years', ModActionDefinition.BAN, 6, 0), + new ModActionDefinition(106, 'Ban avatar-only 100 years', ModActionDefinition.BAN, 6, 0), + new ModActionDefinition(101, 'Kick', ModActionDefinition.KICK, 0, 0), + new ModActionDefinition(102, 'Lock trade 1 week', ModActionDefinition.TRADE_LOCK, 0, 168), + new ModActionDefinition(104, 'Lock trade permanent', ModActionDefinition.TRADE_LOCK, 0, 876000), + new ModActionDefinition(105, 'Message', ModActionDefinition.MESSAGE, 0, 0), +]; + +export const ModToolsUserModActionView: FC = props => +{ + const { user = null, onCloseClick = null } = props; + const [ selectedTopic, setSelectedTopic ] = useState(-1); + const [ selectedAction, setSelectedAction ] = useState(-1); + const [ message, setMessage ] = useState(''); + const { modToolsState = null } = useModToolsContext(); + const { cfhCategories = null, settings = null } = modToolsState; + + const topics = useMemo(() => + { + const values: CallForHelpTopicData[] = []; + + if(cfhCategories && cfhCategories.length) + { + for(const category of cfhCategories) + { + for(const topic of category.topics) values.push(topic); + } + } + + return values; + }, [ cfhCategories ]); + + const sendAlert = (message: string) => + { + NotificationUtilities.simpleAlert(message, NotificationAlertType.DEFAULT, null, null, 'Error'); + } + + const sendDefaultSanction = () => + { + SendMessageHook(new DefaultSanctionMessageComposer(user.userId, selectedTopic, message)); + + onCloseClick(); + } + + const sendSanction = () => + { + let errorMessage: string = null; + + const category = topics[selectedTopic]; + const sanction = MOD_ACTION_DEFINITIONS[selectedAction]; + + if((selectedTopic === -1) || (selectedAction === -1)) errorMessage = 'You must select a CFH topic and Sanction'; + else if(!settings || !settings.cfhPermission) errorMessage = 'You do not have permission to do this'; + else if(!category) errorMessage = 'You must select a CFH topic'; + else if(!sanction) errorMessage = 'You must select a sanction'; + + if(errorMessage) + { + sendAlert('You must select a sanction'); + + return; + } + + const messageOrDefault = (message.trim().length === 0) ? LocalizeText(`help.cfh.topic.${ category.id }`) : message; + + switch(sanction.actionType) + { + case ModActionDefinition.ALERT: { + if(!settings.alertPermission) + { + sendAlert('You have insufficient permissions'); + + return; + } + + if(message.trim().length === 0) + { + sendAlert('Please write a message to user'); + + return; + } + + SendMessageHook(new ModAlertMessageComposer(user.userId, message, category.id)); + break; + } + case ModActionDefinition.MUTE: + SendMessageHook(new ModMuteMessageComposer(user.userId, messageOrDefault, category.id)); + break; + case ModActionDefinition.BAN: { + if(!settings.banPermission) + { + sendAlert('You have insufficient permissions'); + + return; + } + + SendMessageHook(new ModBanMessageComposer(user.userId, messageOrDefault, category.id, selectedAction, (sanction.actionId === 106))); + break; + } + case ModActionDefinition.KICK: { + if(!settings.kickPermission) + { + sendAlert('You have insufficient permissions'); + return; + } + + SendMessageHook(new ModKickMessageComposer(user.userId, messageOrDefault, category.id)); + break; + } + case ModActionDefinition.TRADE_LOCK: { + const numSeconds = (sanction.actionLengthHours * 60); + + SendMessageHook(new ModTradingLockMessageComposer(user.userId, messageOrDefault, numSeconds, category.id)); + break; + } + case ModActionDefinition.MESSAGE: { + if(message.trim().length === 0) + { + sendAlert('Please write a message to user'); + + return; + } + + SendMessageHook(new ModMessageMessageComposer(user.userId, message, category.id)); + break; + } + } + + onCloseClick(); + } + + if(!user) return null; + + return ( + + onCloseClick() } /> + + + + + Optional message type, overrides default + + + + + ); +} diff --git a/src/components/mod-tools/views/user/user-info/ModToolsUserView.tsx b/src/components/mod-tools/views/user/ModToolsUserView.tsx similarity index 72% rename from src/components/mod-tools/views/user/user-info/ModToolsUserView.tsx rename to src/components/mod-tools/views/user/ModToolsUserView.tsx index 24f8c876..3203658f 100644 --- a/src/components/mod-tools/views/user/user-info/ModToolsUserView.tsx +++ b/src/components/mod-tools/views/user/ModToolsUserView.tsx @@ -1,13 +1,19 @@ import { FriendlyTime, GetModeratorUserInfoMessageComposer, ModeratorUserInfoData, ModeratorUserInfoEvent } from '@nitrots/nitro-renderer'; import { FC, useCallback, useEffect, useMemo, useState } from 'react'; -import { LocalizeText } from '../../../../../api'; -import { ModToolsOpenUserChatlogEvent } from '../../../../../events/mod-tools/ModToolsOpenUserChatlogEvent'; -import { CreateMessageHook, dispatchUiEvent, SendMessageHook } from '../../../../../hooks'; -import { NitroCardContentView, NitroCardHeaderView, NitroCardView, NitroLayoutButton, NitroLayoutGrid, NitroLayoutGridColumn } from '../../../../../layout'; -import { ModToolsUserModActionView } from '../user-mod-action/ModToolsUserModActionView'; -import { ModToolsUserRoomVisitsView } from '../user-room-visits/ModToolsUserRoomVisitsView'; -import { ModToolsSendUserMessageView } from '../user-sendmessage/ModToolsSendUserMessageView'; -import { ModToolsUserViewProps } from './ModToolsUserView.types'; +import { LocalizeText } from '../../../../api'; +import { Button, Column, Grid } from '../../../../common'; +import { ModToolsOpenUserChatlogEvent } from '../../../../events/mod-tools/ModToolsOpenUserChatlogEvent'; +import { CreateMessageHook, dispatchUiEvent, SendMessageHook } from '../../../../hooks'; +import { NitroCardContentView, NitroCardHeaderView, NitroCardView } from '../../../../layout'; +import { ModToolsUserModActionView } from './ModToolsUserModActionView'; +import { ModToolsUserRoomVisitsView } from './ModToolsUserRoomVisitsView'; +import { ModToolsUserSendMessageView } from './ModToolsUserSendMessageView'; + +interface ModToolsUserViewProps +{ + userId: number; + onCloseClick: () => void; +} export const ModToolsUserView: FC = props => { @@ -17,11 +23,6 @@ export const ModToolsUserView: FC = props => const [ modActionVisible, setModActionVisible ] = useState(false); const [ roomVisitsVisible, setRoomVisitsVisible ] = useState(false); - useEffect(() => - { - SendMessageHook(new GetModeratorUserInfoMessageComposer(userId)); - }, [ userId ]); - const onModtoolUserInfoEvent = useCallback((event: ModeratorUserInfoEvent) => { const parser = event.getParser(); @@ -29,7 +30,7 @@ export const ModToolsUserView: FC = props => if(!parser || parser.data.userId !== userId) return; setUserInfo(parser.data); - }, [setUserInfo, userId]); + }, [ userId ]); CreateMessageHook(ModeratorUserInfoEvent, onModtoolUserInfoEvent); @@ -98,52 +99,58 @@ export const ModToolsUserView: FC = props => ]; }, [ userInfo ]); + useEffect(() => + { + SendMessageHook(new GetModeratorUserInfoMessageComposer(userId)); + }, [ userId ]); + if(!userInfo) return null; return ( <> - + onCloseClick() } /> - - + + { userProperties.map( (property, index) => { return ( - + + { property.showOnline && + } + ); }) }
{ LocalizeText(property.localeKey) } { property.value } - { property.showOnline && } -
-
- - dispatchUiEvent(new ModToolsOpenUserChatlogEvent(userId)) }> + + + + + + + +
{ sendMessageVisible && - setSendMessageVisible(false) } /> } + setSendMessageVisible(false) } /> } { modActionVisible && setModActionVisible(false) } /> } { roomVisitsVisible && diff --git a/src/components/mod-tools/views/user/user-chatlog/ModToolsUserChatlogView.types.ts b/src/components/mod-tools/views/user/user-chatlog/ModToolsUserChatlogView.types.ts deleted file mode 100644 index c8eea569..00000000 --- a/src/components/mod-tools/views/user/user-chatlog/ModToolsUserChatlogView.types.ts +++ /dev/null @@ -1,5 +0,0 @@ -export interface ModToolsUserChatlogViewProps -{ - userId: number; - onCloseClick: () => void; -} diff --git a/src/components/mod-tools/views/user/user-info/ModToolsUserView.scss b/src/components/mod-tools/views/user/user-info/ModToolsUserView.scss deleted file mode 100644 index ddc24350..00000000 --- a/src/components/mod-tools/views/user/user-info/ModToolsUserView.scss +++ /dev/null @@ -1,23 +0,0 @@ -.nitro-mod-tools-user { - width: 350px; - height: 370px; - - .username { - color: #1E7295; - text-decoration: underline; - } - - .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); - } - } -} diff --git a/src/components/mod-tools/views/user/user-info/ModToolsUserView.types.ts b/src/components/mod-tools/views/user/user-info/ModToolsUserView.types.ts deleted file mode 100644 index 534d647d..00000000 --- a/src/components/mod-tools/views/user/user-info/ModToolsUserView.types.ts +++ /dev/null @@ -1,5 +0,0 @@ -export interface ModToolsUserViewProps -{ - userId: number; - onCloseClick: () => void; -} diff --git a/src/components/mod-tools/views/user/user-mod-action/ModToolsUserModActionView.tsx b/src/components/mod-tools/views/user/user-mod-action/ModToolsUserModActionView.tsx deleted file mode 100644 index 0963d152..00000000 --- a/src/components/mod-tools/views/user/user-mod-action/ModToolsUserModActionView.tsx +++ /dev/null @@ -1,202 +0,0 @@ -import { CallForHelpTopicData, DefaultSanctionMessageComposer, ModAlertMessageComposer, ModBanMessageComposer, ModKickMessageComposer, ModMessageMessageComposer, ModMuteMessageComposer, ModTradingLockMessageComposer } from '@nitrots/nitro-renderer'; -import { FC, useCallback, useMemo, useState } from 'react'; -import { LocalizeText } from '../../../../../api'; -import { SendMessageHook } from '../../../../../hooks'; -import { NitroCardContentView, NitroCardHeaderView, NitroCardView } from '../../../../../layout'; -import { NotificationAlertType } from '../../../../../views/notification-center/common/NotificationAlertType'; -import { NotificationUtilities } from '../../../../../views/notification-center/common/NotificationUtilities'; -import { useModToolsContext } from '../../../context/ModToolsContext'; -import { ModActionDefinition } from '../../../utils/ModActionDefinition'; -import { ModToolsUserModActionViewProps } from './ModToolsUserModActionView.types'; - -const actions = [ - new ModActionDefinition(1, 'Alert', ModActionDefinition.ALERT, 1, 0), - new ModActionDefinition(2, 'Mute 1h', ModActionDefinition.MUTE, 2, 0), - new ModActionDefinition(4, 'Ban 7 days', ModActionDefinition.BAN, 4, 0), - new ModActionDefinition(3, 'Ban 18h', ModActionDefinition.BAN, 3, 0), - new ModActionDefinition(5, 'Ban 30 days (step 1)', ModActionDefinition.BAN, 5, 0), - new ModActionDefinition(7, 'Ban 30 days (step 2)', ModActionDefinition.BAN, 7, 0), - new ModActionDefinition(6, 'Ban 100 years', ModActionDefinition.BAN, 6, 0), - new ModActionDefinition(106, 'Ban avatar-only 100 years', ModActionDefinition.BAN, 6, 0), - new ModActionDefinition(101, 'Kick', ModActionDefinition.KICK, 0, 0), - new ModActionDefinition(102, 'Lock trade 1 week', ModActionDefinition.TRADE_LOCK, 0, 168), - new ModActionDefinition(104, 'Lock trade permanent', ModActionDefinition.TRADE_LOCK, 0, 876000), - new ModActionDefinition(105, 'Message', ModActionDefinition.MESSAGE, 0, 0), -]; - -export const ModToolsUserModActionView: FC = props => -{ - const { user = null, onCloseClick = null } = props; - const { modToolsState = null, dispatchModToolsState = null } = useModToolsContext(); - const { cfhCategories = null, settings = null } = modToolsState; - const [ selectedTopic, setSelectedTopic ] = useState(-1); - const [ selectedAction, setSelectedAction ] = useState(-1); - const [ message, setMessage ] = useState(''); - - const topics = useMemo(() => - { - const values: CallForHelpTopicData[] = []; - - if(!cfhCategories) return values; - - for(let category of cfhCategories) - { - for(let topic of category.topics) - { - values.push(topic) - } - } - - return values; - }, [cfhCategories]); - - const sendDefaultSanction = useCallback(() => - { - SendMessageHook(new DefaultSanctionMessageComposer(user.userId, selectedTopic, message)); - onCloseClick(); - }, [message, onCloseClick, selectedTopic, user.userId]); - - const sendSanction = useCallback(() => - { - if( (selectedTopic === -1) || (selectedAction === -1) ) - { - NotificationUtilities.simpleAlert('You must select a CFH topic and Sanction', NotificationAlertType.DEFAULT, null, null, 'Error'); - return; - } - - if(!settings || !settings.cfhPermission) - { - NotificationUtilities.simpleAlert('You do not have permission to do this', NotificationAlertType.DEFAULT, null, null, 'Error'); - return; - } - - const category = topics[selectedTopic]; - const sanction = actions[selectedAction]; - - if(!category) - { - NotificationUtilities.simpleAlert('You must select a CFH topic', NotificationAlertType.DEFAULT, null, null, 'Error'); - return; - } - - if(!sanction) - { - NotificationUtilities.simpleAlert('You must select a sanction', NotificationAlertType.DEFAULT, null, null, 'Error'); - return; - } - - const messageOrDefault = message.trim().length === 0 ? LocalizeText('help.cfh.topic.' + category.id) : message; - - switch(sanction.actionType) - { - case ModActionDefinition.ALERT: - - if(!settings.alertPermission) - { - NotificationUtilities.simpleAlert('You have insufficient permissions', NotificationAlertType.DEFAULT, null, null, 'Error'); - return; - } - - if(message.trim().length === 0) - { - NotificationUtilities.simpleAlert('Please write a message to user', NotificationAlertType.DEFAULT, null, null, 'Error'); - return; - } - - SendMessageHook(new ModAlertMessageComposer(user.userId, message, category.id)); - - break; - case ModActionDefinition.MUTE: - SendMessageHook(new ModMuteMessageComposer(user.userId, messageOrDefault, category.id)); - - break; - case ModActionDefinition.BAN: - - if(!settings.banPermission) - { - NotificationUtilities.simpleAlert('You have insufficient permissions', NotificationAlertType.DEFAULT, null, null, 'Error'); - return; - } - - SendMessageHook(new ModBanMessageComposer(user.userId, messageOrDefault, category.id, selectedAction, (sanction.actionId === 106))); - - break; - - case ModActionDefinition.KICK: - - if(!settings.kickPermission) - { - NotificationUtilities.simpleAlert('You have insufficient permissions', NotificationAlertType.DEFAULT, null, null, 'Error'); - return; - } - - SendMessageHook(new ModKickMessageComposer(user.userId, messageOrDefault, category.id)); - - break; - - case ModActionDefinition.TRADE_LOCK: - { - const numSeconds = sanction.actionLengthHours * 60; - SendMessageHook(new ModTradingLockMessageComposer(user.userId, messageOrDefault, numSeconds, category.id)); - } - break; - - case ModActionDefinition.MESSAGE: - - if(message.trim().length === 0) - { - NotificationUtilities.simpleAlert('Please write a message to user', NotificationAlertType.DEFAULT, null, null, 'Error'); - return; - } - - SendMessageHook(new ModMessageMessageComposer(user.userId, message, category.id)); - - break; - } - - onCloseClick(); - }, [message, onCloseClick, selectedAction, selectedTopic, settings, topics, user.userId]); - - return ( - - onCloseClick() } /> - - { user && - <> -
- -
- -
- -
- -
- - -
- -
- -
- } -
-
- ); -} diff --git a/src/index.scss b/src/index.scss index d655fc16..82b5446d 100644 --- a/src/index.scss +++ b/src/index.scss @@ -9,6 +9,7 @@ body { user-select: none; image-rendering: pixelated; image-rendering: -moz-crisp-edges; + scrollbar-width: thin; } img {