[desktop] Towards public beta of advanced (ML) search - Part 2/x (#2665)

This commit is contained in:
Manav Rathi
2024-08-12 14:23:17 +05:30
committed by GitHub
6 changed files with 44 additions and 35 deletions

View File

@@ -4,7 +4,6 @@ import { MenuItemGroup, MenuSectionTitle } from "@/base/components/Menu";
import { Titlebar } from "@/base/components/Titlebar";
import {
getLocaleInUse,
pt,
setLocaleInUse,
supportedLocales,
type SupportedLocale,
@@ -96,7 +95,7 @@ export const Preferences: React.FC<SettingsDrawerProps> = ({
<EnteMenuItem
endIcon={<ChevronRight />}
onClick={() => setOpenMLSettings(true)}
label={pt("Face and magic search")}
label={t("face_and_magic_search")}
/>
</MenuItemGroup>
</Box>

View File

@@ -264,6 +264,7 @@
"SCAN_QR_CODE": "Scan QR code instead",
"ENABLE_TWO_FACTOR": "Enable two-factor",
"ENABLE": "Enable",
"enabled": "Enabled",
"LOST_DEVICE": "Lost two-factor device",
"INCORRECT_CODE": "Incorrect code",
"TWO_FACTOR_INFO": "Add an additional layer of security by requiring more than your email and password to log in to your account",
@@ -477,6 +478,16 @@
"ROOT_LEVEL_FILE_WITH_FOLDER_NOT_ALLOWED_MESSAGE": "<p>You have dragged and dropped a mixture of files and folders.</p><p>Please provide either only files, or only folders when selecting option to create separate albums</p>",
"CHOSE_THEME": "Choose theme",
"more_details": "More details",
"face_and_magic_search": "Face and magic search",
"ml_search_description": "Ente supports on-device machine learning for face recognition, magic search and other advanced search features",
"ml_search_footnote": "Magic search allows to search photos by their contents, e.g. 'car', 'red car', 'Ferrari'",
"indexing": "Indexing",
"processed": "Processed",
"indexing_status_running": "Running",
"indexing_status_scheduled": "Scheduled",
"indexing_status_done": "Done",
"ml_search_disable": "Disable face and magic search",
"ml_search_disable_confirm": "Do you want to disable face and magic search on all your devices?",
"ENABLE_FACE_SEARCH": "Enable face recognition",
"ENABLE_FACE_SEARCH_TITLE": "Enable face recognition?",
"ENABLE_FACE_SEARCH_DESCRIPTION": "<p>If you enable face recognition, Ente will extract face geometry from your photos. This will happen on your device, and any generated biometric data will be end-to-encrypted.</p><p><a>Please click here for more details about this feature in our privacy policy</a></p>",

View File

@@ -1,7 +1,6 @@
import { EnteDrawer } from "@/base/components/EnteDrawer";
import { MenuItemGroup } from "@/base/components/Menu";
import { Titlebar } from "@/base/components/Titlebar";
import { pt } from "@/base/i18n";
import log from "@/base/log";
import {
disableML,
@@ -124,7 +123,7 @@ export const MLSettings: React.FC<MLSettingsProps> = ({
<Stack spacing={"4px"} py={"12px"}>
<Titlebar
onClose={onClose}
title={pt("Face and magic search")}
title={t("face_and_magic_search")}
onRootClose={onRootClose}
/>
{component}
@@ -161,9 +160,7 @@ const EnableML: React.FC<EnableMLProps> = ({ onEnable }) => {
return (
<Stack py={"20px"} px={"16px"} spacing={"32px"}>
<Typography color="text.muted">
{pt(
"Ente supports on-device machine learning for face recognition, magic search and other advanced search features",
)}
{t("ml_search_description")}
</Typography>
<Stack spacing={"8px"}>
<Button color={"accent"} size="large" onClick={onEnable}>
@@ -175,9 +172,7 @@ const EnableML: React.FC<EnableMLProps> = ({ onEnable }) => {
</Button>
</Stack>
<Typography color="text.faint" variant="small">
{pt(
'Magic search allows to search photos by their contents, e.g. "car", "red car", "Ferrari"',
)}
{t("ml_search_footnote")}
</Typography>
</Stack>
);
@@ -305,28 +300,26 @@ const ManageML: React.FC<ManageMLProps> = ({
let status: string;
switch (phase) {
case "indexing":
status = pt("Running");
status = t("running");
break;
case "scheduled":
status = pt("Scheduled");
status = t("scheduled");
break;
// TODO: Clustering
default:
status = pt("Done");
status = t("done");
break;
}
const processed = `${nSyncedFiles} / ${nTotalFiles}`;
const confirmDisableML = () => {
setDialogBoxAttributesV2({
title: pt("Disable face and magic search"),
content: pt(
"Do you want to disable face and magic search on all your devices?",
),
title: t("ml_search_disable"),
content: t("ml_search_disable_confirm"),
close: { text: t("cancel") },
proceed: {
variant: "critical",
text: pt("Disable"),
text: t("DISABLE"),
action: onDisableML,
},
buttonDirection: "row",
@@ -338,7 +331,7 @@ const ManageML: React.FC<ManageMLProps> = ({
<Stack gap={3}>
<MenuItemGroup>
<EnteMenuItem
label={pt("Enabled")}
label={t("enabled")}
variant="toggle"
checked={true}
onClick={confirmDisableML}
@@ -356,9 +349,11 @@ const ManageML: React.FC<ManageMLProps> = ({
justifyContent={"space-between"}
>
<Typography color="text.faint">
{pt("Indexing")}
{t("indexing")}
</Typography>
<Typography>
{t("indexing_status", { context: status })}
</Typography>
<Typography>{status}</Typography>
</Stack>
<Divider sx={{ marginInlineStart: 2 }} />
<Stack
@@ -370,7 +365,7 @@ const ManageML: React.FC<ManageMLProps> = ({
justifyContent={"space-between"}
>
<Typography color="text.faint">
{pt("Processed")}
{t("processed")}
</Typography>
<Typography textAlign="right">{processed}</Typography>
</Stack>

View File

@@ -11,7 +11,7 @@ import { dotProduct } from "./math";
*/
export interface FaceCluster {
/**
* A randomly generated ID to uniquely identify this cluster.
* A nanoid for this cluster.
*/
id: string;
/**
@@ -37,7 +37,7 @@ export interface FaceCluster {
*/
export interface Person {
/**
* A randomly generated ID to uniquely identify this person.
* A nanoid for this person.
*/
id: string;
/**

View File

@@ -149,6 +149,12 @@ const deleteLegacyDB = () => {
removeKV("embeddingSyncTime:onnx-clip"),
removeKV("embeddingSyncTime:file-ml-clip-face"),
]);
// Delete legacy ML keys.
//
// This code was added August 2024 (v1.7.3-beta) and can be removed at some
// point when most clients have migrated (tag: Migration).
localStorage.removeItem("faceIndexingEnabled");
};
/**

View File

@@ -160,13 +160,8 @@ export const isMLSupported = isDesktop;
/**
* TODO-ML: This will not be needed when we move to a public beta.
* Was this someone who might've enabled the beta ML? If so, show them the
* coming back soon banner while we finalize it.
*/
export const canEnableML = async () =>
// TODO-ML: The interim condition should be
// isDevBuild || (await isInternalUser()) || (await isBetaUser());
await isInternalUser();
export const canEnableML = async () => await isInternalUser();
/**
* Initialize the ML subsystem if the user has enabled it in preferences.
@@ -224,6 +219,11 @@ export const disableML = async () => {
triggerStatusUpdate();
};
/**
* Local storage key for {@link isMLEnabledLocal}.
*/
const mlLocalKey = "mlEnabled";
/**
* Return true if our local persistence thinks that ML is enabled.
*
@@ -233,17 +233,15 @@ export const disableML = async () => {
* The remote status is tracked with a separate {@link isMLEnabledRemote} flag
* that is synced with remote.
*/
const isMLEnabledLocal = () =>
// TODO-ML: Rename this flag
localStorage.getItem("faceIndexingEnabled") == "1";
const isMLEnabledLocal = () => localStorage.getItem(mlLocalKey) == "1";
/**
* Update the (locally stored) value of {@link isMLEnabledLocal}.
*/
const setIsMLEnabledLocal = (enabled: boolean) =>
enabled
? localStorage.setItem("faceIndexingEnabled", "1")
: localStorage.removeItem("faceIndexingEnabled");
? localStorage.setItem(mlLocalKey, "1")
: localStorage.removeItem(mlLocalKey);
/**
* For historical reasons, this is called "faceSearchEnabled" (it started off as