From 823ec8c6501005ea129a630deb1119796cf70543 Mon Sep 17 00:00:00 2001 From: Bill Date: Thu, 30 Sep 2021 00:38:02 -0400 Subject: [PATCH] Add chat style selector --- .../widgets/chat-input/ChatInputView.scss | 48 +++++++++---- .../room/widgets/chat-input/ChatInputView.tsx | 65 +++++++++++++++-- .../ChatInputStyleSelectorView.scss | 61 ---------------- .../ChatInputStyleSelectorView.tsx | 69 ++++++++++++++++--- .../ChatInputStyleSelectorView.types.ts | 4 +- .../room/widgets/chat/ChatWidgetView.scss | 4 +- 6 files changed, 158 insertions(+), 93 deletions(-) delete mode 100644 src/views/room/widgets/chat-input/style-selector/ChatInputStyleSelectorView.scss diff --git a/src/views/room/widgets/chat-input/ChatInputView.scss b/src/views/room/widgets/chat-input/ChatInputView.scss index 60995c42..d112dc2f 100644 --- a/src/views/room/widgets/chat-input/ChatInputView.scss +++ b/src/views/room/widgets/chat-input/ChatInputView.scss @@ -1,13 +1,3 @@ -@media only screen and (max-width: 600px) { - .nitro-chat-input { - position: fixed; - left: 50%; - transform: translateX(-50%); - bottom: 65px !important; - z-index: $chatinput-zindex; - } -} - .nitro-chat-input-container { display: flex; justify-content: center; @@ -17,7 +7,7 @@ border-radius: 8px; border: 2px solid rgb(0, 0, 0); background: #EDEDED; - padding-right: 30px; + padding-right: 10px; width: 100%; &:before { @@ -60,6 +50,40 @@ white-space: pre-wrap; } } + + .bubble-container { + visibility: visible; + width: 75%; + } } -@import './style-selector/ChatInputStyleSelectorView'; +.nitro-chat-style-selector-button { + position: absolute; + display: flex; + justify-content: center; + align-items: center; + height: 100%; + right: 7px; +} + +.nitro-chat-style-selector-container { + width: $chat-input-style-selector-widget-width; + height: $chat-input-style-selector-widget-height; + + .grid-item { + font-size: $font-size-sm; + height: 30px !important; + border-color: unset !important; + border: 0 !important; + padding: 1px 3px; + + &:not(.active) { + background-color: unset !important; + } + + .bubble-container { + visibility: visible; + width: 75%; + } + } +} diff --git a/src/views/room/widgets/chat-input/ChatInputView.tsx b/src/views/room/widgets/chat-input/ChatInputView.tsx index 534dd93c..4ad7f3ba 100644 --- a/src/views/room/widgets/chat-input/ChatInputView.tsx +++ b/src/views/room/widgets/chat-input/ChatInputView.tsx @@ -1,3 +1,4 @@ +import { HabboClubLevelEnum, RoomControllerLevel } from '@nitrots/nitro-renderer'; import { FC, useCallback, useEffect, useMemo, useRef, useState } from 'react'; import { createPortal } from 'react-dom'; import { GetConfiguration, GetSessionDataManager, LocalizeText, RoomWidgetChatMessage, RoomWidgetChatTypingMessage, RoomWidgetRoomObjectUpdateEvent, RoomWidgetUpdateChatInputContentEvent, RoomWidgetUpdateInfostandUserEvent } from '../../../../api'; @@ -117,6 +118,7 @@ export const ChatInputView: FC<{}> = props => { if(needsChatStyleUpdate) { + console.log('send') GetSessionDataManager().sendChatStyleUpdate(chatStyleId); setNeedsChatStyleUpdate(false); @@ -175,12 +177,6 @@ export const ChatInputView: FC<{}> = props => }, [ inputRef, chatModeIdWhisper, anotherInputHasFocus, setInputFocus, checkSpecialKeywordForInput, sendChatValue ]); - const onStyleSelected = useCallback((styleId: number) => - { - setChatStyleId(styleId); - setNeedsChatStyleUpdate(true); - }, []); - const onRoomWidgetRoomObjectUpdateEvent = useCallback((event: RoomWidgetRoomObjectUpdateEvent) => { setSelectedUsername(''); @@ -210,6 +206,61 @@ export const ChatInputView: FC<{}> = props => CreateEventDispatcherHook(RoomWidgetUpdateChatInputContentEvent.CHAT_INPUT_CONTENT, eventDispatcher, onRoomWidgetChatInputContentUpdateEvent); + const selectChatStyleId = useCallback((styleId: number) => + { + setChatStyleId(styleId); + setNeedsChatStyleUpdate(true); + }, []); + + const chatStyleIds = useMemo(() => + { + let styleIds: number[] = []; + + const styles = GetConfiguration<{ styleId: number, minRank: number, isSystemStyle: boolean, isHcOnly: boolean, isAmbassadorOnly: boolean }[]>('chat.styles'); + + for(const style of styles) + { + if(!style) continue; + + if(style.minRank > 0) + { + if(GetSessionDataManager().hasSecurity(style.minRank)) styleIds.push(style.styleId); + + continue; + } + + if(style.isSystemStyle) + { + if(GetSessionDataManager().hasSecurity(RoomControllerLevel.MODERATOR)) + { + styleIds.push(style.styleId); + + continue; + } + } + + if(GetConfiguration('chat.styles.disabled').indexOf(style.styleId) >= 0) continue; + + if(style.isHcOnly && (GetSessionDataManager().clubLevel >= HabboClubLevelEnum.CLUB)) + { + styleIds.push(style.styleId); + + continue; + } + + if(style.isAmbassadorOnly && GetSessionDataManager().isAmbassador) + { + styleIds.push(style.styleId); + + continue; + } + + if(!style.isHcOnly && !style.isAmbassadorOnly) styleIds.push(style.styleId); + } + + return styleIds; + }, []); + useEffect(() => { if(isTyping) @@ -273,7 +324,7 @@ export const ChatInputView: FC<{}> = props =>
updateChatInput(event.target.value) } onMouseDown={ event => setInputFocus() } />
- + , document.getElementById('toolbar-chat-input-container')) ); } diff --git a/src/views/room/widgets/chat-input/style-selector/ChatInputStyleSelectorView.scss b/src/views/room/widgets/chat-input/style-selector/ChatInputStyleSelectorView.scss deleted file mode 100644 index 5be93b7c..00000000 --- a/src/views/room/widgets/chat-input/style-selector/ChatInputStyleSelectorView.scss +++ /dev/null @@ -1,61 +0,0 @@ -.nitro-chat-style-selector-button { - position: absolute; - display: flex; - justify-content: center; - align-items: center; - height: 100%; - right: 7px; -} - -.nitro-chat-style-selector-test { - display: flex; - position: relative; - right: 30px; - pointer-events: all; - height: 100%; - - i.icon { - cursor: pointer; - align-self: center; - } - - .nitro-chatstyle-selector { - position: absolute; - width: 250px; - top: -4px; - transition: transform 0.22s ease-in-out; - transform: translate(-81px, -50%) scale(0); - - &.active { - visibility: visible; - transform: translate(-160px, -100%) scale(1); - } - - .grid-container { - - .grid-items { - margin-top: -7px; - - .item-detail { - height: 30px; - max-height: 30px; - width: calc(1 / 3 * 100% - (1 - 1 / 3) * 7px); - margin: 7px 7px 0 0; - overflow: visible; - - &:hover { - cursor: pointer; - } - - .detail-info { - - .bubble-container { - visibility: visible; - width: 75%; - } - } - } - } - } - } -} diff --git a/src/views/room/widgets/chat-input/style-selector/ChatInputStyleSelectorView.tsx b/src/views/room/widgets/chat-input/style-selector/ChatInputStyleSelectorView.tsx index 52d1d43f..e2be6302 100644 --- a/src/views/room/widgets/chat-input/style-selector/ChatInputStyleSelectorView.tsx +++ b/src/views/room/widgets/chat-input/style-selector/ChatInputStyleSelectorView.tsx @@ -1,20 +1,69 @@ -import { FC, useState } from 'react'; +import { FC, MouseEvent, useCallback, useEffect, useState } from 'react'; +import { Overlay, Popover } from 'react-bootstrap'; +import { BatchUpdates } from '../../../../../hooks'; +import { NitroCardContentView, NitroCardGridItemView, NitroCardGridView } from '../../../../../layout'; import { ChatInputStyleSelectorViewProps } from './ChatInputStyleSelectorView.types'; export const ChatInputStyleSelectorView: FC = props => { - const { onStyleSelected = null } = props; + const { chatStyleId = 0, chatStyleIds = null, selectChatStyleId = null } = props; + const [ target, setTarget ] = useState<(EventTarget & HTMLElement)>(null); const [ selectorVisible, setSelectorVisible ] = useState(false); + useEffect(() => + { + if(selectorVisible) return; + + setTarget(null); + }, [ selectorVisible ]); + + const selectStyle = (styleId: number) => + { + BatchUpdates(() => + { + selectChatStyleId(styleId); + setSelectorVisible(false); + }); + } + + const toggleSelector = useCallback((event: MouseEvent) => + { + BatchUpdates(() => + { + let visible = false; + + setSelectorVisible(prevValue => + { + visible = !prevValue; + + return visible; + }); + + if(visible) setTarget((event.target as (EventTarget & HTMLElement))); + }) + }, []); + return ( <> -
- -
- { selectorVisible && -
- -
} + + + + + + { chatStyleIds && (chatStyleIds.length > 0) && chatStyleIds.map((styleId) => + { + return ( + selectStyle(styleId) }> +
+
 
+
+
+ ); + }) } +
+
+
+
- ) + ); } diff --git a/src/views/room/widgets/chat-input/style-selector/ChatInputStyleSelectorView.types.ts b/src/views/room/widgets/chat-input/style-selector/ChatInputStyleSelectorView.types.ts index bd159ffe..9df829be 100644 --- a/src/views/room/widgets/chat-input/style-selector/ChatInputStyleSelectorView.types.ts +++ b/src/views/room/widgets/chat-input/style-selector/ChatInputStyleSelectorView.types.ts @@ -1,4 +1,6 @@ export interface ChatInputStyleSelectorViewProps { - onStyleSelected: (styleId: number) => void; + chatStyleId: number; + chatStyleIds: number[]; + selectChatStyleId: (styleId: number) => void; } diff --git a/src/views/room/widgets/chat/ChatWidgetView.scss b/src/views/room/widgets/chat/ChatWidgetView.scss index 67bb611f..53904e1d 100644 --- a/src/views/room/widgets/chat/ChatWidgetView.scss +++ b/src/views/room/widgets/chat/ChatWidgetView.scss @@ -11,6 +11,6 @@ border-radius: 0; box-shadow: none; pointer-events: none; - - @import './message/ChatWidgetMessageView'; } + +@import './message/ChatWidgetMessageView';