From 7dc980af904466d3e2ceedb01a3a6dfe35faa9a3 Mon Sep 17 00:00:00 2001 From: Bill Date: Tue, 26 Jul 2022 18:19:30 -0400 Subject: [PATCH] Refactor reporting, add messenger reporting --- src/api/chat-history/ChatEntryType.ts | 1 + .../MessengerHistoryCurrentDate.ts | 6 + src/api/chat-history/index.ts | 1 + .../{IHelpReportState.ts => IHelpReport.ts} | 9 +- src/api/help/ReportState.ts | 8 + src/api/help/ReportType.ts | 11 ++ src/api/help/index.ts | 4 +- .../views/messenger/FriendsMessengerView.tsx | 7 +- src/components/guide-tool/GuideToolView.tsx | 12 +- src/components/help/HelpContext.tsx | 20 --- src/components/help/HelpMessageHandler.tsx | 45 ----- src/components/help/HelpView.tsx | 166 ++++++++---------- .../help/views/DescribeReportView.tsx | 43 +++-- src/components/help/views/HelpIndexView.tsx | 33 ++-- .../help/views/ReportSummaryView.tsx | 57 ++++++ .../help/views/SanctionStatusView.tsx | 28 +-- .../help/views/SelectReportedChatsView.tsx | 57 +++--- .../help/views/SelectReportedUserView.tsx | 36 ++-- src/components/help/views/SelectTopicView.tsx | 20 +-- .../user/ModToolsUserSendMessageView.tsx | 9 +- .../menu/AvatarInfoWidgetAvatarView.tsx | 8 +- src/events/help/HelpReportUserEvent.ts | 20 --- src/events/help/index.ts | 1 - src/events/index.ts | 1 - .../NotificationAlertEvent.ts | 55 ------ .../NotificationBubbleEvent.ts | 41 ----- .../NotificationCenterAlertEvent.ts | 34 ---- .../NotificationCenterEvent.ts | 9 - .../NotificationConfirmEvent.ts | 62 ------- src/events/notification-center/index.ts | 5 - src/hooks/chat-history/useChatHistory.ts | 39 +++- src/hooks/help/index.ts | 1 + src/hooks/help/useHelp.ts | 144 +++++++++++++++ src/hooks/index.ts | 1 + 34 files changed, 471 insertions(+), 523 deletions(-) create mode 100644 src/api/chat-history/MessengerHistoryCurrentDate.ts rename src/api/help/{IHelpReportState.ts => IHelpReport.ts} (54%) create mode 100644 src/api/help/ReportState.ts create mode 100644 src/api/help/ReportType.ts delete mode 100644 src/components/help/HelpContext.tsx delete mode 100644 src/components/help/HelpMessageHandler.tsx create mode 100644 src/components/help/views/ReportSummaryView.tsx delete mode 100644 src/events/help/HelpReportUserEvent.ts delete mode 100644 src/events/notification-center/NotificationAlertEvent.ts delete mode 100644 src/events/notification-center/NotificationBubbleEvent.ts delete mode 100644 src/events/notification-center/NotificationCenterAlertEvent.ts delete mode 100644 src/events/notification-center/NotificationCenterEvent.ts delete mode 100644 src/events/notification-center/NotificationConfirmEvent.ts delete mode 100644 src/events/notification-center/index.ts create mode 100644 src/hooks/help/index.ts create mode 100644 src/hooks/help/useHelp.ts diff --git a/src/api/chat-history/ChatEntryType.ts b/src/api/chat-history/ChatEntryType.ts index c49cd0ea..045f00ce 100644 --- a/src/api/chat-history/ChatEntryType.ts +++ b/src/api/chat-history/ChatEntryType.ts @@ -2,4 +2,5 @@ export class ChatEntryType { public static TYPE_CHAT = 1; public static TYPE_ROOM_INFO = 2; + public static TYPE_IM = 3; } diff --git a/src/api/chat-history/MessengerHistoryCurrentDate.ts b/src/api/chat-history/MessengerHistoryCurrentDate.ts new file mode 100644 index 00000000..3aeebc50 --- /dev/null +++ b/src/api/chat-history/MessengerHistoryCurrentDate.ts @@ -0,0 +1,6 @@ +export const MessengerHistoryCurrentDate = (secondsSinceNow: number = 0) => +{ + const currentTime = secondsSinceNow ? new Date(Date.now() - secondsSinceNow * 1000) : new Date(); + + return `${ currentTime.getHours().toString().padStart(2, '0') }:${ currentTime.getMinutes().toString().padStart(2, '0') }`; +} diff --git a/src/api/chat-history/index.ts b/src/api/chat-history/index.ts index a1447992..a9893744 100644 --- a/src/api/chat-history/index.ts +++ b/src/api/chat-history/index.ts @@ -2,3 +2,4 @@ export * from './ChatEntryType'; export * from './ChatHistoryCurrentDate'; export * from './IChatEntry'; export * from './IRoomHistoryEntry'; +export * from './MessengerHistoryCurrentDate'; diff --git a/src/api/help/IHelpReportState.ts b/src/api/help/IHelpReport.ts similarity index 54% rename from src/api/help/IHelpReportState.ts rename to src/api/help/IHelpReport.ts index 38c73095..86117072 100644 --- a/src/api/help/IHelpReportState.ts +++ b/src/api/help/IHelpReport.ts @@ -1,12 +1,19 @@ import { IChatEntry } from '../chat-history'; -export interface IHelpReportState +export interface IHelpReport { + reportType: number; reportedUserId: number; reportedChats: IChatEntry[]; cfhCategory: number; cfhTopic: number; roomId: number; + roomName: string; + groupId: number; + threadId: number; + messageId: number; + extraData: string; + roomObjectId: number; message: string; currentStep: number; } diff --git a/src/api/help/ReportState.ts b/src/api/help/ReportState.ts new file mode 100644 index 00000000..ae3a3bd3 --- /dev/null +++ b/src/api/help/ReportState.ts @@ -0,0 +1,8 @@ +export class ReportState +{ + public static readonly SELECT_USER = 0; + public static readonly SELECT_CHATS = 1; + public static readonly SELECT_TOPICS = 2; + public static readonly INPUT_REPORT_MESSAGE = 3; + public static readonly REPORT_SUMMARY = 4; +} diff --git a/src/api/help/ReportType.ts b/src/api/help/ReportType.ts new file mode 100644 index 00000000..24eb7aec --- /dev/null +++ b/src/api/help/ReportType.ts @@ -0,0 +1,11 @@ +export class ReportType +{ + public static readonly EMERGENCY = 1; + public static readonly GUIDE = 2; + public static readonly IM = 3; + public static readonly ROOM = 4; + public static readonly BULLY = 6; + public static readonly THREAD = 7; + public static readonly MESSAGE = 8; + public static readonly PHOTO = 9; +} diff --git a/src/api/help/index.ts b/src/api/help/index.ts index b46aad9e..6fa20455 100644 --- a/src/api/help/index.ts +++ b/src/api/help/index.ts @@ -1,4 +1,6 @@ export * from './CallForHelpResult'; export * from './GetCloseReasonKey'; -export * from './IHelpReportState'; +export * from './IHelpReport'; export * from './IReportedUser'; +export * from './ReportState'; +export * from './ReportType'; diff --git a/src/components/friends/views/messenger/FriendsMessengerView.tsx b/src/components/friends/views/messenger/FriendsMessengerView.tsx index d10770bc..14f6bede 100644 --- a/src/components/friends/views/messenger/FriendsMessengerView.tsx +++ b/src/components/friends/views/messenger/FriendsMessengerView.tsx @@ -1,9 +1,9 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { FollowFriendMessageComposer, ILinkEventTracker } from '@nitrots/nitro-renderer'; import { FC, KeyboardEvent, useEffect, useRef, useState } from 'react'; -import { AddEventLinkTracker, GetUserProfile, LocalizeText, RemoveLinkEventTracker, SendMessageComposer } from '../../../../api'; +import { AddEventLinkTracker, GetUserProfile, LocalizeText, RemoveLinkEventTracker, ReportType, SendMessageComposer } from '../../../../api'; import { Base, Button, ButtonGroup, Column, Flex, Grid, LayoutAvatarImageView, LayoutBadgeImageView, LayoutGridItem, LayoutItemCountView, NitroCardContentView, NitroCardHeaderView, NitroCardView, Text } from '../../../../common'; -import { useMessenger } from '../../../../hooks'; +import { useHelp, useMessenger } from '../../../../hooks'; import { FriendsMessengerThreadView } from './messenger-thread/FriendsMessengerThreadView'; export const FriendsMessengerView: FC<{}> = props => @@ -12,6 +12,7 @@ export const FriendsMessengerView: FC<{}> = props => const [ lastThreadId, setLastThreadId ] = useState(-1); const [ messageText, setMessageText ] = useState(''); const { visibleThreads = [], activeThread = null, getMessageThread = null, sendMessage = null, setActiveThreadId = null, closeThread = null } = useMessenger(); + const { report = null } = useHelp(); const messagesBox = useRef(); const followFriend = () => (activeThread && activeThread.participant && SendMessageComposer(new FollowFriendMessageComposer(activeThread.participant.id))); @@ -141,7 +142,7 @@ export const FriendsMessengerView: FC<{}> = props => - diff --git a/src/components/guide-tool/GuideToolView.tsx b/src/components/guide-tool/GuideToolView.tsx index 2025f493..7d94fa33 100644 --- a/src/components/guide-tool/GuideToolView.tsx +++ b/src/components/guide-tool/GuideToolView.tsx @@ -1,9 +1,9 @@ import { GuideOnDutyStatusMessageEvent, GuideSessionAttachedMessageEvent, GuideSessionDetachedMessageEvent, GuideSessionEndedMessageEvent, GuideSessionInvitedToGuideRoomMessageEvent, GuideSessionMessageMessageEvent, GuideSessionOnDutyUpdateMessageComposer, GuideSessionPartnerIsTypingMessageEvent, GuideSessionStartedMessageEvent, ILinkEventTracker, PerkAllowancesMessageEvent, PerkEnum } from '@nitrots/nitro-renderer'; import { FC, useCallback, useEffect, useState } from 'react'; -import { AddEventLinkTracker, DispatchUiEvent, GetConfiguration, GetSessionDataManager, GuideSessionState, GuideToolMessage, GuideToolMessageGroup, LocalizeText, RemoveLinkEventTracker, SendMessageComposer } from '../../api'; +import { AddEventLinkTracker, GetConfiguration, GetSessionDataManager, GuideSessionState, GuideToolMessage, GuideToolMessageGroup, LocalizeText, RemoveLinkEventTracker, SendMessageComposer } from '../../api'; import { NitroCardContentView, NitroCardHeaderView, NitroCardView } from '../../common'; -import { GuideToolEvent, NotificationAlertEvent } from '../../events'; -import { useMessageEvent, useUiEvent } from '../../hooks'; +import { GuideToolEvent } from '../../events'; +import { useMessageEvent, useNotification, useUiEvent } from '../../hooks'; import { GuideToolAcceptView } from './views/GuideToolAcceptView'; import { GuideToolMenuView } from './views/GuideToolMenuView'; import { GuideToolOngoingView } from './views/GuideToolOngoingView'; @@ -39,6 +39,8 @@ export const GuideToolView: FC<{}> = props => const [ ongoingIsTyping, setOngoingIsTyping ] = useState(false); const [ ongoingMessageGroups, setOngoingMessageGroups ] = useState([]); + const { simpleAlert = null } = useNotification(); + const updateSessionState = useCallback((newState: string, replacement?: string) => { switch(newState) @@ -296,7 +298,7 @@ export const GuideToolView: FC<{}> = props => case 'toggle_duty': if(!isHandlingBullyReports && !isHandlingGuideRequests && !isHandlingHelpRequests) { - DispatchUiEvent(new NotificationAlertEvent([ LocalizeText('guide.help.guide.tool.noqueueselected.message') ], null, null, null, LocalizeText('guide.help.guide.tool.noqueueselected.caption'), null)); + simpleAlert(LocalizeText('guide.help.guide.tool.noqueueselected.message'), null, null, null, LocalizeText('guide.help.guide.tool.noqueueselected.caption'), null); return; } @@ -312,7 +314,7 @@ export const GuideToolView: FC<{}> = props => window.open(url); return; } - }, [ isHandlingBullyReports, isHandlingGuideRequests, isHandlingHelpRequests ]); + }, [ isHandlingBullyReports, isHandlingGuideRequests, isHandlingHelpRequests, simpleAlert ]); if(!isVisible) return null; diff --git a/src/components/help/HelpContext.tsx b/src/components/help/HelpContext.tsx deleted file mode 100644 index aee8e96c..00000000 --- a/src/components/help/HelpContext.tsx +++ /dev/null @@ -1,20 +0,0 @@ -import { createContext, Dispatch, FC, ProviderProps, SetStateAction, useContext } from 'react'; -import { IHelpReportState } from '../../api'; - -interface IHelpContext -{ - helpReportState: IHelpReportState; - setHelpReportState: Dispatch>; -} - -const HelpContext = createContext({ - helpReportState: null, - setHelpReportState: null -}); - -export const HelpContextProvider: FC> = props => -{ - return { props.children } -} - -export const useHelpContext = () => useContext(HelpContext); diff --git a/src/components/help/HelpMessageHandler.tsx b/src/components/help/HelpMessageHandler.tsx deleted file mode 100644 index a72481ce..00000000 --- a/src/components/help/HelpMessageHandler.tsx +++ /dev/null @@ -1,45 +0,0 @@ -import { CallForHelpResultMessageEvent, GetPendingCallsForHelpMessageComposer, IssueCloseNotificationMessageEvent } from '@nitrots/nitro-renderer'; -import { FC } from 'react'; -import { CallForHelpResult, GetCloseReasonKey, LocalizeText, NotificationAlertType, SendMessageComposer } from '../../api'; -import { useMessageEvent, useNotification } from '../../hooks'; - -export const HelpMessageHandler: FC<{}> = props => -{ - const { simpleAlert = null } = useNotification(); - - useMessageEvent(CallForHelpResultMessageEvent, event => - { - const parser = event.getParser(); - - let message = parser.messageText; - - switch(parser.resultType) - { - case CallForHelpResult.TOO_MANY_PENDING_CALLS_CODE: - SendMessageComposer(new GetPendingCallsForHelpMessageComposer()); - simpleAlert(LocalizeText('help.cfh.error.pending'), NotificationAlertType.MODERATION, null, null, LocalizeText('help.cfh.error.title')); - break; - case CallForHelpResult.HAS_ABUSIVE_CALL_CODE: - simpleAlert(LocalizeText('help.cfh.error.abusive'), NotificationAlertType.MODERATION, null, null, LocalizeText('help.cfh.error.title')); - break; - default: - if(message.trim().length === 0) - { - message = LocalizeText('help.cfh.sent.text'); - } - - simpleAlert(message, NotificationAlertType.MODERATION, null, null, LocalizeText('help.cfh.sent.title')); - } - }); - - useMessageEvent(IssueCloseNotificationMessageEvent, event => - { - const parser = event.getParser(); - - const message = parser.messageText.length === 0 ? LocalizeText('help.cfh.closed.' + GetCloseReasonKey(parser.closeReason)) : parser.messageText; - - simpleAlert(message, NotificationAlertType.MODERATION, null, null, LocalizeText('mod.alert.title')); - }); - - return null; -} diff --git a/src/components/help/HelpView.tsx b/src/components/help/HelpView.tsx index 128f50cc..8d1e42ff 100644 --- a/src/components/help/HelpView.tsx +++ b/src/components/help/HelpView.tsx @@ -1,14 +1,12 @@ import { ILinkEventTracker } from '@nitrots/nitro-renderer'; -import { FC, useCallback, useEffect, useState } from 'react'; -import { AddEventLinkTracker, IHelpReportState, LocalizeText, RemoveLinkEventTracker } from '../../api'; +import { FC, useEffect, useState } from 'react'; +import { AddEventLinkTracker, LocalizeText, RemoveLinkEventTracker, ReportState } from '../../api'; import { Base, Column, Grid, NitroCardContentView, NitroCardHeaderView, NitroCardView } from '../../common'; -import { HelpReportUserEvent } from '../../events'; -import { useUiEvent } from '../../hooks'; -import { HelpContextProvider } from './HelpContext'; -import { HelpMessageHandler } from './HelpMessageHandler'; +import { useHelp } from '../../hooks'; import { DescribeReportView } from './views/DescribeReportView'; import { HelpIndexView } from './views/HelpIndexView'; import { NameChangeView } from './views/name-change/NameChangeView'; +import { ReportSummaryView } from './views/ReportSummaryView'; import { SanctionSatusView } from './views/SanctionStatusView'; import { SelectReportedChatsView } from './views/SelectReportedChatsView'; import { SelectReportedUserView } from './views/SelectReportedUserView'; @@ -17,113 +15,103 @@ import { SelectTopicView } from './views/SelectTopicView'; export const HelpView: FC<{}> = props => { const [ isVisible, setIsVisible ] = useState(false); - const [ helpReportState, setHelpReportState ] = useState({ - reportedUserId: -1, - reportedChats: [], - cfhCategory: -1, - cfhTopic: -1, - roomId: -1, - message: '', - currentStep: 0 - }); + const { activeReport = null, setActiveReport = null, report = null } = useHelp(); - const linkReceived = useCallback((url: string) => + const close = () => { - const parts = url.split('/'); - - if(parts.length < 2) return; - - switch(parts[1]) - { - case 'show': - setIsVisible(true); - return; - case 'hide': - setIsVisible(false); - return; - case 'toggle': - setIsVisible(prevValue => !prevValue); - return; - } - }, []); - - const onHelpReportUserEvent = useCallback((event: HelpReportUserEvent) => - { - setHelpReportState({ - reportedUserId: event.reportedUserId, - reportedChats: [], - cfhCategory: -1, - cfhTopic: -1, - roomId: -1, - message: '', - currentStep: 2 - }); - - setIsVisible(true); - }, []); - - useUiEvent(HelpReportUserEvent.REPORT_USER, onHelpReportUserEvent); + setActiveReport(null); + setIsVisible(false); + } useEffect(() => { const linkTracker: ILinkEventTracker = { - linkReceived, + linkReceived: (url: string) => + { + const parts = url.split('/'); + + if(parts.length < 2) return; + + switch(parts[1]) + { + case 'show': + setIsVisible(true); + return; + case 'hide': + setIsVisible(false); + return; + case 'toggle': + setIsVisible(prevValue => !prevValue); + return; + case 'tour': + // todo: launch tour + return; + case 'report': + if((parts.length >= 5) && (parts[2] === 'room')) + { + const roomId = parseInt(parts[3]); + const unknown = unescape(parts.splice(4).join('/')); + //this.reportRoom(roomId, unknown, ""); + } + return; + } + }, eventUrlPrefix: 'help/' }; AddEventLinkTracker(linkTracker); return () => RemoveLinkEventTracker(linkTracker); - }, [ linkReceived ]); + }, []); useEffect(() => { - if(!isVisible) return; + if(!activeReport) return; - setHelpReportState({ - reportedUserId: -1, - reportedChats: [], - cfhCategory: -1, - cfhTopic: -1, - roomId: -1, - message: '', - currentStep: 0 - }); - }, [ isVisible ]); + setIsVisible(true); + }, [ activeReport ]); - const CurrentStepView = useCallback(() => + if(!isVisible && !activeReport) return null; + + const CurrentStepView = () => { - switch(helpReportState.currentStep) + if(activeReport) { - case 0: return - case 1: return - case 2: return - case 3: return - case 4: return + switch(activeReport.currentStep) + { + case ReportState.SELECT_USER: + return ; + case ReportState.SELECT_CHATS: + return ; + case ReportState.SELECT_TOPICS: + return ; + case ReportState.INPUT_REPORT_MESSAGE: + return ; + case ReportState.REPORT_SUMMARY: + return ; + } } - return null; - }, [ helpReportState.currentStep ]); + return ; + } return ( - - - { isVisible && - - setIsVisible(false) } /> - - - - - - - - - - - } + <> + + + + + + + + + + + + + - + ); } diff --git a/src/components/help/views/DescribeReportView.tsx b/src/components/help/views/DescribeReportView.tsx index 420c2019..5f231d3a 100644 --- a/src/components/help/views/DescribeReportView.tsx +++ b/src/components/help/views/DescribeReportView.tsx @@ -1,31 +1,31 @@ -import { CallForHelpMessageComposer } from '@nitrots/nitro-renderer'; import { FC, useState } from 'react'; -import { CreateLinkEvent, LocalizeText, SendMessageComposer } from '../../../api'; -import { Button, Column, Text } from '../../../common'; -import { useHelpContext } from '../HelpContext'; +import { LocalizeText, ReportState, ReportType } from '../../../api'; +import { Button, Column, Flex, Text } from '../../../common'; +import { useHelp } from '../../../hooks'; export const DescribeReportView: FC<{}> = props => { const [ message, setMessage ] = useState(''); - const { helpReportState = null, setHelpReportState = null } = useHelpContext(); - const { reportedChats, cfhTopic, reportedUserId } = helpReportState; + const { activeReport = null, setActiveReport = null } = useHelp(); - const submitReport = () => + const submitMessage = () => { if(message.length < 15) return; - const roomId = reportedChats[0].roomId; - const chats: (string | number )[] = []; - - reportedChats.forEach(entry => + setActiveReport(prevValue => { - chats.push(entry.entityId); - chats.push(entry.message); + const currentStep = ReportState.REPORT_SUMMARY; + + return { ...prevValue, message, currentStep }; }); + } - SendMessageComposer(new CallForHelpMessageComposer(message, cfhTopic, reportedUserId, roomId, chats)); - - CreateLinkEvent('help/hide'); + const back = () => + { + setActiveReport(prevValue => + { + return { ...prevValue, currentStep: (prevValue.currentStep - 1) }; + }); } return ( @@ -35,9 +35,14 @@ export const DescribeReportView: FC<{}> = props => { LocalizeText('help.cfh.input.text') }