From 06bc3f238e324de6a1e6732ca55327fcc578d902 Mon Sep 17 00:00:00 2001 From: Bill Date: Sat, 26 Feb 2022 00:23:11 -0500 Subject: [PATCH] More widget updates --- src/views/room/widgets/RoomWidgets.scss | 99 +++++++++++++- .../avatar-info/AvatarInfoWidgetView.scss | 10 -- .../widgets/furniture/FurnitureWidgets.scss | 14 +- .../FurnitureMannequinPreviewView.tsx | 23 ++++ .../mannequin/FurnitureMannequinView.scss | 9 -- .../mannequin/FurnitureMannequinView.tsx | 62 +++++---- .../preview/FurnitureMannequinPreviewView.tsx | 17 --- .../FurnitureMannequinPreviewView.types.ts | 5 - .../object-location/ObjectLocationView.scss | 2 - .../object-location/ObjectLocationView.tsx | 18 +-- .../ObjectLocationView.types.ts | 8 -- .../room-tools/RoomToolsWidgetView.scss | 55 -------- .../room-tools/RoomToolsWidgetView.tsx | 45 ++++--- .../user-location/UserLocationView.tsx | 7 +- .../user-location/UserLocationView.types.ts | 6 - .../word-quiz/WordQuizQuestionView.tsx | 44 ++++++ .../widgets/word-quiz/WordQuizVoteView.tsx | 24 ++++ .../widgets/word-quiz/WordQuizWidgetView.scss | 39 ------ .../widgets/word-quiz/WordQuizWidgetView.tsx | 126 +++++++++--------- .../word-quiz/views/question/QuestionView.tsx | 24 ---- .../views/question/QuestionView.types.ts | 9 -- .../widgets/word-quiz/views/vote/VoteView.tsx | 16 --- .../word-quiz/views/vote/VoteView.types.ts | 5 - 23 files changed, 346 insertions(+), 321 deletions(-) create mode 100644 src/views/room/widgets/furniture/mannequin/FurnitureMannequinPreviewView.tsx delete mode 100644 src/views/room/widgets/furniture/mannequin/FurnitureMannequinView.scss delete mode 100644 src/views/room/widgets/furniture/mannequin/views/preview/FurnitureMannequinPreviewView.tsx delete mode 100644 src/views/room/widgets/furniture/mannequin/views/preview/FurnitureMannequinPreviewView.types.ts delete mode 100644 src/views/room/widgets/object-location/ObjectLocationView.scss delete mode 100644 src/views/room/widgets/object-location/ObjectLocationView.types.ts delete mode 100644 src/views/room/widgets/room-tools/RoomToolsWidgetView.scss delete mode 100644 src/views/room/widgets/user-location/UserLocationView.types.ts create mode 100644 src/views/room/widgets/word-quiz/WordQuizQuestionView.tsx create mode 100644 src/views/room/widgets/word-quiz/WordQuizVoteView.tsx delete mode 100644 src/views/room/widgets/word-quiz/WordQuizWidgetView.scss delete mode 100644 src/views/room/widgets/word-quiz/views/question/QuestionView.tsx delete mode 100644 src/views/room/widgets/word-quiz/views/question/QuestionView.types.ts delete mode 100644 src/views/room/widgets/word-quiz/views/vote/VoteView.tsx delete mode 100644 src/views/room/widgets/word-quiz/views/vote/VoteView.types.ts diff --git a/src/views/room/widgets/RoomWidgets.scss b/src/views/room/widgets/RoomWidgets.scss index a2f114d6..03b34a57 100644 --- a/src/views/room/widgets/RoomWidgets.scss +++ b/src/views/room/widgets/RoomWidgets.scss @@ -1,3 +1,99 @@ +.nitro-room-tools-container { + position: absolute; + bottom: $toolbar-height + 65px; + left: 0; + + .nitro-room-tools { + background: rgba($dark,.95); + box-shadow: inset 0px 5px lighten(rgba($dark,.6),2.5), inset 0 -4px darken(rgba($dark,.6),4); + border-top-right-radius: $border-radius; + border-bottom-right-radius: $border-radius; + transition: all .2s ease; + z-index: 2; + + .list-group-item { + background: transparent; + padding: 3px 0px; + color: $white; + border-color: rgba($black, 0.3); + cursor: pointer; + + &:hover { + text-decoration: underline; + } + + &:first-child { + padding-top: 8px; + } + + &:last-child { + border-bottom: none; + padding-bottom: 8px; + } + + .tools-item { + .icon { + width: 22px; + background-repeat: no-repeat; + background-position: center; + } + + &:hover { + text-decoration: underline; + } + } + } + } + + .nitro-room-tools-info { + background: rgba($dark,.95); + box-shadow: inset 0px 5px lighten(rgba($dark,.6),2.5), inset 0 -4px darken(rgba($dark,.6),4); + transition: all .2s ease; + pointer-events: none; + max-width: 250px; + } +} + +.wordquiz-question { + position: absolute; + top: 10px; + left: 50%; + transform: translateX(-50%); + font-size: large; + background: rgba($dark, 0.95); + box-shadow: inset 0px 5px lighten(rgba($dark,.6),2.5), inset 0 -4px darken(rgba($dark,.6),4); + border-radius: $border-radius; + transition: all 0.2s ease; + + .question { + max-width: 300px; + } +} + +.word-quiz-dislike { + background: url("../../../assets/images/room-widgets/wordquiz-widget/thumbs-down.png"); + width: 31px; + height: 34px; +} + +.word-quiz-like { + background: url("../../../assets/images/room-widgets/wordquiz-widget/thumbs-up.png"); + width: 31px; + height: 34px; +} + +.word-quiz-dislike-sm { + background: url("../../../assets/images/room-widgets/wordquiz-widget/thumbs-down-small.png"); + width: 22px; + height: 22px; +} + +.word-quiz-like-sm { + background: url("../../../assets/images/room-widgets/wordquiz-widget/thumbs-up-small.png"); + height: 22px; + width: 22px; +} + @import './avatar-info/AvatarInfoWidgetView'; @import './chat/ChatWidgetView'; @import './chat-input/ChatInputView'; @@ -6,6 +102,3 @@ @import './friend-request/FriendRequestDialogView'; @import './furniture/FurnitureWidgets'; @import './infostand/InfoStandWidgetView'; -@import './object-location/ObjectLocationView'; -@import './room-tools/RoomToolsWidgetView'; -@import './word-quiz/WordQuizWidgetView'; diff --git a/src/views/room/widgets/avatar-info/AvatarInfoWidgetView.scss b/src/views/room/widgets/avatar-info/AvatarInfoWidgetView.scss index df009b29..737bf54c 100644 --- a/src/views/room/widgets/avatar-info/AvatarInfoWidgetView.scss +++ b/src/views/room/widgets/avatar-info/AvatarInfoWidgetView.scss @@ -20,14 +20,4 @@ background: url('../../../../assets/images/room-widgets/furni-context-menu/monsterplant-preview.png') no-repeat center; } } - - .mannequin-preview { - display: flex; - justify-content: center; - align-items: center; - width: 83px; - height: 130px; - background-image: url('../../../../assets/images/room-widgets/mannequin-widget/mannequin-spritesheet.png'); - overflow: hidden; - } } diff --git a/src/views/room/widgets/furniture/FurnitureWidgets.scss b/src/views/room/widgets/furniture/FurnitureWidgets.scss index 390c4e14..425d02fa 100644 --- a/src/views/room/widgets/furniture/FurnitureWidgets.scss +++ b/src/views/room/widgets/furniture/FurnitureWidgets.scss @@ -50,9 +50,21 @@ } +.nitro-mannequin { +} + +.mannequin-preview { + display: flex; + justify-content: center; + align-items: center; + width: 83px; + height: 130px; + background-image: url('../../../../assets/images/room-widgets/mannequin-widget/mannequin-spritesheet.png'); + overflow: hidden; +} + @import './friend-furni/FurnitureFriendFurniView'; @import './manipulation-menu/FurnitureManipulationMenuView'; -@import './mannequin/FurnitureMannequinView'; @import './stickie/FurnitureStickieView'; @import './high-score/FurnitureHighScoreView'; @import './youtube-tv/FurnitureYoutubeDisplayView'; diff --git a/src/views/room/widgets/furniture/mannequin/FurnitureMannequinPreviewView.tsx b/src/views/room/widgets/furniture/mannequin/FurnitureMannequinPreviewView.tsx new file mode 100644 index 00000000..a0f6dba2 --- /dev/null +++ b/src/views/room/widgets/furniture/mannequin/FurnitureMannequinPreviewView.tsx @@ -0,0 +1,23 @@ +import { FC } from 'react'; +import { Base } from '../../../../../common'; +import { AvatarImageView } from '../../../../shared/avatar-image/AvatarImageView'; +import { CurrencyIcon } from '../../../../shared/currency-icon/CurrencyIcon'; + +interface FurnitureMannequinPreviewViewProps +{ + figure: string; + clubLevel: number; +} + +export const FurnitureMannequinPreviewView: FC = props => +{ + const { figure = null, clubLevel = 0 } = props; + + return ( + + + { (clubLevel > 0) && + } + + ); +} diff --git a/src/views/room/widgets/furniture/mannequin/FurnitureMannequinView.scss b/src/views/room/widgets/furniture/mannequin/FurnitureMannequinView.scss deleted file mode 100644 index cc16ce4c..00000000 --- a/src/views/room/widgets/furniture/mannequin/FurnitureMannequinView.scss +++ /dev/null @@ -1,9 +0,0 @@ -.nitro-mannequin { - width: 350px; - - .mannequin-preview { - width: 83px; - height: 130px; - background-image: url('../../../../../assets/images/room-widgets/mannequin-widget/mannequin-spritesheet.png'); - } -} diff --git a/src/views/room/widgets/furniture/mannequin/FurnitureMannequinView.tsx b/src/views/room/widgets/furniture/mannequin/FurnitureMannequinView.tsx index da7848c2..c7591e33 100644 --- a/src/views/room/widgets/furniture/mannequin/FurnitureMannequinView.tsx +++ b/src/views/room/widgets/furniture/mannequin/FurnitureMannequinView.tsx @@ -1,16 +1,17 @@ import { AvatarFigurePartType, FurnitureMannequinSaveLookComposer, FurnitureMannequinSaveNameComposer, FurnitureMultiStateComposer, HabboClubLevelEnum, IAvatarFigureContainer, RoomControllerLevel } from '@nitrots/nitro-renderer'; import { FC, KeyboardEvent, useCallback, useEffect, useState } from 'react'; import { GetAvatarRenderManager, GetSessionDataManager, LocalizeText, RoomWidgetUpdateMannequinEvent } from '../../../../../api'; +import { Base } from '../../../../../common'; import { Button } from '../../../../../common/Button'; import { Column } from '../../../../../common/Column'; import { Flex } from '../../../../../common/Flex'; -import { Grid } from '../../../../../common/Grid'; import { Text } from '../../../../../common/Text'; import { BatchUpdates, SendMessageHook } from '../../../../../hooks'; import { CreateEventDispatcherHook } from '../../../../../hooks/events/event-dispatcher.base'; import { NitroCardContentView, NitroCardHeaderView, NitroCardView } from '../../../../../layout'; +import { AvatarImageView } from '../../../../shared/avatar-image/AvatarImageView'; +import { CurrencyIcon } from '../../../../shared/currency-icon/CurrencyIcon'; import { useRoomContext } from '../../../context/RoomContext'; -import { FurnitureMannequinPreviewView } from './views/preview/FurnitureMannequinPreviewView'; const MODE_NONE: number = -1; const MODE_CONTROLLER: number = 0; @@ -143,8 +144,11 @@ export const FurnitureMannequinView: FC<{}> = props => transformAsMannequinFigure(figureContainer); - setRenderedFigure(figureContainer.getFigureString()); - setRenderedClubLevel(clubLevel); + BatchUpdates(() => + { + setRenderedFigure(figureContainer.getFigureString()); + setRenderedClubLevel(clubLevel); + }); break; } case MODE_UPDATE: { @@ -152,16 +156,22 @@ export const FurnitureMannequinView: FC<{}> = props => transformAsMannequinFigure(figureContainer); - setRenderedFigure(figureContainer.getFigureString()); - setRenderedClubLevel(GetAvatarRenderManager().getFigureClubLevel(figureContainer, GetSessionDataManager().gender, MANNEQUIN_CLOTHING_PART_TYPES)); + BatchUpdates(() => + { + setRenderedFigure(figureContainer.getFigureString()); + setRenderedClubLevel(GetAvatarRenderManager().getFigureClubLevel(figureContainer, GetSessionDataManager().gender, MANNEQUIN_CLOTHING_PART_TYPES)); + }); break; } case MODE_PEER: case MODE_NO_CLUB: { const figureContainer = getMergedFigureContainer(GetSessionDataManager().figure, figure); - setRenderedFigure(figureContainer.getFigureString()); - setRenderedClubLevel(clubLevel); + BatchUpdates(() => + { + setRenderedFigure(figureContainer.getFigureString()); + setRenderedClubLevel(clubLevel); + }); break; } } @@ -170,18 +180,22 @@ export const FurnitureMannequinView: FC<{}> = props => if(mode === MODE_NONE) return null; return ( - + setMode(MODE_NONE) } /> - - - - + + + + + + { (clubLevel > 0) && + } + - + { (mode === MODE_CONTROLLER) && <> setName(event.target.value) } onKeyDown={ event => handleKeyDown(event) } /> - + @@ -192,9 +206,9 @@ export const FurnitureMannequinView: FC<{}> = props => } { (mode === MODE_UPDATE) && <> - - { name } - { LocalizeText('mannequin.widget.savetext') } + + { name } + { LocalizeText('mannequin.widget.savetext') } setMode(MODE_CONTROLLER) }> @@ -207,18 +221,20 @@ export const FurnitureMannequinView: FC<{}> = props => } { (mode === MODE_PEER) && <> - - { name } + + { name } { LocalizeText('mannequin.widget.weartext') } } - { (mode === MODE_NO_CLUB) && { LocalizeText('mannequin.widget.clubnotification') } } - { (mode === MODE_WRONG_GENDER) && { LocalizeText('mannequin.widget.wronggender') } } + { (mode === MODE_NO_CLUB) && + { LocalizeText('mannequin.widget.clubnotification') } } + { (mode === MODE_WRONG_GENDER) && + { LocalizeText('mannequin.widget.wronggender') } } - + ); diff --git a/src/views/room/widgets/furniture/mannequin/views/preview/FurnitureMannequinPreviewView.tsx b/src/views/room/widgets/furniture/mannequin/views/preview/FurnitureMannequinPreviewView.tsx deleted file mode 100644 index 194700df..00000000 --- a/src/views/room/widgets/furniture/mannequin/views/preview/FurnitureMannequinPreviewView.tsx +++ /dev/null @@ -1,17 +0,0 @@ -import { FC } from 'react'; -import { NitroLayoutBase } from '../../../../../../../layout/base'; -import { AvatarImageView } from '../../../../../../shared/avatar-image/AvatarImageView'; -import { CurrencyIcon } from '../../../../../../shared/currency-icon/CurrencyIcon'; -import { FurnitureMannequinPreviewViewProps } from './FurnitureMannequinPreviewView.types'; - -export const FurnitureMannequinPreviewView: FC = props => -{ - const { figure = null, clubLevel = 0 } = props; - - return ( - - - { (clubLevel > 0) && } - - ); -} diff --git a/src/views/room/widgets/furniture/mannequin/views/preview/FurnitureMannequinPreviewView.types.ts b/src/views/room/widgets/furniture/mannequin/views/preview/FurnitureMannequinPreviewView.types.ts deleted file mode 100644 index 1a5ee3fe..00000000 --- a/src/views/room/widgets/furniture/mannequin/views/preview/FurnitureMannequinPreviewView.types.ts +++ /dev/null @@ -1,5 +0,0 @@ -export interface FurnitureMannequinPreviewViewProps -{ - figure: string; - clubLevel: number; -} diff --git a/src/views/room/widgets/object-location/ObjectLocationView.scss b/src/views/room/widgets/object-location/ObjectLocationView.scss deleted file mode 100644 index ab82f870..00000000 --- a/src/views/room/widgets/object-location/ObjectLocationView.scss +++ /dev/null @@ -1,2 +0,0 @@ -.object-location { -} diff --git a/src/views/room/widgets/object-location/ObjectLocationView.tsx b/src/views/room/widgets/object-location/ObjectLocationView.tsx index c7df0d2a..d28d2a4e 100644 --- a/src/views/room/widgets/object-location/ObjectLocationView.tsx +++ b/src/views/room/widgets/object-location/ObjectLocationView.tsx @@ -1,11 +1,17 @@ import { FC, useCallback, useEffect, useRef, useState } from 'react'; import { GetNitroInstance, GetRoomEngine, GetRoomSession } from '../../../../api'; -import { NitroLayoutBase } from '../../../../layout/base'; -import { ObjectLocationViewProps } from './ObjectLocationView.types'; +import { Base, BaseProps } from '../../../../common'; + +interface ObjectLocationViewProps extends BaseProps +{ + objectId: number; + category: number; + noFollow?: boolean; +} export const ObjectLocationView: FC = props => { - const { objectId = -1, category = -1, noFollow = false, children = null, ...rest } = props; + const { objectId = -1, category = -1, noFollow = false, position = 'absolute', ...rest } = props; const [ pos, setPos ] = useState<{ x: number, y: number }>({ x: -1, y: -1 }); const elementRef = useRef(); @@ -50,9 +56,5 @@ export const ObjectLocationView: FC = props => } }, [ updatePosition, noFollow ]); - return ( - -1 ? 'visible' : 'invisible') } style={ { left: pos.x, top: pos.y } } { ...rest }> - { children } - - ); + return -1 } className="object-location" style={ { left: pos.x, top: pos.y } } { ...rest } />; } diff --git a/src/views/room/widgets/object-location/ObjectLocationView.types.ts b/src/views/room/widgets/object-location/ObjectLocationView.types.ts deleted file mode 100644 index 0da23b4b..00000000 --- a/src/views/room/widgets/object-location/ObjectLocationView.types.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { NitroLayoutBaseProps } from '../../../../layout/base'; - -export interface ObjectLocationViewProps extends NitroLayoutBaseProps -{ - objectId: number; - category: number; - noFollow?: boolean; -} diff --git a/src/views/room/widgets/room-tools/RoomToolsWidgetView.scss b/src/views/room/widgets/room-tools/RoomToolsWidgetView.scss deleted file mode 100644 index fe081425..00000000 --- a/src/views/room/widgets/room-tools/RoomToolsWidgetView.scss +++ /dev/null @@ -1,55 +0,0 @@ -.nitro-room-tools-container { - position: absolute; - bottom: $toolbar-height + 65px; - left: 0; - - .nitro-room-tools { - background: rgba($dark,.95); - box-shadow: inset 0px 5px lighten(rgba($dark,.6),2.5), inset 0 -4px darken(rgba($dark,.6),4); - border-top-right-radius: $border-radius; - border-bottom-right-radius: $border-radius; - transition: all .2s ease; - - .list-group-item { - background: transparent; - padding: 3px 0px; - color: $white; - border-color: rgba($black, 0.3); - cursor: pointer; - - &:hover { - text-decoration: underline; - } - - &:first-child { - padding-top: 8px; - } - - &:last-child { - border-bottom: none; - padding-bottom: 8px; - } - - .tools-item { - .icon { - width: 22px; - background-repeat: no-repeat; - background-position: center; - } - - &:hover { - text-decoration: underline; - } - } - } - } - - .nitro-room-tools-info { - margin-left: 10px; - background: rgba($dark,.95); - box-shadow: inset 0px 5px lighten(rgba($dark,.6),2.5), inset 0 -4px darken(rgba($dark,.6),4); - transition: all .2s ease; - pointer-events: none; - max-width: 250px; - } -} diff --git a/src/views/room/widgets/room-tools/RoomToolsWidgetView.tsx b/src/views/room/widgets/room-tools/RoomToolsWidgetView.tsx index 6bf17ef8..19ca05c0 100644 --- a/src/views/room/widgets/room-tools/RoomToolsWidgetView.tsx +++ b/src/views/room/widgets/room-tools/RoomToolsWidgetView.tsx @@ -4,8 +4,10 @@ import { FC, useCallback, useEffect, useState } from 'react'; import { CreateLinkEvent, LocalizeText, RoomWidgetZoomToggleMessage } from '../../../../api'; import { Base, Column, Flex, Text } from '../../../../common'; import { NavigatorEvent } from '../../../../events'; +import { BatchUpdates } from '../../../../hooks'; import { dispatchUiEvent } from '../../../../hooks/events'; import { CreateMessageHook, SendMessageHook } from '../../../../hooks/messages'; +import { TransitionAnimation, TransitionAnimationTypes } from '../../../../layout'; import { useRoomContext } from '../../context/RoomContext'; export const RoomToolsWidgetView: FC<{}> = props => @@ -13,14 +15,13 @@ export const RoomToolsWidgetView: FC<{}> = props => const [ isZoomedIn, setIsZoomedIn ] = useState(false); const [ isLiked, setIsLiked ] = useState(false); const { widgetHandler = null } = useRoomContext(); - const [ roomName, setRoomName ] = useState(null); const [ roomOwner, setRoomOwner ] = useState(null); const [ roomTags, setRoomTags ] = useState(null); const [ roomInfoDisplay, setRoomInfoDisplay ] = useState(false); const [ isOpen, setIsOpen ] = useState(false); - const handleToolClick = useCallback((action: string) => + const handleToolClick = (action: string) => { switch(action) { @@ -44,17 +45,18 @@ export const RoomToolsWidgetView: FC<{}> = props => dispatchUiEvent(new NavigatorEvent(NavigatorEvent.TOGGLE_ROOM_LINK)); return; } - }, [ isZoomedIn, isLiked, widgetHandler ]); + } const onGetGuestRoomResultEvent = useCallback((event: GetGuestRoomResultEvent) => { const parser = event.getParser(); - if(roomName !== parser.data.roomName) setRoomName(parser.data.roomName); - - if(roomOwner !== parser.data.ownerName) setRoomOwner(parser.data.ownerName); - - if(roomTags !== parser.data.tags) setRoomTags(parser.data.tags); + BatchUpdates(() => + { + if(roomName !== parser.data.roomName) setRoomName(parser.data.roomName); + if(roomOwner !== parser.data.ownerName) setRoomOwner(parser.data.ownerName); + if(roomTags !== parser.data.tags) setRoomTags(parser.data.tags); + }); }, [ roomName, roomOwner, roomTags ]); CreateMessageHook(GetGuestRoomResultEvent, onGetGuestRoomResultEvent); @@ -69,26 +71,29 @@ export const RoomToolsWidgetView: FC<{}> = props => }, [ roomName, roomOwner, roomTags ]); return ( - + handleToolClick('settings') } /> handleToolClick('zoom') } className={ 'icon ' + classNames({ 'icon-zoom-less': !isZoomedIn, 'icon-zoom-more': isZoomedIn }) } /> handleToolClick('chat_history') } className="icon icon-chat-history" /> { !isLiked && handleToolClick('like_room') } className="icon icon-like-room" /> } - { isOpen && - - - - { roomName } - { roomOwner } + + + + + + { roomName } + { roomOwner } + + { roomTags && roomTags.length > 0 && + + { roomTags.map((tag: string) => #{ tag }) } + } - { roomTags && roomTags.length > 0 && -
- { roomTags.map((tag: string) =>
#{ tag }
) } -
}
-
} + +
); } diff --git a/src/views/room/widgets/user-location/UserLocationView.tsx b/src/views/room/widgets/user-location/UserLocationView.tsx index c8dd2364..61c1cb49 100644 --- a/src/views/room/widgets/user-location/UserLocationView.tsx +++ b/src/views/room/widgets/user-location/UserLocationView.tsx @@ -1,8 +1,13 @@ import { RoomObjectCategory } from '@nitrots/nitro-renderer'; import { FC } from 'react'; +import { BaseProps } from '../../../../common'; import { useRoomContext } from '../../context/RoomContext'; import { ObjectLocationView } from '../object-location/ObjectLocationView'; -import { UserLocationViewProps } from './UserLocationView.types'; + +interface UserLocationViewProps extends BaseProps +{ + userId: number; +} export const UserLocationView: FC = props => { diff --git a/src/views/room/widgets/user-location/UserLocationView.types.ts b/src/views/room/widgets/user-location/UserLocationView.types.ts deleted file mode 100644 index d5951e2b..00000000 --- a/src/views/room/widgets/user-location/UserLocationView.types.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { NitroLayoutBaseProps } from '../../../../layout/base'; - -export interface UserLocationViewProps extends NitroLayoutBaseProps -{ - userId: number; -} diff --git a/src/views/room/widgets/word-quiz/WordQuizQuestionView.tsx b/src/views/room/widgets/word-quiz/WordQuizQuestionView.tsx new file mode 100644 index 00000000..83421ea1 --- /dev/null +++ b/src/views/room/widgets/word-quiz/WordQuizQuestionView.tsx @@ -0,0 +1,44 @@ +import { FC } from 'react'; +import { Base, Column, Flex, Text } from '../../../../common'; +import { VALUE_KEY_DISLIKE, VALUE_KEY_LIKE } from './common/VoteValue'; + +interface WordQuizQuestionViewProps +{ + question: string; + canVote: boolean; + vote(value: string): void; + noVotes: number; + yesVotes: number; +} + +export const WordQuizQuestionView: FC = props => +{ + const { question = null, canVote = null, vote = null, noVotes = null, yesVotes = null } = props; + + return ( + + { !canVote && + + + { noVotes } + + { question } + + { yesVotes } + + } + { canVote && + + { question } + + vote(VALUE_KEY_DISLIKE) }> + + + vote(VALUE_KEY_LIKE) }> + + + + } + + ); +} diff --git a/src/views/room/widgets/word-quiz/WordQuizVoteView.tsx b/src/views/room/widgets/word-quiz/WordQuizVoteView.tsx new file mode 100644 index 00000000..5511b284 --- /dev/null +++ b/src/views/room/widgets/word-quiz/WordQuizVoteView.tsx @@ -0,0 +1,24 @@ +import { RoomObjectCategory } from '@nitrots/nitro-renderer/src'; +import { FC } from 'react'; +import { Base, BaseProps, Flex } from '../../../../common'; +import { ObjectLocationView } from '../object-location/ObjectLocationView'; +import { VALUE_KEY_DISLIKE } from './common/VoteValue'; + +interface WordQuizVoteViewProps extends BaseProps +{ + userIndex: number; + vote: string; +} + +export const WordQuizVoteView: FC = props => +{ + const { userIndex = null, vote = null, ...rest } = props; + + return ( + + + + + + ); +} diff --git a/src/views/room/widgets/word-quiz/WordQuizWidgetView.scss b/src/views/room/widgets/word-quiz/WordQuizWidgetView.scss deleted file mode 100644 index 5889d925..00000000 --- a/src/views/room/widgets/word-quiz/WordQuizWidgetView.scss +++ /dev/null @@ -1,39 +0,0 @@ -.wordquiz-question { - position: absolute; - top: 10px; - left: 50%; - transform: translateX(-50%); - font-size: large; - background: rgba($dark, 0.9); - //box-shadow: inset 0px 5px lighten(rgba($dark,.6),2.5), inset 0 -4px darken(rgba($dark,.6),4); - border-radius: $border-radius; - transition: all 0.2s ease; - - .question { - max-width: 300px; - } -} - -.word-quiz-dislike { - background: url("../../../../assets/images/room-widgets/wordquiz-widget/thumbs-down.png"); - width: 31px; - height: 34px; -} - -.word-quiz-like { - background: url("../../../../assets/images/room-widgets/wordquiz-widget/thumbs-up.png"); - width: 31px; - height: 34px; -} - -.word-quiz-dislike-sm { - background: url("../../../../assets/images/room-widgets/wordquiz-widget/thumbs-down-small.png"); - width: 22px; - height: 22px; -} - -.word-quiz-like-sm { - background: url("../../../../assets/images/room-widgets/wordquiz-widget/thumbs-up-small.png"); - height: 22px; - width: 22px; -} diff --git a/src/views/room/widgets/word-quiz/WordQuizWidgetView.tsx b/src/views/room/widgets/word-quiz/WordQuizWidgetView.tsx index 271853e4..b6b7475e 100644 --- a/src/views/room/widgets/word-quiz/WordQuizWidgetView.tsx +++ b/src/views/room/widgets/word-quiz/WordQuizWidgetView.tsx @@ -5,21 +5,21 @@ import { RoomWidgetPollMessage } from '../../../../api/nitro/room/widgets/messag import { BatchUpdates, CreateEventDispatcherHook } from '../../../../hooks'; import { useRoomContext } from '../../context/RoomContext'; import { VALUE_KEY_DISLIKE, VALUE_KEY_LIKE, VoteValue } from './common/VoteValue'; -import { QuestionView } from './views/question/QuestionView'; -import { VoteView } from './views/vote/VoteView'; +import { WordQuizQuestionView } from './WordQuizQuestionView'; +import { WordQuizVoteView } from './WordQuizVoteView'; const DEFAULT_DISPLAY_DELAY = 4000; const SIGN_FADE_DELAY = 3; export const WordQuizWidgetView: FC<{}> = props => { + const [ pollId, setPollId ] = useState(-1); + const [ question, setQuestion ] = useState(null); + const [ answerSent, setAnswerSent ] = useState(false); + const [ questionClearTimeout, setQuestionClearTimeout ] = useState(null); + const [ answerCounts, setAnswerCounts ] = useState>(new Map()); + const [ userAnswers, setUserAnswers ] = useState>(new Map()); const { eventDispatcher = null, widgetHandler = null, roomSession = null } = useRoomContext(); - const [pollId, setPollId] = useState(-1); - const [question, setQuestion] = useState(null); - const [answerSent, setAnswerSent] = useState(false); - const [questionClearTimeout, setQuestionClearTimeout] = useState(null); - const [answerCounts, setAnswerCounts] = useState>(new Map()); - const [userAnswers, setUserAnswers] = useState>(new Map()); const clearQuestion = useCallback(() => { @@ -39,33 +39,47 @@ export const WordQuizWidgetView: FC<{}> = props => setAnswerSent(false); setAnswerCounts(new Map()); setUserAnswers(new Map()); - if(questionClearTimeout) clearTimeout(questionClearTimeout); - }); - if(event.duration > 0) - { - const delay = event.duration < 1000 ? DEFAULT_DISPLAY_DELAY : event.duration; setQuestionClearTimeout(prevValue => - { - if(prevValue) clearTimeout(prevValue); + { + if(prevValue) clearTimeout(prevValue); - return setTimeout((clearQuestion as TimerHandler), delay); - }) - } + if(event.duration > 0) + { + const delay = event.duration < 1000 ? DEFAULT_DISPLAY_DELAY : event.duration; + + return setTimeout(() => clearQuestion(), delay) as unknown as number; + } + + return null; + }); + }); break; - case RoomWidgetWordQuizUpdateEvent.QUESTION_ANSWERED: + case RoomWidgetWordQuizUpdateEvent.QUESTION_ANSWERED: { const userData = roomSession.userDataManager.getUserData(event.userId); + if(!userData) return; - setAnswerCounts(event.answerCounts); - - if(!userAnswers.has(userData.roomIndex)) + BatchUpdates(() => { - const answersCopy = new Map(userAnswers); - answersCopy.set(userData.roomIndex, { value: event.value, secondsLeft: SIGN_FADE_DELAY }); - setUserAnswers(answersCopy); - } + setAnswerCounts(event.answerCounts); + + setUserAnswers(prevValue => + { + if(!prevValue.has(userData.roomIndex)) + { + const newValue = new Map(userAnswers); + + newValue.set(userData.roomIndex, { value: event.value, secondsLeft: SIGN_FADE_DELAY }); + + return newValue; + } + + return prevValue; + }); + }); break; + } case RoomWidgetWordQuizUpdateEvent.QUESTION_FINISHED: if(question && question.id === event.questionId) { @@ -73,18 +87,20 @@ export const WordQuizWidgetView: FC<{}> = props => { setAnswerCounts(event.answerCounts); setAnswerSent(true); + setQuestionClearTimeout(prevValue => { if(prevValue) clearTimeout(prevValue); - return setTimeout((clearQuestion as TimerHandler), DEFAULT_DISPLAY_DELAY); + return setTimeout(() => clearQuestion(), DEFAULT_DISPLAY_DELAY) as unknown as number; }); - }) + }); } + setUserAnswers(new Map()); break; } - }, [clearQuestion, question, questionClearTimeout, roomSession.userDataManager, userAnswers]); + }, [ question, roomSession.userDataManager, userAnswers, clearQuestion ]); CreateEventDispatcherHook(RoomWidgetWordQuizUpdateEvent.NEW_QUESTION, eventDispatcher, onRoomWidgetWordQuizUpdateEvent); CreateEventDispatcherHook(RoomWidgetWordQuizUpdateEvent.QUESTION_ANSWERED, eventDispatcher, onRoomWidgetWordQuizUpdateEvent); @@ -95,49 +111,44 @@ export const WordQuizWidgetView: FC<{}> = props => if(answerSent || !question) return; const updateMessage = new RoomWidgetPollMessage(RoomWidgetPollMessage.ANSWER, pollId); + updateMessage.questionId = question.id; updateMessage.answers = [vote]; - widgetHandler.processWidgetMessage(updateMessage); - setAnswerSent(true); - }, [answerSent, pollId, question, widgetHandler]); + widgetHandler.processWidgetMessage(updateMessage); + + setAnswerSent(true); + }, [ answerSent, pollId, question, widgetHandler ]); const checkSignFade = useCallback(() => { - setUserAnswers(prev => + setUserAnswers(prevValue => { const keysToRemove: number[] = []; - prev.forEach((value, key) => + + prevValue.forEach((value, key) => { value.secondsLeft--; - if(value.secondsLeft <= 0) - { - keysToRemove.push(key); - } + if(value.secondsLeft <= 0) keysToRemove.push(key); }); - if(keysToRemove.length === 0) return prev; + if(keysToRemove.length === 0) return prevValue; + + const copy = new Map(prevValue); - const copy = new Map(prev); keysToRemove.forEach(key => copy.delete(key)); - return copy; - }) + return copy; + }); }, []); useEffect(() => { - const interval = setInterval(() => - { - checkSignFade(); - }, 1000) + const interval = setInterval(() => checkSignFade(), 1000); - return () => - { - clearInterval(interval); - } - }, [checkSignFade]); + return () => clearInterval(interval); + }, [ checkSignFade ]); useEffect(() => { @@ -154,15 +165,10 @@ export const WordQuizWidgetView: FC<{}> = props => return ( <> - {question && - - } - {userAnswers && - Array.from(userAnswers.entries()).map(([key, value], index) => - { - return - }) - } + { question && + } + { userAnswers && + Array.from(userAnswers.entries()).map(([key, value], index) => ) } ); } diff --git a/src/views/room/widgets/word-quiz/views/question/QuestionView.tsx b/src/views/room/widgets/word-quiz/views/question/QuestionView.tsx deleted file mode 100644 index 2d2b5d17..00000000 --- a/src/views/room/widgets/word-quiz/views/question/QuestionView.tsx +++ /dev/null @@ -1,24 +0,0 @@ -import { FC } from 'react'; -import { VALUE_KEY_DISLIKE, VALUE_KEY_LIKE } from '../../common/VoteValue'; -import { QuestionViewProps } from './QuestionView.types'; - -export const QuestionView:FC = props => -{ - const { question = null, canVote = null, vote = null, noVotes = null, yesVotes = null } = props; - - return ( -
-
- { !canVote && } -
{question}
- { !canVote && } -
- {canVote && -
- - -
- } -
- ) -} diff --git a/src/views/room/widgets/word-quiz/views/question/QuestionView.types.ts b/src/views/room/widgets/word-quiz/views/question/QuestionView.types.ts deleted file mode 100644 index fde51dba..00000000 --- a/src/views/room/widgets/word-quiz/views/question/QuestionView.types.ts +++ /dev/null @@ -1,9 +0,0 @@ - -export interface QuestionViewProps -{ - question: string; - canVote: boolean; - vote(value: string): void; - noVotes: number; - yesVotes: number; -} diff --git a/src/views/room/widgets/word-quiz/views/vote/VoteView.tsx b/src/views/room/widgets/word-quiz/views/vote/VoteView.tsx deleted file mode 100644 index bee02143..00000000 --- a/src/views/room/widgets/word-quiz/views/vote/VoteView.tsx +++ /dev/null @@ -1,16 +0,0 @@ -import { RoomObjectCategory } from '@nitrots/nitro-renderer/src'; -import { FC } from 'react'; -import { ObjectLocationView } from '../../../object-location/ObjectLocationView'; -import { VALUE_KEY_DISLIKE } from '../../common/VoteValue'; -import { VoteViewProps } from './VoteView.types'; - -export const VoteView:FC = props => -{ - const { userIndex = null , vote = null } = props; - - return ( - - - - ) -} diff --git a/src/views/room/widgets/word-quiz/views/vote/VoteView.types.ts b/src/views/room/widgets/word-quiz/views/vote/VoteView.types.ts deleted file mode 100644 index 17062cc6..00000000 --- a/src/views/room/widgets/word-quiz/views/vote/VoteView.types.ts +++ /dev/null @@ -1,5 +0,0 @@ -export interface VoteViewProps -{ - userIndex: number; - vote: string; -}