From 1e8476032460c56db9f1010b86fda6ce4b6f4e5b Mon Sep 17 00:00:00 2001 From: dank074 Date: Wed, 17 Nov 2021 00:09:47 -0600 Subject: [PATCH] finished logic --- .../widgets/handlers/PollWidgetHandler.ts | 1 - .../widgets/handlers/WordQuizWidgetHandler.ts | 1 - .../wordquiz-widget/thumbs-down-small.png | Bin 0 -> 145 bytes .../wordquiz-widget/thumbs-down.png | Bin 0 -> 182 bytes .../wordquiz-widget/thumbs-up-small.png | Bin 0 -> 135 bytes .../wordquiz-widget/thumbs-up.png | Bin 0 -> 174 bytes src/views/room/widgets/RoomWidgetsView.tsx | 8 +- .../widgets/word-quiz/WordQuizWidgetView.scss | 43 ++++- .../widgets/word-quiz/WordQuizWidgetView.tsx | 153 ++++++++++++++++-- .../widgets/word-quiz/common/VoteValue.ts | 6 + .../word-quiz/views/question/QuestionView.tsx | 18 ++- .../views/question/QuestionView.types.ts | 2 + .../widgets/word-quiz/views/vote/VoteView.tsx | 16 ++ .../word-quiz/views/vote/VoteView.types.ts | 5 + 14 files changed, 222 insertions(+), 31 deletions(-) create mode 100644 src/assets/images/room-widgets/wordquiz-widget/thumbs-down-small.png create mode 100644 src/assets/images/room-widgets/wordquiz-widget/thumbs-down.png create mode 100644 src/assets/images/room-widgets/wordquiz-widget/thumbs-up-small.png create mode 100644 src/assets/images/room-widgets/wordquiz-widget/thumbs-up.png create mode 100644 src/views/room/widgets/word-quiz/views/vote/VoteView.tsx create mode 100644 src/views/room/widgets/word-quiz/views/vote/VoteView.types.ts diff --git a/src/api/nitro/room/widgets/handlers/PollWidgetHandler.ts b/src/api/nitro/room/widgets/handlers/PollWidgetHandler.ts index df4d67b7..0d1b0457 100644 --- a/src/api/nitro/room/widgets/handlers/PollWidgetHandler.ts +++ b/src/api/nitro/room/widgets/handlers/PollWidgetHandler.ts @@ -43,7 +43,6 @@ export class PollWidgetHandler extends RoomWidgetHandler public processWidgetMessage(message: RoomWidgetMessage): RoomWidgetUpdateEvent { const pollMessage = (message as RoomWidgetPollMessage); - switch(message.type) { case RoomWidgetPollMessage.START: diff --git a/src/api/nitro/room/widgets/handlers/WordQuizWidgetHandler.ts b/src/api/nitro/room/widgets/handlers/WordQuizWidgetHandler.ts index c65632ee..df24b06e 100644 --- a/src/api/nitro/room/widgets/handlers/WordQuizWidgetHandler.ts +++ b/src/api/nitro/room/widgets/handlers/WordQuizWidgetHandler.ts @@ -11,7 +11,6 @@ export class WordQuizWidgetHandler extends RoomWidgetHandler { const roomQuizEvent = (event as RoomSessionWordQuizEvent); let widgetEvent: RoomWidgetWordQuizUpdateEvent; - switch(event.type) { case RoomSessionWordQuizEvent.ANSWERED: diff --git a/src/assets/images/room-widgets/wordquiz-widget/thumbs-down-small.png b/src/assets/images/room-widgets/wordquiz-widget/thumbs-down-small.png new file mode 100644 index 0000000000000000000000000000000000000000..78e51cfe5666ccc5fe46dcd7976f615d19eab56b GIT binary patch literal 145 zcmeAS@N?(olHy`uVBq!ia0vp^Vj#@H1|*Mc$*~4f5uPrNAr-gYPIcsBP~c$s?*H$9 zZdkj6i$Tur7G^ow5`Hd;Ee-EoTf{t%3P-w%zGj`@S-x*>Vfq>2*}a+NP7@R&Lzig! sFNyP+%$9WF=#@-=yCb|#^S2#h&~MqhAozyaL!ccDp00i_>zopr00L$)8~^|S literal 0 HcmV?d00001 diff --git a/src/assets/images/room-widgets/wordquiz-widget/thumbs-down.png b/src/assets/images/room-widgets/wordquiz-widget/thumbs-down.png new file mode 100644 index 0000000000000000000000000000000000000000..fd320c51d72f0debe17f9537d132ec4de35bf815 GIT binary patch literal 182 zcmeAS@N?(olHy`uVBq!ia0vp^@<6P_!3HFkdog(dsaj7L$B>F!Z?9bBYf#{5O}y9n zz20n9x0&0EGbb0S{y*j`US~PiMJ+NW|82kxr`Fv+B;%QntL{+KYvB5RZqC;?8;co3 zcluQ5JW=caG8r!IE7jJKC2Yu=J)QJ hqVly?g7yYi8Nao2ZhvIZ@C@h>22WQ%mvv4FO#s~;NumG% literal 0 HcmV?d00001 diff --git a/src/assets/images/room-widgets/wordquiz-widget/thumbs-up-small.png b/src/assets/images/room-widgets/wordquiz-widget/thumbs-up-small.png new file mode 100644 index 0000000000000000000000000000000000000000..b93111f0cc078bd21ac90ce83f59ce4663474d53 GIT binary patch literal 135 zcmeAS@N?(olHy`uVBq!ia0vp^Vj#@H1|*Mc$*~4fex5FlAr-fh6BLC0v@@|~G0&3r zDLwo$$zUt5x!UOu|5KP|N%~wU@Zvp|-f74ad^KU#&Wab3Hd4o&EqXL{^;hH>T$#?2 iEs<F!Z>KwQF(~pde^&qh zf7`pzl&z;$ a8+P{toZC}5t{w$CfWgz%&t;ucLK6V707rlT literal 0 HcmV?d00001 diff --git a/src/views/room/widgets/RoomWidgetsView.tsx b/src/views/room/widgets/RoomWidgetsView.tsx index 0a94e885..4f205b1d 100644 --- a/src/views/room/widgets/RoomWidgetsView.tsx +++ b/src/views/room/widgets/RoomWidgetsView.tsx @@ -1,4 +1,4 @@ -import { RoomEngineEvent, RoomEngineObjectEvent, RoomEngineRoomAdEvent, RoomEngineTriggerWidgetEvent, RoomEngineUseProductEvent, RoomId, RoomObjectCategory, RoomObjectOperationType, RoomObjectVariable, RoomSessionChatEvent, RoomSessionDanceEvent, RoomSessionDimmerPresetsEvent, RoomSessionDoorbellEvent, RoomSessionErrorMessageEvent, RoomSessionEvent, RoomSessionFriendRequestEvent, RoomSessionPetInfoUpdateEvent, RoomSessionPresentEvent, RoomSessionUserBadgesEvent, RoomZoomEvent } from '@nitrots/nitro-renderer'; +import { RoomEngineEvent, RoomEngineObjectEvent, RoomEngineRoomAdEvent, RoomEngineTriggerWidgetEvent, RoomEngineUseProductEvent, RoomId, RoomObjectCategory, RoomObjectOperationType, RoomObjectVariable, RoomSessionChatEvent, RoomSessionDanceEvent, RoomSessionDimmerPresetsEvent, RoomSessionDoorbellEvent, RoomSessionErrorMessageEvent, RoomSessionEvent, RoomSessionFriendRequestEvent, RoomSessionPetInfoUpdateEvent, RoomSessionPollEvent, RoomSessionPresentEvent, RoomSessionUserBadgesEvent, RoomSessionWordQuizEvent, RoomZoomEvent } from '@nitrots/nitro-renderer'; import { FC, useCallback } from 'react'; import { CanManipulateFurniture, GetRoomEngine, GetSessionDataManager, IsFurnitureSelectionDisabled, LocalizeText, ProcessRoomObjectOperation, RoomWidgetFurniToWidgetMessage, RoomWidgetUpdateRoomEngineEvent, RoomWidgetUpdateRoomObjectEvent } from '../../../api'; import { useRoomEngineEvent, useRoomSessionManagerEvent } from '../../../hooks/events'; @@ -269,6 +269,12 @@ export const RoomWidgetsView: FC = props => useRoomSessionManagerEvent(RoomSessionFriendRequestEvent.RSFRE_FRIEND_REQUEST, onRoomSessionEvent); useRoomSessionManagerEvent(RoomSessionPresentEvent.RSPE_PRESENT_OPENED, onRoomSessionEvent); useRoomSessionManagerEvent(RoomSessionPetInfoUpdateEvent.PET_INFO, onRoomSessionEvent); + useRoomSessionManagerEvent(RoomSessionWordQuizEvent.ANSWERED, onRoomSessionEvent); + useRoomSessionManagerEvent(RoomSessionWordQuizEvent.FINISHED, onRoomSessionEvent); + useRoomSessionManagerEvent(RoomSessionWordQuizEvent.QUESTION, onRoomSessionEvent); + useRoomSessionManagerEvent(RoomSessionPollEvent.OFFER, onRoomSessionEvent); + useRoomSessionManagerEvent(RoomSessionPollEvent.ERROR, onRoomSessionEvent); + useRoomSessionManagerEvent(RoomSessionPollEvent.CONTENT, onRoomSessionEvent); const onRoomSessionErrorMessageEvent = useCallback((event: RoomSessionErrorMessageEvent) => { diff --git a/src/views/room/widgets/word-quiz/WordQuizWidgetView.scss b/src/views/room/widgets/word-quiz/WordQuizWidgetView.scss index d4291278..5889d925 100644 --- a/src/views/room/widgets/word-quiz/WordQuizWidgetView.scss +++ b/src/views/room/widgets/word-quiz/WordQuizWidgetView.scss @@ -1,12 +1,39 @@ -.word-quiz-question-container { +.wordquiz-question { position: absolute; top: 10px; - left: 0px; - .wordquiz-question { - font-size: large; - background: rgba($dark, 0.90); - //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; + 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 a529f409..af258d59 100644 --- a/src/views/room/widgets/word-quiz/WordQuizWidgetView.tsx +++ b/src/views/room/widgets/word-quiz/WordQuizWidgetView.tsx @@ -1,17 +1,32 @@ import { IQuestion } from '@nitrots/nitro-renderer'; -import { FC, useCallback, useState } from 'react'; +import { FC, useCallback, useEffect, useState } from 'react'; import { RoomWidgetWordQuizUpdateEvent } from '../../../../api/nitro/room/widgets/events/RoomWidgetWordQuizUpdateEvent'; +import { RoomWidgetPollMessage } from '../../../../api/nitro/room/widgets/messages/RoomWidgetPollMessage'; 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'; + +const DEFAULT_DISPLAY_DELAY = 4000; +const SIGN_FADE_DELAY = 3; export const WordQuizWidgetView: FC<{}> = props => { - const { eventDispatcher = null, widgetHandler = null } = useRoomContext(); - const [pollId, setPollId ] = useState(-1); + const { eventDispatcher = null, widgetHandler = null, roomSession = null } = useRoomContext(); + const [pollId, setPollId] = useState(-1); const [question, setQuestion] = useState(null); - const [ answerSent, setAnswerSent ] = useState(false); - + 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(() => + { + setPollId(-1); + setQuestion(null); + }, []); + const onRoomWidgetWordQuizUpdateEvent = useCallback((event: RoomWidgetWordQuizUpdateEvent) => { switch(event.type) @@ -22,25 +37,131 @@ export const WordQuizWidgetView: FC<{}> = props => setPollId(event.id); setQuestion(event.question); setAnswerSent(false); + setAnswerCounts(new Map()); + setUserAnswers(new Map()); + if(questionClearTimeout) clearTimeout(questionClearTimeout); }); - //this._showSignCounters = new Dictionary(); - //this.showNewQuestion(this._question, k.duration); + + if(event.duration > 0) + { + const delay = event.duration < 1000 ? DEFAULT_DISPLAY_DELAY : event.duration; + setQuestionClearTimeout(prevValue => + { + if(prevValue) clearTimeout(prevValue); + + return setTimeout((clearQuestion as TimerHandler), delay); + }) + } + break; + case RoomWidgetWordQuizUpdateEvent.QUESTION_ANSWERED: + const userData = roomSession.userDataManager.getUserData(event.userId); + if(!userData) return; + + setAnswerCounts(event.answerCounts); + + if(!userAnswers.has(userData.roomIndex)) + { + const answersCopy = new Map(userAnswers); + answersCopy.set(userData.roomIndex, { value: event.value, secondsLeft: SIGN_FADE_DELAY }); + setUserAnswers(answersCopy); + } + break; + case RoomWidgetWordQuizUpdateEvent.QUESTION_FINISHED: + if(question && question.id === event.questionId) + { + BatchUpdates(() => + { + setAnswerCounts(event.answerCounts); + setAnswerSent(true); + setQuestionClearTimeout(prevValue => + { + if(prevValue) clearTimeout(prevValue); + + return setTimeout((clearQuestion as TimerHandler), DEFAULT_DISPLAY_DELAY); + }); + }) + } + setUserAnswers(new Map()); break; } - }, []); - - const vote = useCallback((vote: string) => - { - - }, []); + }, [clearQuestion, question, questionClearTimeout, roomSession.userDataManager, userAnswers]); CreateEventDispatcherHook(RoomWidgetWordQuizUpdateEvent.NEW_QUESTION, eventDispatcher, onRoomWidgetWordQuizUpdateEvent); CreateEventDispatcherHook(RoomWidgetWordQuizUpdateEvent.QUESTION_ANSWERED, eventDispatcher, onRoomWidgetWordQuizUpdateEvent); CreateEventDispatcherHook(RoomWidgetWordQuizUpdateEvent.QUESTION_FINISHED, eventDispatcher, onRoomWidgetWordQuizUpdateEvent); + const vote = useCallback((vote: string) => + { + 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]); + + const checkSignFade = useCallback(() => + { + setUserAnswers(prev => + { + const copy = new Map(prev); + const keysToRemove: number[] = []; + copy.forEach((value, key) => + { + value.secondsLeft--; + + if(value.secondsLeft <= 0) + { + keysToRemove.push(key); + } + }); + + keysToRemove.forEach(key => copy.delete(key)); + + return copy; + }) + + }, []); + + useEffect(() => + { + const interval = setInterval(() => + { + checkSignFade(); + }, 1000) + + return () => + { + clearInterval(interval); + } + }, [checkSignFade]); + + useEffect(() => + { + return () => + { + setQuestionClearTimeout(prev => + { + if(prev) clearTimeout(prev); + + return null; + }); + } + }, []); + return ( - <> - {question && } - + <> + {question && + + } + {userAnswers && + Array.from(userAnswers.entries()).map(([key, value], index) => + { + return + }) + } + ); } diff --git a/src/views/room/widgets/word-quiz/common/VoteValue.ts b/src/views/room/widgets/word-quiz/common/VoteValue.ts index ef84aaff..ecf4336e 100644 --- a/src/views/room/widgets/word-quiz/common/VoteValue.ts +++ b/src/views/room/widgets/word-quiz/common/VoteValue.ts @@ -1,2 +1,8 @@ export const VALUE_KEY_DISLIKE = '0'; export const VALUE_KEY_LIKE = '1'; + +export interface VoteValue +{ + value: string; + secondsLeft: number; +} diff --git a/src/views/room/widgets/word-quiz/views/question/QuestionView.tsx b/src/views/room/widgets/word-quiz/views/question/QuestionView.tsx index 13bbf225..2d2b5d17 100644 --- a/src/views/room/widgets/word-quiz/views/question/QuestionView.tsx +++ b/src/views/room/widgets/word-quiz/views/question/QuestionView.tsx @@ -1,14 +1,24 @@ 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 } = props; + const { question = null, canVote = null, vote = null, noVotes = null, yesVotes = null } = props; return ( -
-
{question}
+
+
+ { !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 index 09fda7b4..fde51dba 100644 --- a/src/views/room/widgets/word-quiz/views/question/QuestionView.types.ts +++ b/src/views/room/widgets/word-quiz/views/question/QuestionView.types.ts @@ -4,4 +4,6 @@ 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 new file mode 100644 index 00000000..bee02143 --- /dev/null +++ b/src/views/room/widgets/word-quiz/views/vote/VoteView.tsx @@ -0,0 +1,16 @@ +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 new file mode 100644 index 00000000..17062cc6 --- /dev/null +++ b/src/views/room/widgets/word-quiz/views/vote/VoteView.types.ts @@ -0,0 +1,5 @@ +export interface VoteViewProps +{ + userIndex: number; + vote: string; +}