feat: added navigator saved searches

This commit is contained in:
object 2023-03-17 01:16:03 +01:00 committed by Gurkengewuerz
parent da833a60fc
commit fa48030d43
8 changed files with 168 additions and 10 deletions

View File

@ -0,0 +1,20 @@
import {FC} from "react";
import {FaBolt} from "react-icons/fa";
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}>
<FaBolt />
</Base>
);
};

View File

@ -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";

View File

@ -57,3 +57,23 @@
.room-info {
width: 275px;
}
.nitro-navigator-search-saves-result {
background-color: #fff;
width: 100px;
height: 350px;
border-radius: 10px;
.bg-orange {
background-color: #faa700;
}
}
.button-search-saves {
padding: 4px;
height: 17px;
margin-top: -1px;
font-size: 10px;
border-radius: 4px;
background-color: #faa700;
}

View File

@ -11,7 +11,17 @@ import {FC, useCallback, useEffect, useRef, useState} from "react";
import {FaPlus} from "react-icons/fa";
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";
@ -19,6 +29,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 => {
@ -27,10 +38,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>();
@ -195,6 +207,9 @@ export const NavigatorView: FC<{}> = props => {
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) => {
@ -212,10 +227,19 @@ export const NavigatorView: FC<{}> = props => {
{isLoading && <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 />}

View File

@ -1,9 +1,9 @@
import {NavigatorSearchComposer, NavigatorSearchResultList} from "@nitro/renderer";
import {NavigatorSearchComposer, NavigatorSearchResultList, NavigatorSearchSaveComposer} from "@nitro/renderer";
import {FC, useEffect, useState} from "react";
import {FaBars, FaMinus, FaPlus, FaTh, FaWindowMaximize, FaWindowRestore} from "react-icons/fa";
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,7 +16,7 @@ export const NavigatorSearchResultView: FC<NavigatorSearchResultViewProps> = pro
const [isExtended, setIsExtended] = useState(true);
const [displayMode, setDisplayMode] = useState<number>(0);
const {topLevelContext = null} = useNavigator();
const {topLevelContext = null, searchResultQuery = null} = useNavigator();
const getResultTitle = () => {
let name = searchResult.code;
@ -64,6 +64,12 @@ export const NavigatorSearchResultView: FC<NavigatorSearchResultViewProps> = pro
{displayMode >= NavigatorSearchResultViewDisplayMode.THUMBNAILS && <FaBars className="text-secondary fa-icon" onClick={toggleDisplayMode} />}
{searchResult.action > 0 && searchResult.action === 1 && <FaWindowMaximize className="text-secondary fa-icon" onClick={showMore} />}
{searchResult.action > 0 && searchResult.action !== 1 && <FaWindowRestore className="text-secondary fa-icon" onClick={showMore} />}
{topLevelContext.code !== "official_view" && (
<LayoutSearchSavesView
title={LocalizeText("navigator.tooltip.add.saved.search")}
onSaveSearch={() => SendMessageComposer(new NavigatorSearchSaveComposer(getResultTitle(), searchResultQuery))}
/>
)}
</Flex>
</Flex>{" "}
{isExtended && (

View File

@ -0,0 +1,47 @@
import {NavigatorDeleteSavedSearchComposer, NavigatorSavedSearch, NavigatorSearchComposer} from "@nitro/renderer";
import {FC, useState} from "react";
import {FaMinus} from "react-icons/fa";
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 && (
<FaMinus
color="red"
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>
);
};

View File

@ -0,0 +1,27 @@
import {NavigatorSavedSearch} from "@nitro/renderer";
import {FC} from "react";
import {FaBolt} from "react-icons/fa";
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}>
<FaBolt color="white" />
<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>
);
};

View File

@ -17,8 +17,10 @@ import {
NavigatorHomeRoomEvent,
NavigatorMetadataEvent,
NavigatorOpenRoomCreatorEvent,
NavigatorSavedSearch,
NavigatorSearchEvent,
NavigatorSearchResultSet,
NavigatorSearchesEvent,
NavigatorTopLevelContext,
RoomDataParser,
RoomDoorbellAcceptedEvent,
@ -59,6 +61,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,
@ -334,6 +338,7 @@ const useNavigatorState = () => {
});
setSearchResult(parser.result);
setSearchResultQuery(parser.result.data);
});
useMessageEvent<UserFlatCatsEvent>(UserFlatCatsEvent, event => {
@ -428,7 +433,15 @@ 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);