mirror of
https://github.com/billsonnn/nitro-react.git
synced 2024-11-23 14:40:50 +01:00
Merge branch '@update/navigator' into dev
This commit is contained in:
commit
c8fe1934f1
@ -14,7 +14,7 @@
|
|||||||
"@fortawesome/fontawesome-svg-core": "^6.1.0",
|
"@fortawesome/fontawesome-svg-core": "^6.1.0",
|
||||||
"@fortawesome/free-solid-svg-icons": "^6.1.0",
|
"@fortawesome/free-solid-svg-icons": "^6.1.0",
|
||||||
"@fortawesome/react-fontawesome": "^0.1.17",
|
"@fortawesome/react-fontawesome": "^0.1.17",
|
||||||
"@nitrots/nitro-renderer": "^1.1.13",
|
"@nitrots/nitro-renderer": "^1.1.14",
|
||||||
"animate.css": "^4.1.1",
|
"animate.css": "^4.1.1",
|
||||||
"classnames": "^2.3.1",
|
"classnames": "^2.3.1",
|
||||||
"cross-env": "^7.0.3",
|
"cross-env": "^7.0.3",
|
||||||
|
@ -23,7 +23,10 @@
|
|||||||
<script>
|
<script>
|
||||||
const NitroConfig = {
|
const NitroConfig = {
|
||||||
"config.urls": [ '/renderer-config.json', '/ui-config.json' ],
|
"config.urls": [ '/renderer-config.json', '/ui-config.json' ],
|
||||||
"sso.ticket": (new URLSearchParams(window.location.search).get('sso') || null)
|
"sso.ticket": (new URLSearchParams(window.location.search).get('sso') || null),
|
||||||
|
"forward.type": (new URLSearchParams(window.location.search).get('room') ? 2 : -1),
|
||||||
|
"forward.id": (new URLSearchParams(window.location.search).get('room') || 0),
|
||||||
|
"friend.id": (new URLSearchParams(window.location.search).get('friend') || 0),
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
|
@ -179,6 +179,7 @@ $nitro-card-tabs-height: 33px;
|
|||||||
|
|
||||||
.nitro-card-tabs {
|
.nitro-card-tabs {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
min-height: $nitro-card-tabs-height;
|
||||||
max-height: $nitro-card-tabs-height;
|
max-height: $nitro-card-tabs-height;
|
||||||
border-bottom: $nav-tabs-border-width solid $nav-tabs-border-color;
|
border-bottom: $nav-tabs-border-width solid $nav-tabs-border-color;
|
||||||
}
|
}
|
||||||
|
@ -171,7 +171,7 @@ export const CatalogPurchaseWidgetView: FC<CatalogPurchaseWidgetViewProps> = pro
|
|||||||
switch(purchaseState)
|
switch(purchaseState)
|
||||||
{
|
{
|
||||||
case CatalogPurchaseState.CONFIRM:
|
case CatalogPurchaseState.CONFIRM:
|
||||||
return <Button variant='warning' onClick={ event => purchase() }>{ LocalizeText('catalog.marketplace.confirm_title') }</Button>;
|
return <Button variant="warning" onClick={ event => purchase() }>{ LocalizeText('catalog.marketplace.confirm_title') }</Button>;
|
||||||
case CatalogPurchaseState.PURCHASE:
|
case CatalogPurchaseState.PURCHASE:
|
||||||
return <Button disabled><LayoutLoadingSpinnerView /></Button>;
|
return <Button disabled><LayoutLoadingSpinnerView /></Button>;
|
||||||
case CatalogPurchaseState.FAILED:
|
case CatalogPurchaseState.FAILED:
|
||||||
|
@ -93,14 +93,12 @@ export const GroupsView: FC<{}> = props =>
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<GroupsContextProvider value={ { groupCustomize, setGroupCustomize } }>
|
<GroupsContextProvider value={ { groupCustomize, setGroupCustomize } }>
|
||||||
<div className="nitro-groups">
|
{ isCreatorVisible &&
|
||||||
{ isCreatorVisible &&
|
<GroupCreatorView onClose={ () => setCreatorVisible(false) } /> }
|
||||||
<GroupCreatorView onClose={ () => setCreatorVisible(false) } /> }
|
{ !isCreatorVisible &&
|
||||||
{ !isCreatorVisible &&
|
<GroupManagerView /> }
|
||||||
<GroupManagerView /> }
|
<GroupMembersView />
|
||||||
<GroupMembersView />
|
<GroupInformationStandaloneView />
|
||||||
<GroupInformationStandaloneView />
|
|
||||||
</div>
|
|
||||||
</GroupsContextProvider>
|
</GroupsContextProvider>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -1,15 +1,32 @@
|
|||||||
import { createContext, Dispatch, FC, ProviderProps, useContext } from 'react';
|
import { NavigatorCategoryDataParser, NavigatorSearchResultSet, NavigatorTopLevelContext } from '@nitrots/nitro-renderer';
|
||||||
import { INavigatorAction, INavigatorState } from './reducers/NavigatorReducer';
|
import { createContext, Dispatch, FC, ProviderProps, SetStateAction, useContext } from 'react';
|
||||||
|
import { NavigatorData } from './common/NavigatorData';
|
||||||
|
|
||||||
interface INavigatorContext
|
interface INavigatorContext
|
||||||
{
|
{
|
||||||
navigatorState: INavigatorState;
|
categories: NavigatorCategoryDataParser[];
|
||||||
dispatchNavigatorState: Dispatch<INavigatorAction>;
|
setCategories: Dispatch<SetStateAction<NavigatorCategoryDataParser[]>>;
|
||||||
|
topLevelContext: NavigatorTopLevelContext;
|
||||||
|
setTopLevelContext: Dispatch<SetStateAction<NavigatorTopLevelContext>>;
|
||||||
|
topLevelContexts: NavigatorTopLevelContext[];
|
||||||
|
setTopLevelContexts: Dispatch<SetStateAction<NavigatorTopLevelContext[]>>;
|
||||||
|
navigatorData: NavigatorData;
|
||||||
|
setNavigatorData: Dispatch<SetStateAction<NavigatorData>>;
|
||||||
|
searchResult: NavigatorSearchResultSet;
|
||||||
|
setSearchResult: Dispatch<SetStateAction<NavigatorSearchResultSet>>;
|
||||||
}
|
}
|
||||||
|
|
||||||
const NavigatorContext = createContext<INavigatorContext>({
|
const NavigatorContext = createContext<INavigatorContext>({
|
||||||
navigatorState: null,
|
categories: null,
|
||||||
dispatchNavigatorState: null
|
setCategories: null,
|
||||||
|
topLevelContext: null,
|
||||||
|
setTopLevelContext: null,
|
||||||
|
topLevelContexts: null,
|
||||||
|
setTopLevelContexts: null,
|
||||||
|
navigatorData: null,
|
||||||
|
setNavigatorData: null,
|
||||||
|
searchResult: null,
|
||||||
|
setSearchResult: null
|
||||||
});
|
});
|
||||||
|
|
||||||
export const NavigatorContextProvider: FC<ProviderProps<INavigatorContext>> = props =>
|
export const NavigatorContextProvider: FC<ProviderProps<INavigatorContext>> = props =>
|
||||||
|
@ -1,14 +1,38 @@
|
|||||||
import { CantConnectMessageParser, GenericErrorEvent, GetGuestRoomResultEvent, LegacyExternalInterface, NavigatorCategoriesComposer, NavigatorCategoriesEvent, NavigatorHomeRoomEvent, NavigatorMetadataEvent, NavigatorOpenRoomCreatorEvent, NavigatorSearchEvent, NavigatorSettingsComposer, RoomCreatedEvent, RoomDataParser, RoomDoorbellAcceptedEvent, RoomDoorbellEvent, RoomDoorbellRejectedEvent, RoomEnterErrorEvent, RoomEntryInfoMessageEvent, RoomForwardEvent, RoomInfoComposer, RoomScoreEvent, RoomSettingsUpdatedEvent, UserInfoEvent } from '@nitrots/nitro-renderer';
|
import { CanCreateRoomEventEvent, CantConnectMessageParser, FollowFriendMessageComposer, GenericErrorEvent, GetGuestRoomResultEvent, HabboWebTools, LegacyExternalInterface, NavigatorCategoriesComposer, NavigatorCategoriesEvent, NavigatorHomeRoomEvent, NavigatorMetadataEvent, NavigatorOpenRoomCreatorEvent, NavigatorSearchEvent, NavigatorSettingsComposer, RoomCreatedEvent, RoomDataParser, RoomDoorbellAcceptedEvent, RoomDoorbellEvent, RoomDoorbellRejectedEvent, RoomEnterErrorEvent, RoomEntryInfoMessageEvent, RoomForwardEvent, RoomInfoComposer, RoomScoreEvent, RoomSettingsUpdatedEvent, SecurityLevel, UserInfoEvent, UserPermissionsEvent } from '@nitrots/nitro-renderer';
|
||||||
import { FC, useCallback } from 'react';
|
import { FC, useCallback } from 'react';
|
||||||
import { CreateRoomSession, GetSessionDataManager, LocalizeText, NotificationAlertType, NotificationUtilities, SendMessageComposer, VisitDesktop } from '../../api';
|
import { CreateLinkEvent, CreateRoomSession, GetConfiguration, GetSessionDataManager, LocalizeText, NotificationAlertType, NotificationUtilities, SendMessageComposer, TryVisitRoom, VisitDesktop } from '../../api';
|
||||||
import { NavigatorEvent, UpdateDoorStateEvent } from '../../events';
|
import { UpdateDoorStateEvent } from '../../events';
|
||||||
import { DispatchUiEvent, UseMessageEventHook } from '../../hooks';
|
import { BatchUpdates, DispatchUiEvent, UseMessageEventHook } from '../../hooks';
|
||||||
import { useNavigatorContext } from './NavigatorContext';
|
import { useNavigatorContext } from './NavigatorContext';
|
||||||
import { NavigatorActions } from './reducers/NavigatorReducer';
|
|
||||||
|
|
||||||
export const NavigatorMessageHandler: FC<{}> = props =>
|
export const NavigatorMessageHandler: FC<{}> = props =>
|
||||||
{
|
{
|
||||||
const { navigatorState = null, dispatchNavigatorState = null } = useNavigatorContext();
|
const { setCategories = null, setTopLevelContext = null, topLevelContexts = null, setTopLevelContexts = null, setNavigatorData = null, setSearchResult = null } = useNavigatorContext();
|
||||||
|
|
||||||
|
const onRoomSettingsUpdatedEvent = useCallback((event: RoomSettingsUpdatedEvent) =>
|
||||||
|
{
|
||||||
|
const parser = event.getParser();
|
||||||
|
|
||||||
|
SendMessageComposer(new RoomInfoComposer(parser.roomId, false, false));
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
UseMessageEventHook(RoomSettingsUpdatedEvent, onRoomSettingsUpdatedEvent);
|
||||||
|
|
||||||
|
const onCanCreateRoomEventEvent = useCallback((event: CanCreateRoomEventEvent) =>
|
||||||
|
{
|
||||||
|
const parser = event.getParser();
|
||||||
|
|
||||||
|
if(parser.canCreate)
|
||||||
|
{
|
||||||
|
// show room event cvreate
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
NotificationUtilities.simpleAlert(LocalizeText(`navigator.cannotcreateevent.error.${ parser.errorCode }`), null, null, null, LocalizeText('navigator.cannotcreateevent.title'));
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
UseMessageEventHook(CanCreateRoomEventEvent, onCanCreateRoomEventEvent);
|
||||||
|
|
||||||
const onUserInfoEvent = useCallback((event: UserInfoEvent) =>
|
const onUserInfoEvent = useCallback((event: UserInfoEvent) =>
|
||||||
{
|
{
|
||||||
@ -16,32 +40,51 @@ export const NavigatorMessageHandler: FC<{}> = props =>
|
|||||||
SendMessageComposer(new NavigatorSettingsComposer());
|
SendMessageComposer(new NavigatorSettingsComposer());
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
const onUserPermissionsEvent = useCallback((event: UserPermissionsEvent) =>
|
||||||
|
{
|
||||||
|
const parser = event.getParser();
|
||||||
|
|
||||||
|
setNavigatorData(prevValue =>
|
||||||
|
{
|
||||||
|
const newValue = { ...prevValue };
|
||||||
|
|
||||||
|
newValue.eventMod = (parser.securityLevel >= SecurityLevel.MODERATOR);
|
||||||
|
newValue.roomPicker = (parser.securityLevel >= SecurityLevel.COMMUNITY);
|
||||||
|
|
||||||
|
return newValue;
|
||||||
|
});
|
||||||
|
}, [ setNavigatorData ]);
|
||||||
|
|
||||||
const onRoomForwardEvent = useCallback((event: RoomForwardEvent) =>
|
const onRoomForwardEvent = useCallback((event: RoomForwardEvent) =>
|
||||||
{
|
{
|
||||||
const parser = event.getParser();
|
const parser = event.getParser();
|
||||||
|
|
||||||
SendMessageComposer(new RoomInfoComposer(parser.roomId, false, true));
|
TryVisitRoom(parser.roomId);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const onRoomEntryInfoMessageEvent = useCallback((event: RoomEntryInfoMessageEvent) =>
|
const onRoomEntryInfoMessageEvent = useCallback((event: RoomEntryInfoMessageEvent) =>
|
||||||
{
|
{
|
||||||
const parser = event.getParser();
|
const parser = event.getParser();
|
||||||
|
|
||||||
const roomInfoData = navigatorState.roomInfoData;
|
setNavigatorData(prevValue =>
|
||||||
roomInfoData.currentRoomOwner = parser.isOwner;
|
{
|
||||||
roomInfoData.currentRoomId = parser.roomId;
|
const newValue = { ...prevValue };
|
||||||
|
|
||||||
dispatchNavigatorState({
|
newValue.enteredGuestRoom = null;
|
||||||
type: NavigatorActions.SET_ROOM_INFO_DATA,
|
newValue.currentRoomOwner = parser.isOwner;
|
||||||
payload: {
|
newValue.currentRoomId = parser.roomId;
|
||||||
roomInfoData: roomInfoData
|
|
||||||
}
|
return newValue;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// close room info
|
||||||
|
// close room settings
|
||||||
|
// close room filter
|
||||||
|
|
||||||
SendMessageComposer(new RoomInfoComposer(parser.roomId, true, false));
|
SendMessageComposer(new RoomInfoComposer(parser.roomId, true, false));
|
||||||
|
|
||||||
if(LegacyExternalInterface.available) LegacyExternalInterface.call('legacyTrack', 'navigator', 'private', [ parser.roomId ]);
|
if(LegacyExternalInterface.available) LegacyExternalInterface.call('legacyTrack', 'navigator', 'private', [ parser.roomId ]);
|
||||||
}, [ navigatorState, dispatchNavigatorState ]);
|
}, [ setNavigatorData ]);
|
||||||
|
|
||||||
const onGetGuestRoomResultEvent = useCallback((event: GetGuestRoomResultEvent) =>
|
const onGetGuestRoomResultEvent = useCallback((event: GetGuestRoomResultEvent) =>
|
||||||
{
|
{
|
||||||
@ -49,15 +92,29 @@ export const NavigatorMessageHandler: FC<{}> = props =>
|
|||||||
|
|
||||||
if(parser.roomEnter)
|
if(parser.roomEnter)
|
||||||
{
|
{
|
||||||
const roomInfoData = navigatorState.roomInfoData;
|
setNavigatorData(prevValue =>
|
||||||
roomInfoData.enteredGuestRoom = parser.data;
|
{
|
||||||
|
const newValue = { ...prevValue };
|
||||||
|
|
||||||
dispatchNavigatorState({
|
newValue.enteredGuestRoom = parser.data;
|
||||||
type: NavigatorActions.SET_ROOM_INFO_DATA,
|
newValue.currentRoomIsStaffPick = parser.staffPick;
|
||||||
payload: {
|
|
||||||
roomInfoData: roomInfoData
|
const isCreated = (newValue.createdFlatId === parser.data.roomId);
|
||||||
}
|
|
||||||
});
|
if(!isCreated && parser.data.displayRoomEntryAd)
|
||||||
|
{
|
||||||
|
if(GetConfiguration<boolean>('roomenterad.habblet.enabled', false)) HabboWebTools.openRoomEnterAd();
|
||||||
|
}
|
||||||
|
|
||||||
|
newValue.createdFlatId = 0;
|
||||||
|
|
||||||
|
if(newValue.enteredGuestRoom && (newValue.enteredGuestRoom.habboGroupId > 0))
|
||||||
|
{
|
||||||
|
// close event info
|
||||||
|
}
|
||||||
|
|
||||||
|
return newValue;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
else if(parser.roomForward)
|
else if(parser.roomForward)
|
||||||
{
|
{
|
||||||
@ -74,26 +131,38 @@ export const NavigatorMessageHandler: FC<{}> = props =>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if((parser.data.doorMode === RoomDataParser.NOOB_STATE) && !GetSessionDataManager().isAmbassador && !GetSessionDataManager().isRealNoob && !GetSessionDataManager().isModerator) return;
|
||||||
|
|
||||||
CreateRoomSession(parser.data.roomId);
|
CreateRoomSession(parser.data.roomId);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
const roomInfoData = navigatorState.roomInfoData;
|
setNavigatorData(prevValue =>
|
||||||
roomInfoData.enteredGuestRoom = parser.data;
|
{
|
||||||
|
const newValue = { ...prevValue };
|
||||||
|
|
||||||
dispatchNavigatorState({
|
newValue.enteredGuestRoom = parser.data;
|
||||||
type: NavigatorActions.SET_ROOM_INFO_DATA,
|
newValue.currentRoomIsStaffPick = parser.staffPick;
|
||||||
payload: {
|
|
||||||
roomInfoData: roomInfoData
|
return newValue;
|
||||||
}
|
});
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}, [ dispatchNavigatorState, navigatorState ]);
|
}, [ setNavigatorData ]);
|
||||||
|
|
||||||
const onRoomScoreEvent = useCallback((event: RoomScoreEvent) =>
|
const onRoomScoreEvent = useCallback((event: RoomScoreEvent) =>
|
||||||
{
|
{
|
||||||
const parser = event.getParser();
|
const parser = event.getParser();
|
||||||
}, [ ]);
|
|
||||||
|
setNavigatorData(prevValue =>
|
||||||
|
{
|
||||||
|
const newValue = { ...prevValue };
|
||||||
|
|
||||||
|
newValue.currentRoomRating = parser.totalLikes;
|
||||||
|
newValue.canRate = parser.canLike;
|
||||||
|
|
||||||
|
return newValue;
|
||||||
|
});
|
||||||
|
}, [ setNavigatorData ]);
|
||||||
|
|
||||||
const onRoomDoorbellEvent = useCallback((event: RoomDoorbellEvent) =>
|
const onRoomDoorbellEvent = useCallback((event: RoomDoorbellEvent) =>
|
||||||
{
|
{
|
||||||
@ -141,37 +210,57 @@ export const NavigatorMessageHandler: FC<{}> = props =>
|
|||||||
{
|
{
|
||||||
const parser = event.getParser();
|
const parser = event.getParser();
|
||||||
|
|
||||||
dispatchNavigatorState({
|
BatchUpdates(() =>
|
||||||
type: NavigatorActions.SET_TOP_LEVEL_CONTEXTS,
|
{
|
||||||
payload: {
|
setTopLevelContexts(parser.topLevelContexts);
|
||||||
topLevelContexts: parser.topLevelContexts
|
setTopLevelContext(parser.topLevelContexts.length ? parser.topLevelContexts[0] : null);
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}, [ dispatchNavigatorState ]);
|
}, [ setTopLevelContexts, setTopLevelContext ]);
|
||||||
|
|
||||||
const onNavigatorSearchEvent = useCallback((event: NavigatorSearchEvent) =>
|
const onNavigatorSearchEvent = useCallback((event: NavigatorSearchEvent) =>
|
||||||
{
|
{
|
||||||
const parser = event.getParser();
|
const parser = event.getParser();
|
||||||
|
|
||||||
dispatchNavigatorState({
|
BatchUpdates(() =>
|
||||||
type: NavigatorActions.SET_SEARCH_RESULT,
|
{
|
||||||
payload: {
|
setTopLevelContext(prevValue =>
|
||||||
searchResult: parser.result
|
{
|
||||||
}
|
let newValue = prevValue;
|
||||||
|
|
||||||
|
if(!newValue) newValue = ((topLevelContexts && topLevelContexts.length && topLevelContexts[0]) || null);
|
||||||
|
|
||||||
|
if(!newValue) return null;
|
||||||
|
|
||||||
|
if((parser.result.code !== newValue.code) && topLevelContexts && topLevelContexts.length)
|
||||||
|
{
|
||||||
|
for(const context of topLevelContexts)
|
||||||
|
{
|
||||||
|
if(context.code !== parser.result.code) continue;
|
||||||
|
|
||||||
|
newValue = context;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for(const context of topLevelContexts)
|
||||||
|
{
|
||||||
|
if(context.code !== parser.result.code) continue;
|
||||||
|
|
||||||
|
newValue = context;
|
||||||
|
}
|
||||||
|
|
||||||
|
return newValue;
|
||||||
|
});
|
||||||
|
|
||||||
|
setSearchResult(parser.result);
|
||||||
});
|
});
|
||||||
}, [ dispatchNavigatorState ]);
|
}, [ topLevelContexts, setTopLevelContext, setSearchResult ]);
|
||||||
|
|
||||||
const onNavigatorCategoriesEvent = useCallback((event: NavigatorCategoriesEvent) =>
|
const onNavigatorCategoriesEvent = useCallback((event: NavigatorCategoriesEvent) =>
|
||||||
{
|
{
|
||||||
const parser = event.getParser();
|
const parser = event.getParser();
|
||||||
|
|
||||||
dispatchNavigatorState({
|
setCategories(parser.categories);
|
||||||
type: NavigatorActions.SET_CATEGORIES,
|
}, [ setCategories ]);
|
||||||
payload: {
|
|
||||||
categories: parser.categories
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}, [ dispatchNavigatorState ]);
|
|
||||||
|
|
||||||
const onRoomCreatedEvent = useCallback((event: RoomCreatedEvent) =>
|
const onRoomCreatedEvent = useCallback((event: RoomCreatedEvent) =>
|
||||||
{
|
{
|
||||||
@ -184,20 +273,63 @@ export const NavigatorMessageHandler: FC<{}> = props =>
|
|||||||
{
|
{
|
||||||
const parser = event.getParser();
|
const parser = event.getParser();
|
||||||
|
|
||||||
dispatchNavigatorState({
|
let prevSettingsReceived = false;
|
||||||
type: NavigatorActions.SET_HOME_ROOM_ID,
|
|
||||||
payload: {
|
setNavigatorData(prevValue =>
|
||||||
homeRoomId: parser.homeRoomId
|
{
|
||||||
|
prevSettingsReceived = prevValue.settingsReceived;
|
||||||
|
|
||||||
|
const newValue = { ...prevValue };
|
||||||
|
|
||||||
|
newValue.homeRoomId = parser.homeRoomId;
|
||||||
|
newValue.settingsReceived = true;
|
||||||
|
|
||||||
|
return newValue;
|
||||||
|
});
|
||||||
|
|
||||||
|
if(prevSettingsReceived)
|
||||||
|
{
|
||||||
|
// refresh room info window
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let forwardType = -1;
|
||||||
|
let forwardId = -1;
|
||||||
|
|
||||||
|
if(GetConfiguration<string>('friend.id') !== undefined)
|
||||||
|
{
|
||||||
|
forwardType = 0;
|
||||||
|
SendMessageComposer(new FollowFriendMessageComposer(parseInt(GetConfiguration<string>('friend.id'))));
|
||||||
|
}
|
||||||
|
|
||||||
|
if((GetConfiguration<number>('forward.type') !== undefined) && (GetConfiguration<number>('forward.id') !== undefined))
|
||||||
|
{
|
||||||
|
forwardType = parseInt(GetConfiguration<string>('forward.type'));
|
||||||
|
forwardId = parseInt(GetConfiguration<string>('forward.id'))
|
||||||
|
}
|
||||||
|
|
||||||
|
if(forwardType === 2)
|
||||||
|
{
|
||||||
|
TryVisitRoom(forwardId);
|
||||||
|
}
|
||||||
|
|
||||||
|
else if((forwardType === -1) && (parser.roomIdToEnter > 0))
|
||||||
|
{
|
||||||
|
CreateLinkEvent('navigator/close');
|
||||||
|
CreateRoomSession(parser.roomIdToEnter);
|
||||||
|
|
||||||
|
if(parser.roomIdToEnter !== parser.homeRoomId)
|
||||||
|
{
|
||||||
|
CreateLinkEvent('navigator/close');
|
||||||
|
CreateRoomSession(parser.roomIdToEnter);
|
||||||
}
|
}
|
||||||
});
|
else
|
||||||
}, [ dispatchNavigatorState ]);
|
{
|
||||||
|
CreateLinkEvent('navigator/close');
|
||||||
const onRoomSettingsUpdatedEvent = useCallback((event: RoomSettingsUpdatedEvent) =>
|
CreateRoomSession(parser.homeRoomId);
|
||||||
{
|
}
|
||||||
const parser = event.getParser();
|
}
|
||||||
|
}, [ setNavigatorData ]);
|
||||||
SendMessageComposer(new RoomInfoComposer(parser.roomId, false, false));
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
const onRoomEnterErrorEvent = useCallback((event: RoomEnterErrorEvent) =>
|
const onRoomEnterErrorEvent = useCallback((event: RoomEnterErrorEvent) =>
|
||||||
{
|
{
|
||||||
@ -226,12 +358,13 @@ export const NavigatorMessageHandler: FC<{}> = props =>
|
|||||||
VisitDesktop();
|
VisitDesktop();
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const onRoomCreatorEvent = useCallback((event: RoomEnterErrorEvent) =>
|
const onRoomCreatorEvent = useCallback((event: NavigatorOpenRoomCreatorEvent) =>
|
||||||
{
|
{
|
||||||
DispatchUiEvent(new NavigatorEvent(NavigatorEvent.SHOW_ROOM_CREATOR));
|
CreateLinkEvent('navigator/show');
|
||||||
},[]);
|
}, []);
|
||||||
|
|
||||||
UseMessageEventHook(UserInfoEvent, onUserInfoEvent);
|
UseMessageEventHook(UserInfoEvent, onUserInfoEvent);
|
||||||
|
UseMessageEventHook(UserPermissionsEvent, onUserPermissionsEvent);
|
||||||
UseMessageEventHook(RoomForwardEvent, onRoomForwardEvent);
|
UseMessageEventHook(RoomForwardEvent, onRoomForwardEvent);
|
||||||
UseMessageEventHook(RoomEntryInfoMessageEvent, onRoomEntryInfoMessageEvent);
|
UseMessageEventHook(RoomEntryInfoMessageEvent, onRoomEntryInfoMessageEvent);
|
||||||
UseMessageEventHook(GetGuestRoomResultEvent, onGetGuestRoomResultEvent);
|
UseMessageEventHook(GetGuestRoomResultEvent, onGetGuestRoomResultEvent);
|
||||||
@ -245,7 +378,6 @@ export const NavigatorMessageHandler: FC<{}> = props =>
|
|||||||
UseMessageEventHook(NavigatorCategoriesEvent, onNavigatorCategoriesEvent);
|
UseMessageEventHook(NavigatorCategoriesEvent, onNavigatorCategoriesEvent);
|
||||||
UseMessageEventHook(RoomCreatedEvent, onRoomCreatedEvent);
|
UseMessageEventHook(RoomCreatedEvent, onRoomCreatedEvent);
|
||||||
UseMessageEventHook(NavigatorHomeRoomEvent, onNavigatorHomeRoomEvent);
|
UseMessageEventHook(NavigatorHomeRoomEvent, onNavigatorHomeRoomEvent);
|
||||||
UseMessageEventHook(RoomSettingsUpdatedEvent, onRoomSettingsUpdatedEvent);
|
|
||||||
UseMessageEventHook(RoomEnterErrorEvent, onRoomEnterErrorEvent);
|
UseMessageEventHook(RoomEnterErrorEvent, onRoomEnterErrorEvent);
|
||||||
UseMessageEventHook(NavigatorOpenRoomCreatorEvent, onRoomCreatorEvent);
|
UseMessageEventHook(NavigatorOpenRoomCreatorEvent, onRoomCreatorEvent);
|
||||||
|
|
||||||
|
@ -1,64 +1,52 @@
|
|||||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||||
import { ConvertGlobalRoomIdMessageComposer, HabboWebTools, ILinkEventTracker, LegacyExternalInterface, NavigatorInitComposer, NavigatorSearchComposer, RoomDataParser, RoomSessionEvent } from '@nitrots/nitro-renderer';
|
import { ConvertGlobalRoomIdMessageComposer, HabboWebTools, ILinkEventTracker, LegacyExternalInterface, NavigatorCategoryDataParser, NavigatorInitComposer, NavigatorSearchComposer, NavigatorSearchResultSet, NavigatorTopLevelContext, RoomDataParser, RoomSessionEvent } from '@nitrots/nitro-renderer';
|
||||||
import { FC, useCallback, useEffect, useMemo, useReducer, useState } from 'react';
|
import { FC, useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
||||||
import { AddEventLinkTracker, CreateLinkEvent, GoToDesktop, LocalizeText, RemoveLinkEventTracker, SendMessageComposer, TryVisitRoom } from '../../api';
|
import { AddEventLinkTracker, GoToDesktop, LocalizeText, RemoveLinkEventTracker, SendMessageComposer, TryVisitRoom } from '../../api';
|
||||||
import { Column, NitroCardContentView, NitroCardHeaderView, NitroCardTabsItemView, NitroCardTabsView, NitroCardView } from '../../common';
|
import { Base, Column, NitroCardContentView, NitroCardHeaderView, NitroCardTabsItemView, NitroCardTabsView, NitroCardView } from '../../common';
|
||||||
import { NavigatorEvent, UpdateDoorStateEvent } from '../../events';
|
import { UpdateDoorStateEvent } from '../../events';
|
||||||
import { BatchUpdates, UseMountEffect, UseRoomSessionManagerEvent, UseUiEvent } from '../../hooks';
|
import { BatchUpdates, UseRoomSessionManagerEvent, useSharedState, UseUiEvent } from '../../hooks';
|
||||||
|
import { NavigatorData } from './common/NavigatorData';
|
||||||
import { NavigatorContextProvider } from './NavigatorContext';
|
import { NavigatorContextProvider } from './NavigatorContext';
|
||||||
import { NavigatorMessageHandler } from './NavigatorMessageHandler';
|
import { NavigatorMessageHandler } from './NavigatorMessageHandler';
|
||||||
import { initialNavigator, NavigatorActions, NavigatorReducer } from './reducers/NavigatorReducer';
|
import { NavigatorRoomCreatorView } from './views/NavigatorRoomCreatorView';
|
||||||
import { NavigatorRoomCreatorView } from './views/creator/NavigatorRoomCreatorView';
|
import { NavigatorRoomDoorbellView } from './views/NavigatorRoomDoorbellView';
|
||||||
import { NavigatorRoomDoorbellView } from './views/room-doorbell/NavigatorRoomDoorbellView';
|
import { NavigatorRoomInfoView } from './views/NavigatorRoomInfoView';
|
||||||
import { NavigatorRoomInfoView } from './views/room-info/NavigatorRoomInfoView';
|
import { NavigatorRoomLinkView } from './views/NavigatorRoomLinkView';
|
||||||
import { NavigatorRoomLinkView } from './views/room-link/NavigatorRoomLinkView';
|
import { NavigatorRoomPasswordView } from './views/NavigatorRoomPasswordView';
|
||||||
import { NavigatorRoomPasswordView } from './views/room-password/NavigatorRoomPasswordView';
|
|
||||||
import { NavigatorRoomSettingsView } from './views/room-settings/NavigatorRoomSettingsView';
|
import { NavigatorRoomSettingsView } from './views/room-settings/NavigatorRoomSettingsView';
|
||||||
import { NavigatorSearchResultView } from './views/search-result/NavigatorSearchResultView';
|
import { NavigatorSearchResultView } from './views/search/NavigatorSearchResultView';
|
||||||
import { LAST_SEARCH, NavigatorSearchView } from './views/search/NavigatorSearchView';
|
import { NavigatorSearchView } from './views/search/NavigatorSearchView';
|
||||||
|
|
||||||
export const NavigatorView: FC<{}> = props =>
|
export const NavigatorView: FC<{}> = props =>
|
||||||
{
|
{
|
||||||
const [ isVisible, setIsVisible ] = useState(false);
|
const [ isVisible, setIsVisible ] = useState(false);
|
||||||
|
const [ isReady, setIsReady ] = useState(false);
|
||||||
const [ isCreatorOpen, setCreatorOpen ] = useState(false);
|
const [ isCreatorOpen, setCreatorOpen ] = useState(false);
|
||||||
const [ isRoomInfoOpen, setRoomInfoOpen ] = useState(false);
|
const [ isRoomInfoOpen, setRoomInfoOpen ] = useState(false);
|
||||||
const [ isRoomLinkOpen, setRoomLinkOpen ] = useState(false);
|
const [ isRoomLinkOpen, setRoomLinkOpen ] = useState(false);
|
||||||
|
const [ isLoading, setIsLoading ] = useState(false);
|
||||||
|
const [ needsInit, setNeedsInit ] = useState(true);
|
||||||
|
const [ needsSearch, setNeedsSearch ] = useState(false);
|
||||||
|
const [ categories, setCategories ] = useState<NavigatorCategoryDataParser[]>(null);
|
||||||
|
const [ topLevelContext, setTopLevelContext ] = useState<NavigatorTopLevelContext>(null);
|
||||||
|
const [ topLevelContexts, setTopLevelContexts ] = useState<NavigatorTopLevelContext[]>(null);
|
||||||
|
const [ navigatorData, setNavigatorData ] = useSharedState<NavigatorData>('@navigatorData', {
|
||||||
|
settingsReceived: false,
|
||||||
|
homeRoomId: 0,
|
||||||
|
enteredGuestRoom: null,
|
||||||
|
currentRoomOwner: false,
|
||||||
|
currentRoomId: 0,
|
||||||
|
currentRoomIsStaffPick: false,
|
||||||
|
createdFlatId: 0,
|
||||||
|
avatarId: 0,
|
||||||
|
roomPicker: false,
|
||||||
|
eventMod: false,
|
||||||
|
currentRoomRating: 0,
|
||||||
|
canRate: true
|
||||||
|
});
|
||||||
|
const [ searchResult, setSearchResult ] = useState<NavigatorSearchResultSet>(null);
|
||||||
const [ pendingDoorState, setPendingDoorState ] = useState<{ roomData: RoomDataParser, state: string }>(null);
|
const [ pendingDoorState, setPendingDoorState ] = useState<{ roomData: RoomDataParser, state: string }>(null);
|
||||||
const [ navigatorState, dispatchNavigatorState ] = useReducer(NavigatorReducer, initialNavigator);
|
const pendingSearch = useRef<{ value: string, code: string }>(null);
|
||||||
const { needsNavigatorUpdate = true, topLevelContext = null, topLevelContexts = null, homeRoomId } = navigatorState;
|
|
||||||
|
|
||||||
const onNavigatorEvent = useCallback((event: NavigatorEvent) =>
|
|
||||||
{
|
|
||||||
switch(event.type)
|
|
||||||
{
|
|
||||||
case NavigatorEvent.SHOW_NAVIGATOR:
|
|
||||||
setIsVisible(true);
|
|
||||||
return;
|
|
||||||
case NavigatorEvent.HIDE_NAVIGATOR:
|
|
||||||
setIsVisible(false);
|
|
||||||
return;
|
|
||||||
case NavigatorEvent.TOGGLE_NAVIGATOR:
|
|
||||||
setIsVisible(value => !value);
|
|
||||||
return;
|
|
||||||
case NavigatorEvent.TOGGLE_ROOM_INFO:
|
|
||||||
setRoomInfoOpen(value => !value);
|
|
||||||
return;
|
|
||||||
case NavigatorEvent.TOGGLE_ROOM_LINK:
|
|
||||||
setRoomLinkOpen(value => !value);
|
|
||||||
return;
|
|
||||||
case NavigatorEvent.SHOW_ROOM_CREATOR:
|
|
||||||
setIsVisible(true);
|
|
||||||
setCreatorOpen(true);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
UseUiEvent(NavigatorEvent.SHOW_NAVIGATOR, onNavigatorEvent);
|
|
||||||
UseUiEvent(NavigatorEvent.HIDE_NAVIGATOR, onNavigatorEvent);
|
|
||||||
UseUiEvent(NavigatorEvent.TOGGLE_NAVIGATOR, onNavigatorEvent);
|
|
||||||
UseUiEvent(NavigatorEvent.TOGGLE_ROOM_INFO, onNavigatorEvent);
|
|
||||||
UseUiEvent(NavigatorEvent.TOGGLE_ROOM_LINK, onNavigatorEvent);
|
|
||||||
UseUiEvent(NavigatorEvent.SHOW_ROOM_CREATOR, onNavigatorEvent);
|
|
||||||
|
|
||||||
const onUpdateDoorStateEvent = useCallback((event: UpdateDoorStateEvent) =>
|
const onUpdateDoorStateEvent = useCallback((event: UpdateDoorStateEvent) =>
|
||||||
{
|
{
|
||||||
@ -108,26 +96,67 @@ export const NavigatorView: FC<{}> = props =>
|
|||||||
switch(event.type)
|
switch(event.type)
|
||||||
{
|
{
|
||||||
case RoomSessionEvent.CREATED:
|
case RoomSessionEvent.CREATED:
|
||||||
setIsVisible(false);
|
BatchUpdates(() =>
|
||||||
setCreatorOpen(false);
|
{
|
||||||
|
setIsVisible(false);
|
||||||
|
setCreatorOpen(false);
|
||||||
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
UseRoomSessionManagerEvent(RoomSessionEvent.CREATED, onRoomSessionEvent);
|
UseRoomSessionManagerEvent(RoomSessionEvent.CREATED, onRoomSessionEvent);
|
||||||
|
|
||||||
|
const closePendingDoorState = useCallback((state: string) =>
|
||||||
|
{
|
||||||
|
if(state !== null)
|
||||||
|
{
|
||||||
|
setPendingDoorState(prevValue =>
|
||||||
|
{
|
||||||
|
return { ...prevValue, state };
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else setPendingDoorState(null);
|
||||||
|
}, []);
|
||||||
|
|
||||||
const sendSearch = useCallback((searchValue: string, contextCode: string) =>
|
const sendSearch = useCallback((searchValue: string, contextCode: string) =>
|
||||||
{
|
{
|
||||||
setCreatorOpen(false);
|
setCreatorOpen(false);
|
||||||
|
|
||||||
SendMessageComposer(new NavigatorSearchComposer(contextCode, searchValue));
|
SendMessageComposer(new NavigatorSearchComposer(contextCode, searchValue));
|
||||||
|
|
||||||
|
setIsLoading(true);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const goToHomeRoom = useCallback(() =>
|
const reloadCurrentSearch = useCallback(() =>
|
||||||
{
|
{
|
||||||
if(homeRoomId <= 0) return;
|
if(!isReady)
|
||||||
|
{
|
||||||
|
setNeedsSearch(true);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
TryVisitRoom(homeRoomId);
|
if(pendingSearch.current)
|
||||||
}, [ homeRoomId ]);
|
{
|
||||||
|
sendSearch(pendingSearch.current.value, pendingSearch.current.code);
|
||||||
|
|
||||||
|
pendingSearch.current = null;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(searchResult)
|
||||||
|
{
|
||||||
|
sendSearch(searchResult.data, searchResult.code);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!topLevelContext) return;
|
||||||
|
|
||||||
|
sendSearch('', topLevelContext.code);
|
||||||
|
}, [ isReady, searchResult, topLevelContext, sendSearch ]);
|
||||||
|
|
||||||
const linkReceived = useCallback((url: string) =>
|
const linkReceived = useCallback((url: string) =>
|
||||||
{
|
{
|
||||||
@ -137,19 +166,52 @@ export const NavigatorView: FC<{}> = props =>
|
|||||||
|
|
||||||
switch(parts[1])
|
switch(parts[1])
|
||||||
{
|
{
|
||||||
case 'goto':
|
case 'show': {
|
||||||
if(parts.length > 2)
|
BatchUpdates(() =>
|
||||||
{
|
{
|
||||||
switch(parts[2])
|
setIsVisible(true);
|
||||||
{
|
setNeedsSearch(true);
|
||||||
case 'home':
|
});
|
||||||
goToHomeRoom();
|
return;
|
||||||
break;
|
}
|
||||||
default: {
|
case 'hide':
|
||||||
const roomId = parseInt(parts[2]);
|
setIsVisible(false);
|
||||||
|
return;
|
||||||
|
case 'toggle': {
|
||||||
|
if(isVisible)
|
||||||
|
{
|
||||||
|
setIsVisible(false);
|
||||||
|
|
||||||
TryVisitRoom(roomId);
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BatchUpdates(() =>
|
||||||
|
{
|
||||||
|
setIsVisible(true);
|
||||||
|
setNeedsSearch(true);
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
case 'toggle-room-info':
|
||||||
|
setRoomInfoOpen(value => !value);
|
||||||
|
return;
|
||||||
|
case 'toggle-room-link':
|
||||||
|
setRoomLinkOpen(value => !value);
|
||||||
|
return;
|
||||||
|
case 'goto':
|
||||||
|
if(parts.length <= 2) return;
|
||||||
|
|
||||||
|
switch(parts[2])
|
||||||
|
{
|
||||||
|
case 'home':
|
||||||
|
if(navigatorData.homeRoomId <= 0) return;
|
||||||
|
|
||||||
|
TryVisitRoom(navigatorData.homeRoomId);
|
||||||
|
break;
|
||||||
|
default: {
|
||||||
|
const roomId = parseInt(parts[2]);
|
||||||
|
|
||||||
|
TryVisitRoom(roomId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
@ -169,24 +231,17 @@ export const NavigatorView: FC<{}> = props =>
|
|||||||
|
|
||||||
if(parts.length > 3) searchValue = parts[3];
|
if(parts.length > 3) searchValue = parts[3];
|
||||||
|
|
||||||
setIsVisible(true);
|
pendingSearch.current = { value: searchValue, code: topLevelContextCode };
|
||||||
sendSearch(searchValue, topLevelContextCode);
|
|
||||||
|
BatchUpdates(() =>
|
||||||
|
{
|
||||||
|
setIsVisible(true);
|
||||||
|
setNeedsSearch(true);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}, [ goToHomeRoom, sendSearch ]);
|
}, [ isVisible, navigatorData.homeRoomId ]);
|
||||||
|
|
||||||
const closePendingDoorState = useCallback((state: string) =>
|
|
||||||
{
|
|
||||||
if(state !== null)
|
|
||||||
{
|
|
||||||
setPendingDoorState(prevValue =>
|
|
||||||
{
|
|
||||||
return { roomData: prevValue.roomData, state };
|
|
||||||
});
|
|
||||||
}
|
|
||||||
else setPendingDoorState(null);
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
useEffect(() =>
|
useEffect(() =>
|
||||||
{
|
{
|
||||||
@ -198,52 +253,44 @@ export const NavigatorView: FC<{}> = props =>
|
|||||||
AddEventLinkTracker(linkTracker);
|
AddEventLinkTracker(linkTracker);
|
||||||
|
|
||||||
return () => RemoveLinkEventTracker(linkTracker);
|
return () => RemoveLinkEventTracker(linkTracker);
|
||||||
}, [ linkReceived]);
|
}, [ linkReceived ]);
|
||||||
|
|
||||||
const enterRoomWebRequest = useCallback((k: string, _arg_2:boolean=false, _arg_3:string=null) =>
|
|
||||||
{
|
|
||||||
SendMessageComposer(new ConvertGlobalRoomIdMessageComposer(k));
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
UseMountEffect(() =>
|
|
||||||
{
|
|
||||||
LegacyExternalInterface.addCallback(HabboWebTools.OPENROOM, enterRoomWebRequest);
|
|
||||||
});
|
|
||||||
|
|
||||||
useEffect(() =>
|
useEffect(() =>
|
||||||
{
|
{
|
||||||
if(!needsNavigatorUpdate) return;
|
if(!searchResult) return;
|
||||||
|
|
||||||
dispatchNavigatorState({
|
setIsLoading(false);
|
||||||
type: NavigatorActions.SET_NEEDS_UPDATE,
|
}, [ searchResult ]);
|
||||||
payload: {
|
|
||||||
flag: false
|
useEffect(() =>
|
||||||
}
|
{
|
||||||
});
|
if(!isVisible || !isReady || !needsSearch) return;
|
||||||
|
|
||||||
|
reloadCurrentSearch();
|
||||||
|
|
||||||
|
setNeedsSearch(false);
|
||||||
|
}, [ isVisible, isReady, needsSearch, reloadCurrentSearch ]);
|
||||||
|
|
||||||
|
useEffect(() =>
|
||||||
|
{
|
||||||
|
if(isReady || !topLevelContext) return;
|
||||||
|
|
||||||
|
setIsReady(true);
|
||||||
|
}, [ isReady, topLevelContext ]);
|
||||||
|
|
||||||
|
useEffect(() =>
|
||||||
|
{
|
||||||
|
if(!isVisible || !needsInit) return;
|
||||||
|
|
||||||
SendMessageComposer(new NavigatorInitComposer());
|
SendMessageComposer(new NavigatorInitComposer());
|
||||||
}, [ needsNavigatorUpdate ]);
|
|
||||||
|
setNeedsInit(false);
|
||||||
|
}, [ isVisible, needsInit ]);
|
||||||
|
|
||||||
useEffect(() =>
|
useEffect(() =>
|
||||||
{
|
{
|
||||||
if(!isVisible || !topLevelContext) return;
|
LegacyExternalInterface.addCallback(HabboWebTools.OPENROOM, (k: string, _arg_2: boolean = false, _arg_3: string = null) => SendMessageComposer(new ConvertGlobalRoomIdMessageComposer(k)));
|
||||||
|
}, []);
|
||||||
sendSearch('', topLevelContext.code);
|
|
||||||
}, [isVisible, sendSearch, topLevelContext])
|
|
||||||
|
|
||||||
useEffect(() =>
|
|
||||||
{
|
|
||||||
if(!topLevelContexts || !topLevelContexts.length) return;
|
|
||||||
|
|
||||||
sendSearch('', topLevelContexts[0].code);
|
|
||||||
}, [ topLevelContexts, sendSearch ]);
|
|
||||||
|
|
||||||
useEffect(() =>
|
|
||||||
{
|
|
||||||
if(!isVisible || !LAST_SEARCH || !LAST_SEARCH.length) return;
|
|
||||||
|
|
||||||
CreateLinkEvent(`navigator/search/${ LAST_SEARCH }`);
|
|
||||||
}, [ isVisible ]);
|
|
||||||
|
|
||||||
const getRoomDoorState = useMemo(() =>
|
const getRoomDoorState = useMemo(() =>
|
||||||
{
|
{
|
||||||
@ -264,7 +311,7 @@ export const NavigatorView: FC<{}> = props =>
|
|||||||
}, [ pendingDoorState, closePendingDoorState ]);
|
}, [ pendingDoorState, closePendingDoorState ]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<NavigatorContextProvider value={ { navigatorState, dispatchNavigatorState } }>
|
<NavigatorContextProvider value={ { categories, setCategories, topLevelContext, setTopLevelContext, topLevelContexts, setTopLevelContexts, navigatorData, setNavigatorData, searchResult, setSearchResult } }>
|
||||||
<NavigatorMessageHandler />
|
<NavigatorMessageHandler />
|
||||||
{ getRoomDoorState }
|
{ getRoomDoorState }
|
||||||
{ isVisible &&
|
{ isVisible &&
|
||||||
@ -283,12 +330,14 @@ export const NavigatorView: FC<{}> = props =>
|
|||||||
<FontAwesomeIcon icon="plus" />
|
<FontAwesomeIcon icon="plus" />
|
||||||
</NitroCardTabsItemView>
|
</NitroCardTabsItemView>
|
||||||
</NitroCardTabsView>
|
</NitroCardTabsView>
|
||||||
<NitroCardContentView>
|
<NitroCardContentView position='relative'>
|
||||||
|
{ isLoading &&
|
||||||
|
<Base fit position="absolute" className="top-0 start-0 z-index-1 bg-muted opacity-0-5" /> }
|
||||||
{ !isCreatorOpen &&
|
{ !isCreatorOpen &&
|
||||||
<>
|
<>
|
||||||
<NavigatorSearchView sendSearch={ sendSearch } />
|
<NavigatorSearchView sendSearch={ sendSearch } />
|
||||||
<Column overflow="auto">
|
<Column overflow="auto">
|
||||||
{ (navigatorState.searchResult && navigatorState.searchResult.results.map((result, index) => <NavigatorSearchResultView key={ index } searchResult={ result } />)) }
|
{ (searchResult && searchResult.results.map((result, index) => <NavigatorSearchResultView key={ index } searchResult={ result } />)) }
|
||||||
</Column>
|
</Column>
|
||||||
</> }
|
</> }
|
||||||
{ isCreatorOpen && <NavigatorRoomCreatorView /> }
|
{ isCreatorOpen && <NavigatorRoomCreatorView /> }
|
||||||
|
17
src/components/navigator/common/NavigatorData.ts
Normal file
17
src/components/navigator/common/NavigatorData.ts
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
import { RoomDataParser } from '@nitrots/nitro-renderer';
|
||||||
|
|
||||||
|
export interface NavigatorData
|
||||||
|
{
|
||||||
|
homeRoomId: number;
|
||||||
|
settingsReceived: boolean;
|
||||||
|
enteredGuestRoom: RoomDataParser;
|
||||||
|
currentRoomOwner: boolean;
|
||||||
|
currentRoomId: number;
|
||||||
|
currentRoomIsStaffPick: boolean;
|
||||||
|
createdFlatId: number;
|
||||||
|
avatarId: number;
|
||||||
|
roomPicker: boolean;
|
||||||
|
eventMod: boolean;
|
||||||
|
currentRoomRating: number;
|
||||||
|
canRate: boolean;
|
||||||
|
}
|
@ -33,7 +33,7 @@ export default class RoomSettingsData
|
|||||||
public muteState: number;
|
public muteState: number;
|
||||||
public kickState: number;
|
public kickState: number;
|
||||||
public banState: number;
|
public banState: number;
|
||||||
public bannedUsers: Map<number, string>;
|
public bannedUsers: any[];
|
||||||
public selectedUserToUnban: number;
|
public selectedUserToUnban: number;
|
||||||
|
|
||||||
constructor(parser: RoomSettingsParser)
|
constructor(parser: RoomSettingsParser)
|
||||||
@ -71,6 +71,6 @@ export default class RoomSettingsData
|
|||||||
this.muteState = parser.moderationSettings.allowMute;
|
this.muteState = parser.moderationSettings.allowMute;
|
||||||
this.kickState = parser.moderationSettings.allowKick;
|
this.kickState = parser.moderationSettings.allowKick;
|
||||||
this.banState = parser.moderationSettings.allowBan;
|
this.banState = parser.moderationSettings.allowBan;
|
||||||
this.bannedUsers = new Map<number, string>();
|
this.bannedUsers = [];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,10 @@
|
|||||||
export function GetMaxVisitorsList(): number[]
|
const BuildMaxVisitorsList = () =>
|
||||||
{
|
{
|
||||||
const list: number[] = [];
|
const list: number[] = [];
|
||||||
|
|
||||||
for(let i = 10; i <= 100; i = i + 10)
|
for(let i = 10; i <= 100; i = i + 10) list.push(i);
|
||||||
{
|
|
||||||
list.push(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const GetMaxVisitorsList = BuildMaxVisitorsList();
|
||||||
|
@ -1,115 +0,0 @@
|
|||||||
import { NavigatorCategoryDataParser, NavigatorSearchResultSet, NavigatorTopLevelContext } from '@nitrots/nitro-renderer';
|
|
||||||
import { Reducer } from 'react';
|
|
||||||
import { RoomInfoData } from '../common/RoomInfoData';
|
|
||||||
|
|
||||||
export interface INavigatorState
|
|
||||||
{
|
|
||||||
needsNavigatorUpdate: boolean;
|
|
||||||
topLevelContext: NavigatorTopLevelContext;
|
|
||||||
topLevelContexts: NavigatorTopLevelContext[];
|
|
||||||
searchResult: NavigatorSearchResultSet;
|
|
||||||
categories: NavigatorCategoryDataParser[];
|
|
||||||
roomInfoData: RoomInfoData;
|
|
||||||
homeRoomId: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface INavigatorAction
|
|
||||||
{
|
|
||||||
type: string;
|
|
||||||
payload: {
|
|
||||||
flag?: boolean;
|
|
||||||
topLevelContext?: NavigatorTopLevelContext;
|
|
||||||
topLevelContexts?: NavigatorTopLevelContext[];
|
|
||||||
searchResult?: NavigatorSearchResultSet;
|
|
||||||
categories?: NavigatorCategoryDataParser[];
|
|
||||||
roomInfoData?: RoomInfoData;
|
|
||||||
homeRoomId?: number;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export class NavigatorActions
|
|
||||||
{
|
|
||||||
public static SET_NEEDS_UPDATE: string = 'NA_SET_NEEDS_UPDATE';
|
|
||||||
public static SET_TOP_LEVEL_CONTEXT: string = 'NA_SET_TOP_LEVEL_CONTEXT';
|
|
||||||
public static SET_TOP_LEVEL_CONTEXTS: string = 'NA_SET_TOP_LEVEL_CONTEXTS';
|
|
||||||
public static SET_SEARCH_RESULT: string = 'NA_SET_SEARCH_RESULT';
|
|
||||||
public static SET_CATEGORIES: string = 'NA_SET_CATEGORIES';
|
|
||||||
public static SET_ROOM_INFO_DATA: string = 'NA_SET_ROOM_INFO_DATA';
|
|
||||||
public static SET_HOME_ROOM_ID: string = 'NA_SET_HOME_ROOM_ID';
|
|
||||||
}
|
|
||||||
|
|
||||||
export const initialNavigator: INavigatorState = {
|
|
||||||
needsNavigatorUpdate: true,
|
|
||||||
topLevelContext: null,
|
|
||||||
topLevelContexts: null,
|
|
||||||
searchResult: null,
|
|
||||||
categories: null,
|
|
||||||
roomInfoData: new RoomInfoData(),
|
|
||||||
homeRoomId: null
|
|
||||||
}
|
|
||||||
|
|
||||||
export const NavigatorReducer: Reducer<INavigatorState, INavigatorAction> = (state, action) =>
|
|
||||||
{
|
|
||||||
switch(action.type)
|
|
||||||
{
|
|
||||||
case NavigatorActions.SET_NEEDS_UPDATE:
|
|
||||||
return { ...state, needsNavigatorUpdate: (action.payload.flag || false) };
|
|
||||||
case NavigatorActions.SET_TOP_LEVEL_CONTEXT: {
|
|
||||||
let topLevelContext = (action.payload.topLevelContext || state.topLevelContext || null);
|
|
||||||
|
|
||||||
let index = 0;
|
|
||||||
|
|
||||||
if(topLevelContext)
|
|
||||||
{
|
|
||||||
const foundIndex = state.topLevelContexts.indexOf(topLevelContext);
|
|
||||||
|
|
||||||
if(foundIndex > -1) index = foundIndex;
|
|
||||||
}
|
|
||||||
|
|
||||||
topLevelContext = (state.topLevelContexts[index] || null);
|
|
||||||
|
|
||||||
return { ...state, topLevelContext };
|
|
||||||
}
|
|
||||||
case NavigatorActions.SET_TOP_LEVEL_CONTEXTS: {
|
|
||||||
const topLevelContexts = (action.payload.topLevelContexts || state.topLevelContexts || null);
|
|
||||||
const topLevelContext = topLevelContexts[0];
|
|
||||||
|
|
||||||
return { ...state, topLevelContext, topLevelContexts };
|
|
||||||
}
|
|
||||||
case NavigatorActions.SET_SEARCH_RESULT: {
|
|
||||||
const searchResult = (action.payload.searchResult || state.searchResult || null);
|
|
||||||
const searchCode = searchResult.code;
|
|
||||||
|
|
||||||
let topLevelContext = state.topLevelContext;
|
|
||||||
|
|
||||||
if(searchCode !== topLevelContext.code)
|
|
||||||
{
|
|
||||||
for(const existingContext of state.topLevelContexts)
|
|
||||||
{
|
|
||||||
if(existingContext.code !== searchCode) continue;
|
|
||||||
|
|
||||||
topLevelContext = existingContext;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return { ...state, topLevelContext, searchResult };
|
|
||||||
}
|
|
||||||
case NavigatorActions.SET_CATEGORIES: {
|
|
||||||
const categories = (action.payload.categories || state.categories || null);
|
|
||||||
|
|
||||||
return { ...state, categories };
|
|
||||||
}
|
|
||||||
case NavigatorActions.SET_ROOM_INFO_DATA: {
|
|
||||||
const roomInfoData = (action.payload.roomInfoData || state.roomInfoData || null);
|
|
||||||
|
|
||||||
return { ...state, roomInfoData };
|
|
||||||
}
|
|
||||||
case NavigatorActions.SET_HOME_ROOM_ID: {
|
|
||||||
const homeRoomId = (action.payload.homeRoomId || state.homeRoomId || null);
|
|
||||||
|
|
||||||
return { ...state, homeRoomId };
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
return state;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,11 +1,11 @@
|
|||||||
/* eslint-disable no-template-curly-in-string */
|
/* eslint-disable no-template-curly-in-string */
|
||||||
import { HabboClubLevelEnum, RoomCreateComposer } from '@nitrots/nitro-renderer';
|
import { HabboClubLevelEnum, RoomCreateComposer } from '@nitrots/nitro-renderer';
|
||||||
import { FC, useEffect, useState } from 'react';
|
import { FC, useEffect, useState } from 'react';
|
||||||
import { GetClubMemberLevel, GetConfiguration, LocalizeText, SendMessageComposer } from '../../../../api';
|
import { GetClubMemberLevel, GetConfiguration, LocalizeText, SendMessageComposer } from '../../../api';
|
||||||
import { Button, Column, Flex, Grid, LayoutCurrencyIcon, LayoutGridItem, Text } from '../../../../common';
|
import { Button, Column, Flex, Grid, LayoutCurrencyIcon, LayoutGridItem, Text } from '../../../common';
|
||||||
import { BatchUpdates } from '../../../../hooks';
|
import { BatchUpdates } from '../../../hooks';
|
||||||
import { IRoomModel, RoomModels } from '../../common/RoomModels';
|
import { IRoomModel, RoomModels } from '../common/RoomModels';
|
||||||
import { useNavigatorContext } from '../../NavigatorContext';
|
import { useNavigatorContext } from '../NavigatorContext';
|
||||||
|
|
||||||
export const NavigatorRoomCreatorView: FC<{}> = props =>
|
export const NavigatorRoomCreatorView: FC<{}> = props =>
|
||||||
{
|
{
|
||||||
@ -16,8 +16,7 @@ export const NavigatorRoomCreatorView: FC<{}> = props =>
|
|||||||
const [ visitorsCount, setVisitorsCount ] = useState<number>(null);
|
const [ visitorsCount, setVisitorsCount ] = useState<number>(null);
|
||||||
const [ tradesSetting, setTradesSetting ] = useState<number>(0);
|
const [ tradesSetting, setTradesSetting ] = useState<number>(0);
|
||||||
const [ selectedModelName, setSelectedModelName ] = useState<string>(RoomModels[0].name);
|
const [ selectedModelName, setSelectedModelName ] = useState<string>(RoomModels[0].name);
|
||||||
const { navigatorState = null } = useNavigatorContext();
|
const { categories = null } = useNavigatorContext();
|
||||||
const { categories = null } = navigatorState;
|
|
||||||
|
|
||||||
const getRoomModelImage = (name: string) => GetConfiguration<string>('images.url') + `/navigator/models/model_${ name }.png`;
|
const getRoomModelImage = (name: string) => GetConfiguration<string>('images.url') + `/navigator/models/model_${ name }.png`;
|
||||||
|
|
||||||
@ -64,7 +63,7 @@ export const NavigatorRoomCreatorView: FC<{}> = props =>
|
|||||||
</Column>
|
</Column>
|
||||||
<Column grow gap={ 1 }>
|
<Column grow gap={ 1 }>
|
||||||
<Text>{ LocalizeText('navigator.createroom.roomdescinfo') }</Text>
|
<Text>{ LocalizeText('navigator.createroom.roomdescinfo') }</Text>
|
||||||
<textarea className="flex-grow-1 form-control w-100" maxLength={255} onChange={event => setDescription(event.target.value)} placeholder={ LocalizeText('navigator.createroom.roomdescinfo') } />
|
<textarea className="flex-grow-1 form-control form-control-sm w-100" maxLength={255} onChange={event => setDescription(event.target.value)} placeholder={ LocalizeText('navigator.createroom.roomdescinfo') } />
|
||||||
</Column>
|
</Column>
|
||||||
<Column gap={ 1 }>
|
<Column gap={ 1 }>
|
||||||
<Text>{ LocalizeText('navigator.category') }</Text>
|
<Text>{ LocalizeText('navigator.category') }</Text>
|
@ -1,11 +1,11 @@
|
|||||||
import { RoomDataParser } from '@nitrots/nitro-renderer';
|
import { RoomDataParser } from '@nitrots/nitro-renderer';
|
||||||
import { FC } from 'react';
|
import { FC } from 'react';
|
||||||
import { CreateRoomSession, GoToDesktop, LocalizeText } from '../../../../api';
|
import { CreateRoomSession, GoToDesktop, LocalizeText } from '../../../api';
|
||||||
import { NitroCardContentView, NitroCardHeaderView, NitroCardView } from '../../../../common';
|
import { NitroCardContentView, NitroCardHeaderView, NitroCardView } from '../../../common';
|
||||||
import { Button } from '../../../../common/Button';
|
import { Button } from '../../../common/Button';
|
||||||
import { Column } from '../../../../common/Column';
|
import { Column } from '../../../common/Column';
|
||||||
import { Text } from '../../../../common/Text';
|
import { Text } from '../../../common/Text';
|
||||||
import { UpdateDoorStateEvent } from '../../../../events';
|
import { UpdateDoorStateEvent } from '../../../events';
|
||||||
|
|
||||||
export interface NavigatorRoomDoorbellViewProps
|
export interface NavigatorRoomDoorbellViewProps
|
||||||
{
|
{
|
@ -2,12 +2,11 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
|||||||
import { RoomMuteComposer, RoomSettingsComposer, RoomStaffPickComposer, SecurityLevel, UserHomeRoomComposer } from '@nitrots/nitro-renderer';
|
import { RoomMuteComposer, RoomSettingsComposer, RoomStaffPickComposer, SecurityLevel, UserHomeRoomComposer } from '@nitrots/nitro-renderer';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import { FC, useEffect, useState } from 'react';
|
import { FC, useEffect, useState } from 'react';
|
||||||
import { GetGroupInformation, GetSessionDataManager, LocalizeText, SendMessageComposer } from '../../../../api';
|
import { CreateLinkEvent, GetGroupInformation, GetSessionDataManager, LocalizeText, SendMessageComposer } from '../../../api';
|
||||||
import { Button, Column, Flex, LayoutBadgeImageView, LayoutRoomThumbnailView, NitroCardContentView, NitroCardHeaderView, NitroCardView, Text, UserProfileIconView } from '../../../../common';
|
import { Button, Column, Flex, LayoutBadgeImageView, LayoutRoomThumbnailView, NitroCardContentView, NitroCardHeaderView, NitroCardView, Text, UserProfileIconView } from '../../../common';
|
||||||
import { FloorplanEditorEvent, NavigatorEvent, RoomWidgetThumbnailEvent } from '../../../../events';
|
import { FloorplanEditorEvent, RoomWidgetThumbnailEvent } from '../../../events';
|
||||||
import { BatchUpdates, DispatchUiEvent } from '../../../../hooks';
|
import { BatchUpdates, DispatchUiEvent } from '../../../hooks';
|
||||||
import { useNavigatorContext } from '../../NavigatorContext';
|
import { useNavigatorContext } from '../NavigatorContext';
|
||||||
import { NavigatorActions } from '../../reducers/NavigatorReducer';
|
|
||||||
|
|
||||||
export class NavigatorRoomInfoViewProps
|
export class NavigatorRoomInfoViewProps
|
||||||
{
|
{
|
||||||
@ -20,15 +19,14 @@ export const NavigatorRoomInfoView: FC<NavigatorRoomInfoViewProps> = props =>
|
|||||||
const [ roomThumbnail, setRoomThumbnail ] = useState(null);
|
const [ roomThumbnail, setRoomThumbnail ] = useState(null);
|
||||||
const [ isRoomPicked, setIsRoomPicked ] = useState(false);
|
const [ isRoomPicked, setIsRoomPicked ] = useState(false);
|
||||||
const [ isRoomMuted, setIsRoomMuted ] = useState(false);
|
const [ isRoomMuted, setIsRoomMuted ] = useState(false);
|
||||||
const { navigatorState = null, dispatchNavigatorState = null } = useNavigatorContext();
|
const { navigatorData = null } = useNavigatorContext();
|
||||||
const { roomInfoData = null, homeRoomId = null } = navigatorState;
|
|
||||||
|
|
||||||
const hasPermission = (permission: string) =>
|
const hasPermission = (permission: string) =>
|
||||||
{
|
{
|
||||||
switch(permission)
|
switch(permission)
|
||||||
{
|
{
|
||||||
case 'settings':
|
case 'settings':
|
||||||
return GetSessionDataManager().securityLevel >= SecurityLevel.MODERATOR || roomInfoData.currentRoomOwner;
|
return (GetSessionDataManager().userId === navigatorData.enteredGuestRoom.ownerId);
|
||||||
case 'staff_pick':
|
case 'staff_pick':
|
||||||
return GetSessionDataManager().securityLevel >= SecurityLevel.COMMUNITY;
|
return GetSessionDataManager().securityLevel >= SecurityLevel.COMMUNITY;
|
||||||
default: return false;
|
default: return false;
|
||||||
@ -37,25 +35,18 @@ export const NavigatorRoomInfoView: FC<NavigatorRoomInfoViewProps> = props =>
|
|||||||
|
|
||||||
const processAction = (action: string, value?: string) =>
|
const processAction = (action: string, value?: string) =>
|
||||||
{
|
{
|
||||||
if(!roomInfoData || !roomInfoData.enteredGuestRoom) return;
|
if(!navigatorData || !navigatorData.enteredGuestRoom) return;
|
||||||
|
|
||||||
switch(action)
|
switch(action)
|
||||||
{
|
{
|
||||||
case 'set_home_room':
|
case 'set_home_room':
|
||||||
let newRoomId = -1;
|
let newRoomId = -1;
|
||||||
|
|
||||||
if(homeRoomId !== roomInfoData.enteredGuestRoom.roomId)
|
if(navigatorData.homeRoomId !== navigatorData.enteredGuestRoom.roomId)
|
||||||
{
|
{
|
||||||
newRoomId = roomInfoData.enteredGuestRoom.roomId;
|
newRoomId = navigatorData.enteredGuestRoom.roomId;
|
||||||
}
|
}
|
||||||
|
|
||||||
dispatchNavigatorState({
|
|
||||||
type: NavigatorActions.SET_HOME_ROOM_ID,
|
|
||||||
payload: {
|
|
||||||
homeRoomId: newRoomId
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
SendMessageComposer(new UserHomeRoomComposer(newRoomId));
|
SendMessageComposer(new UserHomeRoomComposer(newRoomId));
|
||||||
return;
|
return;
|
||||||
case 'navigator_search_tag':
|
case 'navigator_search_tag':
|
||||||
@ -64,17 +55,17 @@ export const NavigatorRoomInfoView: FC<NavigatorRoomInfoViewProps> = props =>
|
|||||||
DispatchUiEvent(new RoomWidgetThumbnailEvent(RoomWidgetThumbnailEvent.TOGGLE_THUMBNAIL));
|
DispatchUiEvent(new RoomWidgetThumbnailEvent(RoomWidgetThumbnailEvent.TOGGLE_THUMBNAIL));
|
||||||
return;
|
return;
|
||||||
case 'open_group_info':
|
case 'open_group_info':
|
||||||
GetGroupInformation(roomInfoData.enteredGuestRoom.habboGroupId);
|
GetGroupInformation(navigatorData.enteredGuestRoom.habboGroupId);
|
||||||
return;
|
return;
|
||||||
case 'toggle_room_link':
|
case 'toggle_room_link':
|
||||||
DispatchUiEvent(new NavigatorEvent(NavigatorEvent.TOGGLE_ROOM_LINK));
|
CreateLinkEvent('navigator/toggle-room-link');
|
||||||
return;
|
return;
|
||||||
case 'open_room_settings':
|
case 'open_room_settings':
|
||||||
SendMessageComposer(new RoomSettingsComposer(roomInfoData.enteredGuestRoom.roomId));
|
SendMessageComposer(new RoomSettingsComposer(navigatorData.enteredGuestRoom.roomId));
|
||||||
return;
|
return;
|
||||||
case 'toggle_pick':
|
case 'toggle_pick':
|
||||||
setIsRoomPicked(value => !value);
|
setIsRoomPicked(value => !value);
|
||||||
SendMessageComposer(new RoomStaffPickComposer(roomInfoData.enteredGuestRoom.roomId));
|
SendMessageComposer(new RoomStaffPickComposer(navigatorData.enteredGuestRoom.roomId));
|
||||||
return;
|
return;
|
||||||
case 'toggle_mute':
|
case 'toggle_mute':
|
||||||
setIsRoomMuted(value => !value);
|
setIsRoomMuted(value => !value);
|
||||||
@ -92,49 +83,49 @@ export const NavigatorRoomInfoView: FC<NavigatorRoomInfoViewProps> = props =>
|
|||||||
|
|
||||||
useEffect(() =>
|
useEffect(() =>
|
||||||
{
|
{
|
||||||
if(!roomInfoData || !roomInfoData.enteredGuestRoom) return;
|
if(!navigatorData) return;
|
||||||
|
|
||||||
BatchUpdates(() =>
|
BatchUpdates(() =>
|
||||||
{
|
{
|
||||||
setIsRoomPicked(roomInfoData.enteredGuestRoom.roomPicker);
|
setIsRoomPicked(navigatorData.currentRoomIsStaffPick);
|
||||||
setIsRoomMuted(roomInfoData.enteredGuestRoom.allInRoomMuted);
|
if(navigatorData.enteredGuestRoom) setIsRoomMuted(navigatorData.enteredGuestRoom.allInRoomMuted);
|
||||||
});
|
});
|
||||||
}, [ roomInfoData ]);
|
}, [ navigatorData ]);
|
||||||
|
|
||||||
if(!roomInfoData) return null;
|
if(!navigatorData.enteredGuestRoom) return null;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<NitroCardView className="nitro-room-info" theme="primary-slim">
|
<NitroCardView className="nitro-room-info" theme="primary-slim">
|
||||||
<NitroCardHeaderView headerText={ LocalizeText('navigator.roomsettings.roominfo') } onCloseClick={ () => processAction('close') } />
|
<NitroCardHeaderView headerText={ LocalizeText('navigator.roomsettings.roominfo') } onCloseClick={ () => processAction('close') } />
|
||||||
<NitroCardContentView className="text-black">
|
<NitroCardContentView className="text-black">
|
||||||
{ roomInfoData.enteredGuestRoom &&
|
{ navigatorData.enteredGuestRoom &&
|
||||||
<>
|
<>
|
||||||
<Flex gap={ 2 } overflow="hidden">
|
<Flex gap={ 2 } overflow="hidden">
|
||||||
<LayoutRoomThumbnailView roomId={ roomInfoData.enteredGuestRoom.roomId } customUrl={ roomInfoData.enteredGuestRoom.officialRoomPicRef }>
|
<LayoutRoomThumbnailView roomId={ navigatorData.enteredGuestRoom.roomId } customUrl={ navigatorData.enteredGuestRoom.officialRoomPicRef }>
|
||||||
{ hasPermission('settings') && <i className="icon icon-camera-small position-absolute b-0 r-0 m-1 cursor-pointer top-0" onClick={ () => processAction('open_room_thumbnail_camera') } /> }
|
{ hasPermission('settings') && <i className="icon icon-camera-small position-absolute b-0 r-0 m-1 cursor-pointer top-0" onClick={ () => processAction('open_room_thumbnail_camera') } /> }
|
||||||
</LayoutRoomThumbnailView>
|
</LayoutRoomThumbnailView>
|
||||||
<Column grow gap={ 1 } overflow="hidden">
|
<Column grow gap={ 1 } overflow="hidden">
|
||||||
<Flex gap={ 1 }>
|
<Flex gap={ 1 }>
|
||||||
<Column grow gap={ 1 }>
|
<Column grow gap={ 1 }>
|
||||||
<Flex gap={ 1 }>
|
<Flex gap={ 1 }>
|
||||||
<i onClick={ () => processAction('set_home_room') } className={ 'flex-shrink-0 icon icon-house-small cursor-pointer' + classNames({ ' gray': homeRoomId !== roomInfoData.enteredGuestRoom.roomId }) } />
|
<i onClick={ () => processAction('set_home_room') } className={ 'flex-shrink-0 icon icon-house-small cursor-pointer' + classNames({ ' gray': navigatorData.homeRoomId !== navigatorData.enteredGuestRoom.roomId }) } />
|
||||||
<Text bold>{ roomInfoData.enteredGuestRoom.roomName }</Text>
|
<Text bold>{ navigatorData.enteredGuestRoom.roomName }</Text>
|
||||||
</Flex>
|
</Flex>
|
||||||
{ roomInfoData.enteredGuestRoom.showOwner &&
|
{ navigatorData.enteredGuestRoom.showOwner &&
|
||||||
<Flex alignItems="center" gap={ 1 }>
|
<Flex alignItems="center" gap={ 1 }>
|
||||||
<Text variant="muted">{ LocalizeText('navigator.roomownercaption') }</Text>
|
<Text variant="muted">{ LocalizeText('navigator.roomownercaption') }</Text>
|
||||||
<Flex alignItems="center" gap={ 1 }>
|
<Flex alignItems="center" gap={ 1 }>
|
||||||
<UserProfileIconView userId={ roomInfoData.enteredGuestRoom.ownerId } />
|
<UserProfileIconView userId={ navigatorData.enteredGuestRoom.ownerId } />
|
||||||
<Text>{ roomInfoData.enteredGuestRoom.ownerName }</Text>
|
<Text>{ navigatorData.enteredGuestRoom.ownerName }</Text>
|
||||||
</Flex>
|
</Flex>
|
||||||
</Flex> }
|
</Flex> }
|
||||||
<Flex alignItems="center" gap={ 1 }>
|
<Flex alignItems="center" gap={ 1 }>
|
||||||
<Text variant="muted">{ LocalizeText('navigator.roomrating') }</Text>
|
<Text variant="muted">{ LocalizeText('navigator.roomrating') }</Text>
|
||||||
<Text>{ roomInfoData.enteredGuestRoom.score }</Text>
|
<Text>{ navigatorData.enteredGuestRoom.score }</Text>
|
||||||
</Flex>
|
</Flex>
|
||||||
{ (roomInfoData.enteredGuestRoom.tags.length > 0) &&
|
{ (navigatorData.enteredGuestRoom.tags.length > 0) &&
|
||||||
<Flex alignItems="center" gap={ 1 }>
|
<Flex alignItems="center" gap={ 1 }>
|
||||||
{ roomInfoData.enteredGuestRoom.tags.map(tag =>
|
{ navigatorData.enteredGuestRoom.tags.map(tag =>
|
||||||
{
|
{
|
||||||
return <Text key={ tag } pointer className="bg-muted rounded p-1" onClick={ event => processAction('navigator_search_tag', tag) }>#{ tag }</Text>
|
return <Text key={ tag } pointer className="bg-muted rounded p-1" onClick={ event => processAction('navigator_search_tag', tag) }>#{ tag }</Text>
|
||||||
}) }
|
}) }
|
||||||
@ -143,15 +134,15 @@ export const NavigatorRoomInfoView: FC<NavigatorRoomInfoViewProps> = props =>
|
|||||||
<Column alignItems="center" gap={ 1 }>
|
<Column alignItems="center" gap={ 1 }>
|
||||||
{ hasPermission('settings') &&
|
{ hasPermission('settings') &&
|
||||||
<i className="icon icon-cog cursor-pointer" title={ LocalizeText('navigator.room.popup.info.room.settings') } onClick={ event => processAction('open_room_settings') } /> }
|
<i className="icon icon-cog cursor-pointer" title={ LocalizeText('navigator.room.popup.info.room.settings') } onClick={ event => processAction('open_room_settings') } /> }
|
||||||
<FontAwesomeIcon icon="link" title={ LocalizeText('navigator.embed.caption') } className="cursor-pointer" onClick={ event => DispatchUiEvent(new NavigatorEvent(NavigatorEvent.TOGGLE_ROOM_LINK)) } />
|
<FontAwesomeIcon icon="link" title={ LocalizeText('navigator.embed.caption') } className="cursor-pointer" onClick={ event => CreateLinkEvent('navigator/toggle-room-link') } />
|
||||||
</Column>
|
</Column>
|
||||||
</Flex>
|
</Flex>
|
||||||
<Text overflow="auto" style={ { maxHeight: 50 } }>{ roomInfoData.enteredGuestRoom.description }</Text>
|
<Text overflow="auto" style={ { maxHeight: 50 } }>{ navigatorData.enteredGuestRoom.description }</Text>
|
||||||
{ (roomInfoData.enteredGuestRoom.habboGroupId > 0) &&
|
{ (navigatorData.enteredGuestRoom.habboGroupId > 0) &&
|
||||||
<Flex pointer alignItems="center" gap={ 1 } onClick={ () => processAction('open_group_info') }>
|
<Flex pointer alignItems="center" gap={ 1 } onClick={ () => processAction('open_group_info') }>
|
||||||
<LayoutBadgeImageView className="flex-none" badgeCode={ roomInfoData.enteredGuestRoom.groupBadgeCode } isGroup={ true } />
|
<LayoutBadgeImageView className="flex-none" badgeCode={ navigatorData.enteredGuestRoom.groupBadgeCode } isGroup={ true } />
|
||||||
<Text underline>
|
<Text underline>
|
||||||
{ LocalizeText('navigator.guildbase', ['groupName'], [roomInfoData.enteredGuestRoom.groupName]) }
|
{ LocalizeText('navigator.guildbase', ['groupName'], [navigatorData.enteredGuestRoom.groupName]) }
|
||||||
</Text>
|
</Text>
|
||||||
</Flex> }
|
</Flex> }
|
||||||
</Column>
|
</Column>
|
33
src/components/navigator/views/NavigatorRoomLinkView.tsx
Normal file
33
src/components/navigator/views/NavigatorRoomLinkView.tsx
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
import { FC } from 'react';
|
||||||
|
import { GetConfiguration, LocalizeText } from '../../../api';
|
||||||
|
import { Column, Flex, LayoutRoomThumbnailView, NitroCardContentView, NitroCardHeaderView, NitroCardView, Text } from '../../../common';
|
||||||
|
import { useNavigatorContext } from '../NavigatorContext';
|
||||||
|
|
||||||
|
export class NavigatorRoomLinkViewProps
|
||||||
|
{
|
||||||
|
onCloseClick: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const NavigatorRoomLinkView: FC<NavigatorRoomLinkViewProps> = props =>
|
||||||
|
{
|
||||||
|
const { onCloseClick = null } = props;
|
||||||
|
const { navigatorData = null } = useNavigatorContext();
|
||||||
|
|
||||||
|
if(!navigatorData.enteredGuestRoom) return null;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<NitroCardView className="nitro-room-link" theme="primary-slim">
|
||||||
|
<NitroCardHeaderView headerText={ LocalizeText('navigator.embed.title') } onCloseClick={ onCloseClick } />
|
||||||
|
<NitroCardContentView className="text-black d-flex align-items-center">
|
||||||
|
<Flex gap={ 2 }>
|
||||||
|
<LayoutRoomThumbnailView roomId={ navigatorData.enteredGuestRoom.roomId } customUrl={ navigatorData.enteredGuestRoom.officialRoomPicRef } />
|
||||||
|
<Column>
|
||||||
|
<Text bold fontSize={ 5 }>{ LocalizeText('navigator.embed.headline') }</Text>
|
||||||
|
<Text>{ LocalizeText('navigator.embed.info') }</Text>
|
||||||
|
<input type="text" readOnly className="form-control form-control-sm" value={ GetConfiguration<string>('navigator.embed.src').replace('%roomId%', navigatorData.enteredGuestRoom.roomId.toString()) } />
|
||||||
|
</Column>
|
||||||
|
</Flex>
|
||||||
|
</NitroCardContentView>
|
||||||
|
</NitroCardView>
|
||||||
|
);
|
||||||
|
};
|
@ -1,11 +1,11 @@
|
|||||||
import { RoomDataParser } from '@nitrots/nitro-renderer';
|
import { RoomDataParser } from '@nitrots/nitro-renderer';
|
||||||
import { FC, useCallback, useState } from 'react';
|
import { FC, useCallback, useState } from 'react';
|
||||||
import { CreateRoomSession, LocalizeText } from '../../../../api';
|
import { CreateRoomSession, LocalizeText } from '../../../api';
|
||||||
import { NitroCardContentView, NitroCardHeaderView, NitroCardView } from '../../../../common';
|
import { NitroCardContentView, NitroCardHeaderView, NitroCardView } from '../../../common';
|
||||||
import { Button } from '../../../../common/Button';
|
import { Button } from '../../../common/Button';
|
||||||
import { Column } from '../../../../common/Column';
|
import { Column } from '../../../common/Column';
|
||||||
import { Text } from '../../../../common/Text';
|
import { Text } from '../../../common/Text';
|
||||||
import { UpdateDoorStateEvent } from '../../../../events';
|
import { UpdateDoorStateEvent } from '../../../events';
|
||||||
|
|
||||||
export interface NavigatorRoomPasswordViewProps
|
export interface NavigatorRoomPasswordViewProps
|
||||||
{
|
{
|
@ -1,68 +0,0 @@
|
|||||||
import { FC, useCallback, useEffect, useRef, useState } from 'react';
|
|
||||||
import { GetConfiguration, GetNitroInstance, LocalizeText } from '../../../../api';
|
|
||||||
import { Column, Flex, LayoutRoomThumbnailView, NitroCardContentView, NitroCardHeaderView, NitroCardView, Text } from '../../../../common';
|
|
||||||
import { useNavigatorContext } from '../../NavigatorContext';
|
|
||||||
|
|
||||||
export class NavigatorRoomLinkViewProps
|
|
||||||
{
|
|
||||||
onCloseClick: () => void;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const NavigatorRoomLinkView: FC<NavigatorRoomLinkViewProps> = props =>
|
|
||||||
{
|
|
||||||
const { onCloseClick = null } = props;
|
|
||||||
const [ roomThumbnail, setRoomThumbnail ] = useState(null);
|
|
||||||
const [ roomLink, setRoomLink ] = useState(null);
|
|
||||||
const { navigatorState = null } = useNavigatorContext();
|
|
||||||
const { roomInfoData = null } = navigatorState;
|
|
||||||
const elementRef = useRef<HTMLInputElement>();
|
|
||||||
|
|
||||||
useEffect(() =>
|
|
||||||
{
|
|
||||||
if(!roomInfoData || !roomInfoData.enteredGuestRoom) return;
|
|
||||||
|
|
||||||
if(roomInfoData.enteredGuestRoom.officialRoomPicRef)
|
|
||||||
{
|
|
||||||
setRoomThumbnail(GetConfiguration<string>('image.library.url') + roomInfoData.enteredGuestRoom.officialRoomPicRef);
|
|
||||||
}
|
|
||||||
|
|
||||||
const roomLinkRaw = GetNitroInstance().core.configuration.interpolate(LocalizeText('navigator.embed.src', ['roomId'], [roomInfoData.enteredGuestRoom.roomId.toString()]));
|
|
||||||
|
|
||||||
setRoomLink(roomLinkRaw);
|
|
||||||
}, [ roomInfoData ]);
|
|
||||||
|
|
||||||
const processAction = useCallback((action: string) =>
|
|
||||||
{
|
|
||||||
if(!roomInfoData || !roomInfoData.enteredGuestRoom) return;
|
|
||||||
|
|
||||||
switch(action)
|
|
||||||
{
|
|
||||||
case 'copy_room_link':
|
|
||||||
elementRef.current.select();
|
|
||||||
document.execCommand('copy');
|
|
||||||
return;
|
|
||||||
case 'close':
|
|
||||||
onCloseClick();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
}, [onCloseClick, roomInfoData]);
|
|
||||||
|
|
||||||
if(!roomInfoData) return null;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<NitroCardView className="nitro-room-link" theme="primary-slim">
|
|
||||||
<NitroCardHeaderView headerText={ LocalizeText('navigator.embed.title') } onCloseClick={ onCloseClick } />
|
|
||||||
<NitroCardContentView className="text-black d-flex align-items-center">
|
|
||||||
<Flex gap={ 2 }>
|
|
||||||
<LayoutRoomThumbnailView roomId={ roomInfoData.enteredGuestRoom.roomId } customUrl={ roomInfoData.enteredGuestRoom.officialRoomPicRef } />
|
|
||||||
<Column>
|
|
||||||
<Text bold fontSize={ 5 }>{ LocalizeText('navigator.embed.headline') }</Text>
|
|
||||||
<Text>{ LocalizeText('navigator.embed.info') }</Text>
|
|
||||||
{ roomLink && <input ref={ elementRef } type="text" readOnly className="form-control form-control-sm" value={ roomLink } /> }
|
|
||||||
</Column>
|
|
||||||
</Flex>
|
|
||||||
</NitroCardContentView>
|
|
||||||
</NitroCardView>
|
|
||||||
);
|
|
||||||
};
|
|
@ -1,8 +1,8 @@
|
|||||||
import { RoomDataParser } from '@nitrots/nitro-renderer';
|
import { RoomDataParser } from '@nitrots/nitro-renderer';
|
||||||
import { FC, useCallback } from 'react';
|
import { FC, useCallback } from 'react';
|
||||||
import { LocalizeText } from '../../../../../api';
|
import { LocalizeText } from '../../../../api';
|
||||||
import { Column, Flex, Text } from '../../../../../common';
|
import { Column, Flex, Text } from '../../../../common';
|
||||||
import RoomSettingsData from '../../../common/RoomSettingsData';
|
import RoomSettingsData from '../../common/RoomSettingsData';
|
||||||
|
|
||||||
interface NavigatorRoomSettingsTabViewProps
|
interface NavigatorRoomSettingsTabViewProps
|
||||||
{
|
{
|
@ -1,11 +1,11 @@
|
|||||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||||
import { RoomDeleteComposer } from '@nitrots/nitro-renderer';
|
import { RoomDeleteComposer } from '@nitrots/nitro-renderer';
|
||||||
import { FC, useState } from 'react';
|
import { FC } from 'react';
|
||||||
import { CreateLinkEvent, LocalizeText, NotificationUtilities, SendMessageComposer } from '../../../../../api';
|
import { CreateLinkEvent, LocalizeText, NotificationUtilities, SendMessageComposer } from '../../../../api';
|
||||||
import { Base, Flex, Text } from '../../../../../common';
|
import { Base, Flex, Text } from '../../../../common';
|
||||||
import RoomSettingsData from '../../../common/RoomSettingsData';
|
import RoomSettingsData from '../../common/RoomSettingsData';
|
||||||
import { GetMaxVisitorsList } from '../../../common/RoomSettingsUtils';
|
import { GetMaxVisitorsList } from '../../common/RoomSettingsUtils';
|
||||||
import { useNavigatorContext } from '../../../NavigatorContext';
|
import { useNavigatorContext } from '../../NavigatorContext';
|
||||||
|
|
||||||
const DESC_MAX_LENGTH = 255;
|
const DESC_MAX_LENGTH = 255;
|
||||||
|
|
||||||
@ -20,9 +20,7 @@ interface NavigatorRoomSettingsTabViewProps
|
|||||||
export const NavigatorRoomSettingsBasicTabView: FC<NavigatorRoomSettingsTabViewProps> = props =>
|
export const NavigatorRoomSettingsBasicTabView: FC<NavigatorRoomSettingsTabViewProps> = props =>
|
||||||
{
|
{
|
||||||
const { roomSettingsData = null, handleChange = null, close = null } = props;
|
const { roomSettingsData = null, handleChange = null, close = null } = props;
|
||||||
const [ maxVisitorsList, setMaxVisitorsList ] = useState(GetMaxVisitorsList());
|
const { categories = null } = useNavigatorContext();
|
||||||
const { navigatorState = null } = useNavigatorContext();
|
|
||||||
const { categories = null } = navigatorState;
|
|
||||||
|
|
||||||
const deleteRoom = () =>
|
const deleteRoom = () =>
|
||||||
{
|
{
|
||||||
@ -50,19 +48,13 @@ export const NavigatorRoomSettingsBasicTabView: FC<NavigatorRoomSettingsTabViewP
|
|||||||
<Flex alignItems="center" gap={ 1 }>
|
<Flex alignItems="center" gap={ 1 }>
|
||||||
<Text className="col-3">{ LocalizeText('navigator.category') }</Text>
|
<Text className="col-3">{ LocalizeText('navigator.category') }</Text>
|
||||||
<select className="form-select form-select-sm" value={ roomSettingsData.categoryId } onChange={ event => handleChange('category', event.target.value) }>
|
<select className="form-select form-select-sm" value={ roomSettingsData.categoryId } onChange={ event => handleChange('category', event.target.value) }>
|
||||||
{ categories && categories.map(category =>
|
{ categories && categories.map(category => <option key={ category.id } value={ category.id }>{ LocalizeText(category.name) }</option>) }
|
||||||
{
|
|
||||||
return <option key={ category.id } value={ category.id }>{ LocalizeText(category.name) }</option>
|
|
||||||
}) }
|
|
||||||
</select>
|
</select>
|
||||||
</Flex>
|
</Flex>
|
||||||
<Flex alignItems="center" gap={ 1 }>
|
<Flex alignItems="center" gap={ 1 }>
|
||||||
<Text className="col-3">{ LocalizeText('navigator.maxvisitors') }</Text>
|
<Text className="col-3">{ LocalizeText('navigator.maxvisitors') }</Text>
|
||||||
<select className="form-select form-select-sm" value={ roomSettingsData.userCount } onChange={ event => handleChange('max_visitors', event.target.value) }>
|
<select className="form-select form-select-sm" value={ roomSettingsData.userCount } onChange={ event => handleChange('max_visitors', event.target.value) }>
|
||||||
{ maxVisitorsList && maxVisitorsList.map(value =>
|
{ GetMaxVisitorsList && GetMaxVisitorsList.map(value => <option key={ value } value={ value }>{ value }</option>) }
|
||||||
{
|
|
||||||
return <option key={ value } value={ value }>{ value }</option>
|
|
||||||
}) }
|
|
||||||
</select>
|
</select>
|
||||||
</Flex>
|
</Flex>
|
||||||
<Flex alignItems="center" gap={ 1 }>
|
<Flex alignItems="center" gap={ 1 }>
|
@ -1,8 +1,8 @@
|
|||||||
import { RoomUnbanUserComposer } from '@nitrots/nitro-renderer';
|
import { RoomUnbanUserComposer } from '@nitrots/nitro-renderer';
|
||||||
import { FC, useCallback, useState } from 'react';
|
import { FC, useCallback, useState } from 'react';
|
||||||
import { LocalizeText, SendMessageComposer } from '../../../../../api';
|
import { LocalizeText, SendMessageComposer } from '../../../../api';
|
||||||
import { Base, Button, Column, Grid, Text } from '../../../../../common';
|
import { Base, Button, Column, Grid, Text } from '../../../../common';
|
||||||
import RoomSettingsData from '../../../common/RoomSettingsData';
|
import RoomSettingsData from '../../common/RoomSettingsData';
|
||||||
|
|
||||||
interface NavigatorRoomSettingsTabViewProps
|
interface NavigatorRoomSettingsTabViewProps
|
||||||
{
|
{
|
||||||
@ -26,19 +26,19 @@ export const NavigatorRoomSettingsModTabView: FC<NavigatorRoomSettingsTabViewPro
|
|||||||
return (
|
return (
|
||||||
<Grid overflow="auto">
|
<Grid overflow="auto">
|
||||||
<Column size={ 6 }>
|
<Column size={ 6 }>
|
||||||
<Text bold>{ LocalizeText('navigator.roomsettings.moderation.banned.users') } ({ roomSettingsData.bannedUsers.size })</Text>
|
<Text bold>{ LocalizeText('navigator.roomsettings.moderation.banned.users') } ({ roomSettingsData.bannedUsers.length })</Text>
|
||||||
<Column className="bg-white rounded" overflow="hidden">
|
<Column className="bg-white rounded" overflow="hidden">
|
||||||
<Base className="list-container" overflow="auto">
|
<Base className="list-container" overflow="auto">
|
||||||
{ Array.from(roomSettingsData.bannedUsers.entries()).map(([id, name], index) =>
|
{ roomSettingsData.bannedUsers.map((user, index) =>
|
||||||
{
|
{
|
||||||
return <Text key={index} className={ ((id === selectedUserId) ? 'selected' : '') } onClick={ event => setSelectedUserId(id)}> { name }</Text>
|
return <Text key={ index } className={ ((user.userId === selectedUserId) ? 'selected' : '') } onClick={ event => setSelectedUserId(user.userId)}>{ user.userName }</Text>
|
||||||
}) }
|
}) }
|
||||||
</Base>
|
</Base>
|
||||||
</Column>
|
</Column>
|
||||||
</Column>
|
</Column>
|
||||||
<Column size={ 6 } justifyContent="end">
|
<Column size={ 6 } justifyContent="end">
|
||||||
<Button disabled={ (selectedUserId < 1) } onClick={ event => unBanUser(selectedUserId) }>
|
<Button disabled={ (selectedUserId < 1) } onClick={ event => unBanUser(selectedUserId) }>
|
||||||
{ LocalizeText('navigator.roomsettings.moderation.unban')} {selectedUserId > 0 && roomSettingsData.bannedUsers.get(selectedUserId) }
|
{/* { LocalizeText('navigator.roomsettings.moderation.unban')} {selectedUserId > 0 && roomSettingsData.bannedUsers.get(selectedUserId) } */}
|
||||||
</Button>
|
</Button>
|
||||||
</Column>
|
</Column>
|
||||||
</Grid>
|
</Grid>
|
@ -1,8 +1,8 @@
|
|||||||
import { RemoveAllRightsMessageComposer, RoomTakeRightsComposer } from '@nitrots/nitro-renderer';
|
import { RemoveAllRightsMessageComposer, RoomTakeRightsComposer } from '@nitrots/nitro-renderer';
|
||||||
import { FC, useCallback } from 'react';
|
import { FC, useCallback } from 'react';
|
||||||
import { LocalizeText, SendMessageComposer } from '../../../../../api';
|
import { LocalizeText, SendMessageComposer } from '../../../../api';
|
||||||
import { Button, Column, Flex, Grid, Text, UserProfileIconView } from '../../../../../common';
|
import { Button, Column, Flex, Grid, Text, UserProfileIconView } from '../../../../common';
|
||||||
import RoomSettingsData from '../../../common/RoomSettingsData';
|
import RoomSettingsData from '../../common/RoomSettingsData';
|
||||||
|
|
||||||
interface NavigatorRoomSettingsTabViewProps
|
interface NavigatorRoomSettingsTabViewProps
|
||||||
{
|
{
|
@ -1,14 +1,15 @@
|
|||||||
import { RoomBannedUsersComposer, RoomBannedUsersEvent, RoomSettingsEvent, RoomUsersWithRightsComposer, RoomUsersWithRightsEvent, SaveRoomSettingsComposer } from '@nitrots/nitro-renderer';
|
import { RoomBannedUsersComposer, RoomSettingsEvent, RoomUsersWithRightsComposer, SaveRoomSettingsComposer } from '@nitrots/nitro-renderer';
|
||||||
|
import { BannedUsersFromRoomEvent, FlatControllerAddedEvent, FlatControllerRemovedEvent, FlatControllersEvent } from '@nitrots/nitro-renderer/src/nitro/communication/messages/incoming/roomsettings';
|
||||||
import { FC, useCallback, useState } from 'react';
|
import { FC, useCallback, useState } from 'react';
|
||||||
import { LocalizeText, SendMessageComposer } from '../../../../api';
|
import { LocalizeText, SendMessageComposer } from '../../../../api';
|
||||||
import { NitroCardContentView, NitroCardHeaderView, NitroCardTabsItemView, NitroCardTabsView, NitroCardView } from '../../../../common';
|
import { NitroCardContentView, NitroCardHeaderView, NitroCardTabsItemView, NitroCardTabsView, NitroCardView } from '../../../../common';
|
||||||
import { UseMessageEventHook } from '../../../../hooks';
|
import { UseMessageEventHook } from '../../../../hooks';
|
||||||
import RoomSettingsData from '../../common/RoomSettingsData';
|
import RoomSettingsData from '../../common/RoomSettingsData';
|
||||||
import { NavigatorRoomSettingsAccessTabView } from './views/NavigatorRoomSettingsAccessTabView';
|
import { NavigatorRoomSettingsAccessTabView } from './NavigatorRoomSettingsAccessTabView';
|
||||||
import { NavigatorRoomSettingsBasicTabView } from './views/NavigatorRoomSettingsBasicTabView';
|
import { NavigatorRoomSettingsBasicTabView } from './NavigatorRoomSettingsBasicTabView';
|
||||||
import { NavigatorRoomSettingsModTabView } from './views/NavigatorRoomSettingsModTabView';
|
import { NavigatorRoomSettingsModTabView } from './NavigatorRoomSettingsModTabView';
|
||||||
import { NavigatorRoomSettingsRightsTabView } from './views/NavigatorRoomSettingsRightsTabView';
|
import { NavigatorRoomSettingsRightsTabView } from './NavigatorRoomSettingsRightsTabView';
|
||||||
import { NavigatorRoomSettingsVipChatTabView } from './views/NavigatorRoomSettingsVipChatTabView';
|
import { NavigatorRoomSettingsVipChatTabView } from './NavigatorRoomSettingsVipChatTabView';
|
||||||
|
|
||||||
const TABS: string[] = [
|
const TABS: string[] = [
|
||||||
'navigator.roomsettings.tab.1',
|
'navigator.roomsettings.tab.1',
|
||||||
@ -23,6 +24,57 @@ export const NavigatorRoomSettingsView: FC<{}> = props =>
|
|||||||
const [ roomSettingsData, setRoomSettingsData ] = useState<RoomSettingsData>(null);
|
const [ roomSettingsData, setRoomSettingsData ] = useState<RoomSettingsData>(null);
|
||||||
const [ currentTab, setCurrentTab ] = useState(TABS[0]);
|
const [ currentTab, setCurrentTab ] = useState(TABS[0]);
|
||||||
|
|
||||||
|
const onFlatControllersEvent = useCallback((event: FlatControllersEvent) =>
|
||||||
|
{
|
||||||
|
const parser = event.getParser();
|
||||||
|
|
||||||
|
if(!parser || !roomSettingsData) return;
|
||||||
|
|
||||||
|
if(roomSettingsData.roomId !== parser.roomId) return;
|
||||||
|
|
||||||
|
const data = Object.assign({}, roomSettingsData);
|
||||||
|
|
||||||
|
data.usersWithRights = new Map(parser.users);
|
||||||
|
|
||||||
|
setRoomSettingsData(data);
|
||||||
|
}, [ roomSettingsData] );
|
||||||
|
|
||||||
|
UseMessageEventHook(FlatControllersEvent, onFlatControllersEvent);
|
||||||
|
|
||||||
|
const onFlatControllerAddedEvent = useCallback((event: FlatControllerAddedEvent) =>
|
||||||
|
{
|
||||||
|
const parser = event.getParser();
|
||||||
|
|
||||||
|
if(!parser || !roomSettingsData) return;
|
||||||
|
|
||||||
|
if(roomSettingsData.roomId !== parser.roomId) return;
|
||||||
|
|
||||||
|
const data = Object.assign({}, roomSettingsData);
|
||||||
|
|
||||||
|
// add new controller
|
||||||
|
|
||||||
|
setRoomSettingsData(data);
|
||||||
|
}, [ roomSettingsData] );
|
||||||
|
|
||||||
|
UseMessageEventHook(FlatControllerAddedEvent, onFlatControllerAddedEvent);
|
||||||
|
|
||||||
|
const onFlatControllerRemovedEvent = useCallback((event: FlatControllerRemovedEvent) =>
|
||||||
|
{
|
||||||
|
const parser = event.getParser();
|
||||||
|
|
||||||
|
if(!parser || !roomSettingsData) return;
|
||||||
|
|
||||||
|
if(roomSettingsData.roomId !== parser.roomId) return;
|
||||||
|
|
||||||
|
const data = Object.assign({}, roomSettingsData);
|
||||||
|
|
||||||
|
// remove controller
|
||||||
|
|
||||||
|
setRoomSettingsData(data);
|
||||||
|
}, [ roomSettingsData] );
|
||||||
|
|
||||||
|
UseMessageEventHook(FlatControllerRemovedEvent, onFlatControllerRemovedEvent);
|
||||||
|
|
||||||
const updateSettings = useCallback((roomSettings: RoomSettingsData) =>
|
const updateSettings = useCallback((roomSettings: RoomSettingsData) =>
|
||||||
{
|
{
|
||||||
setRoomSettingsData(roomSettings);
|
setRoomSettingsData(roomSettings);
|
||||||
@ -39,39 +91,24 @@ export const NavigatorRoomSettingsView: FC<{}> = props =>
|
|||||||
SendMessageComposer(new RoomBannedUsersComposer(parser.roomId));
|
SendMessageComposer(new RoomBannedUsersComposer(parser.roomId));
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const onRoomUsersWithRightsEvent = useCallback((event: RoomUsersWithRightsEvent) =>
|
|
||||||
{
|
|
||||||
const parser = event.getParser();
|
|
||||||
|
|
||||||
if(!parser || !roomSettingsData) return;
|
|
||||||
|
|
||||||
if(roomSettingsData.roomId !== parser.roomId) return;
|
|
||||||
|
|
||||||
const data = Object.assign({}, roomSettingsData);
|
|
||||||
|
|
||||||
data.usersWithRights = new Map(parser.users);
|
|
||||||
|
|
||||||
setRoomSettingsData(data);
|
|
||||||
}, [roomSettingsData]);
|
|
||||||
|
|
||||||
const onRoomBannedUsersEvent = useCallback((event: RoomBannedUsersEvent) =>
|
|
||||||
{
|
|
||||||
const parser = event.getParser();
|
|
||||||
|
|
||||||
if(!parser || !roomSettingsData) return;
|
|
||||||
|
|
||||||
if(roomSettingsData.roomId !== parser.roomId) return;
|
|
||||||
|
|
||||||
const data = Object.assign({}, roomSettingsData);
|
|
||||||
|
|
||||||
data.bannedUsers = new Map(parser.users);
|
|
||||||
|
|
||||||
setRoomSettingsData(data);
|
|
||||||
}, [roomSettingsData]);
|
|
||||||
|
|
||||||
UseMessageEventHook(RoomSettingsEvent, onRoomSettingsEvent);
|
UseMessageEventHook(RoomSettingsEvent, onRoomSettingsEvent);
|
||||||
UseMessageEventHook(RoomUsersWithRightsEvent, onRoomUsersWithRightsEvent);
|
|
||||||
UseMessageEventHook(RoomBannedUsersEvent, onRoomBannedUsersEvent);
|
const onBannedUsersFromRoomEvent = useCallback((event: BannedUsersFromRoomEvent) =>
|
||||||
|
{
|
||||||
|
const parser = event.getParser();
|
||||||
|
|
||||||
|
if(!parser || !roomSettingsData) return;
|
||||||
|
|
||||||
|
if(roomSettingsData.roomId !== parser.roomId) return;
|
||||||
|
|
||||||
|
const data = Object.assign({}, roomSettingsData);
|
||||||
|
|
||||||
|
data.bannedUsers = parser.bannedUsers;
|
||||||
|
|
||||||
|
setRoomSettingsData(data);
|
||||||
|
}, [roomSettingsData]);
|
||||||
|
|
||||||
|
UseMessageEventHook(BannedUsersFromRoomEvent, onBannedUsersFromRoomEvent);
|
||||||
|
|
||||||
const saveSettings = useCallback((data: RoomSettingsData) =>
|
const saveSettings = useCallback((data: RoomSettingsData) =>
|
||||||
{
|
{
|
||||||
@ -196,10 +233,13 @@ export const NavigatorRoomSettingsView: FC<{}> = props =>
|
|||||||
roomSettings.chatDistance = Number(value);
|
roomSettings.chatDistance = Number(value);
|
||||||
save = false;
|
save = false;
|
||||||
break;
|
break;
|
||||||
case 'unban_user':
|
case 'unban_user': {
|
||||||
roomSettings.bannedUsers.delete(Number(value));
|
const index = roomSettings.bannedUsers.findIndex(user => (user.userId === Number(value)))
|
||||||
|
|
||||||
|
if(index > -1) roomSettings.bannedUsers.splice(index, 1);
|
||||||
save = false;
|
save = false;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case 'remove_rights_user':
|
case 'remove_rights_user':
|
||||||
roomSettings.usersWithRights.delete(Number(value));
|
roomSettings.usersWithRights.delete(Number(value));
|
||||||
save = false;
|
save = false;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { FC } from 'react';
|
import { FC } from 'react';
|
||||||
import { LocalizeText } from '../../../../../api';
|
import { LocalizeText } from '../../../../api';
|
||||||
import { Column, Flex, Grid, Text } from '../../../../../common';
|
import { Column, Flex, Grid, Text } from '../../../../common';
|
||||||
import RoomSettingsData from '../../../common/RoomSettingsData';
|
import RoomSettingsData from '../../common/RoomSettingsData';
|
||||||
|
|
||||||
interface NavigatorRoomSettingsTabViewProps
|
interface NavigatorRoomSettingsTabViewProps
|
||||||
{
|
{
|
@ -2,7 +2,7 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
|||||||
import { RoomDataParser } from '@nitrots/nitro-renderer';
|
import { RoomDataParser } from '@nitrots/nitro-renderer';
|
||||||
import { FC, MouseEvent } from 'react';
|
import { FC, MouseEvent } from 'react';
|
||||||
import { CreateRoomSession, GetSessionDataManager, TryVisitRoom } from '../../../../api';
|
import { CreateRoomSession, GetSessionDataManager, TryVisitRoom } from '../../../../api';
|
||||||
import { Flex, LayoutBadgeImageView, LayoutGridItemProps, LayoutRoomThumbnailView, Text } from '../../../../common';
|
import { Column, Flex, LayoutBadgeImageView, LayoutGridItemProps, LayoutRoomThumbnailView, Text } from '../../../../common';
|
||||||
import { UpdateDoorStateEvent } from '../../../../events';
|
import { UpdateDoorStateEvent } from '../../../../events';
|
||||||
import { DispatchUiEvent } from '../../../../hooks';
|
import { DispatchUiEvent } from '../../../../hooks';
|
||||||
import { NavigatorSearchResultItemInfoView } from './NavigatorSearchResultItemInfoView';
|
import { NavigatorSearchResultItemInfoView } from './NavigatorSearchResultItemInfoView';
|
||||||
@ -39,13 +39,7 @@ export const NavigatorSearchResultItemView: FC<NavigatorSearchResultItemViewProp
|
|||||||
return bg;
|
return bg;
|
||||||
}
|
}
|
||||||
|
|
||||||
function openInfo(event: MouseEvent): void
|
const visitRoom = (event: MouseEvent) =>
|
||||||
{
|
|
||||||
event.stopPropagation();
|
|
||||||
console.log('info');
|
|
||||||
}
|
|
||||||
|
|
||||||
function visitRoom(): void
|
|
||||||
{
|
{
|
||||||
if(roomData.ownerId !== GetSessionDataManager().userId)
|
if(roomData.ownerId !== GetSessionDataManager().userId)
|
||||||
{
|
{
|
||||||
@ -71,7 +65,7 @@ export const NavigatorSearchResultItemView: FC<NavigatorSearchResultItemViewProp
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(thumbnail) return (
|
if(thumbnail) return (
|
||||||
<Flex pointer overflow="hidden" column={ true } alignItems="center" onClick={visitRoom} gap={0} className="navigator-item p-1 bg-light rounded-3 small mb-1 flex-column border border-muted" {...rest}>
|
<Column pointer overflow="hidden" alignItems="center" onClick={ visitRoom } gap={ 0 } className="navigator-item p-1 bg-light rounded-3 small mb-1 flex-column border border-muted" {...rest}>
|
||||||
<LayoutRoomThumbnailView roomId={roomData.roomId} customUrl={roomData.officialRoomPicRef} className="d-flex flex-column align-items-center justify-content-end mb-1">
|
<LayoutRoomThumbnailView roomId={roomData.roomId} customUrl={roomData.officialRoomPicRef} className="d-flex flex-column align-items-center justify-content-end mb-1">
|
||||||
<LayoutBadgeImageView badgeCode={roomData.groupBadgeCode} isGroup={true} className={ 'position-absolute top-0 start-0 m-1' } />
|
<LayoutBadgeImageView badgeCode={roomData.groupBadgeCode} isGroup={true} className={ 'position-absolute top-0 start-0 m-1' } />
|
||||||
<Flex center className={ 'badge p-1 position-absolute m-1 ' + getUserCounterColor() } gap={ 1 }>
|
<Flex center className={ 'badge p-1 position-absolute m-1 ' + getUserCounterColor() } gap={ 1 }>
|
||||||
@ -89,7 +83,7 @@ export const NavigatorSearchResultItemView: FC<NavigatorSearchResultItemViewProp
|
|||||||
{ children }
|
{ children }
|
||||||
</Flex>
|
</Flex>
|
||||||
|
|
||||||
</Flex>
|
</Column>
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -98,7 +92,7 @@ export const NavigatorSearchResultItemView: FC<NavigatorSearchResultItemViewProp
|
|||||||
<FontAwesomeIcon icon="user" />
|
<FontAwesomeIcon icon="user" />
|
||||||
{ roomData.userCount }
|
{ roomData.userCount }
|
||||||
</Flex>
|
</Flex>
|
||||||
<Text truncate className="flex-grow-1">{ roomData.roomName }</Text>
|
<Text truncate grow>{ roomData.roomName }</Text>
|
||||||
<Flex reverse alignItems="center" gap={ 1 }>
|
<Flex reverse alignItems="center" gap={ 1 }>
|
||||||
<NavigatorSearchResultItemInfoView roomData={ roomData } />
|
<NavigatorSearchResultItemInfoView roomData={ roomData } />
|
||||||
{ roomData.habboGroupId > 0 && <i className="icon icon-navigator-room-group" /> }
|
{ roomData.habboGroupId > 0 && <i className="icon icon-navigator-room-group" /> }
|
@ -1,8 +1,10 @@
|
|||||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||||
import React, { FC, KeyboardEvent, useCallback, useEffect, useState } from 'react';
|
import React, { FC, KeyboardEvent, useEffect, useState } from 'react';
|
||||||
import { LocalizeText } from '../../../../api';
|
import { LocalizeText } from '../../../../api';
|
||||||
import { Button } from '../../../../common/Button';
|
import { Button } from '../../../../common/Button';
|
||||||
import { Flex } from '../../../../common/Flex';
|
import { Flex } from '../../../../common/Flex';
|
||||||
|
import { BatchUpdates } from '../../../../hooks';
|
||||||
|
import { INavigatorSearchFilter } from '../../common/INavigatorSearchFilter';
|
||||||
import { SearchFilterOptions } from '../../common/SearchFilterOptions';
|
import { SearchFilterOptions } from '../../common/SearchFilterOptions';
|
||||||
import { useNavigatorContext } from '../../NavigatorContext';
|
import { useNavigatorContext } from '../../NavigatorContext';
|
||||||
|
|
||||||
@ -11,18 +13,14 @@ export interface NavigatorSearchViewProps
|
|||||||
sendSearch: (searchValue: string, contextCode: string) => void;
|
sendSearch: (searchValue: string, contextCode: string) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export let LAST_SEARCH: string = null;
|
|
||||||
|
|
||||||
export const NavigatorSearchView: FC<NavigatorSearchViewProps> = props =>
|
export const NavigatorSearchView: FC<NavigatorSearchViewProps> = props =>
|
||||||
{
|
{
|
||||||
const { sendSearch = null } = props;
|
const { sendSearch = null } = props;
|
||||||
const [ searchFilterIndex, setSearchFilterIndex ] = useState(0);
|
const [ searchFilterIndex, setSearchFilterIndex ] = useState(0);
|
||||||
const [ searchValue, setSearchValue ] = useState('');
|
const [ searchValue, setSearchValue ] = useState('');
|
||||||
const [ lastSearchQuery, setLastSearchQuery ] = useState('');
|
const { topLevelContext = null, searchResult = null } = useNavigatorContext();
|
||||||
const { navigatorState = null } = useNavigatorContext();
|
|
||||||
const { topLevelContext = null, searchResult = null } = navigatorState;
|
|
||||||
|
|
||||||
const processSearch = useCallback(() =>
|
const processSearch = () =>
|
||||||
{
|
{
|
||||||
if(!topLevelContext) return;
|
if(!topLevelContext) return;
|
||||||
|
|
||||||
@ -32,11 +30,8 @@ export const NavigatorSearchView: FC<NavigatorSearchViewProps> = props =>
|
|||||||
|
|
||||||
const searchQuery = ((searchFilter.query ? (searchFilter.query + ':') : '') + searchValue);
|
const searchQuery = ((searchFilter.query ? (searchFilter.query + ':') : '') + searchValue);
|
||||||
|
|
||||||
if(lastSearchQuery === searchQuery) return;
|
|
||||||
|
|
||||||
setLastSearchQuery(searchQuery);
|
|
||||||
sendSearch((searchQuery || ''), topLevelContext.code);
|
sendSearch((searchQuery || ''), topLevelContext.code);
|
||||||
}, [ lastSearchQuery, searchFilterIndex, searchValue, topLevelContext, sendSearch ]);
|
}
|
||||||
|
|
||||||
const handleKeyDown = (event: KeyboardEvent<HTMLInputElement>) =>
|
const handleKeyDown = (event: KeyboardEvent<HTMLInputElement>) =>
|
||||||
{
|
{
|
||||||
@ -47,20 +42,33 @@ export const NavigatorSearchView: FC<NavigatorSearchViewProps> = props =>
|
|||||||
|
|
||||||
useEffect(() =>
|
useEffect(() =>
|
||||||
{
|
{
|
||||||
if(!searchResult || !searchResult.data) return;
|
if(!searchResult) return null;
|
||||||
|
|
||||||
const searchResultDataParts = searchResult.data.split(':');
|
|
||||||
|
|
||||||
LAST_SEARCH = `${ topLevelContext.code }/${ searchResult.data }`;
|
const split = searchResult.data.split(':');
|
||||||
|
|
||||||
if(searchResultDataParts.length === 2)
|
let filter: INavigatorSearchFilter = null;
|
||||||
|
let value: string = '';
|
||||||
|
|
||||||
|
if(split.length >= 2)
|
||||||
{
|
{
|
||||||
let searchFilterIndex = SearchFilterOptions.findIndex(option => (option.query === searchResultDataParts[0]));
|
const [ query, ...rest ] = split;
|
||||||
|
|
||||||
if(searchFilterIndex > -1) setSearchFilterIndex(searchFilterIndex);
|
filter = SearchFilterOptions.find(option => (option.query === query));
|
||||||
setSearchValue(searchResultDataParts[1]);
|
value = rest.join(':');
|
||||||
}
|
}
|
||||||
}, [ searchResult, topLevelContext ]);
|
else
|
||||||
|
{
|
||||||
|
value = searchResult.data;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!filter) filter = SearchFilterOptions[0];
|
||||||
|
|
||||||
|
BatchUpdates(() =>
|
||||||
|
{
|
||||||
|
setSearchFilterIndex(SearchFilterOptions.findIndex(option => (option === filter)));
|
||||||
|
setSearchValue(value);
|
||||||
|
});
|
||||||
|
}, [ searchResult ]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Flex fullWidth gap={ 1 }>
|
<Flex fullWidth gap={ 1 }>
|
||||||
|
@ -3,19 +3,19 @@ import classNames from 'classnames';
|
|||||||
import { FC, useCallback, useEffect, useState } from 'react';
|
import { FC, useCallback, useEffect, useState } from 'react';
|
||||||
import { CreateLinkEvent, LocalizeText, RoomWidgetZoomToggleMessage, SendMessageComposer } from '../../../../api';
|
import { CreateLinkEvent, LocalizeText, RoomWidgetZoomToggleMessage, SendMessageComposer } from '../../../../api';
|
||||||
import { Base, Column, Flex, Text, TransitionAnimation, TransitionAnimationTypes } from '../../../../common';
|
import { Base, Column, Flex, Text, TransitionAnimation, TransitionAnimationTypes } from '../../../../common';
|
||||||
import { NavigatorEvent } from '../../../../events';
|
import { BatchUpdates, UseMessageEventHook, useSharedState } from '../../../../hooks';
|
||||||
import { BatchUpdates, DispatchUiEvent, UseMessageEventHook } from '../../../../hooks';
|
import { NavigatorData } from '../../../navigator/common/NavigatorData';
|
||||||
import { useRoomContext } from '../../RoomContext';
|
import { useRoomContext } from '../../RoomContext';
|
||||||
|
|
||||||
export const RoomToolsWidgetView: FC<{}> = props =>
|
export const RoomToolsWidgetView: FC<{}> = props =>
|
||||||
{
|
{
|
||||||
const [ isZoomedIn, setIsZoomedIn ] = useState(false);
|
const [ isZoomedIn, setIsZoomedIn ] = useState(false);
|
||||||
const [ isLiked, setIsLiked ] = useState(false);
|
|
||||||
const [ roomName, setRoomName ] = useState(null);
|
const [ roomName, setRoomName ] = useState(null);
|
||||||
const [ roomOwner, setRoomOwner ] = useState(null);
|
const [ roomOwner, setRoomOwner ] = useState(null);
|
||||||
const [ roomTags, setRoomTags ] = useState(null);
|
const [ roomTags, setRoomTags ] = useState(null);
|
||||||
const [ roomInfoDisplay, setRoomInfoDisplay ] = useState(false);
|
const [ roomInfoDisplay, setRoomInfoDisplay ] = useState(false);
|
||||||
const [ isOpen, setIsOpen ] = useState(false);
|
const [ isOpen, setIsOpen ] = useState(false);
|
||||||
|
const [ navigatorData, setNavigatorData ] = useSharedState<NavigatorData>('@navigatorData');
|
||||||
const { widgetHandler = null } = useRoomContext();
|
const { widgetHandler = null } = useRoomContext();
|
||||||
|
|
||||||
const handleToolClick = (action: string) =>
|
const handleToolClick = (action: string) =>
|
||||||
@ -23,7 +23,7 @@ export const RoomToolsWidgetView: FC<{}> = props =>
|
|||||||
switch(action)
|
switch(action)
|
||||||
{
|
{
|
||||||
case 'settings':
|
case 'settings':
|
||||||
DispatchUiEvent(new NavigatorEvent(NavigatorEvent.TOGGLE_ROOM_INFO));
|
CreateLinkEvent('navigator/toggle-room-info');
|
||||||
return;
|
return;
|
||||||
case 'zoom':
|
case 'zoom':
|
||||||
widgetHandler.processWidgetMessage(new RoomWidgetZoomToggleMessage(!isZoomedIn));
|
widgetHandler.processWidgetMessage(new RoomWidgetZoomToggleMessage(!isZoomedIn));
|
||||||
@ -33,13 +33,10 @@ export const RoomToolsWidgetView: FC<{}> = props =>
|
|||||||
CreateLinkEvent('chat-history/toggle');
|
CreateLinkEvent('chat-history/toggle');
|
||||||
return;
|
return;
|
||||||
case 'like_room':
|
case 'like_room':
|
||||||
if(isLiked) return;
|
|
||||||
|
|
||||||
SendMessageComposer(new RoomLikeRoomComposer(1));
|
SendMessageComposer(new RoomLikeRoomComposer(1));
|
||||||
setIsLiked(true);
|
|
||||||
return;
|
return;
|
||||||
case 'toggle_room_link':
|
case 'toggle_room_link':
|
||||||
DispatchUiEvent(new NavigatorEvent(NavigatorEvent.TOGGLE_ROOM_LINK));
|
CreateLinkEvent('navigator/toggle-room-link');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -68,6 +65,11 @@ export const RoomToolsWidgetView: FC<{}> = props =>
|
|||||||
|
|
||||||
return () => clearTimeout(timeout);
|
return () => clearTimeout(timeout);
|
||||||
}, [ roomName, roomOwner, roomTags ]);
|
}, [ roomName, roomOwner, roomTags ]);
|
||||||
|
|
||||||
|
useEffect(() =>
|
||||||
|
{
|
||||||
|
console.log(navigatorData);
|
||||||
|
}, [ navigatorData ]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Flex className="nitro-room-tools-container" gap={ 2 }>
|
<Flex className="nitro-room-tools-container" gap={ 2 }>
|
||||||
@ -75,7 +77,8 @@ export const RoomToolsWidgetView: FC<{}> = props =>
|
|||||||
<Base pointer title={ LocalizeText('room.settings.button.text') } className="icon icon-cog" onClick={ () => handleToolClick('settings') } />
|
<Base pointer title={ LocalizeText('room.settings.button.text') } className="icon icon-cog" onClick={ () => handleToolClick('settings') } />
|
||||||
<Base pointer title={ LocalizeText('room.zoom.button.text') } onClick={ () => handleToolClick('zoom') } className={ 'icon ' + classNames({ 'icon-zoom-less': !isZoomedIn, 'icon-zoom-more': isZoomedIn }) } />
|
<Base pointer title={ LocalizeText('room.zoom.button.text') } onClick={ () => handleToolClick('zoom') } className={ 'icon ' + classNames({ 'icon-zoom-less': !isZoomedIn, 'icon-zoom-more': isZoomedIn }) } />
|
||||||
<Base pointer title={ LocalizeText('room.chathistory.button.text') } onClick={ () => handleToolClick('chat_history') } className="icon icon-chat-history" />
|
<Base pointer title={ LocalizeText('room.chathistory.button.text') } onClick={ () => handleToolClick('chat_history') } className="icon icon-chat-history" />
|
||||||
{ !isLiked && <Base pointer title={ LocalizeText('room.like.button.text') } onClick={ () => handleToolClick('like_room') } className="icon icon-like-room" /> }
|
{ navigatorData.canRate &&
|
||||||
|
<Base pointer title={ LocalizeText('room.like.button.text') } onClick={ () => handleToolClick('like_room') } className="icon icon-like-room" /> }
|
||||||
</Column>
|
</Column>
|
||||||
<Column justifyContent="center">
|
<Column justifyContent="center">
|
||||||
<TransitionAnimation type={ TransitionAnimationTypes.SLIDE_LEFT } inProp={ isOpen } timeout={ 300 }>
|
<TransitionAnimation type={ TransitionAnimationTypes.SLIDE_LEFT } inProp={ isOpen } timeout={ 300 }>
|
||||||
|
@ -2,7 +2,7 @@ import { Dispose, DropBounce, EaseOut, FigureUpdateEvent, JumpBy, Motions, Nitro
|
|||||||
import { FC, useCallback, useState } from 'react';
|
import { FC, useCallback, useState } from 'react';
|
||||||
import { CreateLinkEvent, GetSessionDataManager, GetUserProfile, OpenMessengerChat, VisitDesktop } from '../../api';
|
import { CreateLinkEvent, GetSessionDataManager, GetUserProfile, OpenMessengerChat, VisitDesktop } from '../../api';
|
||||||
import { Base, Flex, LayoutAvatarImageView, LayoutItemCountView, TransitionAnimation, TransitionAnimationTypes } from '../../common';
|
import { Base, Flex, LayoutAvatarImageView, LayoutItemCountView, TransitionAnimation, TransitionAnimationTypes } from '../../common';
|
||||||
import { AchievementsUIEvent, AchievementsUIUnseenCountEvent, FriendsEvent, FriendsMessengerIconEvent, FriendsRequestCountEvent, GuideToolEvent, InventoryEvent, ModToolsEvent, NavigatorEvent, UnseenItemTrackerUpdateEvent, UserSettingsUIEvent } from '../../events';
|
import { AchievementsUIEvent, AchievementsUIUnseenCountEvent, FriendsEvent, FriendsMessengerIconEvent, FriendsRequestCountEvent, GuideToolEvent, InventoryEvent, ModToolsEvent, UnseenItemTrackerUpdateEvent, UserSettingsUIEvent } from '../../events';
|
||||||
import { BatchUpdates, DispatchUiEvent, UseMessageEventHook, UseRoomEngineEvent, UseUiEvent } from '../../hooks';
|
import { BatchUpdates, DispatchUiEvent, UseMessageEventHook, UseRoomEngineEvent, UseUiEvent } from '../../hooks';
|
||||||
import { ToolbarViewItems } from './common/ToolbarViewItems';
|
import { ToolbarViewItems } from './common/ToolbarViewItems';
|
||||||
import { ToolbarMeView } from './ToolbarMeView';
|
import { ToolbarMeView } from './ToolbarMeView';
|
||||||
@ -135,7 +135,7 @@ export const ToolbarView: FC<ToolbarViewProps> = props =>
|
|||||||
switch(item)
|
switch(item)
|
||||||
{
|
{
|
||||||
case ToolbarViewItems.NAVIGATOR_ITEM:
|
case ToolbarViewItems.NAVIGATOR_ITEM:
|
||||||
DispatchUiEvent(new NavigatorEvent(NavigatorEvent.TOGGLE_NAVIGATOR));
|
CreateLinkEvent('navigator/toggle');
|
||||||
return;
|
return;
|
||||||
case ToolbarViewItems.INVENTORY_ITEM:
|
case ToolbarViewItems.INVENTORY_ITEM:
|
||||||
DispatchUiEvent(new InventoryEvent(InventoryEvent.TOGGLE_INVENTORY));
|
DispatchUiEvent(new InventoryEvent(InventoryEvent.TOGGLE_INVENTORY));
|
||||||
|
@ -1,33 +0,0 @@
|
|||||||
import { NitroEvent } from '@nitrots/nitro-renderer';
|
|
||||||
|
|
||||||
export class NavigatorEvent extends NitroEvent
|
|
||||||
{
|
|
||||||
public static SHOW_NAVIGATOR: string = 'NE_SHOW_NAVIGATOR';
|
|
||||||
public static HIDE_NAVIGATOR: string = 'NE_HIDE_NAVIGATOR';
|
|
||||||
public static TOGGLE_NAVIGATOR: string = 'NE_TOGGLE_NAVIGATOR';
|
|
||||||
public static TOGGLE_ROOM_INFO: string = 'NE_TOGGLE_ROOM_INFO';
|
|
||||||
public static TOGGLE_ROOM_LINK: string = 'NE_TOGGLE_ROOM_LINK';
|
|
||||||
public static TOGGLE_ROOM_SETTINGS: string = 'NE_TOGGLE_ROOM_SETTINGS';
|
|
||||||
public static SHOW_ROOM_CREATOR: string = 'NE_TOGGLE_CREATOR';
|
|
||||||
|
|
||||||
private _roomId: number;
|
|
||||||
private _password: string;
|
|
||||||
|
|
||||||
constructor(type: string, roomId: number = -1, password = null)
|
|
||||||
{
|
|
||||||
super(type);
|
|
||||||
|
|
||||||
this._roomId = roomId;
|
|
||||||
this._password = password;
|
|
||||||
}
|
|
||||||
|
|
||||||
public get roomId(): number
|
|
||||||
{
|
|
||||||
return this._roomId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public get password(): string
|
|
||||||
{
|
|
||||||
return this._password;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,2 +1 @@
|
|||||||
export * from './NavigatorEvent';
|
|
||||||
export * from './UpdateDoorStateEvent';
|
export * from './UpdateDoorStateEvent';
|
||||||
|
67
src/hooks/UseSharedState.ts
Normal file
67
src/hooks/UseSharedState.ts
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
import { Dispatch, SetStateAction, useEffect, useState } from 'react';
|
||||||
|
|
||||||
|
const sharedStates: Map<string, any> = new Map();
|
||||||
|
const sharedSetters: Map<string, Dispatch<SetStateAction<any>>[]> = new Map();
|
||||||
|
|
||||||
|
export const useSharedState = <T>(key: string, initialValue?: T | (() => T)): [T, Dispatch<SetStateAction<T>>] =>
|
||||||
|
{
|
||||||
|
const [ state, setState ] = useState<T>(() =>
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
const item = sharedStates.get(key);
|
||||||
|
|
||||||
|
return item || initialValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
catch (error)
|
||||||
|
{
|
||||||
|
console.error(error);
|
||||||
|
|
||||||
|
return initialValue;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const updateState: Dispatch<SetStateAction<T>> = data =>
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
const valueToStore = data instanceof Function ? data(state as T) : data;
|
||||||
|
const setters = sharedSetters.get(key);
|
||||||
|
|
||||||
|
if(setters) for(const setter of setters) setter(valueToStore);
|
||||||
|
|
||||||
|
sharedStates.set(key, valueToStore);
|
||||||
|
}
|
||||||
|
|
||||||
|
catch (error)
|
||||||
|
{
|
||||||
|
console.error(error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect(() =>
|
||||||
|
{
|
||||||
|
if(!key || !key.length) return;
|
||||||
|
|
||||||
|
let existing = sharedSetters.get(key);
|
||||||
|
|
||||||
|
if(!existing)
|
||||||
|
{
|
||||||
|
existing = [];
|
||||||
|
|
||||||
|
sharedSetters.set(key, existing);
|
||||||
|
}
|
||||||
|
|
||||||
|
existing.push(setState);
|
||||||
|
|
||||||
|
return () =>
|
||||||
|
{
|
||||||
|
const index = existing.findIndex(dispatch => (dispatch === setState));
|
||||||
|
|
||||||
|
if(index >= 0) existing.splice(index, 1);
|
||||||
|
}
|
||||||
|
}, [ key ]);
|
||||||
|
|
||||||
|
return [ state as T, updateState ];
|
||||||
|
}
|
@ -5,3 +5,4 @@ export * from './events/nitro';
|
|||||||
export * from './events/ui';
|
export * from './events/ui';
|
||||||
export * from './messages';
|
export * from './messages';
|
||||||
export * from './UseMountEffect';
|
export * from './UseMountEffect';
|
||||||
|
export * from './UseSharedState';
|
||||||
|
@ -1426,10 +1426,10 @@
|
|||||||
"@jridgewell/resolve-uri" "^3.0.3"
|
"@jridgewell/resolve-uri" "^3.0.3"
|
||||||
"@jridgewell/sourcemap-codec" "^1.4.10"
|
"@jridgewell/sourcemap-codec" "^1.4.10"
|
||||||
|
|
||||||
"@nitrots/nitro-renderer@^1.1.13":
|
"@nitrots/nitro-renderer@^1.1.14":
|
||||||
version "1.1.13"
|
version "1.1.14"
|
||||||
resolved "https://registry.yarnpkg.com/@nitrots/nitro-renderer/-/nitro-renderer-1.1.13.tgz#0173ebda69c41031903461a21a4b3dfa0bd6fcaa"
|
resolved "https://registry.yarnpkg.com/@nitrots/nitro-renderer/-/nitro-renderer-1.1.14.tgz#30c792572f4df26e85efab0342894bfeb10c3cfa"
|
||||||
integrity sha512-LGk8514m+/+Y50kOdkP7dVG9DXTNPM3kD/U+wDJBw6MPkxe0R2blhwPoELK02jO6Ehfoz5v+nlhNeUTHzRZzeg==
|
integrity sha512-P4ruZ7eJ169q/pzsTN/AYf5pqr4ZoTCefvsAGHON4VSFqUO1vIivqqNmTgWJlBHMukj2VqrbLZukYrbt0+cUCQ==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@pixi/canvas-renderer" "^6.2.2"
|
"@pixi/canvas-renderer" "^6.2.2"
|
||||||
"@pixi/extract" "^6.2.2"
|
"@pixi/extract" "^6.2.2"
|
||||||
|
Loading…
Reference in New Issue
Block a user