diff --git a/src/views/navigator/NavigatorMessageHandler.tsx b/src/views/navigator/NavigatorMessageHandler.tsx index 5616693f..c3857dd5 100644 --- a/src/views/navigator/NavigatorMessageHandler.tsx +++ b/src/views/navigator/NavigatorMessageHandler.tsx @@ -1,12 +1,13 @@ -import { NavigatorCategoriesComposer, NavigatorMetadataEvent, NavigatorSearchEvent, NavigatorSettingsComposer, RoomDataParser, RoomForwardEvent, RoomInfoComposer, RoomInfoEvent, RoomInfoOwnerEvent, UserInfoEvent } from 'nitro-renderer'; +import { GenericErrorEvent, NavigatorCategoriesComposer, NavigatorMetadataEvent, NavigatorSearchEvent, NavigatorSettingsComposer, RoomDataParser, RoomDoorbellAcceptedEvent, RoomDoorbellEvent, RoomForwardEvent, RoomInfoComposer, RoomInfoEvent, RoomInfoOwnerEvent, UserInfoEvent } from 'nitro-renderer'; import { useCallback } from 'react'; import { GetRoomSessionManager, GetSessionDataManager } from '../../api'; import { CreateMessageHook, SendMessageHook } from '../../hooks/messages/message-event'; +import { NavigatorLockViewStage } from './lock/NavigatorLockView.types'; import { NavigatorMessageHandlerProps } from './NavigatorMessageHandler.types'; export function NavigatorMessageHandler(props: NavigatorMessageHandlerProps): JSX.Element { - const { setTopLevelContext = null, setTopLevelContexts = null, setSearchResults = null } = props; + const { setTopLevelContext = null, setTopLevelContexts = null, setSearchResults = null, showLock = null, hideLock = null } = props; const onUserInfoEvent = useCallback((event: UserInfoEvent) => { @@ -48,7 +49,6 @@ export function NavigatorMessageHandler(props: NavigatorMessageHandlerProps): JS // this._data.createdRoomId = 0; } - else if(parser.roomForward) { if((parser.data.ownerName !== GetSessionDataManager().userName) && !parser.isGroupMember) @@ -56,17 +56,14 @@ export function NavigatorMessageHandler(props: NavigatorMessageHandlerProps): JS switch(parser.data.doorMode) { case RoomDataParser.DOORBELL_STATE: - console.log('open doorbell'); - return; case RoomDataParser.PASSWORD_STATE: - console.log('open password'); + showLock(); return; } } GetRoomSessionManager().createSession(parser.data.roomId); } - else { // this._data.enteredGuestRoom = parser.data; @@ -74,6 +71,50 @@ export function NavigatorMessageHandler(props: NavigatorMessageHandlerProps): JS } }, []); + const onRoomDoorbellEvent = useCallback((event: RoomDoorbellEvent) => + { + if(!event) return; + + const parser = event.getParser(); + + if(!parser) return; + + if(!parser.userName || (parser.userName.length === 0)) + { + showLock(NavigatorLockViewStage.WAITING); + } + }, []); + + const onRoomDoorbellAcceptedEvent = useCallback((event: RoomDoorbellAcceptedEvent) => + { + if(!event) return; + + const parser = event.getParser(); + + if(!parser) return; + + if(!parser.userName || (parser.userName.length === 0)) + { + hideLock(); + } + }, []); + + const onGenericErrorEvent = useCallback((event: GenericErrorEvent) => + { + if(!event) return; + + const parser = event.getParser(); + + if(!parser) return; + + switch(parser.errorCode) + { + case -100002: + showLock(NavigatorLockViewStage.FAILED); + break; + } + }, []); + const onNavigatorMetadataEvent = useCallback((event: NavigatorMetadataEvent) => { const parser = event.getParser(); @@ -96,6 +137,9 @@ export function NavigatorMessageHandler(props: NavigatorMessageHandlerProps): JS CreateMessageHook(new RoomForwardEvent(onRoomForwardEvent)); CreateMessageHook(new RoomInfoOwnerEvent(onRoomInfoOwnerEvent)); CreateMessageHook(new RoomInfoEvent(onRoomInfoEvent)); + CreateMessageHook(new RoomDoorbellEvent(onRoomDoorbellEvent)); + CreateMessageHook(new RoomDoorbellAcceptedEvent(onRoomDoorbellAcceptedEvent)); + CreateMessageHook(new GenericErrorEvent(onGenericErrorEvent)); CreateMessageHook(new NavigatorMetadataEvent(onNavigatorMetadataEvent)); CreateMessageHook(new NavigatorSearchEvent(onNavigatorSearchEvent)); diff --git a/src/views/navigator/NavigatorMessageHandler.types.ts b/src/views/navigator/NavigatorMessageHandler.types.ts index 95922b6f..d7111952 100644 --- a/src/views/navigator/NavigatorMessageHandler.types.ts +++ b/src/views/navigator/NavigatorMessageHandler.types.ts @@ -1,8 +1,11 @@ import { NavigatorSearchResultList, NavigatorTopLevelContext } from 'nitro-renderer'; +import { NavigatorLockViewStage } from './lock/NavigatorLockView.types'; export interface NavigatorMessageHandlerProps { setTopLevelContext: (context: NavigatorTopLevelContext) => void; setTopLevelContexts: (contexts: NavigatorTopLevelContext[]) => void; setSearchResults: (results: NavigatorSearchResultList[]) => void; + showLock: (stage?: NavigatorLockViewStage) => void; + hideLock: () => void; } diff --git a/src/views/navigator/NavigatorView.scss b/src/views/navigator/NavigatorView.scss index 2cc31f50..c8c29c4f 100644 --- a/src/views/navigator/NavigatorView.scss +++ b/src/views/navigator/NavigatorView.scss @@ -2,5 +2,6 @@ width: 400px; } +@import './lock/NavigatorLockView'; @import './result-lists/NavigatorResultListsView'; @import './tabs/NavigatorTabsView'; diff --git a/src/views/navigator/NavigatorView.tsx b/src/views/navigator/NavigatorView.tsx index 74d3540b..931c94bb 100644 --- a/src/views/navigator/NavigatorView.tsx +++ b/src/views/navigator/NavigatorView.tsx @@ -1,26 +1,35 @@ -import { NavigatorInitComposer, NavigatorSearchComposer, NavigatorSearchResultList, NavigatorTopLevelContext, RoomSessionEvent } from 'nitro-renderer'; -import { MouseEvent, useCallback, useEffect, useState } from 'react'; +import { NavigatorInitComposer, NavigatorSearchComposer, NavigatorSearchResultList, NavigatorTopLevelContext, RoomDataParser, RoomInfoComposer, RoomSessionEvent } from 'nitro-renderer'; +import React, { MouseEvent, useCallback, useEffect, useState } from 'react'; +import { GetRoomSessionManager } from '../../api'; import { NavigatorEvent } from '../../events'; import { DraggableWindow } from '../../hooks/draggable-window/DraggableWindow'; import { useRoomSessionManagerEvent } from '../../hooks/events/nitro/session/room-session-manager-event'; import { useUiEvent } from '../../hooks/events/ui/ui-event'; import { SendMessageHook } from '../../hooks/messages/message-event'; import { LocalizeText } from '../../utils/LocalizeText'; +import { NavigatorLockView } from './lock/NavigatorLockView'; +import { NavigatorLockViewStage } from './lock/NavigatorLockView.types'; import { NavigatorMessageHandler } from './NavigatorMessageHandler'; -import { NavigatorViewProps } from './NavigatorView.types'; +import { INavigatorContext, NavigatorViewProps } from './NavigatorView.types'; import { NavigatorResultListsView } from './result-lists/NavigatorResultListsView'; import { NavigatorTabsView } from './tabs/NavigatorTabsView'; +export const NavigatorContext = React.createContext(null); + export function NavigatorView(props: NavigatorViewProps): JSX.Element { - const [ isVisible, setIsVisible ] = useState(false); - const [ isLoaded, setIsLoaded ] = useState(false); - const [ isLoading, setIsLoading ] = useState(false); - const [ isSearching, setIsSearching ] = useState(false); + const [ isVisible, setIsVisible ] = useState(false); + const [ isLoaded, setIsLoaded ] = useState(false); + const [ isLoading, setIsLoading ] = useState(false); + const [ isSearching, setIsSearching ] = useState(false); + const [ isLockVisible, setIsLockVisible ] = useState(false); + + const [ lockStage, setLockStage ] = useState(NavigatorLockViewStage.INIT); + const [ lastRoomVisited, setLastRoomVisited ] = useState(null); const [ topLevelContexts, setTopLevelContexts ] = useState(null); - const [ topLevelContext, setTopLevelContext ] = useState(null); - const [ searchResults, setSearchResults ] = useState(null); + const [ topLevelContext, setTopLevelContext ] = useState(null); + const [ searchResults, setSearchResults ] = useState(null); function hideNavigator(event: MouseEvent = null): void { @@ -29,6 +38,31 @@ export function NavigatorView(props: NavigatorViewProps): JSX.Element setIsVisible(false); } + function hideLock(): void + { + setIsLockVisible(false); + setLockStage(NavigatorLockViewStage.INIT); + } + + function showLock(stage: NavigatorLockViewStage = NavigatorLockViewStage.INIT) + { + setLockStage(stage); + setIsLockVisible(true); + } + + function visitRoom(roomId: number, password: string = null): void + { + setIsLockVisible(false); + GetRoomSessionManager().createSession(roomId, password); + } + + function tryVisitRoom(room: RoomDataParser): void + { + setIsLockVisible(false); + setLastRoomVisited(room); + SendMessageHook(new RoomInfoComposer(room.roomId, false, true)); + } + const onNavigatorEvent = useCallback((event: NavigatorEvent) => { switch(event.type) @@ -94,19 +128,22 @@ export function NavigatorView(props: NavigatorViewProps): JSX.Element return ( <> - - { isVisible && -
-
-
{ LocalizeText((isLoading || isSearching) ? 'navigator.title.is.busy' : 'navigator.title') }
- + + + { isVisible && +
+
+
{ LocalizeText((isLoading || isSearching) ? 'navigator.title.is.busy' : 'navigator.title') }
+ +
+ +
- - -
- } + } + { isLockVisible && } + ); } diff --git a/src/views/navigator/NavigatorView.types.ts b/src/views/navigator/NavigatorView.types.ts index ef5c41bb..842a306f 100644 --- a/src/views/navigator/NavigatorView.types.ts +++ b/src/views/navigator/NavigatorView.types.ts @@ -1,4 +1,8 @@ +import { RoomDataParser } from 'nitro-renderer'; export interface NavigatorViewProps +{} + +export interface INavigatorContext { - + onTryVisitRoom: (roomData: RoomDataParser) => void; } diff --git a/src/views/navigator/lock/NavigatorLockView.scss b/src/views/navigator/lock/NavigatorLockView.scss new file mode 100644 index 00000000..e2f14b60 --- /dev/null +++ b/src/views/navigator/lock/NavigatorLockView.scss @@ -0,0 +1,3 @@ +.nitro-navigator-lock { + width: 250px; +} diff --git a/src/views/navigator/lock/NavigatorLockView.tsx b/src/views/navigator/lock/NavigatorLockView.tsx new file mode 100644 index 00000000..cefbbf7c --- /dev/null +++ b/src/views/navigator/lock/NavigatorLockView.tsx @@ -0,0 +1,38 @@ +import { RoomDataParser } from 'nitro-renderer'; +import { DraggableWindow } from '../../../hooks/draggable-window/DraggableWindow'; +import { LocalizeText } from '../../../utils/LocalizeText'; +import { NavigatorLockDoorbellView } from './doorbell/NavigatorLockDoorbellView'; +import { NavigatorLockViewProps } from './NavigatorLockView.types'; +import { NavigatorLockPasswordView } from './password/NavigatorLockPasswordView'; + +export function NavigatorLockView(props: NavigatorLockViewProps): JSX.Element +{ + const { roomData = null, stage = null, onHideLock = null, onVisitRoom = null } = props; + + function visitRoom(password?: string): void + { + onVisitRoom(roomData.roomId, password); + } + + return ( + <> + +
+
+
{ LocalizeText(roomData.doorMode === RoomDataParser.PASSWORD_STATE ? 'navigator.password.title' : 'navigator.doorbell.title') }
+ +
+
+ { roomData && <> +
{ roomData.roomName }
+ { roomData.doorMode && roomData.doorMode === RoomDataParser.DOORBELL_STATE && } + { roomData.doorMode && roomData.doorMode === RoomDataParser.PASSWORD_STATE && } + } +
+
+
+ + ); +} diff --git a/src/views/navigator/lock/NavigatorLockView.types.ts b/src/views/navigator/lock/NavigatorLockView.types.ts new file mode 100644 index 00000000..fd9a24ba --- /dev/null +++ b/src/views/navigator/lock/NavigatorLockView.types.ts @@ -0,0 +1,16 @@ +import { RoomDataParser } from 'nitro-renderer'; + +export interface NavigatorLockViewProps +{ + roomData: RoomDataParser; + stage: NavigatorLockViewStage; + onHideLock: () => void; + onVisitRoom: (roomId: number, password?: string) => void; +} + +export enum NavigatorLockViewStage +{ + INIT = 'navigator_lock_view_stage_init', + WAITING = 'navigator_lock_view_stage_waiting', + FAILED = 'navigator_lock_view_stage_failed' +} diff --git a/src/views/navigator/lock/doorbell/NavigatorLockDoorbellView.tsx b/src/views/navigator/lock/doorbell/NavigatorLockDoorbellView.tsx new file mode 100644 index 00000000..64e094d8 --- /dev/null +++ b/src/views/navigator/lock/doorbell/NavigatorLockDoorbellView.tsx @@ -0,0 +1,22 @@ +import { LocalizeText } from '../../../../utils/LocalizeText'; +import { NavigatorLockViewStage } from '../NavigatorLockView.types'; +import { NavigatorLockDoorbellViewProps } from './NavigatorLockDoorbellView.types'; + +export function NavigatorLockDoorbellView(props: NavigatorLockDoorbellViewProps): JSX.Element +{ + const { stage = null, onVisitRoom = null, onHideLock = null } = props; + + return ( + <> + { stage &&
+ { stage === NavigatorLockViewStage.INIT && LocalizeText('navigator.doorbell.info') } + { stage === NavigatorLockViewStage.WAITING && LocalizeText('navigator.doorbell.waiting') } + { stage === NavigatorLockViewStage.FAILED && LocalizeText('navigator.doorbell.no.answer') } +
} +
+ + { stage === NavigatorLockViewStage.INIT && } +
+ + ); +} diff --git a/src/views/navigator/lock/doorbell/NavigatorLockDoorbellView.types.ts b/src/views/navigator/lock/doorbell/NavigatorLockDoorbellView.types.ts new file mode 100644 index 00000000..f930df72 --- /dev/null +++ b/src/views/navigator/lock/doorbell/NavigatorLockDoorbellView.types.ts @@ -0,0 +1,8 @@ +import { NavigatorLockViewStage } from '../NavigatorLockView.types'; + +export interface NavigatorLockDoorbellViewProps +{ + stage: NavigatorLockViewStage; + onVisitRoom: (password?: string) => void; + onHideLock: () => void; +} diff --git a/src/views/navigator/lock/password/NavigatorLockPasswordView.tsx b/src/views/navigator/lock/password/NavigatorLockPasswordView.tsx new file mode 100644 index 00000000..a1cc2bb4 --- /dev/null +++ b/src/views/navigator/lock/password/NavigatorLockPasswordView.tsx @@ -0,0 +1,28 @@ +import { useState } from 'react'; +import { LocalizeText } from '../../../../utils/LocalizeText'; +import { NavigatorLockViewStage } from '../NavigatorLockView.types'; +import { NavigatorLockPasswordViewProps } from './NavigatorLockPasswordView.types'; + +export function NavigatorLockPasswordView(props: NavigatorLockPasswordViewProps): JSX.Element +{ + const { stage = null, onVisitRoom = null, onHideLock = null } = props; + + const [ password, setPassword ] = useState(null); + + return ( + <> + { stage &&
+ { stage === NavigatorLockViewStage.INIT && LocalizeText('navigator.password.info') } + { stage === NavigatorLockViewStage.FAILED && LocalizeText('navigator.password.retryinfo') } +
} +
+ + setPassword(event.target.value) } /> +
+
+ + +
+ + ); +} diff --git a/src/views/navigator/lock/password/NavigatorLockPasswordView.types.ts b/src/views/navigator/lock/password/NavigatorLockPasswordView.types.ts new file mode 100644 index 00000000..d0d1707f --- /dev/null +++ b/src/views/navigator/lock/password/NavigatorLockPasswordView.types.ts @@ -0,0 +1,8 @@ +import { NavigatorLockViewStage } from '../NavigatorLockView.types'; + +export interface NavigatorLockPasswordViewProps +{ + stage: NavigatorLockViewStage; + onVisitRoom: (password?: string) => void; + onHideLock: () => void; +} diff --git a/src/views/navigator/result-lists/NavigatorResultListsView.tsx b/src/views/navigator/result-lists/NavigatorResultListsView.tsx index aeaffdca..2d661ca7 100644 --- a/src/views/navigator/result-lists/NavigatorResultListsView.tsx +++ b/src/views/navigator/result-lists/NavigatorResultListsView.tsx @@ -9,7 +9,7 @@ export function NavigatorResultListsView(props: NavigatorResultListsViewProps):
{ resultLists && resultLists.length && resultLists.map((resultList, index) => { - return + return }) }
diff --git a/src/views/navigator/result-lists/result-list/NavigatorResultListView.tsx b/src/views/navigator/result-lists/result-list/NavigatorResultListView.tsx index 7c68c114..2bb04848 100644 --- a/src/views/navigator/result-lists/result-list/NavigatorResultListView.tsx +++ b/src/views/navigator/result-lists/result-list/NavigatorResultListView.tsx @@ -6,7 +6,7 @@ import { NavigatorResultView } from './result/NavigatorResultView'; export function NavigatorResultListView(props: NavigatorResultListViewProps): JSX.Element { - const { resultList = null } = props; + const { resultList = null, isLast = false } = props; const [ isExtended, setIsExtended ] = useState(true); @@ -37,7 +37,7 @@ export function NavigatorResultListView(props: NavigatorResultListViewProps): JS } return ( -
+
{ LocalizeText(getListCode()) }
@@ -47,7 +47,7 @@ export function NavigatorResultListView(props: NavigatorResultListViewProps): JS return }) } -
+ { !isLast &&
}
); } diff --git a/src/views/navigator/result-lists/result-list/NavigatorResultListView.types.ts b/src/views/navigator/result-lists/result-list/NavigatorResultListView.types.ts index 97d5de06..f1a2b0de 100644 --- a/src/views/navigator/result-lists/result-list/NavigatorResultListView.types.ts +++ b/src/views/navigator/result-lists/result-list/NavigatorResultListView.types.ts @@ -3,4 +3,5 @@ import { NavigatorSearchResultList } from 'nitro-renderer'; export interface NavigatorResultListViewProps { resultList: NavigatorSearchResultList; + isLast: boolean; } diff --git a/src/views/navigator/result-lists/result-list/result/NavigatorResultView.tsx b/src/views/navigator/result-lists/result-list/result/NavigatorResultView.tsx index e5dffc3e..1c77393f 100644 --- a/src/views/navigator/result-lists/result-list/result/NavigatorResultView.tsx +++ b/src/views/navigator/result-lists/result-list/result/NavigatorResultView.tsx @@ -1,7 +1,7 @@ import classNames from 'classnames'; -import { RoomDataParser, RoomInfoComposer } from 'nitro-renderer'; +import { RoomDataParser } from 'nitro-renderer'; import React from 'react'; -import { SendMessageHook } from '../../../../../hooks/messages/message-event'; +import { NavigatorContext } from '../../../NavigatorView'; import { NavigatorResultViewProps } from './NavigatorResultView.types'; export function NavigatorResultView(props: NavigatorResultViewProps): JSX.Element @@ -36,32 +36,31 @@ export function NavigatorResultView(props: NavigatorResultViewProps): JSX.Elemen console.log('info'); } - function enterRoom(): void - { - SendMessageHook(new RoomInfoComposer(result.roomId, false, true)); - } - return ( -
-
-
-
{ result.userCount }
-
-
{ result.roomName }
- { result.doorMode !== RoomDataParser.OPEN_STATE && -
- + + { navigatorContext => { + return
navigatorContext.onTryVisitRoom(result) }> +
+
+
{ result.userCount }
+
+
{ result.roomName }
+ { result.doorMode !== RoomDataParser.OPEN_STATE && +
+ +
+ } + { result.habboGroupId > 0 && +
+ +
+ } +
+ +
+
- } - { result.habboGroupId > 0 && -
- -
- } -
- -
-
-
+ }} + ); }