mirror of
https://github.com/billsonnn/nitro-react.git
synced 2024-11-22 22:30:52 +01:00
#55 - Navigator saved searches
This commit is contained in:
parent
9693bcae0b
commit
00fab2b19e
21
src/common/layout/LayoutSearchSavesView.tsx
Normal file
21
src/common/layout/LayoutSearchSavesView.tsx
Normal file
@ -0,0 +1,21 @@
|
||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||
import { FC } from 'react';
|
||||
import { Base } from '../Base';
|
||||
|
||||
export interface LayoutSearchSavesViewProps
|
||||
{
|
||||
title: string;
|
||||
onSaveSearch?: () => void;
|
||||
onClick?: () => void;
|
||||
}
|
||||
|
||||
export const LayoutSearchSavesView: FC<LayoutSearchSavesViewProps> = props =>
|
||||
{
|
||||
const { title = null, onSaveSearch = null, onClick = null } = props;
|
||||
|
||||
return (
|
||||
<Base color="white" className="button-search-saves" pointer title={ title } onClickCapture={ onSaveSearch } onClick={ onClick }>
|
||||
<FontAwesomeIcon icon="bolt-lightning" />
|
||||
</Base>
|
||||
);
|
||||
}
|
@ -18,6 +18,7 @@ export * from './LayoutProgressBar';
|
||||
export * from './LayoutRarityLevelView';
|
||||
export * from './LayoutRoomPreviewerView';
|
||||
export * from './LayoutRoomThumbnailView';
|
||||
export * from './LayoutSearchSavesView';
|
||||
export * from './LayoutTrophyView';
|
||||
export * from './limited-edition';
|
||||
export * from './UserProfileIconView';
|
||||
|
@ -15,17 +15,17 @@
|
||||
&:not(.two-columns) {
|
||||
|
||||
.navigator-item {
|
||||
|
||||
|
||||
&:nth-child(odd) {
|
||||
background-color: $grid-active-bg-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
&.two-columns {
|
||||
|
||||
|
||||
.navigator-item {
|
||||
|
||||
|
||||
&:nth-child(4n-2),
|
||||
&:nth-child(4n-3) {
|
||||
background: $grid-active-bg-color;
|
||||
@ -60,6 +60,26 @@
|
||||
}
|
||||
}
|
||||
|
||||
.nitro-navigator-search-saves-result {
|
||||
background-color: #fff;
|
||||
width: 100px;
|
||||
height: 350px;
|
||||
border-radius: 10px;
|
||||
|
||||
.bg-orange {
|
||||
background-color: #FAA700;
|
||||
}
|
||||
}
|
||||
|
||||
.room-info {
|
||||
width: 275px;
|
||||
}
|
||||
|
||||
.button-search-saves {
|
||||
padding: 4px;
|
||||
height: 17px;
|
||||
margin-top: -1px;
|
||||
font-size: 10px;
|
||||
border-radius: 4px;
|
||||
background-color: #FAA700;
|
||||
}
|
||||
|
@ -2,7 +2,7 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||
import { ConvertGlobalRoomIdMessageComposer, HabboWebTools, ILinkEventTracker, LegacyExternalInterface, NavigatorInitComposer, NavigatorSearchComposer, RoomSessionEvent } from '@nitrots/nitro-renderer';
|
||||
import { FC, useCallback, useEffect, useRef, useState } from 'react';
|
||||
import { AddEventLinkTracker, LocalizeText, RemoveLinkEventTracker, SendMessageComposer, TryVisitRoom } from '../../api';
|
||||
import { Base, Column, NitroCardContentView, NitroCardHeaderView, NitroCardTabsItemView, NitroCardTabsView, NitroCardView } from '../../common';
|
||||
import { Base, Column, Flex, LayoutSearchSavesView, NitroCardContentView, NitroCardHeaderView, NitroCardTabsItemView, NitroCardTabsView, NitroCardView } from '../../common';
|
||||
import { useNavigator, useRoomSessionManagerEvent } from '../../hooks';
|
||||
import { NavigatorDoorStateView } from './views/NavigatorDoorStateView';
|
||||
import { NavigatorRoomCreatorView } from './views/NavigatorRoomCreatorView';
|
||||
@ -10,6 +10,7 @@ import { NavigatorRoomInfoView } from './views/NavigatorRoomInfoView';
|
||||
import { NavigatorRoomLinkView } from './views/NavigatorRoomLinkView';
|
||||
import { NavigatorRoomSettingsView } from './views/room-settings/NavigatorRoomSettingsView';
|
||||
import { NavigatorSearchResultView } from './views/search/NavigatorSearchResultView';
|
||||
import { NavigatorSearchSavesResultView } from './views/search/NavigatorSearchSavesResultView';
|
||||
import { NavigatorSearchView } from './views/search/NavigatorSearchView';
|
||||
|
||||
export const NavigatorView: FC<{}> = props =>
|
||||
@ -19,10 +20,11 @@ export const NavigatorView: FC<{}> = props =>
|
||||
const [ isCreatorOpen, setCreatorOpen ] = useState(false);
|
||||
const [ isRoomInfoOpen, setRoomInfoOpen ] = useState(false);
|
||||
const [ isRoomLinkOpen, setRoomLinkOpen ] = useState(false);
|
||||
const [ isOpenSavesSearchs, setIsOpenSavesSearchs ] = useState(false);
|
||||
const [ isLoading, setIsLoading ] = useState(false);
|
||||
const [ needsInit, setNeedsInit ] = useState(true);
|
||||
const [ needsSearch, setNeedsSearch ] = useState(false);
|
||||
const { searchResult = null, topLevelContext = null, topLevelContexts = null, navigatorData = null } = useNavigator();
|
||||
const { searchResult = null, topLevelContext = null, topLevelContexts = null, navigatorData = null, navigatorSearches = null } = useNavigator();
|
||||
const pendingSearch = useRef<{ value: string, code: string }>(null);
|
||||
const elementRef = useRef<HTMLDivElement>();
|
||||
|
||||
@ -77,9 +79,9 @@ export const NavigatorView: FC<{}> = props =>
|
||||
linkReceived: (url: string) =>
|
||||
{
|
||||
const parts = url.split('/');
|
||||
|
||||
|
||||
if(parts.length < 2) return;
|
||||
|
||||
|
||||
switch(parts[1])
|
||||
{
|
||||
case 'show': {
|
||||
@ -94,10 +96,10 @@ export const NavigatorView: FC<{}> = props =>
|
||||
if(isVisible)
|
||||
{
|
||||
setIsVisible(false);
|
||||
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
setIsVisible(true);
|
||||
setNeedsSearch(true);
|
||||
return;
|
||||
@ -110,17 +112,17 @@ export const NavigatorView: FC<{}> = props =>
|
||||
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);
|
||||
}
|
||||
}
|
||||
@ -133,13 +135,13 @@ export const NavigatorView: FC<{}> = props =>
|
||||
if(parts.length > 2)
|
||||
{
|
||||
const topLevelContextCode = parts[2];
|
||||
|
||||
|
||||
let searchValue = '';
|
||||
|
||||
|
||||
if(parts.length > 3) searchValue = parts[3];
|
||||
|
||||
|
||||
pendingSearch.current = { value: searchValue, code: topLevelContextCode };
|
||||
|
||||
|
||||
setIsVisible(true);
|
||||
setNeedsSearch(true);
|
||||
}
|
||||
@ -199,6 +201,9 @@ export const NavigatorView: FC<{}> = props =>
|
||||
<NitroCardView uniqueKey="navigator" className="nitro-navigator">
|
||||
<NitroCardHeaderView headerText={ LocalizeText(isCreatorOpen ? 'navigator.createroom.title' : 'navigator.title') } onCloseClick={ event => setIsVisible(false) } />
|
||||
<NitroCardTabsView>
|
||||
<Base className="mt-1">
|
||||
<LayoutSearchSavesView title={ LocalizeText('navigator.tooltip.left.show.hide') } onClick={ () => setIsOpenSavesSearchs(prevValue => !prevValue) } />
|
||||
</Base>
|
||||
{ topLevelContexts && (topLevelContexts.length > 0) && topLevelContexts.map((context, index) =>
|
||||
{
|
||||
return (
|
||||
@ -216,10 +221,18 @@ export const NavigatorView: FC<{}> = props =>
|
||||
<Base fit position="absolute" className="top-0 start-0 z-index-1 bg-muted opacity-0-5" /> }
|
||||
{ !isCreatorOpen &&
|
||||
<>
|
||||
<NavigatorSearchView sendSearch={ sendSearch } />
|
||||
<Column innerRef={ elementRef } overflow="auto">
|
||||
{ (searchResult && searchResult.results.map((result, index) => <NavigatorSearchResultView key={ index } searchResult={ result } />)) }
|
||||
</Column>
|
||||
<Flex gap={ 1 }>
|
||||
{ (isOpenSavesSearchs) &&
|
||||
<Column>
|
||||
<NavigatorSearchSavesResultView searchs={ navigatorSearches } />
|
||||
</Column> }
|
||||
<Column fullWidth>
|
||||
<NavigatorSearchView sendSearch={ sendSearch } />
|
||||
<Column innerRef={ elementRef } overflow="auto">
|
||||
{ (searchResult && searchResult.results.map((result, index) => <NavigatorSearchResultView key={ index } searchResult={ result } />)) }
|
||||
</Column>
|
||||
</Column>
|
||||
</Flex>
|
||||
</> }
|
||||
{ isCreatorOpen && <NavigatorRoomCreatorView /> }
|
||||
</NitroCardContentView>
|
||||
|
@ -1,8 +1,8 @@
|
||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||
import { NavigatorSearchComposer, NavigatorSearchResultList } from '@nitrots/nitro-renderer';
|
||||
import { NavigatorSearchComposer, NavigatorSearchResultList, NavigatorSearchSaveComposer } from '@nitrots/nitro-renderer';
|
||||
import { FC, useEffect, useState } from 'react';
|
||||
import { LocalizeText, NavigatorSearchResultViewDisplayMode, SendMessageComposer } from '../../../../api';
|
||||
import { AutoGrid, AutoGridProps, Column, Flex, Grid, Text } from '../../../../common';
|
||||
import { AutoGrid, AutoGridProps, Column, Flex, Grid, LayoutSearchSavesView, Text } from '../../../../common';
|
||||
import { useNavigator } from '../../../../hooks';
|
||||
import { NavigatorSearchResultItemView } from './NavigatorSearchResultItemView';
|
||||
|
||||
@ -16,8 +16,7 @@ export const NavigatorSearchResultView: FC<NavigatorSearchResultViewProps> = pro
|
||||
const { searchResult = null, ...rest } = props;
|
||||
const [ isExtended, setIsExtended ] = useState(true);
|
||||
const [ displayMode, setDisplayMode ] = useState<number>(0);
|
||||
|
||||
const { topLevelContext = null } = useNavigator();
|
||||
const { topLevelContext = null, searchResultQuery = null } = useNavigator();
|
||||
|
||||
const getResultTitle = () =>
|
||||
{
|
||||
@ -39,8 +38,8 @@ export const NavigatorSearchResultView: FC<NavigatorSearchResultViewProps> = pro
|
||||
return NavigatorSearchResultViewDisplayMode.LIST;
|
||||
});
|
||||
}
|
||||
|
||||
const showMore = () =>
|
||||
|
||||
const showMore = () =>
|
||||
{
|
||||
if(searchResult.action == 1) SendMessageComposer(new NavigatorSearchComposer(searchResult.code, ''));
|
||||
else if(searchResult.action == 2 && topLevelContext) SendMessageComposer(new NavigatorSearchComposer(topLevelContext.code,''));
|
||||
@ -51,12 +50,12 @@ export const NavigatorSearchResultView: FC<NavigatorSearchResultViewProps> = pro
|
||||
if(!searchResult) return;
|
||||
|
||||
setIsExtended(!searchResult.closed);
|
||||
|
||||
|
||||
setDisplayMode(searchResult.mode);
|
||||
}, [ searchResult ]);
|
||||
|
||||
const gridHasTwoColumns = (displayMode >= NavigatorSearchResultViewDisplayMode.THUMBNAILS);
|
||||
|
||||
|
||||
return (
|
||||
<Column className="bg-white rounded border border-muted" gap={ 0 }>
|
||||
<Flex fullWidth alignItems="center" justifyContent="between" className="px-2 py-1">
|
||||
@ -67,9 +66,11 @@ export const NavigatorSearchResultView: FC<NavigatorSearchResultViewProps> = pro
|
||||
<Flex gap={ 2 }>
|
||||
<FontAwesomeIcon icon={ ((displayMode === NavigatorSearchResultViewDisplayMode.LIST) ? 'th' : (displayMode >= NavigatorSearchResultViewDisplayMode.THUMBNAILS) ? 'bars' : null) } className="text-secondary" onClick={ toggleDisplayMode } />
|
||||
{ (searchResult.action > 0) && <FontAwesomeIcon icon={ searchResult.action == 1 ? 'window-maximize' : 'window-restore' } className="text-secondary" onClick={ showMore } /> }
|
||||
{ (topLevelContext.code !== 'official_view') &&
|
||||
<LayoutSearchSavesView title={ LocalizeText('navigator.tooltip.add.saved.search') } onSaveSearch={ () => SendMessageComposer(new NavigatorSearchSaveComposer(getResultTitle(), searchResultQuery)) } /> }
|
||||
</Flex>
|
||||
|
||||
</Flex> { isExtended &&
|
||||
</Flex> { isExtended &&
|
||||
<>
|
||||
{
|
||||
gridHasTwoColumns ? <AutoGrid columnCount={ 3 } { ...rest } columnMinWidth={ 110 } columnMinHeight={ 130 } className="mx-2">
|
||||
|
@ -0,0 +1,37 @@
|
||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||
import { NavigatorDeleteSavedSearchComposer, NavigatorSavedSearch, NavigatorSearchComposer } from '@nitrots/nitro-renderer';
|
||||
import { FC, useState } from 'react';
|
||||
import { LocalizeText, SendMessageComposer } from '../../../../api';
|
||||
import { Flex, Text } from '../../../../common';
|
||||
|
||||
export interface NavigatorSearchSavesResultItemViewProps
|
||||
{
|
||||
search: NavigatorSavedSearch
|
||||
}
|
||||
|
||||
export const NavigatorSearchSavesResultItemView: FC<NavigatorSearchSavesResultItemViewProps> = props =>
|
||||
{
|
||||
const { search = null } = props;
|
||||
const [ isHoverText, setIsHoverText ] = useState<boolean>(false);
|
||||
const [ currentIndex, setCurrentIndex ] = useState<number>(0);
|
||||
|
||||
const onHover = (searchId: number) =>
|
||||
{
|
||||
setCurrentIndex(searchId);
|
||||
setIsHoverText(true);
|
||||
}
|
||||
|
||||
const onLeave = () =>
|
||||
{
|
||||
setCurrentIndex(0);
|
||||
setIsHoverText(false);
|
||||
}
|
||||
|
||||
return (
|
||||
<Flex grow pointer alignItems="center" gap={ 1 } onMouseEnter={ () => onHover(search.id) } onMouseLeave={ () => onLeave() }>
|
||||
{ (isHoverText && currentIndex === search.id) &&
|
||||
<FontAwesomeIcon color="red" icon="subtract" title={ LocalizeText('navigator.tooltip.remove.saved.search') } onClick={ () => SendMessageComposer(new NavigatorDeleteSavedSearchComposer(search.id)) } /> }
|
||||
<Text pointer variant="black" title={ LocalizeText('navigator.tooltip.open.saved.search') } onClick={ () => SendMessageComposer(new NavigatorSearchComposer(search.code.split('.').reverse()[0], search.filter)) }>{ search.filter !== '' ? LocalizeText('navigator.searchcode.title.query') + ': ' + (!search.filter.split(':')[1] ? search.filter : search.filter.split(':')[1]) : LocalizeText(`${ search.code }`) }</Text>
|
||||
</Flex>
|
||||
);
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||
import { NavigatorSavedSearch } from '@nitrots/nitro-renderer';
|
||||
import { FC } from 'react';
|
||||
import { LocalizeText } from '../../../../api';
|
||||
import { Column, Flex, Text } from '../../../../common';
|
||||
import { NavigatorSearchSavesResultItemView } from './NavigatorSearchSavesResultItemView';
|
||||
|
||||
export interface NavigatorSearchSavesResultViewProps
|
||||
{
|
||||
searchs: NavigatorSavedSearch[]
|
||||
}
|
||||
|
||||
export const NavigatorSearchSavesResultView: FC<NavigatorSearchSavesResultViewProps> = props =>
|
||||
{
|
||||
const { searchs = [] } = props;
|
||||
|
||||
return (
|
||||
<Column className="nitro-navigator-search-saves-result">
|
||||
<Flex className="badge p-1 bg-orange" gap={ 1 }>
|
||||
<FontAwesomeIcon color="white" icon="bolt-lightning" />
|
||||
<Text variant="white">{ LocalizeText('navigator.quick.links.title') }</Text>
|
||||
</Flex>
|
||||
<Column className="p-1" style={ { overflowX: 'hidden', overflowY: 'auto' } }>
|
||||
{ (searchs && searchs.length > 0) &&
|
||||
searchs.map((search: NavigatorSavedSearch) => <NavigatorSearchSavesResultItemView key={ search.id } search={ search } />)
|
||||
}
|
||||
</Column>
|
||||
</Column>
|
||||
);
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
import { CanCreateRoomEventEvent, CantConnectMessageParser, DoorbellMessageEvent, FlatAccessDeniedMessageEvent, FlatCreatedEvent, FollowFriendMessageComposer, GenericErrorEvent, GetGuestRoomMessageComposer, GetGuestRoomResultEvent, GetUserEventCatsMessageComposer, GetUserFlatCatsMessageComposer, HabboWebTools, LegacyExternalInterface, NavigatorCategoryDataParser, NavigatorEventCategoryDataParser, NavigatorHomeRoomEvent, NavigatorMetadataEvent, NavigatorOpenRoomCreatorEvent, NavigatorSearchEvent, NavigatorSearchResultSet, NavigatorTopLevelContext, RoomDataParser, RoomDoorbellAcceptedEvent, RoomEnterErrorEvent, RoomEntryInfoMessageEvent, RoomForwardEvent, RoomScoreEvent, RoomSettingsUpdatedEvent, SecurityLevel, UserEventCatsEvent, UserFlatCatsEvent, UserInfoEvent, UserPermissionsEvent } from '@nitrots/nitro-renderer';
|
||||
import { CanCreateRoomEventEvent, CantConnectMessageParser, DoorbellMessageEvent, FlatAccessDeniedMessageEvent, FlatCreatedEvent, FollowFriendMessageComposer, GenericErrorEvent, GetGuestRoomMessageComposer, GetGuestRoomResultEvent, GetUserEventCatsMessageComposer, GetUserFlatCatsMessageComposer, HabboWebTools, LegacyExternalInterface, NavigatorCategoryDataParser, NavigatorEventCategoryDataParser, NavigatorHomeRoomEvent, NavigatorMetadataEvent, NavigatorOpenRoomCreatorEvent, NavigatorSavedSearch, NavigatorSearchesEvent, NavigatorSearchEvent, NavigatorSearchResultSet, NavigatorTopLevelContext, RoomDataParser, RoomDoorbellAcceptedEvent, RoomEnterErrorEvent, RoomEntryInfoMessageEvent, RoomForwardEvent, RoomScoreEvent, RoomSettingsUpdatedEvent, SecurityLevel, UserEventCatsEvent, UserFlatCatsEvent, UserInfoEvent, UserPermissionsEvent } from '@nitrots/nitro-renderer';
|
||||
import { useState } from 'react';
|
||||
import { useBetween } from 'use-between';
|
||||
import { CreateLinkEvent, CreateRoomSession, DoorStateType, GetConfiguration, GetSessionDataManager, INavigatorData, LocalizeText, NotificationAlertType, SendMessageComposer, TryVisitRoom, VisitDesktop } from '../../api';
|
||||
@ -13,6 +13,8 @@ const useNavigatorState = () =>
|
||||
const [ topLevelContexts, setTopLevelContexts ] = useState<NavigatorTopLevelContext[]>(null);
|
||||
const [ doorData, setDoorData ] = useState<{ roomInfo: RoomDataParser, state: number }>({ roomInfo: null, state: DoorStateType.NONE });
|
||||
const [ searchResult, setSearchResult ] = useState<NavigatorSearchResultSet>(null);
|
||||
const [ searchResultQuery, setSearchResultQuery ] = useState<string>('');
|
||||
const [ navigatorSearches, setNavigatorSearches ] = useState<NavigatorSavedSearch[]>(null);
|
||||
const [ navigatorData, setNavigatorData ] = useState<INavigatorData>({
|
||||
settingsReceived: false,
|
||||
homeRoomId: 0,
|
||||
@ -198,7 +200,7 @@ const useNavigatorState = () =>
|
||||
});
|
||||
});
|
||||
|
||||
useMessageEvent<DoorbellMessageEvent>(DoorbellMessageEvent, event =>
|
||||
useMessageEvent<DoorbellMessageEvent>(DoorbellMessageEvent, event =>
|
||||
{
|
||||
const parser = event.getParser();
|
||||
|
||||
@ -325,6 +327,7 @@ const useNavigatorState = () =>
|
||||
});
|
||||
|
||||
setSearchResult(parser.result);
|
||||
setSearchResultQuery(parser.result.data);
|
||||
});
|
||||
|
||||
useMessageEvent<UserFlatCatsEvent>(UserFlatCatsEvent, event =>
|
||||
@ -436,7 +439,16 @@ const useNavigatorState = () =>
|
||||
|
||||
useMessageEvent<NavigatorOpenRoomCreatorEvent>(NavigatorOpenRoomCreatorEvent, event => CreateLinkEvent('navigator/show'));
|
||||
|
||||
return { categories, doorData, setDoorData, topLevelContext, topLevelContexts, searchResult, navigatorData };
|
||||
useMessageEvent<NavigatorSearchesEvent>(NavigatorSearchesEvent, event =>
|
||||
{
|
||||
const parser = event.getParser();
|
||||
|
||||
if (!parser) return;
|
||||
|
||||
setNavigatorSearches(parser.searches);
|
||||
});
|
||||
|
||||
return { categories, doorData, setDoorData, topLevelContext, topLevelContexts, searchResult, navigatorData, navigatorSearches, searchResultQuery };
|
||||
}
|
||||
|
||||
export const useNavigator = () => useBetween(useNavigatorState);
|
||||
|
Loading…
Reference in New Issue
Block a user