[web] Search related refactoring - Part x/x (#3224)
This commit is contained in:
@@ -1,7 +1,11 @@
|
||||
import { assertionFailed } from "@/base/assert";
|
||||
import { useIsMobileWidth } from "@/base/hooks";
|
||||
import { FileType } from "@/media/file-type";
|
||||
import { PeopleList } from "@/new/photos/components/PeopleList";
|
||||
import { isMLEnabled } from "@/new/photos/services/ml";
|
||||
import {
|
||||
isMLSupported,
|
||||
mlStatusSnapshot,
|
||||
mlStatusSubscribe,
|
||||
} from "@/new/photos/services/ml";
|
||||
import type {
|
||||
City,
|
||||
SearchDateComponents,
|
||||
@@ -12,7 +16,6 @@ import {
|
||||
ClipSearchScores,
|
||||
SearchOption,
|
||||
SearchQuery,
|
||||
Suggestion,
|
||||
SuggestionType,
|
||||
} from "@/new/photos/services/search/types";
|
||||
import { labelForSuggestionType } from "@/new/photos/services/search/ui";
|
||||
@@ -20,7 +23,6 @@ import type { LocationTag } from "@/new/photos/services/user-entity";
|
||||
import { EnteFile } from "@/new/photos/types/file";
|
||||
import {
|
||||
FreeFlowText,
|
||||
Row,
|
||||
SpaceBetweenFlex,
|
||||
} from "@ente/shared/components/Container";
|
||||
import CalendarIcon from "@mui/icons-material/CalendarMonth";
|
||||
@@ -49,22 +51,18 @@ import {
|
||||
useMemo,
|
||||
useRef,
|
||||
useState,
|
||||
useSyncExternalStore,
|
||||
} from "react";
|
||||
import {
|
||||
components as SelectComponents,
|
||||
type ControlProps,
|
||||
type InputActionMeta,
|
||||
type InputProps,
|
||||
type MenuProps,
|
||||
type OptionProps,
|
||||
type SelectInstance,
|
||||
type StylesConfig,
|
||||
} from "react-select";
|
||||
import AsyncSelect from "react-select/async";
|
||||
import {
|
||||
getAutoCompleteSuggestions,
|
||||
getDefaultOptions,
|
||||
} from "services/searchService";
|
||||
import { getAutoCompleteSuggestions } from "services/searchService";
|
||||
import { Collection } from "types/collection";
|
||||
|
||||
interface SearchBarProps {
|
||||
@@ -139,23 +137,15 @@ const SearchInput: React.FC<SearchInputProps> = ({
|
||||
// The currently selected option.
|
||||
const [value, setValue] = useState<SearchOption | undefined>();
|
||||
// The contents of the input field associated with the select.
|
||||
const [query, setQuery] = useState("");
|
||||
// The default options shown in the select menu when nothing has been typed.
|
||||
const [defaultOptions, setDefaultOptions] = useState([]);
|
||||
const [inputValue, setInputValue] = useState("");
|
||||
|
||||
useEffect(() => {
|
||||
search(value);
|
||||
}, [value]);
|
||||
|
||||
useEffect(() => {
|
||||
refreshDefaultOptions();
|
||||
const t = setInterval(() => refreshDefaultOptions(), 2000);
|
||||
return () => clearInterval(t);
|
||||
}, []);
|
||||
|
||||
const handleChange = (value: SearchOption) => {
|
||||
setValue(value);
|
||||
setQuery(value?.label);
|
||||
setInputValue(value?.label);
|
||||
// The Select has a blurInputOnSelect prop, but that makes the input
|
||||
// field lose focus, not the entire menu (e.g. when pressing twice).
|
||||
//
|
||||
@@ -166,14 +156,10 @@ const SearchInput: React.FC<SearchInputProps> = ({
|
||||
|
||||
const handleInputChange = (value: string, actionMeta: InputActionMeta) => {
|
||||
if (actionMeta.action === "input-change") {
|
||||
setQuery(value);
|
||||
setInputValue(value);
|
||||
}
|
||||
};
|
||||
|
||||
const refreshDefaultOptions = async () => {
|
||||
setDefaultOptions(await getDefaultOptions());
|
||||
};
|
||||
|
||||
const resetSearch = () => {
|
||||
if (isOpen) {
|
||||
appContext.startLoading();
|
||||
@@ -183,7 +169,7 @@ const SearchInput: React.FC<SearchInputProps> = ({
|
||||
}, 10);
|
||||
setIsOpen(false);
|
||||
setValue(null);
|
||||
setQuery("");
|
||||
setInputValue("");
|
||||
}
|
||||
};
|
||||
|
||||
@@ -219,7 +205,7 @@ const SearchInput: React.FC<SearchInputProps> = ({
|
||||
case SuggestionType.COLLECTION:
|
||||
search = { collection: selectedOption.value as number };
|
||||
setValue(null);
|
||||
setQuery("");
|
||||
setInputValue("");
|
||||
break;
|
||||
case SuggestionType.FILE_NAME:
|
||||
search = { files: selectedOption.value as number[] };
|
||||
@@ -242,38 +228,34 @@ const SearchInput: React.FC<SearchInputProps> = ({
|
||||
});
|
||||
};
|
||||
|
||||
// TODO: HACK as AsyncSelect does not support default options reloading on focus/click
|
||||
// unwanted side effect: placeholder is not shown on focus/click
|
||||
// https://github.com/JedWatson/react-select/issues/1879
|
||||
// for correct fix AsyncSelect can be extended to support default options reloading on focus/click
|
||||
const handleOnFocus = () => {
|
||||
refreshDefaultOptions();
|
||||
const handleSelectCGroup = (value: SearchOption) => {
|
||||
// Dismiss the search menu.
|
||||
selectRef.current?.blur();
|
||||
setValue(value);
|
||||
};
|
||||
|
||||
const components = useMemo(
|
||||
() => ({ Option, Control, Menu: CustomMenu, Input: Input }),
|
||||
[],
|
||||
);
|
||||
const components = useMemo(() => ({ Option, Control, Input }), []);
|
||||
|
||||
return (
|
||||
<SearchInputWrapper>
|
||||
<AsyncSelect
|
||||
ref={selectRef}
|
||||
value={value}
|
||||
// @ts-expect-error Type of the Menu is not what Select expects
|
||||
components={components}
|
||||
placeholder={t("search_hint")}
|
||||
loadOptions={getOptions}
|
||||
onChange={handleChange}
|
||||
onFocus={handleOnFocus}
|
||||
isMulti={false}
|
||||
isClearable
|
||||
escapeClearsValue
|
||||
inputValue={query}
|
||||
inputValue={inputValue}
|
||||
onInputChange={handleInputChange}
|
||||
styles={SelectStyles}
|
||||
defaultOptions={isMLEnabled() ? defaultOptions : []}
|
||||
noOptionsMessage={() => null}
|
||||
noOptionsMessage={({ inputValue }) =>
|
||||
shouldShowEmptyState(inputValue) ? (
|
||||
<EmptyState onSelectCGroup={handleSelectCGroup} />
|
||||
) : null
|
||||
}
|
||||
/>
|
||||
|
||||
{isOpen && (
|
||||
@@ -299,7 +281,8 @@ const SelectStyles: StylesConfig<SearchOption, false> = {
|
||||
container: (style) => ({ ...style, flex: 1 }),
|
||||
control: (style, { isFocused }) => ({
|
||||
...style,
|
||||
backgroundColor: "rgba(255, 255, 255, 0.1)",
|
||||
// Give a solid background color.
|
||||
backgroundColor: "rgb(26, 26, 26)",
|
||||
borderColor: isFocused ? "#1DB954" : "transparent",
|
||||
boxShadow: "none",
|
||||
":hover": {
|
||||
@@ -310,8 +293,11 @@ const SelectStyles: StylesConfig<SearchOption, false> = {
|
||||
input: (styles) => ({ ...styles, color: "#fff" }),
|
||||
menu: (style) => ({
|
||||
...style,
|
||||
// Suppress the default margin at the top.
|
||||
marginTop: "1px",
|
||||
backgroundColor: "#1b1b1b",
|
||||
// Same background color as the control (must be solid, otherwise the
|
||||
// content behind the menu shows through).
|
||||
backgroundColor: "rgb(26, 26, 26)",
|
||||
}),
|
||||
option: (style, { isFocused }) => ({
|
||||
...style,
|
||||
@@ -327,14 +313,15 @@ const SelectStyles: StylesConfig<SearchOption, false> = {
|
||||
display: "none",
|
||||
},
|
||||
}),
|
||||
dropdownIndicator: (style) => ({ ...style, display: "none" }),
|
||||
indicatorSeparator: (style) => ({ ...style, display: "none" }),
|
||||
clearIndicator: (style) => ({ ...style, display: "none" }),
|
||||
placeholder: (style) => ({
|
||||
...style,
|
||||
color: "rgba(255, 255, 255, 0.7)",
|
||||
whiteSpace: "nowrap",
|
||||
}),
|
||||
// Hide some things we don't need.
|
||||
dropdownIndicator: (style) => ({ ...style, display: "none" }),
|
||||
indicatorSeparator: (style) => ({ ...style, display: "none" }),
|
||||
clearIndicator: (style) => ({ ...style, display: "none" }),
|
||||
};
|
||||
|
||||
const Control = ({ children, ...props }: ControlProps<SearchOption, false>) => (
|
||||
@@ -379,6 +366,165 @@ const iconForOptionType = (type: SuggestionType | undefined) => {
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* A preflight check for whether or not we should show the EmptyState.
|
||||
*
|
||||
* react-select seems to only suppress showing anything at all in the menu if we
|
||||
* return `null` from the function passed to `noOptionsMessage`. Returning
|
||||
* `false`, or returning `null` from the EmptyState itself doesn't work and
|
||||
* causes a empty div to be shown instead.
|
||||
*/
|
||||
const shouldShowEmptyState = (inputValue: string) => {
|
||||
// Don't show empty state if the user has entered search input.
|
||||
if (inputValue) return false;
|
||||
|
||||
// Don't show empty state if there is no ML related information.
|
||||
if (!isMLSupported) return false;
|
||||
|
||||
const status = isMLSupported && mlStatusSnapshot();
|
||||
if (!status || status.phase == "disabled") return false;
|
||||
|
||||
// Show it otherwise.
|
||||
return true;
|
||||
};
|
||||
|
||||
interface EmptyStateProps {
|
||||
/** Called when the user selects a cgroup shown in the empty state view. */
|
||||
onSelectCGroup: (value: SearchOption) => void;
|
||||
}
|
||||
|
||||
/**
|
||||
* The view shown in the menu area when the user has not typed anything in the
|
||||
* search box.
|
||||
*/
|
||||
const EmptyState: React.FC<EmptyStateProps> = () => {
|
||||
const mlStatus = useSyncExternalStore(mlStatusSubscribe, mlStatusSnapshot);
|
||||
|
||||
if (!mlStatus || mlStatus.phase == "disabled") {
|
||||
assertionFailed();
|
||||
return <></>;
|
||||
}
|
||||
|
||||
let label: string;
|
||||
switch (mlStatus.phase) {
|
||||
case "scheduled":
|
||||
label = t("indexing_scheduled");
|
||||
break;
|
||||
case "indexing":
|
||||
label = t("indexing_photos", mlStatus);
|
||||
break;
|
||||
case "fetching":
|
||||
label = t("indexing_fetching", mlStatus);
|
||||
break;
|
||||
case "clustering":
|
||||
label = t("indexing_people", mlStatus);
|
||||
break;
|
||||
case "done":
|
||||
label = t("indexing_done", mlStatus);
|
||||
break;
|
||||
}
|
||||
|
||||
return (
|
||||
<Box>
|
||||
<Typography variant="mini" sx={{ textAlign: "left" }}>
|
||||
{label}
|
||||
</Typography>
|
||||
</Box>
|
||||
);
|
||||
|
||||
// TODO-Cluster
|
||||
// const options = props.selectProps.options as SearchOption[];
|
||||
// const peopleSuggestions = options.filter(
|
||||
// (o) => o.type === SuggestionType.PERSON,
|
||||
// );
|
||||
// const people = peopleSuggestions.map((o) => o.value as SearchPerson);
|
||||
// return (
|
||||
// <SelectComponents.Menu {...props}>
|
||||
// <Box my={1}>
|
||||
// {isMLEnabled() &&
|
||||
// indexStatus &&
|
||||
// (people && people.length > 0 ? (
|
||||
// <Box>
|
||||
// <Legend>{t("people")}</Legend>
|
||||
// </Box>
|
||||
// ) : (
|
||||
// <Box height={6} />
|
||||
// ))}
|
||||
// {isMLEnabled() && indexStatus && (
|
||||
// <Box>
|
||||
// <Caption>{indexStatusSuggestion.label}</Caption>
|
||||
// </Box>
|
||||
// )}
|
||||
// {people && people.length > 0 && (
|
||||
// <Row> // "@ente/shared/components/Container"
|
||||
// <PeopleList // @/new/photos/components/PeopleList
|
||||
// people={people}
|
||||
// maxRows={2}
|
||||
// onSelect={(_, index) => {
|
||||
// }}
|
||||
// />
|
||||
// </Row>
|
||||
// )}
|
||||
// </Box>
|
||||
// {props.children}
|
||||
// </SelectComponents.Menu>
|
||||
// );
|
||||
};
|
||||
|
||||
// TODO-Cluster
|
||||
// const Legend = styled("span")`
|
||||
// font-size: 20px;
|
||||
// color: #ddd;
|
||||
// display: inline;
|
||||
// padding: 0px 12px;
|
||||
// `;
|
||||
|
||||
/*
|
||||
TODO: Cluster
|
||||
|
||||
export async function getAllPeopleSuggestion(): Promise<Array<Suggestion>> {
|
||||
try {
|
||||
const people = await getAllPeople(200);
|
||||
return people.map((person) => ({
|
||||
label: person.name,
|
||||
type: SuggestionType.PERSON,
|
||||
value: person,
|
||||
hide: true,
|
||||
}));
|
||||
} catch (e) {
|
||||
log.error("getAllPeopleSuggestion failed", e);
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
async function getAllPeople(limit: number = undefined) {
|
||||
return (await wipSearchPersons()).slice(0, limit);
|
||||
// TODO-Clustetr
|
||||
// if (done) return [];
|
||||
|
||||
// done = true;
|
||||
// if (process.env.NEXT_PUBLIC_ENTE_WIP_CL_FETCH) {
|
||||
// await syncCGroups();
|
||||
// const people = await clusterGroups();
|
||||
// log.debug(() => ["people", { people }]);
|
||||
// }
|
||||
|
||||
// let people: Array<SearchPerson> = []; // await mlIDbStorage.getAllPeople();
|
||||
// people = await wipCluster();
|
||||
// // await mlPeopleStore.iterate<Person, void>((person) => {
|
||||
// // people.push(person);
|
||||
// // });
|
||||
// people = people ?? [];
|
||||
// const result = people
|
||||
// .sort((p1, p2) => p2.files.length - p1.files.length)
|
||||
// .slice(0, limit);
|
||||
// // log.debug(() => ["getAllPeople", result]);
|
||||
|
||||
// return result;
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
const Option: React.FC<OptionProps<SearchOption, false>> = (props) => (
|
||||
<SelectComponents.Option {...props}>
|
||||
<LabelWithInfo data={props.data} />
|
||||
@@ -387,116 +533,40 @@ const Option: React.FC<OptionProps<SearchOption, false>> = (props) => (
|
||||
|
||||
const LabelWithInfo = ({ data }: { data: SearchOption }) => {
|
||||
return (
|
||||
!data.hide && (
|
||||
<>
|
||||
<Box className="main" px={2} py={1}>
|
||||
<Typography variant="mini" mb={1}>
|
||||
{labelForSuggestionType(data.type)}
|
||||
</Typography>
|
||||
<SpaceBetweenFlex>
|
||||
<Box mr={1}>
|
||||
<FreeFlowText>
|
||||
<Typography fontWeight={"bold"}>
|
||||
{data.label}
|
||||
</Typography>
|
||||
</FreeFlowText>
|
||||
<Typography color="text.muted">
|
||||
{t("photos_count", { count: data.fileCount })}
|
||||
<>
|
||||
<Box className="main" px={2} py={1}>
|
||||
<Typography variant="mini" mb={1}>
|
||||
{labelForSuggestionType(data.type)}
|
||||
</Typography>
|
||||
<SpaceBetweenFlex>
|
||||
<Box mr={1}>
|
||||
<FreeFlowText>
|
||||
<Typography fontWeight={"bold"}>
|
||||
{data.label}
|
||||
</Typography>
|
||||
</Box>
|
||||
|
||||
<Stack direction={"row"} spacing={1}>
|
||||
{data.previewFiles.map((file) => (
|
||||
<CollectionCard
|
||||
key={file.id}
|
||||
coverFile={file}
|
||||
onClick={() => null}
|
||||
collectionTile={ResultPreviewTile}
|
||||
/>
|
||||
))}
|
||||
</Stack>
|
||||
</SpaceBetweenFlex>
|
||||
</Box>
|
||||
<Divider sx={{ mx: 2, my: 1 }} />
|
||||
</>
|
||||
)
|
||||
);
|
||||
};
|
||||
|
||||
type CustomMenuProps = MenuProps<SearchOption, false> & {
|
||||
selectRef: React.RefObject<SelectInstance>;
|
||||
// Cannot call it setValue since the menu itself already has that.
|
||||
setSelectedValue: (value: SearchOption) => void;
|
||||
};
|
||||
|
||||
const CustomMenu: React.FC<CustomMenuProps> = ({
|
||||
selectRef,
|
||||
setSelectedValue,
|
||||
...props
|
||||
}) => {
|
||||
// Need to cast here, otherwise the react-select types think selectProps can
|
||||
// also be something that supports multiple selection groups.
|
||||
const options = props.selectProps.options as SearchOption[];
|
||||
|
||||
const peopleSuggestions = options.filter(
|
||||
(o) => o.type === SuggestionType.PERSON,
|
||||
);
|
||||
const people = peopleSuggestions.map((o) => o.value as SearchPerson);
|
||||
|
||||
const indexStatusSuggestion = options.filter(
|
||||
(o) => o.type === SuggestionType.INDEX_STATUS,
|
||||
)[0] as Suggestion;
|
||||
|
||||
const indexStatus = indexStatusSuggestion?.value;
|
||||
return (
|
||||
<SelectComponents.Menu {...props}>
|
||||
<Box my={1}>
|
||||
{isMLEnabled() &&
|
||||
indexStatus &&
|
||||
(people && people.length > 0 ? (
|
||||
<Box>
|
||||
<Legend>{t("people")}</Legend>
|
||||
</Box>
|
||||
) : (
|
||||
<Box height={6} />
|
||||
))}
|
||||
|
||||
{isMLEnabled() && indexStatus && (
|
||||
<Box>
|
||||
<Caption>{indexStatusSuggestion.label}</Caption>
|
||||
</FreeFlowText>
|
||||
<Typography color="text.muted">
|
||||
{t("photos_count", { count: data.fileCount })}
|
||||
</Typography>
|
||||
</Box>
|
||||
)}
|
||||
{people && people.length > 0 && (
|
||||
<Row>
|
||||
<PeopleList
|
||||
people={people}
|
||||
maxRows={2}
|
||||
onSelect={(_, index) => {
|
||||
selectRef.current?.blur();
|
||||
setSelectedValue(peopleSuggestions[index]);
|
||||
}}
|
||||
/>
|
||||
</Row>
|
||||
)}
|
||||
|
||||
<Stack direction={"row"} spacing={1}>
|
||||
{data.previewFiles.map((file) => (
|
||||
<CollectionCard
|
||||
key={file.id}
|
||||
coverFile={file}
|
||||
onClick={() => null}
|
||||
collectionTile={ResultPreviewTile}
|
||||
/>
|
||||
))}
|
||||
</Stack>
|
||||
</SpaceBetweenFlex>
|
||||
</Box>
|
||||
{props.children}
|
||||
</SelectComponents.Menu>
|
||||
<Divider sx={{ mx: 2, my: 1 }} />
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
const Legend = styled("span")`
|
||||
font-size: 20px;
|
||||
color: #ddd;
|
||||
display: inline;
|
||||
padding: 0px 12px;
|
||||
`;
|
||||
|
||||
const Caption = styled("span")`
|
||||
font-size: 12px;
|
||||
display: inline;
|
||||
padding: 0px 12px;
|
||||
`;
|
||||
|
||||
// A custom input for react-select that is always visible. This is a roundabout
|
||||
// hack the existing code used to display the search string when showing the
|
||||
// results page; likely there should be a better way.
|
||||
|
||||
@@ -1,10 +1,5 @@
|
||||
import log from "@/base/log";
|
||||
import { FileType } from "@/media/file-type";
|
||||
import {
|
||||
isMLSupported,
|
||||
mlStatusSnapshot,
|
||||
wipSearchPersons,
|
||||
} from "@/new/photos/services/ml";
|
||||
import { createSearchQuery, search } from "@/new/photos/services/search";
|
||||
import type {
|
||||
SearchDateComponents,
|
||||
@@ -20,19 +15,9 @@ import {
|
||||
} from "@/new/photos/services/search/types";
|
||||
import type { LocationTag } from "@/new/photos/services/user-entity";
|
||||
import { EnteFile } from "@/new/photos/types/file";
|
||||
import { t } from "i18next";
|
||||
import { Collection } from "types/collection";
|
||||
import { getUniqueFiles } from "utils/file";
|
||||
|
||||
// Suggestions shown in the search dropdown's empty state, i.e. when the user
|
||||
// selects the search bar but does not provide any input.
|
||||
export const getDefaultOptions = async () => {
|
||||
return [
|
||||
await getMLStatusSuggestion(),
|
||||
...(await convertSuggestionsToOptions(await getAllPeopleSuggestion())),
|
||||
].filter((t) => !!t);
|
||||
};
|
||||
|
||||
// Suggestions shown in the search dropdown when the user has typed something.
|
||||
export const getAutoCompleteSuggestions =
|
||||
(files: EnteFile[], collections: Collection[]) =>
|
||||
@@ -87,55 +72,6 @@ async function convertSuggestionsToOptions(
|
||||
return previewImageAppendedOptions;
|
||||
}
|
||||
|
||||
export async function getAllPeopleSuggestion(): Promise<Array<Suggestion>> {
|
||||
try {
|
||||
const people = await getAllPeople(200);
|
||||
return people.map((person) => ({
|
||||
label: person.name,
|
||||
type: SuggestionType.PERSON,
|
||||
value: person,
|
||||
hide: true,
|
||||
}));
|
||||
} catch (e) {
|
||||
log.error("getAllPeopleSuggestion failed", e);
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
export async function getMLStatusSuggestion(): Promise<Suggestion> {
|
||||
if (!isMLSupported) return undefined;
|
||||
|
||||
const status = mlStatusSnapshot();
|
||||
|
||||
if (!status || status.phase == "disabled") return undefined;
|
||||
|
||||
let label: string;
|
||||
switch (status.phase) {
|
||||
case "scheduled":
|
||||
label = t("indexing_scheduled");
|
||||
break;
|
||||
case "indexing":
|
||||
label = t("indexing_photos", status);
|
||||
break;
|
||||
case "fetching":
|
||||
label = t("indexing_fetching", status);
|
||||
break;
|
||||
case "clustering":
|
||||
label = t("indexing_people", status);
|
||||
break;
|
||||
case "done":
|
||||
label = t("indexing_done", status);
|
||||
break;
|
||||
}
|
||||
|
||||
return {
|
||||
label,
|
||||
type: SuggestionType.INDEX_STATUS,
|
||||
value: status,
|
||||
hide: true,
|
||||
};
|
||||
}
|
||||
|
||||
function getCollectionSuggestion(
|
||||
searchPhrase: string,
|
||||
collections: Collection[],
|
||||
@@ -237,29 +173,3 @@ function convertSuggestionToSearchQuery(option: Suggestion): SearchQuery {
|
||||
return { clip: option.value as ClipSearchScores };
|
||||
}
|
||||
}
|
||||
|
||||
async function getAllPeople(limit: number = undefined) {
|
||||
return (await wipSearchPersons()).slice(0, limit);
|
||||
// TODO-Clustetr
|
||||
// if (done) return [];
|
||||
|
||||
// done = true;
|
||||
// if (process.env.NEXT_PUBLIC_ENTE_WIP_CL_FETCH) {
|
||||
// await syncCGroups();
|
||||
// const people = await clusterGroups();
|
||||
// log.debug(() => ["people", { people }]);
|
||||
// }
|
||||
|
||||
// let people: Array<SearchPerson> = []; // await mlIDbStorage.getAllPeople();
|
||||
// people = await wipCluster();
|
||||
// // await mlPeopleStore.iterate<Person, void>((person) => {
|
||||
// // people.push(person);
|
||||
// // });
|
||||
// people = people ?? [];
|
||||
// const result = people
|
||||
// .sort((p1, p2) => p2.files.length - p1.files.length)
|
||||
// .slice(0, limit);
|
||||
// // log.debug(() => ["getAllPeople", result]);
|
||||
|
||||
// return result;
|
||||
}
|
||||
|
||||
@@ -33,8 +33,9 @@
|
||||
"preview:staff": "yarn workspace staff preview"
|
||||
},
|
||||
"resolutions": {
|
||||
"@emotion/cache": "11.11.0",
|
||||
"@emotion/react": "11.11.3"
|
||||
"@emotion/cache": "11.13.1",
|
||||
"@emotion/react": "^11.13.3",
|
||||
"@emotion/styled": "^11.13.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"concurrently": "^8.2.2",
|
||||
|
||||
@@ -4,8 +4,12 @@ import log from "./log";
|
||||
/**
|
||||
* If running in a dev build, throw an exception with the given message.
|
||||
* Otherwise log it as a warning.
|
||||
*
|
||||
* @param message An optional message to use for the failure. If not provided,
|
||||
* then a generic one is used.
|
||||
*/
|
||||
export const assertionFailed = (message: string) => {
|
||||
export const assertionFailed = (message?: string) => {
|
||||
message = message ?? "Assertion failed";
|
||||
if (isDevBuild) throw new Error(message);
|
||||
log.warn(message);
|
||||
};
|
||||
|
||||
@@ -3,21 +3,21 @@
|
||||
"version": "0.0.0",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@emotion/react": "11.11.3",
|
||||
"@emotion/styled": "^11.11.5",
|
||||
"@mui/icons-material": "^5.16",
|
||||
"@mui/material": "^5.16",
|
||||
"comlink": "^4.4",
|
||||
"get-user-locale": "^2.3",
|
||||
"i18next": "^23.11",
|
||||
"i18next-resources-to-backend": "^1.2",
|
||||
"is-electron": "^2.2",
|
||||
"@emotion/react": "11.13.3",
|
||||
"@emotion/styled": "^11.13.0",
|
||||
"@mui/icons-material": "^5.16.6",
|
||||
"@mui/material": "^5.16.6",
|
||||
"comlink": "^4.4.1",
|
||||
"get-user-locale": "^2.3.2",
|
||||
"i18next": "^23.15.1",
|
||||
"i18next-resources-to-backend": "^1.2.1",
|
||||
"is-electron": "^2.2.2",
|
||||
"libsodium-wrappers-sumo": "^0.7.15",
|
||||
"nanoid": "^5.0.7",
|
||||
"next": "^14.2",
|
||||
"react": "^18",
|
||||
"react-dom": "^18",
|
||||
"react-i18next": "^14"
|
||||
"react-i18next": "^15.0.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@/build-config": "*",
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
|
||||
import type { Location } from "@/base/types";
|
||||
import { FileType } from "@/media/file-type";
|
||||
import type { MLStatus } from "@/new/photos/services/ml";
|
||||
import type { EnteFile } from "@/new/photos/types/file";
|
||||
import type { LocationTag } from "../user-entity";
|
||||
|
||||
@@ -106,7 +105,6 @@ export enum SuggestionType {
|
||||
COLLECTION = "COLLECTION",
|
||||
FILE_NAME = "FILE_NAME",
|
||||
PERSON = "PERSON",
|
||||
INDEX_STATUS = "INDEX_STATUS",
|
||||
FILE_CAPTION = "FILE_CAPTION",
|
||||
FILE_TYPE = "FILE_TYPE",
|
||||
CLIP = "CLIP",
|
||||
@@ -120,12 +118,10 @@ export interface Suggestion {
|
||||
| SearchDateComponents
|
||||
| number[]
|
||||
| SearchPerson
|
||||
| MLStatus
|
||||
| LocationTag
|
||||
| City
|
||||
| FileType
|
||||
| ClipSearchScores;
|
||||
hide?: boolean;
|
||||
}
|
||||
|
||||
export interface SearchQuery {
|
||||
|
||||
@@ -18,8 +18,6 @@ export const labelForSuggestionType = (type: SuggestionType) => {
|
||||
return t("file_name");
|
||||
case SuggestionType.PERSON:
|
||||
return t("person");
|
||||
case SuggestionType.INDEX_STATUS:
|
||||
throw new Error("Not a displayable key");
|
||||
case SuggestionType.FILE_CAPTION:
|
||||
return t("description");
|
||||
case SuggestionType.FILE_TYPE:
|
||||
|
||||
317
web/yarn.lock
317
web/yarn.lock
@@ -204,6 +204,13 @@
|
||||
dependencies:
|
||||
regenerator-runtime "^0.14.0"
|
||||
|
||||
"@babel/runtime@^7.24.8":
|
||||
version "7.25.6"
|
||||
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.25.6.tgz#9afc3289f7184d8d7f98b099884c26317b9264d2"
|
||||
integrity sha512-VBj9MYyDb9tuLq7yzqjgzt6Q+IBQLrGZfdjOekyEirZPHxXWoTSGUTMrpsfi58Up73d13NfYLv8HT9vmznjzhQ==
|
||||
dependencies:
|
||||
regenerator-runtime "^0.14.0"
|
||||
|
||||
"@babel/runtime@^7.25.0":
|
||||
version "7.25.0"
|
||||
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.25.0.tgz#3af9a91c1b739c569d5d80cc917280919c544ecb"
|
||||
@@ -250,16 +257,16 @@
|
||||
resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz#1d572bfbbe14b7704e0ba0f39b74815b84870d70"
|
||||
integrity sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==
|
||||
|
||||
"@emotion/babel-plugin@^11.11.0":
|
||||
version "11.11.0"
|
||||
resolved "https://registry.yarnpkg.com/@emotion/babel-plugin/-/babel-plugin-11.11.0.tgz#c2d872b6a7767a9d176d007f5b31f7d504bb5d6c"
|
||||
integrity sha512-m4HEDZleaaCH+XgDDsPF15Ht6wTLsgDTeR3WYj9Q/k76JtWhrJjcP4+/XlG8LGT/Rol9qUfOIztXeA84ATpqPQ==
|
||||
"@emotion/babel-plugin@^11.12.0":
|
||||
version "11.12.0"
|
||||
resolved "https://registry.yarnpkg.com/@emotion/babel-plugin/-/babel-plugin-11.12.0.tgz#7b43debb250c313101b3f885eba634f1d723fcc2"
|
||||
integrity sha512-y2WQb+oP8Jqvvclh8Q55gLUyb7UFvgv7eJfsj7td5TToBrIUtPay2kMrZi4xjq9qw2vD0ZR5fSho0yqoFgX7Rw==
|
||||
dependencies:
|
||||
"@babel/helper-module-imports" "^7.16.7"
|
||||
"@babel/runtime" "^7.18.3"
|
||||
"@emotion/hash" "^0.9.1"
|
||||
"@emotion/memoize" "^0.8.1"
|
||||
"@emotion/serialize" "^1.1.2"
|
||||
"@emotion/hash" "^0.9.2"
|
||||
"@emotion/memoize" "^0.9.0"
|
||||
"@emotion/serialize" "^1.2.0"
|
||||
babel-plugin-macros "^3.1.0"
|
||||
convert-source-map "^1.5.0"
|
||||
escape-string-regexp "^4.0.0"
|
||||
@@ -267,95 +274,95 @@
|
||||
source-map "^0.5.7"
|
||||
stylis "4.2.0"
|
||||
|
||||
"@emotion/cache@11.11.0", "@emotion/cache@^11.11.0", "@emotion/cache@^11.4.0":
|
||||
version "11.11.0"
|
||||
resolved "https://registry.yarnpkg.com/@emotion/cache/-/cache-11.11.0.tgz#809b33ee6b1cb1a625fef7a45bc568ccd9b8f3ff"
|
||||
integrity sha512-P34z9ssTCBi3e9EI1ZsWpNHcfY1r09ZO0rZbRO2ob3ZQMnFI35jB536qoXbkdesr5EUhYi22anuEJuyxifaqAQ==
|
||||
"@emotion/cache@11.13.1", "@emotion/cache@^11.11.0", "@emotion/cache@^11.13.0", "@emotion/cache@^11.4.0":
|
||||
version "11.13.1"
|
||||
resolved "https://registry.yarnpkg.com/@emotion/cache/-/cache-11.13.1.tgz#fecfc54d51810beebf05bf2a161271a1a91895d7"
|
||||
integrity sha512-iqouYkuEblRcXmylXIwwOodiEK5Ifl7JcX7o6V4jI3iW4mLXX3dmt5xwBtIkJiQEXFAI+pC8X0i67yiPkH9Ucw==
|
||||
dependencies:
|
||||
"@emotion/memoize" "^0.8.1"
|
||||
"@emotion/sheet" "^1.2.2"
|
||||
"@emotion/utils" "^1.2.1"
|
||||
"@emotion/weak-memoize" "^0.3.1"
|
||||
"@emotion/memoize" "^0.9.0"
|
||||
"@emotion/sheet" "^1.4.0"
|
||||
"@emotion/utils" "^1.4.0"
|
||||
"@emotion/weak-memoize" "^0.4.0"
|
||||
stylis "4.2.0"
|
||||
|
||||
"@emotion/hash@^0.9.1":
|
||||
version "0.9.1"
|
||||
resolved "https://registry.yarnpkg.com/@emotion/hash/-/hash-0.9.1.tgz#4ffb0055f7ef676ebc3a5a91fb621393294e2f43"
|
||||
integrity sha512-gJB6HLm5rYwSLI6PQa+X1t5CFGrv1J1TWG+sOyMCeKz2ojaj6Fnl/rZEspogG+cvqbt4AE/2eIyD2QfLKTBNlQ==
|
||||
"@emotion/hash@^0.9.2":
|
||||
version "0.9.2"
|
||||
resolved "https://registry.yarnpkg.com/@emotion/hash/-/hash-0.9.2.tgz#ff9221b9f58b4dfe61e619a7788734bd63f6898b"
|
||||
integrity sha512-MyqliTZGuOm3+5ZRSaaBGP3USLw6+EGykkwZns2EPC5g8jJ4z9OrdZY9apkl3+UP9+sdz76YYkwCKP5gh8iY3g==
|
||||
|
||||
"@emotion/is-prop-valid@^1.2.2":
|
||||
version "1.2.2"
|
||||
resolved "https://registry.yarnpkg.com/@emotion/is-prop-valid/-/is-prop-valid-1.2.2.tgz#d4175076679c6a26faa92b03bb786f9e52612337"
|
||||
integrity sha512-uNsoYd37AFmaCdXlg6EYD1KaPOaRWRByMCYzbKUX4+hhMfrxdVSelShywL4JVaAeM/eHUOSprYBQls+/neX3pw==
|
||||
"@emotion/is-prop-valid@^1.3.0":
|
||||
version "1.3.0"
|
||||
resolved "https://registry.yarnpkg.com/@emotion/is-prop-valid/-/is-prop-valid-1.3.0.tgz#bd84ba972195e8a2d42462387581560ef780e4e2"
|
||||
integrity sha512-SHetuSLvJDzuNbOdtPVbq6yMMMlLoW5Q94uDqJZqy50gcmAjxFkVqmzqSGEFq9gT2iMuIeKV1PXVWmvUhuZLlQ==
|
||||
dependencies:
|
||||
"@emotion/memoize" "^0.8.1"
|
||||
"@emotion/memoize" "^0.9.0"
|
||||
|
||||
"@emotion/memoize@^0.8.1":
|
||||
version "0.8.1"
|
||||
resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.8.1.tgz#c1ddb040429c6d21d38cc945fe75c818cfb68e17"
|
||||
integrity sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA==
|
||||
"@emotion/memoize@^0.9.0":
|
||||
version "0.9.0"
|
||||
resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.9.0.tgz#745969d649977776b43fc7648c556aaa462b4102"
|
||||
integrity sha512-30FAj7/EoJ5mwVPOWhAyCX+FPfMDrVecJAM+Iw9NRoSl4BBAQeqj4cApHHUXOVvIPgLVDsCFoz/hGD+5QQD1GQ==
|
||||
|
||||
"@emotion/react@11.11.3", "@emotion/react@^11.8.1":
|
||||
version "11.11.3"
|
||||
resolved "https://registry.yarnpkg.com/@emotion/react/-/react-11.11.3.tgz#96b855dc40a2a55f52a72f518a41db4f69c31a25"
|
||||
integrity sha512-Cnn0kuq4DoONOMcnoVsTOR8E+AdnKFf//6kUWc4LCdnxj31pZWn7rIULd6Y7/Js1PiPHzn7SKCM9vB/jBni8eA==
|
||||
"@emotion/react@11.13.3", "@emotion/react@^11.13.3", "@emotion/react@^11.8.1":
|
||||
version "11.13.3"
|
||||
resolved "https://registry.yarnpkg.com/@emotion/react/-/react-11.13.3.tgz#a69d0de2a23f5b48e0acf210416638010e4bd2e4"
|
||||
integrity sha512-lIsdU6JNrmYfJ5EbUCf4xW1ovy5wKQ2CkPRM4xogziOxH1nXxBSjpC9YqbFAP7circxMfYp+6x676BqWcEiixg==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.18.3"
|
||||
"@emotion/babel-plugin" "^11.11.0"
|
||||
"@emotion/cache" "^11.11.0"
|
||||
"@emotion/serialize" "^1.1.3"
|
||||
"@emotion/use-insertion-effect-with-fallbacks" "^1.0.1"
|
||||
"@emotion/utils" "^1.2.1"
|
||||
"@emotion/weak-memoize" "^0.3.1"
|
||||
"@emotion/babel-plugin" "^11.12.0"
|
||||
"@emotion/cache" "^11.13.0"
|
||||
"@emotion/serialize" "^1.3.1"
|
||||
"@emotion/use-insertion-effect-with-fallbacks" "^1.1.0"
|
||||
"@emotion/utils" "^1.4.0"
|
||||
"@emotion/weak-memoize" "^0.4.0"
|
||||
hoist-non-react-statics "^3.3.1"
|
||||
|
||||
"@emotion/serialize@^1.1.2", "@emotion/serialize@^1.1.3", "@emotion/serialize@^1.1.4":
|
||||
version "1.1.4"
|
||||
resolved "https://registry.yarnpkg.com/@emotion/serialize/-/serialize-1.1.4.tgz#fc8f6d80c492cfa08801d544a05331d1cc7cd451"
|
||||
integrity sha512-RIN04MBT8g+FnDwgvIUi8czvr1LU1alUMI05LekWB5DGyTm8cCBMCRpq3GqaiyEDRptEXOyXnvZ58GZYu4kBxQ==
|
||||
"@emotion/serialize@^1.2.0", "@emotion/serialize@^1.3.0", "@emotion/serialize@^1.3.1":
|
||||
version "1.3.1"
|
||||
resolved "https://registry.yarnpkg.com/@emotion/serialize/-/serialize-1.3.1.tgz#490b660178f43d2de8e92b278b51079d726c05c3"
|
||||
integrity sha512-dEPNKzBPU+vFPGa+z3axPRn8XVDetYORmDC0wAiej+TNcOZE70ZMJa0X7JdeoM6q/nWTMZeLpN/fTnD9o8MQBA==
|
||||
dependencies:
|
||||
"@emotion/hash" "^0.9.1"
|
||||
"@emotion/memoize" "^0.8.1"
|
||||
"@emotion/unitless" "^0.8.1"
|
||||
"@emotion/utils" "^1.2.1"
|
||||
"@emotion/hash" "^0.9.2"
|
||||
"@emotion/memoize" "^0.9.0"
|
||||
"@emotion/unitless" "^0.10.0"
|
||||
"@emotion/utils" "^1.4.0"
|
||||
csstype "^3.0.2"
|
||||
|
||||
"@emotion/sheet@^1.2.2":
|
||||
version "1.2.2"
|
||||
resolved "https://registry.yarnpkg.com/@emotion/sheet/-/sheet-1.2.2.tgz#d58e788ee27267a14342303e1abb3d508b6d0fec"
|
||||
integrity sha512-0QBtGvaqtWi+nx6doRwDdBIzhNdZrXUppvTM4dtZZWEGTXL/XE/yJxLMGlDT1Gt+UHH5IX1n+jkXyytE/av7OA==
|
||||
"@emotion/sheet@^1.4.0":
|
||||
version "1.4.0"
|
||||
resolved "https://registry.yarnpkg.com/@emotion/sheet/-/sheet-1.4.0.tgz#c9299c34d248bc26e82563735f78953d2efca83c"
|
||||
integrity sha512-fTBW9/8r2w3dXWYM4HCB1Rdp8NLibOw2+XELH5m5+AkWiL/KqYX6dc0kKYlaYyKjrQ6ds33MCdMPEwgs2z1rqg==
|
||||
|
||||
"@emotion/styled@^11.11.5":
|
||||
version "11.11.5"
|
||||
resolved "https://registry.yarnpkg.com/@emotion/styled/-/styled-11.11.5.tgz#0c5c8febef9d86e8a926e663b2e5488705545dfb"
|
||||
integrity sha512-/ZjjnaNKvuMPxcIiUkf/9SHoG4Q196DRl1w82hQ3WCsjo1IUR8uaGWrC6a87CrYAW0Kb/pK7hk8BnLgLRi9KoQ==
|
||||
"@emotion/styled@^11.13.0":
|
||||
version "11.13.0"
|
||||
resolved "https://registry.yarnpkg.com/@emotion/styled/-/styled-11.13.0.tgz#633fd700db701472c7a5dbef54d6f9834e9fb190"
|
||||
integrity sha512-tkzkY7nQhW/zC4hztlwucpT8QEZ6eUzpXDRhww/Eej4tFfO0FxQYWRyg/c5CCXa4d/f174kqeXYjuQRnhzf6dA==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.18.3"
|
||||
"@emotion/babel-plugin" "^11.11.0"
|
||||
"@emotion/is-prop-valid" "^1.2.2"
|
||||
"@emotion/serialize" "^1.1.4"
|
||||
"@emotion/use-insertion-effect-with-fallbacks" "^1.0.1"
|
||||
"@emotion/utils" "^1.2.1"
|
||||
"@emotion/babel-plugin" "^11.12.0"
|
||||
"@emotion/is-prop-valid" "^1.3.0"
|
||||
"@emotion/serialize" "^1.3.0"
|
||||
"@emotion/use-insertion-effect-with-fallbacks" "^1.1.0"
|
||||
"@emotion/utils" "^1.4.0"
|
||||
|
||||
"@emotion/unitless@^0.8.1":
|
||||
version "0.8.1"
|
||||
resolved "https://registry.yarnpkg.com/@emotion/unitless/-/unitless-0.8.1.tgz#182b5a4704ef8ad91bde93f7a860a88fd92c79a3"
|
||||
integrity sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ==
|
||||
"@emotion/unitless@^0.10.0":
|
||||
version "0.10.0"
|
||||
resolved "https://registry.yarnpkg.com/@emotion/unitless/-/unitless-0.10.0.tgz#2af2f7c7e5150f497bdabd848ce7b218a27cf745"
|
||||
integrity sha512-dFoMUuQA20zvtVTuxZww6OHoJYgrzfKM1t52mVySDJnMSEa08ruEvdYQbhvyu6soU+NeLVd3yKfTfT0NeV6qGg==
|
||||
|
||||
"@emotion/use-insertion-effect-with-fallbacks@^1.0.1":
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.0.1.tgz#08de79f54eb3406f9daaf77c76e35313da963963"
|
||||
integrity sha512-jT/qyKZ9rzLErtrjGgdkMBn2OP8wl0G3sQlBb3YPryvKHsjvINUhVaPFfP+fpBcOkmrVOVEEHQFJ7nbj2TH2gw==
|
||||
"@emotion/use-insertion-effect-with-fallbacks@^1.1.0":
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.1.0.tgz#1a818a0b2c481efba0cf34e5ab1e0cb2dcb9dfaf"
|
||||
integrity sha512-+wBOcIV5snwGgI2ya3u99D7/FJquOIniQT1IKyDsBmEgwvpxMNeS65Oib7OnE2d2aY+3BU4OiH+0Wchf8yk3Hw==
|
||||
|
||||
"@emotion/utils@^1.2.1":
|
||||
version "1.2.1"
|
||||
resolved "https://registry.yarnpkg.com/@emotion/utils/-/utils-1.2.1.tgz#bbab58465738d31ae4cb3dbb6fc00a5991f755e4"
|
||||
integrity sha512-Y2tGf3I+XVnajdItskUCn6LX+VUDmP6lTL4fcqsXAv43dnlbZiuW4MWQW38rW/BVWSE7Q/7+XQocmpnRYILUmg==
|
||||
"@emotion/utils@^1.4.0":
|
||||
version "1.4.0"
|
||||
resolved "https://registry.yarnpkg.com/@emotion/utils/-/utils-1.4.0.tgz#262f1d02aaedb2ec91c83a0955dd47822ad5fbdd"
|
||||
integrity sha512-spEnrA1b6hDR/C68lC2M7m6ALPUHZC0lIY7jAS/B/9DuuO1ZP04eov8SMv/6fwRd8pzmsn2AuJEznRREWlQrlQ==
|
||||
|
||||
"@emotion/weak-memoize@^0.3.1":
|
||||
version "0.3.1"
|
||||
resolved "https://registry.yarnpkg.com/@emotion/weak-memoize/-/weak-memoize-0.3.1.tgz#d0fce5d07b0620caa282b5131c297bb60f9d87e6"
|
||||
integrity sha512-EsBwpc7hBUJWAsNPBmJy4hxWx12v6bshQsldrVmjxJoc3isbxhOrF2IcCpaXxfvq03NwkI7sbsOLXbYuqF/8Ww==
|
||||
"@emotion/weak-memoize@^0.4.0":
|
||||
version "0.4.0"
|
||||
resolved "https://registry.yarnpkg.com/@emotion/weak-memoize/-/weak-memoize-0.4.0.tgz#5e13fac887f08c44f76b0ccaf3370eb00fec9bb6"
|
||||
integrity sha512-snKqtPW01tN0ui7yu9rGv69aJXr/a/Ywvl11sUjNtEcRc+ng/mQriFL0wLXMef74iHa/EkftbDzU9F8iFbH+zg==
|
||||
|
||||
"@esbuild/aix-ppc64@0.21.5":
|
||||
version "0.21.5"
|
||||
@@ -511,14 +518,6 @@
|
||||
dependencies:
|
||||
"@floating-ui/utils" "^0.2.4"
|
||||
|
||||
"@floating-ui/dom@^1.0.0":
|
||||
version "1.6.7"
|
||||
resolved "https://registry.yarnpkg.com/@floating-ui/dom/-/dom-1.6.7.tgz#85d22f731fcc5b209db504478fb1df5116a83015"
|
||||
integrity sha512-wmVfPG5o2xnKDU4jx/m4w5qva9FWHcnZ8BvzEe90D/RpwsJaTAVYPEPdQ8sbr/N8zZTAHlZUTQdqg8ZUbzHmng==
|
||||
dependencies:
|
||||
"@floating-ui/core" "^1.6.0"
|
||||
"@floating-ui/utils" "^0.2.4"
|
||||
|
||||
"@floating-ui/dom@^1.0.1":
|
||||
version "1.6.10"
|
||||
resolved "https://registry.yarnpkg.com/@floating-ui/dom/-/dom-1.6.10.tgz#b74c32f34a50336c86dcf1f1c845cf3a39e26d6f"
|
||||
@@ -527,13 +526,6 @@
|
||||
"@floating-ui/core" "^1.6.0"
|
||||
"@floating-ui/utils" "^0.2.7"
|
||||
|
||||
"@floating-ui/react-dom@^2.0.8":
|
||||
version "2.1.1"
|
||||
resolved "https://registry.yarnpkg.com/@floating-ui/react-dom/-/react-dom-2.1.1.tgz#cca58b6b04fc92b4c39288252e285e0422291fb0"
|
||||
integrity sha512-4h84MJt3CHrtG18mGsXuLCHMrug49d7DFkU0RMIyshRveBeyV2hmV/pDaF2Uxtu8kgq5r46llp5E5FQiR0K2Yg==
|
||||
dependencies:
|
||||
"@floating-ui/dom" "^1.0.0"
|
||||
|
||||
"@floating-ui/utils@^0.2.4":
|
||||
version "0.2.4"
|
||||
resolved "https://registry.yarnpkg.com/@floating-ui/utils/-/utils-0.2.4.tgz#1d459cee5031893a08a0e064c406ad2130cced7c"
|
||||
@@ -607,58 +599,36 @@
|
||||
"@jridgewell/resolve-uri" "^3.1.0"
|
||||
"@jridgewell/sourcemap-codec" "^1.4.14"
|
||||
|
||||
"@mui/base@5.0.0-beta.40":
|
||||
version "5.0.0-beta.40"
|
||||
resolved "https://registry.yarnpkg.com/@mui/base/-/base-5.0.0-beta.40.tgz#1f8a782f1fbf3f84a961e954c8176b187de3dae2"
|
||||
integrity sha512-I/lGHztkCzvwlXpjD2+SNmvNQvB4227xBXhISPjEaJUXGImOQ9f3D2Yj/T3KasSI/h0MLWy74X0J6clhPmsRbQ==
|
||||
"@mui/core-downloads-tracker@^5.16.7":
|
||||
version "5.16.7"
|
||||
resolved "https://registry.yarnpkg.com/@mui/core-downloads-tracker/-/core-downloads-tracker-5.16.7.tgz#182a325a520f7ebd75de051fceabfc0314cfd004"
|
||||
integrity sha512-RtsCt4Geed2/v74sbihWzzRs+HsIQCfclHeORh5Ynu2fS4icIKozcSubwuG7vtzq2uW3fOR1zITSP84TNt2GoQ==
|
||||
|
||||
"@mui/icons-material@^5.16.6":
|
||||
version "5.16.7"
|
||||
resolved "https://registry.yarnpkg.com/@mui/icons-material/-/icons-material-5.16.7.tgz#e27f901af792065efc9f3d75d74a66af7529a10a"
|
||||
integrity sha512-UrGwDJCXEszbDI7yV047BYU5A28eGJ79keTCP4cc74WyncuVrnurlmIRxaHL8YK+LI1Kzq+/JM52IAkNnv4u+Q==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.23.9"
|
||||
"@floating-ui/react-dom" "^2.0.8"
|
||||
"@mui/types" "^7.2.14"
|
||||
"@mui/utils" "^5.15.14"
|
||||
|
||||
"@mui/material@^5.16.6":
|
||||
version "5.16.7"
|
||||
resolved "https://registry.yarnpkg.com/@mui/material/-/material-5.16.7.tgz#6e814e2eefdaf065a769cecf549c3569e107a50b"
|
||||
integrity sha512-cwwVQxBhK60OIOqZOVLFt55t01zmarKJiJUWbk0+8s/Ix5IaUzAShqlJchxsIQ4mSrWqgcKCCXKtIlG5H+/Jmg==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.23.9"
|
||||
"@mui/core-downloads-tracker" "^5.16.7"
|
||||
"@mui/system" "^5.16.7"
|
||||
"@mui/types" "^7.2.15"
|
||||
"@mui/utils" "^5.16.6"
|
||||
"@popperjs/core" "^2.11.8"
|
||||
clsx "^2.1.0"
|
||||
prop-types "^15.8.1"
|
||||
|
||||
"@mui/core-downloads-tracker@^5.16.0":
|
||||
version "5.16.0"
|
||||
resolved "https://registry.yarnpkg.com/@mui/core-downloads-tracker/-/core-downloads-tracker-5.16.0.tgz#50153c698e321793c83a0283d8d7a9dc5d43858a"
|
||||
integrity sha512-8SLffXYPRVpcZx5QzxNE8fytTqzp+IuU3deZbQWg/vSaTlDpR5YVrQ4qQtXTi5cRdhOufV5INylmwlKK+//nPw==
|
||||
|
||||
"@mui/icons-material@^5.16":
|
||||
version "5.16.0"
|
||||
resolved "https://registry.yarnpkg.com/@mui/icons-material/-/icons-material-5.16.0.tgz#5269fda922fe5e6db3577ec497e8b987195606ef"
|
||||
integrity sha512-6ISoOhkp9w5gD0PEW9JklrcbyARDkFWNTBdwXZ1Oy5IGlyu9B0zG0hnUIe4H17IaF1Vgj6C8VI+v4tkSdK0veg==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.23.9"
|
||||
|
||||
"@mui/material@^5.16":
|
||||
version "5.16.0"
|
||||
resolved "https://registry.yarnpkg.com/@mui/material/-/material-5.16.0.tgz#2ef4f52ae773574fc0a681f25705f376f5cd13f7"
|
||||
integrity sha512-DbR1NckTLpjt9Zut9EGQ70th86HfN0BYQgyYro6aXQrNfjzSwe3BJS1AyBQ5mJ7TdL6YVRqohfukxj9JlqZZUg==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.23.9"
|
||||
"@mui/base" "5.0.0-beta.40"
|
||||
"@mui/core-downloads-tracker" "^5.16.0"
|
||||
"@mui/system" "^5.16.0"
|
||||
"@mui/types" "^7.2.14"
|
||||
"@mui/utils" "^5.16.0"
|
||||
"@types/react-transition-group" "^4.4.10"
|
||||
clsx "^2.1.0"
|
||||
csstype "^3.1.3"
|
||||
prop-types "^15.8.1"
|
||||
react-is "^18.2.0"
|
||||
react-is "^18.3.1"
|
||||
react-transition-group "^4.4.5"
|
||||
|
||||
"@mui/private-theming@^5.16.0":
|
||||
version "5.16.0"
|
||||
resolved "https://registry.yarnpkg.com/@mui/private-theming/-/private-theming-5.16.0.tgz#c1abfd3e0d9c95459048240ef4209dc7f25dc949"
|
||||
integrity sha512-sYpubkO1MZOnxNyVOClrPNOTs0MfuRVVnAvCeMaOaXt6GimgQbnUcshYv2pSr6PFj+Mqzdff/FYOBceK8u5QgA==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.23.9"
|
||||
"@mui/utils" "^5.16.0"
|
||||
prop-types "^15.8.1"
|
||||
|
||||
"@mui/private-theming@^5.16.6":
|
||||
version "5.16.6"
|
||||
resolved "https://registry.yarnpkg.com/@mui/private-theming/-/private-theming-5.16.6.tgz#547671e7ae3f86b68d1289a0b90af04dfcc1c8c9"
|
||||
@@ -668,16 +638,6 @@
|
||||
"@mui/utils" "^5.16.6"
|
||||
prop-types "^15.8.1"
|
||||
|
||||
"@mui/styled-engine@^5.15.14":
|
||||
version "5.15.14"
|
||||
resolved "https://registry.yarnpkg.com/@mui/styled-engine/-/styled-engine-5.15.14.tgz#168b154c4327fa4ccc1933a498331d53f61c0de2"
|
||||
integrity sha512-RILkuVD8gY6PvjZjqnWhz8fu68dVkqhM5+jYWfB5yhlSQKg+2rHkmEwm75XIeAqI3qwOndK6zELK5H6Zxn4NHw==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.23.9"
|
||||
"@emotion/cache" "^11.11.0"
|
||||
csstype "^3.1.3"
|
||||
prop-types "^15.8.1"
|
||||
|
||||
"@mui/styled-engine@^5.16.6":
|
||||
version "5.16.6"
|
||||
resolved "https://registry.yarnpkg.com/@mui/styled-engine/-/styled-engine-5.16.6.tgz#60110c106dd482dfdb7e2aa94fd6490a0a3f8852"
|
||||
@@ -688,20 +648,6 @@
|
||||
csstype "^3.1.3"
|
||||
prop-types "^15.8.1"
|
||||
|
||||
"@mui/system@^5.16.0":
|
||||
version "5.16.0"
|
||||
resolved "https://registry.yarnpkg.com/@mui/system/-/system-5.16.0.tgz#e5b4cfbdfbc0ee9859f6b168e8b07d750303b7a0"
|
||||
integrity sha512-9YbkC2m3+pNumAvubYv+ijLtog6puJ0fJ6rYfzfLCM47pWrw3m+30nXNM8zMgDaKL6vpfWJcCXm+LPaWBpy7sw==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.23.9"
|
||||
"@mui/private-theming" "^5.16.0"
|
||||
"@mui/styled-engine" "^5.15.14"
|
||||
"@mui/types" "^7.2.14"
|
||||
"@mui/utils" "^5.16.0"
|
||||
clsx "^2.1.0"
|
||||
csstype "^3.1.3"
|
||||
prop-types "^15.8.1"
|
||||
|
||||
"@mui/system@^5.16.5":
|
||||
version "5.16.6"
|
||||
resolved "https://registry.yarnpkg.com/@mui/system/-/system-5.16.6.tgz#2dabe63d2e45816ce611c40d6e3f79b9c2ccbcd7"
|
||||
@@ -716,26 +662,25 @@
|
||||
csstype "^3.1.3"
|
||||
prop-types "^15.8.1"
|
||||
|
||||
"@mui/types@^7.2.14":
|
||||
version "7.2.14"
|
||||
resolved "https://registry.yarnpkg.com/@mui/types/-/types-7.2.14.tgz#8a02ac129b70f3d82f2f9b76ded2c8d48e3fc8c9"
|
||||
integrity sha512-MZsBZ4q4HfzBsywtXgM1Ksj6HDThtiwmOKUXH1pKYISI9gAVXCNHNpo7TlGoGrBaYWZTdNoirIN7JsQcQUjmQQ==
|
||||
"@mui/system@^5.16.7":
|
||||
version "5.16.7"
|
||||
resolved "https://registry.yarnpkg.com/@mui/system/-/system-5.16.7.tgz#4583ca5bf3b38942e02c15a1e622ba869ac51393"
|
||||
integrity sha512-Jncvs/r/d/itkxh7O7opOunTqbbSSzMTHzZkNLM+FjAOg+cYAZHrPDlYe1ZGKUYORwwb2XexlWnpZp0kZ4AHuA==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.23.9"
|
||||
"@mui/private-theming" "^5.16.6"
|
||||
"@mui/styled-engine" "^5.16.6"
|
||||
"@mui/types" "^7.2.15"
|
||||
"@mui/utils" "^5.16.6"
|
||||
clsx "^2.1.0"
|
||||
csstype "^3.1.3"
|
||||
prop-types "^15.8.1"
|
||||
|
||||
"@mui/types@^7.2.15":
|
||||
version "7.2.15"
|
||||
resolved "https://registry.yarnpkg.com/@mui/types/-/types-7.2.15.tgz#dadd232fe9a70be0d526630675dff3b110f30b53"
|
||||
integrity sha512-nbo7yPhtKJkdf9kcVOF8JZHPZTmqXjJ/tI0bdWgHg5tp9AnIN4Y7f7wm9T+0SyGYJk76+GYZ8Q5XaTYAsUHN0Q==
|
||||
|
||||
"@mui/utils@^5.15.14", "@mui/utils@^5.16.0":
|
||||
version "5.16.0"
|
||||
resolved "https://registry.yarnpkg.com/@mui/utils/-/utils-5.16.0.tgz#3963127d9a619c251e5be1aef9adab0e89d3e7df"
|
||||
integrity sha512-kLLi5J1xY+mwtUlMb8Ubdxf4qFAA1+U7WPBvjM/qQ4CIwLCohNb0sHo1oYPufjSIH/Z9+dhVxD7dJlfGjd1AVA==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.23.9"
|
||||
"@types/prop-types" "^15.7.11"
|
||||
prop-types "^15.8.1"
|
||||
react-is "^18.2.0"
|
||||
|
||||
"@mui/utils@^5.16.5", "@mui/utils@^5.16.6":
|
||||
version "5.16.6"
|
||||
resolved "https://registry.yarnpkg.com/@mui/utils/-/utils-5.16.6.tgz#905875bbc58d3dcc24531c3314a6807aba22a711"
|
||||
@@ -1094,7 +1039,7 @@
|
||||
resolved "https://registry.yarnpkg.com/@types/photoswipe/-/photoswipe-4.1.6.tgz#41d1e0a54c1b27628688e8abf9b95baab472a247"
|
||||
integrity sha512-6kN4KYjNF4sg79fSwZ46s4Pron4+YJxoW0DQOcHveUZc/3cWd8Q4B9OLlDmEYw9iI6fODU8kyyq8ZBy+8F/+zQ==
|
||||
|
||||
"@types/prop-types@*", "@types/prop-types@^15.7.11", "@types/prop-types@^15.7.12":
|
||||
"@types/prop-types@*", "@types/prop-types@^15.7.12":
|
||||
version "15.7.12"
|
||||
resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.12.tgz#12bb1e2be27293c1406acb6af1c3f3a1481d98c6"
|
||||
integrity sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q==
|
||||
@@ -1728,7 +1673,7 @@ combined-stream@^1.0.8:
|
||||
dependencies:
|
||||
delayed-stream "~1.0.0"
|
||||
|
||||
comlink@^4.4:
|
||||
comlink@^4.4.1:
|
||||
version "4.4.1"
|
||||
resolved "https://registry.yarnpkg.com/comlink/-/comlink-4.4.1.tgz#e568b8e86410b809e8600eb2cf40c189371ef981"
|
||||
integrity sha512-+1dlx0aY5Jo1vHy/tSsIGpSkN4tS9rZSW8FIhG0JH/crs9wwweswIo/POr451r7bZww3hFbPAKnTpimzL/mm4Q==
|
||||
@@ -2709,7 +2654,7 @@ get-tsconfig@^4.5.0:
|
||||
dependencies:
|
||||
resolve-pkg-maps "^1.0.0"
|
||||
|
||||
get-user-locale@^2.3:
|
||||
get-user-locale@^2.3.2:
|
||||
version "2.3.2"
|
||||
resolved "https://registry.yarnpkg.com/get-user-locale/-/get-user-locale-2.3.2.tgz#d37ae6e670c2b57d23a96fb4d91e04b2059d52cf"
|
||||
integrity sha512-O2GWvQkhnbDoWFUJfaBlDIKUEdND8ATpBXD6KXcbhxlfktyD/d8w6mkzM/IlQEqGZAMz/PW6j6Hv53BiigKLUQ==
|
||||
@@ -2919,17 +2864,17 @@ html-parse-stringify@^3.0.1:
|
||||
dependencies:
|
||||
void-elements "3.1.0"
|
||||
|
||||
i18next-resources-to-backend@^1.2:
|
||||
i18next-resources-to-backend@^1.2.1:
|
||||
version "1.2.1"
|
||||
resolved "https://registry.yarnpkg.com/i18next-resources-to-backend/-/i18next-resources-to-backend-1.2.1.tgz#fded121e63e3139ce839c9901b9449dbbea7351d"
|
||||
integrity sha512-okHbVA+HZ7n1/76MsfhPqDou0fptl2dAlhRDu2ideXloRRduzHsqDOznJBef+R3DFZnbvWoBW+KxJ7fnFjd6Yw==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.23.2"
|
||||
|
||||
i18next@^23.11:
|
||||
version "23.11.5"
|
||||
resolved "https://registry.yarnpkg.com/i18next/-/i18next-23.11.5.tgz#d71eb717a7e65498d87d0594f2664237f9e361ef"
|
||||
integrity sha512-41pvpVbW9rhZPk5xjCX2TPJi2861LEig/YRhUkY+1FQ2IQPS0bKUDYnEqY8XPPbB48h1uIwLnP9iiEfuSl20CA==
|
||||
i18next@^23.15.1:
|
||||
version "23.15.1"
|
||||
resolved "https://registry.yarnpkg.com/i18next/-/i18next-23.15.1.tgz#c50de337bf12ca5195e697cc0fbe5f32304871d9"
|
||||
integrity sha512-wB4abZ3uK7EWodYisHl/asf8UYEhrI/vj/8aoSsrj/ZDxj4/UXPOa1KvFt1Fq5hkUHquNqwFlDprmjZ8iySgYA==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.23.2"
|
||||
|
||||
@@ -3061,7 +3006,7 @@ is-date-object@^1.0.1, is-date-object@^1.0.5:
|
||||
dependencies:
|
||||
has-tostringtag "^1.0.0"
|
||||
|
||||
is-electron@^2.2:
|
||||
is-electron@^2.2.2:
|
||||
version "2.2.2"
|
||||
resolved "https://registry.yarnpkg.com/is-electron/-/is-electron-2.2.2.tgz#3778902a2044d76de98036f5dc58089ac4d80bb9"
|
||||
integrity sha512-FO/Rhvz5tuw4MCWkpMzHFKWD2LsfHzIb7i6MdPYZ/KW7AlxawyLkqdy+jPZP1WubqEADE3O4FUENlJHDfQASRg==
|
||||
@@ -3965,12 +3910,12 @@ react-fast-compare@^2.0.1:
|
||||
resolved "https://registry.yarnpkg.com/react-fast-compare/-/react-fast-compare-2.0.4.tgz#e84b4d455b0fec113e0402c329352715196f81f9"
|
||||
integrity sha512-suNP+J1VU1MWFKcyt7RtjiSWUjvidmQSlqu+eHslq+342xCbGTYmC0mEhPCOHxlW0CywylOC1u2DFAT+bv4dBw==
|
||||
|
||||
react-i18next@^14:
|
||||
version "14.1.2"
|
||||
resolved "https://registry.yarnpkg.com/react-i18next/-/react-i18next-14.1.2.tgz#cd57a755f25a32a5fcc3dbe546cf3cc62b4f3ebd"
|
||||
integrity sha512-FSIcJy6oauJbGEXfhUgVeLzvWBhIBIS+/9c6Lj4niwKZyGaGb4V4vUbATXSlsHJDXXB+ociNxqFNiFuV1gmoqg==
|
||||
react-i18next@^15.0.1:
|
||||
version "15.0.1"
|
||||
resolved "https://registry.yarnpkg.com/react-i18next/-/react-i18next-15.0.1.tgz#fc662d93829ecb39683fe2757a47ebfbc5c912a0"
|
||||
integrity sha512-NwxLqNM6CLbeGA9xPsjits0EnXdKgCRSS6cgkgOdNcPXqL+1fYNl8fBg1wmnnHvFy812Bt4IWTPE9zjoPmFj3w==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.23.9"
|
||||
"@babel/runtime" "^7.24.8"
|
||||
html-parse-stringify "^3.0.1"
|
||||
|
||||
react-is@^16.13.1, react-is@^16.7.0:
|
||||
@@ -3978,7 +3923,7 @@ react-is@^16.13.1, react-is@^16.7.0:
|
||||
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4"
|
||||
integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==
|
||||
|
||||
react-is@^18.2.0, react-is@^18.3.1:
|
||||
react-is@^18.3.1:
|
||||
version "18.3.1"
|
||||
resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.3.1.tgz#e83557dc12eae63a99e003a46388b1dcbb44db7e"
|
||||
integrity sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==
|
||||
|
||||
Reference in New Issue
Block a user