From 24858ab73b2cbe0c5ec5871db096809690d3c87e Mon Sep 17 00:00:00 2001 From: Manav Rathi Date: Wed, 10 Jul 2024 10:17:35 +0530 Subject: [PATCH 01/67] Move --- .../components/PhotoViewer/FileInfo/index.tsx | 4 +- .../SearchBar/searchInput/MenuWithPeople.tsx | 2 +- .../new/photos/components}/PeopleList.tsx | 38 +++++++++---------- web/packages/new/photos/services/ml/people.ts | 2 +- 4 files changed, 22 insertions(+), 24 deletions(-) rename web/{apps/photos/src/components/ml => packages/new/photos/components}/PeopleList.tsx (86%) diff --git a/web/apps/photos/src/components/PhotoViewer/FileInfo/index.tsx b/web/apps/photos/src/components/PhotoViewer/FileInfo/index.tsx index 158277ff23..ac764bd1a4 100644 --- a/web/apps/photos/src/components/PhotoViewer/FileInfo/index.tsx +++ b/web/apps/photos/src/components/PhotoViewer/FileInfo/index.tsx @@ -1,3 +1,4 @@ +import { UnidentifiedFaces } from "@/new/photos/components/PeopleList"; import { isMLEnabled } from "@/new/photos/services/ml"; import { EnteFile } from "@/new/photos/types/file"; import CopyButton from "@ente/shared/components/CodeBlock/CopyButton"; @@ -12,9 +13,8 @@ import TextSnippetOutlined from "@mui/icons-material/TextSnippetOutlined"; import { Box, DialogProps, Link, Stack, styled } from "@mui/material"; import { Chip } from "components/Chip"; import { EnteDrawer } from "components/EnteDrawer"; -import Titlebar from "components/Titlebar"; -import { UnidentifiedFaces } from "components/ml/PeopleList"; import LinkButton from "components/pages/gallery/LinkButton"; +import Titlebar from "components/Titlebar"; import { t } from "i18next"; import { AppContext } from "pages/_app"; import { GalleryContext } from "pages/gallery"; diff --git a/web/apps/photos/src/components/Search/SearchBar/searchInput/MenuWithPeople.tsx b/web/apps/photos/src/components/Search/SearchBar/searchInput/MenuWithPeople.tsx index 6242090dfe..56dbd305fb 100644 --- a/web/apps/photos/src/components/Search/SearchBar/searchInput/MenuWithPeople.tsx +++ b/web/apps/photos/src/components/Search/SearchBar/searchInput/MenuWithPeople.tsx @@ -1,7 +1,7 @@ +import { PeopleList } from "@/new/photos/components/PeopleList"; import { isMLEnabled } from "@/new/photos/services/ml"; import { Row } from "@ente/shared/components/Container"; import { Box, styled } from "@mui/material"; -import { PeopleList } from "components/ml/PeopleList"; import { t } from "i18next"; import { components } from "react-select"; import { Suggestion, SuggestionType } from "types/search"; diff --git a/web/apps/photos/src/components/ml/PeopleList.tsx b/web/packages/new/photos/components/PeopleList.tsx similarity index 86% rename from web/apps/photos/src/components/ml/PeopleList.tsx rename to web/packages/new/photos/components/PeopleList.tsx index 2a3da9f3b0..964f93a9f6 100644 --- a/web/apps/photos/src/components/ml/PeopleList.tsx +++ b/web/packages/new/photos/components/PeopleList.tsx @@ -10,34 +10,30 @@ import { t } from "i18next"; import React, { useEffect, useState } from "react"; export interface PeopleListProps { - people: Array; - maxRows?: number; + people: Person[]; + maxRows: number; onSelect?: (person: Person, index: number) => void; } -export const PeopleList = React.memo((props: PeopleListProps) => { +export const PeopleList: React.FC = ({ + people, + maxRows, + onSelect, +}) => { return ( - - {props.people.map((person, index) => ( + + {people.map((person, index) => ( - props.onSelect && props.onSelect(person, index) - } + clickable={!!onSelect} + onClick={() => onSelect && onSelect(person, index)} > ))} ); -}); +}; const FaceChipContainer = styled("div")` display: flex; @@ -89,7 +85,7 @@ export const UnidentifiedFaces: React.FC = ({ useEffect(() => { let didCancel = false; - (async () => { + const go = async () => { const faceIDs = await unidentifiedFaceIDs(enteFile); !didCancel && setFaceIDs(faceIDs); // Don't block for the regeneration to happen. If anything got @@ -99,7 +95,9 @@ export const UnidentifiedFaces: React.FC = ({ void regenerateFaceCropsIfNeeded(enteFile).then((r) => setDidRegen(r), ); - })(); + }; + + void go(); return () => { didCancel = true; @@ -110,7 +108,7 @@ export const UnidentifiedFaces: React.FC = ({ return ( <> - + {t("UNIDENTIFIED_FACES")} @@ -140,7 +138,7 @@ const FaceCropImageView: React.FC = ({ faceID }) => { useEffect(() => { let didCancel = false; if (faceID) { - blobCache("face-crops") + void blobCache("face-crops") .then((cache) => cache.get(faceID)) .then((data) => { if (data) { diff --git a/web/packages/new/photos/services/ml/people.ts b/web/packages/new/photos/services/ml/people.ts index 0dac096dc4..97118ea94a 100644 --- a/web/packages/new/photos/services/ml/people.ts +++ b/web/packages/new/photos/services/ml/people.ts @@ -2,7 +2,7 @@ export interface Person { id: number; name?: string; files: number[]; - displayFaceId?: string; + displayFaceId: string; } // TODO-ML(MR): Forced disable clustering. It doesn't currently work, From d4be782b9cae66ba100fe9bdc3042f796857b4b4 Mon Sep 17 00:00:00 2001 From: Manav Rathi Date: Wed, 10 Jul 2024 10:22:14 +0530 Subject: [PATCH 02/67] Silence a warning to avoid changing behaviour for now --- web/packages/new/photos/components/PeopleList.tsx | 3 +++ 1 file changed, 3 insertions(+) diff --git a/web/packages/new/photos/components/PeopleList.tsx b/web/packages/new/photos/components/PeopleList.tsx index 964f93a9f6..7b9a1369a0 100644 --- a/web/packages/new/photos/components/PeopleList.tsx +++ b/web/packages/new/photos/components/PeopleList.tsx @@ -152,6 +152,9 @@ const FaceCropImageView: React.FC = ({ faceID }) => { didCancel = true; if (objectURL) URL.revokeObjectURL(objectURL); }; + // TODO: The linter warning is actually correct, objectURL should be a + // dependency, but adding that require reworking this code first. + // eslint-disable-next-line react-hooks/exhaustive-deps }, [faceID]); return objectURL ? ( From 57ff75b85585f784ef5a943e3a2c285cbf414a8d Mon Sep 17 00:00:00 2001 From: Manav Rathi Date: Wed, 10 Jul 2024 10:22:50 +0530 Subject: [PATCH 03/67] lf --- web/packages/new/photos/components/PeopleList.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/packages/new/photos/components/PeopleList.tsx b/web/packages/new/photos/components/PeopleList.tsx index 7b9a1369a0..39361f8741 100644 --- a/web/packages/new/photos/components/PeopleList.tsx +++ b/web/packages/new/photos/components/PeopleList.tsx @@ -3,7 +3,7 @@ import { unidentifiedFaceIDs, } from "@/new/photos/services/ml"; import type { Person } from "@/new/photos/services/ml/people"; -import { EnteFile } from "@/new/photos/types/file"; +import type { EnteFile } from "@/new/photos/types/file"; import { blobCache } from "@/next/blob-cache"; import { Skeleton, Typography, styled } from "@mui/material"; import { t } from "i18next"; From 4519dc94b88b00d78915927bec1486e839cfe7e5 Mon Sep 17 00:00:00 2001 From: Manav Rathi Date: Wed, 10 Jul 2024 10:38:53 +0530 Subject: [PATCH 04/67] Move --- .../accounts/src/pages/passkeys/index.tsx | 4 +-- .../emailShare/AddParticipantForm.tsx | 6 ++-- .../emailShare/ManageEmailShare.tsx | 8 +++--- .../emailShare/ManageParticipant.tsx | 4 +-- .../CollectionShare/emailShare/index.tsx | 6 ++-- .../publicShare/EnablePublicShareOptions.tsx | 6 ++-- .../publicShare/manage/deviceLimit.tsx | 4 +-- .../publicShare/manage/index.tsx | 4 +-- .../publicShare/manage/linkExpiry.tsx | 4 +-- .../publicShare/manage/publicCollect.tsx | 4 +-- .../publicShare/managePublicShare.tsx | 4 +-- .../CollectionShare/sharingDetails.tsx | 6 ++-- .../ImageEditorOverlay/ColoursMenu.tsx | 4 +-- .../ImageEditorOverlay/CropMenu.tsx | 4 +-- .../ImageEditorOverlay/TransformMenu.tsx | 6 ++-- .../PhotoViewer/ImageEditorOverlay/index.tsx | 6 ++-- .../components/Sidebar/AdvancedSettings.tsx | 4 +-- .../src/components/Sidebar/MapSetting.tsx | 2 +- .../src/components/ml/MLSearchSettings.tsx | 2 +- .../components/menu}/MenuItemDivider.tsx | 0 .../common/components/menu}/MenuItemGroup.tsx | 0 .../components/menu}/MenuSectionTitle.tsx | 0 .../components/Menu/MenuItemDivider.tsx | 16 ----------- .../shared/components/Menu/MenuItemGroup.tsx | 20 ------------- .../components/Menu/MenuSectionTitle.tsx | 28 ------------------- 25 files changed, 44 insertions(+), 108 deletions(-) rename web/{apps/photos/src/components/Menu => packages/new/common/components/menu}/MenuItemDivider.tsx (100%) rename web/{apps/photos/src/components/Menu => packages/new/common/components/menu}/MenuItemGroup.tsx (100%) rename web/{apps/photos/src/components/Menu => packages/new/common/components/menu}/MenuSectionTitle.tsx (100%) delete mode 100644 web/packages/shared/components/Menu/MenuItemDivider.tsx delete mode 100644 web/packages/shared/components/Menu/MenuItemGroup.tsx delete mode 100644 web/packages/shared/components/Menu/MenuSectionTitle.tsx diff --git a/web/apps/accounts/src/pages/passkeys/index.tsx b/web/apps/accounts/src/pages/passkeys/index.tsx index 6f201ff33a..f928cabcca 100644 --- a/web/apps/accounts/src/pages/passkeys/index.tsx +++ b/web/apps/accounts/src/pages/passkeys/index.tsx @@ -1,3 +1,5 @@ +import MenuItemDivider from "@/new/common/components/menu/MenuItemDivider"; +import { MenuItemGroup } from "@/new/common/components/menu/MenuItemGroup"; import log from "@/next/log"; import { ensure } from "@/utils/ensure"; import { CenteredFlex } from "@ente/shared/components/Container"; @@ -7,8 +9,6 @@ import { EnteDrawer } from "@ente/shared/components/EnteDrawer"; import FormPaper from "@ente/shared/components/Form/FormPaper"; import InfoItem from "@ente/shared/components/Info/InfoItem"; import { EnteMenuItem } from "@ente/shared/components/Menu/EnteMenuItem"; -import MenuItemDivider from "@ente/shared/components/Menu/MenuItemDivider"; -import { MenuItemGroup } from "@ente/shared/components/Menu/MenuItemGroup"; import SingleInputForm from "@ente/shared/components/SingleInputForm"; import Titlebar from "@ente/shared/components/Titlebar"; import { formatDateTimeFull } from "@ente/shared/time/format"; diff --git a/web/apps/photos/src/components/Collections/CollectionShare/emailShare/AddParticipantForm.tsx b/web/apps/photos/src/components/Collections/CollectionShare/emailShare/AddParticipantForm.tsx index 29e8be1015..bb36ae2e8a 100644 --- a/web/apps/photos/src/components/Collections/CollectionShare/emailShare/AddParticipantForm.tsx +++ b/web/apps/photos/src/components/Collections/CollectionShare/emailShare/AddParticipantForm.tsx @@ -1,12 +1,12 @@ +import MenuItemDivider from "@/new/common/components/menu/MenuItemDivider"; +import { MenuItemGroup } from "@/new/common/components/menu/MenuItemGroup"; +import MenuSectionTitle from "@/new/common/components/menu/MenuSectionTitle"; import { FlexWrapper } from "@ente/shared/components/Container"; import { EnteMenuItem } from "@ente/shared/components/Menu/EnteMenuItem"; import SubmitButton from "@ente/shared/components/SubmitButton"; import DoneIcon from "@mui/icons-material/Done"; import { Button, FormHelperText, Stack } from "@mui/material"; import TextField from "@mui/material/TextField"; -import MenuItemDivider from "components/Menu/MenuItemDivider"; -import { MenuItemGroup } from "components/Menu/MenuItemGroup"; -import MenuSectionTitle from "components/Menu/MenuSectionTitle"; import Avatar from "components/pages/gallery/Avatar"; import { Formik, type FormikHelpers } from "formik"; import { t } from "i18next"; diff --git a/web/apps/photos/src/components/Collections/CollectionShare/emailShare/ManageEmailShare.tsx b/web/apps/photos/src/components/Collections/CollectionShare/emailShare/ManageEmailShare.tsx index 78e5dfe7ef..d33ce32605 100644 --- a/web/apps/photos/src/components/Collections/CollectionShare/emailShare/ManageEmailShare.tsx +++ b/web/apps/photos/src/components/Collections/CollectionShare/emailShare/ManageEmailShare.tsx @@ -1,3 +1,6 @@ +import MenuItemDivider from "@/new/common/components/menu/MenuItemDivider"; +import { MenuItemGroup } from "@/new/common/components/menu/MenuItemGroup"; +import MenuSectionTitle from "@/new/common/components/menu/MenuSectionTitle"; import { EnteMenuItem } from "@ente/shared/components/Menu/EnteMenuItem"; import Add from "@mui/icons-material/Add"; import AdminPanelSettingsIcon from "@mui/icons-material/AdminPanelSettings"; @@ -6,11 +9,8 @@ import ModeEditIcon from "@mui/icons-material/ModeEdit"; import Photo from "@mui/icons-material/Photo"; import { DialogProps, Stack } from "@mui/material"; import { EnteDrawer } from "components/EnteDrawer"; -import MenuItemDivider from "components/Menu/MenuItemDivider"; -import { MenuItemGroup } from "components/Menu/MenuItemGroup"; -import MenuSectionTitle from "components/Menu/MenuSectionTitle"; -import Titlebar from "components/Titlebar"; import Avatar from "components/pages/gallery/Avatar"; +import Titlebar from "components/Titlebar"; import { t } from "i18next"; import { AppContext } from "pages/_app"; import { GalleryContext } from "pages/gallery"; diff --git a/web/apps/photos/src/components/Collections/CollectionShare/emailShare/ManageParticipant.tsx b/web/apps/photos/src/components/Collections/CollectionShare/emailShare/ManageParticipant.tsx index c444c63faf..014f013a40 100644 --- a/web/apps/photos/src/components/Collections/CollectionShare/emailShare/ManageParticipant.tsx +++ b/web/apps/photos/src/components/Collections/CollectionShare/emailShare/ManageParticipant.tsx @@ -1,3 +1,5 @@ +import MenuItemDivider from "@/new/common/components/menu/MenuItemDivider"; +import { MenuItemGroup } from "@/new/common/components/menu/MenuItemGroup"; import log from "@/next/log"; import { EnteMenuItem } from "@ente/shared/components/Menu/EnteMenuItem"; import BlockIcon from "@mui/icons-material/Block"; @@ -6,8 +8,6 @@ import ModeEditIcon from "@mui/icons-material/ModeEdit"; import PhotoIcon from "@mui/icons-material/Photo"; import { DialogProps, Stack, Typography } from "@mui/material"; import { EnteDrawer } from "components/EnteDrawer"; -import MenuItemDivider from "components/Menu/MenuItemDivider"; -import { MenuItemGroup } from "components/Menu/MenuItemGroup"; import Titlebar from "components/Titlebar"; import { t } from "i18next"; import { AppContext } from "pages/_app"; diff --git a/web/apps/photos/src/components/Collections/CollectionShare/emailShare/index.tsx b/web/apps/photos/src/components/Collections/CollectionShare/emailShare/index.tsx index 9d2444e8aa..febb6e4d29 100644 --- a/web/apps/photos/src/components/Collections/CollectionShare/emailShare/index.tsx +++ b/web/apps/photos/src/components/Collections/CollectionShare/emailShare/index.tsx @@ -1,14 +1,14 @@ import { useRef, useState } from "react"; import { COLLECTION_ROLE, Collection } from "types/collection"; +import MenuItemDivider from "@/new/common/components/menu/MenuItemDivider"; +import { MenuItemGroup } from "@/new/common/components/menu/MenuItemGroup"; +import MenuSectionTitle from "@/new/common/components/menu/MenuSectionTitle"; import { EnteMenuItem } from "@ente/shared/components/Menu/EnteMenuItem"; import AddIcon from "@mui/icons-material/Add"; import ChevronRight from "@mui/icons-material/ChevronRight"; import Workspaces from "@mui/icons-material/Workspaces"; import { Stack } from "@mui/material"; -import MenuItemDivider from "components/Menu/MenuItemDivider"; -import { MenuItemGroup } from "components/Menu/MenuItemGroup"; -import MenuSectionTitle from "components/Menu/MenuSectionTitle"; import AvatarGroup from "components/pages/gallery/AvatarGroup"; import { t } from "i18next"; import AddParticipant from "./AddParticipant"; diff --git a/web/apps/photos/src/components/Collections/CollectionShare/publicShare/EnablePublicShareOptions.tsx b/web/apps/photos/src/components/Collections/CollectionShare/publicShare/EnablePublicShareOptions.tsx index 5df152e0c7..d5ca9c8bdf 100644 --- a/web/apps/photos/src/components/Collections/CollectionShare/publicShare/EnablePublicShareOptions.tsx +++ b/web/apps/photos/src/components/Collections/CollectionShare/publicShare/EnablePublicShareOptions.tsx @@ -1,11 +1,11 @@ +import MenuItemDivider from "@/new/common/components/menu/MenuItemDivider"; +import { MenuItemGroup } from "@/new/common/components/menu/MenuItemGroup"; +import MenuSectionTitle from "@/new/common/components/menu/MenuSectionTitle"; import { EnteMenuItem } from "@ente/shared/components/Menu/EnteMenuItem"; import DownloadSharp from "@mui/icons-material/DownloadSharp"; import LinkIcon from "@mui/icons-material/Link"; import PublicIcon from "@mui/icons-material/Public"; import { Stack, Typography } from "@mui/material"; -import MenuItemDivider from "components/Menu/MenuItemDivider"; -import { MenuItemGroup } from "components/Menu/MenuItemGroup"; -import MenuSectionTitle from "components/Menu/MenuSectionTitle"; import { t } from "i18next"; import { GalleryContext } from "pages/gallery"; import { useContext, useState } from "react"; diff --git a/web/apps/photos/src/components/Collections/CollectionShare/publicShare/manage/deviceLimit.tsx b/web/apps/photos/src/components/Collections/CollectionShare/publicShare/manage/deviceLimit.tsx index aacd0f2185..3377cb0276 100644 --- a/web/apps/photos/src/components/Collections/CollectionShare/publicShare/manage/deviceLimit.tsx +++ b/web/apps/photos/src/components/Collections/CollectionShare/publicShare/manage/deviceLimit.tsx @@ -1,9 +1,9 @@ +import MenuItemDivider from "@/new/common/components/menu/MenuItemDivider"; +import { MenuItemGroup } from "@/new/common/components/menu/MenuItemGroup"; import { EnteMenuItem } from "@ente/shared/components/Menu/EnteMenuItem"; import ChevronRight from "@mui/icons-material/ChevronRight"; import { DialogProps, Stack } from "@mui/material"; import { EnteDrawer } from "components/EnteDrawer"; -import MenuItemDivider from "components/Menu/MenuItemDivider"; -import { MenuItemGroup } from "components/Menu/MenuItemGroup"; import Titlebar from "components/Titlebar"; import { t } from "i18next"; import { useMemo, useState } from "react"; diff --git a/web/apps/photos/src/components/Collections/CollectionShare/publicShare/manage/index.tsx b/web/apps/photos/src/components/Collections/CollectionShare/publicShare/manage/index.tsx index be93a36a10..d4b253780b 100644 --- a/web/apps/photos/src/components/Collections/CollectionShare/publicShare/manage/index.tsx +++ b/web/apps/photos/src/components/Collections/CollectionShare/publicShare/manage/index.tsx @@ -1,10 +1,10 @@ +import MenuItemDivider from "@/new/common/components/menu/MenuItemDivider"; +import { MenuItemGroup } from "@/new/common/components/menu/MenuItemGroup"; import { EnteMenuItem } from "@ente/shared/components/Menu/EnteMenuItem"; import ContentCopyIcon from "@mui/icons-material/ContentCopy"; import RemoveCircleOutline from "@mui/icons-material/RemoveCircleOutline"; import { DialogProps, Stack, Typography } from "@mui/material"; import { EnteDrawer } from "components/EnteDrawer"; -import MenuItemDivider from "components/Menu/MenuItemDivider"; -import { MenuItemGroup } from "components/Menu/MenuItemGroup"; import Titlebar from "components/Titlebar"; import { t } from "i18next"; import { GalleryContext } from "pages/gallery"; diff --git a/web/apps/photos/src/components/Collections/CollectionShare/publicShare/manage/linkExpiry.tsx b/web/apps/photos/src/components/Collections/CollectionShare/publicShare/manage/linkExpiry.tsx index 458fcd20a1..6c311e365b 100644 --- a/web/apps/photos/src/components/Collections/CollectionShare/publicShare/manage/linkExpiry.tsx +++ b/web/apps/photos/src/components/Collections/CollectionShare/publicShare/manage/linkExpiry.tsx @@ -1,10 +1,10 @@ +import MenuItemDivider from "@/new/common/components/menu/MenuItemDivider"; +import { MenuItemGroup } from "@/new/common/components/menu/MenuItemGroup"; import { EnteMenuItem } from "@ente/shared/components/Menu/EnteMenuItem"; import { formatDateTime } from "@ente/shared/time/format"; import ChevronRight from "@mui/icons-material/ChevronRight"; import { DialogProps, Stack } from "@mui/material"; import { EnteDrawer } from "components/EnteDrawer"; -import MenuItemDivider from "components/Menu/MenuItemDivider"; -import { MenuItemGroup } from "components/Menu/MenuItemGroup"; import Titlebar from "components/Titlebar"; import { t } from "i18next"; import { useMemo, useState } from "react"; diff --git a/web/apps/photos/src/components/Collections/CollectionShare/publicShare/manage/publicCollect.tsx b/web/apps/photos/src/components/Collections/CollectionShare/publicShare/manage/publicCollect.tsx index bfd78f1a31..1fc5a3385d 100644 --- a/web/apps/photos/src/components/Collections/CollectionShare/publicShare/manage/publicCollect.tsx +++ b/web/apps/photos/src/components/Collections/CollectionShare/publicShare/manage/publicCollect.tsx @@ -1,7 +1,7 @@ +import { MenuItemGroup } from "@/new/common/components/menu/MenuItemGroup"; +import MenuSectionTitle from "@/new/common/components/menu/MenuSectionTitle"; import { EnteMenuItem } from "@ente/shared/components/Menu/EnteMenuItem"; import { Stack } from "@mui/material"; -import { MenuItemGroup } from "components/Menu/MenuItemGroup"; -import MenuSectionTitle from "components/Menu/MenuSectionTitle"; import { t } from "i18next"; import { Collection, PublicURL, UpdatePublicURL } from "types/collection"; diff --git a/web/apps/photos/src/components/Collections/CollectionShare/publicShare/managePublicShare.tsx b/web/apps/photos/src/components/Collections/CollectionShare/publicShare/managePublicShare.tsx index 677228d55f..fe3dc1cf83 100644 --- a/web/apps/photos/src/components/Collections/CollectionShare/publicShare/managePublicShare.tsx +++ b/web/apps/photos/src/components/Collections/CollectionShare/publicShare/managePublicShare.tsx @@ -1,3 +1,5 @@ +import MenuItemDivider from "@/new/common/components/menu/MenuItemDivider"; +import { MenuItemGroup } from "@/new/common/components/menu/MenuItemGroup"; import { EnteMenuItem } from "@ente/shared/components/Menu/EnteMenuItem"; import ChevronRightIcon from "@mui/icons-material/ChevronRight"; import ContentCopyIcon from "@mui/icons-material/ContentCopyOutlined"; @@ -5,8 +7,6 @@ import ErrorOutlineIcon from "@mui/icons-material/ErrorOutline"; import LinkIcon from "@mui/icons-material/Link"; import PublicIcon from "@mui/icons-material/Public"; import { Stack, Typography } from "@mui/material"; -import MenuItemDivider from "components/Menu/MenuItemDivider"; -import { MenuItemGroup } from "components/Menu/MenuItemGroup"; import { t } from "i18next"; import { useState } from "react"; import { Collection, PublicURL } from "types/collection"; diff --git a/web/apps/photos/src/components/Collections/CollectionShare/sharingDetails.tsx b/web/apps/photos/src/components/Collections/CollectionShare/sharingDetails.tsx index e7ae9011cc..45dd8d9135 100644 --- a/web/apps/photos/src/components/Collections/CollectionShare/sharingDetails.tsx +++ b/web/apps/photos/src/components/Collections/CollectionShare/sharingDetails.tsx @@ -1,11 +1,11 @@ +import MenuItemDivider from "@/new/common/components/menu/MenuItemDivider"; +import { MenuItemGroup } from "@/new/common/components/menu/MenuItemGroup"; +import MenuSectionTitle from "@/new/common/components/menu/MenuSectionTitle"; import { EnteMenuItem } from "@ente/shared/components/Menu/EnteMenuItem"; import AdminPanelSettingsIcon from "@mui/icons-material/AdminPanelSettings"; import ModeEditIcon from "@mui/icons-material/ModeEdit"; import Photo from "@mui/icons-material/Photo"; import { Stack } from "@mui/material"; -import MenuItemDivider from "components/Menu/MenuItemDivider"; -import { MenuItemGroup } from "components/Menu/MenuItemGroup"; -import MenuSectionTitle from "components/Menu/MenuSectionTitle"; import Avatar from "components/pages/gallery/Avatar"; import { CollectionSummaryType } from "constants/collection"; import { t } from "i18next"; diff --git a/web/apps/photos/src/components/PhotoViewer/ImageEditorOverlay/ColoursMenu.tsx b/web/apps/photos/src/components/PhotoViewer/ImageEditorOverlay/ColoursMenu.tsx index deaebe2cf2..0db42793e2 100644 --- a/web/apps/photos/src/components/PhotoViewer/ImageEditorOverlay/ColoursMenu.tsx +++ b/web/apps/photos/src/components/PhotoViewer/ImageEditorOverlay/ColoursMenu.tsx @@ -1,7 +1,7 @@ +import { MenuItemGroup } from "@/new/common/components/menu/MenuItemGroup"; +import MenuSectionTitle from "@/new/common/components/menu/MenuSectionTitle"; import { EnteMenuItem } from "@ente/shared/components/Menu/EnteMenuItem"; import { Box, Slider } from "@mui/material"; -import { MenuItemGroup } from "components/Menu/MenuItemGroup"; -import MenuSectionTitle from "components/Menu/MenuSectionTitle"; import { t } from "i18next"; import type { Dispatch, SetStateAction } from "react"; diff --git a/web/apps/photos/src/components/PhotoViewer/ImageEditorOverlay/CropMenu.tsx b/web/apps/photos/src/components/PhotoViewer/ImageEditorOverlay/CropMenu.tsx index 11916a13a1..dd4a13b29d 100644 --- a/web/apps/photos/src/components/PhotoViewer/ImageEditorOverlay/CropMenu.tsx +++ b/web/apps/photos/src/components/PhotoViewer/ImageEditorOverlay/CropMenu.tsx @@ -1,7 +1,7 @@ +import { MenuItemGroup } from "@/new/common/components/menu/MenuItemGroup"; +import MenuSectionTitle from "@/new/common/components/menu/MenuSectionTitle"; import { EnteMenuItem } from "@ente/shared/components/Menu/EnteMenuItem"; import CropIcon from "@mui/icons-material/Crop"; -import { MenuItemGroup } from "components/Menu/MenuItemGroup"; -import MenuSectionTitle from "components/Menu/MenuSectionTitle"; import { t } from "i18next"; import type { MutableRefObject } from "react"; import { useContext } from "react"; diff --git a/web/apps/photos/src/components/PhotoViewer/ImageEditorOverlay/TransformMenu.tsx b/web/apps/photos/src/components/PhotoViewer/ImageEditorOverlay/TransformMenu.tsx index 6176ab3c18..2c56b93ff8 100644 --- a/web/apps/photos/src/components/PhotoViewer/ImageEditorOverlay/TransformMenu.tsx +++ b/web/apps/photos/src/components/PhotoViewer/ImageEditorOverlay/TransformMenu.tsx @@ -1,3 +1,6 @@ +import MenuItemDivider from "@/new/common/components/menu/MenuItemDivider"; +import { MenuItemGroup } from "@/new/common/components/menu/MenuItemGroup"; +import MenuSectionTitle from "@/new/common/components/menu/MenuSectionTitle"; import log from "@/next/log"; import { EnteMenuItem } from "@ente/shared/components/Menu/EnteMenuItem"; import Crop169Icon from "@mui/icons-material/Crop169"; @@ -6,9 +9,6 @@ import CropSquareIcon from "@mui/icons-material/CropSquare"; import FlipIcon from "@mui/icons-material/Flip"; import RotateLeftIcon from "@mui/icons-material/RotateLeft"; import RotateRightIcon from "@mui/icons-material/RotateRight"; -import MenuItemDivider from "components/Menu/MenuItemDivider"; -import { MenuItemGroup } from "components/Menu/MenuItemGroup"; -import MenuSectionTitle from "components/Menu/MenuSectionTitle"; import { t } from "i18next"; import { Fragment, useContext } from "react"; import { ImageEditorOverlayContext } from "."; diff --git a/web/apps/photos/src/components/PhotoViewer/ImageEditorOverlay/index.tsx b/web/apps/photos/src/components/PhotoViewer/ImageEditorOverlay/index.tsx index fe7f2724e2..2aa924a054 100644 --- a/web/apps/photos/src/components/PhotoViewer/ImageEditorOverlay/index.tsx +++ b/web/apps/photos/src/components/PhotoViewer/ImageEditorOverlay/index.tsx @@ -1,3 +1,6 @@ +import MenuItemDivider from "@/new/common/components/menu/MenuItemDivider"; +import { MenuItemGroup } from "@/new/common/components/menu/MenuItemGroup"; +import MenuSectionTitle from "@/new/common/components/menu/MenuSectionTitle"; import downloadManager from "@/new/photos/services/download"; import { EnteFile } from "@/new/photos/types/file"; import { nameAndExtension } from "@/next/file"; @@ -27,9 +30,6 @@ import { Typography, } from "@mui/material"; import { EnteDrawer } from "components/EnteDrawer"; -import MenuItemDivider from "components/Menu/MenuItemDivider"; -import { MenuItemGroup } from "components/Menu/MenuItemGroup"; -import MenuSectionTitle from "components/Menu/MenuSectionTitle"; import { CORNER_THRESHOLD, FILTER_DEFAULT_VALUES } from "constants/photoEditor"; import { t } from "i18next"; import { AppContext } from "pages/_app"; diff --git a/web/apps/photos/src/components/Sidebar/AdvancedSettings.tsx b/web/apps/photos/src/components/Sidebar/AdvancedSettings.tsx index 9ef7a26973..742ebe0ebf 100644 --- a/web/apps/photos/src/components/Sidebar/AdvancedSettings.tsx +++ b/web/apps/photos/src/components/Sidebar/AdvancedSettings.tsx @@ -1,10 +1,10 @@ +import { MenuItemGroup } from "@/new/common/components/menu/MenuItemGroup"; +import MenuSectionTitle from "@/new/common/components/menu/MenuSectionTitle"; import { EnteMenuItem } from "@ente/shared/components/Menu/EnteMenuItem"; import ChevronRight from "@mui/icons-material/ChevronRight"; import ScienceIcon from "@mui/icons-material/Science"; import { Box, DialogProps, Stack } from "@mui/material"; import { EnteDrawer } from "components/EnteDrawer"; -import { MenuItemGroup } from "components/Menu/MenuItemGroup"; -import MenuSectionTitle from "components/Menu/MenuSectionTitle"; import Titlebar from "components/Titlebar"; import { MLSearchSettings } from "components/ml/MLSearchSettings"; import { t } from "i18next"; diff --git a/web/apps/photos/src/components/Sidebar/MapSetting.tsx b/web/apps/photos/src/components/Sidebar/MapSetting.tsx index 18d1a0639a..7ce53ca852 100644 --- a/web/apps/photos/src/components/Sidebar/MapSetting.tsx +++ b/web/apps/photos/src/components/Sidebar/MapSetting.tsx @@ -1,3 +1,4 @@ +import { MenuItemGroup } from "@/new/common/components/menu/MenuItemGroup"; import log from "@/next/log"; import { EnteMenuItem } from "@ente/shared/components/Menu/EnteMenuItem"; import { @@ -9,7 +10,6 @@ import { Typography, } from "@mui/material"; import { EnteDrawer } from "components/EnteDrawer"; -import { MenuItemGroup } from "components/Menu/MenuItemGroup"; import Titlebar from "components/Titlebar"; import { t } from "i18next"; import { AppContext } from "pages/_app"; diff --git a/web/apps/photos/src/components/ml/MLSearchSettings.tsx b/web/apps/photos/src/components/ml/MLSearchSettings.tsx index 118684dccc..abdc8a38c7 100644 --- a/web/apps/photos/src/components/ml/MLSearchSettings.tsx +++ b/web/apps/photos/src/components/ml/MLSearchSettings.tsx @@ -1,3 +1,4 @@ +import { MenuItemGroup } from "@/new/common/components/menu/MenuItemGroup"; import { canEnableFaceIndexing, disableML, @@ -18,7 +19,6 @@ import { Typography, } from "@mui/material"; import { EnteDrawer } from "components/EnteDrawer"; -import { MenuItemGroup } from "components/Menu/MenuItemGroup"; import Titlebar from "components/Titlebar"; import { t } from "i18next"; import { AppContext } from "pages/_app"; diff --git a/web/apps/photos/src/components/Menu/MenuItemDivider.tsx b/web/packages/new/common/components/menu/MenuItemDivider.tsx similarity index 100% rename from web/apps/photos/src/components/Menu/MenuItemDivider.tsx rename to web/packages/new/common/components/menu/MenuItemDivider.tsx diff --git a/web/apps/photos/src/components/Menu/MenuItemGroup.tsx b/web/packages/new/common/components/menu/MenuItemGroup.tsx similarity index 100% rename from web/apps/photos/src/components/Menu/MenuItemGroup.tsx rename to web/packages/new/common/components/menu/MenuItemGroup.tsx diff --git a/web/apps/photos/src/components/Menu/MenuSectionTitle.tsx b/web/packages/new/common/components/menu/MenuSectionTitle.tsx similarity index 100% rename from web/apps/photos/src/components/Menu/MenuSectionTitle.tsx rename to web/packages/new/common/components/menu/MenuSectionTitle.tsx diff --git a/web/packages/shared/components/Menu/MenuItemDivider.tsx b/web/packages/shared/components/Menu/MenuItemDivider.tsx deleted file mode 100644 index da3b309a2b..0000000000 --- a/web/packages/shared/components/Menu/MenuItemDivider.tsx +++ /dev/null @@ -1,16 +0,0 @@ -import { Divider } from "@mui/material"; -interface Iprops { - hasIcon?: boolean; -} -export default function MenuItemDivider({ hasIcon = false }: Iprops) { - return ( - - ); -} diff --git a/web/packages/shared/components/Menu/MenuItemGroup.tsx b/web/packages/shared/components/Menu/MenuItemGroup.tsx deleted file mode 100644 index 0b80262b5f..0000000000 --- a/web/packages/shared/components/Menu/MenuItemGroup.tsx +++ /dev/null @@ -1,20 +0,0 @@ -import { styled } from "@mui/material"; - -export const MenuItemGroup = styled("div")( - ({ theme }) => ` - & > .MuiMenuItem-root{ - border-radius: 8px; - background-color: transparent; - } - & > .MuiMenuItem-root:not(:last-of-type) { - border-bottom-left-radius: 0; - border-bottom-right-radius: 0; - } - & > .MuiMenuItem-root:not(:first-of-type) { - border-top-left-radius: 0; - border-top-right-radius: 0; - } - background-color: ${theme.colors.fill.faint}; - border-radius: 8px; -`, -); diff --git a/web/packages/shared/components/Menu/MenuSectionTitle.tsx b/web/packages/shared/components/Menu/MenuSectionTitle.tsx deleted file mode 100644 index 5c07b8d92b..0000000000 --- a/web/packages/shared/components/Menu/MenuSectionTitle.tsx +++ /dev/null @@ -1,28 +0,0 @@ -import { VerticallyCenteredFlex } from "@ente/shared/components/Container"; -import { Typography } from "@mui/material"; - -interface Iprops { - title: string; - icon?: JSX.Element; -} - -export default function MenuSectionTitle({ title, icon }: Iprops) { - return ( - svg": { - fontSize: "17px", - color: (theme) => theme.colors.stroke.muted, - }, - }} - > - {icon && icon} - - {title} - - - ); -} From 4d11623f770cadac01be0dc7e215111fe6a0b02a Mon Sep 17 00:00:00 2001 From: Manav Rathi Date: Wed, 10 Jul 2024 10:47:41 +0530 Subject: [PATCH 05/67] Fix warnings --- web/apps/accounts/src/pages/passkeys/index.tsx | 2 +- .../CollectionShare/emailShare/AddParticipantForm.tsx | 2 +- .../CollectionShare/emailShare/ManageEmailShare.tsx | 2 +- .../CollectionShare/emailShare/ManageParticipant.tsx | 2 +- .../Collections/CollectionShare/emailShare/index.tsx | 2 +- .../publicShare/EnablePublicShareOptions.tsx | 2 +- .../publicShare/manage/deviceLimit.tsx | 2 +- .../CollectionShare/publicShare/manage/index.tsx | 2 +- .../CollectionShare/publicShare/manage/linkExpiry.tsx | 2 +- .../CollectionShare/publicShare/managePublicShare.tsx | 2 +- .../Collections/CollectionShare/sharingDetails.tsx | 2 +- .../PhotoViewer/ImageEditorOverlay/TransformMenu.tsx | 2 +- .../PhotoViewer/ImageEditorOverlay/index.tsx | 2 +- .../new/common/components/menu/MenuItemDivider.tsx | 11 ++++++++--- 14 files changed, 21 insertions(+), 16 deletions(-) diff --git a/web/apps/accounts/src/pages/passkeys/index.tsx b/web/apps/accounts/src/pages/passkeys/index.tsx index f928cabcca..04a68e1c84 100644 --- a/web/apps/accounts/src/pages/passkeys/index.tsx +++ b/web/apps/accounts/src/pages/passkeys/index.tsx @@ -1,4 +1,4 @@ -import MenuItemDivider from "@/new/common/components/menu/MenuItemDivider"; +import { MenuItemDivider } from "@/new/common/components/menu/MenuItemDivider"; import { MenuItemGroup } from "@/new/common/components/menu/MenuItemGroup"; import log from "@/next/log"; import { ensure } from "@/utils/ensure"; diff --git a/web/apps/photos/src/components/Collections/CollectionShare/emailShare/AddParticipantForm.tsx b/web/apps/photos/src/components/Collections/CollectionShare/emailShare/AddParticipantForm.tsx index bb36ae2e8a..bd07d854cf 100644 --- a/web/apps/photos/src/components/Collections/CollectionShare/emailShare/AddParticipantForm.tsx +++ b/web/apps/photos/src/components/Collections/CollectionShare/emailShare/AddParticipantForm.tsx @@ -1,4 +1,4 @@ -import MenuItemDivider from "@/new/common/components/menu/MenuItemDivider"; +import { MenuItemDivider } from "@/new/common/components/menu/MenuItemDivider"; import { MenuItemGroup } from "@/new/common/components/menu/MenuItemGroup"; import MenuSectionTitle from "@/new/common/components/menu/MenuSectionTitle"; import { FlexWrapper } from "@ente/shared/components/Container"; diff --git a/web/apps/photos/src/components/Collections/CollectionShare/emailShare/ManageEmailShare.tsx b/web/apps/photos/src/components/Collections/CollectionShare/emailShare/ManageEmailShare.tsx index d33ce32605..13f4a2d9e7 100644 --- a/web/apps/photos/src/components/Collections/CollectionShare/emailShare/ManageEmailShare.tsx +++ b/web/apps/photos/src/components/Collections/CollectionShare/emailShare/ManageEmailShare.tsx @@ -1,4 +1,4 @@ -import MenuItemDivider from "@/new/common/components/menu/MenuItemDivider"; +import { MenuItemDivider } from "@/new/common/components/menu/MenuItemDivider"; import { MenuItemGroup } from "@/new/common/components/menu/MenuItemGroup"; import MenuSectionTitle from "@/new/common/components/menu/MenuSectionTitle"; import { EnteMenuItem } from "@ente/shared/components/Menu/EnteMenuItem"; diff --git a/web/apps/photos/src/components/Collections/CollectionShare/emailShare/ManageParticipant.tsx b/web/apps/photos/src/components/Collections/CollectionShare/emailShare/ManageParticipant.tsx index 014f013a40..38adca4c87 100644 --- a/web/apps/photos/src/components/Collections/CollectionShare/emailShare/ManageParticipant.tsx +++ b/web/apps/photos/src/components/Collections/CollectionShare/emailShare/ManageParticipant.tsx @@ -1,4 +1,4 @@ -import MenuItemDivider from "@/new/common/components/menu/MenuItemDivider"; +import { MenuItemDivider } from "@/new/common/components/menu/MenuItemDivider"; import { MenuItemGroup } from "@/new/common/components/menu/MenuItemGroup"; import log from "@/next/log"; import { EnteMenuItem } from "@ente/shared/components/Menu/EnteMenuItem"; diff --git a/web/apps/photos/src/components/Collections/CollectionShare/emailShare/index.tsx b/web/apps/photos/src/components/Collections/CollectionShare/emailShare/index.tsx index febb6e4d29..58dc59b385 100644 --- a/web/apps/photos/src/components/Collections/CollectionShare/emailShare/index.tsx +++ b/web/apps/photos/src/components/Collections/CollectionShare/emailShare/index.tsx @@ -1,7 +1,7 @@ import { useRef, useState } from "react"; import { COLLECTION_ROLE, Collection } from "types/collection"; -import MenuItemDivider from "@/new/common/components/menu/MenuItemDivider"; +import { MenuItemDivider } from "@/new/common/components/menu/MenuItemDivider"; import { MenuItemGroup } from "@/new/common/components/menu/MenuItemGroup"; import MenuSectionTitle from "@/new/common/components/menu/MenuSectionTitle"; import { EnteMenuItem } from "@ente/shared/components/Menu/EnteMenuItem"; diff --git a/web/apps/photos/src/components/Collections/CollectionShare/publicShare/EnablePublicShareOptions.tsx b/web/apps/photos/src/components/Collections/CollectionShare/publicShare/EnablePublicShareOptions.tsx index d5ca9c8bdf..ab8cc25239 100644 --- a/web/apps/photos/src/components/Collections/CollectionShare/publicShare/EnablePublicShareOptions.tsx +++ b/web/apps/photos/src/components/Collections/CollectionShare/publicShare/EnablePublicShareOptions.tsx @@ -1,4 +1,4 @@ -import MenuItemDivider from "@/new/common/components/menu/MenuItemDivider"; +import { MenuItemDivider } from "@/new/common/components/menu/MenuItemDivider"; import { MenuItemGroup } from "@/new/common/components/menu/MenuItemGroup"; import MenuSectionTitle from "@/new/common/components/menu/MenuSectionTitle"; import { EnteMenuItem } from "@ente/shared/components/Menu/EnteMenuItem"; diff --git a/web/apps/photos/src/components/Collections/CollectionShare/publicShare/manage/deviceLimit.tsx b/web/apps/photos/src/components/Collections/CollectionShare/publicShare/manage/deviceLimit.tsx index 3377cb0276..c076da752e 100644 --- a/web/apps/photos/src/components/Collections/CollectionShare/publicShare/manage/deviceLimit.tsx +++ b/web/apps/photos/src/components/Collections/CollectionShare/publicShare/manage/deviceLimit.tsx @@ -1,4 +1,4 @@ -import MenuItemDivider from "@/new/common/components/menu/MenuItemDivider"; +import { MenuItemDivider } from "@/new/common/components/menu/MenuItemDivider"; import { MenuItemGroup } from "@/new/common/components/menu/MenuItemGroup"; import { EnteMenuItem } from "@ente/shared/components/Menu/EnteMenuItem"; import ChevronRight from "@mui/icons-material/ChevronRight"; diff --git a/web/apps/photos/src/components/Collections/CollectionShare/publicShare/manage/index.tsx b/web/apps/photos/src/components/Collections/CollectionShare/publicShare/manage/index.tsx index d4b253780b..d97d59c191 100644 --- a/web/apps/photos/src/components/Collections/CollectionShare/publicShare/manage/index.tsx +++ b/web/apps/photos/src/components/Collections/CollectionShare/publicShare/manage/index.tsx @@ -1,4 +1,4 @@ -import MenuItemDivider from "@/new/common/components/menu/MenuItemDivider"; +import { MenuItemDivider } from "@/new/common/components/menu/MenuItemDivider"; import { MenuItemGroup } from "@/new/common/components/menu/MenuItemGroup"; import { EnteMenuItem } from "@ente/shared/components/Menu/EnteMenuItem"; import ContentCopyIcon from "@mui/icons-material/ContentCopy"; diff --git a/web/apps/photos/src/components/Collections/CollectionShare/publicShare/manage/linkExpiry.tsx b/web/apps/photos/src/components/Collections/CollectionShare/publicShare/manage/linkExpiry.tsx index 6c311e365b..8b4e04cb93 100644 --- a/web/apps/photos/src/components/Collections/CollectionShare/publicShare/manage/linkExpiry.tsx +++ b/web/apps/photos/src/components/Collections/CollectionShare/publicShare/manage/linkExpiry.tsx @@ -1,4 +1,4 @@ -import MenuItemDivider from "@/new/common/components/menu/MenuItemDivider"; +import { MenuItemDivider } from "@/new/common/components/menu/MenuItemDivider"; import { MenuItemGroup } from "@/new/common/components/menu/MenuItemGroup"; import { EnteMenuItem } from "@ente/shared/components/Menu/EnteMenuItem"; import { formatDateTime } from "@ente/shared/time/format"; diff --git a/web/apps/photos/src/components/Collections/CollectionShare/publicShare/managePublicShare.tsx b/web/apps/photos/src/components/Collections/CollectionShare/publicShare/managePublicShare.tsx index fe3dc1cf83..e2b58b15cf 100644 --- a/web/apps/photos/src/components/Collections/CollectionShare/publicShare/managePublicShare.tsx +++ b/web/apps/photos/src/components/Collections/CollectionShare/publicShare/managePublicShare.tsx @@ -1,4 +1,4 @@ -import MenuItemDivider from "@/new/common/components/menu/MenuItemDivider"; +import { MenuItemDivider } from "@/new/common/components/menu/MenuItemDivider"; import { MenuItemGroup } from "@/new/common/components/menu/MenuItemGroup"; import { EnteMenuItem } from "@ente/shared/components/Menu/EnteMenuItem"; import ChevronRightIcon from "@mui/icons-material/ChevronRight"; diff --git a/web/apps/photos/src/components/Collections/CollectionShare/sharingDetails.tsx b/web/apps/photos/src/components/Collections/CollectionShare/sharingDetails.tsx index 45dd8d9135..16f715520a 100644 --- a/web/apps/photos/src/components/Collections/CollectionShare/sharingDetails.tsx +++ b/web/apps/photos/src/components/Collections/CollectionShare/sharingDetails.tsx @@ -1,4 +1,4 @@ -import MenuItemDivider from "@/new/common/components/menu/MenuItemDivider"; +import { MenuItemDivider } from "@/new/common/components/menu/MenuItemDivider"; import { MenuItemGroup } from "@/new/common/components/menu/MenuItemGroup"; import MenuSectionTitle from "@/new/common/components/menu/MenuSectionTitle"; import { EnteMenuItem } from "@ente/shared/components/Menu/EnteMenuItem"; diff --git a/web/apps/photos/src/components/PhotoViewer/ImageEditorOverlay/TransformMenu.tsx b/web/apps/photos/src/components/PhotoViewer/ImageEditorOverlay/TransformMenu.tsx index 2c56b93ff8..dd0e1f43cb 100644 --- a/web/apps/photos/src/components/PhotoViewer/ImageEditorOverlay/TransformMenu.tsx +++ b/web/apps/photos/src/components/PhotoViewer/ImageEditorOverlay/TransformMenu.tsx @@ -1,4 +1,4 @@ -import MenuItemDivider from "@/new/common/components/menu/MenuItemDivider"; +import { MenuItemDivider } from "@/new/common/components/menu/MenuItemDivider"; import { MenuItemGroup } from "@/new/common/components/menu/MenuItemGroup"; import MenuSectionTitle from "@/new/common/components/menu/MenuSectionTitle"; import log from "@/next/log"; diff --git a/web/apps/photos/src/components/PhotoViewer/ImageEditorOverlay/index.tsx b/web/apps/photos/src/components/PhotoViewer/ImageEditorOverlay/index.tsx index 2aa924a054..ff1310d232 100644 --- a/web/apps/photos/src/components/PhotoViewer/ImageEditorOverlay/index.tsx +++ b/web/apps/photos/src/components/PhotoViewer/ImageEditorOverlay/index.tsx @@ -1,4 +1,4 @@ -import MenuItemDivider from "@/new/common/components/menu/MenuItemDivider"; +import { MenuItemDivider } from "@/new/common/components/menu/MenuItemDivider"; import { MenuItemGroup } from "@/new/common/components/menu/MenuItemGroup"; import MenuSectionTitle from "@/new/common/components/menu/MenuSectionTitle"; import downloadManager from "@/new/photos/services/download"; diff --git a/web/packages/new/common/components/menu/MenuItemDivider.tsx b/web/packages/new/common/components/menu/MenuItemDivider.tsx index da3b309a2b..21c632ee49 100644 --- a/web/packages/new/common/components/menu/MenuItemDivider.tsx +++ b/web/packages/new/common/components/menu/MenuItemDivider.tsx @@ -1,8 +1,13 @@ import { Divider } from "@mui/material"; -interface Iprops { +import React from "react"; + +interface MenuItemDividerProps { hasIcon?: boolean; } -export default function MenuItemDivider({ hasIcon = false }: Iprops) { + +export const MenuItemDivider: React.FC = ({ + hasIcon, +}) => { return ( ); -} +}; From ecd4201304249763d01e440aeabb17d3da1a4e2e Mon Sep 17 00:00:00 2001 From: Manav Rathi Date: Wed, 10 Jul 2024 10:49:11 +0530 Subject: [PATCH 06/67] Fix warnings --- .../CollectionShare/emailShare/AddParticipantForm.tsx | 2 +- .../CollectionShare/emailShare/ManageEmailShare.tsx | 2 +- .../Collections/CollectionShare/emailShare/index.tsx | 2 +- .../publicShare/EnablePublicShareOptions.tsx | 2 +- .../publicShare/manage/publicCollect.tsx | 2 +- .../Collections/CollectionShare/sharingDetails.tsx | 2 +- .../PhotoViewer/ImageEditorOverlay/ColoursMenu.tsx | 2 +- .../PhotoViewer/ImageEditorOverlay/CropMenu.tsx | 2 +- .../PhotoViewer/ImageEditorOverlay/TransformMenu.tsx | 2 +- .../PhotoViewer/ImageEditorOverlay/index.tsx | 2 +- .../photos/src/components/Sidebar/AdvancedSettings.tsx | 2 +- .../new/common/components/menu/MenuSectionTitle.tsx | 10 +++++++--- 12 files changed, 18 insertions(+), 14 deletions(-) diff --git a/web/apps/photos/src/components/Collections/CollectionShare/emailShare/AddParticipantForm.tsx b/web/apps/photos/src/components/Collections/CollectionShare/emailShare/AddParticipantForm.tsx index bd07d854cf..0673dddff4 100644 --- a/web/apps/photos/src/components/Collections/CollectionShare/emailShare/AddParticipantForm.tsx +++ b/web/apps/photos/src/components/Collections/CollectionShare/emailShare/AddParticipantForm.tsx @@ -1,6 +1,6 @@ import { MenuItemDivider } from "@/new/common/components/menu/MenuItemDivider"; import { MenuItemGroup } from "@/new/common/components/menu/MenuItemGroup"; -import MenuSectionTitle from "@/new/common/components/menu/MenuSectionTitle"; +import { MenuSectionTitle } from "@/new/common/components/menu/MenuSectionTitle"; import { FlexWrapper } from "@ente/shared/components/Container"; import { EnteMenuItem } from "@ente/shared/components/Menu/EnteMenuItem"; import SubmitButton from "@ente/shared/components/SubmitButton"; diff --git a/web/apps/photos/src/components/Collections/CollectionShare/emailShare/ManageEmailShare.tsx b/web/apps/photos/src/components/Collections/CollectionShare/emailShare/ManageEmailShare.tsx index 13f4a2d9e7..b6ca4ba235 100644 --- a/web/apps/photos/src/components/Collections/CollectionShare/emailShare/ManageEmailShare.tsx +++ b/web/apps/photos/src/components/Collections/CollectionShare/emailShare/ManageEmailShare.tsx @@ -1,6 +1,6 @@ import { MenuItemDivider } from "@/new/common/components/menu/MenuItemDivider"; import { MenuItemGroup } from "@/new/common/components/menu/MenuItemGroup"; -import MenuSectionTitle from "@/new/common/components/menu/MenuSectionTitle"; +import { MenuSectionTitle } from "@/new/common/components/menu/MenuSectionTitle"; import { EnteMenuItem } from "@ente/shared/components/Menu/EnteMenuItem"; import Add from "@mui/icons-material/Add"; import AdminPanelSettingsIcon from "@mui/icons-material/AdminPanelSettings"; diff --git a/web/apps/photos/src/components/Collections/CollectionShare/emailShare/index.tsx b/web/apps/photos/src/components/Collections/CollectionShare/emailShare/index.tsx index 58dc59b385..72ebb02aac 100644 --- a/web/apps/photos/src/components/Collections/CollectionShare/emailShare/index.tsx +++ b/web/apps/photos/src/components/Collections/CollectionShare/emailShare/index.tsx @@ -3,7 +3,7 @@ import { COLLECTION_ROLE, Collection } from "types/collection"; import { MenuItemDivider } from "@/new/common/components/menu/MenuItemDivider"; import { MenuItemGroup } from "@/new/common/components/menu/MenuItemGroup"; -import MenuSectionTitle from "@/new/common/components/menu/MenuSectionTitle"; +import { MenuSectionTitle } from "@/new/common/components/menu/MenuSectionTitle"; import { EnteMenuItem } from "@ente/shared/components/Menu/EnteMenuItem"; import AddIcon from "@mui/icons-material/Add"; import ChevronRight from "@mui/icons-material/ChevronRight"; diff --git a/web/apps/photos/src/components/Collections/CollectionShare/publicShare/EnablePublicShareOptions.tsx b/web/apps/photos/src/components/Collections/CollectionShare/publicShare/EnablePublicShareOptions.tsx index ab8cc25239..e4751e939a 100644 --- a/web/apps/photos/src/components/Collections/CollectionShare/publicShare/EnablePublicShareOptions.tsx +++ b/web/apps/photos/src/components/Collections/CollectionShare/publicShare/EnablePublicShareOptions.tsx @@ -1,6 +1,6 @@ import { MenuItemDivider } from "@/new/common/components/menu/MenuItemDivider"; import { MenuItemGroup } from "@/new/common/components/menu/MenuItemGroup"; -import MenuSectionTitle from "@/new/common/components/menu/MenuSectionTitle"; +import { MenuSectionTitle } from "@/new/common/components/menu/MenuSectionTitle"; import { EnteMenuItem } from "@ente/shared/components/Menu/EnteMenuItem"; import DownloadSharp from "@mui/icons-material/DownloadSharp"; import LinkIcon from "@mui/icons-material/Link"; diff --git a/web/apps/photos/src/components/Collections/CollectionShare/publicShare/manage/publicCollect.tsx b/web/apps/photos/src/components/Collections/CollectionShare/publicShare/manage/publicCollect.tsx index 1fc5a3385d..88e16303fd 100644 --- a/web/apps/photos/src/components/Collections/CollectionShare/publicShare/manage/publicCollect.tsx +++ b/web/apps/photos/src/components/Collections/CollectionShare/publicShare/manage/publicCollect.tsx @@ -1,5 +1,5 @@ import { MenuItemGroup } from "@/new/common/components/menu/MenuItemGroup"; -import MenuSectionTitle from "@/new/common/components/menu/MenuSectionTitle"; +import { MenuSectionTitle } from "@/new/common/components/menu/MenuSectionTitle"; import { EnteMenuItem } from "@ente/shared/components/Menu/EnteMenuItem"; import { Stack } from "@mui/material"; import { t } from "i18next"; diff --git a/web/apps/photos/src/components/Collections/CollectionShare/sharingDetails.tsx b/web/apps/photos/src/components/Collections/CollectionShare/sharingDetails.tsx index 16f715520a..8ed470bc4f 100644 --- a/web/apps/photos/src/components/Collections/CollectionShare/sharingDetails.tsx +++ b/web/apps/photos/src/components/Collections/CollectionShare/sharingDetails.tsx @@ -1,6 +1,6 @@ import { MenuItemDivider } from "@/new/common/components/menu/MenuItemDivider"; import { MenuItemGroup } from "@/new/common/components/menu/MenuItemGroup"; -import MenuSectionTitle from "@/new/common/components/menu/MenuSectionTitle"; +import { MenuSectionTitle } from "@/new/common/components/menu/MenuSectionTitle"; import { EnteMenuItem } from "@ente/shared/components/Menu/EnteMenuItem"; import AdminPanelSettingsIcon from "@mui/icons-material/AdminPanelSettings"; import ModeEditIcon from "@mui/icons-material/ModeEdit"; diff --git a/web/apps/photos/src/components/PhotoViewer/ImageEditorOverlay/ColoursMenu.tsx b/web/apps/photos/src/components/PhotoViewer/ImageEditorOverlay/ColoursMenu.tsx index 0db42793e2..b440cb3ad4 100644 --- a/web/apps/photos/src/components/PhotoViewer/ImageEditorOverlay/ColoursMenu.tsx +++ b/web/apps/photos/src/components/PhotoViewer/ImageEditorOverlay/ColoursMenu.tsx @@ -1,5 +1,5 @@ import { MenuItemGroup } from "@/new/common/components/menu/MenuItemGroup"; -import MenuSectionTitle from "@/new/common/components/menu/MenuSectionTitle"; +import { MenuSectionTitle } from "@/new/common/components/menu/MenuSectionTitle"; import { EnteMenuItem } from "@ente/shared/components/Menu/EnteMenuItem"; import { Box, Slider } from "@mui/material"; import { t } from "i18next"; diff --git a/web/apps/photos/src/components/PhotoViewer/ImageEditorOverlay/CropMenu.tsx b/web/apps/photos/src/components/PhotoViewer/ImageEditorOverlay/CropMenu.tsx index dd4a13b29d..65528a7833 100644 --- a/web/apps/photos/src/components/PhotoViewer/ImageEditorOverlay/CropMenu.tsx +++ b/web/apps/photos/src/components/PhotoViewer/ImageEditorOverlay/CropMenu.tsx @@ -1,5 +1,5 @@ import { MenuItemGroup } from "@/new/common/components/menu/MenuItemGroup"; -import MenuSectionTitle from "@/new/common/components/menu/MenuSectionTitle"; +import { MenuSectionTitle } from "@/new/common/components/menu/MenuSectionTitle"; import { EnteMenuItem } from "@ente/shared/components/Menu/EnteMenuItem"; import CropIcon from "@mui/icons-material/Crop"; import { t } from "i18next"; diff --git a/web/apps/photos/src/components/PhotoViewer/ImageEditorOverlay/TransformMenu.tsx b/web/apps/photos/src/components/PhotoViewer/ImageEditorOverlay/TransformMenu.tsx index dd0e1f43cb..a1a184e321 100644 --- a/web/apps/photos/src/components/PhotoViewer/ImageEditorOverlay/TransformMenu.tsx +++ b/web/apps/photos/src/components/PhotoViewer/ImageEditorOverlay/TransformMenu.tsx @@ -1,6 +1,6 @@ import { MenuItemDivider } from "@/new/common/components/menu/MenuItemDivider"; import { MenuItemGroup } from "@/new/common/components/menu/MenuItemGroup"; -import MenuSectionTitle from "@/new/common/components/menu/MenuSectionTitle"; +import { MenuSectionTitle } from "@/new/common/components/menu/MenuSectionTitle"; import log from "@/next/log"; import { EnteMenuItem } from "@ente/shared/components/Menu/EnteMenuItem"; import Crop169Icon from "@mui/icons-material/Crop169"; diff --git a/web/apps/photos/src/components/PhotoViewer/ImageEditorOverlay/index.tsx b/web/apps/photos/src/components/PhotoViewer/ImageEditorOverlay/index.tsx index ff1310d232..ab0b4afae6 100644 --- a/web/apps/photos/src/components/PhotoViewer/ImageEditorOverlay/index.tsx +++ b/web/apps/photos/src/components/PhotoViewer/ImageEditorOverlay/index.tsx @@ -1,6 +1,6 @@ import { MenuItemDivider } from "@/new/common/components/menu/MenuItemDivider"; import { MenuItemGroup } from "@/new/common/components/menu/MenuItemGroup"; -import MenuSectionTitle from "@/new/common/components/menu/MenuSectionTitle"; +import { MenuSectionTitle } from "@/new/common/components/menu/MenuSectionTitle"; import downloadManager from "@/new/photos/services/download"; import { EnteFile } from "@/new/photos/types/file"; import { nameAndExtension } from "@/next/file"; diff --git a/web/apps/photos/src/components/Sidebar/AdvancedSettings.tsx b/web/apps/photos/src/components/Sidebar/AdvancedSettings.tsx index 742ebe0ebf..178dbba813 100644 --- a/web/apps/photos/src/components/Sidebar/AdvancedSettings.tsx +++ b/web/apps/photos/src/components/Sidebar/AdvancedSettings.tsx @@ -1,5 +1,5 @@ import { MenuItemGroup } from "@/new/common/components/menu/MenuItemGroup"; -import MenuSectionTitle from "@/new/common/components/menu/MenuSectionTitle"; +import { MenuSectionTitle } from "@/new/common/components/menu/MenuSectionTitle"; import { EnteMenuItem } from "@ente/shared/components/Menu/EnteMenuItem"; import ChevronRight from "@mui/icons-material/ChevronRight"; import ScienceIcon from "@mui/icons-material/Science"; diff --git a/web/packages/new/common/components/menu/MenuSectionTitle.tsx b/web/packages/new/common/components/menu/MenuSectionTitle.tsx index 5c07b8d92b..0a79fd4b5f 100644 --- a/web/packages/new/common/components/menu/MenuSectionTitle.tsx +++ b/web/packages/new/common/components/menu/MenuSectionTitle.tsx @@ -1,12 +1,16 @@ import { VerticallyCenteredFlex } from "@ente/shared/components/Container"; import { Typography } from "@mui/material"; +import React from "react"; -interface Iprops { +interface MenuSectionTitleProps { title: string; icon?: JSX.Element; } -export default function MenuSectionTitle({ title, icon }: Iprops) { +export const MenuSectionTitle: React.FC = ({ + title, + icon, +}) => { return ( ); -} +}; From 2510226a576e553d4e6f7a5587fd781ef4b1d8c7 Mon Sep 17 00:00:00 2001 From: Manav Rathi Date: Wed, 10 Jul 2024 10:54:27 +0530 Subject: [PATCH 07/67] Consolidate --- .../accounts/src/pages/passkeys/index.tsx | 3 +- .../emailShare/AddParticipantForm.tsx | 8 ++- .../emailShare/ManageEmailShare.tsx | 8 ++- .../emailShare/ManageParticipant.tsx | 3 +- .../CollectionShare/emailShare/index.tsx | 8 ++- .../publicShare/EnablePublicShareOptions.tsx | 8 ++- .../publicShare/manage/deviceLimit.tsx | 3 +- .../publicShare/manage/index.tsx | 3 +- .../publicShare/manage/linkExpiry.tsx | 3 +- .../publicShare/manage/publicCollect.tsx | 3 +- .../publicShare/managePublicShare.tsx | 3 +- .../CollectionShare/sharingDetails.tsx | 8 ++- .../ImageEditorOverlay/ColoursMenu.tsx | 3 +- .../ImageEditorOverlay/CropMenu.tsx | 3 +- .../ImageEditorOverlay/TransformMenu.tsx | 8 ++- .../PhotoViewer/ImageEditorOverlay/index.tsx | 8 ++- .../components/Sidebar/AdvancedSettings.tsx | 3 +- .../src/components/Sidebar/MapSetting.tsx | 2 +- .../src/components/ml/MLSearchSettings.tsx | 2 +- web/packages/new/common/components/Menu.tsx | 70 +++++++++++++++++++ .../components/menu/MenuItemDivider.tsx | 21 ------ .../common/components/menu/MenuItemGroup.tsx | 20 ------ .../components/menu/MenuSectionTitle.tsx | 32 --------- 23 files changed, 117 insertions(+), 116 deletions(-) create mode 100644 web/packages/new/common/components/Menu.tsx delete mode 100644 web/packages/new/common/components/menu/MenuItemDivider.tsx delete mode 100644 web/packages/new/common/components/menu/MenuItemGroup.tsx delete mode 100644 web/packages/new/common/components/menu/MenuSectionTitle.tsx diff --git a/web/apps/accounts/src/pages/passkeys/index.tsx b/web/apps/accounts/src/pages/passkeys/index.tsx index 04a68e1c84..96915d3d85 100644 --- a/web/apps/accounts/src/pages/passkeys/index.tsx +++ b/web/apps/accounts/src/pages/passkeys/index.tsx @@ -1,5 +1,4 @@ -import { MenuItemDivider } from "@/new/common/components/menu/MenuItemDivider"; -import { MenuItemGroup } from "@/new/common/components/menu/MenuItemGroup"; +import { MenuItemDivider, MenuItemGroup } from "@/new/common/components/Menu"; import log from "@/next/log"; import { ensure } from "@/utils/ensure"; import { CenteredFlex } from "@ente/shared/components/Container"; diff --git a/web/apps/photos/src/components/Collections/CollectionShare/emailShare/AddParticipantForm.tsx b/web/apps/photos/src/components/Collections/CollectionShare/emailShare/AddParticipantForm.tsx index 0673dddff4..bff0c8489e 100644 --- a/web/apps/photos/src/components/Collections/CollectionShare/emailShare/AddParticipantForm.tsx +++ b/web/apps/photos/src/components/Collections/CollectionShare/emailShare/AddParticipantForm.tsx @@ -1,6 +1,8 @@ -import { MenuItemDivider } from "@/new/common/components/menu/MenuItemDivider"; -import { MenuItemGroup } from "@/new/common/components/menu/MenuItemGroup"; -import { MenuSectionTitle } from "@/new/common/components/menu/MenuSectionTitle"; +import { + MenuItemDivider, + MenuItemGroup, + MenuSectionTitle, +} from "@/new/common/components/Menu"; import { FlexWrapper } from "@ente/shared/components/Container"; import { EnteMenuItem } from "@ente/shared/components/Menu/EnteMenuItem"; import SubmitButton from "@ente/shared/components/SubmitButton"; diff --git a/web/apps/photos/src/components/Collections/CollectionShare/emailShare/ManageEmailShare.tsx b/web/apps/photos/src/components/Collections/CollectionShare/emailShare/ManageEmailShare.tsx index b6ca4ba235..7dd4ab75a6 100644 --- a/web/apps/photos/src/components/Collections/CollectionShare/emailShare/ManageEmailShare.tsx +++ b/web/apps/photos/src/components/Collections/CollectionShare/emailShare/ManageEmailShare.tsx @@ -1,6 +1,8 @@ -import { MenuItemDivider } from "@/new/common/components/menu/MenuItemDivider"; -import { MenuItemGroup } from "@/new/common/components/menu/MenuItemGroup"; -import { MenuSectionTitle } from "@/new/common/components/menu/MenuSectionTitle"; +import { + MenuItemDivider, + MenuItemGroup, + MenuSectionTitle, +} from "@/new/common/components/Menu"; import { EnteMenuItem } from "@ente/shared/components/Menu/EnteMenuItem"; import Add from "@mui/icons-material/Add"; import AdminPanelSettingsIcon from "@mui/icons-material/AdminPanelSettings"; diff --git a/web/apps/photos/src/components/Collections/CollectionShare/emailShare/ManageParticipant.tsx b/web/apps/photos/src/components/Collections/CollectionShare/emailShare/ManageParticipant.tsx index 38adca4c87..976fee2df8 100644 --- a/web/apps/photos/src/components/Collections/CollectionShare/emailShare/ManageParticipant.tsx +++ b/web/apps/photos/src/components/Collections/CollectionShare/emailShare/ManageParticipant.tsx @@ -1,5 +1,4 @@ -import { MenuItemDivider } from "@/new/common/components/menu/MenuItemDivider"; -import { MenuItemGroup } from "@/new/common/components/menu/MenuItemGroup"; +import { MenuItemDivider, MenuItemGroup } from "@/new/common/components/Menu"; import log from "@/next/log"; import { EnteMenuItem } from "@ente/shared/components/Menu/EnteMenuItem"; import BlockIcon from "@mui/icons-material/Block"; diff --git a/web/apps/photos/src/components/Collections/CollectionShare/emailShare/index.tsx b/web/apps/photos/src/components/Collections/CollectionShare/emailShare/index.tsx index 72ebb02aac..f5a9fa40aa 100644 --- a/web/apps/photos/src/components/Collections/CollectionShare/emailShare/index.tsx +++ b/web/apps/photos/src/components/Collections/CollectionShare/emailShare/index.tsx @@ -1,9 +1,11 @@ import { useRef, useState } from "react"; import { COLLECTION_ROLE, Collection } from "types/collection"; -import { MenuItemDivider } from "@/new/common/components/menu/MenuItemDivider"; -import { MenuItemGroup } from "@/new/common/components/menu/MenuItemGroup"; -import { MenuSectionTitle } from "@/new/common/components/menu/MenuSectionTitle"; +import { + MenuItemDivider, + MenuItemGroup, + MenuSectionTitle, +} from "@/new/common/components/Menu"; import { EnteMenuItem } from "@ente/shared/components/Menu/EnteMenuItem"; import AddIcon from "@mui/icons-material/Add"; import ChevronRight from "@mui/icons-material/ChevronRight"; diff --git a/web/apps/photos/src/components/Collections/CollectionShare/publicShare/EnablePublicShareOptions.tsx b/web/apps/photos/src/components/Collections/CollectionShare/publicShare/EnablePublicShareOptions.tsx index e4751e939a..fe3acb8c57 100644 --- a/web/apps/photos/src/components/Collections/CollectionShare/publicShare/EnablePublicShareOptions.tsx +++ b/web/apps/photos/src/components/Collections/CollectionShare/publicShare/EnablePublicShareOptions.tsx @@ -1,6 +1,8 @@ -import { MenuItemDivider } from "@/new/common/components/menu/MenuItemDivider"; -import { MenuItemGroup } from "@/new/common/components/menu/MenuItemGroup"; -import { MenuSectionTitle } from "@/new/common/components/menu/MenuSectionTitle"; +import { + MenuItemDivider, + MenuItemGroup, + MenuSectionTitle, +} from "@/new/common/components/Menu"; import { EnteMenuItem } from "@ente/shared/components/Menu/EnteMenuItem"; import DownloadSharp from "@mui/icons-material/DownloadSharp"; import LinkIcon from "@mui/icons-material/Link"; diff --git a/web/apps/photos/src/components/Collections/CollectionShare/publicShare/manage/deviceLimit.tsx b/web/apps/photos/src/components/Collections/CollectionShare/publicShare/manage/deviceLimit.tsx index c076da752e..4377609cbf 100644 --- a/web/apps/photos/src/components/Collections/CollectionShare/publicShare/manage/deviceLimit.tsx +++ b/web/apps/photos/src/components/Collections/CollectionShare/publicShare/manage/deviceLimit.tsx @@ -1,5 +1,4 @@ -import { MenuItemDivider } from "@/new/common/components/menu/MenuItemDivider"; -import { MenuItemGroup } from "@/new/common/components/menu/MenuItemGroup"; +import { MenuItemDivider, MenuItemGroup } from "@/new/common/components/Menu"; import { EnteMenuItem } from "@ente/shared/components/Menu/EnteMenuItem"; import ChevronRight from "@mui/icons-material/ChevronRight"; import { DialogProps, Stack } from "@mui/material"; diff --git a/web/apps/photos/src/components/Collections/CollectionShare/publicShare/manage/index.tsx b/web/apps/photos/src/components/Collections/CollectionShare/publicShare/manage/index.tsx index d97d59c191..4543594028 100644 --- a/web/apps/photos/src/components/Collections/CollectionShare/publicShare/manage/index.tsx +++ b/web/apps/photos/src/components/Collections/CollectionShare/publicShare/manage/index.tsx @@ -1,5 +1,4 @@ -import { MenuItemDivider } from "@/new/common/components/menu/MenuItemDivider"; -import { MenuItemGroup } from "@/new/common/components/menu/MenuItemGroup"; +import { MenuItemDivider, MenuItemGroup } from "@/new/common/components/Menu"; import { EnteMenuItem } from "@ente/shared/components/Menu/EnteMenuItem"; import ContentCopyIcon from "@mui/icons-material/ContentCopy"; import RemoveCircleOutline from "@mui/icons-material/RemoveCircleOutline"; diff --git a/web/apps/photos/src/components/Collections/CollectionShare/publicShare/manage/linkExpiry.tsx b/web/apps/photos/src/components/Collections/CollectionShare/publicShare/manage/linkExpiry.tsx index 8b4e04cb93..5f2d1b7035 100644 --- a/web/apps/photos/src/components/Collections/CollectionShare/publicShare/manage/linkExpiry.tsx +++ b/web/apps/photos/src/components/Collections/CollectionShare/publicShare/manage/linkExpiry.tsx @@ -1,5 +1,4 @@ -import { MenuItemDivider } from "@/new/common/components/menu/MenuItemDivider"; -import { MenuItemGroup } from "@/new/common/components/menu/MenuItemGroup"; +import { MenuItemDivider, MenuItemGroup } from "@/new/common/components/Menu"; import { EnteMenuItem } from "@ente/shared/components/Menu/EnteMenuItem"; import { formatDateTime } from "@ente/shared/time/format"; import ChevronRight from "@mui/icons-material/ChevronRight"; diff --git a/web/apps/photos/src/components/Collections/CollectionShare/publicShare/manage/publicCollect.tsx b/web/apps/photos/src/components/Collections/CollectionShare/publicShare/manage/publicCollect.tsx index 88e16303fd..3e8bf8bd33 100644 --- a/web/apps/photos/src/components/Collections/CollectionShare/publicShare/manage/publicCollect.tsx +++ b/web/apps/photos/src/components/Collections/CollectionShare/publicShare/manage/publicCollect.tsx @@ -1,5 +1,4 @@ -import { MenuItemGroup } from "@/new/common/components/menu/MenuItemGroup"; -import { MenuSectionTitle } from "@/new/common/components/menu/MenuSectionTitle"; +import { MenuItemGroup, MenuSectionTitle } from "@/new/common/components/Menu"; import { EnteMenuItem } from "@ente/shared/components/Menu/EnteMenuItem"; import { Stack } from "@mui/material"; import { t } from "i18next"; diff --git a/web/apps/photos/src/components/Collections/CollectionShare/publicShare/managePublicShare.tsx b/web/apps/photos/src/components/Collections/CollectionShare/publicShare/managePublicShare.tsx index e2b58b15cf..e85f0ded45 100644 --- a/web/apps/photos/src/components/Collections/CollectionShare/publicShare/managePublicShare.tsx +++ b/web/apps/photos/src/components/Collections/CollectionShare/publicShare/managePublicShare.tsx @@ -1,5 +1,4 @@ -import { MenuItemDivider } from "@/new/common/components/menu/MenuItemDivider"; -import { MenuItemGroup } from "@/new/common/components/menu/MenuItemGroup"; +import { MenuItemDivider, MenuItemGroup } from "@/new/common/components/Menu"; import { EnteMenuItem } from "@ente/shared/components/Menu/EnteMenuItem"; import ChevronRightIcon from "@mui/icons-material/ChevronRight"; import ContentCopyIcon from "@mui/icons-material/ContentCopyOutlined"; diff --git a/web/apps/photos/src/components/Collections/CollectionShare/sharingDetails.tsx b/web/apps/photos/src/components/Collections/CollectionShare/sharingDetails.tsx index 8ed470bc4f..f6c78cb7c9 100644 --- a/web/apps/photos/src/components/Collections/CollectionShare/sharingDetails.tsx +++ b/web/apps/photos/src/components/Collections/CollectionShare/sharingDetails.tsx @@ -1,6 +1,8 @@ -import { MenuItemDivider } from "@/new/common/components/menu/MenuItemDivider"; -import { MenuItemGroup } from "@/new/common/components/menu/MenuItemGroup"; -import { MenuSectionTitle } from "@/new/common/components/menu/MenuSectionTitle"; +import { + MenuItemDivider, + MenuItemGroup, + MenuSectionTitle, +} from "@/new/common/components/Menu"; import { EnteMenuItem } from "@ente/shared/components/Menu/EnteMenuItem"; import AdminPanelSettingsIcon from "@mui/icons-material/AdminPanelSettings"; import ModeEditIcon from "@mui/icons-material/ModeEdit"; diff --git a/web/apps/photos/src/components/PhotoViewer/ImageEditorOverlay/ColoursMenu.tsx b/web/apps/photos/src/components/PhotoViewer/ImageEditorOverlay/ColoursMenu.tsx index b440cb3ad4..009160bf1f 100644 --- a/web/apps/photos/src/components/PhotoViewer/ImageEditorOverlay/ColoursMenu.tsx +++ b/web/apps/photos/src/components/PhotoViewer/ImageEditorOverlay/ColoursMenu.tsx @@ -1,5 +1,4 @@ -import { MenuItemGroup } from "@/new/common/components/menu/MenuItemGroup"; -import { MenuSectionTitle } from "@/new/common/components/menu/MenuSectionTitle"; +import { MenuItemGroup, MenuSectionTitle } from "@/new/common/components/Menu"; import { EnteMenuItem } from "@ente/shared/components/Menu/EnteMenuItem"; import { Box, Slider } from "@mui/material"; import { t } from "i18next"; diff --git a/web/apps/photos/src/components/PhotoViewer/ImageEditorOverlay/CropMenu.tsx b/web/apps/photos/src/components/PhotoViewer/ImageEditorOverlay/CropMenu.tsx index 65528a7833..d257ce4b72 100644 --- a/web/apps/photos/src/components/PhotoViewer/ImageEditorOverlay/CropMenu.tsx +++ b/web/apps/photos/src/components/PhotoViewer/ImageEditorOverlay/CropMenu.tsx @@ -1,5 +1,4 @@ -import { MenuItemGroup } from "@/new/common/components/menu/MenuItemGroup"; -import { MenuSectionTitle } from "@/new/common/components/menu/MenuSectionTitle"; +import { MenuItemGroup, MenuSectionTitle } from "@/new/common/components/Menu"; import { EnteMenuItem } from "@ente/shared/components/Menu/EnteMenuItem"; import CropIcon from "@mui/icons-material/Crop"; import { t } from "i18next"; diff --git a/web/apps/photos/src/components/PhotoViewer/ImageEditorOverlay/TransformMenu.tsx b/web/apps/photos/src/components/PhotoViewer/ImageEditorOverlay/TransformMenu.tsx index a1a184e321..1951224a10 100644 --- a/web/apps/photos/src/components/PhotoViewer/ImageEditorOverlay/TransformMenu.tsx +++ b/web/apps/photos/src/components/PhotoViewer/ImageEditorOverlay/TransformMenu.tsx @@ -1,6 +1,8 @@ -import { MenuItemDivider } from "@/new/common/components/menu/MenuItemDivider"; -import { MenuItemGroup } from "@/new/common/components/menu/MenuItemGroup"; -import { MenuSectionTitle } from "@/new/common/components/menu/MenuSectionTitle"; +import { + MenuItemDivider, + MenuItemGroup, + MenuSectionTitle, +} from "@/new/common/components/Menu"; import log from "@/next/log"; import { EnteMenuItem } from "@ente/shared/components/Menu/EnteMenuItem"; import Crop169Icon from "@mui/icons-material/Crop169"; diff --git a/web/apps/photos/src/components/PhotoViewer/ImageEditorOverlay/index.tsx b/web/apps/photos/src/components/PhotoViewer/ImageEditorOverlay/index.tsx index ab0b4afae6..6899f145cd 100644 --- a/web/apps/photos/src/components/PhotoViewer/ImageEditorOverlay/index.tsx +++ b/web/apps/photos/src/components/PhotoViewer/ImageEditorOverlay/index.tsx @@ -1,6 +1,8 @@ -import { MenuItemDivider } from "@/new/common/components/menu/MenuItemDivider"; -import { MenuItemGroup } from "@/new/common/components/menu/MenuItemGroup"; -import { MenuSectionTitle } from "@/new/common/components/menu/MenuSectionTitle"; +import { + MenuItemDivider, + MenuItemGroup, + MenuSectionTitle, +} from "@/new/common/components/Menu"; import downloadManager from "@/new/photos/services/download"; import { EnteFile } from "@/new/photos/types/file"; import { nameAndExtension } from "@/next/file"; diff --git a/web/apps/photos/src/components/Sidebar/AdvancedSettings.tsx b/web/apps/photos/src/components/Sidebar/AdvancedSettings.tsx index 178dbba813..d1c1a9a0a4 100644 --- a/web/apps/photos/src/components/Sidebar/AdvancedSettings.tsx +++ b/web/apps/photos/src/components/Sidebar/AdvancedSettings.tsx @@ -1,5 +1,4 @@ -import { MenuItemGroup } from "@/new/common/components/menu/MenuItemGroup"; -import { MenuSectionTitle } from "@/new/common/components/menu/MenuSectionTitle"; +import { MenuItemGroup, MenuSectionTitle } from "@/new/common/components/Menu"; import { EnteMenuItem } from "@ente/shared/components/Menu/EnteMenuItem"; import ChevronRight from "@mui/icons-material/ChevronRight"; import ScienceIcon from "@mui/icons-material/Science"; diff --git a/web/apps/photos/src/components/Sidebar/MapSetting.tsx b/web/apps/photos/src/components/Sidebar/MapSetting.tsx index 7ce53ca852..1c5cb1df70 100644 --- a/web/apps/photos/src/components/Sidebar/MapSetting.tsx +++ b/web/apps/photos/src/components/Sidebar/MapSetting.tsx @@ -1,4 +1,4 @@ -import { MenuItemGroup } from "@/new/common/components/menu/MenuItemGroup"; +import { MenuItemGroup } from "@/new/common/components/Menu"; import log from "@/next/log"; import { EnteMenuItem } from "@ente/shared/components/Menu/EnteMenuItem"; import { diff --git a/web/apps/photos/src/components/ml/MLSearchSettings.tsx b/web/apps/photos/src/components/ml/MLSearchSettings.tsx index abdc8a38c7..3f69a41fbe 100644 --- a/web/apps/photos/src/components/ml/MLSearchSettings.tsx +++ b/web/apps/photos/src/components/ml/MLSearchSettings.tsx @@ -1,4 +1,4 @@ -import { MenuItemGroup } from "@/new/common/components/menu/MenuItemGroup"; +import { MenuItemGroup } from "@/new/common/components/Menu"; import { canEnableFaceIndexing, disableML, diff --git a/web/packages/new/common/components/Menu.tsx b/web/packages/new/common/components/Menu.tsx new file mode 100644 index 0000000000..00381aea67 --- /dev/null +++ b/web/packages/new/common/components/Menu.tsx @@ -0,0 +1,70 @@ +import { VerticallyCenteredFlex } from "@ente/shared/components/Container"; +import { Divider, styled, Typography } from "@mui/material"; +import React from "react"; + +interface MenuSectionTitleProps { + title: string; + icon?: JSX.Element; +} + +export const MenuSectionTitle: React.FC = ({ + title, + icon, +}) => { + return ( + svg": { + fontSize: "17px", + color: (theme) => theme.colors.stroke.muted, + }, + }} + > + {icon && icon} + + {title} + + + ); +}; + +interface MenuItemDividerProps { + hasIcon?: boolean; +} + +export const MenuItemDivider: React.FC = ({ + hasIcon, +}) => { + return ( + + ); +}; + +export const MenuItemGroup = styled("div")( + ({ theme }) => ` + & > .MuiMenuItem-root{ + border-radius: 8px; + background-color: transparent; + } + & > .MuiMenuItem-root:not(:last-of-type) { + border-bottom-left-radius: 0; + border-bottom-right-radius: 0; + } + & > .MuiMenuItem-root:not(:first-of-type) { + border-top-left-radius: 0; + border-top-right-radius: 0; + } + background-color: ${theme.colors.fill.faint}; + border-radius: 8px; +`, +); diff --git a/web/packages/new/common/components/menu/MenuItemDivider.tsx b/web/packages/new/common/components/menu/MenuItemDivider.tsx deleted file mode 100644 index 21c632ee49..0000000000 --- a/web/packages/new/common/components/menu/MenuItemDivider.tsx +++ /dev/null @@ -1,21 +0,0 @@ -import { Divider } from "@mui/material"; -import React from "react"; - -interface MenuItemDividerProps { - hasIcon?: boolean; -} - -export const MenuItemDivider: React.FC = ({ - hasIcon, -}) => { - return ( - - ); -}; diff --git a/web/packages/new/common/components/menu/MenuItemGroup.tsx b/web/packages/new/common/components/menu/MenuItemGroup.tsx deleted file mode 100644 index 0b80262b5f..0000000000 --- a/web/packages/new/common/components/menu/MenuItemGroup.tsx +++ /dev/null @@ -1,20 +0,0 @@ -import { styled } from "@mui/material"; - -export const MenuItemGroup = styled("div")( - ({ theme }) => ` - & > .MuiMenuItem-root{ - border-radius: 8px; - background-color: transparent; - } - & > .MuiMenuItem-root:not(:last-of-type) { - border-bottom-left-radius: 0; - border-bottom-right-radius: 0; - } - & > .MuiMenuItem-root:not(:first-of-type) { - border-top-left-radius: 0; - border-top-right-radius: 0; - } - background-color: ${theme.colors.fill.faint}; - border-radius: 8px; -`, -); diff --git a/web/packages/new/common/components/menu/MenuSectionTitle.tsx b/web/packages/new/common/components/menu/MenuSectionTitle.tsx deleted file mode 100644 index 0a79fd4b5f..0000000000 --- a/web/packages/new/common/components/menu/MenuSectionTitle.tsx +++ /dev/null @@ -1,32 +0,0 @@ -import { VerticallyCenteredFlex } from "@ente/shared/components/Container"; -import { Typography } from "@mui/material"; -import React from "react"; - -interface MenuSectionTitleProps { - title: string; - icon?: JSX.Element; -} - -export const MenuSectionTitle: React.FC = ({ - title, - icon, -}) => { - return ( - svg": { - fontSize: "17px", - color: (theme) => theme.colors.stroke.muted, - }, - }} - > - {icon && icon} - - {title} - - - ); -}; From cd433aa39e362401d94eeeff515620bbdec79f45 Mon Sep 17 00:00:00 2001 From: Manav Rathi Date: Wed, 10 Jul 2024 10:58:57 +0530 Subject: [PATCH 08/67] Move --- web/apps/accounts/src/pages/passkeys/index.tsx | 2 +- .../CollectionShare/emailShare/AddParticipantForm.tsx | 2 +- .../CollectionShare/emailShare/ManageEmailShare.tsx | 2 +- .../CollectionShare/emailShare/ManageParticipant.tsx | 2 +- .../Collections/CollectionShare/emailShare/index.tsx | 2 +- .../publicShare/EnablePublicShareOptions.tsx | 2 +- .../CollectionShare/publicShare/manage/deviceLimit.tsx | 2 +- .../CollectionShare/publicShare/manage/index.tsx | 2 +- .../CollectionShare/publicShare/manage/linkExpiry.tsx | 2 +- .../CollectionShare/publicShare/manage/publicCollect.tsx | 2 +- .../CollectionShare/publicShare/managePublicShare.tsx | 2 +- .../Collections/CollectionShare/sharingDetails.tsx | 2 +- .../PhotoViewer/ImageEditorOverlay/ColoursMenu.tsx | 2 +- .../PhotoViewer/ImageEditorOverlay/CropMenu.tsx | 2 +- .../PhotoViewer/ImageEditorOverlay/TransformMenu.tsx | 2 +- .../components/PhotoViewer/ImageEditorOverlay/index.tsx | 6 +++--- .../photos/src/components/Sidebar/AdvancedSettings.tsx | 2 +- web/apps/photos/src/components/Sidebar/MapSetting.tsx | 2 +- web/apps/photos/src/components/ml/MLSearchSettings.tsx | 2 +- web/packages/new/photos/services/ml/embedding.ts | 8 ++++---- web/packages/new/{common => shared}/components/Menu.tsx | 0 web/packages/new/{common => shared}/crypto/ente.ts | 0 22 files changed, 25 insertions(+), 25 deletions(-) rename web/packages/new/{common => shared}/components/Menu.tsx (100%) rename web/packages/new/{common => shared}/crypto/ente.ts (100%) diff --git a/web/apps/accounts/src/pages/passkeys/index.tsx b/web/apps/accounts/src/pages/passkeys/index.tsx index 96915d3d85..e46e7d2681 100644 --- a/web/apps/accounts/src/pages/passkeys/index.tsx +++ b/web/apps/accounts/src/pages/passkeys/index.tsx @@ -1,4 +1,4 @@ -import { MenuItemDivider, MenuItemGroup } from "@/new/common/components/Menu"; +import { MenuItemDivider, MenuItemGroup } from "@/new/shared/components/Menu"; import log from "@/next/log"; import { ensure } from "@/utils/ensure"; import { CenteredFlex } from "@ente/shared/components/Container"; diff --git a/web/apps/photos/src/components/Collections/CollectionShare/emailShare/AddParticipantForm.tsx b/web/apps/photos/src/components/Collections/CollectionShare/emailShare/AddParticipantForm.tsx index bff0c8489e..9bf36991d4 100644 --- a/web/apps/photos/src/components/Collections/CollectionShare/emailShare/AddParticipantForm.tsx +++ b/web/apps/photos/src/components/Collections/CollectionShare/emailShare/AddParticipantForm.tsx @@ -2,7 +2,7 @@ import { MenuItemDivider, MenuItemGroup, MenuSectionTitle, -} from "@/new/common/components/Menu"; +} from "@/new/shared/components/Menu"; import { FlexWrapper } from "@ente/shared/components/Container"; import { EnteMenuItem } from "@ente/shared/components/Menu/EnteMenuItem"; import SubmitButton from "@ente/shared/components/SubmitButton"; diff --git a/web/apps/photos/src/components/Collections/CollectionShare/emailShare/ManageEmailShare.tsx b/web/apps/photos/src/components/Collections/CollectionShare/emailShare/ManageEmailShare.tsx index 7dd4ab75a6..a7ee1293d8 100644 --- a/web/apps/photos/src/components/Collections/CollectionShare/emailShare/ManageEmailShare.tsx +++ b/web/apps/photos/src/components/Collections/CollectionShare/emailShare/ManageEmailShare.tsx @@ -2,7 +2,7 @@ import { MenuItemDivider, MenuItemGroup, MenuSectionTitle, -} from "@/new/common/components/Menu"; +} from "@/new/shared/components/Menu"; import { EnteMenuItem } from "@ente/shared/components/Menu/EnteMenuItem"; import Add from "@mui/icons-material/Add"; import AdminPanelSettingsIcon from "@mui/icons-material/AdminPanelSettings"; diff --git a/web/apps/photos/src/components/Collections/CollectionShare/emailShare/ManageParticipant.tsx b/web/apps/photos/src/components/Collections/CollectionShare/emailShare/ManageParticipant.tsx index 976fee2df8..1a8c975f3a 100644 --- a/web/apps/photos/src/components/Collections/CollectionShare/emailShare/ManageParticipant.tsx +++ b/web/apps/photos/src/components/Collections/CollectionShare/emailShare/ManageParticipant.tsx @@ -1,4 +1,4 @@ -import { MenuItemDivider, MenuItemGroup } from "@/new/common/components/Menu"; +import { MenuItemDivider, MenuItemGroup } from "@/new/shared/components/Menu"; import log from "@/next/log"; import { EnteMenuItem } from "@ente/shared/components/Menu/EnteMenuItem"; import BlockIcon from "@mui/icons-material/Block"; diff --git a/web/apps/photos/src/components/Collections/CollectionShare/emailShare/index.tsx b/web/apps/photos/src/components/Collections/CollectionShare/emailShare/index.tsx index f5a9fa40aa..768e91d5e1 100644 --- a/web/apps/photos/src/components/Collections/CollectionShare/emailShare/index.tsx +++ b/web/apps/photos/src/components/Collections/CollectionShare/emailShare/index.tsx @@ -5,7 +5,7 @@ import { MenuItemDivider, MenuItemGroup, MenuSectionTitle, -} from "@/new/common/components/Menu"; +} from "@/new/shared/components/Menu"; import { EnteMenuItem } from "@ente/shared/components/Menu/EnteMenuItem"; import AddIcon from "@mui/icons-material/Add"; import ChevronRight from "@mui/icons-material/ChevronRight"; diff --git a/web/apps/photos/src/components/Collections/CollectionShare/publicShare/EnablePublicShareOptions.tsx b/web/apps/photos/src/components/Collections/CollectionShare/publicShare/EnablePublicShareOptions.tsx index fe3acb8c57..e6a9baf3cc 100644 --- a/web/apps/photos/src/components/Collections/CollectionShare/publicShare/EnablePublicShareOptions.tsx +++ b/web/apps/photos/src/components/Collections/CollectionShare/publicShare/EnablePublicShareOptions.tsx @@ -2,7 +2,7 @@ import { MenuItemDivider, MenuItemGroup, MenuSectionTitle, -} from "@/new/common/components/Menu"; +} from "@/new/shared/components/Menu"; import { EnteMenuItem } from "@ente/shared/components/Menu/EnteMenuItem"; import DownloadSharp from "@mui/icons-material/DownloadSharp"; import LinkIcon from "@mui/icons-material/Link"; diff --git a/web/apps/photos/src/components/Collections/CollectionShare/publicShare/manage/deviceLimit.tsx b/web/apps/photos/src/components/Collections/CollectionShare/publicShare/manage/deviceLimit.tsx index 4377609cbf..c198bc5aa5 100644 --- a/web/apps/photos/src/components/Collections/CollectionShare/publicShare/manage/deviceLimit.tsx +++ b/web/apps/photos/src/components/Collections/CollectionShare/publicShare/manage/deviceLimit.tsx @@ -1,4 +1,4 @@ -import { MenuItemDivider, MenuItemGroup } from "@/new/common/components/Menu"; +import { MenuItemDivider, MenuItemGroup } from "@/new/shared/components/Menu"; import { EnteMenuItem } from "@ente/shared/components/Menu/EnteMenuItem"; import ChevronRight from "@mui/icons-material/ChevronRight"; import { DialogProps, Stack } from "@mui/material"; diff --git a/web/apps/photos/src/components/Collections/CollectionShare/publicShare/manage/index.tsx b/web/apps/photos/src/components/Collections/CollectionShare/publicShare/manage/index.tsx index 4543594028..10b1410782 100644 --- a/web/apps/photos/src/components/Collections/CollectionShare/publicShare/manage/index.tsx +++ b/web/apps/photos/src/components/Collections/CollectionShare/publicShare/manage/index.tsx @@ -1,4 +1,4 @@ -import { MenuItemDivider, MenuItemGroup } from "@/new/common/components/Menu"; +import { MenuItemDivider, MenuItemGroup } from "@/new/shared/components/Menu"; import { EnteMenuItem } from "@ente/shared/components/Menu/EnteMenuItem"; import ContentCopyIcon from "@mui/icons-material/ContentCopy"; import RemoveCircleOutline from "@mui/icons-material/RemoveCircleOutline"; diff --git a/web/apps/photos/src/components/Collections/CollectionShare/publicShare/manage/linkExpiry.tsx b/web/apps/photos/src/components/Collections/CollectionShare/publicShare/manage/linkExpiry.tsx index 5f2d1b7035..c969429c42 100644 --- a/web/apps/photos/src/components/Collections/CollectionShare/publicShare/manage/linkExpiry.tsx +++ b/web/apps/photos/src/components/Collections/CollectionShare/publicShare/manage/linkExpiry.tsx @@ -1,4 +1,4 @@ -import { MenuItemDivider, MenuItemGroup } from "@/new/common/components/Menu"; +import { MenuItemDivider, MenuItemGroup } from "@/new/shared/components/Menu"; import { EnteMenuItem } from "@ente/shared/components/Menu/EnteMenuItem"; import { formatDateTime } from "@ente/shared/time/format"; import ChevronRight from "@mui/icons-material/ChevronRight"; diff --git a/web/apps/photos/src/components/Collections/CollectionShare/publicShare/manage/publicCollect.tsx b/web/apps/photos/src/components/Collections/CollectionShare/publicShare/manage/publicCollect.tsx index 3e8bf8bd33..4290cd349f 100644 --- a/web/apps/photos/src/components/Collections/CollectionShare/publicShare/manage/publicCollect.tsx +++ b/web/apps/photos/src/components/Collections/CollectionShare/publicShare/manage/publicCollect.tsx @@ -1,4 +1,4 @@ -import { MenuItemGroup, MenuSectionTitle } from "@/new/common/components/Menu"; +import { MenuItemGroup, MenuSectionTitle } from "@/new/shared/components/Menu"; import { EnteMenuItem } from "@ente/shared/components/Menu/EnteMenuItem"; import { Stack } from "@mui/material"; import { t } from "i18next"; diff --git a/web/apps/photos/src/components/Collections/CollectionShare/publicShare/managePublicShare.tsx b/web/apps/photos/src/components/Collections/CollectionShare/publicShare/managePublicShare.tsx index e85f0ded45..1f723ae161 100644 --- a/web/apps/photos/src/components/Collections/CollectionShare/publicShare/managePublicShare.tsx +++ b/web/apps/photos/src/components/Collections/CollectionShare/publicShare/managePublicShare.tsx @@ -1,4 +1,4 @@ -import { MenuItemDivider, MenuItemGroup } from "@/new/common/components/Menu"; +import { MenuItemDivider, MenuItemGroup } from "@/new/shared/components/Menu"; import { EnteMenuItem } from "@ente/shared/components/Menu/EnteMenuItem"; import ChevronRightIcon from "@mui/icons-material/ChevronRight"; import ContentCopyIcon from "@mui/icons-material/ContentCopyOutlined"; diff --git a/web/apps/photos/src/components/Collections/CollectionShare/sharingDetails.tsx b/web/apps/photos/src/components/Collections/CollectionShare/sharingDetails.tsx index f6c78cb7c9..25e3771fc1 100644 --- a/web/apps/photos/src/components/Collections/CollectionShare/sharingDetails.tsx +++ b/web/apps/photos/src/components/Collections/CollectionShare/sharingDetails.tsx @@ -2,7 +2,7 @@ import { MenuItemDivider, MenuItemGroup, MenuSectionTitle, -} from "@/new/common/components/Menu"; +} from "@/new/shared/components/Menu"; import { EnteMenuItem } from "@ente/shared/components/Menu/EnteMenuItem"; import AdminPanelSettingsIcon from "@mui/icons-material/AdminPanelSettings"; import ModeEditIcon from "@mui/icons-material/ModeEdit"; diff --git a/web/apps/photos/src/components/PhotoViewer/ImageEditorOverlay/ColoursMenu.tsx b/web/apps/photos/src/components/PhotoViewer/ImageEditorOverlay/ColoursMenu.tsx index 009160bf1f..7f7fcf5112 100644 --- a/web/apps/photos/src/components/PhotoViewer/ImageEditorOverlay/ColoursMenu.tsx +++ b/web/apps/photos/src/components/PhotoViewer/ImageEditorOverlay/ColoursMenu.tsx @@ -1,4 +1,4 @@ -import { MenuItemGroup, MenuSectionTitle } from "@/new/common/components/Menu"; +import { MenuItemGroup, MenuSectionTitle } from "@/new/shared/components/Menu"; import { EnteMenuItem } from "@ente/shared/components/Menu/EnteMenuItem"; import { Box, Slider } from "@mui/material"; import { t } from "i18next"; diff --git a/web/apps/photos/src/components/PhotoViewer/ImageEditorOverlay/CropMenu.tsx b/web/apps/photos/src/components/PhotoViewer/ImageEditorOverlay/CropMenu.tsx index d257ce4b72..923998b009 100644 --- a/web/apps/photos/src/components/PhotoViewer/ImageEditorOverlay/CropMenu.tsx +++ b/web/apps/photos/src/components/PhotoViewer/ImageEditorOverlay/CropMenu.tsx @@ -1,4 +1,4 @@ -import { MenuItemGroup, MenuSectionTitle } from "@/new/common/components/Menu"; +import { MenuItemGroup, MenuSectionTitle } from "@/new/shared/components/Menu"; import { EnteMenuItem } from "@ente/shared/components/Menu/EnteMenuItem"; import CropIcon from "@mui/icons-material/Crop"; import { t } from "i18next"; diff --git a/web/apps/photos/src/components/PhotoViewer/ImageEditorOverlay/TransformMenu.tsx b/web/apps/photos/src/components/PhotoViewer/ImageEditorOverlay/TransformMenu.tsx index 1951224a10..9c578c0261 100644 --- a/web/apps/photos/src/components/PhotoViewer/ImageEditorOverlay/TransformMenu.tsx +++ b/web/apps/photos/src/components/PhotoViewer/ImageEditorOverlay/TransformMenu.tsx @@ -2,7 +2,7 @@ import { MenuItemDivider, MenuItemGroup, MenuSectionTitle, -} from "@/new/common/components/Menu"; +} from "@/new/shared/components/Menu"; import log from "@/next/log"; import { EnteMenuItem } from "@ente/shared/components/Menu/EnteMenuItem"; import Crop169Icon from "@mui/icons-material/Crop169"; diff --git a/web/apps/photos/src/components/PhotoViewer/ImageEditorOverlay/index.tsx b/web/apps/photos/src/components/PhotoViewer/ImageEditorOverlay/index.tsx index 6899f145cd..1bc3f3ad5c 100644 --- a/web/apps/photos/src/components/PhotoViewer/ImageEditorOverlay/index.tsx +++ b/web/apps/photos/src/components/PhotoViewer/ImageEditorOverlay/index.tsx @@ -1,10 +1,10 @@ +import downloadManager from "@/new/photos/services/download"; +import { EnteFile } from "@/new/photos/types/file"; import { MenuItemDivider, MenuItemGroup, MenuSectionTitle, -} from "@/new/common/components/Menu"; -import downloadManager from "@/new/photos/services/download"; -import { EnteFile } from "@/new/photos/types/file"; +} from "@/new/shared/components/Menu"; import { nameAndExtension } from "@/next/file"; import log from "@/next/log"; import { ensure } from "@/utils/ensure"; diff --git a/web/apps/photos/src/components/Sidebar/AdvancedSettings.tsx b/web/apps/photos/src/components/Sidebar/AdvancedSettings.tsx index d1c1a9a0a4..c07dd2c7e6 100644 --- a/web/apps/photos/src/components/Sidebar/AdvancedSettings.tsx +++ b/web/apps/photos/src/components/Sidebar/AdvancedSettings.tsx @@ -1,4 +1,4 @@ -import { MenuItemGroup, MenuSectionTitle } from "@/new/common/components/Menu"; +import { MenuItemGroup, MenuSectionTitle } from "@/new/shared/components/Menu"; import { EnteMenuItem } from "@ente/shared/components/Menu/EnteMenuItem"; import ChevronRight from "@mui/icons-material/ChevronRight"; import ScienceIcon from "@mui/icons-material/Science"; diff --git a/web/apps/photos/src/components/Sidebar/MapSetting.tsx b/web/apps/photos/src/components/Sidebar/MapSetting.tsx index 1c5cb1df70..8e6a1f1764 100644 --- a/web/apps/photos/src/components/Sidebar/MapSetting.tsx +++ b/web/apps/photos/src/components/Sidebar/MapSetting.tsx @@ -1,4 +1,4 @@ -import { MenuItemGroup } from "@/new/common/components/Menu"; +import { MenuItemGroup } from "@/new/shared/components/Menu"; import log from "@/next/log"; import { EnteMenuItem } from "@ente/shared/components/Menu/EnteMenuItem"; import { diff --git a/web/apps/photos/src/components/ml/MLSearchSettings.tsx b/web/apps/photos/src/components/ml/MLSearchSettings.tsx index 3f69a41fbe..a98afaf3a0 100644 --- a/web/apps/photos/src/components/ml/MLSearchSettings.tsx +++ b/web/apps/photos/src/components/ml/MLSearchSettings.tsx @@ -1,10 +1,10 @@ -import { MenuItemGroup } from "@/new/common/components/Menu"; import { canEnableFaceIndexing, disableML, enableML, isMLEnabled, } from "@/new/photos/services/ml"; +import { MenuItemGroup } from "@/new/shared/components/Menu"; import log from "@/next/log"; import { EnteMenuItem } from "@ente/shared/components/Menu/EnteMenuItem"; import { diff --git a/web/packages/new/photos/services/ml/embedding.ts b/web/packages/new/photos/services/ml/embedding.ts index eadeb00b0e..a6884bc17d 100644 --- a/web/packages/new/photos/services/ml/embedding.ts +++ b/web/packages/new/photos/services/ml/embedding.ts @@ -1,12 +1,12 @@ -import { - decryptFileMetadata, - encryptFileMetadata, -} from "@/new/common/crypto/ente"; import { getAllLocalFiles, getLocalTrashedFiles, } from "@/new/photos/services/files"; import type { EnteFile } from "@/new/photos/types/file"; +import { + decryptFileMetadata, + encryptFileMetadata, +} from "@/new/shared/crypto/ente"; import { authenticatedRequestHeaders, ensureOk } from "@/next/http"; import { getKV, setKV } from "@/next/kv"; import log from "@/next/log"; diff --git a/web/packages/new/common/components/Menu.tsx b/web/packages/new/shared/components/Menu.tsx similarity index 100% rename from web/packages/new/common/components/Menu.tsx rename to web/packages/new/shared/components/Menu.tsx diff --git a/web/packages/new/common/crypto/ente.ts b/web/packages/new/shared/crypto/ente.ts similarity index 100% rename from web/packages/new/common/crypto/ente.ts rename to web/packages/new/shared/crypto/ente.ts From fde6e14440b843a14e6185c69a67a17193eceeb3 Mon Sep 17 00:00:00 2001 From: Manav Rathi Date: Wed, 10 Jul 2024 11:00:43 +0530 Subject: [PATCH 09/67] Move --- .../accounts/src/pages/passkeys/index.tsx | 2 +- .../emailShare/AddParticipant.tsx | 2 +- .../emailShare/ManageEmailShare.tsx | 2 +- .../emailShare/ManageParticipant.tsx | 2 +- .../Collections/CollectionShare/index.tsx | 2 +- .../publicShare/manage/deviceLimit.tsx | 2 +- .../publicShare/manage/index.tsx | 2 +- .../publicShare/manage/linkExpiry.tsx | 2 +- .../PhotoViewer/FileInfo/ExifData.tsx | 2 +- .../components/PhotoViewer/FileInfo/index.tsx | 2 +- .../components/Sidebar/AdvancedSettings.tsx | 2 +- .../src/components/Sidebar/MapSetting.tsx | 2 +- .../src/components/Sidebar/Preferences.tsx | 2 +- .../src/components/ml/MLSearchSettings.tsx | 2 +- .../new/shared}/components/Titlebar.tsx | 0 web/packages/shared/components/Titlebar.tsx | 59 ------------------- 16 files changed, 14 insertions(+), 73 deletions(-) rename web/{apps/photos/src => packages/new/shared}/components/Titlebar.tsx (100%) delete mode 100644 web/packages/shared/components/Titlebar.tsx diff --git a/web/apps/accounts/src/pages/passkeys/index.tsx b/web/apps/accounts/src/pages/passkeys/index.tsx index e46e7d2681..e98cc3f167 100644 --- a/web/apps/accounts/src/pages/passkeys/index.tsx +++ b/web/apps/accounts/src/pages/passkeys/index.tsx @@ -1,4 +1,5 @@ import { MenuItemDivider, MenuItemGroup } from "@/new/shared/components/Menu"; +import Titlebar from "@/new/shared/components/Titlebar"; import log from "@/next/log"; import { ensure } from "@/utils/ensure"; import { CenteredFlex } from "@ente/shared/components/Container"; @@ -9,7 +10,6 @@ import FormPaper from "@ente/shared/components/Form/FormPaper"; import InfoItem from "@ente/shared/components/Info/InfoItem"; import { EnteMenuItem } from "@ente/shared/components/Menu/EnteMenuItem"; import SingleInputForm from "@ente/shared/components/SingleInputForm"; -import Titlebar from "@ente/shared/components/Titlebar"; import { formatDateTimeFull } from "@ente/shared/time/format"; import CalendarTodayIcon from "@mui/icons-material/CalendarToday"; import ChevronRightIcon from "@mui/icons-material/ChevronRight"; diff --git a/web/apps/photos/src/components/Collections/CollectionShare/emailShare/AddParticipant.tsx b/web/apps/photos/src/components/Collections/CollectionShare/emailShare/AddParticipant.tsx index 05437ada00..733406c968 100644 --- a/web/apps/photos/src/components/Collections/CollectionShare/emailShare/AddParticipant.tsx +++ b/web/apps/photos/src/components/Collections/CollectionShare/emailShare/AddParticipant.tsx @@ -1,6 +1,6 @@ +import Titlebar from "@/new/shared/components/Titlebar"; import { DialogProps, Stack } from "@mui/material"; import { EnteDrawer } from "components/EnteDrawer"; -import Titlebar from "components/Titlebar"; import { t } from "i18next"; import { COLLECTION_ROLE, Collection } from "types/collection"; diff --git a/web/apps/photos/src/components/Collections/CollectionShare/emailShare/ManageEmailShare.tsx b/web/apps/photos/src/components/Collections/CollectionShare/emailShare/ManageEmailShare.tsx index a7ee1293d8..807551b4fe 100644 --- a/web/apps/photos/src/components/Collections/CollectionShare/emailShare/ManageEmailShare.tsx +++ b/web/apps/photos/src/components/Collections/CollectionShare/emailShare/ManageEmailShare.tsx @@ -3,6 +3,7 @@ import { MenuItemGroup, MenuSectionTitle, } from "@/new/shared/components/Menu"; +import Titlebar from "@/new/shared/components/Titlebar"; import { EnteMenuItem } from "@ente/shared/components/Menu/EnteMenuItem"; import Add from "@mui/icons-material/Add"; import AdminPanelSettingsIcon from "@mui/icons-material/AdminPanelSettings"; @@ -12,7 +13,6 @@ import Photo from "@mui/icons-material/Photo"; import { DialogProps, Stack } from "@mui/material"; import { EnteDrawer } from "components/EnteDrawer"; import Avatar from "components/pages/gallery/Avatar"; -import Titlebar from "components/Titlebar"; import { t } from "i18next"; import { AppContext } from "pages/_app"; import { GalleryContext } from "pages/gallery"; diff --git a/web/apps/photos/src/components/Collections/CollectionShare/emailShare/ManageParticipant.tsx b/web/apps/photos/src/components/Collections/CollectionShare/emailShare/ManageParticipant.tsx index 1a8c975f3a..022e1d9e4b 100644 --- a/web/apps/photos/src/components/Collections/CollectionShare/emailShare/ManageParticipant.tsx +++ b/web/apps/photos/src/components/Collections/CollectionShare/emailShare/ManageParticipant.tsx @@ -1,4 +1,5 @@ import { MenuItemDivider, MenuItemGroup } from "@/new/shared/components/Menu"; +import Titlebar from "@/new/shared/components/Titlebar"; import log from "@/next/log"; import { EnteMenuItem } from "@ente/shared/components/Menu/EnteMenuItem"; import BlockIcon from "@mui/icons-material/Block"; @@ -7,7 +8,6 @@ import ModeEditIcon from "@mui/icons-material/ModeEdit"; import PhotoIcon from "@mui/icons-material/Photo"; import { DialogProps, Stack, Typography } from "@mui/material"; import { EnteDrawer } from "components/EnteDrawer"; -import Titlebar from "components/Titlebar"; import { t } from "i18next"; import { AppContext } from "pages/_app"; import { GalleryContext } from "pages/gallery"; diff --git a/web/apps/photos/src/components/Collections/CollectionShare/index.tsx b/web/apps/photos/src/components/Collections/CollectionShare/index.tsx index 22de9b55e8..f8ba77f510 100644 --- a/web/apps/photos/src/components/Collections/CollectionShare/index.tsx +++ b/web/apps/photos/src/components/Collections/CollectionShare/index.tsx @@ -1,6 +1,6 @@ +import Titlebar from "@/new/shared/components/Titlebar"; import { DialogProps, Stack } from "@mui/material"; import { EnteDrawer } from "components/EnteDrawer"; -import Titlebar from "components/Titlebar"; import { CollectionSummaryType } from "constants/collection"; import { t } from "i18next"; import { Collection, CollectionSummary } from "types/collection"; diff --git a/web/apps/photos/src/components/Collections/CollectionShare/publicShare/manage/deviceLimit.tsx b/web/apps/photos/src/components/Collections/CollectionShare/publicShare/manage/deviceLimit.tsx index c198bc5aa5..7e4a91608b 100644 --- a/web/apps/photos/src/components/Collections/CollectionShare/publicShare/manage/deviceLimit.tsx +++ b/web/apps/photos/src/components/Collections/CollectionShare/publicShare/manage/deviceLimit.tsx @@ -1,9 +1,9 @@ import { MenuItemDivider, MenuItemGroup } from "@/new/shared/components/Menu"; +import Titlebar from "@/new/shared/components/Titlebar"; import { EnteMenuItem } from "@ente/shared/components/Menu/EnteMenuItem"; import ChevronRight from "@mui/icons-material/ChevronRight"; import { DialogProps, Stack } from "@mui/material"; import { EnteDrawer } from "components/EnteDrawer"; -import Titlebar from "components/Titlebar"; import { t } from "i18next"; import { useMemo, useState } from "react"; import { Collection, PublicURL, UpdatePublicURL } from "types/collection"; diff --git a/web/apps/photos/src/components/Collections/CollectionShare/publicShare/manage/index.tsx b/web/apps/photos/src/components/Collections/CollectionShare/publicShare/manage/index.tsx index 10b1410782..438e69eb03 100644 --- a/web/apps/photos/src/components/Collections/CollectionShare/publicShare/manage/index.tsx +++ b/web/apps/photos/src/components/Collections/CollectionShare/publicShare/manage/index.tsx @@ -1,10 +1,10 @@ import { MenuItemDivider, MenuItemGroup } from "@/new/shared/components/Menu"; +import Titlebar from "@/new/shared/components/Titlebar"; import { EnteMenuItem } from "@ente/shared/components/Menu/EnteMenuItem"; import ContentCopyIcon from "@mui/icons-material/ContentCopy"; import RemoveCircleOutline from "@mui/icons-material/RemoveCircleOutline"; import { DialogProps, Stack, Typography } from "@mui/material"; import { EnteDrawer } from "components/EnteDrawer"; -import Titlebar from "components/Titlebar"; import { t } from "i18next"; import { GalleryContext } from "pages/gallery"; import { useContext, useState } from "react"; diff --git a/web/apps/photos/src/components/Collections/CollectionShare/publicShare/manage/linkExpiry.tsx b/web/apps/photos/src/components/Collections/CollectionShare/publicShare/manage/linkExpiry.tsx index c969429c42..6d808a4450 100644 --- a/web/apps/photos/src/components/Collections/CollectionShare/publicShare/manage/linkExpiry.tsx +++ b/web/apps/photos/src/components/Collections/CollectionShare/publicShare/manage/linkExpiry.tsx @@ -1,10 +1,10 @@ import { MenuItemDivider, MenuItemGroup } from "@/new/shared/components/Menu"; +import Titlebar from "@/new/shared/components/Titlebar"; import { EnteMenuItem } from "@ente/shared/components/Menu/EnteMenuItem"; import { formatDateTime } from "@ente/shared/time/format"; import ChevronRight from "@mui/icons-material/ChevronRight"; import { DialogProps, Stack } from "@mui/material"; import { EnteDrawer } from "components/EnteDrawer"; -import Titlebar from "components/Titlebar"; import { t } from "i18next"; import { useMemo, useState } from "react"; import { Collection, PublicURL, UpdatePublicURL } from "types/collection"; diff --git a/web/apps/photos/src/components/PhotoViewer/FileInfo/ExifData.tsx b/web/apps/photos/src/components/PhotoViewer/FileInfo/ExifData.tsx index c6c0582f8e..54db4e3849 100644 --- a/web/apps/photos/src/components/PhotoViewer/FileInfo/ExifData.tsx +++ b/web/apps/photos/src/components/PhotoViewer/FileInfo/ExifData.tsx @@ -1,7 +1,7 @@ +import Titlebar from "@/new/shared/components/Titlebar"; import CopyButton from "@ente/shared/components/CodeBlock/CopyButton"; import { formatDateTimeFull } from "@ente/shared/time/format"; import { Box, Stack, styled, Typography } from "@mui/material"; -import Titlebar from "components/Titlebar"; import { t } from "i18next"; import React from "react"; import { FileInfoSidebar } from "."; diff --git a/web/apps/photos/src/components/PhotoViewer/FileInfo/index.tsx b/web/apps/photos/src/components/PhotoViewer/FileInfo/index.tsx index ac764bd1a4..875041bf4b 100644 --- a/web/apps/photos/src/components/PhotoViewer/FileInfo/index.tsx +++ b/web/apps/photos/src/components/PhotoViewer/FileInfo/index.tsx @@ -1,6 +1,7 @@ import { UnidentifiedFaces } from "@/new/photos/components/PeopleList"; import { isMLEnabled } from "@/new/photos/services/ml"; import { EnteFile } from "@/new/photos/types/file"; +import Titlebar from "@/new/shared/components/Titlebar"; import CopyButton from "@ente/shared/components/CodeBlock/CopyButton"; import { FlexWrapper } from "@ente/shared/components/Container"; import EnteSpinner from "@ente/shared/components/EnteSpinner"; @@ -14,7 +15,6 @@ import { Box, DialogProps, Link, Stack, styled } from "@mui/material"; import { Chip } from "components/Chip"; import { EnteDrawer } from "components/EnteDrawer"; import LinkButton from "components/pages/gallery/LinkButton"; -import Titlebar from "components/Titlebar"; import { t } from "i18next"; import { AppContext } from "pages/_app"; import { GalleryContext } from "pages/gallery"; diff --git a/web/apps/photos/src/components/Sidebar/AdvancedSettings.tsx b/web/apps/photos/src/components/Sidebar/AdvancedSettings.tsx index c07dd2c7e6..6362ca9d12 100644 --- a/web/apps/photos/src/components/Sidebar/AdvancedSettings.tsx +++ b/web/apps/photos/src/components/Sidebar/AdvancedSettings.tsx @@ -1,10 +1,10 @@ import { MenuItemGroup, MenuSectionTitle } from "@/new/shared/components/Menu"; +import Titlebar from "@/new/shared/components/Titlebar"; import { EnteMenuItem } from "@ente/shared/components/Menu/EnteMenuItem"; import ChevronRight from "@mui/icons-material/ChevronRight"; import ScienceIcon from "@mui/icons-material/Science"; import { Box, DialogProps, Stack } from "@mui/material"; import { EnteDrawer } from "components/EnteDrawer"; -import Titlebar from "components/Titlebar"; import { MLSearchSettings } from "components/ml/MLSearchSettings"; import { t } from "i18next"; import isElectron from "is-electron"; diff --git a/web/apps/photos/src/components/Sidebar/MapSetting.tsx b/web/apps/photos/src/components/Sidebar/MapSetting.tsx index 8e6a1f1764..3b07087402 100644 --- a/web/apps/photos/src/components/Sidebar/MapSetting.tsx +++ b/web/apps/photos/src/components/Sidebar/MapSetting.tsx @@ -1,4 +1,5 @@ import { MenuItemGroup } from "@/new/shared/components/Menu"; +import Titlebar from "@/new/shared/components/Titlebar"; import log from "@/next/log"; import { EnteMenuItem } from "@ente/shared/components/Menu/EnteMenuItem"; import { @@ -10,7 +11,6 @@ import { Typography, } from "@mui/material"; import { EnteDrawer } from "components/EnteDrawer"; -import Titlebar from "components/Titlebar"; import { t } from "i18next"; import { AppContext } from "pages/_app"; import { useContext, useEffect, useState } from "react"; diff --git a/web/apps/photos/src/components/Sidebar/Preferences.tsx b/web/apps/photos/src/components/Sidebar/Preferences.tsx index 0fe44712e2..9ca8c944e5 100644 --- a/web/apps/photos/src/components/Sidebar/Preferences.tsx +++ b/web/apps/photos/src/components/Sidebar/Preferences.tsx @@ -1,3 +1,4 @@ +import Titlebar from "@/new/shared/components/Titlebar"; import { getLocaleInUse, setLocaleInUse, @@ -9,7 +10,6 @@ import ChevronRight from "@mui/icons-material/ChevronRight"; import { Box, DialogProps, Stack } from "@mui/material"; import DropdownInput from "components/DropdownInput"; import { EnteDrawer } from "components/EnteDrawer"; -import Titlebar from "components/Titlebar"; import { t } from "i18next"; import { useState } from "react"; import AdvancedSettings from "./AdvancedSettings"; diff --git a/web/apps/photos/src/components/ml/MLSearchSettings.tsx b/web/apps/photos/src/components/ml/MLSearchSettings.tsx index a98afaf3a0..d51a7609cf 100644 --- a/web/apps/photos/src/components/ml/MLSearchSettings.tsx +++ b/web/apps/photos/src/components/ml/MLSearchSettings.tsx @@ -5,6 +5,7 @@ import { isMLEnabled, } from "@/new/photos/services/ml"; import { MenuItemGroup } from "@/new/shared/components/Menu"; +import Titlebar from "@/new/shared/components/Titlebar"; import log from "@/next/log"; import { EnteMenuItem } from "@ente/shared/components/Menu/EnteMenuItem"; import { @@ -19,7 +20,6 @@ import { Typography, } from "@mui/material"; import { EnteDrawer } from "components/EnteDrawer"; -import Titlebar from "components/Titlebar"; import { t } from "i18next"; import { AppContext } from "pages/_app"; import { useContext, useEffect, useState } from "react"; diff --git a/web/apps/photos/src/components/Titlebar.tsx b/web/packages/new/shared/components/Titlebar.tsx similarity index 100% rename from web/apps/photos/src/components/Titlebar.tsx rename to web/packages/new/shared/components/Titlebar.tsx diff --git a/web/packages/shared/components/Titlebar.tsx b/web/packages/shared/components/Titlebar.tsx deleted file mode 100644 index ed9089f4c2..0000000000 --- a/web/packages/shared/components/Titlebar.tsx +++ /dev/null @@ -1,59 +0,0 @@ -import { FlexWrapper } from "@ente/shared/components/Container"; -import ArrowBack from "@mui/icons-material/ArrowBack"; -import Close from "@mui/icons-material/Close"; -import { Box, IconButton, Typography } from "@mui/material"; - -interface Iprops { - title: string; - caption?: string; - onClose: () => void; - backIsClose?: boolean; - onRootClose?: () => void; - actionButton?: JSX.Element; -} - -export default function Titlebar({ - title, - caption, - onClose, - backIsClose, - actionButton, - onRootClose, -}: Iprops): JSX.Element { - return ( - <> - - - {backIsClose ? : } - - - {actionButton && actionButton} - {!backIsClose && ( - - - - )} - - - - - {title} - - - {caption} - - - - ); -} From eb271088a40adc020ffd90db8554d3f53bbe5166 Mon Sep 17 00:00:00 2001 From: Manav Rathi Date: Wed, 10 Jul 2024 11:02:01 +0530 Subject: [PATCH 10/67] Move --- web/apps/accounts/src/pages/passkeys/index.tsx | 2 +- .../CollectionShare/emailShare/AddParticipant.tsx | 2 +- .../CollectionShare/emailShare/ManageEmailShare.tsx | 2 +- .../CollectionShare/emailShare/ManageParticipant.tsx | 2 +- .../src/components/Collections/CollectionShare/index.tsx | 2 +- .../CollectionShare/publicShare/manage/deviceLimit.tsx | 2 +- .../CollectionShare/publicShare/manage/index.tsx | 2 +- .../CollectionShare/publicShare/manage/linkExpiry.tsx | 2 +- .../src/components/PhotoViewer/FileInfo/ExifData.tsx | 2 +- .../photos/src/components/PhotoViewer/FileInfo/index.tsx | 2 +- .../photos/src/components/Sidebar/AdvancedSettings.tsx | 2 +- web/apps/photos/src/components/Sidebar/MapSetting.tsx | 2 +- web/apps/photos/src/components/Sidebar/Preferences.tsx | 2 +- web/apps/photos/src/components/ml/MLSearchSettings.tsx | 2 +- web/packages/new/shared/components/Titlebar.tsx | 9 +++++---- 15 files changed, 19 insertions(+), 18 deletions(-) diff --git a/web/apps/accounts/src/pages/passkeys/index.tsx b/web/apps/accounts/src/pages/passkeys/index.tsx index e98cc3f167..5e91654559 100644 --- a/web/apps/accounts/src/pages/passkeys/index.tsx +++ b/web/apps/accounts/src/pages/passkeys/index.tsx @@ -1,5 +1,5 @@ import { MenuItemDivider, MenuItemGroup } from "@/new/shared/components/Menu"; -import Titlebar from "@/new/shared/components/Titlebar"; +import { Titlebar } from "@/new/shared/components/Titlebar"; import log from "@/next/log"; import { ensure } from "@/utils/ensure"; import { CenteredFlex } from "@ente/shared/components/Container"; diff --git a/web/apps/photos/src/components/Collections/CollectionShare/emailShare/AddParticipant.tsx b/web/apps/photos/src/components/Collections/CollectionShare/emailShare/AddParticipant.tsx index 733406c968..9edb18b0de 100644 --- a/web/apps/photos/src/components/Collections/CollectionShare/emailShare/AddParticipant.tsx +++ b/web/apps/photos/src/components/Collections/CollectionShare/emailShare/AddParticipant.tsx @@ -1,4 +1,4 @@ -import Titlebar from "@/new/shared/components/Titlebar"; +import { Titlebar } from "@/new/shared/components/Titlebar"; import { DialogProps, Stack } from "@mui/material"; import { EnteDrawer } from "components/EnteDrawer"; import { t } from "i18next"; diff --git a/web/apps/photos/src/components/Collections/CollectionShare/emailShare/ManageEmailShare.tsx b/web/apps/photos/src/components/Collections/CollectionShare/emailShare/ManageEmailShare.tsx index 807551b4fe..8e15765a5a 100644 --- a/web/apps/photos/src/components/Collections/CollectionShare/emailShare/ManageEmailShare.tsx +++ b/web/apps/photos/src/components/Collections/CollectionShare/emailShare/ManageEmailShare.tsx @@ -3,7 +3,7 @@ import { MenuItemGroup, MenuSectionTitle, } from "@/new/shared/components/Menu"; -import Titlebar from "@/new/shared/components/Titlebar"; +import { Titlebar } from "@/new/shared/components/Titlebar"; import { EnteMenuItem } from "@ente/shared/components/Menu/EnteMenuItem"; import Add from "@mui/icons-material/Add"; import AdminPanelSettingsIcon from "@mui/icons-material/AdminPanelSettings"; diff --git a/web/apps/photos/src/components/Collections/CollectionShare/emailShare/ManageParticipant.tsx b/web/apps/photos/src/components/Collections/CollectionShare/emailShare/ManageParticipant.tsx index 022e1d9e4b..ca233755d4 100644 --- a/web/apps/photos/src/components/Collections/CollectionShare/emailShare/ManageParticipant.tsx +++ b/web/apps/photos/src/components/Collections/CollectionShare/emailShare/ManageParticipant.tsx @@ -1,5 +1,5 @@ import { MenuItemDivider, MenuItemGroup } from "@/new/shared/components/Menu"; -import Titlebar from "@/new/shared/components/Titlebar"; +import { Titlebar } from "@/new/shared/components/Titlebar"; import log from "@/next/log"; import { EnteMenuItem } from "@ente/shared/components/Menu/EnteMenuItem"; import BlockIcon from "@mui/icons-material/Block"; diff --git a/web/apps/photos/src/components/Collections/CollectionShare/index.tsx b/web/apps/photos/src/components/Collections/CollectionShare/index.tsx index f8ba77f510..7653877c9b 100644 --- a/web/apps/photos/src/components/Collections/CollectionShare/index.tsx +++ b/web/apps/photos/src/components/Collections/CollectionShare/index.tsx @@ -1,4 +1,4 @@ -import Titlebar from "@/new/shared/components/Titlebar"; +import { Titlebar } from "@/new/shared/components/Titlebar"; import { DialogProps, Stack } from "@mui/material"; import { EnteDrawer } from "components/EnteDrawer"; import { CollectionSummaryType } from "constants/collection"; diff --git a/web/apps/photos/src/components/Collections/CollectionShare/publicShare/manage/deviceLimit.tsx b/web/apps/photos/src/components/Collections/CollectionShare/publicShare/manage/deviceLimit.tsx index 7e4a91608b..7b3950edb8 100644 --- a/web/apps/photos/src/components/Collections/CollectionShare/publicShare/manage/deviceLimit.tsx +++ b/web/apps/photos/src/components/Collections/CollectionShare/publicShare/manage/deviceLimit.tsx @@ -1,5 +1,5 @@ import { MenuItemDivider, MenuItemGroup } from "@/new/shared/components/Menu"; -import Titlebar from "@/new/shared/components/Titlebar"; +import { Titlebar } from "@/new/shared/components/Titlebar"; import { EnteMenuItem } from "@ente/shared/components/Menu/EnteMenuItem"; import ChevronRight from "@mui/icons-material/ChevronRight"; import { DialogProps, Stack } from "@mui/material"; diff --git a/web/apps/photos/src/components/Collections/CollectionShare/publicShare/manage/index.tsx b/web/apps/photos/src/components/Collections/CollectionShare/publicShare/manage/index.tsx index 438e69eb03..d072d5b4cd 100644 --- a/web/apps/photos/src/components/Collections/CollectionShare/publicShare/manage/index.tsx +++ b/web/apps/photos/src/components/Collections/CollectionShare/publicShare/manage/index.tsx @@ -1,5 +1,5 @@ import { MenuItemDivider, MenuItemGroup } from "@/new/shared/components/Menu"; -import Titlebar from "@/new/shared/components/Titlebar"; +import { Titlebar } from "@/new/shared/components/Titlebar"; import { EnteMenuItem } from "@ente/shared/components/Menu/EnteMenuItem"; import ContentCopyIcon from "@mui/icons-material/ContentCopy"; import RemoveCircleOutline from "@mui/icons-material/RemoveCircleOutline"; diff --git a/web/apps/photos/src/components/Collections/CollectionShare/publicShare/manage/linkExpiry.tsx b/web/apps/photos/src/components/Collections/CollectionShare/publicShare/manage/linkExpiry.tsx index 6d808a4450..2902055b9e 100644 --- a/web/apps/photos/src/components/Collections/CollectionShare/publicShare/manage/linkExpiry.tsx +++ b/web/apps/photos/src/components/Collections/CollectionShare/publicShare/manage/linkExpiry.tsx @@ -1,5 +1,5 @@ import { MenuItemDivider, MenuItemGroup } from "@/new/shared/components/Menu"; -import Titlebar from "@/new/shared/components/Titlebar"; +import { Titlebar } from "@/new/shared/components/Titlebar"; import { EnteMenuItem } from "@ente/shared/components/Menu/EnteMenuItem"; import { formatDateTime } from "@ente/shared/time/format"; import ChevronRight from "@mui/icons-material/ChevronRight"; diff --git a/web/apps/photos/src/components/PhotoViewer/FileInfo/ExifData.tsx b/web/apps/photos/src/components/PhotoViewer/FileInfo/ExifData.tsx index 54db4e3849..d84aa106c3 100644 --- a/web/apps/photos/src/components/PhotoViewer/FileInfo/ExifData.tsx +++ b/web/apps/photos/src/components/PhotoViewer/FileInfo/ExifData.tsx @@ -1,4 +1,4 @@ -import Titlebar from "@/new/shared/components/Titlebar"; +import { Titlebar } from "@/new/shared/components/Titlebar"; import CopyButton from "@ente/shared/components/CodeBlock/CopyButton"; import { formatDateTimeFull } from "@ente/shared/time/format"; import { Box, Stack, styled, Typography } from "@mui/material"; diff --git a/web/apps/photos/src/components/PhotoViewer/FileInfo/index.tsx b/web/apps/photos/src/components/PhotoViewer/FileInfo/index.tsx index 875041bf4b..0f1869e28e 100644 --- a/web/apps/photos/src/components/PhotoViewer/FileInfo/index.tsx +++ b/web/apps/photos/src/components/PhotoViewer/FileInfo/index.tsx @@ -1,7 +1,7 @@ import { UnidentifiedFaces } from "@/new/photos/components/PeopleList"; import { isMLEnabled } from "@/new/photos/services/ml"; import { EnteFile } from "@/new/photos/types/file"; -import Titlebar from "@/new/shared/components/Titlebar"; +import { Titlebar } from "@/new/shared/components/Titlebar"; import CopyButton from "@ente/shared/components/CodeBlock/CopyButton"; import { FlexWrapper } from "@ente/shared/components/Container"; import EnteSpinner from "@ente/shared/components/EnteSpinner"; diff --git a/web/apps/photos/src/components/Sidebar/AdvancedSettings.tsx b/web/apps/photos/src/components/Sidebar/AdvancedSettings.tsx index 6362ca9d12..6f270670d2 100644 --- a/web/apps/photos/src/components/Sidebar/AdvancedSettings.tsx +++ b/web/apps/photos/src/components/Sidebar/AdvancedSettings.tsx @@ -1,5 +1,5 @@ import { MenuItemGroup, MenuSectionTitle } from "@/new/shared/components/Menu"; -import Titlebar from "@/new/shared/components/Titlebar"; +import { Titlebar } from "@/new/shared/components/Titlebar"; import { EnteMenuItem } from "@ente/shared/components/Menu/EnteMenuItem"; import ChevronRight from "@mui/icons-material/ChevronRight"; import ScienceIcon from "@mui/icons-material/Science"; diff --git a/web/apps/photos/src/components/Sidebar/MapSetting.tsx b/web/apps/photos/src/components/Sidebar/MapSetting.tsx index 3b07087402..373243612f 100644 --- a/web/apps/photos/src/components/Sidebar/MapSetting.tsx +++ b/web/apps/photos/src/components/Sidebar/MapSetting.tsx @@ -1,5 +1,5 @@ import { MenuItemGroup } from "@/new/shared/components/Menu"; -import Titlebar from "@/new/shared/components/Titlebar"; +import { Titlebar } from "@/new/shared/components/Titlebar"; import log from "@/next/log"; import { EnteMenuItem } from "@ente/shared/components/Menu/EnteMenuItem"; import { diff --git a/web/apps/photos/src/components/Sidebar/Preferences.tsx b/web/apps/photos/src/components/Sidebar/Preferences.tsx index 9ca8c944e5..e8cb67de21 100644 --- a/web/apps/photos/src/components/Sidebar/Preferences.tsx +++ b/web/apps/photos/src/components/Sidebar/Preferences.tsx @@ -1,4 +1,4 @@ -import Titlebar from "@/new/shared/components/Titlebar"; +import { Titlebar } from "@/new/shared/components/Titlebar"; import { getLocaleInUse, setLocaleInUse, diff --git a/web/apps/photos/src/components/ml/MLSearchSettings.tsx b/web/apps/photos/src/components/ml/MLSearchSettings.tsx index d51a7609cf..bb057a1dd3 100644 --- a/web/apps/photos/src/components/ml/MLSearchSettings.tsx +++ b/web/apps/photos/src/components/ml/MLSearchSettings.tsx @@ -5,7 +5,7 @@ import { isMLEnabled, } from "@/new/photos/services/ml"; import { MenuItemGroup } from "@/new/shared/components/Menu"; -import Titlebar from "@/new/shared/components/Titlebar"; +import { Titlebar } from "@/new/shared/components/Titlebar"; import log from "@/next/log"; import { EnteMenuItem } from "@ente/shared/components/Menu/EnteMenuItem"; import { diff --git a/web/packages/new/shared/components/Titlebar.tsx b/web/packages/new/shared/components/Titlebar.tsx index ed9089f4c2..e46fb92ce0 100644 --- a/web/packages/new/shared/components/Titlebar.tsx +++ b/web/packages/new/shared/components/Titlebar.tsx @@ -2,8 +2,9 @@ import { FlexWrapper } from "@ente/shared/components/Container"; import ArrowBack from "@mui/icons-material/ArrowBack"; import Close from "@mui/icons-material/Close"; import { Box, IconButton, Typography } from "@mui/material"; +import React from "react"; -interface Iprops { +interface TitlebarProps { title: string; caption?: string; onClose: () => void; @@ -12,14 +13,14 @@ interface Iprops { actionButton?: JSX.Element; } -export default function Titlebar({ +export const Titlebar: React.FC = ({ title, caption, onClose, backIsClose, actionButton, onRootClose, -}: Iprops): JSX.Element { +}) => { return ( <> ); -} +}; From 8e10c8bec6e00aff65f056a1d3d4b5de44668bd6 Mon Sep 17 00:00:00 2001 From: Manav Rathi Date: Wed, 10 Jul 2024 11:33:07 +0530 Subject: [PATCH 11/67] Move --- web/apps/accounts/src/pages/passkeys/index.tsx | 2 +- .../CollectionShare/emailShare/AddParticipant.tsx | 2 +- .../CollectionShare/emailShare/ManageEmailShare.tsx | 2 +- .../CollectionShare/emailShare/ManageParticipant.tsx | 2 +- .../components/Collections/CollectionShare/index.tsx | 2 +- .../CollectionShare/publicShare/manage/deviceLimit.tsx | 2 +- .../CollectionShare/publicShare/manage/index.tsx | 2 +- .../CollectionShare/publicShare/manage/linkExpiry.tsx | 2 +- .../src/components/PhotoViewer/FileInfo/index.tsx | 2 +- .../PhotoViewer/ImageEditorOverlay/index.tsx | 2 +- .../photos/src/components/Sidebar/AdvancedSettings.tsx | 2 +- web/apps/photos/src/components/Sidebar/MapSetting.tsx | 2 +- web/apps/photos/src/components/Sidebar/Preferences.tsx | 2 +- web/apps/photos/src/components/Sidebar/index.tsx | 2 +- web/apps/photos/src/components/ml/MLSearchSettings.tsx | 2 +- .../new/shared}/components/EnteDrawer.tsx | 0 web/packages/shared/components/EnteDrawer.tsx | 10 ---------- 17 files changed, 15 insertions(+), 25 deletions(-) rename web/{apps/photos/src => packages/new/shared}/components/EnteDrawer.tsx (100%) delete mode 100644 web/packages/shared/components/EnteDrawer.tsx diff --git a/web/apps/accounts/src/pages/passkeys/index.tsx b/web/apps/accounts/src/pages/passkeys/index.tsx index 5e91654559..1ca210d5f6 100644 --- a/web/apps/accounts/src/pages/passkeys/index.tsx +++ b/web/apps/accounts/src/pages/passkeys/index.tsx @@ -1,3 +1,4 @@ +import { EnteDrawer } from "@/new/shared/components/EnteDrawer"; import { MenuItemDivider, MenuItemGroup } from "@/new/shared/components/Menu"; import { Titlebar } from "@/new/shared/components/Titlebar"; import log from "@/next/log"; @@ -5,7 +6,6 @@ import { ensure } from "@/utils/ensure"; import { CenteredFlex } from "@ente/shared/components/Container"; import DialogBoxV2 from "@ente/shared/components/DialogBoxV2"; import EnteButton from "@ente/shared/components/EnteButton"; -import { EnteDrawer } from "@ente/shared/components/EnteDrawer"; import FormPaper from "@ente/shared/components/Form/FormPaper"; import InfoItem from "@ente/shared/components/Info/InfoItem"; import { EnteMenuItem } from "@ente/shared/components/Menu/EnteMenuItem"; diff --git a/web/apps/photos/src/components/Collections/CollectionShare/emailShare/AddParticipant.tsx b/web/apps/photos/src/components/Collections/CollectionShare/emailShare/AddParticipant.tsx index 9edb18b0de..5d833642df 100644 --- a/web/apps/photos/src/components/Collections/CollectionShare/emailShare/AddParticipant.tsx +++ b/web/apps/photos/src/components/Collections/CollectionShare/emailShare/AddParticipant.tsx @@ -1,6 +1,6 @@ +import { EnteDrawer } from "@/new/shared/components/EnteDrawer"; import { Titlebar } from "@/new/shared/components/Titlebar"; import { DialogProps, Stack } from "@mui/material"; -import { EnteDrawer } from "components/EnteDrawer"; import { t } from "i18next"; import { COLLECTION_ROLE, Collection } from "types/collection"; diff --git a/web/apps/photos/src/components/Collections/CollectionShare/emailShare/ManageEmailShare.tsx b/web/apps/photos/src/components/Collections/CollectionShare/emailShare/ManageEmailShare.tsx index 8e15765a5a..972b11019e 100644 --- a/web/apps/photos/src/components/Collections/CollectionShare/emailShare/ManageEmailShare.tsx +++ b/web/apps/photos/src/components/Collections/CollectionShare/emailShare/ManageEmailShare.tsx @@ -1,3 +1,4 @@ +import { EnteDrawer } from "@/new/shared/components/EnteDrawer"; import { MenuItemDivider, MenuItemGroup, @@ -11,7 +12,6 @@ import ChevronRightIcon from "@mui/icons-material/ChevronRight"; import ModeEditIcon from "@mui/icons-material/ModeEdit"; import Photo from "@mui/icons-material/Photo"; import { DialogProps, Stack } from "@mui/material"; -import { EnteDrawer } from "components/EnteDrawer"; import Avatar from "components/pages/gallery/Avatar"; import { t } from "i18next"; import { AppContext } from "pages/_app"; diff --git a/web/apps/photos/src/components/Collections/CollectionShare/emailShare/ManageParticipant.tsx b/web/apps/photos/src/components/Collections/CollectionShare/emailShare/ManageParticipant.tsx index ca233755d4..fd8421ed5d 100644 --- a/web/apps/photos/src/components/Collections/CollectionShare/emailShare/ManageParticipant.tsx +++ b/web/apps/photos/src/components/Collections/CollectionShare/emailShare/ManageParticipant.tsx @@ -1,3 +1,4 @@ +import { EnteDrawer } from "@/new/shared/components/EnteDrawer"; import { MenuItemDivider, MenuItemGroup } from "@/new/shared/components/Menu"; import { Titlebar } from "@/new/shared/components/Titlebar"; import log from "@/next/log"; @@ -7,7 +8,6 @@ import DoneIcon from "@mui/icons-material/Done"; import ModeEditIcon from "@mui/icons-material/ModeEdit"; import PhotoIcon from "@mui/icons-material/Photo"; import { DialogProps, Stack, Typography } from "@mui/material"; -import { EnteDrawer } from "components/EnteDrawer"; import { t } from "i18next"; import { AppContext } from "pages/_app"; import { GalleryContext } from "pages/gallery"; diff --git a/web/apps/photos/src/components/Collections/CollectionShare/index.tsx b/web/apps/photos/src/components/Collections/CollectionShare/index.tsx index 7653877c9b..0e675fcafa 100644 --- a/web/apps/photos/src/components/Collections/CollectionShare/index.tsx +++ b/web/apps/photos/src/components/Collections/CollectionShare/index.tsx @@ -1,6 +1,6 @@ +import { EnteDrawer } from "@/new/shared/components/EnteDrawer"; import { Titlebar } from "@/new/shared/components/Titlebar"; import { DialogProps, Stack } from "@mui/material"; -import { EnteDrawer } from "components/EnteDrawer"; import { CollectionSummaryType } from "constants/collection"; import { t } from "i18next"; import { Collection, CollectionSummary } from "types/collection"; diff --git a/web/apps/photos/src/components/Collections/CollectionShare/publicShare/manage/deviceLimit.tsx b/web/apps/photos/src/components/Collections/CollectionShare/publicShare/manage/deviceLimit.tsx index 7b3950edb8..4090b08ec1 100644 --- a/web/apps/photos/src/components/Collections/CollectionShare/publicShare/manage/deviceLimit.tsx +++ b/web/apps/photos/src/components/Collections/CollectionShare/publicShare/manage/deviceLimit.tsx @@ -1,9 +1,9 @@ +import { EnteDrawer } from "@/new/shared/components/EnteDrawer"; import { MenuItemDivider, MenuItemGroup } from "@/new/shared/components/Menu"; import { Titlebar } from "@/new/shared/components/Titlebar"; import { EnteMenuItem } from "@ente/shared/components/Menu/EnteMenuItem"; import ChevronRight from "@mui/icons-material/ChevronRight"; import { DialogProps, Stack } from "@mui/material"; -import { EnteDrawer } from "components/EnteDrawer"; import { t } from "i18next"; import { useMemo, useState } from "react"; import { Collection, PublicURL, UpdatePublicURL } from "types/collection"; diff --git a/web/apps/photos/src/components/Collections/CollectionShare/publicShare/manage/index.tsx b/web/apps/photos/src/components/Collections/CollectionShare/publicShare/manage/index.tsx index d072d5b4cd..5cb996e86f 100644 --- a/web/apps/photos/src/components/Collections/CollectionShare/publicShare/manage/index.tsx +++ b/web/apps/photos/src/components/Collections/CollectionShare/publicShare/manage/index.tsx @@ -1,10 +1,10 @@ +import { EnteDrawer } from "@/new/shared/components/EnteDrawer"; import { MenuItemDivider, MenuItemGroup } from "@/new/shared/components/Menu"; import { Titlebar } from "@/new/shared/components/Titlebar"; import { EnteMenuItem } from "@ente/shared/components/Menu/EnteMenuItem"; import ContentCopyIcon from "@mui/icons-material/ContentCopy"; import RemoveCircleOutline from "@mui/icons-material/RemoveCircleOutline"; import { DialogProps, Stack, Typography } from "@mui/material"; -import { EnteDrawer } from "components/EnteDrawer"; import { t } from "i18next"; import { GalleryContext } from "pages/gallery"; import { useContext, useState } from "react"; diff --git a/web/apps/photos/src/components/Collections/CollectionShare/publicShare/manage/linkExpiry.tsx b/web/apps/photos/src/components/Collections/CollectionShare/publicShare/manage/linkExpiry.tsx index 2902055b9e..6cafd68c3b 100644 --- a/web/apps/photos/src/components/Collections/CollectionShare/publicShare/manage/linkExpiry.tsx +++ b/web/apps/photos/src/components/Collections/CollectionShare/publicShare/manage/linkExpiry.tsx @@ -1,10 +1,10 @@ +import { EnteDrawer } from "@/new/shared/components/EnteDrawer"; import { MenuItemDivider, MenuItemGroup } from "@/new/shared/components/Menu"; import { Titlebar } from "@/new/shared/components/Titlebar"; import { EnteMenuItem } from "@ente/shared/components/Menu/EnteMenuItem"; import { formatDateTime } from "@ente/shared/time/format"; import ChevronRight from "@mui/icons-material/ChevronRight"; import { DialogProps, Stack } from "@mui/material"; -import { EnteDrawer } from "components/EnteDrawer"; import { t } from "i18next"; import { useMemo, useState } from "react"; import { Collection, PublicURL, UpdatePublicURL } from "types/collection"; diff --git a/web/apps/photos/src/components/PhotoViewer/FileInfo/index.tsx b/web/apps/photos/src/components/PhotoViewer/FileInfo/index.tsx index 0f1869e28e..d486efb990 100644 --- a/web/apps/photos/src/components/PhotoViewer/FileInfo/index.tsx +++ b/web/apps/photos/src/components/PhotoViewer/FileInfo/index.tsx @@ -1,6 +1,7 @@ import { UnidentifiedFaces } from "@/new/photos/components/PeopleList"; import { isMLEnabled } from "@/new/photos/services/ml"; import { EnteFile } from "@/new/photos/types/file"; +import { EnteDrawer } from "@/new/shared/components/EnteDrawer"; import { Titlebar } from "@/new/shared/components/Titlebar"; import CopyButton from "@ente/shared/components/CodeBlock/CopyButton"; import { FlexWrapper } from "@ente/shared/components/Container"; @@ -13,7 +14,6 @@ import LocationOnOutlined from "@mui/icons-material/LocationOnOutlined"; import TextSnippetOutlined from "@mui/icons-material/TextSnippetOutlined"; import { Box, DialogProps, Link, Stack, styled } from "@mui/material"; import { Chip } from "components/Chip"; -import { EnteDrawer } from "components/EnteDrawer"; import LinkButton from "components/pages/gallery/LinkButton"; import { t } from "i18next"; import { AppContext } from "pages/_app"; diff --git a/web/apps/photos/src/components/PhotoViewer/ImageEditorOverlay/index.tsx b/web/apps/photos/src/components/PhotoViewer/ImageEditorOverlay/index.tsx index 1bc3f3ad5c..94002c664f 100644 --- a/web/apps/photos/src/components/PhotoViewer/ImageEditorOverlay/index.tsx +++ b/web/apps/photos/src/components/PhotoViewer/ImageEditorOverlay/index.tsx @@ -1,5 +1,6 @@ import downloadManager from "@/new/photos/services/download"; import { EnteFile } from "@/new/photos/types/file"; +import { EnteDrawer } from "@/new/shared/components/EnteDrawer"; import { MenuItemDivider, MenuItemGroup, @@ -31,7 +32,6 @@ import { Tabs, Typography, } from "@mui/material"; -import { EnteDrawer } from "components/EnteDrawer"; import { CORNER_THRESHOLD, FILTER_DEFAULT_VALUES } from "constants/photoEditor"; import { t } from "i18next"; import { AppContext } from "pages/_app"; diff --git a/web/apps/photos/src/components/Sidebar/AdvancedSettings.tsx b/web/apps/photos/src/components/Sidebar/AdvancedSettings.tsx index 6f270670d2..c3c9134aa8 100644 --- a/web/apps/photos/src/components/Sidebar/AdvancedSettings.tsx +++ b/web/apps/photos/src/components/Sidebar/AdvancedSettings.tsx @@ -1,10 +1,10 @@ +import { EnteDrawer } from "@/new/shared/components/EnteDrawer"; import { MenuItemGroup, MenuSectionTitle } from "@/new/shared/components/Menu"; import { Titlebar } from "@/new/shared/components/Titlebar"; import { EnteMenuItem } from "@ente/shared/components/Menu/EnteMenuItem"; import ChevronRight from "@mui/icons-material/ChevronRight"; import ScienceIcon from "@mui/icons-material/Science"; import { Box, DialogProps, Stack } from "@mui/material"; -import { EnteDrawer } from "components/EnteDrawer"; import { MLSearchSettings } from "components/ml/MLSearchSettings"; import { t } from "i18next"; import isElectron from "is-electron"; diff --git a/web/apps/photos/src/components/Sidebar/MapSetting.tsx b/web/apps/photos/src/components/Sidebar/MapSetting.tsx index 373243612f..60d71dca66 100644 --- a/web/apps/photos/src/components/Sidebar/MapSetting.tsx +++ b/web/apps/photos/src/components/Sidebar/MapSetting.tsx @@ -1,3 +1,4 @@ +import { EnteDrawer } from "@/new/shared/components/EnteDrawer"; import { MenuItemGroup } from "@/new/shared/components/Menu"; import { Titlebar } from "@/new/shared/components/Titlebar"; import log from "@/next/log"; @@ -10,7 +11,6 @@ import { Stack, Typography, } from "@mui/material"; -import { EnteDrawer } from "components/EnteDrawer"; import { t } from "i18next"; import { AppContext } from "pages/_app"; import { useContext, useEffect, useState } from "react"; diff --git a/web/apps/photos/src/components/Sidebar/Preferences.tsx b/web/apps/photos/src/components/Sidebar/Preferences.tsx index e8cb67de21..ac6e9ecb57 100644 --- a/web/apps/photos/src/components/Sidebar/Preferences.tsx +++ b/web/apps/photos/src/components/Sidebar/Preferences.tsx @@ -1,3 +1,4 @@ +import { EnteDrawer } from "@/new/shared/components/EnteDrawer"; import { Titlebar } from "@/new/shared/components/Titlebar"; import { getLocaleInUse, @@ -9,7 +10,6 @@ import { EnteMenuItem } from "@ente/shared/components/Menu/EnteMenuItem"; import ChevronRight from "@mui/icons-material/ChevronRight"; import { Box, DialogProps, Stack } from "@mui/material"; import DropdownInput from "components/DropdownInput"; -import { EnteDrawer } from "components/EnteDrawer"; import { t } from "i18next"; import { useState } from "react"; import AdvancedSettings from "./AdvancedSettings"; diff --git a/web/apps/photos/src/components/Sidebar/index.tsx b/web/apps/photos/src/components/Sidebar/index.tsx index 1dedaf6a79..3d3f9f964a 100644 --- a/web/apps/photos/src/components/Sidebar/index.tsx +++ b/web/apps/photos/src/components/Sidebar/index.tsx @@ -1,4 +1,5 @@ import { openAccountsManagePasskeysPage } from "@/accounts/services/passkey"; +import { EnteDrawer } from "@/new/shared/components/EnteDrawer"; import log from "@/next/log"; import { savedLogs } from "@/next/log-web"; import { customAPIHost } from "@/next/origins"; @@ -34,7 +35,6 @@ import { } from "@mui/material"; import Typography from "@mui/material/Typography"; import DeleteAccountModal from "components/DeleteAccountModal"; -import { EnteDrawer } from "components/EnteDrawer"; import TwoFactorModal from "components/TwoFactor/Modal"; import { WatchFolder } from "components/WatchFolder"; import LinkButton from "components/pages/gallery/LinkButton"; diff --git a/web/apps/photos/src/components/ml/MLSearchSettings.tsx b/web/apps/photos/src/components/ml/MLSearchSettings.tsx index bb057a1dd3..4f7b251bc3 100644 --- a/web/apps/photos/src/components/ml/MLSearchSettings.tsx +++ b/web/apps/photos/src/components/ml/MLSearchSettings.tsx @@ -4,6 +4,7 @@ import { enableML, isMLEnabled, } from "@/new/photos/services/ml"; +import { EnteDrawer } from "@/new/shared/components/EnteDrawer"; import { MenuItemGroup } from "@/new/shared/components/Menu"; import { Titlebar } from "@/new/shared/components/Titlebar"; import log from "@/next/log"; @@ -19,7 +20,6 @@ import { Stack, Typography, } from "@mui/material"; -import { EnteDrawer } from "components/EnteDrawer"; import { t } from "i18next"; import { AppContext } from "pages/_app"; import { useContext, useEffect, useState } from "react"; diff --git a/web/apps/photos/src/components/EnteDrawer.tsx b/web/packages/new/shared/components/EnteDrawer.tsx similarity index 100% rename from web/apps/photos/src/components/EnteDrawer.tsx rename to web/packages/new/shared/components/EnteDrawer.tsx diff --git a/web/packages/shared/components/EnteDrawer.tsx b/web/packages/shared/components/EnteDrawer.tsx deleted file mode 100644 index e6fc35bb15..0000000000 --- a/web/packages/shared/components/EnteDrawer.tsx +++ /dev/null @@ -1,10 +0,0 @@ -import { Drawer, styled } from "@mui/material"; - -export const EnteDrawer = styled(Drawer)(({ theme }) => ({ - "& .MuiPaper-root": { - maxWidth: "375px", - width: "100%", - scrollbarWidth: "thin", - padding: theme.spacing(1), - }, -})); From 6f40cbe27e01a940a47bee7a1be054935de36780 Mon Sep 17 00:00:00 2001 From: Manav Rathi Date: Wed, 10 Jul 2024 12:08:22 +0530 Subject: [PATCH 12/67] Agenda --- .../src/components/ml/MLSearchSettings.tsx | 4 +- web/packages/new/photos/services/ml/index.ts | 80 +++++++++++++------ 2 files changed, 59 insertions(+), 25 deletions(-) diff --git a/web/apps/photos/src/components/ml/MLSearchSettings.tsx b/web/apps/photos/src/components/ml/MLSearchSettings.tsx index 4f7b251bc3..80b09d0e81 100644 --- a/web/apps/photos/src/components/ml/MLSearchSettings.tsx +++ b/web/apps/photos/src/components/ml/MLSearchSettings.tsx @@ -1,5 +1,5 @@ import { - canEnableFaceIndexing, + canEnableML, disableML, enableML, isMLEnabled, @@ -264,7 +264,7 @@ function EnableMLSearch({ onClose, enableMlSearch, onRootClose }) { const [canEnable, setCanEnable] = useState(false); useEffect(() => { - canEnableFaceIndexing().then((v) => setCanEnable(v)); + canEnableML().then((v) => setCanEnable(v)); }, []); return ( diff --git a/web/packages/new/photos/services/ml/index.ts b/web/packages/new/photos/services/ml/index.ts index f26357d48d..4c66ddf65d 100644 --- a/web/packages/new/photos/services/ml/index.ts +++ b/web/packages/new/photos/services/ml/index.ts @@ -22,13 +22,13 @@ import { MLWorker } from "./worker"; /** * In-memory flag that tracks if ML is enabled. * - * - On app start, this is read from local storage in the `initML` function. + * - On app start, this is read from local storage during {@link initML}. * * - If the user updates their preference, then `setMLEnabled` will get called * with the updated preference where this value will be updated (in addition * to updating local storage). * - * - It is cleared in `logoutML`. + * - It is cleared in {@link logoutML}. */ let _isMLEnabled = false; @@ -79,7 +79,7 @@ export const initML = () => { // ML currently only works when we're running in our desktop app. if (!isDesktop) return; // TODO-ML: Rename the isFace* flag since it now drives ML as a whole. - _isMLEnabled = isFaceIndexingEnabled(); + _isMLEnabled = isMLEnabledLocally(); }; export const logoutML = async () => { @@ -92,30 +92,40 @@ export const logoutML = async () => { }; /** - * Return true if we should show an option to the user to allow them to enable - * face search in the UI. + * Return true if we should show an UI option to the user to allow them to + * enable ML. */ -export const canEnableFaceIndexing = async () => +export const canEnableML = async () => (await isInternalUser()) || (await isBetaUser()); /** * Return true if the user has enabled machine learning in their preferences. * - * TODO-ML: The UI for this needs rework. We might retain the older remote (and - * local) storage key, but otherwise this setting now reflects the state of ML - * overall and not just face search. + * [Note: ML preferences] + * + * The user may enable ML. This enables in both locally by persisting a local + * storage flag, and sets a flag on remote so that the user's other devices can + * also enable it. + * + * The user may pause ML locally. This does not modify the remote flag, but it + * unsets the local flag. Subsequently resuming ML (locally) will set the local + * flag again. + * + * ML related operations are driven by the {@link isMLEnabled} property. This is + * true if ML is enabled locally (which implies it is also enabled on remote). */ export const isMLEnabled = () => - // Impl note: Keep it fast, the UI directly calls this multiple times. + // Implementation note: Keep it fast, the UI directly calls this many times. _isMLEnabled; /** * Enable ML. * - * Persist the user's preference and trigger a sync. + * Persist the user's preference both locally and on remote, and trigger a sync. */ export const enableML = () => { - setIsFaceIndexingEnabled(true); + // TODO-ML: API call. + setIsMLEnabledLocally(true); _isMLEnabled = true; triggerMLSync(); }; @@ -123,30 +133,54 @@ export const enableML = () => { /** * Disable ML. * - * Stop any in-progress ML tasks and persist the user's preference. + * Stop any in-progress ML tasks, and persist the user's preference both locally + * and on remote. */ export const disableML = () => { terminateMLWorker(); - setIsFaceIndexingEnabled(false); + setIsMLEnabledLocally(false); + // TODO-ML: API call. + _isMLEnabled = false; +}; + +/** + * Pause ML on this device. + * + * Stop any in-progress ML tasks, and persist the user's local preference. + */ +export const pauseML = () => { + terminateMLWorker(); + setIsMLEnabledLocally(false); _isMLEnabled = false; }; /** - * Return true if the user has enabled face indexing in the app's settings. + * Resume ML on this device. + * + * Persist the user's preference locally, and trigger a sync. + */ +export const resumeML = () => { + setIsMLEnabledLocally(true); + _isMLEnabled = true; + triggerMLSync(); +}; + +/** + * Return true if ML is enabled locally. + * + * This setting is persisted locally (in local storage). It is not synced with + * remote and only tracks if ML is enabled locally. * - * This setting is persisted locally (in local storage) and is not synced with - * remote. There is a separate setting, "faceSearchEnabled" that is synced with - * remote, but that tracks whether or not the user has enabled face search once - * on any client. This {@link isFaceIndexingEnabled} property, on the other - * hand, denotes whether or not indexing is enabled on the current client. + * The remote status is tracked with a separate {@link isMLEnabledRemote} flag + * that is synced with remote. */ -const isFaceIndexingEnabled = () => +const isMLEnabledLocally = () => localStorage.getItem("faceIndexingEnabled") == "1"; /** - * Update the (locally stored) value of {@link isFaceIndexingEnabled}. + * Update the (locally stored) value of {@link isMLEnabledLocally}. */ -const setIsFaceIndexingEnabled = (enabled: boolean) => +const setIsMLEnabledLocally = (enabled: boolean) => enabled ? localStorage.setItem("faceIndexingEnabled", "1") : localStorage.removeItem("faceIndexingEnabled"); From e1ce2e5e840b65c567e904e7fcad6ffc7720e11d Mon Sep 17 00:00:00 2001 From: Manav Rathi Date: Wed, 10 Jul 2024 12:22:45 +0530 Subject: [PATCH 13/67] Cont --- web/packages/new/photos/services/ml/index.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/web/packages/new/photos/services/ml/index.ts b/web/packages/new/photos/services/ml/index.ts index 4c66ddf65d..6def77972c 100644 --- a/web/packages/new/photos/services/ml/index.ts +++ b/web/packages/new/photos/services/ml/index.ts @@ -20,13 +20,12 @@ import { clearMLDB, faceIndex, indexableAndIndexedCounts } from "./db"; import { MLWorker } from "./worker"; /** - * In-memory flag that tracks if ML is enabled. + * In-memory flag that tracks if ML is enabled locally. * * - On app start, this is read from local storage during {@link initML}. * - * - If the user updates their preference, then `setMLEnabled` will get called - * with the updated preference where this value will be updated (in addition - * to updating local storage). + * - It gets updated if the user enables/disables ML (remote) or if they + * pause/resume ML (local). * * - It is cleared in {@link logoutML}. */ @@ -64,6 +63,8 @@ const createComlinkWorker = async () => { * This is useful during logout to immediately stop any background ML operations * that are in-flight for the current user. After the user logs in again, a new * {@link worker} will be created on demand for subsequent usage. + * + * It is also called when the user pauses or disables ML. */ export const terminateMLWorker = () => { if (_comlinkWorker) { @@ -78,7 +79,6 @@ export const terminateMLWorker = () => { export const initML = () => { // ML currently only works when we're running in our desktop app. if (!isDesktop) return; - // TODO-ML: Rename the isFace* flag since it now drives ML as a whole. _isMLEnabled = isMLEnabledLocally(); }; @@ -137,9 +137,9 @@ export const enableML = () => { * and on remote. */ export const disableML = () => { + // TODO-ML: API call. terminateMLWorker(); setIsMLEnabledLocally(false); - // TODO-ML: API call. _isMLEnabled = false; }; From 6d09d1f9b7a64584d6953bf93e102aec1d79acf2 Mon Sep 17 00:00:00 2001 From: Manav Rathi Date: Wed, 10 Jul 2024 12:39:51 +0530 Subject: [PATCH 14/67] rs 1 --- .../new/photos/services/remote-store.ts | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 web/packages/new/photos/services/remote-store.ts diff --git a/web/packages/new/photos/services/remote-store.ts b/web/packages/new/photos/services/remote-store.ts new file mode 100644 index 0000000000..d9e26dd680 --- /dev/null +++ b/web/packages/new/photos/services/remote-store.ts @@ -0,0 +1,19 @@ +import { authenticatedRequestHeaders, ensureOk } from "@/next/http"; +import { apiURL } from "@/next/origins"; +import { z } from "zod"; + +/** + * Fetch the value of a remote value for the given {@link key}. + */ +export const getRemoteValue = async (key: string) => { + const url = await apiURL("/remote-store"); + const params = new URLSearchParams({ key }); + const res = await fetch(`${url}?${params.toString()}`, { + headers: await authenticatedRequestHeaders(), + }); + ensureOk(res); + const data = GetRemoteStoreResponse.parse(await res.json()); + return data?.value; +}; + +const GetRemoteStoreResponse = z.object({ value: z.string() }).nullable(); From cfad9f841ef842821465c5cc8bf918d890b773fb Mon Sep 17 00:00:00 2001 From: Manav Rathi Date: Wed, 10 Jul 2024 12:53:06 +0530 Subject: [PATCH 15/67] flags --- web/packages/new/photos/services/ml/index.ts | 12 ++++++++ .../new/photos/services/remote-store.ts | 30 +++++++++++++++++-- 2 files changed, 39 insertions(+), 3 deletions(-) diff --git a/web/packages/new/photos/services/ml/index.ts b/web/packages/new/photos/services/ml/index.ts index 6def77972c..a4d129459f 100644 --- a/web/packages/new/photos/services/ml/index.ts +++ b/web/packages/new/photos/services/ml/index.ts @@ -14,6 +14,7 @@ import { ensureElectron } from "@/next/electron"; import log from "@/next/log"; import { ComlinkWorker } from "@/next/worker/comlink-worker"; import { proxy } from "comlink"; +import { getRemoteFlag, updateRemoteFlag } from "../remote-store"; import type { UploadItem } from "../upload/types"; import { regenerateFaceCrops } from "./crop"; import { clearMLDB, faceIndex, indexableAndIndexedCounts } from "./db"; @@ -185,6 +186,17 @@ const setIsMLEnabledLocally = (enabled: boolean) => ? localStorage.setItem("faceIndexingEnabled", "1") : localStorage.removeItem("faceIndexingEnabled"); +/** + * For historical reasons, this is called "faceSearchEnabled" (it started off as + * a flag to ensure we have taken the face recognition consent from the user). + * + * Now it tracks the status of ML in general (which includes faces + consent). + */ +const mlRemoteKey = "faceSearchEnabled"; +const getIsMLEnabledRemote = () => getRemoteFlag(mlRemoteKey); +const updateIsMLEnabledRemote = (enabled: boolean) => + updateRemoteFlag(mlRemoteKey, enabled); + /** * Trigger a "sync", whatever that means for the ML subsystem. * diff --git a/web/packages/new/photos/services/remote-store.ts b/web/packages/new/photos/services/remote-store.ts index d9e26dd680..1501c0d220 100644 --- a/web/packages/new/photos/services/remote-store.ts +++ b/web/packages/new/photos/services/remote-store.ts @@ -3,7 +3,9 @@ import { apiURL } from "@/next/origins"; import { z } from "zod"; /** - * Fetch the value of a remote value for the given {@link key}. + * Fetch the value for the given {@link key} from remote store. + * + * If the key is not present in the remote store, return `undefined`. */ export const getRemoteValue = async (key: string) => { const url = await apiURL("/remote-store"); @@ -12,8 +14,30 @@ export const getRemoteValue = async (key: string) => { headers: await authenticatedRequestHeaders(), }); ensureOk(res); - const data = GetRemoteStoreResponse.parse(await res.json()); - return data?.value; + return GetRemoteStoreResponse.parse(await res.json())?.value; }; const GetRemoteStoreResponse = z.object({ value: z.string() }).nullable(); + +/** + * Convenience wrapper over {@link getRemoteValue} that returns booleans. + */ +export const getRemoteFlag = async (key: string) => + (await getRemoteValue(key)) == "true"; + +/** + * Update or insert {@link value} for the given {@link key} into remote store. + */ +export const updateRemoteValue = async (key: string, value: string) => + ensureOk( + await fetch(await apiURL("/remote-store/update"), { + headers: await authenticatedRequestHeaders(), + body: JSON.stringify({ key, value }), + }), + ); + +/** + * Convenience wrapper over {@link updateRemoteValue} that sets booleans. + */ +export const updateRemoteFlag = (key: string, value: boolean) => + updateRemoteValue(key, JSON.stringify(value)); From c5cd6cbbca521c6ba8d48d93a8a52ea79db4fc07 Mon Sep 17 00:00:00 2001 From: Manav Rathi Date: Wed, 10 Jul 2024 13:03:25 +0530 Subject: [PATCH 16/67] Use new --- .../src/components/ml/MLSearchSettings.tsx | 21 ++++------ web/apps/photos/src/services/userService.ts | 41 ------------------- web/packages/new/photos/services/ml/index.ts | 12 +++--- 3 files changed, 15 insertions(+), 59 deletions(-) diff --git a/web/apps/photos/src/components/ml/MLSearchSettings.tsx b/web/apps/photos/src/components/ml/MLSearchSettings.tsx index 80b09d0e81..66eac5a578 100644 --- a/web/apps/photos/src/components/ml/MLSearchSettings.tsx +++ b/web/apps/photos/src/components/ml/MLSearchSettings.tsx @@ -2,7 +2,9 @@ import { canEnableML, disableML, enableML, + getIsMLEnabledRemote, isMLEnabled, + pauseML, } from "@/new/photos/services/ml"; import { EnteDrawer } from "@/new/shared/components/EnteDrawer"; import { MenuItemGroup } from "@/new/shared/components/Menu"; @@ -24,10 +26,6 @@ import { t } from "i18next"; import { AppContext } from "pages/_app"; import { useContext, useEffect, useState } from "react"; import { Trans } from "react-i18next"; -import { - getFaceSearchEnabledStatus, - updateFaceSearchEnabledStatus, -} from "services/userService"; export const MLSearchSettings = ({ open, onClose, onRootClose }) => { const { @@ -48,11 +46,11 @@ export const MLSearchSettings = ({ open, onClose, onRootClose }) => { const enableMlSearch = async () => { try { - const hasEnabledFaceSearch = await getFaceSearchEnabledStatus(); - if (!hasEnabledFaceSearch) { + const isEnabledRemote = await getIsMLEnabledRemote(); + if (!isEnabledRemote) { openEnableFaceSearch(); } else { - enableML(); + await enableML(); } } catch (e) { log.error("Enable ML search failed", e); @@ -63,9 +61,7 @@ export const MLSearchSettings = ({ open, onClose, onRootClose }) => { const enableFaceSearch = async () => { try { startLoading(); - // Update the consent flag. - await updateFaceSearchEnabledStatus(true); - enableML(); + await enableML(); closeEnableFaceSearch(); finishLoading(); } catch (e) { @@ -76,7 +72,7 @@ export const MLSearchSettings = ({ open, onClose, onRootClose }) => { const disableMlSearch = async () => { try { - disableML(); + pauseML(); onClose(); } catch (e) { log.error("Disable ML search failed", e); @@ -87,7 +83,8 @@ export const MLSearchSettings = ({ open, onClose, onRootClose }) => { const disableFaceSearch = async () => { try { startLoading(); - await disableMlSearch(); + await disableML(); + onClose(); finishLoading(); } catch (e) { log.error("Disable face search failed", e); diff --git a/web/apps/photos/src/services/userService.ts b/web/apps/photos/src/services/userService.ts index 11da7b07c8..4c6e17e826 100644 --- a/web/apps/photos/src/services/userService.ts +++ b/web/apps/photos/src/services/userService.ts @@ -206,47 +206,6 @@ export const deleteAccount = async ( } }; -export const getFaceSearchEnabledStatus = async () => { - try { - const token = getToken(); - const resp: AxiosResponse = - await HTTPService.get( - await apiURL("/remote-store"), - { - key: "faceSearchEnabled", - defaultValue: false, - }, - { - "X-Auth-Token": token, - }, - ); - return resp.data.value === "true"; - } catch (e) { - log.error("failed to get face search enabled status", e); - throw e; - } -}; - -export const updateFaceSearchEnabledStatus = async (newStatus: boolean) => { - try { - const token = getToken(); - await HTTPService.post( - await apiURL("/remote-store/update"), - { - key: "faceSearchEnabled", - value: newStatus.toString(), - }, - null, - { - "X-Auth-Token": token, - }, - ); - } catch (e) { - log.error("failed to update face search enabled status", e); - throw e; - } -}; - export const syncMapEnabled = async () => { try { const status = await getMapEnabledStatus(); diff --git a/web/packages/new/photos/services/ml/index.ts b/web/packages/new/photos/services/ml/index.ts index a4d129459f..9e6c3fdda5 100644 --- a/web/packages/new/photos/services/ml/index.ts +++ b/web/packages/new/photos/services/ml/index.ts @@ -106,7 +106,7 @@ export const canEnableML = async () => * * The user may enable ML. This enables in both locally by persisting a local * storage flag, and sets a flag on remote so that the user's other devices can - * also enable it. + * also enable it if they wish. * * The user may pause ML locally. This does not modify the remote flag, but it * unsets the local flag. Subsequently resuming ML (locally) will set the local @@ -124,8 +124,8 @@ export const isMLEnabled = () => * * Persist the user's preference both locally and on remote, and trigger a sync. */ -export const enableML = () => { - // TODO-ML: API call. +export const enableML = async () => { + await updateIsMLEnabledRemote(true); setIsMLEnabledLocally(true); _isMLEnabled = true; triggerMLSync(); @@ -137,8 +137,8 @@ export const enableML = () => { * Stop any in-progress ML tasks, and persist the user's preference both locally * and on remote. */ -export const disableML = () => { - // TODO-ML: API call. +export const disableML = async () => { + await updateIsMLEnabledRemote(false); terminateMLWorker(); setIsMLEnabledLocally(false); _isMLEnabled = false; @@ -193,7 +193,7 @@ const setIsMLEnabledLocally = (enabled: boolean) => * Now it tracks the status of ML in general (which includes faces + consent). */ const mlRemoteKey = "faceSearchEnabled"; -const getIsMLEnabledRemote = () => getRemoteFlag(mlRemoteKey); +export const getIsMLEnabledRemote = () => getRemoteFlag(mlRemoteKey); const updateIsMLEnabledRemote = (enabled: boolean) => updateRemoteFlag(mlRemoteKey, enabled); From 5c916374f312980935ad7386a6c334fe7e453256 Mon Sep 17 00:00:00 2001 From: Manav Rathi Date: Wed, 10 Jul 2024 13:04:48 +0530 Subject: [PATCH 17/67] Move --- web/apps/photos/src/components/Sidebar/AdvancedSettings.tsx | 2 +- .../new/photos/components/MLSettings.tsx} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename web/{apps/photos/src/components/ml/MLSearchSettings.tsx => packages/new/photos/components/MLSettings.tsx} (100%) diff --git a/web/apps/photos/src/components/Sidebar/AdvancedSettings.tsx b/web/apps/photos/src/components/Sidebar/AdvancedSettings.tsx index c3c9134aa8..c580c6a758 100644 --- a/web/apps/photos/src/components/Sidebar/AdvancedSettings.tsx +++ b/web/apps/photos/src/components/Sidebar/AdvancedSettings.tsx @@ -1,3 +1,4 @@ +import { MLSearchSettings } from "@/new/photos/components/MLSettings"; import { EnteDrawer } from "@/new/shared/components/EnteDrawer"; import { MenuItemGroup, MenuSectionTitle } from "@/new/shared/components/Menu"; import { Titlebar } from "@/new/shared/components/Titlebar"; @@ -5,7 +6,6 @@ import { EnteMenuItem } from "@ente/shared/components/Menu/EnteMenuItem"; import ChevronRight from "@mui/icons-material/ChevronRight"; import ScienceIcon from "@mui/icons-material/Science"; import { Box, DialogProps, Stack } from "@mui/material"; -import { MLSearchSettings } from "components/ml/MLSearchSettings"; import { t } from "i18next"; import isElectron from "is-electron"; import { AppContext } from "pages/_app"; diff --git a/web/apps/photos/src/components/ml/MLSearchSettings.tsx b/web/packages/new/photos/components/MLSettings.tsx similarity index 100% rename from web/apps/photos/src/components/ml/MLSearchSettings.tsx rename to web/packages/new/photos/components/MLSettings.tsx From aa6e5c923443afc14299bed1d93873e7f5335571 Mon Sep 17 00:00:00 2001 From: Manav Rathi Date: Wed, 10 Jul 2024 13:17:50 +0530 Subject: [PATCH 18/67] Start fixing lint issues --- .../components/Sidebar/AdvancedSettings.tsx | 5 ++-- .../new/photos/components/MLSettings.tsx | 26 +++++++++++++++---- web/packages/new/photos/types/context.ts | 19 ++++++++++++++ 3 files changed, 43 insertions(+), 7 deletions(-) create mode 100644 web/packages/new/photos/types/context.ts diff --git a/web/apps/photos/src/components/Sidebar/AdvancedSettings.tsx b/web/apps/photos/src/components/Sidebar/AdvancedSettings.tsx index c580c6a758..1520845400 100644 --- a/web/apps/photos/src/components/Sidebar/AdvancedSettings.tsx +++ b/web/apps/photos/src/components/Sidebar/AdvancedSettings.tsx @@ -1,4 +1,4 @@ -import { MLSearchSettings } from "@/new/photos/components/MLSettings"; +import { MLSettings } from "@/new/photos/components/MLSettings"; import { EnteDrawer } from "@/new/shared/components/EnteDrawer"; import { MenuItemGroup, MenuSectionTitle } from "@/new/shared/components/Menu"; import { Titlebar } from "@/new/shared/components/Titlebar"; @@ -132,10 +132,11 @@ export default function AdvancedSettings({ open, onClose, onRootClose }) { - ); diff --git a/web/packages/new/photos/components/MLSettings.tsx b/web/packages/new/photos/components/MLSettings.tsx index 66eac5a578..8553ac0b75 100644 --- a/web/packages/new/photos/components/MLSettings.tsx +++ b/web/packages/new/photos/components/MLSettings.tsx @@ -15,7 +15,7 @@ import { Box, Button, Checkbox, - DialogProps, + type DialogProps, FormControlLabel, FormGroup, Link, @@ -23,17 +23,33 @@ import { Typography, } from "@mui/material"; import { t } from "i18next"; -import { AppContext } from "pages/_app"; -import { useContext, useEffect, useState } from "react"; +import React, { useEffect, useState } from "react"; import { Trans } from "react-i18next"; +import type { NewAppContextPhotos } from "../types/context"; -export const MLSearchSettings = ({ open, onClose, onRootClose }) => { +interface MLSettingsProps { + /** If `true`, then the drawer page is shown. */ + open: boolean; + /** Called when the user wants to go back from this drawer page. */ + onClose: () => void; + /** Called when the user wants to close the containing drawer. */ + onRootClose: () => void; + /** See: [Note: Migrating components that need the app context]. */ + appContext: NewAppContextPhotos; +} + +export const MLSettings: React.FC = ({ + open, + onClose, + onRootClose, + appContext, +}) => { const { setDialogMessage, somethingWentWrong, startLoading, finishLoading, - } = useContext(AppContext); + } = appContext; const [enableFaceSearchView, setEnableFaceSearchView] = useState(false); diff --git a/web/packages/new/photos/types/context.ts b/web/packages/new/photos/types/context.ts new file mode 100644 index 0000000000..d864717146 --- /dev/null +++ b/web/packages/new/photos/types/context.ts @@ -0,0 +1,19 @@ +import type { SetDialogBoxAttributes } from "@ente/shared/components/DialogBox/types"; + +/** + * A subset of the AppContext type used by the photos app. + * + * [Note: Migrating components that need the app context] + * + * This only exists to make it easier to migrate code into the @/new package. + * Once we move this code back (after TypeScript strict mode migration is done), + * then the code that uses this can start directly using the actual app context + * instead of needing to explicitly pass a prop of this type. + * */ +export interface NewAppContextPhotos { + startLoading: () => void; + finishLoading: () => void; + closeMessageDialog: () => void; + setDialogMessage: SetDialogBoxAttributes; + somethingWentWrong: () => void; +} From 071a63a81c4e0472a77fcfb062f9bd19821df6c3 Mon Sep 17 00:00:00 2001 From: Manav Rathi Date: Wed, 10 Jul 2024 13:27:00 +0530 Subject: [PATCH 19/67] Outer --- .../photos/src/components/Sidebar/AdvancedSettings.tsx | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/web/apps/photos/src/components/Sidebar/AdvancedSettings.tsx b/web/apps/photos/src/components/Sidebar/AdvancedSettings.tsx index 1520845400..20552ed655 100644 --- a/web/apps/photos/src/components/Sidebar/AdvancedSettings.tsx +++ b/web/apps/photos/src/components/Sidebar/AdvancedSettings.tsx @@ -2,6 +2,7 @@ import { MLSettings } from "@/new/photos/components/MLSettings"; import { EnteDrawer } from "@/new/shared/components/EnteDrawer"; import { MenuItemGroup, MenuSectionTitle } from "@/new/shared/components/Menu"; import { Titlebar } from "@/new/shared/components/Titlebar"; +import { pt } from "@/next/i18n"; import { EnteMenuItem } from "@ente/shared/components/Menu/EnteMenuItem"; import ChevronRight from "@mui/icons-material/ChevronRight"; import ScienceIcon from "@mui/icons-material/Science"; @@ -75,9 +76,14 @@ export default function AdvancedSettings({ open, onClose, onRootClose }) { } onClick={openMlSearchSettings} - label={t("ML_SEARCH")} + label={pt("ML search")} /> + )} From 8830a60ecfcaebde544b6e80781b5bd231b3ca29 Mon Sep 17 00:00:00 2001 From: Manav Rathi Date: Wed, 10 Jul 2024 13:34:54 +0530 Subject: [PATCH 20/67] Move up --- .../components/Sidebar/AdvancedSettings.tsx | 85 +------------------ .../src/components/Sidebar/Preferences.tsx | 48 +++++++++-- .../new/photos/components/MLSettings.tsx | 47 ++++++++++ 3 files changed, 91 insertions(+), 89 deletions(-) diff --git a/web/apps/photos/src/components/Sidebar/AdvancedSettings.tsx b/web/apps/photos/src/components/Sidebar/AdvancedSettings.tsx index 20552ed655..5810834636 100644 --- a/web/apps/photos/src/components/Sidebar/AdvancedSettings.tsx +++ b/web/apps/photos/src/components/Sidebar/AdvancedSettings.tsx @@ -1,23 +1,14 @@ -import { MLSettings } from "@/new/photos/components/MLSettings"; import { EnteDrawer } from "@/new/shared/components/EnteDrawer"; import { MenuItemGroup, MenuSectionTitle } from "@/new/shared/components/Menu"; import { Titlebar } from "@/new/shared/components/Titlebar"; -import { pt } from "@/next/i18n"; import { EnteMenuItem } from "@ente/shared/components/Menu/EnteMenuItem"; -import ChevronRight from "@mui/icons-material/ChevronRight"; -import ScienceIcon from "@mui/icons-material/Science"; import { Box, DialogProps, Stack } from "@mui/material"; import { t } from "i18next"; -import isElectron from "is-electron"; import { AppContext } from "pages/_app"; -import { useContext, useState } from "react"; +import { useContext } from "react"; export default function AdvancedSettings({ open, onClose, onRootClose }) { const appContext = useContext(AppContext); - const [mlSearchSettingsView, setMlSearchSettingsView] = useState(false); - - const openMlSearchSettings = () => setMlSearchSettingsView(true); - const closeMlSearchSettings = () => setMlSearchSettingsView(false); const handleRootClose = () => { onClose(); @@ -36,18 +27,6 @@ export default function AdvancedSettings({ open, onClose, onRootClose }) { appContext.setIsCFProxyDisabled(!appContext.isCFProxyDisabled); }; - // TODO-ML: - // const [indexingStatus, setIndexingStatus] = useState({ - // indexed: 0, - // pending: 0, - // }); - - // useEffect(() => { - // clipService.setOnUpdateHandler(setIndexingStatus); - // clipService.getIndexingStatus().then((st) => setIndexingStatus(st)); - // return () => clipService.setOnUpdateHandler(undefined); - // }, []); - return ( - {isElectron() && ( - - } - /> - - } - onClick={openMlSearchSettings} - label={pt("ML search")} - /> - - - - )} - - {/* TODO-ML: isElectron() && ( - - - - - - {t("INDEXED_ITEMS")} - - - {formatNumber( - indexingStatus.indexed, - )} - - - - - {t("PENDING_ITEMS")} - - - {formatNumber( - indexingStatus.pending, - )} - - - - - )*/} - ); } diff --git a/web/apps/photos/src/components/Sidebar/Preferences.tsx b/web/apps/photos/src/components/Sidebar/Preferences.tsx index ac6e9ecb57..0889af6ecc 100644 --- a/web/apps/photos/src/components/Sidebar/Preferences.tsx +++ b/web/apps/photos/src/components/Sidebar/Preferences.tsx @@ -1,23 +1,35 @@ +import { MLSettings } from "@/new/photos/components/MLSettings"; import { EnteDrawer } from "@/new/shared/components/EnteDrawer"; +import { MenuItemGroup, MenuSectionTitle } from "@/new/shared/components/Menu"; import { Titlebar } from "@/new/shared/components/Titlebar"; import { getLocaleInUse, + pt, setLocaleInUse, supportedLocales, type SupportedLocale, } from "@/next/i18n"; import { EnteMenuItem } from "@ente/shared/components/Menu/EnteMenuItem"; import ChevronRight from "@mui/icons-material/ChevronRight"; +import ScienceIcon from "@mui/icons-material/Science"; import { Box, DialogProps, Stack } from "@mui/material"; import DropdownInput from "components/DropdownInput"; import { t } from "i18next"; -import { useState } from "react"; +import isElectron from "is-electron"; +import { AppContext } from "pages/_app"; +import { useContext, useState } from "react"; import AdvancedSettings from "./AdvancedSettings"; import MapSettings from "./MapSetting"; export default function Preferences({ open, onClose, onRootClose }) { + const appContext = useContext(AppContext); + const [advancedSettingsView, setAdvancedSettingsView] = useState(false); const [mapSettingsView, setMapSettingsView] = useState(false); + const [mlSearchSettingsView, setMlSearchSettingsView] = useState(false); + + const openMlSearchSettings = () => setMlSearchSettingsView(true); + const closeMlSearchSettings = () => setMlSearchSettingsView(false); const openAdvancedSettings = () => setAdvancedSettingsView(true); const closeAdvancedSettings = () => setAdvancedSettingsView(false); @@ -66,19 +78,45 @@ export default function Preferences({ open, onClose, onRootClose }) { endIcon={} label={t("ADVANCED")} /> + {isElectron() && ( + + } + /> + + } + onClick={openMlSearchSettings} + label={pt("ML search")} + /> + + + + )} - + ); } diff --git a/web/packages/new/photos/components/MLSettings.tsx b/web/packages/new/photos/components/MLSettings.tsx index 8553ac0b75..07db162c1a 100644 --- a/web/packages/new/photos/components/MLSettings.tsx +++ b/web/packages/new/photos/components/MLSettings.tsx @@ -138,6 +138,53 @@ export const MLSettings: React.FC = ({ } }; + // TODO-ML: + // const [indexingStatus, setIndexingStatus] = useState({ + // indexed: 0, + // pending: 0, + // }); + + // useEffect(() => { + // clipService.setOnUpdateHandler(setIndexingStatus); + // clipService.getIndexingStatus().then((st) => setIndexingStatus(st)); + // return () => clipService.setOnUpdateHandler(undefined); + // }, []); + /* TODO-ML: isElectron() && ( + + + + + + {t("INDEXED_ITEMS")} + + + {formatNumber( + indexingStatus.indexed, + )} + + + + + {t("PENDING_ITEMS")} + + + {formatNumber( + indexingStatus.pending, + )} + + + + + )*/ + return ( Date: Wed, 10 Jul 2024 13:40:11 +0530 Subject: [PATCH 21/67] Tweaks --- .../src/components/Sidebar/Preferences.tsx | 11 +++----- .../new/photos/components/MLSettings.tsx | 28 +++++++++---------- 2 files changed, 18 insertions(+), 21 deletions(-) diff --git a/web/apps/photos/src/components/Sidebar/Preferences.tsx b/web/apps/photos/src/components/Sidebar/Preferences.tsx index 0889af6ecc..5975059af9 100644 --- a/web/apps/photos/src/components/Sidebar/Preferences.tsx +++ b/web/apps/photos/src/components/Sidebar/Preferences.tsx @@ -26,10 +26,7 @@ export default function Preferences({ open, onClose, onRootClose }) { const [advancedSettingsView, setAdvancedSettingsView] = useState(false); const [mapSettingsView, setMapSettingsView] = useState(false); - const [mlSearchSettingsView, setMlSearchSettingsView] = useState(false); - - const openMlSearchSettings = () => setMlSearchSettingsView(true); - const closeMlSearchSettings = () => setMlSearchSettingsView(false); + const [openMLSettings, setOpenMLSettings] = useState(false); const openAdvancedSettings = () => setAdvancedSettingsView(true); const closeAdvancedSettings = () => setAdvancedSettingsView(false); @@ -87,7 +84,7 @@ export default function Preferences({ open, onClose, onRootClose }) { } - onClick={openMlSearchSettings} + onClick={() => setOpenMLSettings(true)} label={pt("ML search")} /> @@ -102,8 +99,8 @@ export default function Preferences({ open, onClose, onRootClose }) { setOpenMLSettings(false)} onRootClose={handleRootClose} appContext={appContext} /> diff --git a/web/packages/new/photos/components/MLSettings.tsx b/web/packages/new/photos/components/MLSettings.tsx index 07db162c1a..a74fe48460 100644 --- a/web/packages/new/photos/components/MLSettings.tsx +++ b/web/packages/new/photos/components/MLSettings.tsx @@ -28,7 +28,7 @@ import { Trans } from "react-i18next"; import type { NewAppContextPhotos } from "../types/context"; interface MLSettingsProps { - /** If `true`, then the drawer page is shown. */ + /** If `true`, then this drawer page is shown. */ open: boolean; /** Called when the user wants to go back from this drawer page. */ onClose: () => void; @@ -53,6 +53,19 @@ export const MLSettings: React.FC = ({ const [enableFaceSearchView, setEnableFaceSearchView] = useState(false); + const handleRootClose = () => { + onClose(); + onRootClose(); + }; + + const handleDrawerClose: DialogProps["onClose"] = (_, reason) => { + if (reason === "backdropClick") { + handleRootClose(); + } else { + onClose(); + } + }; + const openEnableFaceSearch = () => { setEnableFaceSearchView(true); }; @@ -125,19 +138,6 @@ export const MLSettings: React.FC = ({ }); }; - const handleRootClose = () => { - onClose(); - onRootClose(); - }; - - const handleDrawerClose: DialogProps["onClose"] = (_, reason) => { - if (reason === "backdropClick") { - handleRootClose(); - } else { - onClose(); - } - }; - // TODO-ML: // const [indexingStatus, setIndexingStatus] = useState({ // indexed: 0, From 162107b3a9b696ecf49b1beefe58e0eec71f3138 Mon Sep 17 00:00:00 2001 From: Manav Rathi Date: Wed, 10 Jul 2024 13:40:39 +0530 Subject: [PATCH 22/67] Fix --- web/packages/new/photos/services/remote-store.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/web/packages/new/photos/services/remote-store.ts b/web/packages/new/photos/services/remote-store.ts index 1501c0d220..ac4d6941a6 100644 --- a/web/packages/new/photos/services/remote-store.ts +++ b/web/packages/new/photos/services/remote-store.ts @@ -31,6 +31,7 @@ export const getRemoteFlag = async (key: string) => export const updateRemoteValue = async (key: string, value: string) => ensureOk( await fetch(await apiURL("/remote-store/update"), { + method: "POST", headers: await authenticatedRequestHeaders(), body: JSON.stringify({ key, value }), }), From 3b951f237f78b3b05cca8e521e780c98a651e2a1 Mon Sep 17 00:00:00 2001 From: Manav Rathi Date: Wed, 10 Jul 2024 14:16:04 +0530 Subject: [PATCH 23/67] wip refactor --- .../new/photos/components/MLSettings.tsx | 173 +++++++++++------- 1 file changed, 109 insertions(+), 64 deletions(-) diff --git a/web/packages/new/photos/components/MLSettings.tsx b/web/packages/new/photos/components/MLSettings.tsx index a74fe48460..33c7367cdf 100644 --- a/web/packages/new/photos/components/MLSettings.tsx +++ b/web/packages/new/photos/components/MLSettings.tsx @@ -3,13 +3,14 @@ import { disableML, enableML, getIsMLEnabledRemote, - isMLEnabled, pauseML, } from "@/new/photos/services/ml"; import { EnteDrawer } from "@/new/shared/components/EnteDrawer"; import { MenuItemGroup } from "@/new/shared/components/Menu"; import { Titlebar } from "@/new/shared/components/Titlebar"; +import { pt } from "@/next/i18n"; import log from "@/next/log"; +import EnteSpinner from "@ente/shared/components/EnteSpinner"; import { EnteMenuItem } from "@ente/shared/components/Menu/EnteMenuItem"; import { Box, @@ -51,6 +52,21 @@ export const MLSettings: React.FC = ({ finishLoading, } = appContext; + /** + * The state of our component. + * + * To avoid confusion with useState, we call it status instead. */ + // TODO: This Status is not automatically synced with the lower layers that + // hold the actual state. + type Status = + | "loading" /* fetching the data we need from the lower layers */ + | "notEligible" /* user is not in the beta program */ + | "disabled" /* eligible, but ML is currently disabled */ + | "enabled" /* ML is enabled */ + | "paused"; /* ML is disabled locally, but is otherwise enabled */ + + const [status, setStatus] = useState("loading"); + const [enableFaceSearchView, setEnableFaceSearchView] = useState(false); const handleRootClose = () => { @@ -185,6 +201,25 @@ export const MLSettings: React.FC = ({ )*/ + const components: Record = { + loading: , + disabled: ( + + ), + enabled: ( + + ), + }; + return ( = ({ sx: { "&&&": { backgroundColor: "transparent" } }, }} > - {isMLEnabled() ? ( - - ) : ( - + - )} + {components[status] ?? } + = ({ ); }; +const Loading: React.FC = () => { + return ( + + + + ); +}; +type EnableMLProps = Omit & { + /** Called when the user enables ML */ + onEnable: () => void; +}; + +const EnableML: React.FC = ({ + onClose, + enableMlSearch, + onRootClose, +}) => { + // const showDetails = () => + // openLink("https://ente.io/blog/desktop-ml-beta", true); + + const [canEnable, setCanEnable] = useState(false); + + useEffect(() => { + canEnableML().then((v) => setCanEnable(v)); + }, []); + + return ( + + + + {canEnable ? ( + + + {/* + + */} + + ) : ( + + {" "} + + {/* */} + We're putting finishing touches, coming back soon! + + + )} + + + ); +}; + function EnableFaceSearch({ open, onClose, enableFaceSearch, onRootClose }) { const [acceptTerms, setAcceptTerms] = useState(false); @@ -317,57 +413,6 @@ function EnableFaceSearch({ open, onClose, enableFaceSearch, onRootClose }) { ); } -function EnableMLSearch({ onClose, enableMlSearch, onRootClose }) { - // const showDetails = () => - // openLink("https://ente.io/blog/desktop-ml-beta", true); - - const [canEnable, setCanEnable] = useState(false); - - useEffect(() => { - canEnableML().then((v) => setCanEnable(v)); - }, []); - - return ( - - - - {canEnable ? ( - - - {/* - - */} - - ) : ( - - {" "} - - {/* */} - We're putting finishing touches, coming back soon! - - - )} - - - ); -} - function ManageMLSearch({ onClose, disableMlSearch, From 1322e5df79f70922f04d600c5a73b15ee6d5a08a Mon Sep 17 00:00:00 2001 From: Manav Rathi Date: Wed, 10 Jul 2024 14:23:44 +0530 Subject: [PATCH 24/67] r2 --- .../new/photos/components/MLSettings.tsx | 39 +++++++++++++++---- 1 file changed, 31 insertions(+), 8 deletions(-) diff --git a/web/packages/new/photos/components/MLSettings.tsx b/web/packages/new/photos/components/MLSettings.tsx index 33c7367cdf..0011265122 100644 --- a/web/packages/new/photos/components/MLSettings.tsx +++ b/web/packages/new/photos/components/MLSettings.tsx @@ -3,12 +3,13 @@ import { disableML, enableML, getIsMLEnabledRemote, + isMLEnabled, pauseML, } from "@/new/photos/services/ml"; import { EnteDrawer } from "@/new/shared/components/EnteDrawer"; import { MenuItemGroup } from "@/new/shared/components/Menu"; import { Titlebar } from "@/new/shared/components/Titlebar"; -import { pt } from "@/next/i18n"; +import { pt, ut } from "@/next/i18n"; import log from "@/next/log"; import EnteSpinner from "@ente/shared/components/EnteSpinner"; import { EnteMenuItem } from "@ente/shared/components/Menu/EnteMenuItem"; @@ -67,6 +68,22 @@ export const MLSettings: React.FC = ({ const [status, setStatus] = useState("loading"); + const refreshStatus = async () => { + if (isMLEnabled()) { + setStatus("enabled"); + } else if (await getIsMLEnabledRemote()) { + setStatus("paused"); + } else if (await canEnableML()) { + setStatus("disabled"); + } else { + setStatus("notEligible"); + } + }; + + useEffect(() => { + void refreshStatus(); + }, []); + const [enableFaceSearchView, setEnableFaceSearchView] = useState(false); const handleRootClose = () => { @@ -203,6 +220,7 @@ export const MLSettings: React.FC = ({ const components: Record = { loading: , + notEligible: , disabled: ( { ); }; + +const ComingSoon: React.FC = () => { + return ( + + + {ut("We're putting finishing touches, coming back soon!")} + + + ); +}; + type EnableMLProps = Omit & { /** Called when the user enables ML */ onEnable: () => void; @@ -305,13 +334,7 @@ const EnableML: React.FC = ({ */} ) : ( - - {" "} - - {/* */} - We're putting finishing touches, coming back soon! - - +
)} From 83d6d99469b8244cb6dfbf5f165be18b6103be83 Mon Sep 17 00:00:00 2001 From: Manav Rathi Date: Wed, 10 Jul 2024 14:32:01 +0530 Subject: [PATCH 25/67] r3 --- .../new/photos/components/MLSettings.tsx | 31 +++++++++---------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/web/packages/new/photos/components/MLSettings.tsx b/web/packages/new/photos/components/MLSettings.tsx index 0011265122..29658df882 100644 --- a/web/packages/new/photos/components/MLSettings.tsx +++ b/web/packages/new/photos/components/MLSettings.tsx @@ -84,7 +84,7 @@ export const MLSettings: React.FC = ({ void refreshStatus(); }, []); - const [enableFaceSearchView, setEnableFaceSearchView] = useState(false); + const [openFaceConsent, setOpenFaceConsent] = useState(false); const handleRootClose = () => { onClose(); @@ -92,11 +92,8 @@ export const MLSettings: React.FC = ({ }; const handleDrawerClose: DialogProps["onClose"] = (_, reason) => { - if (reason === "backdropClick") { - handleRootClose(); - } else { - onClose(); - } + if (reason == "backdropClick") handleRootClose(); + else onClose(); }; const openEnableFaceSearch = () => { @@ -106,16 +103,18 @@ export const MLSettings: React.FC = ({ setEnableFaceSearchView(false); }; - const enableMlSearch = async () => { + // The user may've changed the remote flag on a different device, so in both + // cases (enable or resume), do the same flow: + // + // - If remote flag is not set, then show the consent dialog + // - Otherwise enable ML (both locally and on remote). + // + const handleEnableOrResumeML = async () => { try { - const isEnabledRemote = await getIsMLEnabledRemote(); - if (!isEnabledRemote) { - openEnableFaceSearch(); - } else { - await enableML(); - } + if (await getIsMLEnabledRemote()) await enableML(); + else setOpenFaceConsent(true); } catch (e) { - log.error("Enable ML search failed", e); + log.error("Failed to enable or resume ML", e); somethingWentWrong(); } }; @@ -224,7 +223,7 @@ export const MLSettings: React.FC = ({ disabled: ( ), @@ -288,7 +287,7 @@ const ComingSoon: React.FC = () => { }; type EnableMLProps = Omit & { - /** Called when the user enables ML */ + /** Called when the user enables ML. */ onEnable: () => void; }; From ebfd8909a947c65d1e1603a13361c52956a98784 Mon Sep 17 00:00:00 2001 From: Manav Rathi Date: Wed, 10 Jul 2024 14:32:36 +0530 Subject: [PATCH 26/67] Move to its final place --- .../new/photos/components/MLSettings.tsx | 94 +++++++++---------- 1 file changed, 47 insertions(+), 47 deletions(-) diff --git a/web/packages/new/photos/components/MLSettings.tsx b/web/packages/new/photos/components/MLSettings.tsx index 29658df882..3f38856e0e 100644 --- a/web/packages/new/photos/components/MLSettings.tsx +++ b/web/packages/new/photos/components/MLSettings.tsx @@ -170,53 +170,6 @@ export const MLSettings: React.FC = ({ }); }; - // TODO-ML: - // const [indexingStatus, setIndexingStatus] = useState({ - // indexed: 0, - // pending: 0, - // }); - - // useEffect(() => { - // clipService.setOnUpdateHandler(setIndexingStatus); - // clipService.getIndexingStatus().then((st) => setIndexingStatus(st)); - // return () => clipService.setOnUpdateHandler(undefined); - // }, []); - /* TODO-ML: isElectron() && ( - - - - - - {t("INDEXED_ITEMS")} - - - {formatNumber( - indexingStatus.indexed, - )} - - - - - {t("PENDING_ITEMS")} - - - {formatNumber( - indexingStatus.pending, - )} - - - - - )*/ - const components: Record = { loading: , notEligible: , @@ -441,6 +394,53 @@ function ManageMLSearch({ handleDisableFaceSearch, onRootClose, }) { + // TODO-ML: + // const [indexingStatus, setIndexingStatus] = useState({ + // indexed: 0, + // pending: 0, + // }); + + // useEffect(() => { + // clipService.setOnUpdateHandler(setIndexingStatus); + // clipService.getIndexingStatus().then((st) => setIndexingStatus(st)); + // return () => clipService.setOnUpdateHandler(undefined); + // }, []); + /* TODO-ML: isElectron() && ( + + + + + + {t("INDEXED_ITEMS")} + + + {formatNumber( + indexingStatus.indexed, + )} + + + + + {t("PENDING_ITEMS")} + + + {formatNumber( + indexingStatus.pending, + )} + + + + + )*/ + return ( Date: Wed, 10 Jul 2024 14:35:00 +0530 Subject: [PATCH 27/67] r4 --- .../new/photos/components/MLSettings.tsx | 53 ++++++------------- 1 file changed, 17 insertions(+), 36 deletions(-) diff --git a/web/packages/new/photos/components/MLSettings.tsx b/web/packages/new/photos/components/MLSettings.tsx index 3f38856e0e..f22eaf4d96 100644 --- a/web/packages/new/photos/components/MLSettings.tsx +++ b/web/packages/new/photos/components/MLSettings.tsx @@ -111,8 +111,12 @@ export const MLSettings: React.FC = ({ // const handleEnableOrResumeML = async () => { try { - if (await getIsMLEnabledRemote()) await enableML(); - else setOpenFaceConsent(true); + if (!(await getIsMLEnabledRemote())) { + setOpenFaceConsent(true); + } else { + await enableML(); + setStatus("enabled"); + } } catch (e) { log.error("Failed to enable or resume ML", e); somethingWentWrong(); @@ -239,43 +243,23 @@ const ComingSoon: React.FC = () => { ); }; -type EnableMLProps = Omit & { +interface EnableMLProps { /** Called when the user enables ML. */ onEnable: () => void; -}; +} -const EnableML: React.FC = ({ - onClose, - enableMlSearch, - onRootClose, -}) => { +const EnableML: React.FC = ({ onEnable }) => { // const showDetails = () => // openLink("https://ente.io/blog/desktop-ml-beta", true); - const [canEnable, setCanEnable] = useState(false); - - useEffect(() => { - canEnableML().then((v) => setCanEnable(v)); - }, []); - return ( - - - - {canEnable ? ( - - - {/* + + ( + + + {/* */} - - ) : ( -
- )} + ) ); }; From 70b74fc2855889b88eb8954aa64383816bd7f3d2 Mon Sep 17 00:00:00 2001 From: Manav Rathi Date: Wed, 10 Jul 2024 15:08:09 +0530 Subject: [PATCH 28/67] Continue --- .../new/photos/components/MLSettings.tsx | 90 +++++++++++++------ 1 file changed, 64 insertions(+), 26 deletions(-) diff --git a/web/packages/new/photos/components/MLSettings.tsx b/web/packages/new/photos/components/MLSettings.tsx index f22eaf4d96..668fa0ab4b 100644 --- a/web/packages/new/photos/components/MLSettings.tsx +++ b/web/packages/new/photos/components/MLSettings.tsx @@ -67,6 +67,7 @@ export const MLSettings: React.FC = ({ | "paused"; /* ML is disabled locally, but is otherwise enabled */ const [status, setStatus] = useState("loading"); + const [openFaceConsent, setOpenFaceConsent] = useState(false); const refreshStatus = async () => { if (isMLEnabled()) { @@ -84,8 +85,6 @@ export const MLSettings: React.FC = ({ void refreshStatus(); }, []); - const [openFaceConsent, setOpenFaceConsent] = useState(false); - const handleRootClose = () => { onClose(); onRootClose(); @@ -96,13 +95,6 @@ export const MLSettings: React.FC = ({ else onClose(); }; - const openEnableFaceSearch = () => { - setEnableFaceSearchView(true); - }; - const closeEnableFaceSearch = () => { - setEnableFaceSearchView(false); - }; - // The user may've changed the remote flag on a different device, so in both // cases (enable or resume), do the same flow: // @@ -110,6 +102,7 @@ export const MLSettings: React.FC = ({ // - Otherwise enable ML (both locally and on remote). // const handleEnableOrResumeML = async () => { + startLoading(); try { if (!(await getIsMLEnabledRemote())) { setOpenFaceConsent(true); @@ -120,9 +113,71 @@ export const MLSettings: React.FC = ({ } catch (e) { log.error("Failed to enable or resume ML", e); somethingWentWrong(); + } finally { + finishLoading(); + } + }; + + const handleConsent = async () => { + startLoading(); + try { + await enableML(); + setStatus("enabled"); + } catch (e) { + log.error("Failed to enable ML", e); + somethingWentWrong(); + } finally { + finishLoading(); + } + }; + + const handlePauseML = () => { + try { + pauseML(); + setStatus("paused"); + } catch (e) { + log.error("Failed to enable ML", e); + somethingWentWrong(); + } + }; + + const confirmDisableML = () => { + setDialogMessage({ + title: t("DISABLE_FACE_SEARCH_TITLE"), + content: ( + + + + ), + close: { text: t("CANCEL") }, + proceed: { + variant: "primary", + text: t("DISABLE_FACE_SEARCH"), + action: () => void didConfirmDisableML(), + }, + }); + }; + + const didConfirmDisableML = async () => { + startLoading(); + try { + await disableML(); + setStatus("disabled"); + } catch (e) { + log.error("Failed to disable ML", e); + somethingWentWrong(); + } finally { + finishLoading(); } }; + const openEnableFaceSearch = () => { + setEnableFaceSearchView(true); + }; + const closeEnableFaceSearch = () => { + setEnableFaceSearchView(false); + }; + const enableFaceSearch = async () => { try { startLoading(); @@ -157,23 +212,6 @@ export const MLSettings: React.FC = ({ } }; - const confirmDisableFaceSearch = () => { - setDialogMessage({ - title: t("DISABLE_FACE_SEARCH_TITLE"), - content: ( - - - - ), - close: { text: t("CANCEL") }, - proceed: { - variant: "primary", - text: t("DISABLE_FACE_SEARCH"), - action: disableFaceSearch, - }, - }); - }; - const components: Record = { loading: , notEligible: , From 2ac968fdf6ebec4cf3937be5a3c174d06cc1b3b3 Mon Sep 17 00:00:00 2001 From: Manav Rathi Date: Wed, 10 Jul 2024 15:34:23 +0530 Subject: [PATCH 29/67] Fixed --- .../new/photos/components/MLSettings.tsx | 220 ++++++++---------- 1 file changed, 102 insertions(+), 118 deletions(-) diff --git a/web/packages/new/photos/components/MLSettings.tsx b/web/packages/new/photos/components/MLSettings.tsx index 668fa0ab4b..f30ee64b1d 100644 --- a/web/packages/new/photos/components/MLSettings.tsx +++ b/web/packages/new/photos/components/MLSettings.tsx @@ -34,7 +34,7 @@ interface MLSettingsProps { open: boolean; /** Called when the user wants to go back from this drawer page. */ onClose: () => void; - /** Called when the user wants to close the containing drawer. */ + /** Called when the user wants to close the entire stack of drawers. */ onRootClose: () => void; /** See: [Note: Migrating components that need the app context]. */ appContext: NewAppContextPhotos; @@ -63,17 +63,20 @@ export const MLSettings: React.FC = ({ | "loading" /* fetching the data we need from the lower layers */ | "notEligible" /* user is not in the beta program */ | "disabled" /* eligible, but ML is currently disabled */ - | "enabled" /* ML is enabled */ - | "paused"; /* ML is disabled locally, but is otherwise enabled */ + | "enabledOrPaused"; /* ML is enabled, but may be paused (See isPaused) */ const [status, setStatus] = useState("loading"); const [openFaceConsent, setOpenFaceConsent] = useState(false); + /** Only valid when status is "enabledOrPaused" */ + const [isPaused, setIsPaused] = useState(false); const refreshStatus = async () => { if (isMLEnabled()) { - setStatus("enabled"); + setStatus("enabledOrPaused"); + setIsPaused(false); } else if (await getIsMLEnabledRemote()) { - setStatus("paused"); + setStatus("enabledOrPaused"); + setIsPaused(true); } else if (await canEnableML()) { setStatus("disabled"); } else { @@ -108,7 +111,8 @@ export const MLSettings: React.FC = ({ setOpenFaceConsent(true); } else { await enableML(); - setStatus("enabled"); + setStatus("enabledOrPaused"); + setIsPaused(false); } } catch (e) { log.error("Failed to enable or resume ML", e); @@ -122,7 +126,10 @@ export const MLSettings: React.FC = ({ startLoading(); try { await enableML(); - setStatus("enabled"); + setStatus("enabledOrPaused"); + setIsPaused(false); + // Close the FaceConsent drawer, come back to ourselves. + setOpenFaceConsent(false); } catch (e) { log.error("Failed to enable ML", e); somethingWentWrong(); @@ -134,31 +141,15 @@ export const MLSettings: React.FC = ({ const handlePauseML = () => { try { pauseML(); - setStatus("paused"); + setStatus("enabledOrPaused"); + setIsPaused(true); } catch (e) { log.error("Failed to enable ML", e); somethingWentWrong(); } }; - const confirmDisableML = () => { - setDialogMessage({ - title: t("DISABLE_FACE_SEARCH_TITLE"), - content: ( - - - - ), - close: { text: t("CANCEL") }, - proceed: { - variant: "primary", - text: t("DISABLE_FACE_SEARCH"), - action: () => void didConfirmDisableML(), - }, - }); - }; - - const didConfirmDisableML = async () => { + const handleDisableML = async () => { startLoading(); try { await disableML(); @@ -171,63 +162,17 @@ export const MLSettings: React.FC = ({ } }; - const openEnableFaceSearch = () => { - setEnableFaceSearchView(true); - }; - const closeEnableFaceSearch = () => { - setEnableFaceSearchView(false); - }; - - const enableFaceSearch = async () => { - try { - startLoading(); - await enableML(); - closeEnableFaceSearch(); - finishLoading(); - } catch (e) { - log.error("Enable face search failed", e); - somethingWentWrong(); - } - }; - - const disableMlSearch = async () => { - try { - pauseML(); - onClose(); - } catch (e) { - log.error("Disable ML search failed", e); - somethingWentWrong(); - } - }; - - const disableFaceSearch = async () => { - try { - startLoading(); - await disableML(); - onClose(); - finishLoading(); - } catch (e) { - log.error("Disable face search failed", e); - somethingWentWrong(); - } - }; - const components: Record = { loading: , notEligible: , - disabled: ( - - ), - enabled: ( - , + enabledOrPaused: ( + ), }; @@ -249,15 +194,15 @@ export const MLSettings: React.FC = ({ title={pt("ML search")} onRootClose={onRootClose} /> - {components[status] ?? } + {components[status]} - setOpenFaceConsent(false)} onRootClose={handleRootClose} + onConsent={handleConsent} /> ); @@ -312,7 +257,17 @@ const EnableML: React.FC = ({ onEnable }) => { ); }; -function EnableFaceSearch({ open, onClose, enableFaceSearch, onRootClose }) { +type FaceConsentProps = Omit & { + /** Called when the user provides their consent. */ + onConsent: () => void; +}; + +const FaceConsent: React.FC = ({ + open, + onClose, + onRootClose, + onConsent, +}) => { const [acceptTerms, setAcceptTerms] = useState(false); useEffect(() => { @@ -325,12 +280,10 @@ function EnableFaceSearch({ open, onClose, enableFaceSearch, onRootClose }) { }; const handleDrawerClose: DialogProps["onClose"] = (_, reason) => { - if (reason === "backdropClick") { - handleRootClose(); - } else { - onClose(); - } + if (reason == "backdropClick") handleRootClose(); + else onClose(); }; + return ( {t("ENABLE_FACE_SEARCH")} @@ -405,14 +358,45 @@ function EnableFaceSearch({ open, onClose, enableFaceSearch, onRootClose }) { ); +}; + +interface ManageMLProps { + /** `true` if ML is locally paused. */ + isPaused: boolean; + /** Called when the user wants to pause ML. */ + onPauseML: () => void; + /** Called when the user wants to resume ML. */ + onResumeML: () => void; + /** Called when the user wants to disable ML. */ + onDisableML: () => void; + /** Subset of appContext. */ + setDialogMessage: NewAppContextPhotos["setDialogMessage"]; } -function ManageMLSearch({ - onClose, - disableMlSearch, - handleDisableFaceSearch, - onRootClose, -}) { +const ManageML: React.FC = ({ + isPaused, + onPauseML, + onResumeML, + onDisableML, + setDialogMessage, +}) => { + const confirmDisableML = () => { + setDialogMessage({ + title: t("DISABLE_FACE_SEARCH_TITLE"), + content: ( + + + + ), + close: { text: t("CANCEL") }, + proceed: { + variant: "primary", + text: t("DISABLE_FACE_SEARCH"), + action: onDisableML, + }, + }); + }; + // TODO-ML: // const [indexingStatus, setIndexingStatus] = useState({ // indexed: 0, @@ -461,28 +445,28 @@ function ManageMLSearch({ )*/ return ( - - - - - + + + + {isPaused ? ( - - + ) : ( - - - - + )} + + + + + + ); -} +}; From f9b8c5287de841ecff885284d883764accfb75dd Mon Sep 17 00:00:00 2001 From: Manav Rathi Date: Wed, 10 Jul 2024 15:51:53 +0530 Subject: [PATCH 30/67] Work towards --- .../new/photos/components/MLSettings.tsx | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/web/packages/new/photos/components/MLSettings.tsx b/web/packages/new/photos/components/MLSettings.tsx index f30ee64b1d..a316fabdf8 100644 --- a/web/packages/new/photos/components/MLSettings.tsx +++ b/web/packages/new/photos/components/MLSettings.tsx @@ -236,9 +236,13 @@ const EnableML: React.FC = ({ onEnable }) => { // openLink("https://ente.io/blog/desktop-ml-beta", true); return ( - - ( - + + + {pt( + "Enable ML (Machine Learning) for face recognition, magic search and other advanced search features", + )} + + @@ -252,7 +256,11 @@ const EnableML: React.FC = ({ onEnable }) => { */} - ) + + {pt( + 'Magic search allows to search photos by their contents (e.g. "car", "red car" or even "ferrari")', + )} + ); }; From 0f4459112ea72dd1e90bbfdd194b4d28f94ddec9 Mon Sep 17 00:00:00 2001 From: Manav Rathi Date: Wed, 10 Jul 2024 15:59:51 +0530 Subject: [PATCH 31/67] Context --- .../new/photos/components/MLSettings.tsx | 21 +++++++------------ 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/web/packages/new/photos/components/MLSettings.tsx b/web/packages/new/photos/components/MLSettings.tsx index a316fabdf8..b52439d785 100644 --- a/web/packages/new/photos/components/MLSettings.tsx +++ b/web/packages/new/photos/components/MLSettings.tsx @@ -232,29 +232,22 @@ interface EnableMLProps { } const EnableML: React.FC = ({ onEnable }) => { - // const showDetails = () => - // openLink("https://ente.io/blog/desktop-ml-beta", true); - - return ( + const showDetails = () => 3; + /*openLink("https://ente.io/blog/desktop-ml-beta", true)*/ return ( {pt( "Enable ML (Machine Learning) for face recognition, magic search and other advanced search features", )} - + - {/* - - */} + + {pt( From 2865b33fc2ce9338934d7c75003d4a4c868c48f8 Mon Sep 17 00:00:00 2001 From: Manav Rathi Date: Wed, 10 Jul 2024 16:01:04 +0530 Subject: [PATCH 32/67] lf --- web/packages/new/photos/components/MLSettings.tsx | 2 +- web/packages/shared/components/DialogBox/types.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/web/packages/new/photos/components/MLSettings.tsx b/web/packages/new/photos/components/MLSettings.tsx index b52439d785..8e010d0ac6 100644 --- a/web/packages/new/photos/components/MLSettings.tsx +++ b/web/packages/new/photos/components/MLSettings.tsx @@ -240,7 +240,7 @@ const EnableML: React.FC = ({ onEnable }) => { "Enable ML (Machine Learning) for face recognition, magic search and other advanced search features", )} - + diff --git a/web/packages/shared/components/DialogBox/types.ts b/web/packages/shared/components/DialogBox/types.ts index 08b52fe4c3..944cd79017 100644 --- a/web/packages/shared/components/DialogBox/types.ts +++ b/web/packages/shared/components/DialogBox/types.ts @@ -1,4 +1,4 @@ -import { ButtonProps } from "@mui/material"; +import type { ButtonProps } from "@mui/material"; export interface DialogBoxAttributes { icon?: React.ReactNode; From d661f4ac1f3f74e95e3aaa893dbb46e0a0a082b0 Mon Sep 17 00:00:00 2001 From: Manav Rathi Date: Wed, 10 Jul 2024 19:14:04 +0530 Subject: [PATCH 33/67] Space --- desktop/src/main/services/ml-clip.ts | 1 + desktop/src/main/services/ml-face.ts | 1 + desktop/src/main/services/ml.ts | 3 ++- 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/desktop/src/main/services/ml-clip.ts b/desktop/src/main/services/ml-clip.ts index ae3470d2c7..cea1d667b5 100644 --- a/desktop/src/main/services/ml-clip.ts +++ b/desktop/src/main/services/ml-clip.ts @@ -3,6 +3,7 @@ * * The embeddings are computed using ONNX runtime, with CLIP as the model. */ + import Tokenizer from "clip-bpe-js"; import * as ort from "onnxruntime-node"; import log from "../log"; diff --git a/desktop/src/main/services/ml-face.ts b/desktop/src/main/services/ml-face.ts index b6fb5c90f3..33c09efaa2 100644 --- a/desktop/src/main/services/ml-face.ts +++ b/desktop/src/main/services/ml-face.ts @@ -6,6 +6,7 @@ * * The runtime used is ONNX. */ + import * as ort from "onnxruntime-node"; import log from "../log"; import { ensure } from "../utils/common"; diff --git a/desktop/src/main/services/ml.ts b/desktop/src/main/services/ml.ts index 6b38bc74dc..55bb8d79c2 100644 --- a/desktop/src/main/services/ml.ts +++ b/desktop/src/main/services/ml.ts @@ -1,5 +1,5 @@ /** - * @file AI/ML related functionality, generic layer. + * @file ML related functionality, generic layer. * * @see also `ml-clip.ts`, `ml-face.ts`. * @@ -10,6 +10,7 @@ * can use the binary ONNX runtime which is 10-20x faster than the WASM based * web one. */ + import { app, net } from "electron/main"; import { existsSync } from "fs"; import fs from "node:fs/promises"; From 10e55b67396b5456130c038204dbfa0a88671205 Mon Sep 17 00:00:00 2001 From: Manav Rathi Date: Wed, 10 Jul 2024 19:27:50 +0530 Subject: [PATCH 34/67] Newer --- web/apps/photos/src/components/Sidebar/index.tsx | 10 +++++----- web/apps/photos/src/utils/billing/index.ts | 4 ++-- web/apps/photos/src/utils/common/index.ts | 10 ---------- web/apps/photos/src/utils/ui/index.tsx | 4 ++-- web/packages/new/photos/components/MLSettings.tsx | 9 ++++++--- web/packages/new/photos/utils/web.ts | 15 ++++++++++++++- 6 files changed, 29 insertions(+), 23 deletions(-) diff --git a/web/apps/photos/src/components/Sidebar/index.tsx b/web/apps/photos/src/components/Sidebar/index.tsx index 3d3f9f964a..9108d29d2e 100644 --- a/web/apps/photos/src/components/Sidebar/index.tsx +++ b/web/apps/photos/src/components/Sidebar/index.tsx @@ -1,4 +1,5 @@ import { openAccountsManagePasskeysPage } from "@/accounts/services/passkey"; +import { initiateEmail, openURL } from "@/new/photos/utils/web"; import { EnteDrawer } from "@/new/shared/components/EnteDrawer"; import log from "@/next/log"; import { savedLogs } from "@/next/log-web"; @@ -73,7 +74,6 @@ import { isSubscriptionCancelled, isSubscriptionPastDue, } from "utils/billing"; -import { openLink } from "utils/common"; import { getDownloadAppMessage } from "utils/ui"; import { isFamilyAdmin, isPartOfFamily } from "utils/user/family"; import { testUpload } from "../../../tests/upload.test"; @@ -594,10 +594,10 @@ const HelpSection: React.FC = () => { const { setDialogMessage } = useContext(AppContext); const { openExportModal } = useContext(GalleryContext); - const openRoadmap = () => - openLink("https://github.com/ente-io/ente/discussions", true); + const requestFeature = () => + openURL("https://github.com/ente-io/ente/discussions"); - const contactSupport = () => openLink("mailto:support@ente.io", true); + const contactSupport = () => initiateEmail("support@ente.io"); function openExport() { if (isElectron()) { @@ -610,7 +610,7 @@ const HelpSection: React.FC = () => { return ( <> diff --git a/web/apps/photos/src/utils/billing/index.ts b/web/apps/photos/src/utils/billing/index.ts index 302baa97ee..2afe4f395f 100644 --- a/web/apps/photos/src/utils/billing/index.ts +++ b/web/apps/photos/src/utils/billing/index.ts @@ -1,3 +1,4 @@ +import { openURL } from "@/new/photos/utils/web"; import log from "@/next/log"; import { SetDialogBoxAttributes } from "@ente/shared/components/DialogBox/types"; import { LS_KEYS, getData } from "@ente/shared/storage/localStorage"; @@ -8,7 +9,6 @@ import billingService from "services/billingService"; import { Plan, Subscription } from "types/billing"; import { SetLoading } from "types/gallery"; import { BonusData, UserDetails } from "types/user"; -import { openLink } from "utils/common"; import { getSubscriptionPurchaseSuccessMessage } from "utils/ui"; import { getTotalFamilyUsage, isPartOfFamily } from "utils/user/family"; @@ -220,7 +220,7 @@ export async function manageFamilyMethod( try { setLoading(true); const familyPortalRedirectURL = getRedirectURL(REDIRECTS.FAMILIES); - openLink(familyPortalRedirectURL, true); + openURL(familyPortalRedirectURL); } catch (e) { log.error("failed to redirect to family portal", e); setDialogMessage({ diff --git a/web/apps/photos/src/utils/common/index.ts b/web/apps/photos/src/utils/common/index.ts index 9de9f54c41..91628f98c4 100644 --- a/web/apps/photos/src/utils/common/index.ts +++ b/web/apps/photos/src/utils/common/index.ts @@ -6,16 +6,6 @@ export const preloadImage = (imgBasePath: string) => { new Image().srcset = srcSet.join(","); }; -export function openLink(href: string, newTab?: boolean) { - const a = document.createElement("a"); - a.href = href; - if (newTab) { - a.target = "_blank"; - } - a.rel = "noreferrer noopener"; - a.click(); -} - export function isClipboardItemPresent() { return typeof ClipboardItem !== "undefined"; } diff --git a/web/apps/photos/src/utils/ui/index.tsx b/web/apps/photos/src/utils/ui/index.tsx index c930f47c8c..f8c0d6cb12 100644 --- a/web/apps/photos/src/utils/ui/index.tsx +++ b/web/apps/photos/src/utils/ui/index.tsx @@ -1,3 +1,4 @@ +import { openURL } from "@/new/photos/utils/web"; import { ensureElectron } from "@/next/electron"; import { AppUpdate } from "@/next/types/ipc"; import { DialogBoxAttributes } from "@ente/shared/components/DialogBox/types"; @@ -7,7 +8,6 @@ import { Link } from "@mui/material"; import { t } from "i18next"; import { Trans } from "react-i18next"; import { Subscription } from "types/billing"; -import { openLink } from "utils/common"; export const getDownloadAppMessage = (): DialogBoxAttributes => { return { @@ -25,7 +25,7 @@ export const getDownloadAppMessage = (): DialogBoxAttributes => { }; }; -const downloadApp = () => openLink("https://ente.io/download/desktop", true); +const downloadApp = () => openURL("https://ente.io/download/desktop"); export const getTrashFilesMessage = ( deleteFileHelper, diff --git a/web/packages/new/photos/components/MLSettings.tsx b/web/packages/new/photos/components/MLSettings.tsx index 8e010d0ac6..96d9be767b 100644 --- a/web/packages/new/photos/components/MLSettings.tsx +++ b/web/packages/new/photos/components/MLSettings.tsx @@ -28,6 +28,7 @@ import { t } from "i18next"; import React, { useEffect, useState } from "react"; import { Trans } from "react-i18next"; import type { NewAppContextPhotos } from "../types/context"; +import { openURL } from "../utils/web"; interface MLSettingsProps { /** If `true`, then this drawer page is shown. */ @@ -232,8 +233,10 @@ interface EnableMLProps { } const EnableML: React.FC = ({ onEnable }) => { - const showDetails = () => 3; - /*openLink("https://ente.io/blog/desktop-ml-beta", true)*/ return ( + // TODO-ML: Update link. + const moreDetails = () => openURL("https://ente.io/blog/desktop-ml-beta"); + + return ( {pt( @@ -245,7 +248,7 @@ const EnableML: React.FC = ({ onEnable }) => { {t("ENABLE")} - diff --git a/web/packages/new/photos/utils/web.ts b/web/packages/new/photos/utils/web.ts index 18f72bd61e..7236cab798 100644 --- a/web/packages/new/photos/utils/web.ts +++ b/web/packages/new/photos/utils/web.ts @@ -1,3 +1,16 @@ +/** + * Open the given {@link url} in a new browser tab. + * + * @param url The URL to open. + */ +export const openURL = (url: string) => { + const a = document.createElement("a"); + a.href = url; + a.target = "_blank"; + a.rel = "noopener"; + a.click(); +}; + /** * Open the system configured email client, initiating a new email to the given * {@link email} address. @@ -5,6 +18,6 @@ export const initiateEmail = (email: string) => { const a = document.createElement("a"); a.href = "mailto:" + email; - a.rel = "noreferrer noopener"; + a.rel = "noopener"; a.click(); }; From 9616640fce7cc60cdb92aa06c25fb2d816652291 Mon Sep 17 00:00:00 2001 From: Manav Rathi Date: Wed, 10 Jul 2024 19:34:46 +0530 Subject: [PATCH 35/67] Fix p nesting warning --- web/packages/new/photos/components/MLSettings.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/packages/new/photos/components/MLSettings.tsx b/web/packages/new/photos/components/MLSettings.tsx index 96d9be767b..7c29c67e52 100644 --- a/web/packages/new/photos/components/MLSettings.tsx +++ b/web/packages/new/photos/components/MLSettings.tsx @@ -304,7 +304,7 @@ const FaceConsent: React.FC = ({ onRootClose={handleRootClose} /> - + Date: Wed, 10 Jul 2024 19:42:13 +0530 Subject: [PATCH 36/67] Modify --- web/packages/new/photos/components/MLSettings.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/web/packages/new/photos/components/MLSettings.tsx b/web/packages/new/photos/components/MLSettings.tsx index 7c29c67e52..9e0c2e0f81 100644 --- a/web/packages/new/photos/components/MLSettings.tsx +++ b/web/packages/new/photos/components/MLSettings.tsx @@ -460,14 +460,14 @@ const ManageML: React.FC = ({ ) : ( )} From b0b82aabd8bcf09c8d13c8faf866b86d844260b2 Mon Sep 17 00:00:00 2001 From: Manav Rathi Date: Wed, 10 Jul 2024 20:03:52 +0530 Subject: [PATCH 37/67] Face => ML --- .../new/photos/components/MLSettings.tsx | 24 ++++++++++--------- web/packages/new/photos/types/context.ts | 5 ++-- 2 files changed, 15 insertions(+), 14 deletions(-) diff --git a/web/packages/new/photos/components/MLSettings.tsx b/web/packages/new/photos/components/MLSettings.tsx index 9e0c2e0f81..5925464113 100644 --- a/web/packages/new/photos/components/MLSettings.tsx +++ b/web/packages/new/photos/components/MLSettings.tsx @@ -48,10 +48,10 @@ export const MLSettings: React.FC = ({ appContext, }) => { const { - setDialogMessage, - somethingWentWrong, startLoading, finishLoading, + setDialogBoxAttributesV2, + somethingWentWrong, } = appContext; /** @@ -169,11 +169,10 @@ export const MLSettings: React.FC = ({ disabled: , enabledOrPaused: ( ), }; @@ -374,7 +373,7 @@ interface ManageMLProps { /** Called when the user wants to disable ML. */ onDisableML: () => void; /** Subset of appContext. */ - setDialogMessage: NewAppContextPhotos["setDialogMessage"]; + setDialogBoxAttributesV2: NewAppContextPhotos["setDialogBoxAttributesV2"]; } const ManageML: React.FC = ({ @@ -382,22 +381,25 @@ const ManageML: React.FC = ({ onPauseML, onResumeML, onDisableML, - setDialogMessage, + setDialogBoxAttributesV2, }) => { const confirmDisableML = () => { - setDialogMessage({ - title: t("DISABLE_FACE_SEARCH_TITLE"), + setDialogBoxAttributesV2({ + title: pt("Disable ML search"), content: ( - + {pt( + "Do you want to disable ML search on all your devices?", + )} ), close: { text: t("CANCEL") }, proceed: { - variant: "primary", - text: t("DISABLE_FACE_SEARCH"), + variant: "critical", + text: pt("Disable"), action: onDisableML, }, + buttonDirection: "row" }); }; diff --git a/web/packages/new/photos/types/context.ts b/web/packages/new/photos/types/context.ts index d864717146..6076bc22a7 100644 --- a/web/packages/new/photos/types/context.ts +++ b/web/packages/new/photos/types/context.ts @@ -1,4 +1,4 @@ -import type { SetDialogBoxAttributes } from "@ente/shared/components/DialogBox/types"; +import type { DialogBoxAttributesV2 } from "@ente/shared/components/DialogBoxV2/types"; /** * A subset of the AppContext type used by the photos app. @@ -13,7 +13,6 @@ import type { SetDialogBoxAttributes } from "@ente/shared/components/DialogBox/t export interface NewAppContextPhotos { startLoading: () => void; finishLoading: () => void; - closeMessageDialog: () => void; - setDialogMessage: SetDialogBoxAttributes; + setDialogBoxAttributesV2: (attrs: DialogBoxAttributesV2) => void; somethingWentWrong: () => void; } From 44e165b8ee4eeb81c1352a3d380de7435baf9b67 Mon Sep 17 00:00:00 2001 From: Manav Rathi Date: Wed, 10 Jul 2024 20:24:52 +0530 Subject: [PATCH 38/67] Rework --- .../new/photos/components/MLSettings.tsx | 86 +++++++++---------- 1 file changed, 40 insertions(+), 46 deletions(-) diff --git a/web/packages/new/photos/components/MLSettings.tsx b/web/packages/new/photos/components/MLSettings.tsx index 5925464113..4baaa7a2ff 100644 --- a/web/packages/new/photos/components/MLSettings.tsx +++ b/web/packages/new/photos/components/MLSettings.tsx @@ -64,20 +64,16 @@ export const MLSettings: React.FC = ({ | "loading" /* fetching the data we need from the lower layers */ | "notEligible" /* user is not in the beta program */ | "disabled" /* eligible, but ML is currently disabled */ - | "enabledOrPaused"; /* ML is enabled, but may be paused (See isPaused) */ + | "enabled"; /* ML is enabled, but may be paused locally */ const [status, setStatus] = useState("loading"); const [openFaceConsent, setOpenFaceConsent] = useState(false); - /** Only valid when status is "enabledOrPaused" */ - const [isPaused, setIsPaused] = useState(false); + const [isEnabledLocal, setIsEnabledLocal] = useState(false); const refreshStatus = async () => { - if (isMLEnabled()) { - setStatus("enabledOrPaused"); - setIsPaused(false); - } else if (await getIsMLEnabledRemote()) { - setStatus("enabledOrPaused"); - setIsPaused(true); + if (isMLEnabled() || (await getIsMLEnabledRemote())) { + setStatus("enabled"); + setIsEnabledLocal(isMLEnabled()); } else if (await canEnableML()) { setStatus("disabled"); } else { @@ -112,8 +108,8 @@ export const MLSettings: React.FC = ({ setOpenFaceConsent(true); } else { await enableML(); - setStatus("enabledOrPaused"); - setIsPaused(false); + setStatus("enabled"); + setIsEnabledLocal(isMLEnabled()); } } catch (e) { log.error("Failed to enable or resume ML", e); @@ -127,8 +123,8 @@ export const MLSettings: React.FC = ({ startLoading(); try { await enableML(); - setStatus("enabledOrPaused"); - setIsPaused(false); + setStatus("enabled"); + setIsEnabledLocal(isMLEnabled()); // Close the FaceConsent drawer, come back to ourselves. setOpenFaceConsent(false); } catch (e) { @@ -139,13 +135,12 @@ export const MLSettings: React.FC = ({ } }; - const handlePauseML = () => { + const handleToggleLocal = async () => { try { - pauseML(); - setStatus("enabledOrPaused"); - setIsPaused(true); + isMLEnabled() ? pauseML() : await handleEnableOrResumeML(); + setIsEnabledLocal(isMLEnabled()); } catch (e) { - log.error("Failed to enable ML", e); + log.error("Failed to toggle local state of ML", e); somethingWentWrong(); } }; @@ -167,11 +162,10 @@ export const MLSettings: React.FC = ({ loading: , notEligible: , disabled: , - enabledOrPaused: ( + enabled: ( ), @@ -364,12 +358,10 @@ const FaceConsent: React.FC = ({ }; interface ManageMLProps { - /** `true` if ML is locally paused. */ - isPaused: boolean; - /** Called when the user wants to pause ML. */ - onPauseML: () => void; - /** Called when the user wants to resume ML. */ - onResumeML: () => void; + /** `true` if ML is enabled locally (in addition to remote). */ + isEnabledLocal: boolean; + /** Called when the user wants to toggle the ML status locally. */ + onToggleLocal: () => void; /** Called when the user wants to disable ML. */ onDisableML: () => void; /** Subset of appContext. */ @@ -377,9 +369,8 @@ interface ManageMLProps { } const ManageML: React.FC = ({ - isPaused, - onPauseML, - onResumeML, + isEnabledLocal, + onToggleLocal, onDisableML, setDialogBoxAttributesV2, }) => { @@ -399,7 +390,7 @@ const ManageML: React.FC = ({ text: pt("Disable"), action: onDisableML, }, - buttonDirection: "row" + buttonDirection: "row", }); }; @@ -450,28 +441,31 @@ const ManageML: React.FC = ({ )*/ + console.log("rendering", isEnabledLocal, isMLEnabled()); return ( - {isPaused ? ( - - ) : ( - - )} + - + + {/* - + */} ); From 7069e15b79a33f21c8b2d423d81b151eaff5959d Mon Sep 17 00:00:00 2001 From: Manav Rathi Date: Wed, 10 Jul 2024 20:49:19 +0530 Subject: [PATCH 39/67] Duals --- .../new/photos/components/MLSettings.tsx | 22 +++++++------------ 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/web/packages/new/photos/components/MLSettings.tsx b/web/packages/new/photos/components/MLSettings.tsx index 4baaa7a2ff..a5bf59ae29 100644 --- a/web/packages/new/photos/components/MLSettings.tsx +++ b/web/packages/new/photos/components/MLSettings.tsx @@ -441,10 +441,17 @@ const ManageML: React.FC = ({ )*/ - console.log("rendering", isEnabledLocal, isMLEnabled()); return ( + + + = ({ onClick={onToggleLocal} /> - - {/* - - */} ); From 5fef9b21e59b4f3933a4c647f3b9cef530f84de2 Mon Sep 17 00:00:00 2001 From: Manav Rathi Date: Thu, 11 Jul 2024 10:00:54 +0530 Subject: [PATCH 40/67] Template --- .../new/photos/components/MLSettings.tsx | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/web/packages/new/photos/components/MLSettings.tsx b/web/packages/new/photos/components/MLSettings.tsx index a5bf59ae29..578a388399 100644 --- a/web/packages/new/photos/components/MLSettings.tsx +++ b/web/packages/new/photos/components/MLSettings.tsx @@ -21,6 +21,7 @@ import { FormControlLabel, FormGroup, Link, + Paper, Stack, Typography, } from "@mui/material"; @@ -442,8 +443,8 @@ const ManageML: React.FC = ({ )*/ return ( - - + + = ({ /> - + + + + Status + Indexing + + + Processed + 34 / 133 + + + + ); }; From 6086e139e436bb80339721b39d792857edf35270 Mon Sep 17 00:00:00 2001 From: Manav Rathi Date: Thu, 11 Jul 2024 10:06:52 +0530 Subject: [PATCH 41/67] Degrade gracefully --- web/packages/new/photos/components/MLSettings.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/web/packages/new/photos/components/MLSettings.tsx b/web/packages/new/photos/components/MLSettings.tsx index 578a388399..3502739a54 100644 --- a/web/packages/new/photos/components/MLSettings.tsx +++ b/web/packages/new/photos/components/MLSettings.tsx @@ -464,13 +464,13 @@ const ManageML: React.FC = ({ - + Status Indexing - + Processed - 34 / 133 + 33,000,000 / 13,000,000 From 6f577d150a3d9cce08b87f2732573dd03658caf3 Mon Sep 17 00:00:00 2001 From: Manav Rathi Date: Thu, 11 Jul 2024 10:37:57 +0530 Subject: [PATCH 42/67] wip useSyncExternalStore --- .../new/photos/components/MLSettings.tsx | 19 +++++-- web/packages/new/photos/services/ml/index.ts | 52 ++++++++++++++++--- 2 files changed, 60 insertions(+), 11 deletions(-) diff --git a/web/packages/new/photos/components/MLSettings.tsx b/web/packages/new/photos/components/MLSettings.tsx index 3502739a54..34b1284287 100644 --- a/web/packages/new/photos/components/MLSettings.tsx +++ b/web/packages/new/photos/components/MLSettings.tsx @@ -26,7 +26,7 @@ import { Typography, } from "@mui/material"; import { t } from "i18next"; -import React, { useEffect, useState } from "react"; +import React, { useEffect, useState, useSyncExternalStore } from "react"; import { Trans } from "react-i18next"; import type { NewAppContextPhotos } from "../types/context"; import { openURL } from "../utils/web"; @@ -375,6 +375,7 @@ const ManageML: React.FC = ({ onDisableML, setDialogBoxAttributesV2, }) => { + const status = useSyncExternalStore(); const confirmDisableML = () => { setDialogBoxAttributesV2({ title: pt("Disable ML search"), @@ -464,13 +465,23 @@ const ManageML: React.FC = ({ - + Status Indexing - + Processed - 33,000,000 / 13,000,000 + + 33,000,000 / 13,000,000 + diff --git a/web/packages/new/photos/services/ml/index.ts b/web/packages/new/photos/services/ml/index.ts index 9e6c3fdda5..683b6fd8d7 100644 --- a/web/packages/new/photos/services/ml/index.ts +++ b/web/packages/new/photos/services/ml/index.ts @@ -35,6 +35,13 @@ let _isMLEnabled = false; /** Cached instance of the {@link ComlinkWorker} that wraps our web worker. */ let _comlinkWorker: ComlinkWorker | undefined; +/** + * Subscriptions to {@link MLStatus}. + * + * See {@link mlStatusSubscribe}. + */ +let _mlStatusListeners: (() => void)[] = []; + /** Lazily created, cached, instance of {@link MLWorker}. */ const worker = async () => { if (!_comlinkWorker) _comlinkWorker = await createComlinkWorker(); @@ -89,6 +96,7 @@ export const logoutML = async () => { // contexts], it gets called first in the logout sequence, and then this // function (`logoutML`) gets called at a later point in time. _isMLEnabled = false; + _mlStatusListeners = []; await clearMLDB(); }; @@ -193,7 +201,15 @@ const setIsMLEnabledLocally = (enabled: boolean) => * Now it tracks the status of ML in general (which includes faces + consent). */ const mlRemoteKey = "faceSearchEnabled"; + +/** + * Return `true` if the flag to enable ML is set on remote. + */ export const getIsMLEnabledRemote = () => getRemoteFlag(mlRemoteKey); + +/** + * Update the remote flag that tracks ML status across the user's devices. + */ const updateIsMLEnabledRemote = (enabled: boolean) => updateRemoteFlag(mlRemoteKey, enabled); @@ -234,41 +250,63 @@ export const indexNewUpload = (enteFile: EnteFile, uploadItem: UploadItem) => { void worker().then((w) => w.onUpload(enteFile, uploadItem)); }; -export interface FaceIndexingStatus { +export interface MLStatus { /** * Which phase we are in within the indexing pipeline when viewed across the * user's entire library: * + * - "paused": ML is currently paused on this device. + * * - "scheduled": There are files we know of that have not been indexed. * - * - "indexing": The face indexer is currently running. + * - "indexing": The indexer is currently running. * - * - "clustering": All files we know of have been indexed, and we are now + * - "clustering": All file we know of have been indexed, and we are now * clustering the faces that were found. * - * - "done": Face indexing and clustering is complete for the user's + * - "done": ML indexing and face clustering is complete for the user's * library. */ - phase: "scheduled" | "indexing" | "clustering" | "done"; + phase: "paused" | "scheduled" | "indexing" | "clustering" | "done"; /** The number of files that have already been indexed. */ nSyncedFiles: number; /** The total number of files that are eligible for indexing. */ nTotalFiles: number; } +/** + * A function that can be used to subscribe to updates in the ML status. + * + * This, along with {@link mlStatusSnapshot}, are meant to be used as arguments + * to React's {@link useSyncExternalStore}. + * + * @param callback A function that will be invoked whenever the result of + * {@link mlStatusSnapshot} changes. + * + * @returns A function that can be used to clear the subscription. + */ +export const mlStatusSubscribe = (onChange: () => void): (() => void) => { + _mlStatusListeners.push(onChange); + return () => { + _mlStatusListeners = _mlStatusListeners.filter((v) => v != onChange); + }; +}; + + + /** * Return the current state of the face indexing pipeline. * * Precondition: ML must be enabled. */ -export const faceIndexingStatus = async (): Promise => { +export const faceIndexingStatus = async (): Promise => { if (!isMLEnabled()) throw new Error("Cannot get indexing status when ML is not enabled"); const { indexedCount, indexableCount } = await indexableAndIndexedCounts(); const isIndexing = await (await worker()).isIndexing(); - let phase: FaceIndexingStatus["phase"]; + let phase: MLStatus["phase"]; if (indexableCount > 0) { phase = !isIndexing ? "scheduled" : "indexing"; } else { From 661d0383fbbbf339a3d4fb3edbd44f168635f30b Mon Sep 17 00:00:00 2001 From: Manav Rathi Date: Thu, 11 Jul 2024 10:41:37 +0530 Subject: [PATCH 43/67] Scaffold --- web/packages/new/photos/services/ml/index.ts | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/web/packages/new/photos/services/ml/index.ts b/web/packages/new/photos/services/ml/index.ts index 683b6fd8d7..663541a3e0 100644 --- a/web/packages/new/photos/services/ml/index.ts +++ b/web/packages/new/photos/services/ml/index.ts @@ -42,6 +42,13 @@ let _comlinkWorker: ComlinkWorker | undefined; */ let _mlStatusListeners: (() => void)[] = []; +/** + * Snapshot of {@link MLStatus}. + * + * See {@link mlStatusSnapshot}. + */ +let _mlStatusSnapshot: MLStatus | undefined; + /** Lazily created, cached, instance of {@link MLWorker}. */ const worker = async () => { if (!_comlinkWorker) _comlinkWorker = await createComlinkWorker(); @@ -97,6 +104,7 @@ export const logoutML = async () => { // function (`logoutML`) gets called at a later point in time. _isMLEnabled = false; _mlStatusListeners = []; + _mlStatusSnapshot = undefined; await clearMLDB(); }; @@ -292,7 +300,16 @@ export const mlStatusSubscribe = (onChange: () => void): (() => void) => { }; }; +export const mlStatusSnapshot = (): MLStatus => + (_mlStatusSnapshot ??= getMLStatus()); +const getMLStatus = (): MLStatus => { + return { + phase: "paused", + nSyncedFiles: 0, + nTotalFiles: 0, + }; +}; /** * Return the current state of the face indexing pipeline. From df4364525d21562cf8a2e379ed3de09d908d89ec Mon Sep 17 00:00:00 2001 From: Manav Rathi Date: Thu, 11 Jul 2024 11:00:22 +0530 Subject: [PATCH 44/67] Hook it up --- .../new/photos/components/MLSettings.tsx | 22 ++++--- web/packages/new/photos/services/ml/index.ts | 57 ++++++++++++------- 2 files changed, 46 insertions(+), 33 deletions(-) diff --git a/web/packages/new/photos/components/MLSettings.tsx b/web/packages/new/photos/components/MLSettings.tsx index 34b1284287..35c8a2585f 100644 --- a/web/packages/new/photos/components/MLSettings.tsx +++ b/web/packages/new/photos/components/MLSettings.tsx @@ -4,6 +4,8 @@ import { enableML, getIsMLEnabledRemote, isMLEnabled, + mlStatusSnapshot, + mlStatusSubscribe, pauseML, } from "@/new/photos/services/ml"; import { EnteDrawer } from "@/new/shared/components/EnteDrawer"; @@ -69,12 +71,10 @@ export const MLSettings: React.FC = ({ const [status, setStatus] = useState("loading"); const [openFaceConsent, setOpenFaceConsent] = useState(false); - const [isEnabledLocal, setIsEnabledLocal] = useState(false); const refreshStatus = async () => { if (isMLEnabled() || (await getIsMLEnabledRemote())) { setStatus("enabled"); - setIsEnabledLocal(isMLEnabled()); } else if (await canEnableML()) { setStatus("disabled"); } else { @@ -110,7 +110,6 @@ export const MLSettings: React.FC = ({ } else { await enableML(); setStatus("enabled"); - setIsEnabledLocal(isMLEnabled()); } } catch (e) { log.error("Failed to enable or resume ML", e); @@ -125,7 +124,6 @@ export const MLSettings: React.FC = ({ try { await enableML(); setStatus("enabled"); - setIsEnabledLocal(isMLEnabled()); // Close the FaceConsent drawer, come back to ourselves. setOpenFaceConsent(false); } catch (e) { @@ -139,7 +137,6 @@ export const MLSettings: React.FC = ({ const handleToggleLocal = async () => { try { isMLEnabled() ? pauseML() : await handleEnableOrResumeML(); - setIsEnabledLocal(isMLEnabled()); } catch (e) { log.error("Failed to toggle local state of ML", e); somethingWentWrong(); @@ -165,7 +162,7 @@ export const MLSettings: React.FC = ({ disabled: , enabled: ( @@ -359,8 +356,6 @@ const FaceConsent: React.FC = ({ }; interface ManageMLProps { - /** `true` if ML is enabled locally (in addition to remote). */ - isEnabledLocal: boolean; /** Called when the user wants to toggle the ML status locally. */ onToggleLocal: () => void; /** Called when the user wants to disable ML. */ @@ -370,12 +365,15 @@ interface ManageMLProps { } const ManageML: React.FC = ({ - isEnabledLocal, onToggleLocal, onDisableML, setDialogBoxAttributesV2, }) => { - const status = useSyncExternalStore(); + const { phase, nSyncedFiles, nTotalFiles } = useSyncExternalStore( + mlStatusSubscribe, + mlStatusSnapshot, + ); + const confirmDisableML = () => { setDialogBoxAttributesV2({ title: pt("Disable ML search"), @@ -458,7 +456,7 @@ const ManageML: React.FC = ({ @@ -480,7 +478,7 @@ const ManageML: React.FC = ({ > Processed - 33,000,000 / 13,000,000 + {`${nSyncedFiles} / ${nTotalFiles}`} diff --git a/web/packages/new/photos/services/ml/index.ts b/web/packages/new/photos/services/ml/index.ts index 663541a3e0..a90a30c577 100644 --- a/web/packages/new/photos/services/ml/index.ts +++ b/web/packages/new/photos/services/ml/index.ts @@ -42,12 +42,25 @@ let _comlinkWorker: ComlinkWorker | undefined; */ let _mlStatusListeners: (() => void)[] = []; +/** + * Type-wise, we should''ve used undefined to indicate that we don't yet have a + * snapshot, but that would make the {@link mlStatusSnapshot} async, + * complicating its usage with React's {@link useSyncExternalStore}. + * + * So instead this value stands in for an `undefined` {@link MLStatus}. + */ +const placeholderMLStatus: MLStatus = { + phase: "paused", + nSyncedFiles: 0, + nTotalFiles: 0, +}; + /** * Snapshot of {@link MLStatus}. * * See {@link mlStatusSnapshot}. */ -let _mlStatusSnapshot: MLStatus | undefined; +let _mlStatusSnapshot = placeholderMLStatus; /** Lazily created, cached, instance of {@link MLWorker}. */ const worker = async () => { @@ -104,7 +117,7 @@ export const logoutML = async () => { // function (`logoutML`) gets called at a later point in time. _isMLEnabled = false; _mlStatusListeners = []; - _mlStatusSnapshot = undefined; + _mlStatusSnapshot = placeholderMLStatus; await clearMLDB(); }; @@ -295,39 +308,41 @@ export interface MLStatus { */ export const mlStatusSubscribe = (onChange: () => void): (() => void) => { _mlStatusListeners.push(onChange); + // Unconditionally update the snapshot. + void updateMLStatusSnapshot(); return () => { - _mlStatusListeners = _mlStatusListeners.filter((v) => v != onChange); + _mlStatusListeners = _mlStatusListeners.filter((l) => l != onChange); }; }; -export const mlStatusSnapshot = (): MLStatus => - (_mlStatusSnapshot ??= getMLStatus()); +export const mlStatusSnapshot = (): MLStatus => _mlStatusSnapshot; -const getMLStatus = (): MLStatus => { - return { - phase: "paused", - nSyncedFiles: 0, - nTotalFiles: 0, - }; +export const updateMLStatusSnapshot = async () => { + const status = await getMLStatus(); + _mlStatusSnapshot = status; + _mlStatusListeners.forEach((l) => l()); }; /** - * Return the current state of the face indexing pipeline. + * Return the current state of the ML subsystem. * - * Precondition: ML must be enabled. + * Precondition: ML must be enabled on remote, though it is fine if it is paused + * locally. */ -export const faceIndexingStatus = async (): Promise => { - if (!isMLEnabled()) - throw new Error("Cannot get indexing status when ML is not enabled"); - +export const getMLStatus = async (): Promise => { const { indexedCount, indexableCount } = await indexableAndIndexedCounts(); - const isIndexing = await (await worker()).isIndexing(); let phase: MLStatus["phase"]; - if (indexableCount > 0) { - phase = !isIndexing ? "scheduled" : "indexing"; + if (!isMLEnabled()) { + phase = "paused"; } else { - phase = "done"; + const isIndexing = await (await worker()).isIndexing(); + + if (indexableCount > 0) { + phase = !isIndexing ? "scheduled" : "indexing"; + } else { + phase = "done"; + } } return { From 2e1fde906ea34992d5548b5e87fd7ecf5579a749 Mon Sep 17 00:00:00 2001 From: Manav Rathi Date: Thu, 11 Jul 2024 11:15:53 +0530 Subject: [PATCH 45/67] The type annotation for _mlStatusSnapshot is required --- web/packages/new/photos/services/ml/index.ts | 53 +++++++++++--------- 1 file changed, 28 insertions(+), 25 deletions(-) diff --git a/web/packages/new/photos/services/ml/index.ts b/web/packages/new/photos/services/ml/index.ts index a90a30c577..68e8c0ce0f 100644 --- a/web/packages/new/photos/services/ml/index.ts +++ b/web/packages/new/photos/services/ml/index.ts @@ -60,7 +60,7 @@ const placeholderMLStatus: MLStatus = { * * See {@link mlStatusSnapshot}. */ -let _mlStatusSnapshot = placeholderMLStatus; +let _mlStatusSnapshot: MLStatus = placeholderMLStatus; /** Lazily created, cached, instance of {@link MLWorker}. */ const worker = async () => { @@ -271,29 +271,31 @@ export const indexNewUpload = (enteFile: EnteFile, uploadItem: UploadItem) => { void worker().then((w) => w.onUpload(enteFile, uploadItem)); }; -export interface MLStatus { - /** - * Which phase we are in within the indexing pipeline when viewed across the - * user's entire library: - * - * - "paused": ML is currently paused on this device. - * - * - "scheduled": There are files we know of that have not been indexed. - * - * - "indexing": The indexer is currently running. - * - * - "clustering": All file we know of have been indexed, and we are now - * clustering the faces that were found. - * - * - "done": ML indexing and face clustering is complete for the user's - * library. - */ - phase: "paused" | "scheduled" | "indexing" | "clustering" | "done"; - /** The number of files that have already been indexed. */ - nSyncedFiles: number; - /** The total number of files that are eligible for indexing. */ - nTotalFiles: number; -} +export type MLStatus = + | { phase: "disabled" /* The ML remote flag is off */ } + | { + /** + * Which phase we are in within the indexing pipeline when viewed across the + * user's entire library: + * + * - "paused": ML is currently paused on this device. + * + * - "scheduled": There are files we know of that have not been indexed. + * + * - "indexing": The indexer is currently running. + * + * - "clustering": All file we know of have been indexed, and we are now + * clustering the faces that were found. + * + * - "done": ML indexing and face clustering is complete for the user's + * library. + */ + phase: "paused" | "scheduled" | "indexing" | "clustering" | "done"; + /** The number of files that have already been indexed. */ + nSyncedFiles: number; + /** The total number of files that are eligible for indexing. */ + nTotalFiles: number; + }; /** * A function that can be used to subscribe to updates in the ML status. @@ -334,7 +336,8 @@ export const getMLStatus = async (): Promise => { let phase: MLStatus["phase"]; if (!isMLEnabled()) { - phase = "paused"; + phase = "disabled"; + return { phase }; } else { const isIndexing = await (await worker()).isIndexing(); From 0214ccf680c07df5b22d1c3121c381804d185c7b Mon Sep 17 00:00:00 2001 From: Manav Rathi Date: Thu, 11 Jul 2024 11:43:49 +0530 Subject: [PATCH 46/67] Integrate --- web/packages/new/photos/services/ml/index.ts | 111 ++++++++++++------- 1 file changed, 71 insertions(+), 40 deletions(-) diff --git a/web/packages/new/photos/services/ml/index.ts b/web/packages/new/photos/services/ml/index.ts index 68e8c0ce0f..d310f1ea8e 100644 --- a/web/packages/new/photos/services/ml/index.ts +++ b/web/packages/new/photos/services/ml/index.ts @@ -30,7 +30,16 @@ import { MLWorker } from "./worker"; * * - It is cleared in {@link logoutML}. */ -let _isMLEnabled = false; +let _isMLEnabledLocal = false; + +/** + * In-memory flag that tracks if the remote flag for ML is set. + * + * - It is updated each time we sync the status with remote. + * + * - It is cleared in {@link logoutML}. + */ +let _isMLEnabledRemote: boolean | undefined; /** Cached instance of the {@link ComlinkWorker} that wraps our web worker. */ let _comlinkWorker: ComlinkWorker | undefined; @@ -42,25 +51,12 @@ let _comlinkWorker: ComlinkWorker | undefined; */ let _mlStatusListeners: (() => void)[] = []; -/** - * Type-wise, we should''ve used undefined to indicate that we don't yet have a - * snapshot, but that would make the {@link mlStatusSnapshot} async, - * complicating its usage with React's {@link useSyncExternalStore}. - * - * So instead this value stands in for an `undefined` {@link MLStatus}. - */ -const placeholderMLStatus: MLStatus = { - phase: "paused", - nSyncedFiles: 0, - nTotalFiles: 0, -}; - /** * Snapshot of {@link MLStatus}. * * See {@link mlStatusSnapshot}. */ -let _mlStatusSnapshot: MLStatus = placeholderMLStatus; +let _mlStatusSnapshot: MLStatus | undefined; /** Lazily created, cached, instance of {@link MLWorker}. */ const worker = async () => { @@ -107,7 +103,7 @@ export const terminateMLWorker = () => { export const initML = () => { // ML currently only works when we're running in our desktop app. if (!isDesktop) return; - _isMLEnabled = isMLEnabledLocally(); + _isMLEnabledLocal = isMLEnabledLocally(); }; export const logoutML = async () => { @@ -115,9 +111,10 @@ export const logoutML = async () => { // reasons mentioned in [Note: Caching IDB instances in separate execution // contexts], it gets called first in the logout sequence, and then this // function (`logoutML`) gets called at a later point in time. - _isMLEnabled = false; + _isMLEnabledLocal = false; + _isMLEnabledRemote = undefined; _mlStatusListeners = []; - _mlStatusSnapshot = placeholderMLStatus; + _mlStatusSnapshot = undefined; await clearMLDB(); }; @@ -145,8 +142,8 @@ export const canEnableML = async () => * true if ML is enabled locally (which implies it is also enabled on remote). */ export const isMLEnabled = () => - // Implementation note: Keep it fast, the UI directly calls this many times. - _isMLEnabled; + // Implementation note: Keep it fast, it might be called frequently. + _isMLEnabledLocal; /** * Enable ML. @@ -156,7 +153,9 @@ export const isMLEnabled = () => export const enableML = async () => { await updateIsMLEnabledRemote(true); setIsMLEnabledLocally(true); - _isMLEnabled = true; + _isMLEnabledRemote = true; + _isMLEnabledLocal = true; + triggerStatusUpdate(); triggerMLSync(); }; @@ -170,7 +169,9 @@ export const disableML = async () => { await updateIsMLEnabledRemote(false); terminateMLWorker(); setIsMLEnabledLocally(false); - _isMLEnabled = false; + _isMLEnabledRemote = false; + _isMLEnabledLocal = false; + triggerStatusUpdate(); }; /** @@ -181,7 +182,8 @@ export const disableML = async () => { export const pauseML = () => { terminateMLWorker(); setIsMLEnabledLocally(false); - _isMLEnabled = false; + _isMLEnabledLocal = false; + triggerStatusUpdate(); }; /** @@ -191,7 +193,8 @@ export const pauseML = () => { */ export const resumeML = () => { setIsMLEnabledLocally(true); - _isMLEnabled = true; + _isMLEnabledLocal = true; + triggerStatusUpdate(); triggerMLSync(); }; @@ -237,16 +240,25 @@ const updateIsMLEnabledRemote = (enabled: boolean) => /** * Trigger a "sync", whatever that means for the ML subsystem. * - * This is called during the global sync sequence. If ML is enabled, then we use - * this as a signal to pull embeddings from remote, and start backfilling if - * needed. + * This is called during the global sync sequence. + * + * First we check again with remote ML flag is set. If it is not set, then we + * disable ML locally too. + * + * Otherwise, and if ML is enabled locally also, then we use this as a signal to + * pull embeddings from remote, and start backfilling if needed. * * This function does not wait for these processes to run to completion, and * returns immediately. */ -export const triggerMLSync = () => { - if (!_isMLEnabled) return; - void worker().then((w) => w.sync()); +export const triggerMLSync = () => void mlSync(); + +const mlSync = async () => { + _isMLEnabledRemote = await getIsMLEnabledRemote(); + if (!_isMLEnabledRemote) _isMLEnabledLocal = false; + triggerStatusUpdate(); + + if (_isMLEnabledLocal) void worker().then((w) => w.sync()); }; /** @@ -265,7 +277,7 @@ export const triggerMLSync = () => { * image part of the live photo that was uploaded. */ export const indexNewUpload = (enteFile: EnteFile, uploadItem: UploadItem) => { - if (!_isMLEnabled) return; + if (!_isMLEnabledLocal) return; if (enteFile.metadata.fileType !== FILE_TYPE.IMAGE) return; log.debug(() => ["ml/liveq", { enteFile, uploadItem }]); void worker().then((w) => w.onUpload(enteFile, uploadItem)); @@ -300,7 +312,7 @@ export type MLStatus = /** * A function that can be used to subscribe to updates in the ML status. * - * This, along with {@link mlStatusSnapshot}, are meant to be used as arguments + * This, along with {@link mlStatusSnapshot}, is meant to be used as arguments * to React's {@link useSyncExternalStore}. * * @param callback A function that will be invoked whenever the result of @@ -310,18 +322,36 @@ export type MLStatus = */ export const mlStatusSubscribe = (onChange: () => void): (() => void) => { _mlStatusListeners.push(onChange); - // Unconditionally update the snapshot. - void updateMLStatusSnapshot(); return () => { _mlStatusListeners = _mlStatusListeners.filter((l) => l != onChange); }; }; -export const mlStatusSnapshot = (): MLStatus => _mlStatusSnapshot; +/** + * Return the last known, cached {@link MLStatus}. + * + * This, along with {@link mlStatusSnapshot}, is meant to be used as arguments + * to React's {@link useSyncExternalStore}. + * + * A return value of `undefined` indicates that we're still performing the + * asynchronous tasks that are needed to get the status. + */ +export const mlStatusSnapshot = (): MLStatus | undefined => { + const result = _mlStatusSnapshot; + // We don't have it yet, so start figuring it out now. + if (!result) triggerStatusUpdate(); + return result; +}; + +/** + * Trigger an asynchronous and unconditional update of the {@link MLStatus} + * snapshot. + */ +const triggerStatusUpdate = () => void updateMLStatusSnapshot(); -export const updateMLStatusSnapshot = async () => { - const status = await getMLStatus(); - _mlStatusSnapshot = status; +/** Unconditionally update of the {@link MLStatus} snapshot. */ +const updateMLStatusSnapshot = async () => { + _mlStatusSnapshot = await getMLStatus(); _mlStatusListeners.forEach((l) => l()); }; @@ -332,12 +362,13 @@ export const updateMLStatusSnapshot = async () => { * locally. */ export const getMLStatus = async (): Promise => { + if (!_isMLEnabledRemote) return { phase: "disabled" }; + const { indexedCount, indexableCount } = await indexableAndIndexedCounts(); let phase: MLStatus["phase"]; - if (!isMLEnabled()) { + if (!_isMLEnabledLocal) { phase = "disabled"; - return { phase }; } else { const isIndexing = await (await worker()).isIndexing(); From 06bf2ddad4e4b6423fb02a212ceaad3151a41e56 Mon Sep 17 00:00:00 2001 From: Manav Rathi Date: Thu, 11 Jul 2024 11:56:53 +0530 Subject: [PATCH 47/67] Integrate --- .../new/photos/components/MLSettings.tsx | 122 +++--------------- web/packages/new/photos/services/ml/index.ts | 2 +- 2 files changed, 20 insertions(+), 104 deletions(-) diff --git a/web/packages/new/photos/components/MLSettings.tsx b/web/packages/new/photos/components/MLSettings.tsx index 35c8a2585f..72bf56e4d2 100644 --- a/web/packages/new/photos/components/MLSettings.tsx +++ b/web/packages/new/photos/components/MLSettings.tsx @@ -1,5 +1,4 @@ import { - canEnableML, disableML, enableML, getIsMLEnabledRemote, @@ -7,11 +6,12 @@ import { mlStatusSnapshot, mlStatusSubscribe, pauseML, + type MLStatus, } from "@/new/photos/services/ml"; import { EnteDrawer } from "@/new/shared/components/EnteDrawer"; import { MenuItemGroup } from "@/new/shared/components/Menu"; import { Titlebar } from "@/new/shared/components/Titlebar"; -import { pt, ut } from "@/next/i18n"; +import { pt } from "@/next/i18n"; import log from "@/next/log"; import EnteSpinner from "@ente/shared/components/EnteSpinner"; import { EnteMenuItem } from "@ente/shared/components/Menu/EnteMenuItem"; @@ -19,13 +19,13 @@ import { Box, Button, Checkbox, - type DialogProps, FormControlLabel, FormGroup, Link, Paper, Stack, Typography, + type DialogProps, } from "@mui/material"; import { t } from "i18next"; import React, { useEffect, useState, useSyncExternalStore } from "react"; @@ -57,35 +57,9 @@ export const MLSettings: React.FC = ({ somethingWentWrong, } = appContext; - /** - * The state of our component. - * - * To avoid confusion with useState, we call it status instead. */ - // TODO: This Status is not automatically synced with the lower layers that - // hold the actual state. - type Status = - | "loading" /* fetching the data we need from the lower layers */ - | "notEligible" /* user is not in the beta program */ - | "disabled" /* eligible, but ML is currently disabled */ - | "enabled"; /* ML is enabled, but may be paused locally */ - - const [status, setStatus] = useState("loading"); + const mlStatus = useSyncExternalStore(mlStatusSubscribe, mlStatusSnapshot); const [openFaceConsent, setOpenFaceConsent] = useState(false); - const refreshStatus = async () => { - if (isMLEnabled() || (await getIsMLEnabledRemote())) { - setStatus("enabled"); - } else if (await canEnableML()) { - setStatus("disabled"); - } else { - setStatus("notEligible"); - } - }; - - useEffect(() => { - void refreshStatus(); - }, []); - const handleRootClose = () => { onClose(); onRootClose(); @@ -109,7 +83,6 @@ export const MLSettings: React.FC = ({ setOpenFaceConsent(true); } else { await enableML(); - setStatus("enabled"); } } catch (e) { log.error("Failed to enable or resume ML", e); @@ -123,7 +96,6 @@ export const MLSettings: React.FC = ({ startLoading(); try { await enableML(); - setStatus("enabled"); // Close the FaceConsent drawer, come back to ourselves. setOpenFaceConsent(false); } catch (e) { @@ -147,7 +119,6 @@ export const MLSettings: React.FC = ({ startLoading(); try { await disableML(); - setStatus("disabled"); } catch (e) { log.error("Failed to disable ML", e); somethingWentWrong(); @@ -156,18 +127,20 @@ export const MLSettings: React.FC = ({ } }; - const components: Record = { - loading: , - notEligible: , - disabled: , - enabled: ( + let component: React.ReactNode; + if (!mlStatus) { + component = ; + } else if (mlStatus.phase == "disabled") { + component = ; + } else { + component = ( - ), - }; + ); + } return ( @@ -186,7 +159,7 @@ export const MLSettings: React.FC = ({ title={pt("ML search")} onRootClose={onRootClose} /> - {components[status]} + {component} @@ -208,16 +181,6 @@ const Loading: React.FC = () => { ); }; -const ComingSoon: React.FC = () => { - return ( - - - {ut("We're putting finishing touches, coming back soon!")} - - - ); -}; - interface EnableMLProps { /** Called when the user enables ML. */ onEnable: () => void; @@ -356,6 +319,8 @@ const FaceConsent: React.FC = ({ }; interface ManageMLProps { + /** The {@link MLStatus}; a non-disabled one. */ + mlStatus: Exclude; /** Called when the user wants to toggle the ML status locally. */ onToggleLocal: () => void; /** Called when the user wants to disable ML. */ @@ -365,14 +330,12 @@ interface ManageMLProps { } const ManageML: React.FC = ({ + mlStatus, onToggleLocal, onDisableML, setDialogBoxAttributesV2, }) => { - const { phase, nSyncedFiles, nTotalFiles } = useSyncExternalStore( - mlStatusSubscribe, - mlStatusSnapshot, - ); + const { phase, nSyncedFiles, nTotalFiles } = mlStatus; const confirmDisableML = () => { setDialogBoxAttributesV2({ @@ -394,53 +357,6 @@ const ManageML: React.FC = ({ }); }; - // TODO-ML: - // const [indexingStatus, setIndexingStatus] = useState({ - // indexed: 0, - // pending: 0, - // }); - - // useEffect(() => { - // clipService.setOnUpdateHandler(setIndexingStatus); - // clipService.getIndexingStatus().then((st) => setIndexingStatus(st)); - // return () => clipService.setOnUpdateHandler(undefined); - // }, []); - /* TODO-ML: isElectron() && ( - - - - - - {t("INDEXED_ITEMS")} - - - {formatNumber( - indexingStatus.indexed, - )} - - - - - {t("PENDING_ITEMS")} - - - {formatNumber( - indexingStatus.pending, - )} - - - - - )*/ - return ( diff --git a/web/packages/new/photos/services/ml/index.ts b/web/packages/new/photos/services/ml/index.ts index d310f1ea8e..c599368fc5 100644 --- a/web/packages/new/photos/services/ml/index.ts +++ b/web/packages/new/photos/services/ml/index.ts @@ -368,7 +368,7 @@ export const getMLStatus = async (): Promise => { let phase: MLStatus["phase"]; if (!_isMLEnabledLocal) { - phase = "disabled"; + phase = "paused"; } else { const isIndexing = await (await worker()).isIndexing(); From 5ff9f408eba1ff97bbbe121da0e1c0199c8df8ae Mon Sep 17 00:00:00 2001 From: Manav Rathi Date: Thu, 11 Jul 2024 12:07:27 +0530 Subject: [PATCH 48/67] Touchups --- web/packages/new/photos/services/ml/index.ts | 25 +++++++++----------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/web/packages/new/photos/services/ml/index.ts b/web/packages/new/photos/services/ml/index.ts index c599368fc5..e0084045d1 100644 --- a/web/packages/new/photos/services/ml/index.ts +++ b/web/packages/new/photos/services/ml/index.ts @@ -3,10 +3,6 @@ */ import { FILE_TYPE } from "@/media/file-type"; -import { - isBetaUser, - isInternalUser, -} from "@/new/photos/services/feature-flags"; import type { EnteFile } from "@/new/photos/types/file"; import { isDesktop } from "@/next/app"; import { blobCache } from "@/next/blob-cache"; @@ -97,12 +93,17 @@ export const terminateMLWorker = () => { } }; +/** Gatekeep some common entry points to catch accidental invocations. */ +const ensureDesktop = () => { + // ML currently only works when we're running in our desktop app. + if (!isDesktop) throw new Error("ML subsystem can only be used on desktop"); +}; + /** * Initialize the ML subsystem if the user has enabled it in preferences. */ export const initML = () => { - // ML currently only works when we're running in our desktop app. - if (!isDesktop) return; + ensureDesktop(); _isMLEnabledLocal = isMLEnabledLocally(); }; @@ -118,13 +119,6 @@ export const logoutML = async () => { await clearMLDB(); }; -/** - * Return true if we should show an UI option to the user to allow them to - * enable ML. - */ -export const canEnableML = async () => - (await isInternalUser()) || (await isBetaUser()); - /** * Return true if the user has enabled machine learning in their preferences. * @@ -251,7 +245,10 @@ const updateIsMLEnabledRemote = (enabled: boolean) => * This function does not wait for these processes to run to completion, and * returns immediately. */ -export const triggerMLSync = () => void mlSync(); +export const triggerMLSync = () => { + ensureDesktop(); + void mlSync(); +}; const mlSync = async () => { _isMLEnabledRemote = await getIsMLEnabledRemote(); From 52251ad6547f212bbf1988d4557249a80ae151a5 Mon Sep 17 00:00:00 2001 From: Manav Rathi Date: Thu, 11 Jul 2024 12:30:02 +0530 Subject: [PATCH 49/67] Improve UI feedback --- .../new/photos/components/MLSettings.tsx | 54 +++++++++---------- web/packages/new/photos/services/ml/index.ts | 31 +++++++++-- 2 files changed, 55 insertions(+), 30 deletions(-) diff --git a/web/packages/new/photos/components/MLSettings.tsx b/web/packages/new/photos/components/MLSettings.tsx index 72bf56e4d2..ee3624d6fa 100644 --- a/web/packages/new/photos/components/MLSettings.tsx +++ b/web/packages/new/photos/components/MLSettings.tsx @@ -6,6 +6,7 @@ import { mlStatusSnapshot, mlStatusSubscribe, pauseML, + resumeML, type MLStatus, } from "@/new/photos/services/ml"; import { EnteDrawer } from "@/new/shared/components/EnteDrawer"; @@ -70,13 +71,7 @@ export const MLSettings: React.FC = ({ else onClose(); }; - // The user may've changed the remote flag on a different device, so in both - // cases (enable or resume), do the same flow: - // - // - If remote flag is not set, then show the consent dialog - // - Otherwise enable ML (both locally and on remote). - // - const handleEnableOrResumeML = async () => { + const handleEnableML = async () => { startLoading(); try { if (!(await getIsMLEnabledRemote())) { @@ -106,15 +101,6 @@ export const MLSettings: React.FC = ({ } }; - const handleToggleLocal = async () => { - try { - isMLEnabled() ? pauseML() : await handleEnableOrResumeML(); - } catch (e) { - log.error("Failed to toggle local state of ML", e); - somethingWentWrong(); - } - }; - const handleDisableML = async () => { startLoading(); try { @@ -131,12 +117,11 @@ export const MLSettings: React.FC = ({ if (!mlStatus) { component = ; } else if (mlStatus.phase == "disabled") { - component = ; + component = ; } else { component = ( ); @@ -321,8 +306,6 @@ const FaceConsent: React.FC = ({ interface ManageMLProps { /** The {@link MLStatus}; a non-disabled one. */ mlStatus: Exclude; - /** Called when the user wants to toggle the ML status locally. */ - onToggleLocal: () => void; /** Called when the user wants to disable ML. */ onDisableML: () => void; /** Subset of appContext. */ @@ -331,12 +314,31 @@ interface ManageMLProps { const ManageML: React.FC = ({ mlStatus, - onToggleLocal, onDisableML, setDialogBoxAttributesV2, }) => { const { phase, nSyncedFiles, nTotalFiles } = mlStatus; + let status: string; + switch (phase) { + case "paused": + status = pt("Paused"); + break; + case "indexing": + status = pt("Indexing"); + break; + case "scheduled": + status = pt("Scheduled"); + break; + // TODO: Clustering + default: + status = pt("Done"); + break; + } + const processed = `${nSyncedFiles} / ${nTotalFiles}`; + + const handleToggleLocal = () => (isMLEnabled() ? pauseML() : resumeML()); + const confirmDisableML = () => { setDialogBoxAttributesV2({ title: pt("Disable ML search"), @@ -373,19 +375,19 @@ const ManageML: React.FC = ({ label={pt("On this device")} variant="toggle" checked={phase != "paused"} - onClick={onToggleLocal} + onClick={handleToggleLocal} /> - + Status - Indexing + {status} = ({ justifyContent={"space-between"} > Processed - - {`${nSyncedFiles} / ${nTotalFiles}`} - + {processed} diff --git a/web/packages/new/photos/services/ml/index.ts b/web/packages/new/photos/services/ml/index.ts index e0084045d1..f5a501151d 100644 --- a/web/packages/new/photos/services/ml/index.ts +++ b/web/packages/new/photos/services/ml/index.ts @@ -149,6 +149,7 @@ export const enableML = async () => { setIsMLEnabledLocally(true); _isMLEnabledRemote = true; _isMLEnabledLocal = true; + setInterimScheduledStatus(); triggerStatusUpdate(); triggerMLSync(); }; @@ -188,6 +189,7 @@ export const pauseML = () => { export const resumeML = () => { setIsMLEnabledLocally(true); _isMLEnabledLocal = true; + setInterimScheduledStatus(); triggerStatusUpdate(); triggerMLSync(); }; @@ -347,8 +349,11 @@ export const mlStatusSnapshot = (): MLStatus | undefined => { const triggerStatusUpdate = () => void updateMLStatusSnapshot(); /** Unconditionally update of the {@link MLStatus} snapshot. */ -const updateMLStatusSnapshot = async () => { - _mlStatusSnapshot = await getMLStatus(); +const updateMLStatusSnapshot = async () => + setMLStatusSnapshot(await getMLStatus()); + +const setMLStatusSnapshot = (snapshot: MLStatus) => { + _mlStatusSnapshot = snapshot; _mlStatusListeners.forEach((l) => l()); }; @@ -358,7 +363,7 @@ const updateMLStatusSnapshot = async () => { * Precondition: ML must be enabled on remote, though it is fine if it is paused * locally. */ -export const getMLStatus = async (): Promise => { +const getMLStatus = async (): Promise => { if (!_isMLEnabledRemote) return { phase: "disabled" }; const { indexedCount, indexableCount } = await indexableAndIndexedCounts(); @@ -383,6 +388,26 @@ export const getMLStatus = async (): Promise => { }; }; +/** + * When the user enables or resumes ML, we wish to give immediate feedback. + * + * So this is an intermediate state with possibly incorrect counts (but correct + * phase) that is set immediately to trigger a UI update. It uses the counts + * from the last known status, just updates the phase. + * + * Once the worker is initialized and the correct counts fetched, this will + * update to the correct state (should take less than one second). + */ +const setInterimScheduledStatus = () => { + let nSyncedFiles = 0, + nTotalFiles = 0; + if (_mlStatusSnapshot && _mlStatusSnapshot.phase != "disabled") { + nSyncedFiles = _mlStatusSnapshot.nSyncedFiles; + nTotalFiles = _mlStatusSnapshot.nTotalFiles; + } + setMLStatusSnapshot({ phase: "scheduled", nSyncedFiles, nTotalFiles }); +}; + /** * Return the IDs of all the faces in the given {@link enteFile} that are not * associated with a person cluster. From 6ccb61b425a6cdc25bfec98472c087210753e2f5 Mon Sep 17 00:00:00 2001 From: Manav Rathi Date: Thu, 11 Jul 2024 13:40:57 +0530 Subject: [PATCH 50/67] Enhance --- .../new/photos/components/MLSettings.tsx | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/web/packages/new/photos/components/MLSettings.tsx b/web/packages/new/photos/components/MLSettings.tsx index ee3624d6fa..3adb4b6a0b 100644 --- a/web/packages/new/photos/components/MLSettings.tsx +++ b/web/packages/new/photos/components/MLSettings.tsx @@ -20,6 +20,7 @@ import { Box, Button, Checkbox, + Divider, FormControlLabel, FormGroup, Link, @@ -380,21 +381,32 @@ const ManageML: React.FC = ({ - + - Status + + {pt("Status")} + {status} + - Processed + + {pt("Processed")} + {processed} From 8dad88eca6e571ec6aa08c5e3886b24c7f2dec12 Mon Sep 17 00:00:00 2001 From: Manav Rathi Date: Thu, 11 Jul 2024 13:43:04 +0530 Subject: [PATCH 51/67] Disable ripples on the background item for toggles --- web/packages/shared/components/Menu/EnteMenuItem.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/web/packages/shared/components/Menu/EnteMenuItem.tsx b/web/packages/shared/components/Menu/EnteMenuItem.tsx index 042348482b..ba52e78701 100644 --- a/web/packages/shared/components/Menu/EnteMenuItem.tsx +++ b/web/packages/shared/components/Menu/EnteMenuItem.tsx @@ -72,6 +72,7 @@ export function EnteMenuItem({ From 62e4a6c344546555a6de8747e4587bff6ad5ffc0 Mon Sep 17 00:00:00 2001 From: Manav Rathi Date: Thu, 11 Jul 2024 13:50:22 +0530 Subject: [PATCH 52/67] Dot product --- web/packages/new/photos/services/ml/clip.ts | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/web/packages/new/photos/services/ml/clip.ts b/web/packages/new/photos/services/ml/clip.ts index 22fd05ec80..91a0270dc8 100644 --- a/web/packages/new/photos/services/ml/clip.ts +++ b/web/packages/new/photos/services/ml/clip.ts @@ -3,7 +3,7 @@ import type { Electron } from "@/next/types/ipc"; import type { ImageBitmapAndData } from "./bitmap"; import { clipIndexes } from "./db"; import { pixelRGBBicubic } from "./image"; -import { cosineSimilarity, norm } from "./math"; +import { dotProduct, norm } from "./math"; import type { MLWorkerElectron } from "./worker-electron"; /** @@ -202,7 +202,12 @@ export const clipMatches = async ( const textEmbedding = normalized(t); const items = (await clipIndexes()).map( ({ fileID, embedding }) => - [fileID, cosineSimilarity(embedding, textEmbedding)] as const, + // What we want to do is `cosineSimilarity`, but since both the + // embeddings involved are already normalized, we can save the norm + // calculations and directly do their `dotProduct`. + // + // This code is on the hot path, so these optimizations help. + [fileID, dotProduct(embedding, textEmbedding)] as const, ); return new Map(items.filter(([, score]) => score >= 0.23)); }; From 13c042f692f8ed6eef106d6ba2308b9882dc7cc4 Mon Sep 17 00:00:00 2001 From: Manav Rathi Date: Thu, 11 Jul 2024 13:53:27 +0530 Subject: [PATCH 53/67] Remove scaffolding code --- web/packages/new/photos/services/ml/bitmap.ts | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/web/packages/new/photos/services/ml/bitmap.ts b/web/packages/new/photos/services/ml/bitmap.ts index 3772385425..fe3fc7da4e 100644 --- a/web/packages/new/photos/services/ml/bitmap.ts +++ b/web/packages/new/photos/services/ml/bitmap.ts @@ -35,22 +35,14 @@ export const imageBitmapAndData = async ( ? await renderableUploadItemImageBitmap(enteFile, uploadItem, electron) : await renderableImageBitmap(enteFile); - // Use an OffscreenCanvas to get the bitmap's data. - const { width, height } = imageBitmap; + // Use an OffscreenCanvas to get the bitmap's data. const offscreenCanvas = new OffscreenCanvas(width, height); const ctx = ensure(offscreenCanvas.getContext("2d")); ctx.drawImage(imageBitmap, 0, 0, width, height); const imageData = ctx.getImageData(0, 0, width, height); - // TODO-ML: This check isn't needed, keeping it around during scaffolding. - if ( - imageBitmap.width != imageData.width || - imageBitmap.height != imageData.height - ) - throw new Error("Dimension mismatch"); - return { bitmap: imageBitmap, data: imageData }; }; From b25dbfc10b7d453bf83d757555666646e073290e Mon Sep 17 00:00:00 2001 From: Manav Rathi Date: Thu, 11 Jul 2024 14:02:55 +0530 Subject: [PATCH 54/67] wip separate flag --- .../src/components/Sidebar/Preferences.tsx | 4 ++-- web/apps/photos/src/pages/_app.tsx | 4 ++-- web/apps/photos/src/services/searchService.ts | 23 +++++++++---------- web/apps/photos/src/services/sync.ts | 7 ++---- web/packages/new/photos/services/ml/index.ts | 21 ++++++++--------- 5 files changed, 26 insertions(+), 33 deletions(-) diff --git a/web/apps/photos/src/components/Sidebar/Preferences.tsx b/web/apps/photos/src/components/Sidebar/Preferences.tsx index 5975059af9..32c36f991c 100644 --- a/web/apps/photos/src/components/Sidebar/Preferences.tsx +++ b/web/apps/photos/src/components/Sidebar/Preferences.tsx @@ -1,4 +1,5 @@ import { MLSettings } from "@/new/photos/components/MLSettings"; +import { isMLSupported } from "@/new/photos/services/ml"; import { EnteDrawer } from "@/new/shared/components/EnteDrawer"; import { MenuItemGroup, MenuSectionTitle } from "@/new/shared/components/Menu"; import { Titlebar } from "@/new/shared/components/Titlebar"; @@ -15,7 +16,6 @@ import ScienceIcon from "@mui/icons-material/Science"; import { Box, DialogProps, Stack } from "@mui/material"; import DropdownInput from "components/DropdownInput"; import { t } from "i18next"; -import isElectron from "is-electron"; import { AppContext } from "pages/_app"; import { useContext, useState } from "react"; import AdvancedSettings from "./AdvancedSettings"; @@ -75,7 +75,7 @@ export default function Preferences({ open, onClose, onRootClose }) { endIcon={} label={t("ADVANCED")} /> - {isElectron() && ( + {isMLSupported && ( { return [ - // TODO-ML(MR): Skip this for now if indexing is disabled (eventually - // the indexing status should not be tied to results). - ...(isMLEnabled() ? [await getIndexStatusSuggestion()] : []), + ...(await getMLStatusSuggestion()), ...(await convertSuggestionsToOptions(await getAllPeopleSuggestion())), ].filter((t) => !!t); }; @@ -171,32 +169,33 @@ export async function getAllPeopleSuggestion(): Promise> { } } -export async function getIndexStatusSuggestion(): Promise { - try { - const indexStatus = await faceIndexingStatus(); +export async function getMLStatusSuggestion(): Promise { + const status = await mlStatusSnapshot(); + isMLEnabled(); + try { let label: string; - switch (indexStatus.phase) { + switch (status.phase) { case "scheduled": label = t("INDEXING_SCHEDULED"); break; case "indexing": label = t("ANALYZING_PHOTOS", { - indexStatus, + indexStatus: status, }); break; case "clustering": - label = t("INDEXING_PEOPLE", { indexStatus }); + label = t("INDEXING_PEOPLE", { indexStatus: status }); break; case "done": - label = t("INDEXING_DONE", { indexStatus }); + label = t("INDEXING_DONE", { indexStatus: status }); break; } return { label, type: SuggestionType.INDEX_STATUS, - value: indexStatus, + value: status, hide: true, }; } catch (e) { diff --git a/web/apps/photos/src/services/sync.ts b/web/apps/photos/src/services/sync.ts index b628a3510d..5ebc5b43b0 100644 --- a/web/apps/photos/src/services/sync.ts +++ b/web/apps/photos/src/services/sync.ts @@ -1,6 +1,5 @@ import { fetchAndSaveFeatureFlagsIfNeeded } from "@/new/photos/services/feature-flags"; -import { triggerMLSync } from "@/new/photos/services/ml"; -import { isDesktop } from "@/next/app"; +import { isMLSupported, triggerMLSync } from "@/new/photos/services/ml"; import { syncEntities } from "services/entityService"; import { syncMapEnabled } from "services/userService"; @@ -17,7 +16,5 @@ export const sync = async () => { await syncEntities(); await syncMapEnabled(); fetchAndSaveFeatureFlagsIfNeeded(); - if (isDesktop) { - triggerMLSync(); - } + if (isMLSupported) triggerMLSync(); }; diff --git a/web/packages/new/photos/services/ml/index.ts b/web/packages/new/photos/services/ml/index.ts index f5a501151d..8ac088253d 100644 --- a/web/packages/new/photos/services/ml/index.ts +++ b/web/packages/new/photos/services/ml/index.ts @@ -93,17 +93,17 @@ export const terminateMLWorker = () => { } }; -/** Gatekeep some common entry points to catch accidental invocations. */ -const ensureDesktop = () => { - // ML currently only works when we're running in our desktop app. - if (!isDesktop) throw new Error("ML subsystem can only be used on desktop"); -}; +/** + * Return true if the current client supports ML. + * + * ML currently only works when we're running in our desktop app. + */ +export const isMLSupported = isDesktop; /** * Initialize the ML subsystem if the user has enabled it in preferences. */ export const initML = () => { - ensureDesktop(); _isMLEnabledLocal = isMLEnabledLocally(); }; @@ -247,10 +247,7 @@ const updateIsMLEnabledRemote = (enabled: boolean) => * This function does not wait for these processes to run to completion, and * returns immediately. */ -export const triggerMLSync = () => { - ensureDesktop(); - void mlSync(); -}; +export const triggerMLSync = () => void mlSync(); const mlSync = async () => { _isMLEnabledRemote = await getIsMLEnabledRemote(); @@ -337,8 +334,8 @@ export const mlStatusSubscribe = (onChange: () => void): (() => void) => { */ export const mlStatusSnapshot = (): MLStatus | undefined => { const result = _mlStatusSnapshot; - // We don't have it yet, so start figuring it out now. - if (!result) triggerStatusUpdate(); + // We don't have it yet but we're on a supported client, trigger an update. + if (!result && isDesktop) triggerStatusUpdate(); return result; }; From a3dc69188554557ce147107a7c3847ea9eeb464b Mon Sep 17 00:00:00 2001 From: Manav Rathi Date: Thu, 11 Jul 2024 14:12:44 +0530 Subject: [PATCH 55/67] Use in search bar --- web/apps/photos/src/services/searchService.ts | 62 +++++++++---------- web/packages/new/photos/services/ml/index.ts | 4 +- 2 files changed, 33 insertions(+), 33 deletions(-) diff --git a/web/apps/photos/src/services/searchService.ts b/web/apps/photos/src/services/searchService.ts index 42b35c57a9..fc89877759 100644 --- a/web/apps/photos/src/services/searchService.ts +++ b/web/apps/photos/src/services/searchService.ts @@ -1,5 +1,5 @@ import { FILE_TYPE } from "@/media/file-type"; -import { mlStatusSnapshot } from "@/new/photos/services/ml"; +import { isMLSupported, mlStatusSnapshot } from "@/new/photos/services/ml"; import type { Person } from "@/new/photos/services/ml/people"; import { EnteFile } from "@/new/photos/types/file"; import { isDesktop } from "@/next/app"; @@ -26,7 +26,7 @@ const DIGITS = new Set(["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"]); export const getDefaultOptions = async () => { return [ - ...(await getMLStatusSuggestion()), + await getMLStatusSuggestion(), ...(await convertSuggestionsToOptions(await getAllPeopleSuggestion())), ].filter((t) => !!t); }; @@ -169,38 +169,38 @@ export async function getAllPeopleSuggestion(): Promise> { } } -export async function getMLStatusSuggestion(): Promise { - const status = await mlStatusSnapshot(); +export async function getMLStatusSuggestion(): Promise { + if (!isMLSupported) return undefined; - isMLEnabled(); - try { - let label: string; - switch (status.phase) { - case "scheduled": - label = t("INDEXING_SCHEDULED"); - break; - case "indexing": - label = t("ANALYZING_PHOTOS", { - indexStatus: status, - }); - break; - case "clustering": - label = t("INDEXING_PEOPLE", { indexStatus: status }); - break; - case "done": - label = t("INDEXING_DONE", { indexStatus: status }); - break; - } + const status = mlStatusSnapshot(); - return { - label, - type: SuggestionType.INDEX_STATUS, - value: status, - hide: true, - }; - } catch (e) { - log.error("getIndexStatusSuggestion failed", e); + if (!status || status.phase == "disabled" || status.phase == "paused") + return undefined; + + let label: string; + switch (status.phase) { + case "scheduled": + label = t("INDEXING_SCHEDULED"); + break; + case "indexing": + label = t("ANALYZING_PHOTOS", { + indexStatus: status, + }); + break; + case "clustering": + label = t("INDEXING_PEOPLE", { indexStatus: status }); + break; + case "done": + label = t("INDEXING_DONE", { indexStatus: status }); + break; } + + return { + label, + type: SuggestionType.INDEX_STATUS, + value: status, + hide: true, + }; } function getDateSuggestion(searchPhrase: string): Suggestion[] { diff --git a/web/packages/new/photos/services/ml/index.ts b/web/packages/new/photos/services/ml/index.ts index 8ac088253d..3152980886 100644 --- a/web/packages/new/photos/services/ml/index.ts +++ b/web/packages/new/photos/services/ml/index.ts @@ -334,8 +334,8 @@ export const mlStatusSubscribe = (onChange: () => void): (() => void) => { */ export const mlStatusSnapshot = (): MLStatus | undefined => { const result = _mlStatusSnapshot; - // We don't have it yet but we're on a supported client, trigger an update. - if (!result && isDesktop) triggerStatusUpdate(); + // We don't have it yet, trigger an update. + if (!result) triggerStatusUpdate(); return result; }; From 73ad758191a10a305011651964e0065366f6ed84 Mon Sep 17 00:00:00 2001 From: Manav Rathi Date: Thu, 11 Jul 2024 14:18:10 +0530 Subject: [PATCH 56/67] Fix --- web/packages/new/photos/components/PeopleList.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/packages/new/photos/components/PeopleList.tsx b/web/packages/new/photos/components/PeopleList.tsx index 39361f8741..5c13aa9c55 100644 --- a/web/packages/new/photos/components/PeopleList.tsx +++ b/web/packages/new/photos/components/PeopleList.tsx @@ -108,7 +108,7 @@ export const UnidentifiedFaces: React.FC = ({ return ( <> - + {t("UNIDENTIFIED_FACES")} From fdcc6b6997159a933e4f6f708713359b25b06505 Mon Sep 17 00:00:00 2001 From: Manav Rathi Date: Thu, 11 Jul 2024 14:19:03 +0530 Subject: [PATCH 57/67] Tweak and lint --- web/apps/photos/src/services/searchService.ts | 4 +--- web/apps/photos/src/types/search/index.ts | 4 ++-- web/packages/new/photos/services/ml/clip.ts | 2 +- 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/web/apps/photos/src/services/searchService.ts b/web/apps/photos/src/services/searchService.ts index fc89877759..acf12a1e94 100644 --- a/web/apps/photos/src/services/searchService.ts +++ b/web/apps/photos/src/services/searchService.ts @@ -183,9 +183,7 @@ export async function getMLStatusSuggestion(): Promise { label = t("INDEXING_SCHEDULED"); break; case "indexing": - label = t("ANALYZING_PHOTOS", { - indexStatus: status, - }); + label = t("ANALYZING_PHOTOS", { indexStatus: status }); break; case "clustering": label = t("INDEXING_PEOPLE", { indexStatus: status }); diff --git a/web/apps/photos/src/types/search/index.ts b/web/apps/photos/src/types/search/index.ts index 575cb0a9c7..130471ae76 100644 --- a/web/apps/photos/src/types/search/index.ts +++ b/web/apps/photos/src/types/search/index.ts @@ -1,5 +1,5 @@ import { FILE_TYPE } from "@/media/file-type"; -import type { FaceIndexingStatus } from "@/new/photos/services/ml"; +import type { MLStatus } from "@/new/photos/services/ml"; import type { Person } from "@/new/photos/services/ml/people"; import { EnteFile } from "@/new/photos/types/file"; import { City } from "services/locationSearchService"; @@ -31,7 +31,7 @@ export interface Suggestion { | DateValue | number[] | Person - | FaceIndexingStatus + | MLStatus | LocationTagData | City | FILE_TYPE diff --git a/web/packages/new/photos/services/ml/clip.ts b/web/packages/new/photos/services/ml/clip.ts index 91a0270dc8..0726929e2a 100644 --- a/web/packages/new/photos/services/ml/clip.ts +++ b/web/packages/new/photos/services/ml/clip.ts @@ -26,7 +26,7 @@ export const clipIndexingVersion = 1; * trained) encoders - one for images, and one for text - that both map to the * same embedding space. * - * We use this for natural language search within the app: + * We use this for natural language search (aka "magic search") within the app: * * 1. Pre-compute an embedding for each image. * From 544a5a9ccc908b9e7c6ddc43ec042c12617e1cb3 Mon Sep 17 00:00:00 2001 From: Manav Rathi Date: Thu, 11 Jul 2024 14:39:45 +0530 Subject: [PATCH 58/67] Use consistent key --- desktop/src/main.ts | 2 +- desktop/src/main/services/upload.ts | 2 +- web/apps/accounts/src/pages/_app.tsx | 6 ++++-- web/packages/new/photos/components/DevSettings.tsx | 14 ++++++++++---- web/packages/new/photos/services/ml/db.ts | 8 ++++---- web/packages/next/i18n.ts | 2 +- 6 files changed, 21 insertions(+), 13 deletions(-) diff --git a/desktop/src/main.ts b/desktop/src/main.ts index be5721ed0e..2622d09a6e 100644 --- a/desktop/src/main.ts +++ b/desktop/src/main.ts @@ -537,7 +537,7 @@ const setupTrayItem = (mainWindow: BrowserWindow) => { * old cache dir if it exists. * * Added May 2024, v1.7.0. This migration code can be removed after some time - * once most people have upgraded to newer versions. + * once most people have upgraded to newer versions (tag: Migration). */ const deleteLegacyDiskCacheDirIfExists = async () => { const removeIfExists = async (dirPath: string) => { diff --git a/desktop/src/main/services/upload.ts b/desktop/src/main/services/upload.ts index 3da9cafd7c..a7e3fc8671 100644 --- a/desktop/src/main/services/upload.ts +++ b/desktop/src/main/services/upload.ts @@ -58,7 +58,7 @@ export const pendingUploads = async (): Promise => { const allZipItems = uploadStatusStore.get("zipItems"); let zipItems: typeof allZipItems; - // Migration code - May 2024. Remove after a bit. + // Migration code - May 2024. Remove after a bit (tag: Migration). // // The older store formats will not have zipItems and instead will have // zipPaths. If we find such a case, read the zipPaths and enqueue all of diff --git a/web/apps/accounts/src/pages/_app.tsx b/web/apps/accounts/src/pages/_app.tsx index 7029cacd86..2cf427b918 100644 --- a/web/apps/accounts/src/pages/_app.tsx +++ b/web/apps/accounts/src/pages/_app.tsx @@ -33,8 +33,10 @@ const App: React.FC = ({ Component, pageProps }) => { useEffect(() => { disableDiskLogs(); // The accounts app has no local state, but some older builds might've - // leftover some scraps. Clear it out. This code added 1 July 2024, can - // be removed after a while (tag: Migration). + // leftover some scraps. Clear it out. + // + // This code added on 1 July 2024, can be removed soon since this data + // was never saved before this was released (tag: Migration). clearData(); void setupI18n().finally(() => setIsI18nReady(true)); logUnhandledErrorsAndRejections(true); diff --git a/web/packages/new/photos/components/DevSettings.tsx b/web/packages/new/photos/components/DevSettings.tsx index 84c71b09c5..7919314068 100644 --- a/web/packages/new/photos/components/DevSettings.tsx +++ b/web/packages/new/photos/components/DevSettings.tsx @@ -71,8 +71,11 @@ const Contents: React.FC = (props) => { () => void getKV("apiOrigin").then((o) => setInitialAPIOrigin( - // TODO: Migration of apiOrigin from local storage to indexed DB - // Remove me after a bit (27 June 2024). + // Migrate apiOrigin from local storage to indexed DB. + // + // This code was added 27 June 2024. Note that the legacy + // value was never in production builds, only nightlies, so + // this code can be removed soon (tag: Migration). o ?? localStorage.getItem("apiOrigin") ?? "", ), ), @@ -215,8 +218,11 @@ const Form: React.FC = ({ initialAPIOrigin, onClose }) => { const updateAPIOrigin = async (origin: string) => { if (!origin) { await removeKV("apiOrigin"); - // TODO: Migration of apiOrigin from local storage to indexed DB - // Remove me after a bit (27 June 2024). + // Migrate apiOrigin from local storage to indexed DB. + // + // This code was added 27 June 2024. Note that the legacy value was + // never in production builds, only nightlies, so this code can be + // removed at some point soon (tag: Migration). localStorage.removeItem("apiOrigin"); return; } diff --git a/web/packages/new/photos/services/ml/db.ts b/web/packages/new/photos/services/ml/db.ts index 9e4f9cf90b..51ca2f749b 100644 --- a/web/packages/new/photos/services/ml/db.ts +++ b/web/packages/new/photos/services/ml/db.ts @@ -135,14 +135,14 @@ const openMLDB = async () => { const deleteLegacyDB = () => { // Delete the legacy face DB v1. // - // This code was added June 2024 (v1.7.1-rc) and can be removed once clients - // have migrated over. + // This code was added June 2024 (v1.7.1-rc) and can be removed at some + // point when most clients have migrated (tag: Migration). void deleteDB("mldata"); // Delete the legacy CLIP (mostly) related keys from LocalForage. // - // This code was added July 2024 (v1.7.2-rc) and can be removed once - // sufficient clients have migrated over (tag: Migration). + // This code was added July 2024 (v1.7.2-rc) and can be removed at some + // point when most clients have migrated (tag: Migration). void Promise.all([ localForage.removeItem("embeddings"), localForage.removeItem("embedding_sync_time"), diff --git a/web/packages/next/i18n.ts b/web/packages/next/i18n.ts index cec28add94..9cd5293832 100644 --- a/web/packages/next/i18n.ts +++ b/web/packages/next/i18n.ts @@ -136,7 +136,7 @@ const savedLocaleStringMigratingIfNeeded = (): SupportedLocale | undefined => { // This migration is dated Feb 2024. And it can be removed after a few // months, because by then either customers would've opened the app and // their setting migrated to the new format, or the browser would've cleared - // the older local storage entry anyway. + // the older local storage entry anyway (tag: Migration). if (!ls) { // Nothing found From 936e0470e63fae6c26cd9e2b81689e43c4d356cd Mon Sep 17 00:00:00 2001 From: Manav Rathi Date: Thu, 11 Jul 2024 14:56:55 +0530 Subject: [PATCH 59/67] Live update --- web/packages/new/photos/services/ml/bitmap.ts | 2 +- web/packages/new/photos/services/ml/clip.ts | 2 +- web/packages/new/photos/services/ml/face.ts | 2 +- web/packages/new/photos/services/ml/index.ts | 9 ++++++++- .../ml/{worker-electron.ts => worker-types.ts} | 18 ++++++++++++++++++ web/packages/new/photos/services/ml/worker.ts | 12 ++++++++++-- web/packages/new/photos/utils/native-stream.ts | 2 +- 7 files changed, 40 insertions(+), 7 deletions(-) rename web/packages/new/photos/services/ml/{worker-electron.ts => worker-types.ts} (57%) diff --git a/web/packages/new/photos/services/ml/bitmap.ts b/web/packages/new/photos/services/ml/bitmap.ts index fe3fc7da4e..7b851d2b8c 100644 --- a/web/packages/new/photos/services/ml/bitmap.ts +++ b/web/packages/new/photos/services/ml/bitmap.ts @@ -7,7 +7,7 @@ import { renderableImageBlob } from "../../utils/file"; import { readStream } from "../../utils/native-stream"; import DownloadManager from "../download"; import type { UploadItem } from "../upload/types"; -import type { MLWorkerElectron } from "./worker-electron"; +import type { MLWorkerElectron } from "./worker-types"; export interface ImageBitmapAndData { bitmap: ImageBitmap; diff --git a/web/packages/new/photos/services/ml/clip.ts b/web/packages/new/photos/services/ml/clip.ts index 0726929e2a..16bf637e5a 100644 --- a/web/packages/new/photos/services/ml/clip.ts +++ b/web/packages/new/photos/services/ml/clip.ts @@ -4,7 +4,7 @@ import type { ImageBitmapAndData } from "./bitmap"; import { clipIndexes } from "./db"; import { pixelRGBBicubic } from "./image"; import { dotProduct, norm } from "./math"; -import type { MLWorkerElectron } from "./worker-electron"; +import type { MLWorkerElectron } from "./worker-types"; /** * The version of the CLIP indexing pipeline implemented by the current client. diff --git a/web/packages/new/photos/services/ml/face.ts b/web/packages/new/photos/services/ml/face.ts index 5ecd57d771..4e18127a2c 100644 --- a/web/packages/new/photos/services/ml/face.ts +++ b/web/packages/new/photos/services/ml/face.ts @@ -26,7 +26,7 @@ import { warpAffineFloat32List, } from "./image"; import { clamp } from "./math"; -import type { MLWorkerElectron } from "./worker-electron"; +import type { MLWorkerElectron } from "./worker-types"; /** * The version of the face indexing pipeline implemented by the current client. diff --git a/web/packages/new/photos/services/ml/index.ts b/web/packages/new/photos/services/ml/index.ts index 3152980886..39aaeec8d9 100644 --- a/web/packages/new/photos/services/ml/index.ts +++ b/web/packages/new/photos/services/ml/index.ts @@ -68,12 +68,17 @@ const createComlinkWorker = async () => { computeFaceEmbeddings: electron.computeFaceEmbeddings, computeCLIPImageEmbedding: electron.computeCLIPImageEmbedding, }; + const delegate = { + workerDidProcessFile, + }; const cw = new ComlinkWorker( "ML", new Worker(new URL("worker.ts", import.meta.url)), ); - await cw.remote.then((w) => w.init(proxy(mlWorkerElectron))); + await cw.remote.then((w) => + w.init(proxy(mlWorkerElectron), proxy(delegate)), + ); return cw; }; @@ -405,6 +410,8 @@ const setInterimScheduledStatus = () => { setMLStatusSnapshot({ phase: "scheduled", nSyncedFiles, nTotalFiles }); }; +const workerDidProcessFile = () => triggerStatusUpdate(); + /** * Return the IDs of all the faces in the given {@link enteFile} that are not * associated with a person cluster. diff --git a/web/packages/new/photos/services/ml/worker-electron.ts b/web/packages/new/photos/services/ml/worker-types.ts similarity index 57% rename from web/packages/new/photos/services/ml/worker-electron.ts rename to web/packages/new/photos/services/ml/worker-types.ts index 0e187a178a..2e30703844 100644 --- a/web/packages/new/photos/services/ml/worker-electron.ts +++ b/web/packages/new/photos/services/ml/worker-types.ts @@ -1,3 +1,8 @@ +/** + * @file Type for the objects shared (as a Comlink proxy) by the main thread and + * the ML worker. + */ + /** * A subset of {@link Electron} provided to the {@link MLWorker}. * @@ -12,3 +17,16 @@ export interface MLWorkerElectron { computeFaceEmbeddings: (input: Float32Array) => Promise; computeCLIPImageEmbedding: (input: Float32Array) => Promise; } + +/** + * Callbacks invoked by the worker at various points in the indexing pipeline to + * notify the main thread of events it might be interested in. + */ +export interface MLWorkerDelegate { + /** + * Called whenever a file is processed during indexing. + * + * It is called both when the indexing was successful or failed. + */ + workerDidProcessFile: () => void; +} diff --git a/web/packages/new/photos/services/ml/worker.ts b/web/packages/new/photos/services/ml/worker.ts index e71d56a85d..22013d0811 100644 --- a/web/packages/new/photos/services/ml/worker.ts +++ b/web/packages/new/photos/services/ml/worker.ts @@ -22,7 +22,7 @@ import { } from "./db"; import { pullFaceEmbeddings, putCLIPIndex, putFaceIndex } from "./embedding"; import { indexFaces, type FaceIndex } from "./face"; -import type { MLWorkerElectron } from "./worker-electron"; +import type { MLWorkerDelegate, MLWorkerElectron } from "./worker-types"; const idleDurationStart = 5; /* 5 seconds */ const idleDurationMax = 16 * 60; /* 16 minutes */ @@ -56,6 +56,7 @@ interface IndexableItem { */ export class MLWorker { private electron: MLWorkerElectron | undefined; + private delegate: MLWorkerDelegate | undefined; private userAgent: string | undefined; private state: "idle" | "pull" | "indexing" = "idle"; private shouldPull = false; @@ -73,9 +74,13 @@ export class MLWorker { * @param electron The {@link MLWorkerElectron} that allows the worker to * use the functionality provided by our Node.js layer when running in the * context of our desktop app + * + * @param delegate The {@link MLWorkerDelegate} the worker can use to inform + * the main thread of interesting events. */ - async init(electron: MLWorkerElectron) { + async init(electron: MLWorkerElectron, delegate?: MLWorkerDelegate) { this.electron = electron; + this.delegate = delegate; // Set the user agent that'll be set in the generated embeddings. this.userAgent = `${clientPackageName}/${await electron.appVersion()}`; // Initialize the downloadManager running in the web worker with the @@ -202,6 +207,7 @@ export class MLWorker { items, ensure(this.electron), ensure(this.userAgent), + this.delegate, ); if (allSuccess) { // Everything is running smoothly. Reset the idle duration. @@ -276,6 +282,7 @@ const indexNextBatch = async ( items: IndexableItem[], electron: MLWorkerElectron, userAgent: string, + delegate: MLWorkerDelegate | undefined, ) => { // Don't try to index if we wouldn't be able to upload them anyway. The // liveQ has already been drained, but that's fine, it'll be rare that we @@ -293,6 +300,7 @@ const indexNextBatch = async ( for (const { enteFile, uploadItem } of items) { try { await index(enteFile, uploadItem, electron, userAgent); + delegate?.workerDidProcessFile(); // Possibly unnecessary, but let us drain the microtask queue. await wait(0); } catch { diff --git a/web/packages/new/photos/utils/native-stream.ts b/web/packages/new/photos/utils/native-stream.ts index 70b052b4c1..0475f070db 100644 --- a/web/packages/new/photos/utils/native-stream.ts +++ b/web/packages/new/photos/utils/native-stream.ts @@ -7,7 +7,7 @@ */ import type { Electron, ZipItem } from "@/next/types/ipc"; -import type { MLWorkerElectron } from "../services/ml/worker-electron"; +import type { MLWorkerElectron } from "../services/ml/worker-types"; /** * Stream the given file or zip entry from the user's local file system. From 4773c7c26267777e9bc88ca5b8c09740efc144f0 Mon Sep 17 00:00:00 2001 From: Manav Rathi Date: Thu, 11 Jul 2024 15:12:23 +0530 Subject: [PATCH 60/67] Debounce --- web/packages/new/photos/services/ml/index.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/web/packages/new/photos/services/ml/index.ts b/web/packages/new/photos/services/ml/index.ts index 39aaeec8d9..2589c95512 100644 --- a/web/packages/new/photos/services/ml/index.ts +++ b/web/packages/new/photos/services/ml/index.ts @@ -10,6 +10,7 @@ import { ensureElectron } from "@/next/electron"; import log from "@/next/log"; import { ComlinkWorker } from "@/next/worker/comlink-worker"; import { proxy } from "comlink"; +import pDebounce from "p-debounce"; import { getRemoteFlag, updateRemoteFlag } from "../remote-store"; import type { UploadItem } from "../upload/types"; import { regenerateFaceCrops } from "./crop"; @@ -410,7 +411,7 @@ const setInterimScheduledStatus = () => { setMLStatusSnapshot({ phase: "scheduled", nSyncedFiles, nTotalFiles }); }; -const workerDidProcessFile = () => triggerStatusUpdate(); +const workerDidProcessFile = () => void pDebounce(triggerStatusUpdate, 2000)(); /** * Return the IDs of all the faces in the given {@link enteFile} that are not From 349a5021a50e0591e2c9cd7047770068eb3dc4d6 Mon Sep 17 00:00:00 2001 From: Manav Rathi Date: Thu, 11 Jul 2024 20:07:31 +0530 Subject: [PATCH 61/67] Debounce never calls the underyling if it keeps getting called within wait --- web/packages/new/photos/services/ml/index.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/web/packages/new/photos/services/ml/index.ts b/web/packages/new/photos/services/ml/index.ts index 2589c95512..54eaac31ae 100644 --- a/web/packages/new/photos/services/ml/index.ts +++ b/web/packages/new/photos/services/ml/index.ts @@ -10,7 +10,6 @@ import { ensureElectron } from "@/next/electron"; import log from "@/next/log"; import { ComlinkWorker } from "@/next/worker/comlink-worker"; import { proxy } from "comlink"; -import pDebounce from "p-debounce"; import { getRemoteFlag, updateRemoteFlag } from "../remote-store"; import type { UploadItem } from "../upload/types"; import { regenerateFaceCrops } from "./crop"; @@ -411,7 +410,7 @@ const setInterimScheduledStatus = () => { setMLStatusSnapshot({ phase: "scheduled", nSyncedFiles, nTotalFiles }); }; -const workerDidProcessFile = () => void pDebounce(triggerStatusUpdate, 2000)(); +const workerDidProcessFile = triggerStatusUpdate; /** * Return the IDs of all the faces in the given {@link enteFile} that are not From 21b63169963b1d906e6d042dedfe60fc205c1a52 Mon Sep 17 00:00:00 2001 From: Manav Rathi Date: Thu, 11 Jul 2024 20:19:01 +0530 Subject: [PATCH 62/67] Disable ML for everyone while it is WIP Preparing for merge and the interim release --- .../components/Sidebar/AdvancedSettings.tsx | 36 ++++++++++- .../new/photos/components/MLSettingsBeta.tsx | 60 +++++++++++++++++++ web/packages/new/photos/services/ml/index.ts | 13 +++- 3 files changed, 107 insertions(+), 2 deletions(-) create mode 100644 web/packages/new/photos/components/MLSettingsBeta.tsx diff --git a/web/apps/photos/src/components/Sidebar/AdvancedSettings.tsx b/web/apps/photos/src/components/Sidebar/AdvancedSettings.tsx index 5810834636..5dfd95b30c 100644 --- a/web/apps/photos/src/components/Sidebar/AdvancedSettings.tsx +++ b/web/apps/photos/src/components/Sidebar/AdvancedSettings.tsx @@ -1,15 +1,27 @@ +import { MLSettingsBeta } from "@/new/photos/components/MLSettingsBeta"; +import { canEnableML } from "@/new/photos/services/ml"; import { EnteDrawer } from "@/new/shared/components/EnteDrawer"; import { MenuItemGroup, MenuSectionTitle } from "@/new/shared/components/Menu"; import { Titlebar } from "@/new/shared/components/Titlebar"; +import { isDesktop } from "@/next/app"; +import { pt } from "@/next/i18n"; import { EnteMenuItem } from "@ente/shared/components/Menu/EnteMenuItem"; +import ChevronRight from "@mui/icons-material/ChevronRight"; +import ScienceIcon from "@mui/icons-material/Science"; import { Box, DialogProps, Stack } from "@mui/material"; import { t } from "i18next"; import { AppContext } from "pages/_app"; -import { useContext } from "react"; +import { useContext, useEffect, useState } from "react"; export default function AdvancedSettings({ open, onClose, onRootClose }) { const appContext = useContext(AppContext); + const [showMLSettings, setShowMLSettings] = useState(false); + const [openMLSettings, setOpenMLSettings] = useState(false); + + useEffect(() => { + if (isDesktop) void canEnableML().then(setShowMLSettings); + }, []); const handleRootClose = () => { onClose(); onRootClose(); @@ -59,8 +71,30 @@ export default function AdvancedSettings({ open, onClose, onRootClose }) { /> + + {showMLSettings && ( + + } + /> + + } + onClick={() => setOpenMLSettings(true)} + label={pt("ML search")} + /> + + + )} + + setOpenMLSettings(false)} + onRootClose={handleRootClose} + /> ); } diff --git a/web/packages/new/photos/components/MLSettingsBeta.tsx b/web/packages/new/photos/components/MLSettingsBeta.tsx new file mode 100644 index 0000000000..8e50a6119a --- /dev/null +++ b/web/packages/new/photos/components/MLSettingsBeta.tsx @@ -0,0 +1,60 @@ +import { EnteDrawer } from "@/new/shared/components/EnteDrawer"; +import { Titlebar } from "@/new/shared/components/Titlebar"; +import { pt, ut } from "@/next/i18n"; +import { Box, Stack, Typography, type DialogProps } from "@mui/material"; +import React from "react"; + +interface MLSettingsBetaProps { + /** If `true`, then this drawer page is shown. */ + open: boolean; + /** Called when the user wants to go back from this drawer page. */ + onClose: () => void; + /** Called when the user wants to close the entire stack of drawers. */ + onRootClose: () => void; +} + +export const MLSettingsBeta: React.FC = ({ + open, + onClose, + onRootClose, +}) => { + const handleRootClose = () => { + onClose(); + onRootClose(); + }; + + const handleDrawerClose: DialogProps["onClose"] = (_, reason) => { + if (reason == "backdropClick") handleRootClose(); + else onClose(); + }; + + return ( + + + + + + + + {ut( + "We're putting finishing touches, coming back soon!", + )} + + + + + + ); +}; diff --git a/web/packages/new/photos/services/ml/index.ts b/web/packages/new/photos/services/ml/index.ts index 54eaac31ae..64571f1de0 100644 --- a/web/packages/new/photos/services/ml/index.ts +++ b/web/packages/new/photos/services/ml/index.ts @@ -10,6 +10,7 @@ import { ensureElectron } from "@/next/electron"; import log from "@/next/log"; import { ComlinkWorker } from "@/next/worker/comlink-worker"; import { proxy } from "comlink"; +import { isBetaUser, isInternalUser } from "../feature-flags"; import { getRemoteFlag, updateRemoteFlag } from "../remote-store"; import type { UploadItem } from "../upload/types"; import { regenerateFaceCrops } from "./crop"; @@ -103,7 +104,17 @@ export const terminateMLWorker = () => { * * ML currently only works when we're running in our desktop app. */ -export const isMLSupported = isDesktop; +// TODO-ML: +export const isMLSupported = + isDesktop && process.env.NEXT_PUBLIC_ENTE_ENABLE_WIP_ML; + +/** + * Was this someone who might've enabled the beta ML? If so, show them the + * coming back soon banner while we finalize it. + * TODO-ML: + */ +export const canEnableML = async () => + (await isInternalUser()) || (await isBetaUser()); /** * Initialize the ML subsystem if the user has enabled it in preferences. From eeab98c768499785b4832d71db1852f53c7d0c26 Mon Sep 17 00:00:00 2001 From: Manav Rathi Date: Fri, 12 Jul 2024 11:00:53 +0530 Subject: [PATCH 63/67] [server] Add a workaround for Safari to recognize Yubikeys Safari just doesn't recognize the Yubikey (macOS/iOS, NFC/USB, doesn't matter) if display name is set to the empty string. Safari's long description doesn't care to mention this requirement: https://webkit.org/blog/11312/meet-face-id-and-touch-id-for-the-web/ Tested on localhost with Safari macOS. Will test on iOS post deployment. --- server/pkg/repo/passkey/passkey.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/server/pkg/repo/passkey/passkey.go b/server/pkg/repo/passkey/passkey.go index 2c46320212..603c3ab26c 100644 --- a/server/pkg/repo/passkey/passkey.go +++ b/server/pkg/repo/passkey/passkey.go @@ -47,7 +47,9 @@ func (u *PasskeyUser) WebAuthnName() string { } func (u *PasskeyUser) WebAuthnDisplayName() string { - return u.Name + // Safari requires a display name to be set, otherwise it does not recognize + // security keys. + return u.Email } func (u *PasskeyUser) WebAuthnCredentials() []webauthn.Credential { From 0ea408379a26d43641b6c7d18d91bec48690ceb4 Mon Sep 17 00:00:00 2001 From: Manav Rathi Date: Fri, 12 Jul 2024 11:17:02 +0530 Subject: [PATCH 64/67] [server] [cli] Fix docker "FROM AS" case warnings With the latest Docker update (27.0.3), it now warns about the "FROM" and "AS" in the Dockerfile not matching. E.g. when building the server docker image: > WARN: FromAsCasing: 'as' and 'FROM' keywords' casing do not match (line 1) --- cli/Dockerfile | 2 +- cli/Dockerfile-x86 | 2 +- server/Dockerfile | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/cli/Dockerfile b/cli/Dockerfile index 827269f5f8..4e00a47645 100644 --- a/cli/Dockerfile +++ b/cli/Dockerfile @@ -1,4 +1,4 @@ -FROM golang:1.20-alpine3.17 as builder +FROM golang:1.20-alpine3.17 AS builder RUN apk add --no-cache gcc musl-dev git build-base pkgconfig libsodium-dev ENV GOOS=linux diff --git a/cli/Dockerfile-x86 b/cli/Dockerfile-x86 index 23a877cb9f..42ea9c90dc 100644 --- a/cli/Dockerfile-x86 +++ b/cli/Dockerfile-x86 @@ -1,4 +1,4 @@ -FROM golang:1.20-alpine3.17@sha256:9c2f89db6fda13c3c480749787f62fed5831699bb2c32881b8f327f1cf7bae42 as builder386 +FROM golang:1.20-alpine3.17@sha256:9c2f89db6fda13c3c480749787f62fed5831699bb2c32881b8f327f1cf7bae42 AS builder386 RUN apt-get update RUN apt-get install -y gcc RUN apt-get install -y git diff --git a/server/Dockerfile b/server/Dockerfile index d902deebfd..778d5ed8ee 100644 --- a/server/Dockerfile +++ b/server/Dockerfile @@ -1,4 +1,4 @@ -FROM golang:1.21-alpine3.17 as builder +FROM golang:1.21-alpine3.17 AS builder RUN apk add --no-cache gcc musl-dev git build-base pkgconfig libsodium-dev ENV GOOS=linux From 7047383e09c55e05e4cdd3d3f8343c3013633bc7 Mon Sep 17 00:00:00 2001 From: Manav Rathi Date: Fri, 12 Jul 2024 12:19:44 +0530 Subject: [PATCH 65/67] [accounts] Restore the workaround for Safari This restores the workaround I'd removed in 4d84e966b0298a92de895c4dedc3390d8fda7387. listItem.transports = ["usb", "nfc", "ble", "internal"]; - This PR fixes the passkey verification on Safari. - Sibling PR that fixes the passkey registration: https://github.com/ente-io/ente/pull/2429/files --- web/apps/accounts/src/services/passkey.ts | 56 ++++++++++++++++++++++- 1 file changed, 55 insertions(+), 1 deletion(-) diff --git a/web/apps/accounts/src/services/passkey.ts b/web/apps/accounts/src/services/passkey.ts index 469881e5c6..8f2f15b6d2 100644 --- a/web/apps/accounts/src/services/passkey.ts +++ b/web/apps/accounts/src/services/passkey.ts @@ -454,7 +454,61 @@ export const beginPasskeyAuthentication = async ( */ export const signChallenge = async ( publicKey: PublicKeyCredentialRequestOptions, -) => nullToUndefined(await navigator.credentials.get({ publicKey })); +) => { + // Hint all transports to make security keys like Yubikey work across + // varying registration/verification scenarios. + // + // During verification, we need to pass a `transport` property. + // + // > The `transports` property is hint of the methods that the client could + // > use to communicate with the relevant authenticator of the public key + // > credential to retrieve. Possible values are ["ble", "hybrid", + // > "internal", "nfc", "usb"]. + // > + // > MDN + // + // When we register a passkey, we save the transport alongwith the + // credential. During authentication, we pass that transport back to the + // browser. This is the approach recommended by the spec: + // + // > When registering a new credential, the Relying Party SHOULD store the + // > value returned from getTransports(). When creating a + // > PublicKeyCredentialDescriptor for that credential, the Relying Party + // > SHOULD retrieve that stored value and set it as the value of the + // > transports member. + // > + // > https://www.w3.org/TR/webauthn-3/#dom-publickeycredentialdescriptor-transports + // + // However, following this recommendation break things currently (2024) in + // various ways. For example, if a user registers a Yubikey NFC security key + // on Firefox on their laptop, then Firefox returns ["usb"]. This is + // incorrect, it should be ["usb", "nfc"] (which is what Chrome does, since + // the hardware itself supports both USB and NFC transports). + // + // Later, if the user tries to verifying with their security key on their + // iPhone Safari via NFC, the browser doesn't recognize it (which seems + // incorrect too, the transport is meant to be a "hint" not a binding). + // + // > Note that these hints represent the WebAuthn Relying Party's best + // > belief as to how an authenticator may be reached. + // > + // > https://www.w3.org/TR/webauthn-3/#dom-publickeycredentialdescriptor-transports + // + // As a workaround, we override transports with known possible values. + + for (const cred of publicKey.allowCredentials ?? []) { + cred.transports = [ + ...(cred.transports ?? []), + "usb", + "nfc", + "ble", + "hybrid", + "internal", + ]; + } + + return nullToUndefined(await navigator.credentials.get({ publicKey })); +}; interface FinishPasskeyAuthenticationOptions { passkeySessionID: string; From 95c04b554c86b0542b2b5aa9c702fe57a9c13278 Mon Sep 17 00:00:00 2001 From: Neeraj Gupta <254676+ua741@users.noreply.github.com> Date: Fri, 12 Jul 2024 13:59:03 +0530 Subject: [PATCH 66/67] [mob] Add missing tr file for Turkish --- mobile/lib/generated/intl/messages_all.dart | 4 + mobile/lib/generated/intl/messages_de.dart | 167 +- mobile/lib/generated/intl/messages_en.dart | 136 +- mobile/lib/generated/intl/messages_es.dart | 132 +- mobile/lib/generated/intl/messages_fr.dart | 132 +- mobile/lib/generated/intl/messages_it.dart | 128 +- mobile/lib/generated/intl/messages_nl.dart | 218 ++- mobile/lib/generated/intl/messages_pl.dart | 4 +- mobile/lib/generated/intl/messages_pt.dart | 184 +- mobile/lib/generated/intl/messages_ru.dart | 132 +- mobile/lib/generated/intl/messages_tr.dart | 1710 +++++++++++++++++++ mobile/lib/generated/intl/messages_zh.dart | 166 +- mobile/lib/generated/l10n.dart | 1 + mobile/lib/l10n/intl_en.arb | 1 + mobile/lib/l10n/intl_tr.arb | 1279 ++++++++++++++ mobile/pubspec.lock | 16 +- mobile/pubspec.yaml | 1 + 17 files changed, 3738 insertions(+), 673 deletions(-) create mode 100644 mobile/lib/generated/intl/messages_tr.dart create mode 100644 mobile/lib/l10n/intl_tr.arb diff --git a/mobile/lib/generated/intl/messages_all.dart b/mobile/lib/generated/intl/messages_all.dart index aa2bd004dd..e274c0ccdb 100644 --- a/mobile/lib/generated/intl/messages_all.dart +++ b/mobile/lib/generated/intl/messages_all.dart @@ -28,6 +28,7 @@ import 'messages_no.dart' as messages_no; import 'messages_pl.dart' as messages_pl; import 'messages_pt.dart' as messages_pt; import 'messages_ru.dart' as messages_ru; +import 'messages_tr.dart' as messages_tr; import 'messages_zh.dart' as messages_zh; typedef Future LibraryLoader(); @@ -44,6 +45,7 @@ Map _deferredLibraries = { 'pl': () => new SynchronousFuture(null), 'pt': () => new SynchronousFuture(null), 'ru': () => new SynchronousFuture(null), + 'tr': () => new SynchronousFuture(null), 'zh': () => new SynchronousFuture(null), }; @@ -73,6 +75,8 @@ MessageLookupByLibrary? _findExact(String localeName) { return messages_pt.messages; case 'ru': return messages_ru.messages; + case 'tr': + return messages_tr.messages; case 'zh': return messages_zh.messages; default: diff --git a/mobile/lib/generated/intl/messages_de.dart b/mobile/lib/generated/intl/messages_de.dart index 7cc6c8c726..fa53d3ac76 100644 --- a/mobile/lib/generated/intl/messages_de.dart +++ b/mobile/lib/generated/intl/messages_de.dart @@ -127,92 +127,94 @@ class MessageLookup extends MessageLookupByLibrary { static String m36(albumName) => "Erfolgreich zu ${albumName} hinzugefügt"; - static String m37(passwordStrengthValue) => + static String m37(name) => "Nicht ${name}?"; + + static String m38(passwordStrengthValue) => "Passwortstärke: ${passwordStrengthValue}"; - static String m38(providerName) => + static String m39(providerName) => "Bitte kontaktiere den Support von ${providerName}, falls etwas abgebucht wurde"; - static String m39(endDate) => + static String m40(endDate) => "Kostenlose Testversion gültig bis ${endDate}.\nSie können anschließend ein bezahltes Paket auswählen."; - static String m40(toEmail) => "Bitte sende uns eine E-Mail an ${toEmail}"; + static String m41(toEmail) => "Bitte sende uns eine E-Mail an ${toEmail}"; - static String m41(toEmail) => "Bitte sende die Protokolle an ${toEmail}"; + static String m42(toEmail) => "Bitte sende die Protokolle an ${toEmail}"; - static String m42(storeName) => "Bewerte uns auf ${storeName}"; + static String m43(storeName) => "Bewerte uns auf ${storeName}"; - static String m43(storageInGB) => + static String m44(storageInGB) => "3. Ihr beide erhaltet ${storageInGB} GB* kostenlos"; - static String m44(userEmail) => + static String m45(userEmail) => "${userEmail} wird aus diesem geteilten Album entfernt\n\nAlle von ihnen hinzugefügte Fotos werden ebenfalls aus dem Album entfernt"; - static String m45(endDate) => "Erneuert am ${endDate}"; + static String m46(endDate) => "Erneuert am ${endDate}"; - static String m46(count) => + static String m47(count) => "${Intl.plural(count, one: '${count} Ergebnis gefunden', other: '${count} Ergebnisse gefunden')}"; - static String m47(count) => "${count} ausgewählt"; + static String m48(count) => "${count} ausgewählt"; - static String m48(count, yourCount) => + static String m49(count, yourCount) => "${count} ausgewählt (${yourCount} von Ihnen)"; - static String m49(verificationID) => + static String m50(verificationID) => "Hier ist meine Verifizierungs-ID: ${verificationID} für ente.io."; - static String m50(verificationID) => + static String m51(verificationID) => "Hey, kannst du bestätigen, dass dies deine ente.io Verifizierungs-ID ist: ${verificationID}"; - static String m51(referralCode, referralStorageInGB) => + static String m52(referralCode, referralStorageInGB) => "Ente Weiterempfehlungs-Code: ${referralCode} \n\nEinlösen unter Einstellungen → Allgemein → Weiterempfehlungen, um ${referralStorageInGB} GB kostenlos zu erhalten, sobald Sie einen kostenpflichtigen Tarif abgeschlossen haben\n\nhttps://ente.io"; - static String m52(numberOfPeople) => + static String m53(numberOfPeople) => "${Intl.plural(numberOfPeople, zero: 'Teile mit bestimmten Personen', one: 'Teilen mit 1 Person', other: 'Teilen mit ${numberOfPeople} Personen')}"; - static String m53(emailIDs) => "Geteilt mit ${emailIDs}"; + static String m54(emailIDs) => "Geteilt mit ${emailIDs}"; - static String m54(fileType) => + static String m55(fileType) => "Dieses ${fileType} wird von deinem Gerät gelöscht."; - static String m55(fileType) => + static String m56(fileType) => "Diese Datei ist sowohl in Ente als auch auf deinem Gerät."; - static String m56(fileType) => "Diese Datei wird von Ente gelöscht."; + static String m57(fileType) => "Diese Datei wird von Ente gelöscht."; - static String m57(storageAmountInGB) => "${storageAmountInGB} GB"; + static String m58(storageAmountInGB) => "${storageAmountInGB} GB"; - static String m58( + static String m59( usedAmount, usedStorageUnit, totalAmount, totalStorageUnit) => "${usedAmount} ${usedStorageUnit} von ${totalAmount} ${totalStorageUnit} verwendet"; - static String m59(id) => + static String m60(id) => "Ihr ${id} ist bereits mit einem anderen Ente-Konto verknüpft.\nWenn Sie Ihre ${id} mit diesem Konto verwenden möchten, kontaktieren Sie bitte unseren Support"; - static String m60(endDate) => "Ihr Abo endet am ${endDate}"; + static String m61(endDate) => "Ihr Abo endet am ${endDate}"; - static String m61(completed, total) => + static String m62(completed, total) => "${completed}/${total} Erinnerungsstücke gesichert"; - static String m62(storageAmountInGB) => + static String m63(storageAmountInGB) => "Diese erhalten auch ${storageAmountInGB} GB"; - static String m63(email) => "Dies ist ${email}s Verifizierungs-ID"; + static String m64(email) => "Dies ist ${email}s Verifizierungs-ID"; - static String m64(count) => + static String m65(count) => "${Intl.plural(count, zero: '', one: '1 Tag', other: '${count} Tage')}"; - static String m65(endDate) => "Gültig bis ${endDate}"; + static String m66(endDate) => "Gültig bis ${endDate}"; - static String m66(email) => "Verifiziere ${email}"; + static String m67(email) => "Verifiziere ${email}"; - static String m67(email) => + static String m68(email) => "Wir haben eine E-Mail an ${email} gesendet"; - static String m68(count) => + static String m69(count) => "${Intl.plural(count, one: 'vor einem Jahr', other: 'vor ${count} Jahren')}"; - static String m69(storageSaved) => + static String m70(storageSaved) => "Du hast ${storageSaved} erfolgreich freigegeben!"; final messages = _notInlinedMessages(_notInlinedMessages); @@ -309,7 +311,7 @@ class MessageLookup extends MessageLookupByLibrary { MessageLookupByLibrary.simpleMessage("Android, iOS, Web, Desktop"), "androidSignInTitle": MessageLookupByLibrary.simpleMessage( "Authentifizierung erforderlich"), - "appLock": MessageLookupByLibrary.simpleMessage("App lock"), + "appLock": MessageLookupByLibrary.simpleMessage("App-Sperre"), "appVersion": m7, "appleId": MessageLookupByLibrary.simpleMessage("Apple ID"), "apply": MessageLookupByLibrary.simpleMessage("Anwenden"), @@ -613,7 +615,7 @@ class MessageLookup extends MessageLookupByLibrary { "deviceCodeHint": MessageLookupByLibrary.simpleMessage("Code eingeben"), "deviceFilesAutoUploading": MessageLookupByLibrary.simpleMessage( "Dateien, die zu diesem Album hinzugefügt werden, werden automatisch zu Ente hochgeladen."), - "deviceLock": MessageLookupByLibrary.simpleMessage("Device lock"), + "deviceLock": MessageLookupByLibrary.simpleMessage("Gerätsperre"), "deviceLockExplanation": MessageLookupByLibrary.simpleMessage( "Verhindern, dass der Bildschirm gesperrt wird, während die App im Vordergrund ist und eine Sicherung läuft. Das ist normalerweise nicht notwendig, kann aber dabei helfen, große Uploads wie einen Erstimport schneller abzuschließen."), "deviceNotFound": @@ -708,7 +710,7 @@ class MessageLookup extends MessageLookupByLibrary { "Gib ein Passwort ein, mit dem wir deine Daten verschlüsseln können"), "enterPersonName": MessageLookupByLibrary.simpleMessage("Namen der Person eingeben"), - "enterPin": MessageLookupByLibrary.simpleMessage("Enter PIN"), + "enterPin": MessageLookupByLibrary.simpleMessage("PIN eingeben"), "enterReferralCode": MessageLookupByLibrary.simpleMessage( "Gib den Weiterempfehlungs-Code ein"), "enterThe6digitCodeFromnyourAuthenticatorApp": @@ -1015,7 +1017,7 @@ class MessageLookup extends MessageLookupByLibrary { "newAlbum": MessageLookupByLibrary.simpleMessage("Neues Album"), "newToEnte": MessageLookupByLibrary.simpleMessage("Neu bei Ente"), "newest": MessageLookupByLibrary.simpleMessage("Zuletzt"), - "next": MessageLookupByLibrary.simpleMessage("Next"), + "next": MessageLookupByLibrary.simpleMessage("Weiter"), "no": MessageLookupByLibrary.simpleMessage("Nein"), "noAlbumsSharedByYouYet": MessageLookupByLibrary.simpleMessage( "Noch keine Alben von dir geteilt"), @@ -1046,7 +1048,8 @@ class MessageLookup extends MessageLookupByLibrary { "noResultsFound": MessageLookupByLibrary.simpleMessage("Keine Ergebnisse gefunden"), "noSystemLockFound": - MessageLookupByLibrary.simpleMessage("No system lock found"), + MessageLookupByLibrary.simpleMessage("Keine Systemsperre gefunden"), + "notPersonLabel": m37, "nothingSharedWithYouYet": MessageLookupByLibrary.simpleMessage("Noch nichts mit Dir geteilt"), "nothingToSeeHere": MessageLookupByLibrary.simpleMessage( @@ -1084,7 +1087,7 @@ class MessageLookup extends MessageLookupByLibrary { "passwordChangedSuccessfully": MessageLookupByLibrary.simpleMessage( "Passwort erfolgreich geändert"), "passwordLock": MessageLookupByLibrary.simpleMessage("Passwort Sperre"), - "passwordStrength": m37, + "passwordStrength": m38, "passwordWarning": MessageLookupByLibrary.simpleMessage( "Wir speichern dieses Passwort nicht. Wenn du es vergisst, können wir deine Daten nicht entschlüsseln"), "paymentDetails": @@ -1093,7 +1096,7 @@ class MessageLookup extends MessageLookupByLibrary { MessageLookupByLibrary.simpleMessage("Zahlung fehlgeschlagen"), "paymentFailedMessage": MessageLookupByLibrary.simpleMessage( "Leider ist deine Zahlung fehlgeschlagen. Wende dich an unseren Support und wir helfen dir weiter!"), - "paymentFailedTalkToProvider": m38, + "paymentFailedTalkToProvider": m39, "pendingItems": MessageLookupByLibrary.simpleMessage("Ausstehende Elemente"), "pendingSync": @@ -1119,10 +1122,10 @@ class MessageLookup extends MessageLookupByLibrary { "pickCenterPoint": MessageLookupByLibrary.simpleMessage("Mittelpunkt auswählen"), "pinAlbum": MessageLookupByLibrary.simpleMessage("Album anheften"), - "pinLock": MessageLookupByLibrary.simpleMessage("PIN lock"), + "pinLock": MessageLookupByLibrary.simpleMessage("PIN-Sperre"), "playOnTv": MessageLookupByLibrary.simpleMessage( "Album auf dem Fernseher wiedergeben"), - "playStoreFreeTrialValidTill": m39, + "playStoreFreeTrialValidTill": m40, "playstoreSubscription": MessageLookupByLibrary.simpleMessage("PlayStore Abo"), "pleaseCheckYourInternetConnectionAndTryAgain": @@ -1134,12 +1137,12 @@ class MessageLookup extends MessageLookupByLibrary { "pleaseContactSupportIfTheProblemPersists": MessageLookupByLibrary.simpleMessage( "Bitte wenden Sie sich an den Support, falls das Problem weiterhin besteht"), - "pleaseEmailUsAt": m40, + "pleaseEmailUsAt": m41, "pleaseGrantPermissions": MessageLookupByLibrary.simpleMessage( "Bitte erteile die nötigen Berechtigungen"), "pleaseLoginAgain": MessageLookupByLibrary.simpleMessage("Bitte logge dich erneut ein"), - "pleaseSendTheLogsTo": m41, + "pleaseSendTheLogsTo": m42, "pleaseTryAgain": MessageLookupByLibrary.simpleMessage("Bitte versuche es erneut"), "pleaseVerifyTheCodeYouHaveEntered": @@ -1175,7 +1178,7 @@ class MessageLookup extends MessageLookupByLibrary { "raiseTicket": MessageLookupByLibrary.simpleMessage("Ticket erstellen"), "rateTheApp": MessageLookupByLibrary.simpleMessage("App bewerten"), "rateUs": MessageLookupByLibrary.simpleMessage("Bewerte uns"), - "rateUsOnStore": m42, + "rateUsOnStore": m43, "recover": MessageLookupByLibrary.simpleMessage("Wiederherstellen"), "recoverAccount": MessageLookupByLibrary.simpleMessage("Konto wiederherstellen"), @@ -1203,15 +1206,16 @@ class MessageLookup extends MessageLookupByLibrary { MessageLookupByLibrary.simpleMessage("Passwort wiederherstellen"), "reddit": MessageLookupByLibrary.simpleMessage("Reddit"), "reenterPassword": - MessageLookupByLibrary.simpleMessage("Re-enter password"), - "reenterPin": MessageLookupByLibrary.simpleMessage("Re-enter PIN"), + MessageLookupByLibrary.simpleMessage("Passwort erneut eingeben"), + "reenterPin": + MessageLookupByLibrary.simpleMessage("PIN erneut eingeben"), "referFriendsAnd2xYourPlan": MessageLookupByLibrary.simpleMessage( "Begeistere Freunde für uns und verdopple deinen Speicher"), "referralStep1": MessageLookupByLibrary.simpleMessage( "1. Gib diesen Code an deine Freunde"), "referralStep2": MessageLookupByLibrary.simpleMessage( "2. Sie schließen ein bezahltes Abo ab"), - "referralStep3": m43, + "referralStep3": m44, "referrals": MessageLookupByLibrary.simpleMessage("Weiterempfehlungen"), "referralsAreCurrentlyPaused": MessageLookupByLibrary.simpleMessage( "Einlösungen sind derzeit pausiert"), @@ -1239,7 +1243,7 @@ class MessageLookup extends MessageLookupByLibrary { "removeLink": MessageLookupByLibrary.simpleMessage("Link entfernen"), "removeParticipant": MessageLookupByLibrary.simpleMessage("Teilnehmer entfernen"), - "removeParticipantBody": m44, + "removeParticipantBody": m45, "removePersonLabel": MessageLookupByLibrary.simpleMessage("Personenetikett entfernen"), "removePublicLink": @@ -1255,7 +1259,7 @@ class MessageLookup extends MessageLookupByLibrary { "renameFile": MessageLookupByLibrary.simpleMessage("Datei umbenennen"), "renewSubscription": MessageLookupByLibrary.simpleMessage("Abonnement erneuern"), - "renewsOn": m45, + "renewsOn": m46, "reportABug": MessageLookupByLibrary.simpleMessage("Fehler melden"), "reportBug": MessageLookupByLibrary.simpleMessage("Fehler melden"), "resendEmail": @@ -1325,7 +1329,7 @@ class MessageLookup extends MessageLookupByLibrary { "Gruppiere Fotos, die innerhalb des Radius eines bestimmten Fotos aufgenommen wurden"), "searchPeopleEmptySection": MessageLookupByLibrary.simpleMessage( "Laden Sie Personen ein, damit Sie geteilte Fotos hier einsehen können"), - "searchResultCount": m46, + "searchResultCount": m47, "security": MessageLookupByLibrary.simpleMessage("Sicherheit"), "selectALocation": MessageLookupByLibrary.simpleMessage("Standort auswählen"), @@ -1352,8 +1356,8 @@ class MessageLookup extends MessageLookupByLibrary { "selectedItemsWillBeDeletedFromAllAlbumsAndMoved": MessageLookupByLibrary.simpleMessage( "Ausgewählte Elemente werden aus allen Alben gelöscht und in den Papierkorb verschoben."), - "selectedPhotos": m47, - "selectedPhotosWithYours": m48, + "selectedPhotos": m48, + "selectedPhotosWithYours": m49, "send": MessageLookupByLibrary.simpleMessage("Absenden"), "sendEmail": MessageLookupByLibrary.simpleMessage("E-Mail senden"), "sendInvite": MessageLookupByLibrary.simpleMessage("Einladung senden"), @@ -1367,8 +1371,8 @@ class MessageLookup extends MessageLookupByLibrary { "setCover": MessageLookupByLibrary.simpleMessage("Titelbild festlegen"), "setLabel": MessageLookupByLibrary.simpleMessage("Festlegen"), "setNewPassword": - MessageLookupByLibrary.simpleMessage("Set new password"), - "setNewPin": MessageLookupByLibrary.simpleMessage("Set new PIN"), + MessageLookupByLibrary.simpleMessage("Neues Passwort festlegen"), + "setNewPin": MessageLookupByLibrary.simpleMessage("Neue PIN festlegen"), "setPasswordTitle": MessageLookupByLibrary.simpleMessage("Passwort festlegen"), "setRadius": MessageLookupByLibrary.simpleMessage("Radius festlegen"), @@ -1381,16 +1385,16 @@ class MessageLookup extends MessageLookupByLibrary { "shareAnAlbumNow": MessageLookupByLibrary.simpleMessage("Teile jetzt ein Album"), "shareLink": MessageLookupByLibrary.simpleMessage("Link teilen"), - "shareMyVerificationID": m49, + "shareMyVerificationID": m50, "shareOnlyWithThePeopleYouWant": MessageLookupByLibrary.simpleMessage( "Teile mit ausgewählten Personen"), - "shareTextConfirmOthersVerificationID": m50, + "shareTextConfirmOthersVerificationID": m51, "shareTextRecommendUsingEnte": MessageLookupByLibrary.simpleMessage( "Hol dir Ente, damit wir ganz einfach Fotos und Videos in Originalqualität teilen können\n\nhttps://ente.io"), - "shareTextReferralCode": m51, + "shareTextReferralCode": m52, "shareWithNonenteUsers": MessageLookupByLibrary.simpleMessage( "Mit Nicht-Ente-Benutzern teilen"), - "shareWithPeopleSectionTitle": m52, + "shareWithPeopleSectionTitle": m53, "shareYourFirstAlbum": MessageLookupByLibrary.simpleMessage("Teile dein erstes Album"), "sharedAlbumSectionDescription": MessageLookupByLibrary.simpleMessage( @@ -1401,7 +1405,7 @@ class MessageLookup extends MessageLookupByLibrary { MessageLookupByLibrary.simpleMessage("Neue geteilte Fotos"), "sharedPhotoNotificationsExplanation": MessageLookupByLibrary.simpleMessage( "Erhalte Benachrichtigungen, wenn jemand ein Foto zu einem gemeinsam genutzten Album hinzufügt, dem du angehörst"), - "sharedWith": m53, + "sharedWith": m54, "sharedWithMe": MessageLookupByLibrary.simpleMessage("Mit mir geteilt"), "sharedWithYou": MessageLookupByLibrary.simpleMessage("Mit dir geteilt"), @@ -1416,11 +1420,11 @@ class MessageLookup extends MessageLookupByLibrary { MessageLookupByLibrary.simpleMessage("Andere Geräte abmelden"), "signUpTerms": MessageLookupByLibrary.simpleMessage( "Ich stimme den Nutzungsbedingungen und der Datenschutzerklärung zu"), - "singleFileDeleteFromDevice": m54, + "singleFileDeleteFromDevice": m55, "singleFileDeleteHighlight": MessageLookupByLibrary.simpleMessage( "Es wird aus allen Alben gelöscht."), - "singleFileInBothLocalAndRemote": m55, - "singleFileInRemoteOnly": m56, + "singleFileInBothLocalAndRemote": m56, + "singleFileInRemoteOnly": m57, "skip": MessageLookupByLibrary.simpleMessage("Überspringen"), "social": MessageLookupByLibrary.simpleMessage("Social Media"), "someItemsAreInBothEnteAndYourDevice": @@ -1466,13 +1470,13 @@ class MessageLookup extends MessageLookupByLibrary { "storage": MessageLookupByLibrary.simpleMessage("Speicherplatz"), "storageBreakupFamily": MessageLookupByLibrary.simpleMessage("Familie"), "storageBreakupYou": MessageLookupByLibrary.simpleMessage("Sie"), - "storageInGB": m57, + "storageInGB": m58, "storageLimitExceeded": MessageLookupByLibrary.simpleMessage( "Speichergrenze überschritten"), - "storageUsageInfo": m58, + "storageUsageInfo": m59, "strongStrength": MessageLookupByLibrary.simpleMessage("Stark"), - "subAlreadyLinkedErrMessage": m59, - "subWillBeCancelledOn": m60, + "subAlreadyLinkedErrMessage": m60, + "subWillBeCancelledOn": m61, "subscribe": MessageLookupByLibrary.simpleMessage("Abonnieren"), "subscribeToEnableSharing": MessageLookupByLibrary.simpleMessage( "Sieht aus, als sei dein Abonnement abgelaufen. Bitte abonniere, um das Teilen zu aktivieren."), @@ -1489,7 +1493,7 @@ class MessageLookup extends MessageLookupByLibrary { "suggestFeatures": MessageLookupByLibrary.simpleMessage("Verbesserung vorschlagen"), "support": MessageLookupByLibrary.simpleMessage("Support"), - "syncProgress": m61, + "syncProgress": m62, "syncStopped": MessageLookupByLibrary.simpleMessage("Synchronisierung angehalten"), "syncing": MessageLookupByLibrary.simpleMessage("Synchronisiere …"), @@ -1498,7 +1502,8 @@ class MessageLookup extends MessageLookupByLibrary { MessageLookupByLibrary.simpleMessage("zum Kopieren antippen"), "tapToEnterCode": MessageLookupByLibrary.simpleMessage( "Antippen, um den Code einzugeben"), - "tapToUnlock": MessageLookupByLibrary.simpleMessage("Tap to unlock"), + "tapToUnlock": + MessageLookupByLibrary.simpleMessage("Zum Entsperren antippen"), "tempErrorContactSupportIfPersists": MessageLookupByLibrary.simpleMessage( "Etwas ist schiefgelaufen. Bitte versuche es später noch einmal. Sollte der Fehler weiter bestehen, kontaktiere unser Supportteam."), "terminate": MessageLookupByLibrary.simpleMessage("Beenden"), @@ -1519,7 +1524,7 @@ class MessageLookup extends MessageLookupByLibrary { "theseItemsWillBeDeletedFromYourDevice": MessageLookupByLibrary.simpleMessage( "Diese Elemente werden von deinem Gerät gelöscht."), - "theyAlsoGetXGb": m62, + "theyAlsoGetXGb": m63, "theyWillBeDeletedFromAllAlbums": MessageLookupByLibrary.simpleMessage( "Sie werden aus allen Alben gelöscht."), "thisActionCannotBeUndone": MessageLookupByLibrary.simpleMessage( @@ -1535,7 +1540,7 @@ class MessageLookup extends MessageLookupByLibrary { "Diese E-Mail-Adresse wird bereits verwendet"), "thisImageHasNoExifData": MessageLookupByLibrary.simpleMessage( "Dieses Bild hat keine Exif-Daten"), - "thisIsPersonVerificationId": m63, + "thisIsPersonVerificationId": m64, "thisIsYourVerificationId": MessageLookupByLibrary.simpleMessage( "Dies ist deine Verifizierungs-ID"), "thisWillLogYouOutOfTheFollowingDevice": @@ -1545,19 +1550,19 @@ class MessageLookup extends MessageLookupByLibrary { "Dadurch wirst du von diesem Gerät abgemeldet!"), "toEnableAppLockPleaseSetupDevicePasscodeOrScreen": MessageLookupByLibrary.simpleMessage( - "To enable app lock, please setup device passcode or screen lock in your system settings."), + "Um die App-Sperre zu aktivieren, konfigurieren Sie bitte den Gerätepasscode oder die Bildschirmsperre in Ihren Systemeinstellungen."), "toHideAPhotoOrVideo": MessageLookupByLibrary.simpleMessage("Foto oder Video verstecken"), "toResetVerifyEmail": MessageLookupByLibrary.simpleMessage( "Um dein Passwort zurückzusetzen, verifiziere bitte zuerst deine E-Mail Adresse."), "todaysLogs": MessageLookupByLibrary.simpleMessage("Heutiges Protokoll"), - "tooManyIncorrectAttempts": - MessageLookupByLibrary.simpleMessage("Too many incorrect attempts"), + "tooManyIncorrectAttempts": MessageLookupByLibrary.simpleMessage( + "Zu viele fehlerhafte Versuche"), "total": MessageLookupByLibrary.simpleMessage("Gesamt"), "totalSize": MessageLookupByLibrary.simpleMessage("Gesamtgröße"), "trash": MessageLookupByLibrary.simpleMessage("Papierkorb"), - "trashDaysLeft": m64, + "trashDaysLeft": m65, "trim": MessageLookupByLibrary.simpleMessage("Schneiden"), "tryAgain": MessageLookupByLibrary.simpleMessage("Erneut versuchen"), "turnOnBackupForAutoUpload": MessageLookupByLibrary.simpleMessage( @@ -1604,6 +1609,8 @@ class MessageLookup extends MessageLookupByLibrary { "Bis zu 50% Rabatt bis zum 4. Dezember."), "usableReferralStorageInfo": MessageLookupByLibrary.simpleMessage( "Der verwendbare Speicherplatz ist von deinem aktuellen Abonnement eingeschränkt. Überschüssiger, beanspruchter Speicherplatz wird automatisch verwendbar werden, wenn du ein höheres Abonnement buchst."), + "useAsCover": + MessageLookupByLibrary.simpleMessage("Als Titelbild festlegen"), "usePublicLinksForPeopleNotOnEnte": MessageLookupByLibrary.simpleMessage( "Verwenden Sie öffentliche Links für Personen, die kein Ente-Konto haben"), "useRecoveryKey": MessageLookupByLibrary.simpleMessage( @@ -1612,7 +1619,7 @@ class MessageLookup extends MessageLookupByLibrary { MessageLookupByLibrary.simpleMessage("Ausgewähltes Foto verwenden"), "usedSpace": MessageLookupByLibrary.simpleMessage("Belegter Speicherplatz"), - "validTill": m65, + "validTill": m66, "verificationFailedPleaseTryAgain": MessageLookupByLibrary.simpleMessage( "Verifizierung fehlgeschlagen, bitte versuchen Sie es erneut"), @@ -1621,7 +1628,7 @@ class MessageLookup extends MessageLookupByLibrary { "verify": MessageLookupByLibrary.simpleMessage("Überprüfen"), "verifyEmail": MessageLookupByLibrary.simpleMessage("E-Mail-Adresse verifizieren"), - "verifyEmailID": m66, + "verifyEmailID": m67, "verifyIDLabel": MessageLookupByLibrary.simpleMessage("Überprüfen"), "verifyPasskey": MessageLookupByLibrary.simpleMessage("Passkey verifizieren"), @@ -1657,13 +1664,13 @@ class MessageLookup extends MessageLookupByLibrary { "weDontSupportEditingPhotosAndAlbumsThatYouDont": MessageLookupByLibrary.simpleMessage( "Wir unterstützen keine Bearbeitung von Fotos und Alben, die du noch nicht besitzt"), - "weHaveSendEmailTo": m67, + "weHaveSendEmailTo": m68, "weakStrength": MessageLookupByLibrary.simpleMessage("Schwach"), "welcomeBack": MessageLookupByLibrary.simpleMessage("Willkommen zurück!"), "whatsNew": MessageLookupByLibrary.simpleMessage("Neue Funktionen"), "yearly": MessageLookupByLibrary.simpleMessage("Jährlich"), - "yearsAgo": m68, + "yearsAgo": m69, "yes": MessageLookupByLibrary.simpleMessage("Ja"), "yesCancel": MessageLookupByLibrary.simpleMessage("Ja, kündigen"), "yesConvertToViewer": MessageLookupByLibrary.simpleMessage( @@ -1693,7 +1700,7 @@ class MessageLookup extends MessageLookupByLibrary { "Du kannst nicht mit dir selbst teilen"), "youDontHaveAnyArchivedItems": MessageLookupByLibrary.simpleMessage( "Du hast keine archivierten Elemente."), - "youHaveSuccessfullyFreedUp": m69, + "youHaveSuccessfullyFreedUp": m70, "yourAccountHasBeenDeleted": MessageLookupByLibrary.simpleMessage( "Dein Benutzerkonto wurde gelöscht"), "yourMap": MessageLookupByLibrary.simpleMessage("Deine Karte"), diff --git a/mobile/lib/generated/intl/messages_en.dart b/mobile/lib/generated/intl/messages_en.dart index 8131326606..90a82c55c9 100644 --- a/mobile/lib/generated/intl/messages_en.dart +++ b/mobile/lib/generated/intl/messages_en.dart @@ -125,94 +125,94 @@ class MessageLookup extends MessageLookupByLibrary { static String m36(albumName) => "Moved successfully to ${albumName}"; - static String m70(name) => "Not ${name}?"; + static String m37(name) => "Not ${name}?"; - static String m37(passwordStrengthValue) => + static String m38(passwordStrengthValue) => "Password strength: ${passwordStrengthValue}"; - static String m38(providerName) => + static String m39(providerName) => "Please talk to ${providerName} support if you were charged"; - static String m39(endDate) => + static String m40(endDate) => "Free trial valid till ${endDate}.\nYou can choose a paid plan afterwards."; - static String m40(toEmail) => "Please email us at ${toEmail}"; + static String m41(toEmail) => "Please email us at ${toEmail}"; - static String m41(toEmail) => "Please send the logs to \n${toEmail}"; + static String m42(toEmail) => "Please send the logs to \n${toEmail}"; - static String m42(storeName) => "Rate us on ${storeName}"; + static String m43(storeName) => "Rate us on ${storeName}"; - static String m43(storageInGB) => + static String m44(storageInGB) => "3. Both of you get ${storageInGB} GB* free"; - static String m44(userEmail) => + static String m45(userEmail) => "${userEmail} will be removed from this shared album\n\nAny photos added by them will also be removed from the album"; - static String m45(endDate) => "Subscription renews on ${endDate}"; + static String m46(endDate) => "Subscription renews on ${endDate}"; - static String m46(count) => + static String m47(count) => "${Intl.plural(count, one: '${count} result found', other: '${count} results found')}"; - static String m47(count) => "${count} selected"; + static String m48(count) => "${count} selected"; - static String m48(count, yourCount) => + static String m49(count, yourCount) => "${count} selected (${yourCount} yours)"; - static String m49(verificationID) => + static String m50(verificationID) => "Here\'s my verification ID: ${verificationID} for ente.io."; - static String m50(verificationID) => + static String m51(verificationID) => "Hey, can you confirm that this is your ente.io verification ID: ${verificationID}"; - static String m51(referralCode, referralStorageInGB) => + static String m52(referralCode, referralStorageInGB) => "Ente referral code: ${referralCode} \n\nApply it in Settings → General → Referrals to get ${referralStorageInGB} GB free after you signup for a paid plan\n\nhttps://ente.io"; - static String m52(numberOfPeople) => + static String m53(numberOfPeople) => "${Intl.plural(numberOfPeople, zero: 'Share with specific people', one: 'Shared with 1 person', other: 'Shared with ${numberOfPeople} people')}"; - static String m53(emailIDs) => "Shared with ${emailIDs}"; + static String m54(emailIDs) => "Shared with ${emailIDs}"; - static String m54(fileType) => + static String m55(fileType) => "This ${fileType} will be deleted from your device."; - static String m55(fileType) => + static String m56(fileType) => "This ${fileType} is in both Ente and your device."; - static String m56(fileType) => "This ${fileType} will be deleted from Ente."; + static String m57(fileType) => "This ${fileType} will be deleted from Ente."; - static String m57(storageAmountInGB) => "${storageAmountInGB} GB"; + static String m58(storageAmountInGB) => "${storageAmountInGB} GB"; - static String m58( + static String m59( usedAmount, usedStorageUnit, totalAmount, totalStorageUnit) => "${usedAmount} ${usedStorageUnit} of ${totalAmount} ${totalStorageUnit} used"; - static String m59(id) => + static String m60(id) => "Your ${id} is already linked to another Ente account.\nIf you would like to use your ${id} with this account, please contact our support\'\'"; - static String m60(endDate) => + static String m61(endDate) => "Your subscription will be cancelled on ${endDate}"; - static String m61(completed, total) => + static String m62(completed, total) => "${completed}/${total} memories preserved"; - static String m62(storageAmountInGB) => + static String m63(storageAmountInGB) => "They also get ${storageAmountInGB} GB"; - static String m63(email) => "This is ${email}\'s Verification ID"; + static String m64(email) => "This is ${email}\'s Verification ID"; - static String m64(count) => + static String m65(count) => "${Intl.plural(count, zero: '', one: '1 day', other: '${count} days')}"; - static String m65(endDate) => "Valid till ${endDate}"; + static String m66(endDate) => "Valid till ${endDate}"; - static String m66(email) => "Verify ${email}"; + static String m67(email) => "Verify ${email}"; - static String m67(email) => "We have sent a mail to ${email}"; + static String m68(email) => "We have sent a mail to ${email}"; - static String m68(count) => + static String m69(count) => "${Intl.plural(count, one: '${count} year ago', other: '${count} years ago')}"; - static String m69(storageSaved) => + static String m70(storageSaved) => "You have successfully freed up ${storageSaved}!"; final messages = _notInlinedMessages(_notInlinedMessages); @@ -1007,7 +1007,7 @@ class MessageLookup extends MessageLookupByLibrary { MessageLookupByLibrary.simpleMessage("No results found"), "noSystemLockFound": MessageLookupByLibrary.simpleMessage("No system lock found"), - "notPersonLabel": m70, + "notPersonLabel": m37, "nothingSharedWithYouYet": MessageLookupByLibrary.simpleMessage("Nothing shared with you yet"), "nothingToSeeHere": @@ -1043,7 +1043,7 @@ class MessageLookup extends MessageLookupByLibrary { "passwordChangedSuccessfully": MessageLookupByLibrary.simpleMessage( "Password changed successfully"), "passwordLock": MessageLookupByLibrary.simpleMessage("Password lock"), - "passwordStrength": m37, + "passwordStrength": m38, "passwordWarning": MessageLookupByLibrary.simpleMessage( "We don\'t store this password, so if you forget, we cannot decrypt your data"), "paymentDetails": @@ -1051,7 +1051,7 @@ class MessageLookup extends MessageLookupByLibrary { "paymentFailed": MessageLookupByLibrary.simpleMessage("Payment failed"), "paymentFailedMessage": MessageLookupByLibrary.simpleMessage( "Unfortunately your payment failed. Please contact support and we\'ll help you out!"), - "paymentFailedTalkToProvider": m38, + "paymentFailedTalkToProvider": m39, "pendingItems": MessageLookupByLibrary.simpleMessage("Pending items"), "pendingSync": MessageLookupByLibrary.simpleMessage("Pending sync"), "people": MessageLookupByLibrary.simpleMessage("People"), @@ -1077,7 +1077,7 @@ class MessageLookup extends MessageLookupByLibrary { "pinAlbum": MessageLookupByLibrary.simpleMessage("Pin album"), "pinLock": MessageLookupByLibrary.simpleMessage("PIN lock"), "playOnTv": MessageLookupByLibrary.simpleMessage("Play album on TV"), - "playStoreFreeTrialValidTill": m39, + "playStoreFreeTrialValidTill": m40, "playstoreSubscription": MessageLookupByLibrary.simpleMessage("PlayStore subscription"), "pleaseCheckYourInternetConnectionAndTryAgain": @@ -1089,12 +1089,12 @@ class MessageLookup extends MessageLookupByLibrary { "pleaseContactSupportIfTheProblemPersists": MessageLookupByLibrary.simpleMessage( "Please contact support if the problem persists"), - "pleaseEmailUsAt": m40, + "pleaseEmailUsAt": m41, "pleaseGrantPermissions": MessageLookupByLibrary.simpleMessage("Please grant permissions"), "pleaseLoginAgain": MessageLookupByLibrary.simpleMessage("Please login again"), - "pleaseSendTheLogsTo": m41, + "pleaseSendTheLogsTo": m42, "pleaseTryAgain": MessageLookupByLibrary.simpleMessage("Please try again"), "pleaseVerifyTheCodeYouHaveEntered": @@ -1129,7 +1129,7 @@ class MessageLookup extends MessageLookupByLibrary { "raiseTicket": MessageLookupByLibrary.simpleMessage("Raise ticket"), "rateTheApp": MessageLookupByLibrary.simpleMessage("Rate the app"), "rateUs": MessageLookupByLibrary.simpleMessage("Rate us"), - "rateUsOnStore": m42, + "rateUsOnStore": m43, "recover": MessageLookupByLibrary.simpleMessage("Recover"), "recoverAccount": MessageLookupByLibrary.simpleMessage("Recover account"), @@ -1163,7 +1163,7 @@ class MessageLookup extends MessageLookupByLibrary { "1. Give this code to your friends"), "referralStep2": MessageLookupByLibrary.simpleMessage( "2. They sign up for a paid plan"), - "referralStep3": m43, + "referralStep3": m44, "referrals": MessageLookupByLibrary.simpleMessage("Referrals"), "referralsAreCurrentlyPaused": MessageLookupByLibrary.simpleMessage( "Referrals are currently paused"), @@ -1189,7 +1189,7 @@ class MessageLookup extends MessageLookupByLibrary { "removeLink": MessageLookupByLibrary.simpleMessage("Remove link"), "removeParticipant": MessageLookupByLibrary.simpleMessage("Remove participant"), - "removeParticipantBody": m44, + "removeParticipantBody": m45, "removePersonLabel": MessageLookupByLibrary.simpleMessage("Remove person label"), "removePublicLink": @@ -1205,7 +1205,7 @@ class MessageLookup extends MessageLookupByLibrary { "renameFile": MessageLookupByLibrary.simpleMessage("Rename file"), "renewSubscription": MessageLookupByLibrary.simpleMessage("Renew subscription"), - "renewsOn": m45, + "renewsOn": m46, "reportABug": MessageLookupByLibrary.simpleMessage("Report a bug"), "reportBug": MessageLookupByLibrary.simpleMessage("Report bug"), "resendEmail": MessageLookupByLibrary.simpleMessage("Resend email"), @@ -1271,7 +1271,7 @@ class MessageLookup extends MessageLookupByLibrary { "Group photos that are taken within some radius of a photo"), "searchPeopleEmptySection": MessageLookupByLibrary.simpleMessage( "Invite people, and you\'ll see all photos shared by them here"), - "searchResultCount": m46, + "searchResultCount": m47, "security": MessageLookupByLibrary.simpleMessage("Security"), "selectALocation": MessageLookupByLibrary.simpleMessage("Select a location"), @@ -1298,8 +1298,8 @@ class MessageLookup extends MessageLookupByLibrary { "selectedItemsWillBeDeletedFromAllAlbumsAndMoved": MessageLookupByLibrary.simpleMessage( "Selected items will be deleted from all albums and moved to trash."), - "selectedPhotos": m47, - "selectedPhotosWithYours": m48, + "selectedPhotos": m48, + "selectedPhotosWithYours": m49, "send": MessageLookupByLibrary.simpleMessage("Send"), "sendEmail": MessageLookupByLibrary.simpleMessage("Send email"), "sendInvite": MessageLookupByLibrary.simpleMessage("Send invite"), @@ -1326,16 +1326,16 @@ class MessageLookup extends MessageLookupByLibrary { "shareAnAlbumNow": MessageLookupByLibrary.simpleMessage("Share an album now"), "shareLink": MessageLookupByLibrary.simpleMessage("Share link"), - "shareMyVerificationID": m49, + "shareMyVerificationID": m50, "shareOnlyWithThePeopleYouWant": MessageLookupByLibrary.simpleMessage( "Share only with the people you want"), - "shareTextConfirmOthersVerificationID": m50, + "shareTextConfirmOthersVerificationID": m51, "shareTextRecommendUsingEnte": MessageLookupByLibrary.simpleMessage( "Download Ente so we can easily share original quality photos and videos\n\nhttps://ente.io"), - "shareTextReferralCode": m51, + "shareTextReferralCode": m52, "shareWithNonenteUsers": MessageLookupByLibrary.simpleMessage("Share with non-Ente users"), - "shareWithPeopleSectionTitle": m52, + "shareWithPeopleSectionTitle": m53, "shareYourFirstAlbum": MessageLookupByLibrary.simpleMessage("Share your first album"), "sharedAlbumSectionDescription": MessageLookupByLibrary.simpleMessage( @@ -1346,7 +1346,7 @@ class MessageLookup extends MessageLookupByLibrary { MessageLookupByLibrary.simpleMessage("New shared photos"), "sharedPhotoNotificationsExplanation": MessageLookupByLibrary.simpleMessage( "Receive notifications when someone adds a photo to a shared album that you\'re a part of"), - "sharedWith": m53, + "sharedWith": m54, "sharedWithMe": MessageLookupByLibrary.simpleMessage("Shared with me"), "sharedWithYou": MessageLookupByLibrary.simpleMessage("Shared with you"), @@ -1360,11 +1360,11 @@ class MessageLookup extends MessageLookupByLibrary { MessageLookupByLibrary.simpleMessage("Sign out other devices"), "signUpTerms": MessageLookupByLibrary.simpleMessage( "I agree to the terms of service and privacy policy"), - "singleFileDeleteFromDevice": m54, + "singleFileDeleteFromDevice": m55, "singleFileDeleteHighlight": MessageLookupByLibrary.simpleMessage( "It will be deleted from all albums."), - "singleFileInBothLocalAndRemote": m55, - "singleFileInRemoteOnly": m56, + "singleFileInBothLocalAndRemote": m56, + "singleFileInRemoteOnly": m57, "skip": MessageLookupByLibrary.simpleMessage("Skip"), "social": MessageLookupByLibrary.simpleMessage("Social"), "someItemsAreInBothEnteAndYourDevice": @@ -1406,13 +1406,13 @@ class MessageLookup extends MessageLookupByLibrary { "storage": MessageLookupByLibrary.simpleMessage("Storage"), "storageBreakupFamily": MessageLookupByLibrary.simpleMessage("Family"), "storageBreakupYou": MessageLookupByLibrary.simpleMessage("You"), - "storageInGB": m57, + "storageInGB": m58, "storageLimitExceeded": MessageLookupByLibrary.simpleMessage("Storage limit exceeded"), - "storageUsageInfo": m58, + "storageUsageInfo": m59, "strongStrength": MessageLookupByLibrary.simpleMessage("Strong"), - "subAlreadyLinkedErrMessage": m59, - "subWillBeCancelledOn": m60, + "subAlreadyLinkedErrMessage": m60, + "subWillBeCancelledOn": m61, "subscribe": MessageLookupByLibrary.simpleMessage("Subscribe"), "subscribeToEnableSharing": MessageLookupByLibrary.simpleMessage( "Looks like your subscription has expired. Please subscribe to enable sharing."), @@ -1429,7 +1429,7 @@ class MessageLookup extends MessageLookupByLibrary { "suggestFeatures": MessageLookupByLibrary.simpleMessage("Suggest features"), "support": MessageLookupByLibrary.simpleMessage("Support"), - "syncProgress": m61, + "syncProgress": m62, "syncStopped": MessageLookupByLibrary.simpleMessage("Sync stopped"), "syncing": MessageLookupByLibrary.simpleMessage("Syncing..."), "systemTheme": MessageLookupByLibrary.simpleMessage("System"), @@ -1456,7 +1456,7 @@ class MessageLookup extends MessageLookupByLibrary { "theseItemsWillBeDeletedFromYourDevice": MessageLookupByLibrary.simpleMessage( "These items will be deleted from your device."), - "theyAlsoGetXGb": m62, + "theyAlsoGetXGb": m63, "theyWillBeDeletedFromAllAlbums": MessageLookupByLibrary.simpleMessage( "They will be deleted from all albums."), "thisActionCannotBeUndone": MessageLookupByLibrary.simpleMessage( @@ -1472,7 +1472,7 @@ class MessageLookup extends MessageLookupByLibrary { "This email is already in use"), "thisImageHasNoExifData": MessageLookupByLibrary.simpleMessage("This image has no exif data"), - "thisIsPersonVerificationId": m63, + "thisIsPersonVerificationId": m64, "thisIsYourVerificationId": MessageLookupByLibrary.simpleMessage( "This is your Verification ID"), "thisWillLogYouOutOfTheFollowingDevice": @@ -1493,7 +1493,7 @@ class MessageLookup extends MessageLookupByLibrary { "total": MessageLookupByLibrary.simpleMessage("total"), "totalSize": MessageLookupByLibrary.simpleMessage("Total size"), "trash": MessageLookupByLibrary.simpleMessage("Trash"), - "trashDaysLeft": m64, + "trashDaysLeft": m65, "trim": MessageLookupByLibrary.simpleMessage("Trim"), "tryAgain": MessageLookupByLibrary.simpleMessage("Try again"), "turnOnBackupForAutoUpload": MessageLookupByLibrary.simpleMessage( @@ -1547,7 +1547,7 @@ class MessageLookup extends MessageLookupByLibrary { "useSelectedPhoto": MessageLookupByLibrary.simpleMessage("Use selected photo"), "usedSpace": MessageLookupByLibrary.simpleMessage("Used space"), - "validTill": m65, + "validTill": m66, "verificationFailedPleaseTryAgain": MessageLookupByLibrary.simpleMessage( "Verification failed, please try again"), @@ -1555,7 +1555,7 @@ class MessageLookup extends MessageLookupByLibrary { MessageLookupByLibrary.simpleMessage("Verification ID"), "verify": MessageLookupByLibrary.simpleMessage("Verify"), "verifyEmail": MessageLookupByLibrary.simpleMessage("Verify email"), - "verifyEmailID": m66, + "verifyEmailID": m67, "verifyIDLabel": MessageLookupByLibrary.simpleMessage("Verify"), "verifyPasskey": MessageLookupByLibrary.simpleMessage("Verify passkey"), "verifyPassword": @@ -1589,12 +1589,12 @@ class MessageLookup extends MessageLookupByLibrary { "weDontSupportEditingPhotosAndAlbumsThatYouDont": MessageLookupByLibrary.simpleMessage( "We don\'t support editing photos and albums that you don\'t own yet"), - "weHaveSendEmailTo": m67, + "weHaveSendEmailTo": m68, "weakStrength": MessageLookupByLibrary.simpleMessage("Weak"), "welcomeBack": MessageLookupByLibrary.simpleMessage("Welcome back!"), "whatsNew": MessageLookupByLibrary.simpleMessage("What\'s new"), "yearly": MessageLookupByLibrary.simpleMessage("Yearly"), - "yearsAgo": m68, + "yearsAgo": m69, "yes": MessageLookupByLibrary.simpleMessage("Yes"), "yesCancel": MessageLookupByLibrary.simpleMessage("Yes, cancel"), "yesConvertToViewer": @@ -1624,7 +1624,7 @@ class MessageLookup extends MessageLookupByLibrary { "You cannot share with yourself"), "youDontHaveAnyArchivedItems": MessageLookupByLibrary.simpleMessage( "You don\'t have any archived items."), - "youHaveSuccessfullyFreedUp": m69, + "youHaveSuccessfullyFreedUp": m70, "yourAccountHasBeenDeleted": MessageLookupByLibrary.simpleMessage( "Your account has been deleted"), "yourMap": MessageLookupByLibrary.simpleMessage("Your map"), diff --git a/mobile/lib/generated/intl/messages_es.dart b/mobile/lib/generated/intl/messages_es.dart index fc2186f45c..fc25d0b4dc 100644 --- a/mobile/lib/generated/intl/messages_es.dart +++ b/mobile/lib/generated/intl/messages_es.dart @@ -129,93 +129,93 @@ class MessageLookup extends MessageLookupByLibrary { static String m36(albumName) => "Movido exitosamente a ${albumName}"; - static String m37(passwordStrengthValue) => + static String m38(passwordStrengthValue) => "Seguridad de la contraseña : ${passwordStrengthValue}"; - static String m38(providerName) => + static String m39(providerName) => "Por favor, habla con el soporte de ${providerName} si se te cobró"; - static String m39(endDate) => + static String m40(endDate) => "Prueba gratuita válida hasta ${endDate}.\nPuedes elegir un plan de pago después."; - static String m40(toEmail) => + static String m41(toEmail) => "Por favor, envíanos un correo electrónico a ${toEmail}"; - static String m41(toEmail) => "Por favor, envía los registros a ${toEmail}"; + static String m42(toEmail) => "Por favor, envía los registros a ${toEmail}"; - static String m42(storeName) => "Califícanos en ${storeName}"; + static String m43(storeName) => "Califícanos en ${storeName}"; - static String m43(storageInGB) => + static String m44(storageInGB) => "3. Ambos obtienen ${storageInGB} GB* gratis"; - static String m44(userEmail) => + static String m45(userEmail) => "${userEmail} será eliminado de este álbum compartido\n\nCualquier foto añadida por ellos también será eliminada del álbum"; - static String m45(endDate) => "La suscripción se renueva el ${endDate}"; + static String m46(endDate) => "La suscripción se renueva el ${endDate}"; - static String m46(count) => + static String m47(count) => "${Intl.plural(count, one: '${count} resultado encontrado', other: '${count} resultados encontrados')}"; - static String m47(count) => "${count} seleccionados"; + static String m48(count) => "${count} seleccionados"; - static String m48(count, yourCount) => + static String m49(count, yourCount) => "${count} seleccionados (${yourCount} tuyos)"; - static String m49(verificationID) => + static String m50(verificationID) => "Aquí está mi ID de verificación: ${verificationID} para ente.io."; - static String m50(verificationID) => + static String m51(verificationID) => "Hola, ¿puedes confirmar que esta es tu ID de verificación ente.io: ${verificationID}?"; - static String m51(referralCode, referralStorageInGB) => + static String m52(referralCode, referralStorageInGB) => "Código de referido de Ente: ${referralCode} \n\nAñádelo en Ajustes → General → Referidos para obtener ${referralStorageInGB} GB gratis tras comprar un plan de pago.\n\nhttps://ente.io"; - static String m52(numberOfPeople) => + static String m53(numberOfPeople) => "${Intl.plural(numberOfPeople, zero: 'Compartir con personas específicas', one: 'Compartido con 1 persona', other: 'Compartido con ${numberOfPeople} personas')}"; - static String m53(emailIDs) => "Compartido con ${emailIDs}"; + static String m54(emailIDs) => "Compartido con ${emailIDs}"; - static String m54(fileType) => + static String m55(fileType) => "Este ${fileType} se eliminará de tu dispositivo."; - static String m55(fileType) => + static String m56(fileType) => "Este ${fileType} está tanto en Ente como en tu dispositivo."; - static String m56(fileType) => "Este ${fileType} será eliminado de Ente."; + static String m57(fileType) => "Este ${fileType} será eliminado de Ente."; - static String m57(storageAmountInGB) => "${storageAmountInGB} GB"; + static String m58(storageAmountInGB) => "${storageAmountInGB} GB"; - static String m58( + static String m59( usedAmount, usedStorageUnit, totalAmount, totalStorageUnit) => "${usedAmount} ${usedStorageUnit} de ${totalAmount} ${totalStorageUnit} usados"; - static String m59(id) => + static String m60(id) => "Tu ${id} ya está vinculada a otra cuenta de Ente.\nSi deseas utilizar tu ${id} con esta cuenta, ponte en contacto con nuestro servicio de asistencia\'\'"; - static String m60(endDate) => "Tu suscripción se cancelará el ${endDate}"; + static String m61(endDate) => "Tu suscripción se cancelará el ${endDate}"; - static String m61(completed, total) => + static String m62(completed, total) => "${completed}/${total} recuerdos conservados"; - static String m62(storageAmountInGB) => + static String m63(storageAmountInGB) => "También obtienen ${storageAmountInGB} GB"; - static String m63(email) => "Este es el ID de verificación de ${email}"; + static String m64(email) => "Este es el ID de verificación de ${email}"; - static String m64(count) => + static String m65(count) => "${Intl.plural(count, zero: '', one: '1 día', other: '${count} días')}"; - static String m65(endDate) => "Válido hasta ${endDate}"; + static String m66(endDate) => "Válido hasta ${endDate}"; - static String m66(email) => "Verificar ${email}"; + static String m67(email) => "Verificar ${email}"; - static String m67(email) => + static String m68(email) => "Hemos enviado un correo a ${email}"; - static String m68(count) => + static String m69(count) => "${Intl.plural(count, one: '${count} año atrás', other: '${count} años atrás')}"; - static String m69(storageSaved) => "¡Has liberado ${storageSaved} con éxito!"; + static String m70(storageSaved) => "¡Has liberado ${storageSaved} con éxito!"; final messages = _notInlinedMessages(_notInlinedMessages); static Map _notInlinedMessages(_) => { @@ -1094,7 +1094,7 @@ class MessageLookup extends MessageLookupByLibrary { "Contraseña cambiada correctamente"), "passwordLock": MessageLookupByLibrary.simpleMessage("Bloqueo por contraseña"), - "passwordStrength": m37, + "passwordStrength": m38, "passwordWarning": MessageLookupByLibrary.simpleMessage( "No almacenamos esta contraseña, así que si la olvidas, no podemos descifrar tus datos"), "paymentDetails": @@ -1102,7 +1102,7 @@ class MessageLookup extends MessageLookupByLibrary { "paymentFailed": MessageLookupByLibrary.simpleMessage("Pago fallido"), "paymentFailedMessage": MessageLookupByLibrary.simpleMessage( "Lamentablemente tu pago falló. Por favor, ¡contacta con el soporte técnico y te ayudaremos!"), - "paymentFailedTalkToProvider": m38, + "paymentFailedTalkToProvider": m39, "pendingItems": MessageLookupByLibrary.simpleMessage("Elementos pendientes"), "pendingSync": @@ -1131,7 +1131,7 @@ class MessageLookup extends MessageLookupByLibrary { "pinLock": MessageLookupByLibrary.simpleMessage("PIN lock"), "playOnTv": MessageLookupByLibrary.simpleMessage("Reproducir álbum en TV"), - "playStoreFreeTrialValidTill": m39, + "playStoreFreeTrialValidTill": m40, "playstoreSubscription": MessageLookupByLibrary.simpleMessage("Suscripción en la PlayStore"), "pleaseCheckYourInternetConnectionAndTryAgain": @@ -1143,12 +1143,12 @@ class MessageLookup extends MessageLookupByLibrary { "pleaseContactSupportIfTheProblemPersists": MessageLookupByLibrary.simpleMessage( "Por favor, contacta a soporte técnico si el problema persiste"), - "pleaseEmailUsAt": m40, + "pleaseEmailUsAt": m41, "pleaseGrantPermissions": MessageLookupByLibrary.simpleMessage("Por favor, concede permiso"), "pleaseLoginAgain": MessageLookupByLibrary.simpleMessage( "Por favor, vuelve a iniciar sesión"), - "pleaseSendTheLogsTo": m41, + "pleaseSendTheLogsTo": m42, "pleaseTryAgain": MessageLookupByLibrary.simpleMessage( "Por favor, inténtalo nuevamente"), "pleaseVerifyTheCodeYouHaveEntered": @@ -1185,7 +1185,7 @@ class MessageLookup extends MessageLookupByLibrary { "rateTheApp": MessageLookupByLibrary.simpleMessage("Evalúa la aplicación"), "rateUs": MessageLookupByLibrary.simpleMessage("Califícanos"), - "rateUsOnStore": m42, + "rateUsOnStore": m43, "recover": MessageLookupByLibrary.simpleMessage("Recuperar"), "recoverAccount": MessageLookupByLibrary.simpleMessage("Recuperar cuenta"), @@ -1220,7 +1220,7 @@ class MessageLookup extends MessageLookupByLibrary { "1. Dale este código a tus amigos"), "referralStep2": MessageLookupByLibrary.simpleMessage( "2. Se inscriben a un plan pagado"), - "referralStep3": m43, + "referralStep3": m44, "referrals": MessageLookupByLibrary.simpleMessage("Referidos"), "referralsAreCurrentlyPaused": MessageLookupByLibrary.simpleMessage( "Las referencias están actualmente en pausa"), @@ -1247,7 +1247,7 @@ class MessageLookup extends MessageLookupByLibrary { "removeLink": MessageLookupByLibrary.simpleMessage("Eliminar enlace"), "removeParticipant": MessageLookupByLibrary.simpleMessage("Quitar participante"), - "removeParticipantBody": m44, + "removeParticipantBody": m45, "removePersonLabel": MessageLookupByLibrary.simpleMessage( "Eliminar etiqueta de persona"), "removePublicLink": @@ -1263,7 +1263,7 @@ class MessageLookup extends MessageLookupByLibrary { "renameFile": MessageLookupByLibrary.simpleMessage("Renombrar archivo"), "renewSubscription": MessageLookupByLibrary.simpleMessage("Renovar suscripción"), - "renewsOn": m45, + "renewsOn": m46, "reportABug": MessageLookupByLibrary.simpleMessage("Reportar un error"), "reportBug": MessageLookupByLibrary.simpleMessage("Reportar error"), "resendEmail": @@ -1334,7 +1334,7 @@ class MessageLookup extends MessageLookupByLibrary { "Agrupar las fotos que se tomaron cerca de la localización de una foto"), "searchPeopleEmptySection": MessageLookupByLibrary.simpleMessage( "Invita a gente y verás todas las fotos compartidas aquí"), - "searchResultCount": m46, + "searchResultCount": m47, "security": MessageLookupByLibrary.simpleMessage("Seguridad"), "selectALocation": MessageLookupByLibrary.simpleMessage("Seleccionar una ubicación"), @@ -1363,8 +1363,8 @@ class MessageLookup extends MessageLookupByLibrary { "selectedItemsWillBeDeletedFromAllAlbumsAndMoved": MessageLookupByLibrary.simpleMessage( "Los archivos seleccionados serán eliminados de todos los álbumes y movidos a la papelera."), - "selectedPhotos": m47, - "selectedPhotosWithYours": m48, + "selectedPhotos": m48, + "selectedPhotosWithYours": m49, "send": MessageLookupByLibrary.simpleMessage("Enviar"), "sendEmail": MessageLookupByLibrary.simpleMessage("Enviar correo electrónico"), @@ -1395,16 +1395,16 @@ class MessageLookup extends MessageLookupByLibrary { "shareAnAlbumNow": MessageLookupByLibrary.simpleMessage("Compartir un álbum ahora"), "shareLink": MessageLookupByLibrary.simpleMessage("Compartir enlace"), - "shareMyVerificationID": m49, + "shareMyVerificationID": m50, "shareOnlyWithThePeopleYouWant": MessageLookupByLibrary.simpleMessage( "Comparte sólo con la gente que quieres"), - "shareTextConfirmOthersVerificationID": m50, + "shareTextConfirmOthersVerificationID": m51, "shareTextRecommendUsingEnte": MessageLookupByLibrary.simpleMessage( "Descarga Ente para que podamos compartir fácilmente fotos y videos en calidad original.\n\nhttps://ente.io"), - "shareTextReferralCode": m51, + "shareTextReferralCode": m52, "shareWithNonenteUsers": MessageLookupByLibrary.simpleMessage( "Compartir con usuarios fuera de Ente"), - "shareWithPeopleSectionTitle": m52, + "shareWithPeopleSectionTitle": m53, "shareYourFirstAlbum": MessageLookupByLibrary.simpleMessage("Comparte tu primer álbum"), "sharedAlbumSectionDescription": MessageLookupByLibrary.simpleMessage( @@ -1416,7 +1416,7 @@ class MessageLookup extends MessageLookupByLibrary { MessageLookupByLibrary.simpleMessage("Nuevas fotos compartidas"), "sharedPhotoNotificationsExplanation": MessageLookupByLibrary.simpleMessage( "Recibir notificaciones cuando alguien agrega una foto a un álbum compartido contigo"), - "sharedWith": m53, + "sharedWith": m54, "sharedWithMe": MessageLookupByLibrary.simpleMessage("Compartido conmigo"), "sharedWithYou": @@ -1432,11 +1432,11 @@ class MessageLookup extends MessageLookupByLibrary { "Cerrar la sesión de otros dispositivos"), "signUpTerms": MessageLookupByLibrary.simpleMessage( "Estoy de acuerdo con los términos del servicio y la política de privacidad"), - "singleFileDeleteFromDevice": m54, + "singleFileDeleteFromDevice": m55, "singleFileDeleteHighlight": MessageLookupByLibrary.simpleMessage( "Se borrará de todos los álbumes."), - "singleFileInBothLocalAndRemote": m55, - "singleFileInRemoteOnly": m56, + "singleFileInBothLocalAndRemote": m56, + "singleFileInRemoteOnly": m57, "skip": MessageLookupByLibrary.simpleMessage("Omitir"), "social": MessageLookupByLibrary.simpleMessage("Social"), "someItemsAreInBothEnteAndYourDevice": @@ -1481,13 +1481,13 @@ class MessageLookup extends MessageLookupByLibrary { "storage": MessageLookupByLibrary.simpleMessage("Almacenamiento"), "storageBreakupFamily": MessageLookupByLibrary.simpleMessage("Familia"), "storageBreakupYou": MessageLookupByLibrary.simpleMessage("Usted"), - "storageInGB": m57, + "storageInGB": m58, "storageLimitExceeded": MessageLookupByLibrary.simpleMessage("Límite de datos excedido"), - "storageUsageInfo": m58, + "storageUsageInfo": m59, "strongStrength": MessageLookupByLibrary.simpleMessage("Segura"), - "subAlreadyLinkedErrMessage": m59, - "subWillBeCancelledOn": m60, + "subAlreadyLinkedErrMessage": m60, + "subWillBeCancelledOn": m61, "subscribe": MessageLookupByLibrary.simpleMessage("Suscribirse"), "subscribeToEnableSharing": MessageLookupByLibrary.simpleMessage( "Parece que tu suscripción ha caducado. Por favor, suscríbete para habilitar el compartir."), @@ -1504,7 +1504,7 @@ class MessageLookup extends MessageLookupByLibrary { "suggestFeatures": MessageLookupByLibrary.simpleMessage("Sugerir una característica"), "support": MessageLookupByLibrary.simpleMessage("Soporte"), - "syncProgress": m61, + "syncProgress": m62, "syncStopped": MessageLookupByLibrary.simpleMessage("Sincronización detenida"), "syncing": MessageLookupByLibrary.simpleMessage("Sincronizando..."), @@ -1533,7 +1533,7 @@ class MessageLookup extends MessageLookupByLibrary { "theseItemsWillBeDeletedFromYourDevice": MessageLookupByLibrary.simpleMessage( "Estos elementos se eliminarán de tu dispositivo."), - "theyAlsoGetXGb": m62, + "theyAlsoGetXGb": m63, "theyWillBeDeletedFromAllAlbums": MessageLookupByLibrary.simpleMessage( "Se borrarán de todos los álbumes."), "thisActionCannotBeUndone": MessageLookupByLibrary.simpleMessage( @@ -1549,7 +1549,7 @@ class MessageLookup extends MessageLookupByLibrary { "Este correo electrónico ya está en uso"), "thisImageHasNoExifData": MessageLookupByLibrary.simpleMessage( "Esta imagen no tiene datos exif"), - "thisIsPersonVerificationId": m63, + "thisIsPersonVerificationId": m64, "thisIsYourVerificationId": MessageLookupByLibrary.simpleMessage( "Esta es tu ID de verificación"), "thisWillLogYouOutOfTheFollowingDevice": @@ -1570,7 +1570,7 @@ class MessageLookup extends MessageLookupByLibrary { "total": MessageLookupByLibrary.simpleMessage("total"), "totalSize": MessageLookupByLibrary.simpleMessage("Tamaño total"), "trash": MessageLookupByLibrary.simpleMessage("Papelera"), - "trashDaysLeft": m64, + "trashDaysLeft": m65, "trim": MessageLookupByLibrary.simpleMessage("Recortar"), "tryAgain": MessageLookupByLibrary.simpleMessage("Inténtalo de nuevo"), "turnOnBackupForAutoUpload": MessageLookupByLibrary.simpleMessage( @@ -1625,7 +1625,7 @@ class MessageLookup extends MessageLookupByLibrary { "useSelectedPhoto": MessageLookupByLibrary.simpleMessage("Usar foto seleccionada"), "usedSpace": MessageLookupByLibrary.simpleMessage("Espacio usado"), - "validTill": m65, + "validTill": m66, "verificationFailedPleaseTryAgain": MessageLookupByLibrary.simpleMessage( "Verificación fallida, por favor inténtalo de nuevo"), @@ -1634,7 +1634,7 @@ class MessageLookup extends MessageLookupByLibrary { "verify": MessageLookupByLibrary.simpleMessage("Verificar"), "verifyEmail": MessageLookupByLibrary.simpleMessage( "Verificar correo electrónico"), - "verifyEmailID": m66, + "verifyEmailID": m67, "verifyIDLabel": MessageLookupByLibrary.simpleMessage("Verificar"), "verifyPasskey": MessageLookupByLibrary.simpleMessage("Verificar clave de acceso"), @@ -1671,13 +1671,13 @@ class MessageLookup extends MessageLookupByLibrary { "weDontSupportEditingPhotosAndAlbumsThatYouDont": MessageLookupByLibrary.simpleMessage( "No admitimos la edición de fotos y álbumes que aún no son tuyos"), - "weHaveSendEmailTo": m67, + "weHaveSendEmailTo": m68, "weakStrength": MessageLookupByLibrary.simpleMessage("Poco segura"), "welcomeBack": MessageLookupByLibrary.simpleMessage("¡Bienvenido de nuevo!"), "whatsNew": MessageLookupByLibrary.simpleMessage("Qué hay de nuevo"), "yearly": MessageLookupByLibrary.simpleMessage("Anualmente"), - "yearsAgo": m68, + "yearsAgo": m69, "yes": MessageLookupByLibrary.simpleMessage("Sí"), "yesCancel": MessageLookupByLibrary.simpleMessage("Sí, cancelar"), "yesConvertToViewer": @@ -1707,7 +1707,7 @@ class MessageLookup extends MessageLookupByLibrary { "No puedes compartir contigo mismo"), "youDontHaveAnyArchivedItems": MessageLookupByLibrary.simpleMessage( "No tienes ningún elemento archivado."), - "youHaveSuccessfullyFreedUp": m69, + "youHaveSuccessfullyFreedUp": m70, "yourAccountHasBeenDeleted": MessageLookupByLibrary.simpleMessage("Tu cuenta ha sido eliminada"), "yourMap": MessageLookupByLibrary.simpleMessage("Tu mapa"), diff --git a/mobile/lib/generated/intl/messages_fr.dart b/mobile/lib/generated/intl/messages_fr.dart index fc95fa5408..5812e22671 100644 --- a/mobile/lib/generated/intl/messages_fr.dart +++ b/mobile/lib/generated/intl/messages_fr.dart @@ -120,92 +120,92 @@ class MessageLookup extends MessageLookupByLibrary { static String m36(albumName) => "Déplacé avec succès vers ${albumName}"; - static String m37(passwordStrengthValue) => + static String m38(passwordStrengthValue) => "Sécurité du mot de passe : ${passwordStrengthValue}"; - static String m38(providerName) => + static String m39(providerName) => "Veuillez contacter le support ${providerName} si vous avez été facturé"; - static String m39(endDate) => + static String m40(endDate) => "Essai gratuit valable jusqu\'à ${endDate}.\nVous pouvez choisir un plan payant par la suite."; - static String m40(toEmail) => "Merci de nous envoyer un e-mail à ${toEmail}"; + static String m41(toEmail) => "Merci de nous envoyer un e-mail à ${toEmail}"; - static String m41(toEmail) => "Envoyez les logs à ${toEmail}"; + static String m42(toEmail) => "Envoyez les logs à ${toEmail}"; - static String m42(storeName) => "Notez-nous sur ${storeName}"; + static String m43(storeName) => "Notez-nous sur ${storeName}"; - static String m43(storageInGB) => + static String m44(storageInGB) => "3. Vous recevez tous les deux ${storageInGB} GB* gratuits"; - static String m44(userEmail) => + static String m45(userEmail) => "${userEmail} sera retiré de cet album partagé\n\nToutes les photos ajoutées par eux seront également retirées de l\'album"; - static String m45(endDate) => "Renouvellement le ${endDate}"; + static String m46(endDate) => "Renouvellement le ${endDate}"; - static String m46(count) => + static String m47(count) => "${Intl.plural(count, one: '${count} résultat trouvé', other: '${count} résultats trouvés')}"; - static String m47(count) => "${count} sélectionné(s)"; + static String m48(count) => "${count} sélectionné(s)"; - static String m48(count, yourCount) => + static String m49(count, yourCount) => "${count} sélectionné(s) (${yourCount} à vous)"; - static String m49(verificationID) => + static String m50(verificationID) => "Voici mon ID de vérification : ${verificationID} pour ente.io."; - static String m50(verificationID) => + static String m51(verificationID) => "Hé, pouvez-vous confirmer qu\'il s\'agit de votre ID de vérification ente.io : ${verificationID}"; - static String m51(referralCode, referralStorageInGB) => + static String m52(referralCode, referralStorageInGB) => "code de parrainage ente : ${referralCode} \n\nAppliquez le dans Paramètres → Général → Références pour obtenir ${referralStorageInGB} Go gratuitement après votre inscription à un plan payant\n\nhttps://ente.io"; - static String m52(numberOfPeople) => + static String m53(numberOfPeople) => "${Intl.plural(numberOfPeople, zero: 'Partagez avec des personnes spécifiques', one: 'Partagé avec 1 personne', other: 'Partagé avec ${numberOfPeople} des gens')}"; - static String m53(emailIDs) => "Partagé avec ${emailIDs}"; + static String m54(emailIDs) => "Partagé avec ${emailIDs}"; - static String m54(fileType) => + static String m55(fileType) => "Elle ${fileType} sera supprimée de votre appareil."; - static String m55(fileType) => + static String m56(fileType) => "Cette ${fileType} est à la fois sur ente et sur votre appareil."; - static String m56(fileType) => "Ce ${fileType} sera supprimé de ente."; + static String m57(fileType) => "Ce ${fileType} sera supprimé de ente."; - static String m57(storageAmountInGB) => "${storageAmountInGB} Go"; + static String m58(storageAmountInGB) => "${storageAmountInGB} Go"; - static String m58( + static String m59( usedAmount, usedStorageUnit, totalAmount, totalStorageUnit) => "${usedAmount} ${usedStorageUnit} sur ${totalAmount} ${totalStorageUnit} utilisé"; - static String m59(id) => + static String m60(id) => "Votre ${id} est déjà lié à un autre compte ente.\nSi vous souhaitez utiliser votre ${id} avec ce compte, veuillez contacter notre support"; - static String m60(endDate) => "Votre abonnement sera annulé le ${endDate}"; + static String m61(endDate) => "Votre abonnement sera annulé le ${endDate}"; - static String m61(completed, total) => + static String m62(completed, total) => "${completed}/${total} souvenirs préservés"; - static String m62(storageAmountInGB) => + static String m63(storageAmountInGB) => "Ils obtiennent aussi ${storageAmountInGB} Go"; - static String m63(email) => "Ceci est l\'ID de vérification de ${email}"; + static String m64(email) => "Ceci est l\'ID de vérification de ${email}"; - static String m64(count) => + static String m65(count) => "${Intl.plural(count, zero: '0 jour', one: '1 jour', other: '${count} jours')}"; - static String m65(endDate) => "Valable jusqu\'au ${endDate}"; + static String m66(endDate) => "Valable jusqu\'au ${endDate}"; - static String m66(email) => "Vérifier ${email}"; + static String m67(email) => "Vérifier ${email}"; - static String m67(email) => + static String m68(email) => "Nous avons envoyé un e-mail à ${email}"; - static String m68(count) => + static String m69(count) => "${Intl.plural(count, one: 'il y a ${count} an', other: 'il y a ${count} ans')}"; - static String m69(storageSaved) => + static String m70(storageSaved) => "Vous avez libéré ${storageSaved} avec succès !"; final messages = _notInlinedMessages(_notInlinedMessages); @@ -1004,14 +1004,14 @@ class MessageLookup extends MessageLookupByLibrary { "Le mot de passe a été modifié"), "passwordLock": MessageLookupByLibrary.simpleMessage("Mot de passe verrou"), - "passwordStrength": m37, + "passwordStrength": m38, "passwordWarning": MessageLookupByLibrary.simpleMessage( "Nous ne stockons pas ce mot de passe, donc si vous l\'oubliez, nous ne pouvons pas déchiffrer vos données"), "paymentDetails": MessageLookupByLibrary.simpleMessage("Détails de paiement"), "paymentFailed": MessageLookupByLibrary.simpleMessage("Échec du paiement"), - "paymentFailedTalkToProvider": m38, + "paymentFailedTalkToProvider": m39, "pendingSync": MessageLookupByLibrary.simpleMessage("Synchronisation en attente"), "peopleUsingYourCode": MessageLookupByLibrary.simpleMessage( @@ -1035,7 +1035,7 @@ class MessageLookup extends MessageLookupByLibrary { "Sélectionner le point central"), "pinAlbum": MessageLookupByLibrary.simpleMessage("Épingler l\'album"), "pinLock": MessageLookupByLibrary.simpleMessage("PIN lock"), - "playStoreFreeTrialValidTill": m39, + "playStoreFreeTrialValidTill": m40, "playstoreSubscription": MessageLookupByLibrary.simpleMessage("Abonnement au PlayStore"), "pleaseContactSupportAndWeWillBeHappyToHelp": @@ -1044,12 +1044,12 @@ class MessageLookup extends MessageLookupByLibrary { "pleaseContactSupportIfTheProblemPersists": MessageLookupByLibrary.simpleMessage( "Merci de contacter l\'assistance si cette erreur persiste"), - "pleaseEmailUsAt": m40, + "pleaseEmailUsAt": m41, "pleaseGrantPermissions": MessageLookupByLibrary.simpleMessage( "Veuillez accorder la permission"), "pleaseLoginAgain": MessageLookupByLibrary.simpleMessage("Veuillez vous reconnecter"), - "pleaseSendTheLogsTo": m41, + "pleaseSendTheLogsTo": m42, "pleaseTryAgain": MessageLookupByLibrary.simpleMessage("Veuillez réessayer"), "pleaseVerifyTheCodeYouHaveEntered": @@ -1085,7 +1085,7 @@ class MessageLookup extends MessageLookupByLibrary { "rateTheApp": MessageLookupByLibrary.simpleMessage("Évaluer l\'application"), "rateUs": MessageLookupByLibrary.simpleMessage("Évaluez-nous"), - "rateUsOnStore": m42, + "rateUsOnStore": m43, "recover": MessageLookupByLibrary.simpleMessage("Récupérer"), "recoverAccount": MessageLookupByLibrary.simpleMessage("Récupérer un compte"), @@ -1119,7 +1119,7 @@ class MessageLookup extends MessageLookupByLibrary { "1. Donnez ce code à vos amis"), "referralStep2": MessageLookupByLibrary.simpleMessage( "2. Ils s\'inscrivent à une offre payante"), - "referralStep3": m43, + "referralStep3": m44, "referrals": MessageLookupByLibrary.simpleMessage("Parrainages"), "referralsAreCurrentlyPaused": MessageLookupByLibrary.simpleMessage( "Les recommandations sont actuellement en pause"), @@ -1145,7 +1145,7 @@ class MessageLookup extends MessageLookupByLibrary { "removeLink": MessageLookupByLibrary.simpleMessage("Supprimer le lien"), "removeParticipant": MessageLookupByLibrary.simpleMessage("Supprimer le participant"), - "removeParticipantBody": m44, + "removeParticipantBody": m45, "removePersonLabel": MessageLookupByLibrary.simpleMessage("Remove person label"), "removePublicLink": @@ -1163,7 +1163,7 @@ class MessageLookup extends MessageLookupByLibrary { MessageLookupByLibrary.simpleMessage("Renommer le fichier"), "renewSubscription": MessageLookupByLibrary.simpleMessage("Renouveler l’abonnement"), - "renewsOn": m45, + "renewsOn": m46, "reportABug": MessageLookupByLibrary.simpleMessage("Signaler un bug"), "reportBug": MessageLookupByLibrary.simpleMessage("Signaler un bug"), "resendEmail": @@ -1229,7 +1229,7 @@ class MessageLookup extends MessageLookupByLibrary { "Grouper les photos qui sont prises dans un certain angle d\'une photo"), "searchPeopleEmptySection": MessageLookupByLibrary.simpleMessage( "Invitez des gens, et vous verrez ici toutes les photos qu\'ils partagent"), - "searchResultCount": m46, + "searchResultCount": m47, "security": MessageLookupByLibrary.simpleMessage("Sécurité"), "selectALocation": MessageLookupByLibrary.simpleMessage("Select a location"), @@ -1258,8 +1258,8 @@ class MessageLookup extends MessageLookupByLibrary { "selectedItemsWillBeDeletedFromAllAlbumsAndMoved": MessageLookupByLibrary.simpleMessage( "Les éléments sélectionnés seront supprimés de tous les albums et déplacés dans la corbeille."), - "selectedPhotos": m47, - "selectedPhotosWithYours": m48, + "selectedPhotos": m48, + "selectedPhotosWithYours": m49, "send": MessageLookupByLibrary.simpleMessage("Envoyer"), "sendEmail": MessageLookupByLibrary.simpleMessage("Envoyer un e-mail"), "sendInvite": @@ -1288,16 +1288,16 @@ class MessageLookup extends MessageLookupByLibrary { "shareAnAlbumNow": MessageLookupByLibrary.simpleMessage( "Partagez un album maintenant"), "shareLink": MessageLookupByLibrary.simpleMessage("Partager le lien"), - "shareMyVerificationID": m49, + "shareMyVerificationID": m50, "shareOnlyWithThePeopleYouWant": MessageLookupByLibrary.simpleMessage( "Partager uniquement avec les personnes que vous voulez"), - "shareTextConfirmOthersVerificationID": m50, + "shareTextConfirmOthersVerificationID": m51, "shareTextRecommendUsingEnte": MessageLookupByLibrary.simpleMessage( "Téléchargez ente pour que nous puissions facilement partager des photos et des vidéos de qualité originale\n\nhttps://ente.io"), - "shareTextReferralCode": m51, + "shareTextReferralCode": m52, "shareWithNonenteUsers": MessageLookupByLibrary.simpleMessage( "Partager avec des utilisateurs non-ente"), - "shareWithPeopleSectionTitle": m52, + "shareWithPeopleSectionTitle": m53, "shareYourFirstAlbum": MessageLookupByLibrary.simpleMessage( "Partagez votre premier album"), "sharedAlbumSectionDescription": MessageLookupByLibrary.simpleMessage( @@ -1308,7 +1308,7 @@ class MessageLookup extends MessageLookupByLibrary { MessageLookupByLibrary.simpleMessage("Nouvelles photos partagées"), "sharedPhotoNotificationsExplanation": MessageLookupByLibrary.simpleMessage( "Recevoir des notifications quand quelqu\'un ajoute une photo à un album partagé dont vous faites partie"), - "sharedWith": m53, + "sharedWith": m54, "sharedWithMe": MessageLookupByLibrary.simpleMessage("Partagés avec moi"), "sharedWithYou": @@ -1318,11 +1318,11 @@ class MessageLookup extends MessageLookupByLibrary { MessageLookupByLibrary.simpleMessage("Montrer les souvenirs"), "signUpTerms": MessageLookupByLibrary.simpleMessage( "J\'accepte les conditions d\'utilisation et la politique de confidentialité"), - "singleFileDeleteFromDevice": m54, + "singleFileDeleteFromDevice": m55, "singleFileDeleteHighlight": MessageLookupByLibrary.simpleMessage( "Elle sera supprimée de tous les albums."), - "singleFileInBothLocalAndRemote": m55, - "singleFileInRemoteOnly": m56, + "singleFileInBothLocalAndRemote": m56, + "singleFileInRemoteOnly": m57, "skip": MessageLookupByLibrary.simpleMessage("Ignorer"), "social": MessageLookupByLibrary.simpleMessage("Réseaux Sociaux"), "someItemsAreInBothEnteAndYourDevice": @@ -1362,14 +1362,14 @@ class MessageLookup extends MessageLookupByLibrary { "storage": MessageLookupByLibrary.simpleMessage("Stockage"), "storageBreakupFamily": MessageLookupByLibrary.simpleMessage("Famille"), "storageBreakupYou": MessageLookupByLibrary.simpleMessage("Vous"), - "storageInGB": m57, + "storageInGB": m58, "storageLimitExceeded": MessageLookupByLibrary.simpleMessage("Limite de stockage atteinte"), - "storageUsageInfo": m58, + "storageUsageInfo": m59, "strongStrength": MessageLookupByLibrary.simpleMessage("Securité forte"), - "subAlreadyLinkedErrMessage": m59, - "subWillBeCancelledOn": m60, + "subAlreadyLinkedErrMessage": m60, + "subWillBeCancelledOn": m61, "subscribe": MessageLookupByLibrary.simpleMessage("S\'abonner"), "subscribeToEnableSharing": MessageLookupByLibrary.simpleMessage( "Il semble que votre abonnement ait expiré. Veuillez vous abonner pour activer le partage."), @@ -1386,7 +1386,7 @@ class MessageLookup extends MessageLookupByLibrary { "suggestFeatures": MessageLookupByLibrary.simpleMessage( "Suggérer des fonctionnalités"), "support": MessageLookupByLibrary.simpleMessage("Support"), - "syncProgress": m61, + "syncProgress": m62, "syncStopped": MessageLookupByLibrary.simpleMessage("Synchronisation arrêtée ?"), "syncing": MessageLookupByLibrary.simpleMessage( @@ -1416,7 +1416,7 @@ class MessageLookup extends MessageLookupByLibrary { "theseItemsWillBeDeletedFromYourDevice": MessageLookupByLibrary.simpleMessage( "Ces éléments seront supprimés de votre appareil."), - "theyAlsoGetXGb": m62, + "theyAlsoGetXGb": m63, "theyWillBeDeletedFromAllAlbums": MessageLookupByLibrary.simpleMessage( "Ils seront supprimés de tous les albums."), "thisActionCannotBeUndone": MessageLookupByLibrary.simpleMessage( @@ -1432,7 +1432,7 @@ class MessageLookup extends MessageLookupByLibrary { "Cette adresse mail est déjà utilisé"), "thisImageHasNoExifData": MessageLookupByLibrary.simpleMessage( "Cette image n\'a pas de données exif"), - "thisIsPersonVerificationId": m63, + "thisIsPersonVerificationId": m64, "thisIsYourVerificationId": MessageLookupByLibrary.simpleMessage( "Ceci est votre ID de vérification"), "thisWillLogYouOutOfTheFollowingDevice": @@ -1453,7 +1453,7 @@ class MessageLookup extends MessageLookupByLibrary { "total": MessageLookupByLibrary.simpleMessage("total"), "totalSize": MessageLookupByLibrary.simpleMessage("Taille totale"), "trash": MessageLookupByLibrary.simpleMessage("Corbeille"), - "trashDaysLeft": m64, + "trashDaysLeft": m65, "tryAgain": MessageLookupByLibrary.simpleMessage("Réessayer"), "turnOnBackupForAutoUpload": MessageLookupByLibrary.simpleMessage( "Activez la sauvegarde pour télécharger automatiquement les fichiers ajoutés à ce dossier de l\'appareil sur ente."), @@ -1511,7 +1511,7 @@ class MessageLookup extends MessageLookupByLibrary { "useSelectedPhoto": MessageLookupByLibrary.simpleMessage( "Utiliser la photo sélectionnée"), "usedSpace": MessageLookupByLibrary.simpleMessage("Mémoire utilisée"), - "validTill": m65, + "validTill": m66, "verificationFailedPleaseTryAgain": MessageLookupByLibrary.simpleMessage( "La vérification a échouée, veuillez réessayer"), @@ -1520,7 +1520,7 @@ class MessageLookup extends MessageLookupByLibrary { "verify": MessageLookupByLibrary.simpleMessage("Vérifier"), "verifyEmail": MessageLookupByLibrary.simpleMessage("Vérifier l\'email"), - "verifyEmailID": m66, + "verifyEmailID": m67, "verifyIDLabel": MessageLookupByLibrary.simpleMessage("Vérifier"), "verifyPassword": MessageLookupByLibrary.simpleMessage("Vérifier le mot de passe"), @@ -1549,11 +1549,11 @@ class MessageLookup extends MessageLookupByLibrary { "weDontSupportEditingPhotosAndAlbumsThatYouDont": MessageLookupByLibrary.simpleMessage( "Nous ne prenons pas en charge l\'édition des photos et des albums que vous ne possédez pas encore"), - "weHaveSendEmailTo": m67, + "weHaveSendEmailTo": m68, "weakStrength": MessageLookupByLibrary.simpleMessage("Securité Faible"), "welcomeBack": MessageLookupByLibrary.simpleMessage("Bienvenue !"), "yearly": MessageLookupByLibrary.simpleMessage("Annuel"), - "yearsAgo": m68, + "yearsAgo": m69, "yes": MessageLookupByLibrary.simpleMessage("Oui"), "yesCancel": MessageLookupByLibrary.simpleMessage("Oui, annuler"), "yesConvertToViewer": MessageLookupByLibrary.simpleMessage( @@ -1584,7 +1584,7 @@ class MessageLookup extends MessageLookupByLibrary { "Vous ne pouvez pas partager avec vous-même"), "youDontHaveAnyArchivedItems": MessageLookupByLibrary.simpleMessage( "Vous n\'avez aucun élément archivé."), - "youHaveSuccessfullyFreedUp": m69, + "youHaveSuccessfullyFreedUp": m70, "yourAccountHasBeenDeleted": MessageLookupByLibrary.simpleMessage("Votre compte a été supprimé"), "yourMap": MessageLookupByLibrary.simpleMessage("Votre carte"), diff --git a/mobile/lib/generated/intl/messages_it.dart b/mobile/lib/generated/intl/messages_it.dart index 8793aeac73..2acce1be64 100644 --- a/mobile/lib/generated/intl/messages_it.dart +++ b/mobile/lib/generated/intl/messages_it.dart @@ -118,89 +118,89 @@ class MessageLookup extends MessageLookupByLibrary { static String m36(albumName) => "Spostato con successo su ${albumName}"; - static String m37(passwordStrengthValue) => + static String m38(passwordStrengthValue) => "Sicurezza password: ${passwordStrengthValue}"; - static String m38(providerName) => + static String m39(providerName) => "Si prega di parlare con il supporto di ${providerName} se ti è stato addebitato qualcosa"; - static String m39(endDate) => + static String m40(endDate) => "Prova gratuita valida fino al ${endDate}.\nPuoi scegliere un piano a pagamento in seguito."; - static String m40(toEmail) => "Per favore invia un\'email a ${toEmail}"; + static String m41(toEmail) => "Per favore invia un\'email a ${toEmail}"; - static String m41(toEmail) => "Invia i log a \n${toEmail}"; + static String m42(toEmail) => "Invia i log a \n${toEmail}"; - static String m42(storeName) => "Valutaci su ${storeName}"; + static String m43(storeName) => "Valutaci su ${storeName}"; - static String m43(storageInGB) => + static String m44(storageInGB) => "3. Ottenete entrambi ${storageInGB} GB* gratis"; - static String m44(userEmail) => + static String m45(userEmail) => "${userEmail} verrà rimosso da questo album condiviso\n\nQualsiasi foto aggiunta dall\'utente verrà rimossa dall\'album"; - static String m45(endDate) => "Si rinnova il ${endDate}"; + static String m46(endDate) => "Si rinnova il ${endDate}"; - static String m47(count) => "${count} selezionati"; + static String m48(count) => "${count} selezionati"; - static String m48(count, yourCount) => + static String m49(count, yourCount) => "${count} selezionato (${yourCount} tuoi)"; - static String m49(verificationID) => + static String m50(verificationID) => "Ecco il mio ID di verifica: ${verificationID} per ente.io."; - static String m50(verificationID) => + static String m51(verificationID) => "Hey, puoi confermare che questo è il tuo ID di verifica: ${verificationID} su ente.io"; - static String m51(referralCode, referralStorageInGB) => + static String m52(referralCode, referralStorageInGB) => "ente referral code: ${referralCode} \n\nApplicalo in Impostazioni → Generale → Referral per ottenere ${referralStorageInGB} GB gratis dopo la registrazione di un piano a pagamento\n\nhttps://ente.io"; - static String m52(numberOfPeople) => + static String m53(numberOfPeople) => "${Intl.plural(numberOfPeople, zero: 'Condividi con persone specifiche', one: 'Condividi con una persona', other: 'Condividi con ${numberOfPeople} persone')}"; - static String m53(emailIDs) => "Condiviso con ${emailIDs}"; + static String m54(emailIDs) => "Condiviso con ${emailIDs}"; - static String m54(fileType) => + static String m55(fileType) => "Questo ${fileType} verrà eliminato dal tuo dispositivo."; - static String m55(fileType) => + static String m56(fileType) => "Questo ${fileType} è sia su ente che sul tuo dispositivo."; - static String m56(fileType) => "Questo ${fileType} verrà eliminato su ente."; + static String m57(fileType) => "Questo ${fileType} verrà eliminato su ente."; - static String m57(storageAmountInGB) => "${storageAmountInGB} GB"; + static String m58(storageAmountInGB) => "${storageAmountInGB} GB"; - static String m58( + static String m59( usedAmount, usedStorageUnit, totalAmount, totalStorageUnit) => "${usedAmount} ${usedStorageUnit} di ${totalAmount} ${totalStorageUnit} utilizzati"; - static String m59(id) => + static String m60(id) => "Il tuo ${id} è già collegato ad un altro account ente.\nSe desideri utilizzare il tuo ${id} con questo account, contatta il nostro supporto\'\'"; - static String m60(endDate) => "L\'abbonamento verrà cancellato il ${endDate}"; + static String m61(endDate) => "L\'abbonamento verrà cancellato il ${endDate}"; - static String m61(completed, total) => + static String m62(completed, total) => "${completed}/${total} ricordi conservati"; - static String m62(storageAmountInGB) => + static String m63(storageAmountInGB) => "Anche loro riceveranno ${storageAmountInGB} GB"; - static String m63(email) => "Questo è l\'ID di verifica di ${email}"; + static String m64(email) => "Questo è l\'ID di verifica di ${email}"; - static String m64(count) => + static String m65(count) => "${Intl.plural(count, zero: '', one: '1 giorno', other: '${count} giorni')}"; - static String m65(endDate) => "Valido fino al ${endDate}"; + static String m66(endDate) => "Valido fino al ${endDate}"; - static String m66(email) => "Verifica ${email}"; + static String m67(email) => "Verifica ${email}"; - static String m67(email) => + static String m68(email) => "Abbiamo inviato una mail a ${email}"; - static String m68(count) => + static String m69(count) => "${Intl.plural(count, one: '${count} anno fa', other: '${count} anni fa')}"; - static String m69(storageSaved) => + static String m70(storageSaved) => "Hai liberato con successo ${storageSaved}!"; final messages = _notInlinedMessages(_notInlinedMessages); @@ -971,14 +971,14 @@ class MessageLookup extends MessageLookupByLibrary { "Password modificata con successo"), "passwordLock": MessageLookupByLibrary.simpleMessage("Blocco con password"), - "passwordStrength": m37, + "passwordStrength": m38, "passwordWarning": MessageLookupByLibrary.simpleMessage( "Noi non memorizziamo la tua password, quindi se te la dimentichi, non possiamo decriptare i tuoi dati"), "paymentDetails": MessageLookupByLibrary.simpleMessage("Dettagli di Pagamento"), "paymentFailed": MessageLookupByLibrary.simpleMessage("Pagamento non riuscito"), - "paymentFailedTalkToProvider": m38, + "paymentFailedTalkToProvider": m39, "pendingSync": MessageLookupByLibrary.simpleMessage("Sincronizzazione in sospeso"), "peopleUsingYourCode": MessageLookupByLibrary.simpleMessage( @@ -999,7 +999,7 @@ class MessageLookup extends MessageLookupByLibrary { "Selezionare il punto centrale"), "pinAlbum": MessageLookupByLibrary.simpleMessage("Fissa l\'album"), "pinLock": MessageLookupByLibrary.simpleMessage("PIN lock"), - "playStoreFreeTrialValidTill": m39, + "playStoreFreeTrialValidTill": m40, "playstoreSubscription": MessageLookupByLibrary.simpleMessage("Abbonamento su PlayStore"), "pleaseContactSupportAndWeWillBeHappyToHelp": @@ -1008,12 +1008,12 @@ class MessageLookup extends MessageLookupByLibrary { "pleaseContactSupportIfTheProblemPersists": MessageLookupByLibrary.simpleMessage( "Riprova. Se il problema persiste, ti invitiamo a contattare l\'assistenza"), - "pleaseEmailUsAt": m40, + "pleaseEmailUsAt": m41, "pleaseGrantPermissions": MessageLookupByLibrary.simpleMessage("Concedi i permessi"), "pleaseLoginAgain": MessageLookupByLibrary.simpleMessage( "Effettua nuovamente l\'accesso"), - "pleaseSendTheLogsTo": m41, + "pleaseSendTheLogsTo": m42, "pleaseTryAgain": MessageLookupByLibrary.simpleMessage("Riprova"), "pleaseVerifyTheCodeYouHaveEntered": MessageLookupByLibrary.simpleMessage( @@ -1047,7 +1047,7 @@ class MessageLookup extends MessageLookupByLibrary { "raiseTicket": MessageLookupByLibrary.simpleMessage("Invia ticket"), "rateTheApp": MessageLookupByLibrary.simpleMessage("Valuta l\'app"), "rateUs": MessageLookupByLibrary.simpleMessage("Lascia una recensione"), - "rateUsOnStore": m42, + "rateUsOnStore": m43, "recover": MessageLookupByLibrary.simpleMessage("Recupera"), "recoverAccount": MessageLookupByLibrary.simpleMessage("Recupera account"), @@ -1082,7 +1082,7 @@ class MessageLookup extends MessageLookupByLibrary { "1. Condividi questo codice con i tuoi amici"), "referralStep2": MessageLookupByLibrary.simpleMessage( "2. Si iscrivono per un piano a pagamento"), - "referralStep3": m43, + "referralStep3": m44, "referrals": MessageLookupByLibrary.simpleMessage("Invita un Amico"), "referralsAreCurrentlyPaused": MessageLookupByLibrary.simpleMessage( "I referral code sono attualmente in pausa"), @@ -1106,7 +1106,7 @@ class MessageLookup extends MessageLookupByLibrary { "removeLink": MessageLookupByLibrary.simpleMessage("Elimina link"), "removeParticipant": MessageLookupByLibrary.simpleMessage("Rimuovi partecipante"), - "removeParticipantBody": m44, + "removeParticipantBody": m45, "removePersonLabel": MessageLookupByLibrary.simpleMessage("Remove person label"), "removePublicLink": @@ -1122,7 +1122,7 @@ class MessageLookup extends MessageLookupByLibrary { "renameFile": MessageLookupByLibrary.simpleMessage("Rinomina file"), "renewSubscription": MessageLookupByLibrary.simpleMessage("Rinnova abbonamento"), - "renewsOn": m45, + "renewsOn": m46, "reportABug": MessageLookupByLibrary.simpleMessage("Segnala un bug"), "reportBug": MessageLookupByLibrary.simpleMessage("Segnala un bug"), "resendEmail": MessageLookupByLibrary.simpleMessage("Rinvia email"), @@ -1188,8 +1188,8 @@ class MessageLookup extends MessageLookupByLibrary { "selectedItemsWillBeDeletedFromAllAlbumsAndMoved": MessageLookupByLibrary.simpleMessage( "Gli elementi selezionati verranno eliminati da tutti gli album e spostati nel cestino."), - "selectedPhotos": m47, - "selectedPhotosWithYours": m48, + "selectedPhotos": m48, + "selectedPhotosWithYours": m49, "send": MessageLookupByLibrary.simpleMessage("Invia"), "sendEmail": MessageLookupByLibrary.simpleMessage("Invia email"), "sendInvite": MessageLookupByLibrary.simpleMessage("Invita"), @@ -1216,16 +1216,16 @@ class MessageLookup extends MessageLookupByLibrary { "shareAnAlbumNow": MessageLookupByLibrary.simpleMessage("Condividi un album"), "shareLink": MessageLookupByLibrary.simpleMessage("Condividi link"), - "shareMyVerificationID": m49, + "shareMyVerificationID": m50, "shareOnlyWithThePeopleYouWant": MessageLookupByLibrary.simpleMessage( "Condividi solo con le persone che vuoi"), - "shareTextConfirmOthersVerificationID": m50, + "shareTextConfirmOthersVerificationID": m51, "shareTextRecommendUsingEnte": MessageLookupByLibrary.simpleMessage( "Scarica ente in modo da poter facilmente condividere foto e video senza perdita di qualità\n\nhttps://ente.io"), - "shareTextReferralCode": m51, + "shareTextReferralCode": m52, "shareWithNonenteUsers": MessageLookupByLibrary.simpleMessage( "Condividi con utenti che non hanno un account ente"), - "shareWithPeopleSectionTitle": m52, + "shareWithPeopleSectionTitle": m53, "shareYourFirstAlbum": MessageLookupByLibrary.simpleMessage( "Condividi il tuo primo album"), "sharedAlbumSectionDescription": MessageLookupByLibrary.simpleMessage( @@ -1236,7 +1236,7 @@ class MessageLookup extends MessageLookupByLibrary { MessageLookupByLibrary.simpleMessage("Nuove foto condivise"), "sharedPhotoNotificationsExplanation": MessageLookupByLibrary.simpleMessage( "Ricevi notifiche quando qualcuno aggiunge una foto a un album condiviso, di cui fai parte"), - "sharedWith": m53, + "sharedWith": m54, "sharedWithMe": MessageLookupByLibrary.simpleMessage("Condivisi con me"), "sharedWithYou": @@ -1246,11 +1246,11 @@ class MessageLookup extends MessageLookupByLibrary { "showMemories": MessageLookupByLibrary.simpleMessage("Mostra ricordi"), "signUpTerms": MessageLookupByLibrary.simpleMessage( "Accetto i termini di servizio e la politica sulla privacy"), - "singleFileDeleteFromDevice": m54, + "singleFileDeleteFromDevice": m55, "singleFileDeleteHighlight": MessageLookupByLibrary.simpleMessage( "Verrà eliminato da tutti gli album."), - "singleFileInBothLocalAndRemote": m55, - "singleFileInRemoteOnly": m56, + "singleFileInBothLocalAndRemote": m56, + "singleFileInRemoteOnly": m57, "skip": MessageLookupByLibrary.simpleMessage("Salta"), "social": MessageLookupByLibrary.simpleMessage("Social"), "someItemsAreInBothEnteAndYourDevice": @@ -1291,13 +1291,13 @@ class MessageLookup extends MessageLookupByLibrary { "storageBreakupFamily": MessageLookupByLibrary.simpleMessage("Famiglia"), "storageBreakupYou": MessageLookupByLibrary.simpleMessage("Tu"), - "storageInGB": m57, + "storageInGB": m58, "storageLimitExceeded": MessageLookupByLibrary.simpleMessage( "Limite d\'archiviazione superato"), - "storageUsageInfo": m58, + "storageUsageInfo": m59, "strongStrength": MessageLookupByLibrary.simpleMessage("Forte"), - "subAlreadyLinkedErrMessage": m59, - "subWillBeCancelledOn": m60, + "subAlreadyLinkedErrMessage": m60, + "subWillBeCancelledOn": m61, "subscribe": MessageLookupByLibrary.simpleMessage("Iscriviti"), "subscribeToEnableSharing": MessageLookupByLibrary.simpleMessage( "Sembra che il tuo abbonamento sia scaduto. Iscriviti per abilitare la condivisione."), @@ -1314,7 +1314,7 @@ class MessageLookup extends MessageLookupByLibrary { "suggestFeatures": MessageLookupByLibrary.simpleMessage("Suggerisci una funzionalità"), "support": MessageLookupByLibrary.simpleMessage("Assistenza"), - "syncProgress": m61, + "syncProgress": m62, "syncStopped": MessageLookupByLibrary.simpleMessage("Sincronizzazione interrotta"), "syncing": MessageLookupByLibrary.simpleMessage( @@ -1344,7 +1344,7 @@ class MessageLookup extends MessageLookupByLibrary { "theseItemsWillBeDeletedFromYourDevice": MessageLookupByLibrary.simpleMessage( "Questi file verranno eliminati dal tuo dispositivo."), - "theyAlsoGetXGb": m62, + "theyAlsoGetXGb": m63, "theyWillBeDeletedFromAllAlbums": MessageLookupByLibrary.simpleMessage( "Verranno eliminati da tutti gli album."), "thisActionCannotBeUndone": MessageLookupByLibrary.simpleMessage( @@ -1361,7 +1361,7 @@ class MessageLookup extends MessageLookupByLibrary { "Questo indirizzo email è già registrato"), "thisImageHasNoExifData": MessageLookupByLibrary.simpleMessage( "Questa immagine non ha dati EXIF"), - "thisIsPersonVerificationId": m63, + "thisIsPersonVerificationId": m64, "thisIsYourVerificationId": MessageLookupByLibrary.simpleMessage( "Questo è il tuo ID di verifica"), "thisWillLogYouOutOfTheFollowingDevice": @@ -1382,7 +1382,7 @@ class MessageLookup extends MessageLookupByLibrary { "total": MessageLookupByLibrary.simpleMessage("totale"), "totalSize": MessageLookupByLibrary.simpleMessage("Dimensioni totali"), "trash": MessageLookupByLibrary.simpleMessage("Cestino"), - "trashDaysLeft": m64, + "trashDaysLeft": m65, "tryAgain": MessageLookupByLibrary.simpleMessage("Riprova"), "turnOnBackupForAutoUpload": MessageLookupByLibrary.simpleMessage( "Attiva il backup per caricare automaticamente i file aggiunti in questa cartella del dispositivo su ente."), @@ -1439,7 +1439,7 @@ class MessageLookup extends MessageLookupByLibrary { "useSelectedPhoto": MessageLookupByLibrary.simpleMessage("Usa la foto selezionata"), "usedSpace": MessageLookupByLibrary.simpleMessage("Spazio utilizzato"), - "validTill": m65, + "validTill": m66, "verificationFailedPleaseTryAgain": MessageLookupByLibrary.simpleMessage( "Verifica fallita, per favore prova di nuovo"), @@ -1447,7 +1447,7 @@ class MessageLookup extends MessageLookupByLibrary { MessageLookupByLibrary.simpleMessage("ID di verifica"), "verify": MessageLookupByLibrary.simpleMessage("Verifica"), "verifyEmail": MessageLookupByLibrary.simpleMessage("Verifica email"), - "verifyEmailID": m66, + "verifyEmailID": m67, "verifyIDLabel": MessageLookupByLibrary.simpleMessage("Verifica"), "verifyPassword": MessageLookupByLibrary.simpleMessage("Verifica password"), @@ -1474,11 +1474,11 @@ class MessageLookup extends MessageLookupByLibrary { "weDontSupportEditingPhotosAndAlbumsThatYouDont": MessageLookupByLibrary.simpleMessage( "Non puoi modificare foto e album che non possiedi"), - "weHaveSendEmailTo": m67, + "weHaveSendEmailTo": m68, "weakStrength": MessageLookupByLibrary.simpleMessage("Debole"), "welcomeBack": MessageLookupByLibrary.simpleMessage("Bentornato/a!"), "yearly": MessageLookupByLibrary.simpleMessage("Annuale"), - "yearsAgo": m68, + "yearsAgo": m69, "yes": MessageLookupByLibrary.simpleMessage("Si"), "yesCancel": MessageLookupByLibrary.simpleMessage("Sì, cancella"), "yesConvertToViewer": MessageLookupByLibrary.simpleMessage( @@ -1508,7 +1508,7 @@ class MessageLookup extends MessageLookupByLibrary { "Non puoi condividere con te stesso"), "youDontHaveAnyArchivedItems": MessageLookupByLibrary.simpleMessage( "Non hai nulla di archiviato."), - "youHaveSuccessfullyFreedUp": m69, + "youHaveSuccessfullyFreedUp": m70, "yourAccountHasBeenDeleted": MessageLookupByLibrary.simpleMessage( "Il tuo account è stato eliminato"), "yourMap": MessageLookupByLibrary.simpleMessage("Your map"), diff --git a/mobile/lib/generated/intl/messages_nl.dart b/mobile/lib/generated/intl/messages_nl.dart index 6b16b1bcc5..6ffb2b0eab 100644 --- a/mobile/lib/generated/intl/messages_nl.dart +++ b/mobile/lib/generated/intl/messages_nl.dart @@ -127,94 +127,96 @@ class MessageLookup extends MessageLookupByLibrary { static String m36(albumName) => "Succesvol verplaatst naar ${albumName}"; - static String m37(passwordStrengthValue) => + static String m37(name) => "Niet ${name}?"; + + static String m38(passwordStrengthValue) => "Wachtwoord sterkte: ${passwordStrengthValue}"; - static String m38(providerName) => + static String m39(providerName) => "Praat met ${providerName} klantenservice als u in rekening bent gebracht"; - static String m39(endDate) => + static String m40(endDate) => "Gratis proefperiode geldig tot ${endDate}.\nU kunt naderhand een betaald abonnement kiezen."; - static String m40(toEmail) => "Stuur ons een e-mail op ${toEmail}"; + static String m41(toEmail) => "Stuur ons een e-mail op ${toEmail}"; - static String m41(toEmail) => + static String m42(toEmail) => "Verstuur de logboeken alstublieft naar ${toEmail}"; - static String m42(storeName) => "Beoordeel ons op ${storeName}"; + static String m43(storeName) => "Beoordeel ons op ${storeName}"; - static String m43(storageInGB) => + static String m44(storageInGB) => "Jullie krijgen allebei ${storageInGB} GB* gratis"; - static String m44(userEmail) => + static String m45(userEmail) => "${userEmail} zal worden verwijderd uit dit gedeelde album\n\nAlle door hen toegevoegde foto\'s worden ook uit het album verwijderd"; - static String m45(endDate) => "Wordt verlengd op ${endDate}"; + static String m46(endDate) => "Wordt verlengd op ${endDate}"; - static String m46(count) => + static String m47(count) => "${Intl.plural(count, one: '${count} resultaat gevonden', other: '${count} resultaten gevonden')}"; - static String m47(count) => "${count} geselecteerd"; + static String m48(count) => "${count} geselecteerd"; - static String m48(count, yourCount) => + static String m49(count, yourCount) => "${count} geselecteerd (${yourCount} van jou)"; - static String m49(verificationID) => + static String m50(verificationID) => "Hier is mijn verificatie-ID: ${verificationID} voor ente.io."; - static String m50(verificationID) => + static String m51(verificationID) => "Hey, kunt u bevestigen dat dit uw ente.io verificatie-ID is: ${verificationID}"; - static String m51(referralCode, referralStorageInGB) => + static String m52(referralCode, referralStorageInGB) => "Ente verwijzingscode: ${referralCode} \n\nPas het toe bij Instellingen → Algemeen → Verwijzingen om ${referralStorageInGB} GB gratis te krijgen nadat je je hebt aangemeld voor een betaald abonnement\n\nhttps://ente.io"; - static String m52(numberOfPeople) => + static String m53(numberOfPeople) => "${Intl.plural(numberOfPeople, zero: 'Deel met specifieke mensen', one: 'Gedeeld met 1 persoon', other: 'Gedeeld met ${numberOfPeople} mensen')}"; - static String m53(emailIDs) => "Gedeeld met ${emailIDs}"; + static String m54(emailIDs) => "Gedeeld met ${emailIDs}"; - static String m54(fileType) => + static String m55(fileType) => "Deze ${fileType} zal worden verwijderd van jouw apparaat."; - static String m55(fileType) => + static String m56(fileType) => "Deze ${fileType} staat zowel in Ente als op jouw apparaat."; - static String m56(fileType) => + static String m57(fileType) => "Deze ${fileType} zal worden verwijderd uit Ente."; - static String m57(storageAmountInGB) => "${storageAmountInGB} GB"; + static String m58(storageAmountInGB) => "${storageAmountInGB} GB"; - static String m58( + static String m59( usedAmount, usedStorageUnit, totalAmount, totalStorageUnit) => "${usedAmount} ${usedStorageUnit} van ${totalAmount} ${totalStorageUnit} gebruikt"; - static String m59(id) => + static String m60(id) => "Jouw ${id} is al aan een ander Ente account gekoppeld.\nAls je jouw ${id} wilt gebruiken met dit account, neem dan contact op met onze klantenservice"; - static String m60(endDate) => "Uw abonnement loopt af op ${endDate}"; + static String m61(endDate) => "Uw abonnement loopt af op ${endDate}"; - static String m61(completed, total) => + static String m62(completed, total) => "${completed}/${total} herinneringen bewaard"; - static String m62(storageAmountInGB) => + static String m63(storageAmountInGB) => "Zij krijgen ook ${storageAmountInGB} GB"; - static String m63(email) => "Dit is de verificatie-ID van ${email}"; + static String m64(email) => "Dit is de verificatie-ID van ${email}"; - static String m64(count) => + static String m65(count) => "${Intl.plural(count, zero: '', one: '1 dag', other: '${count} dagen')}"; - static String m65(endDate) => "Geldig tot ${endDate}"; + static String m66(endDate) => "Geldig tot ${endDate}"; - static String m66(email) => "Verifieer ${email}"; + static String m67(email) => "Verifieer ${email}"; - static String m67(email) => + static String m68(email) => "We hebben een e-mail gestuurd naar ${email}"; - static String m68(count) => + static String m69(count) => "${Intl.plural(count, one: '${count} jaar geleden', other: '${count} jaar geleden')}"; - static String m69(storageSaved) => + static String m70(storageSaved) => "Je hebt ${storageSaved} succesvol vrijgemaakt!"; final messages = _notInlinedMessages(_notInlinedMessages); @@ -229,6 +231,7 @@ class MessageLookup extends MessageLookupByLibrary { "Ik begrijp dat als ik mijn wachtwoord verlies, ik mijn gegevens kan verliezen omdat mijn gegevens end-to-end versleuteld zijn."), "activeSessions": MessageLookupByLibrary.simpleMessage("Actieve sessies"), + "addAName": MessageLookupByLibrary.simpleMessage("Een naam toevoegen"), "addANewEmail": MessageLookupByLibrary.simpleMessage("Nieuw e-mailadres toevoegen"), "addCollaborator": @@ -307,7 +310,7 @@ class MessageLookup extends MessageLookupByLibrary { MessageLookupByLibrary.simpleMessage("Android, iOS, Web, Desktop"), "androidSignInTitle": MessageLookupByLibrary.simpleMessage("Verificatie vereist"), - "appLock": MessageLookupByLibrary.simpleMessage("App lock"), + "appLock": MessageLookupByLibrary.simpleMessage("App-vergrendeling"), "appVersion": m7, "appleId": MessageLookupByLibrary.simpleMessage("Apple ID"), "apply": MessageLookupByLibrary.simpleMessage("Toepassen"), @@ -373,6 +376,8 @@ class MessageLookup extends MessageLookupByLibrary { "Je zult de beschikbare Cast apparaten hier zien."), "autoCastiOSPermission": MessageLookupByLibrary.simpleMessage( "Zorg ervoor dat lokale netwerkrechten zijn ingeschakeld voor de Ente Photos app, in Instellingen."), + "autoLogoutMessage": MessageLookupByLibrary.simpleMessage( + "Door een technische storing bent u uitgelogd. Onze excuses voor het ongemak."), "autoPair": MessageLookupByLibrary.simpleMessage("Automatisch koppelen"), "autoPairDesc": MessageLookupByLibrary.simpleMessage( @@ -429,6 +434,8 @@ class MessageLookup extends MessageLookupByLibrary { MessageLookupByLibrary.simpleMessage("Controleer op updates"), "checkInboxAndSpamFolder": MessageLookupByLibrary.simpleMessage( "Controleer je inbox (en spam) om verificatie te voltooien"), + "checkStatus": + MessageLookupByLibrary.simpleMessage("Status controleren"), "checking": MessageLookupByLibrary.simpleMessage("Controleren..."), "claimFreeStorage": MessageLookupByLibrary.simpleMessage("Claim gratis opslag"), @@ -450,7 +457,7 @@ class MessageLookup extends MessageLookupByLibrary { "clubByFileName": MessageLookupByLibrary.simpleMessage("Samenvoegen op bestandsnaam"), "clusteringProgress": - MessageLookupByLibrary.simpleMessage("Clustering progress"), + MessageLookupByLibrary.simpleMessage("Voortgang clusteren"), "codeAppliedPageTitle": MessageLookupByLibrary.simpleMessage("Code toegepast"), "codeCopiedToClipboard": MessageLookupByLibrary.simpleMessage( @@ -535,6 +542,7 @@ class MessageLookup extends MessageLookupByLibrary { MessageLookupByLibrary.simpleMessage("Link aanmaken..."), "criticalUpdateAvailable": MessageLookupByLibrary.simpleMessage( "Belangrijke update beschikbaar"), + "crop": MessageLookupByLibrary.simpleMessage("Bijsnijden"), "currentUsageIs": MessageLookupByLibrary.simpleMessage("Huidig gebruik is "), "custom": MessageLookupByLibrary.simpleMessage("Aangepast"), @@ -608,7 +616,8 @@ class MessageLookup extends MessageLookupByLibrary { MessageLookupByLibrary.simpleMessage("Voer de code in"), "deviceFilesAutoUploading": MessageLookupByLibrary.simpleMessage( "Bestanden toegevoegd aan dit album van dit apparaat zullen automatisch geüpload worden naar Ente."), - "deviceLock": MessageLookupByLibrary.simpleMessage("Device lock"), + "deviceLock": + MessageLookupByLibrary.simpleMessage("Apparaat vergrendeld"), "deviceLockExplanation": MessageLookupByLibrary.simpleMessage( "Schakel de schermvergrendeling van het apparaat uit wanneer Ente op de voorgrond is en er een back-up aan de gang is. Dit is normaal gesproken niet nodig, maar kan grote uploads en initiële imports van grote mappen sneller laten verlopen."), "deviceNotFound": @@ -702,7 +711,9 @@ class MessageLookup extends MessageLookupByLibrary { MessageLookupByLibrary.simpleMessage("Voer wachtwoord in"), "enterPasswordToEncrypt": MessageLookupByLibrary.simpleMessage( "Voer een wachtwoord in dat we kunnen gebruiken om je gegevens te versleutelen"), - "enterPin": MessageLookupByLibrary.simpleMessage("Enter PIN"), + "enterPersonName": + MessageLookupByLibrary.simpleMessage("Naam van persoon invoeren"), + "enterPin": MessageLookupByLibrary.simpleMessage("PIN invoeren"), "enterReferralCode": MessageLookupByLibrary.simpleMessage("Voer verwijzingscode in"), "enterThe6digitCodeFromnyourAuthenticatorApp": @@ -728,7 +739,7 @@ class MessageLookup extends MessageLookupByLibrary { "exportYourData": MessageLookupByLibrary.simpleMessage("Exporteer je gegevens"), "faceRecognition": - MessageLookupByLibrary.simpleMessage("Face recognition"), + MessageLookupByLibrary.simpleMessage("Gezichtsherkenning"), "faces": MessageLookupByLibrary.simpleMessage("Gezichten"), "failedToApplyCode": MessageLookupByLibrary.simpleMessage("Code toepassen mislukt"), @@ -772,12 +783,15 @@ class MessageLookup extends MessageLookupByLibrary { MessageLookupByLibrary.simpleMessage("Bestanden verwijderd"), "filesSavedToGallery": MessageLookupByLibrary.simpleMessage( "Bestand opgeslagen in galerij"), + "findPeopleByName": + MessageLookupByLibrary.simpleMessage("Mensen snel op naam zoeken"), "flip": MessageLookupByLibrary.simpleMessage("Omdraaien"), "forYourMemories": MessageLookupByLibrary.simpleMessage("voor uw herinneringen"), "forgotPassword": MessageLookupByLibrary.simpleMessage("Wachtwoord vergeten"), - "foundFaces": MessageLookupByLibrary.simpleMessage("Found faces"), + "foundFaces": + MessageLookupByLibrary.simpleMessage("Gezichten gevonden"), "freeStorageClaimed": MessageLookupByLibrary.simpleMessage("Gratis opslag geclaimd"), "freeStorageOnReferralSuccess": m26, @@ -789,6 +803,8 @@ class MessageLookup extends MessageLookupByLibrary { "freeUpAmount": m29, "freeUpDeviceSpace": MessageLookupByLibrary.simpleMessage("Apparaatruimte vrijmaken"), + "freeUpDeviceSpaceDesc": MessageLookupByLibrary.simpleMessage( + "Bespaar ruimte op je apparaat door bestanden die al geback-upt zijn te wissen."), "freeUpSpace": MessageLookupByLibrary.simpleMessage("Ruimte vrijmaken"), "freeUpSpaceSaving": m30, "galleryMemoryLimitInfo": MessageLookupByLibrary.simpleMessage( @@ -840,7 +856,7 @@ class MessageLookup extends MessageLookupByLibrary { "indexedItems": MessageLookupByLibrary.simpleMessage("Geïndexeerde bestanden"), "indexingIsPaused": MessageLookupByLibrary.simpleMessage( - "Indexing is paused, will automatically resume when device is ready"), + "Indexeren is gepauzeerd. Het zal automatisch hervatten wanneer het apparaat klaar is."), "insecureDevice": MessageLookupByLibrary.simpleMessage("Onveilig apparaat"), "installManually": @@ -883,6 +899,7 @@ class MessageLookup extends MessageLookupByLibrary { MessageLookupByLibrary.simpleMessage("Familie abonnement verlaten"), "leaveSharedAlbum": MessageLookupByLibrary.simpleMessage("Gedeeld album verlaten?"), + "left": MessageLookupByLibrary.simpleMessage("Links"), "light": MessageLookupByLibrary.simpleMessage("Licht"), "lightTheme": MessageLookupByLibrary.simpleMessage("Licht"), "linkCopiedToClipboard": MessageLookupByLibrary.simpleMessage( @@ -935,6 +952,10 @@ class MessageLookup extends MessageLookupByLibrary { "lockscreen": MessageLookupByLibrary.simpleMessage("Vergrendelscherm"), "logInLabel": MessageLookupByLibrary.simpleMessage("Inloggen"), "loggingOut": MessageLookupByLibrary.simpleMessage("Uitloggen..."), + "loginSessionExpired": + MessageLookupByLibrary.simpleMessage("Sessie verlopen"), + "loginSessionExpiredDetails": MessageLookupByLibrary.simpleMessage( + "Jouw sessie is verlopen. Log opnieuw in."), "loginTerms": MessageLookupByLibrary.simpleMessage( "Door op inloggen te klikken, ga ik akkoord met de gebruiksvoorwaarden en privacybeleid"), "logout": MessageLookupByLibrary.simpleMessage("Uitloggen"), @@ -968,6 +989,8 @@ class MessageLookup extends MessageLookupByLibrary { "matrix": MessageLookupByLibrary.simpleMessage("Matrix"), "memoryCount": m34, "merchandise": MessageLookupByLibrary.simpleMessage("Merchandise"), + "mlIndexingDescription": MessageLookupByLibrary.simpleMessage( + "Houd er rekening mee dat dit zal resulteren in een hoger internet- en batterijverbruik totdat alle items zijn geïndexeerd."), "mobileWebDesktop": MessageLookupByLibrary.simpleMessage("Mobiel, Web, Desktop"), "moderateStrength": MessageLookupByLibrary.simpleMessage("Matig"), @@ -995,7 +1018,7 @@ class MessageLookup extends MessageLookupByLibrary { "newAlbum": MessageLookupByLibrary.simpleMessage("Nieuw album"), "newToEnte": MessageLookupByLibrary.simpleMessage("Nieuw bij Ente"), "newest": MessageLookupByLibrary.simpleMessage("Nieuwste"), - "next": MessageLookupByLibrary.simpleMessage("Next"), + "next": MessageLookupByLibrary.simpleMessage("Volgende"), "no": MessageLookupByLibrary.simpleMessage("Nee"), "noAlbumsSharedByYouYet": MessageLookupByLibrary.simpleMessage( "Nog geen albums gedeeld door jou"), @@ -1026,8 +1049,9 @@ class MessageLookup extends MessageLookupByLibrary { "noResults": MessageLookupByLibrary.simpleMessage("Geen resultaten"), "noResultsFound": MessageLookupByLibrary.simpleMessage("Geen resultaten gevonden"), - "noSystemLockFound": - MessageLookupByLibrary.simpleMessage("No system lock found"), + "noSystemLockFound": MessageLookupByLibrary.simpleMessage( + "Geen systeemvergrendeling gevonden"), + "notPersonLabel": m37, "nothingSharedWithYouYet": MessageLookupByLibrary.simpleMessage("Nog niets met je gedeeld"), "nothingToSeeHere": @@ -1055,6 +1079,8 @@ class MessageLookup extends MessageLookupByLibrary { "pairWithPin": MessageLookupByLibrary.simpleMessage("Koppelen met PIN"), "pairingComplete": MessageLookupByLibrary.simpleMessage("Koppeling voltooid"), + "passKeyPendingVerification": MessageLookupByLibrary.simpleMessage( + "Verificatie is nog in behandeling"), "passkey": MessageLookupByLibrary.simpleMessage("Passkey"), "passkeyAuthTitle": MessageLookupByLibrary.simpleMessage("Passkey verificatie"), @@ -1062,7 +1088,7 @@ class MessageLookup extends MessageLookupByLibrary { "passwordChangedSuccessfully": MessageLookupByLibrary.simpleMessage( "Wachtwoord succesvol aangepast"), "passwordLock": MessageLookupByLibrary.simpleMessage("Wachtwoord slot"), - "passwordStrength": m37, + "passwordStrength": m38, "passwordWarning": MessageLookupByLibrary.simpleMessage( "Wij slaan dit wachtwoord niet op, dus als je het vergeet, kunnen we je gegevens niet ontsleutelen"), "paymentDetails": @@ -1071,11 +1097,12 @@ class MessageLookup extends MessageLookupByLibrary { MessageLookupByLibrary.simpleMessage("Betaling mislukt"), "paymentFailedMessage": MessageLookupByLibrary.simpleMessage( "Helaas is je betaling mislukt. Neem contact op met support zodat we je kunnen helpen!"), - "paymentFailedTalkToProvider": m38, + "paymentFailedTalkToProvider": m39, "pendingItems": MessageLookupByLibrary.simpleMessage("Bestanden in behandeling"), "pendingSync": MessageLookupByLibrary.simpleMessage( "Synchronisatie in behandeling"), + "people": MessageLookupByLibrary.simpleMessage("Personen"), "peopleUsingYourCode": MessageLookupByLibrary.simpleMessage( "Mensen die jouw code gebruiken"), "permDeleteWarning": MessageLookupByLibrary.simpleMessage( @@ -1097,10 +1124,10 @@ class MessageLookup extends MessageLookupByLibrary { MessageLookupByLibrary.simpleMessage("Kies middelpunt"), "pinAlbum": MessageLookupByLibrary.simpleMessage("Album bovenaan vastzetten"), - "pinLock": MessageLookupByLibrary.simpleMessage("PIN lock"), + "pinLock": MessageLookupByLibrary.simpleMessage("PIN vergrendeling"), "playOnTv": MessageLookupByLibrary.simpleMessage("Album afspelen op TV"), - "playStoreFreeTrialValidTill": m39, + "playStoreFreeTrialValidTill": m40, "playstoreSubscription": MessageLookupByLibrary.simpleMessage("PlayStore abonnement"), "pleaseCheckYourInternetConnectionAndTryAgain": @@ -1112,12 +1139,12 @@ class MessageLookup extends MessageLookupByLibrary { "pleaseContactSupportIfTheProblemPersists": MessageLookupByLibrary.simpleMessage( "Neem contact op met klantenservice als het probleem aanhoudt"), - "pleaseEmailUsAt": m40, + "pleaseEmailUsAt": m41, "pleaseGrantPermissions": MessageLookupByLibrary.simpleMessage( "Geef alstublieft toestemming"), "pleaseLoginAgain": MessageLookupByLibrary.simpleMessage("Log opnieuw in"), - "pleaseSendTheLogsTo": m41, + "pleaseSendTheLogsTo": m42, "pleaseTryAgain": MessageLookupByLibrary.simpleMessage("Probeer het nog eens"), "pleaseVerifyTheCodeYouHaveEntered": @@ -1152,7 +1179,7 @@ class MessageLookup extends MessageLookupByLibrary { "raiseTicket": MessageLookupByLibrary.simpleMessage("Meld probleem"), "rateTheApp": MessageLookupByLibrary.simpleMessage("Beoordeel de app"), "rateUs": MessageLookupByLibrary.simpleMessage("Beoordeel ons"), - "rateUsOnStore": m42, + "rateUsOnStore": m43, "recover": MessageLookupByLibrary.simpleMessage("Herstellen"), "recoverAccount": MessageLookupByLibrary.simpleMessage("Account herstellen"), @@ -1178,15 +1205,16 @@ class MessageLookup extends MessageLookupByLibrary { "Wachtwoord opnieuw instellen"), "reddit": MessageLookupByLibrary.simpleMessage("Reddit"), "reenterPassword": - MessageLookupByLibrary.simpleMessage("Re-enter password"), - "reenterPin": MessageLookupByLibrary.simpleMessage("Re-enter PIN"), + MessageLookupByLibrary.simpleMessage("Wachtwoord opnieuw invoeren"), + "reenterPin": + MessageLookupByLibrary.simpleMessage("PIN opnieuw invoeren"), "referFriendsAnd2xYourPlan": MessageLookupByLibrary.simpleMessage( "Verwijs vrienden en 2x uw abonnement"), "referralStep1": MessageLookupByLibrary.simpleMessage( "1. Geef deze code aan je vrienden"), "referralStep2": MessageLookupByLibrary.simpleMessage( "2. Ze registreren voor een betaald plan"), - "referralStep3": m43, + "referralStep3": m44, "referrals": MessageLookupByLibrary.simpleMessage("Referenties"), "referralsAreCurrentlyPaused": MessageLookupByLibrary.simpleMessage( "Verwijzingen zijn momenteel gepauzeerd"), @@ -1203,6 +1231,8 @@ class MessageLookup extends MessageLookupByLibrary { "remove": MessageLookupByLibrary.simpleMessage("Verwijder"), "removeDuplicates": MessageLookupByLibrary.simpleMessage("Duplicaten verwijderen"), + "removeDuplicatesDesc": MessageLookupByLibrary.simpleMessage( + "Controleer en verwijder bestanden die exacte kopieën zijn."), "removeFromAlbum": MessageLookupByLibrary.simpleMessage("Verwijder uit album"), "removeFromAlbumTitle": @@ -1212,7 +1242,9 @@ class MessageLookup extends MessageLookupByLibrary { "removeLink": MessageLookupByLibrary.simpleMessage("Verwijder link"), "removeParticipant": MessageLookupByLibrary.simpleMessage("Deelnemer verwijderen"), - "removeParticipantBody": m44, + "removeParticipantBody": m45, + "removePersonLabel": + MessageLookupByLibrary.simpleMessage("Verwijder persoonslabel"), "removePublicLink": MessageLookupByLibrary.simpleMessage("Verwijder publieke link"), "removeShareItemsWarning": MessageLookupByLibrary.simpleMessage( @@ -1228,7 +1260,7 @@ class MessageLookup extends MessageLookupByLibrary { MessageLookupByLibrary.simpleMessage("Bestandsnaam wijzigen"), "renewSubscription": MessageLookupByLibrary.simpleMessage("Abonnement verlengen"), - "renewsOn": m45, + "renewsOn": m46, "reportABug": MessageLookupByLibrary.simpleMessage("Een fout melden"), "reportBug": MessageLookupByLibrary.simpleMessage("Fout melden"), "resendEmail": @@ -1247,6 +1279,10 @@ class MessageLookup extends MessageLookupByLibrary { "retry": MessageLookupByLibrary.simpleMessage("Opnieuw"), "reviewDeduplicateItems": MessageLookupByLibrary.simpleMessage( "Controleer en verwijder de bestanden die u denkt dat dubbel zijn."), + "reviewSuggestions": + MessageLookupByLibrary.simpleMessage("Suggesties beoordelen"), + "right": MessageLookupByLibrary.simpleMessage("Rechts"), + "rotate": MessageLookupByLibrary.simpleMessage("Roteren"), "rotateLeft": MessageLookupByLibrary.simpleMessage("Roteer links"), "rotateRight": MessageLookupByLibrary.simpleMessage("Rechtsom draaien"), "safelyStored": @@ -1259,6 +1295,8 @@ class MessageLookup extends MessageLookupByLibrary { MessageLookupByLibrary.simpleMessage( "Sla je herstelsleutel op als je dat nog niet gedaan hebt"), "saving": MessageLookupByLibrary.simpleMessage("Opslaan..."), + "savingEdits": + MessageLookupByLibrary.simpleMessage("Bewerken opslaan..."), "scanCode": MessageLookupByLibrary.simpleMessage("Scan code"), "scanThisBarcodeWithnyourAuthenticatorApp": MessageLookupByLibrary.simpleMessage( @@ -1275,7 +1313,7 @@ class MessageLookup extends MessageLookupByLibrary { "searchDatesEmptySection": MessageLookupByLibrary.simpleMessage( "Zoeken op een datum, maand of jaar"), "searchFaceEmptySection": MessageLookupByLibrary.simpleMessage( - "Vind alle foto\'s van een persoon"), + "Mensen worden hier getoond als het indexeren klaar is"), "searchFileTypesAndNamesEmptySection": MessageLookupByLibrary.simpleMessage("Bestandstypen en namen"), "searchHint1": @@ -1291,7 +1329,7 @@ class MessageLookup extends MessageLookupByLibrary { "Foto\'s groeperen die in een bepaalde straal van een foto worden genomen"), "searchPeopleEmptySection": MessageLookupByLibrary.simpleMessage( "Nodig mensen uit, en je ziet alle foto\'s die door hen worden gedeeld hier"), - "searchResultCount": m46, + "searchResultCount": m47, "security": MessageLookupByLibrary.simpleMessage("Beveiliging"), "selectALocation": MessageLookupByLibrary.simpleMessage("Selecteer een locatie"), @@ -1318,8 +1356,8 @@ class MessageLookup extends MessageLookupByLibrary { "selectedItemsWillBeDeletedFromAllAlbumsAndMoved": MessageLookupByLibrary.simpleMessage( "Geselecteerde bestanden worden verwijderd uit alle albums en verplaatst naar de prullenbak."), - "selectedPhotos": m47, - "selectedPhotosWithYours": m48, + "selectedPhotos": m48, + "selectedPhotosWithYours": m49, "send": MessageLookupByLibrary.simpleMessage("Verzenden"), "sendEmail": MessageLookupByLibrary.simpleMessage("E-mail versturen"), "sendInvite": @@ -1335,8 +1373,9 @@ class MessageLookup extends MessageLookupByLibrary { "setCover": MessageLookupByLibrary.simpleMessage("Omslag instellen"), "setLabel": MessageLookupByLibrary.simpleMessage("Instellen"), "setNewPassword": - MessageLookupByLibrary.simpleMessage("Set new password"), - "setNewPin": MessageLookupByLibrary.simpleMessage("Set new PIN"), + MessageLookupByLibrary.simpleMessage("Nieuw wachtwoord instellen"), + "setNewPin": + MessageLookupByLibrary.simpleMessage("Nieuwe PIN instellen"), "setPasswordTitle": MessageLookupByLibrary.simpleMessage("Wachtwoord instellen"), "setRadius": MessageLookupByLibrary.simpleMessage("Radius instellen"), @@ -1348,16 +1387,16 @@ class MessageLookup extends MessageLookupByLibrary { "shareAnAlbumNow": MessageLookupByLibrary.simpleMessage("Deel nu een album"), "shareLink": MessageLookupByLibrary.simpleMessage("Link delen"), - "shareMyVerificationID": m49, + "shareMyVerificationID": m50, "shareOnlyWithThePeopleYouWant": MessageLookupByLibrary.simpleMessage( "Deel alleen met de mensen die u wilt"), - "shareTextConfirmOthersVerificationID": m50, + "shareTextConfirmOthersVerificationID": m51, "shareTextRecommendUsingEnte": MessageLookupByLibrary.simpleMessage( "Download Ente zodat we gemakkelijk foto\'s en video\'s in originele kwaliteit kunnen delen\n\nhttps://ente.io"), - "shareTextReferralCode": m51, + "shareTextReferralCode": m52, "shareWithNonenteUsers": MessageLookupByLibrary.simpleMessage( "Delen met niet-Ente gebruikers"), - "shareWithPeopleSectionTitle": m52, + "shareWithPeopleSectionTitle": m53, "shareYourFirstAlbum": MessageLookupByLibrary.simpleMessage("Deel jouw eerste album"), "sharedAlbumSectionDescription": MessageLookupByLibrary.simpleMessage( @@ -1368,7 +1407,7 @@ class MessageLookup extends MessageLookupByLibrary { MessageLookupByLibrary.simpleMessage("Nieuwe gedeelde foto\'s"), "sharedPhotoNotificationsExplanation": MessageLookupByLibrary.simpleMessage( "Ontvang meldingen wanneer iemand een foto toevoegt aan een gedeeld album waar je deel van uitmaakt"), - "sharedWith": m53, + "sharedWith": m54, "sharedWithMe": MessageLookupByLibrary.simpleMessage("Gedeeld met mij"), "sharedWithYou": MessageLookupByLibrary.simpleMessage("Gedeeld met jou"), @@ -1383,11 +1422,11 @@ class MessageLookup extends MessageLookupByLibrary { MessageLookupByLibrary.simpleMessage("Log uit op andere apparaten"), "signUpTerms": MessageLookupByLibrary.simpleMessage( "Ik ga akkoord met de gebruiksvoorwaarden en privacybeleid"), - "singleFileDeleteFromDevice": m54, + "singleFileDeleteFromDevice": m55, "singleFileDeleteHighlight": MessageLookupByLibrary.simpleMessage( "Het wordt uit alle albums verwijderd."), - "singleFileInBothLocalAndRemote": m55, - "singleFileInRemoteOnly": m56, + "singleFileInBothLocalAndRemote": m56, + "singleFileInRemoteOnly": m57, "skip": MessageLookupByLibrary.simpleMessage("Overslaan"), "social": MessageLookupByLibrary.simpleMessage("Sociale media"), "someItemsAreInBothEnteAndYourDevice": MessageLookupByLibrary.simpleMessage( @@ -1429,13 +1468,13 @@ class MessageLookup extends MessageLookupByLibrary { "storage": MessageLookupByLibrary.simpleMessage("Opslagruimte"), "storageBreakupFamily": MessageLookupByLibrary.simpleMessage("Familie"), "storageBreakupYou": MessageLookupByLibrary.simpleMessage("Jij"), - "storageInGB": m57, + "storageInGB": m58, "storageLimitExceeded": MessageLookupByLibrary.simpleMessage("Opslaglimiet overschreden"), - "storageUsageInfo": m58, + "storageUsageInfo": m59, "strongStrength": MessageLookupByLibrary.simpleMessage("Sterk"), - "subAlreadyLinkedErrMessage": m59, - "subWillBeCancelledOn": m60, + "subAlreadyLinkedErrMessage": m60, + "subWillBeCancelledOn": m61, "subscribe": MessageLookupByLibrary.simpleMessage("Abonneer"), "subscribeToEnableSharing": MessageLookupByLibrary.simpleMessage( "Het lijkt erop dat je abonnement is verlopen. Abonneer om delen mogelijk te maken."), @@ -1452,7 +1491,7 @@ class MessageLookup extends MessageLookupByLibrary { "suggestFeatures": MessageLookupByLibrary.simpleMessage("Features voorstellen"), "support": MessageLookupByLibrary.simpleMessage("Ondersteuning"), - "syncProgress": m61, + "syncProgress": m62, "syncStopped": MessageLookupByLibrary.simpleMessage("Synchronisatie gestopt"), "syncing": MessageLookupByLibrary.simpleMessage("Synchroniseren..."), @@ -1460,7 +1499,8 @@ class MessageLookup extends MessageLookupByLibrary { "tapToCopy": MessageLookupByLibrary.simpleMessage("tik om te kopiëren"), "tapToEnterCode": MessageLookupByLibrary.simpleMessage("Tik om code in te voeren"), - "tapToUnlock": MessageLookupByLibrary.simpleMessage("Tap to unlock"), + "tapToUnlock": + MessageLookupByLibrary.simpleMessage("Tik om te ontgrendelen"), "tempErrorContactSupportIfPersists": MessageLookupByLibrary.simpleMessage( "Het lijkt erop dat er iets fout is gegaan. Probeer het later opnieuw. Als de fout zich blijft voordoen, neem dan contact op met ons supportteam."), "terminate": MessageLookupByLibrary.simpleMessage("Beëindigen"), @@ -1481,7 +1521,7 @@ class MessageLookup extends MessageLookupByLibrary { "theseItemsWillBeDeletedFromYourDevice": MessageLookupByLibrary.simpleMessage( "Deze bestanden zullen worden verwijderd van uw apparaat."), - "theyAlsoGetXGb": m62, + "theyAlsoGetXGb": m63, "theyWillBeDeletedFromAllAlbums": MessageLookupByLibrary.simpleMessage( "Ze zullen uit alle albums worden verwijderd."), "thisActionCannotBeUndone": MessageLookupByLibrary.simpleMessage( @@ -1497,7 +1537,7 @@ class MessageLookup extends MessageLookupByLibrary { "Dit e-mailadres is al in gebruik"), "thisImageHasNoExifData": MessageLookupByLibrary.simpleMessage( "Deze foto heeft geen exif gegevens"), - "thisIsPersonVerificationId": m63, + "thisIsPersonVerificationId": m64, "thisIsYourVerificationId": MessageLookupByLibrary.simpleMessage("Dit is uw verificatie-ID"), "thisWillLogYouOutOfTheFollowingDevice": @@ -1507,7 +1547,7 @@ class MessageLookup extends MessageLookupByLibrary { "Dit zal je uitloggen van dit apparaat!"), "toEnableAppLockPleaseSetupDevicePasscodeOrScreen": MessageLookupByLibrary.simpleMessage( - "To enable app lock, please setup device passcode or screen lock in your system settings."), + "Om vergrendelscherm in te schakelen, moet u een toegangscode of schermvergrendeling instellen in uw systeeminstellingen."), "toHideAPhotoOrVideo": MessageLookupByLibrary.simpleMessage( "Om een foto of video te verbergen"), "toResetVerifyEmail": MessageLookupByLibrary.simpleMessage( @@ -1515,11 +1555,12 @@ class MessageLookup extends MessageLookupByLibrary { "todaysLogs": MessageLookupByLibrary.simpleMessage("Logboeken van vandaag"), "tooManyIncorrectAttempts": - MessageLookupByLibrary.simpleMessage("Too many incorrect attempts"), + MessageLookupByLibrary.simpleMessage("Te veel onjuiste pogingen"), "total": MessageLookupByLibrary.simpleMessage("totaal"), "totalSize": MessageLookupByLibrary.simpleMessage("Totale grootte"), "trash": MessageLookupByLibrary.simpleMessage("Prullenbak"), - "trashDaysLeft": m64, + "trashDaysLeft": m65, + "trim": MessageLookupByLibrary.simpleMessage("Knippen"), "tryAgain": MessageLookupByLibrary.simpleMessage("Probeer opnieuw"), "turnOnBackupForAutoUpload": MessageLookupByLibrary.simpleMessage( "Schakel back-up in om bestanden die toegevoegd zijn aan deze map op dit apparaat automatisch te uploaden."), @@ -1567,6 +1608,8 @@ class MessageLookup extends MessageLookupByLibrary { "Tot 50% korting, tot 4 december."), "usableReferralStorageInfo": MessageLookupByLibrary.simpleMessage( "Bruikbare opslag is beperkt door je huidige abonnement. Buitensporige geclaimde opslag zal automatisch bruikbaar worden wanneer je je abonnement upgrade."), + "useAsCover": + MessageLookupByLibrary.simpleMessage("Als cover gebruiken"), "usePublicLinksForPeopleNotOnEnte": MessageLookupByLibrary.simpleMessage( "Gebruik publieke links voor mensen die geen Ente account hebben"), "useRecoveryKey": @@ -1574,7 +1617,7 @@ class MessageLookup extends MessageLookupByLibrary { "useSelectedPhoto": MessageLookupByLibrary.simpleMessage("Gebruik geselecteerde foto"), "usedSpace": MessageLookupByLibrary.simpleMessage("Gebruikte ruimte"), - "validTill": m65, + "validTill": m66, "verificationFailedPleaseTryAgain": MessageLookupByLibrary.simpleMessage( "Verificatie mislukt, probeer het opnieuw"), @@ -1582,7 +1625,7 @@ class MessageLookup extends MessageLookupByLibrary { MessageLookupByLibrary.simpleMessage("Verificatie ID"), "verify": MessageLookupByLibrary.simpleMessage("Verifiëren"), "verifyEmail": MessageLookupByLibrary.simpleMessage("Bevestig e-mail"), - "verifyEmailID": m66, + "verifyEmailID": m67, "verifyIDLabel": MessageLookupByLibrary.simpleMessage("Verifiëren"), "verifyPasskey": MessageLookupByLibrary.simpleMessage("Bevestig passkey"), @@ -1600,6 +1643,10 @@ class MessageLookup extends MessageLookupByLibrary { "viewAll": MessageLookupByLibrary.simpleMessage("Alles weergeven"), "viewAllExifData": MessageLookupByLibrary.simpleMessage("Bekijk alle EXIF gegevens"), + "viewLargeFiles": + MessageLookupByLibrary.simpleMessage("Grote bestanden"), + "viewLargeFilesDesc": MessageLookupByLibrary.simpleMessage( + "Bekijk bestanden die de meeste opslagruimte verbruiken"), "viewLogs": MessageLookupByLibrary.simpleMessage("Logboeken bekijken"), "viewRecoveryKey": MessageLookupByLibrary.simpleMessage("Toon herstelsleutel"), @@ -1615,11 +1662,12 @@ class MessageLookup extends MessageLookupByLibrary { "weDontSupportEditingPhotosAndAlbumsThatYouDont": MessageLookupByLibrary.simpleMessage( "We ondersteunen het bewerken van foto\'s en albums waar je niet de eigenaar van bent nog niet"), - "weHaveSendEmailTo": m67, + "weHaveSendEmailTo": m68, "weakStrength": MessageLookupByLibrary.simpleMessage("Zwak"), "welcomeBack": MessageLookupByLibrary.simpleMessage("Welkom terug!"), + "whatsNew": MessageLookupByLibrary.simpleMessage("Nieuw"), "yearly": MessageLookupByLibrary.simpleMessage("Jaarlijks"), - "yearsAgo": m68, + "yearsAgo": m69, "yes": MessageLookupByLibrary.simpleMessage("Ja"), "yesCancel": MessageLookupByLibrary.simpleMessage("Ja, opzeggen"), "yesConvertToViewer": @@ -1649,7 +1697,7 @@ class MessageLookup extends MessageLookupByLibrary { "Je kunt niet met jezelf delen"), "youDontHaveAnyArchivedItems": MessageLookupByLibrary.simpleMessage( "U heeft geen gearchiveerde bestanden."), - "youHaveSuccessfullyFreedUp": m69, + "youHaveSuccessfullyFreedUp": m70, "yourAccountHasBeenDeleted": MessageLookupByLibrary.simpleMessage("Je account is verwijderd"), "yourMap": MessageLookupByLibrary.simpleMessage("Jouw kaart"), diff --git a/mobile/lib/generated/intl/messages_pl.dart b/mobile/lib/generated/intl/messages_pl.dart index 093efa6bc1..0d26436a56 100644 --- a/mobile/lib/generated/intl/messages_pl.dart +++ b/mobile/lib/generated/intl/messages_pl.dart @@ -26,7 +26,7 @@ class MessageLookup extends MessageLookupByLibrary { static String m1(count) => "${Intl.plural(count, zero: 'Add viewer', one: 'Add viewer', other: 'Add viewers')}"; - static String m37(passwordStrengthValue) => + static String m38(passwordStrengthValue) => "Siła hasła: ${passwordStrengthValue}"; final messages = _notInlinedMessages(_notInlinedMessages); @@ -163,7 +163,7 @@ class MessageLookup extends MessageLookupByLibrary { "passwordChangedSuccessfully": MessageLookupByLibrary.simpleMessage( "Hasło zostało pomyślnie zmienione"), "passwordLock": MessageLookupByLibrary.simpleMessage("Password lock"), - "passwordStrength": m37, + "passwordStrength": m38, "passwordWarning": MessageLookupByLibrary.simpleMessage( "Nie przechowujemy tego hasła, więc jeśli go zapomnisz, nie będziemy w stanie odszyfrować Twoich danych"), "pinLock": MessageLookupByLibrary.simpleMessage("PIN lock"), diff --git a/mobile/lib/generated/intl/messages_pt.dart b/mobile/lib/generated/intl/messages_pt.dart index 02d3d41889..1be5a827f9 100644 --- a/mobile/lib/generated/intl/messages_pt.dart +++ b/mobile/lib/generated/intl/messages_pt.dart @@ -21,7 +21,7 @@ class MessageLookup extends MessageLookupByLibrary { String get localeName => 'pt'; static String m0(count) => - "${Intl.plural(count, zero: 'Adicionar colaborador', one: 'Adicionar coloborador', other: 'Adicionar colaboradores')}"; + "${Intl.plural(count, zero: 'Adicionar colaborador', one: 'Adicionar colaborador', other: 'Adicionar colaboradores')}"; static String m2(count) => "${Intl.plural(count, one: 'Adicionar item', other: 'Adicionar itens')}"; @@ -126,92 +126,94 @@ class MessageLookup extends MessageLookupByLibrary { static String m36(albumName) => "Movido com sucesso para ${albumName}"; - static String m37(passwordStrengthValue) => + static String m37(name) => "Não é ${name}?"; + + static String m38(passwordStrengthValue) => "Segurança da senha: ${passwordStrengthValue}"; - static String m38(providerName) => + static String m39(providerName) => "Por favor, fale com o suporte ${providerName} se você foi cobrado"; - static String m39(endDate) => + static String m40(endDate) => "Teste gratuito válido até ${endDate}.\nVocê pode escolher um plano pago depois."; - static String m40(toEmail) => + static String m41(toEmail) => "Por favor, envie-nos um e-mail para ${toEmail}"; - static String m41(toEmail) => "Por favor, envie os logs para \n${toEmail}"; + static String m42(toEmail) => "Por favor, envie os logs para \n${toEmail}"; - static String m42(storeName) => "Avalie-nos em ${storeName}"; + static String m43(storeName) => "Avalie-nos em ${storeName}"; - static String m43(storageInGB) => "3. Ambos ganham ${storageInGB} GB* grátis"; + static String m44(storageInGB) => "3. Ambos ganham ${storageInGB} GB* grátis"; - static String m44(userEmail) => + static String m45(userEmail) => "${userEmail} será removido deste álbum compartilhado\n\nQuaisquer fotos adicionadas por eles também serão removidas do álbum"; - static String m45(endDate) => "Renovação de assinatura em ${endDate}"; + static String m46(endDate) => "Renovação de assinatura em ${endDate}"; - static String m46(count) => + static String m47(count) => "${Intl.plural(count, one: '${count} resultado encontrado', other: '${count} resultado encontrado')}"; - static String m47(count) => "${count} Selecionados"; + static String m48(count) => "${count} Selecionados"; - static String m48(count, yourCount) => + static String m49(count, yourCount) => "${count} Selecionado (${yourCount} seus)"; - static String m49(verificationID) => + static String m50(verificationID) => "Aqui está meu ID de verificação para o Ente.io: ${verificationID}"; - static String m50(verificationID) => + static String m51(verificationID) => "Ei, você pode confirmar que este é seu ID de verificação do Ente.io? ${verificationID}"; - static String m51(referralCode, referralStorageInGB) => + static String m52(referralCode, referralStorageInGB) => "Código de referência do ente: ${referralCode} \n\nAplique em Configurações → Geral → Indicações para obter ${referralStorageInGB} GB gratuitamente após a sua inscrição em um plano pago\n\nhttps://ente.io"; - static String m52(numberOfPeople) => + static String m53(numberOfPeople) => "${Intl.plural(numberOfPeople, zero: 'Compartilhe com pessoas específicas', one: 'Compartilhado com 1 pessoa', other: 'Compartilhado com ${numberOfPeople} pessoas')}"; - static String m53(emailIDs) => "Compartilhado com ${emailIDs}"; + static String m54(emailIDs) => "Compartilhado com ${emailIDs}"; - static String m54(fileType) => + static String m55(fileType) => "Este(a) ${fileType} será excluído(a) do seu dispositivo."; - static String m55(fileType) => + static String m56(fileType) => "Este(a) ${fileType} está tanto no Ente quanto no seu dispositivo."; - static String m56(fileType) => + static String m57(fileType) => "Este(a) ${fileType} será excluído(a) do Ente."; - static String m57(storageAmountInGB) => "${storageAmountInGB} GB"; + static String m58(storageAmountInGB) => "${storageAmountInGB} GB"; - static String m58( + static String m59( usedAmount, usedStorageUnit, totalAmount, totalStorageUnit) => "${usedAmount} ${usedStorageUnit} de ${totalAmount} ${totalStorageUnit} usado"; - static String m59(id) => + static String m60(id) => "Seu ${id} já está vinculado a outra conta Ente.\nSe você gostaria de usar seu ${id} com esta conta, por favor contate nosso suporte\'\'"; - static String m60(endDate) => "Sua assinatura será cancelada em ${endDate}"; + static String m61(endDate) => "Sua assinatura será cancelada em ${endDate}"; - static String m61(completed, total) => + static String m62(completed, total) => "${completed}/${total} memórias preservadas"; - static String m62(storageAmountInGB) => + static String m63(storageAmountInGB) => "Eles também recebem ${storageAmountInGB} GB"; - static String m63(email) => "Este é o ID de verificação de ${email}"; + static String m64(email) => "Este é o ID de verificação de ${email}"; - static String m64(count) => + static String m65(count) => "${Intl.plural(count, zero: '', one: '1 dia', other: '${count} dias')}"; - static String m65(endDate) => "Válido até ${endDate}"; + static String m66(endDate) => "Válido até ${endDate}"; - static String m66(email) => "Verificar ${email}"; + static String m67(email) => "Verificar ${email}"; - static String m67(email) => "Enviamos um e-mail à ${email}"; + static String m68(email) => "Enviamos um e-mail à ${email}"; - static String m68(count) => + static String m69(count) => "${Intl.plural(count, one: '${count} anos atrás', other: '${count} anos atrás')}"; - static String m69(storageSaved) => + static String m70(storageSaved) => "Você liberou ${storageSaved} com sucesso!"; final messages = _notInlinedMessages(_notInlinedMessages); @@ -228,7 +230,7 @@ class MessageLookup extends MessageLookupByLibrary { MessageLookupByLibrary.simpleMessage("Sessões ativas"), "addAName": MessageLookupByLibrary.simpleMessage("Adicione um nome"), "addANewEmail": - MessageLookupByLibrary.simpleMessage("Adicionar um novo email"), + MessageLookupByLibrary.simpleMessage("Adicionar um novo e-mail"), "addCollaborator": MessageLookupByLibrary.simpleMessage("Adicionar colaborador"), "addCollaborators": m0, @@ -306,7 +308,7 @@ class MessageLookup extends MessageLookupByLibrary { MessageLookupByLibrary.simpleMessage("Android, iOS, Web, Desktop"), "androidSignInTitle": MessageLookupByLibrary.simpleMessage("Autenticação necessária"), - "appLock": MessageLookupByLibrary.simpleMessage("App lock"), + "appLock": MessageLookupByLibrary.simpleMessage("Bloqueio de app"), "appVersion": m7, "appleId": MessageLookupByLibrary.simpleMessage("ID da Apple"), "apply": MessageLookupByLibrary.simpleMessage("Aplicar"), @@ -381,7 +383,7 @@ class MessageLookup extends MessageLookupByLibrary { "available": MessageLookupByLibrary.simpleMessage("Disponível"), "availableStorageSpace": m8, "backedUpFolders": - MessageLookupByLibrary.simpleMessage("Backup de pastas concluído"), + MessageLookupByLibrary.simpleMessage("Pastas com backup"), "backup": MessageLookupByLibrary.simpleMessage("Backup"), "backupFailed": MessageLookupByLibrary.simpleMessage("Erro ao efetuar o backup"), @@ -430,7 +432,7 @@ class MessageLookup extends MessageLookupByLibrary { "checkForUpdates": MessageLookupByLibrary.simpleMessage("Verificar por atualizações"), "checkInboxAndSpamFolder": MessageLookupByLibrary.simpleMessage( - "Verifique sua caixa de entrada (e ‘spam’) para concluir a verificação"), + "Verifique sua caixa de entrada (e spam) para concluir a verificação"), "checkStatus": MessageLookupByLibrary.simpleMessage("Verificar status"), "checking": MessageLookupByLibrary.simpleMessage("Verificando..."), "claimFreeStorage": MessageLookupByLibrary.simpleMessage( @@ -607,7 +609,8 @@ class MessageLookup extends MessageLookupByLibrary { MessageLookupByLibrary.simpleMessage("Insira o código"), "deviceFilesAutoUploading": MessageLookupByLibrary.simpleMessage( "Arquivos adicionados a este álbum do dispositivo serão automaticamente enviados para o Ente."), - "deviceLock": MessageLookupByLibrary.simpleMessage("Device lock"), + "deviceLock": + MessageLookupByLibrary.simpleMessage("Bloqueio de dispositivo"), "deviceLockExplanation": MessageLookupByLibrary.simpleMessage( "Desative o bloqueio de tela do dispositivo quando o Ente estiver em primeiro plano e houver um backup em andamento. Isso normalmente não é necessário, mas pode ajudar nos envios grandes e importações iniciais de grandes bibliotecas a serem concluídos mais rapidamente."), "deviceNotFound": @@ -662,7 +665,7 @@ class MessageLookup extends MessageLookupByLibrary { MessageLookupByLibrary.simpleMessage("Verificação de e-mail"), "emailYourLogs": MessageLookupByLibrary.simpleMessage("Enviar por email seus logs"), - "empty": MessageLookupByLibrary.simpleMessage("Vazio"), + "empty": MessageLookupByLibrary.simpleMessage("Esvaziar"), "emptyTrash": MessageLookupByLibrary.simpleMessage("Esvaziar a lixeira?"), "enableMaps": MessageLookupByLibrary.simpleMessage("Habilitar mapa"), @@ -701,7 +704,7 @@ class MessageLookup extends MessageLookupByLibrary { "Insira a senha para criptografar seus dados"), "enterPersonName": MessageLookupByLibrary.simpleMessage("Inserir nome da pessoa"), - "enterPin": MessageLookupByLibrary.simpleMessage("Enter PIN"), + "enterPin": MessageLookupByLibrary.simpleMessage("Insira o PIN"), "enterReferralCode": MessageLookupByLibrary.simpleMessage( "Insira o código de referência"), "enterThe6digitCodeFromnyourAuthenticatorApp": @@ -738,7 +741,7 @@ class MessageLookup extends MessageLookupByLibrary { "failedToFetchOriginalForEdit": MessageLookupByLibrary.simpleMessage( "Falha ao obter original para edição"), "failedToFetchReferralDetails": MessageLookupByLibrary.simpleMessage( - "Não foi possível buscar informações do produto. Por favor, tente novamente mais tarde."), + "Não foi possível buscar os detalhes de referência. Por favor, tente novamente mais tarde."), "failedToLoadAlbums": MessageLookupByLibrary.simpleMessage("Falha ao carregar álbuns"), "failedToRenew": @@ -1006,7 +1009,7 @@ class MessageLookup extends MessageLookupByLibrary { "newAlbum": MessageLookupByLibrary.simpleMessage("Novo álbum"), "newToEnte": MessageLookupByLibrary.simpleMessage("Novo no Ente"), "newest": MessageLookupByLibrary.simpleMessage("Mais recente"), - "next": MessageLookupByLibrary.simpleMessage("Next"), + "next": MessageLookupByLibrary.simpleMessage("Próximo"), "no": MessageLookupByLibrary.simpleMessage("Não"), "noAlbumsSharedByYouYet": MessageLookupByLibrary.simpleMessage( "Nenhum álbum compartilhado por você ainda"), @@ -1036,8 +1039,9 @@ class MessageLookup extends MessageLookupByLibrary { "noResults": MessageLookupByLibrary.simpleMessage("Nenhum resultado"), "noResultsFound": MessageLookupByLibrary.simpleMessage("Nenhum resultado encontrado"), - "noSystemLockFound": - MessageLookupByLibrary.simpleMessage("No system lock found"), + "noSystemLockFound": MessageLookupByLibrary.simpleMessage( + "Nenhum bloqueio de sistema encontrado"), + "notPersonLabel": m37, "nothingSharedWithYouYet": MessageLookupByLibrary.simpleMessage( "Nada compartilhado com você ainda"), "nothingToSeeHere": @@ -1075,7 +1079,7 @@ class MessageLookup extends MessageLookupByLibrary { MessageLookupByLibrary.simpleMessage("Senha alterada com sucesso"), "passwordLock": MessageLookupByLibrary.simpleMessage("Bloqueio de senha"), - "passwordStrength": m37, + "passwordStrength": m38, "passwordWarning": MessageLookupByLibrary.simpleMessage( "Nós não salvamos essa senha, se você esquecer nós não poderemos descriptografar seus dados"), "paymentDetails": @@ -1084,7 +1088,7 @@ class MessageLookup extends MessageLookupByLibrary { MessageLookupByLibrary.simpleMessage("Falha no pagamento"), "paymentFailedMessage": MessageLookupByLibrary.simpleMessage( "Infelizmente o seu pagamento falhou. Entre em contato com o suporte e nós ajudaremos você!"), - "paymentFailedTalkToProvider": m38, + "paymentFailedTalkToProvider": m39, "pendingItems": MessageLookupByLibrary.simpleMessage("Itens pendentes"), "pendingSync": MessageLookupByLibrary.simpleMessage("Sincronização pendente"), @@ -1109,10 +1113,10 @@ class MessageLookup extends MessageLookupByLibrary { "pickCenterPoint": MessageLookupByLibrary.simpleMessage("Escolha o ponto central"), "pinAlbum": MessageLookupByLibrary.simpleMessage("Fixar álbum"), - "pinLock": MessageLookupByLibrary.simpleMessage("PIN lock"), + "pinLock": MessageLookupByLibrary.simpleMessage("Bloqueio PIN"), "playOnTv": MessageLookupByLibrary.simpleMessage("Reproduzir álbum na TV"), - "playStoreFreeTrialValidTill": m39, + "playStoreFreeTrialValidTill": m40, "playstoreSubscription": MessageLookupByLibrary.simpleMessage("Assinatura da PlayStore"), "pleaseCheckYourInternetConnectionAndTryAgain": @@ -1124,12 +1128,12 @@ class MessageLookup extends MessageLookupByLibrary { "pleaseContactSupportIfTheProblemPersists": MessageLookupByLibrary.simpleMessage( "Por favor, contate o suporte se o problema persistir"), - "pleaseEmailUsAt": m40, + "pleaseEmailUsAt": m41, "pleaseGrantPermissions": MessageLookupByLibrary.simpleMessage( "Por favor, conceda as permissões"), "pleaseLoginAgain": MessageLookupByLibrary.simpleMessage( "Por favor, faça login novamente"), - "pleaseSendTheLogsTo": m41, + "pleaseSendTheLogsTo": m42, "pleaseTryAgain": MessageLookupByLibrary.simpleMessage("Por favor, tente novamente"), "pleaseVerifyTheCodeYouHaveEntered": @@ -1166,7 +1170,7 @@ class MessageLookup extends MessageLookupByLibrary { "rateTheApp": MessageLookupByLibrary.simpleMessage("Avalie o aplicativo"), "rateUs": MessageLookupByLibrary.simpleMessage("Avalie-nos"), - "rateUsOnStore": m42, + "rateUsOnStore": m43, "recover": MessageLookupByLibrary.simpleMessage("Recuperar"), "recoverAccount": MessageLookupByLibrary.simpleMessage("Recuperar conta"), @@ -1193,15 +1197,15 @@ class MessageLookup extends MessageLookupByLibrary { MessageLookupByLibrary.simpleMessage("Redefinir senha"), "reddit": MessageLookupByLibrary.simpleMessage("Reddit"), "reenterPassword": - MessageLookupByLibrary.simpleMessage("Re-enter password"), - "reenterPin": MessageLookupByLibrary.simpleMessage("Re-enter PIN"), + MessageLookupByLibrary.simpleMessage("Reinserir senha"), + "reenterPin": MessageLookupByLibrary.simpleMessage("Reinserir PIN"), "referFriendsAnd2xYourPlan": MessageLookupByLibrary.simpleMessage( "Indique amigos e 2x seu plano"), "referralStep1": MessageLookupByLibrary.simpleMessage( "Envie esse código aos seus amigos"), "referralStep2": MessageLookupByLibrary.simpleMessage( "2. Eles se inscreveram para um plano pago"), - "referralStep3": m43, + "referralStep3": m44, "referrals": MessageLookupByLibrary.simpleMessage("Referências"), "referralsAreCurrentlyPaused": MessageLookupByLibrary.simpleMessage( "Referências estão atualmente pausadas"), @@ -1227,7 +1231,7 @@ class MessageLookup extends MessageLookupByLibrary { "removeLink": MessageLookupByLibrary.simpleMessage("Remover link"), "removeParticipant": MessageLookupByLibrary.simpleMessage("Remover participante"), - "removeParticipantBody": m44, + "removeParticipantBody": m45, "removePersonLabel": MessageLookupByLibrary.simpleMessage("Remover etiqueta da pessoa"), "removePublicLink": @@ -1243,7 +1247,7 @@ class MessageLookup extends MessageLookupByLibrary { "renameFile": MessageLookupByLibrary.simpleMessage("Renomear arquivo"), "renewSubscription": MessageLookupByLibrary.simpleMessage("Renovar assinatura"), - "renewsOn": m45, + "renewsOn": m46, "reportABug": MessageLookupByLibrary.simpleMessage("Reportar um problema"), "reportBug": @@ -1315,7 +1319,7 @@ class MessageLookup extends MessageLookupByLibrary { "Fotos de grupo que estão sendo tiradas em algum raio da foto"), "searchPeopleEmptySection": MessageLookupByLibrary.simpleMessage( "Convide pessoas e você verá todas as fotos compartilhadas por elas aqui"), - "searchResultCount": m46, + "searchResultCount": m47, "security": MessageLookupByLibrary.simpleMessage("Segurança"), "selectALocation": MessageLookupByLibrary.simpleMessage("Selecionar um local"), @@ -1343,14 +1347,14 @@ class MessageLookup extends MessageLookupByLibrary { "selectedItemsWillBeDeletedFromAllAlbumsAndMoved": MessageLookupByLibrary.simpleMessage( "Os itens selecionados serão excluídos de todos os álbuns e movidos para a lixeira."), - "selectedPhotos": m47, - "selectedPhotosWithYours": m48, + "selectedPhotos": m48, + "selectedPhotosWithYours": m49, "send": MessageLookupByLibrary.simpleMessage("Enviar"), "sendEmail": MessageLookupByLibrary.simpleMessage("Enviar e-mail"), "sendInvite": MessageLookupByLibrary.simpleMessage("Enviar convite"), "sendLink": MessageLookupByLibrary.simpleMessage("Enviar link"), "serverEndpoint": - MessageLookupByLibrary.simpleMessage("Servidor endpoint"), + MessageLookupByLibrary.simpleMessage("Endpoint do servidor"), "sessionExpired": MessageLookupByLibrary.simpleMessage("Sessão expirada"), "setAPassword": @@ -1359,8 +1363,8 @@ class MessageLookup extends MessageLookupByLibrary { "setCover": MessageLookupByLibrary.simpleMessage("Definir capa"), "setLabel": MessageLookupByLibrary.simpleMessage("Aplicar"), "setNewPassword": - MessageLookupByLibrary.simpleMessage("Set new password"), - "setNewPin": MessageLookupByLibrary.simpleMessage("Set new PIN"), + MessageLookupByLibrary.simpleMessage("Defina nova senha"), + "setNewPin": MessageLookupByLibrary.simpleMessage("Definir novo PIN"), "setPasswordTitle": MessageLookupByLibrary.simpleMessage("Definir senha"), "setRadius": MessageLookupByLibrary.simpleMessage("Definir raio"), @@ -1373,16 +1377,16 @@ class MessageLookup extends MessageLookupByLibrary { "shareAnAlbumNow": MessageLookupByLibrary.simpleMessage("Compartilhar um álbum agora"), "shareLink": MessageLookupByLibrary.simpleMessage("Compartilhar link"), - "shareMyVerificationID": m49, + "shareMyVerificationID": m50, "shareOnlyWithThePeopleYouWant": MessageLookupByLibrary.simpleMessage( "Compartilhar apenas com as pessoas que você quiser"), - "shareTextConfirmOthersVerificationID": m50, + "shareTextConfirmOthersVerificationID": m51, "shareTextRecommendUsingEnte": MessageLookupByLibrary.simpleMessage( "Baixe o Ente para que possamos compartilhar facilmente fotos e vídeos de qualidade original\n\nhttps://ente.io"), - "shareTextReferralCode": m51, + "shareTextReferralCode": m52, "shareWithNonenteUsers": MessageLookupByLibrary.simpleMessage( "Compartilhar com usuários não-Ente"), - "shareWithPeopleSectionTitle": m52, + "shareWithPeopleSectionTitle": m53, "shareYourFirstAlbum": MessageLookupByLibrary.simpleMessage( "Compartilhar seu primeiro álbum"), "sharedAlbumSectionDescription": MessageLookupByLibrary.simpleMessage( @@ -1395,7 +1399,7 @@ class MessageLookup extends MessageLookupByLibrary { MessageLookupByLibrary.simpleMessage("Novas fotos compartilhadas"), "sharedPhotoNotificationsExplanation": MessageLookupByLibrary.simpleMessage( "Receber notificações quando alguém adicionar uma foto em um álbum compartilhado que você faz parte"), - "sharedWith": m53, + "sharedWith": m54, "sharedWithMe": MessageLookupByLibrary.simpleMessage("Compartilhado comigo"), "sharedWithYou": @@ -1411,11 +1415,11 @@ class MessageLookup extends MessageLookupByLibrary { "Encerrar sessão em outros dispositivos"), "signUpTerms": MessageLookupByLibrary.simpleMessage( "Eu concordo com os termos de serviço e a política de privacidade"), - "singleFileDeleteFromDevice": m54, + "singleFileDeleteFromDevice": m55, "singleFileDeleteHighlight": MessageLookupByLibrary.simpleMessage( "Será excluído de todos os álbuns."), - "singleFileInBothLocalAndRemote": m55, - "singleFileInRemoteOnly": m56, + "singleFileInBothLocalAndRemote": m56, + "singleFileInRemoteOnly": m57, "skip": MessageLookupByLibrary.simpleMessage("Pular"), "social": MessageLookupByLibrary.simpleMessage("Redes sociais"), "someItemsAreInBothEnteAndYourDevice": @@ -1460,13 +1464,13 @@ class MessageLookup extends MessageLookupByLibrary { "storage": MessageLookupByLibrary.simpleMessage("Armazenamento"), "storageBreakupFamily": MessageLookupByLibrary.simpleMessage("Família"), "storageBreakupYou": MessageLookupByLibrary.simpleMessage("Você"), - "storageInGB": m57, + "storageInGB": m58, "storageLimitExceeded": MessageLookupByLibrary.simpleMessage( "Limite de armazenamento excedido"), - "storageUsageInfo": m58, + "storageUsageInfo": m59, "strongStrength": MessageLookupByLibrary.simpleMessage("Forte"), - "subAlreadyLinkedErrMessage": m59, - "subWillBeCancelledOn": m60, + "subAlreadyLinkedErrMessage": m60, + "subWillBeCancelledOn": m61, "subscribe": MessageLookupByLibrary.simpleMessage("Assinar"), "subscribeToEnableSharing": MessageLookupByLibrary.simpleMessage( "Parece que sua assinatura expirou. Por favor inscreva-se para ativar o compartilhamento."), @@ -1483,7 +1487,7 @@ class MessageLookup extends MessageLookupByLibrary { "suggestFeatures": MessageLookupByLibrary.simpleMessage("Sugerir recurso"), "support": MessageLookupByLibrary.simpleMessage("Suporte"), - "syncProgress": m61, + "syncProgress": m62, "syncStopped": MessageLookupByLibrary.simpleMessage("Sincronização interrompida"), "syncing": MessageLookupByLibrary.simpleMessage("Sincronizando..."), @@ -1491,7 +1495,8 @@ class MessageLookup extends MessageLookupByLibrary { "tapToCopy": MessageLookupByLibrary.simpleMessage("toque para copiar"), "tapToEnterCode": MessageLookupByLibrary.simpleMessage("Toque para inserir código"), - "tapToUnlock": MessageLookupByLibrary.simpleMessage("Tap to unlock"), + "tapToUnlock": + MessageLookupByLibrary.simpleMessage("Toque para desbloquear"), "tempErrorContactSupportIfPersists": MessageLookupByLibrary.simpleMessage( "Parece que algo deu errado. Por favor, tente novamente mais tarde. Se o erro persistir, entre em contato com nossa equipe de suporte."), "terminate": MessageLookupByLibrary.simpleMessage("Encerrar"), @@ -1511,7 +1516,7 @@ class MessageLookup extends MessageLookupByLibrary { "theseItemsWillBeDeletedFromYourDevice": MessageLookupByLibrary.simpleMessage( "Estes itens serão excluídos do seu dispositivo."), - "theyAlsoGetXGb": m62, + "theyAlsoGetXGb": m63, "theyWillBeDeletedFromAllAlbums": MessageLookupByLibrary.simpleMessage( "Eles(a) serão excluídos(as) de todos os álbuns."), "thisActionCannotBeUndone": MessageLookupByLibrary.simpleMessage( @@ -1527,7 +1532,7 @@ class MessageLookup extends MessageLookupByLibrary { MessageLookupByLibrary.simpleMessage("Este e-mail já está em uso"), "thisImageHasNoExifData": MessageLookupByLibrary.simpleMessage( "Esta imagem não tem dados exif"), - "thisIsPersonVerificationId": m63, + "thisIsPersonVerificationId": m64, "thisIsYourVerificationId": MessageLookupByLibrary.simpleMessage( "Este é o seu ID de verificação"), "thisWillLogYouOutOfTheFollowingDevice": @@ -1537,18 +1542,18 @@ class MessageLookup extends MessageLookupByLibrary { "Isso fará com que você saia deste dispositivo!"), "toEnableAppLockPleaseSetupDevicePasscodeOrScreen": MessageLookupByLibrary.simpleMessage( - "To enable app lock, please setup device passcode or screen lock in your system settings."), + "Para ativar o bloqueio de app, por favor ative um método de autenticação nas configurações do sistema do seu dispositivo."), "toHideAPhotoOrVideo": MessageLookupByLibrary.simpleMessage( "Para ocultar uma foto ou vídeo"), "toResetVerifyEmail": MessageLookupByLibrary.simpleMessage( - "Para redefinir a sua senha, por favor verifique o seu email primeiro."), + "Para redefinir a sua senha, por favor verifique o seu e-mail primeiro."), "todaysLogs": MessageLookupByLibrary.simpleMessage("Logs de hoje"), - "tooManyIncorrectAttempts": - MessageLookupByLibrary.simpleMessage("Too many incorrect attempts"), + "tooManyIncorrectAttempts": MessageLookupByLibrary.simpleMessage( + "Muitas tentativas incorretas"), "total": MessageLookupByLibrary.simpleMessage("total"), "totalSize": MessageLookupByLibrary.simpleMessage("Tamanho total"), "trash": MessageLookupByLibrary.simpleMessage("Lixeira"), - "trashDaysLeft": m64, + "trashDaysLeft": m65, "trim": MessageLookupByLibrary.simpleMessage("Cortar"), "tryAgain": MessageLookupByLibrary.simpleMessage("Tente novamente"), "turnOnBackupForAutoUpload": MessageLookupByLibrary.simpleMessage( @@ -1594,6 +1599,7 @@ class MessageLookup extends MessageLookupByLibrary { "Até 50% de desconto, até 4 de dezembro."), "usableReferralStorageInfo": MessageLookupByLibrary.simpleMessage( "Armazenamento utilizável é limitado pelo seu plano atual. O armazenamento reivindicado em excesso se tornará utilizável automaticamente quando você fizer a melhoria do seu plano."), + "useAsCover": MessageLookupByLibrary.simpleMessage("Usar como capa"), "usePublicLinksForPeopleNotOnEnte": MessageLookupByLibrary.simpleMessage( "Usar links públicos para pessoas que não estão no Ente"), @@ -1602,7 +1608,7 @@ class MessageLookup extends MessageLookupByLibrary { "useSelectedPhoto": MessageLookupByLibrary.simpleMessage("Utilizar foto selecionada"), "usedSpace": MessageLookupByLibrary.simpleMessage("Espaço em uso"), - "validTill": m65, + "validTill": m66, "verificationFailedPleaseTryAgain": MessageLookupByLibrary.simpleMessage( "Falha na verificação, por favor, tente novamente"), @@ -1610,7 +1616,7 @@ class MessageLookup extends MessageLookupByLibrary { MessageLookupByLibrary.simpleMessage("ID de Verificação"), "verify": MessageLookupByLibrary.simpleMessage("Verificar"), "verifyEmail": MessageLookupByLibrary.simpleMessage("Verificar e-mail"), - "verifyEmailID": m66, + "verifyEmailID": m67, "verifyIDLabel": MessageLookupByLibrary.simpleMessage("Verificar"), "verifyPasskey": MessageLookupByLibrary.simpleMessage("Verificar chave de acesso"), @@ -1647,13 +1653,13 @@ class MessageLookup extends MessageLookupByLibrary { "weDontSupportEditingPhotosAndAlbumsThatYouDont": MessageLookupByLibrary.simpleMessage( "Não suportamos a edição de fotos e álbuns que você ainda não possui"), - "weHaveSendEmailTo": m67, + "weHaveSendEmailTo": m68, "weakStrength": MessageLookupByLibrary.simpleMessage("Fraca"), "welcomeBack": MessageLookupByLibrary.simpleMessage("Bem-vindo de volta!"), "whatsNew": MessageLookupByLibrary.simpleMessage("O que há de novo"), "yearly": MessageLookupByLibrary.simpleMessage("Anual"), - "yearsAgo": m68, + "yearsAgo": m69, "yes": MessageLookupByLibrary.simpleMessage("Sim"), "yesCancel": MessageLookupByLibrary.simpleMessage("Sim, cancelar"), "yesConvertToViewer": MessageLookupByLibrary.simpleMessage( @@ -1684,7 +1690,7 @@ class MessageLookup extends MessageLookupByLibrary { "Você não pode compartilhar consigo mesmo"), "youDontHaveAnyArchivedItems": MessageLookupByLibrary.simpleMessage( "Você não tem nenhum item arquivado."), - "youHaveSuccessfullyFreedUp": m69, + "youHaveSuccessfullyFreedUp": m70, "yourAccountHasBeenDeleted": MessageLookupByLibrary.simpleMessage("Sua conta foi excluída"), "yourMap": MessageLookupByLibrary.simpleMessage("Seu mapa"), diff --git a/mobile/lib/generated/intl/messages_ru.dart b/mobile/lib/generated/intl/messages_ru.dart index 3514bfef6c..eff8e6d898 100644 --- a/mobile/lib/generated/intl/messages_ru.dart +++ b/mobile/lib/generated/intl/messages_ru.dart @@ -127,90 +127,90 @@ class MessageLookup extends MessageLookupByLibrary { static String m36(albumName) => "Успешно перемещено в ${albumName}"; - static String m37(passwordStrengthValue) => + static String m38(passwordStrengthValue) => "Мощность пароля: ${passwordStrengthValue}"; - static String m38(providerName) => + static String m39(providerName) => "Если с вас сняли оплату, обратитесь в службу поддержки ${providerName}"; - static String m39(endDate) => + static String m40(endDate) => "Бесплатный пробный период до ${endDate}.\nПосле, вы сможете выбрать платный план."; - static String m40(toEmail) => "Пожалуйста, напишите нам на ${toEmail}"; + static String m41(toEmail) => "Пожалуйста, напишите нам на ${toEmail}"; - static String m41(toEmail) => "Пожалуйста, отправьте логи на \n${toEmail}"; + static String m42(toEmail) => "Пожалуйста, отправьте логи на \n${toEmail}"; - static String m42(storeName) => "Оцените нас в ${storeName}"; + static String m43(storeName) => "Оцените нас в ${storeName}"; - static String m43(storageInGB) => + static String m44(storageInGB) => "3. Вы оба получаете ${storageInGB} Гигабайт* бесплатно"; - static String m44(userEmail) => + static String m45(userEmail) => "${userEmail} будет удален из этого общего альбома\n\nВсе добавленные им фотографии также будут удалены из альбома"; - static String m45(endDate) => "Обновление подписки на ${endDate}"; + static String m46(endDate) => "Обновление подписки на ${endDate}"; - static String m46(count) => + static String m47(count) => "${Intl.plural(count, one: '${count} результат найден', other: '${count} результатов найдено')}"; - static String m47(count) => "${count} выбрано"; + static String m48(count) => "${count} выбрано"; - static String m48(count, yourCount) => "${count} выбрано (${yourCount} ваши)"; + static String m49(count, yourCount) => "${count} выбрано (${yourCount} ваши)"; - static String m49(verificationID) => + static String m50(verificationID) => "Вот мой проверочный ID: ${verificationID} для ente.io."; - static String m50(verificationID) => + static String m51(verificationID) => "Эй, вы можете подтвердить, что это ваш идентификатор подтверждения ente.io: ${verificationID}"; - static String m51(referralCode, referralStorageInGB) => + static String m52(referralCode, referralStorageInGB) => "Реферальный код Ente: ${referralCode} \n\nПримените его в разделе «Настройки» → «Основные» → «Рефералы», чтобы получить ${referralStorageInGB} Гигабайт бесплатно после того как вы подпишетесь на платный план"; - static String m52(numberOfPeople) => + static String m53(numberOfPeople) => "${Intl.plural(numberOfPeople, zero: 'Поделится с конкретными людьми', one: 'Поделено с 1 человеком', other: 'Поделено с ${numberOfPeople} людьми')}"; - static String m53(emailIDs) => "Поделиться с ${emailIDs}"; + static String m54(emailIDs) => "Поделиться с ${emailIDs}"; - static String m54(fileType) => + static String m55(fileType) => "Это ${fileType} будет удалено с вашего устройства."; - static String m55(fileType) => + static String m56(fileType) => "Этот ${fileType} есть и в Ente, и на вашем устройстве."; - static String m56(fileType) => "Этот ${fileType} будет удалён из Ente."; + static String m57(fileType) => "Этот ${fileType} будет удалён из Ente."; - static String m57(storageAmountInGB) => "${storageAmountInGB} Гигабайт"; + static String m58(storageAmountInGB) => "${storageAmountInGB} Гигабайт"; - static String m58( + static String m59( usedAmount, usedStorageUnit, totalAmount, totalStorageUnit) => "${usedAmount} ${usedStorageUnit} из ${totalAmount} ${totalStorageUnit} использовано"; - static String m59(id) => + static String m60(id) => "Ваш ${id} уже связан с другой учетной записью Ente.\nЕсли вы хотите использовать ${id} с этой учетной записью, пожалуйста, свяжитесь с нашей службой поддержки"; - static String m60(endDate) => "Ваша подписка будет отменена ${endDate}"; + static String m61(endDate) => "Ваша подписка будет отменена ${endDate}"; - static String m61(completed, total) => "${completed}/${total} сохранено"; + static String m62(completed, total) => "${completed}/${total} сохранено"; - static String m62(storageAmountInGB) => + static String m63(storageAmountInGB) => "Они тоже получат ${storageAmountInGB} Гигабайт"; - static String m63(email) => + static String m64(email) => "Этот идентификатор подтверждения пользователя ${email}"; - static String m64(count) => + static String m65(count) => "${Intl.plural(count, zero: '', one: '1 день', other: '${count} дней')}"; - static String m65(endDate) => "Действителен по ${endDate}"; + static String m66(endDate) => "Действителен по ${endDate}"; - static String m66(email) => "Подтвердить ${email}"; + static String m67(email) => "Подтвердить ${email}"; - static String m67(email) => "Мы отправили письмо на ${email}"; + static String m68(email) => "Мы отправили письмо на ${email}"; - static String m68(count) => + static String m69(count) => "${Intl.plural(count, one: '${count} год назад', other: '${count} лет назад')}"; - static String m69(storageSaved) => "Вы успешно освободили ${storageSaved}!"; + static String m70(storageSaved) => "Вы успешно освободили ${storageSaved}!"; final messages = _notInlinedMessages(_notInlinedMessages); static Map _notInlinedMessages(_) => { @@ -1079,7 +1079,7 @@ class MessageLookup extends MessageLookupByLibrary { MessageLookupByLibrary.simpleMessage("Пароль успешно изменён"), "passwordLock": MessageLookupByLibrary.simpleMessage("Блокировка паролем"), - "passwordStrength": m37, + "passwordStrength": m38, "passwordWarning": MessageLookupByLibrary.simpleMessage( "Мы не храним этот пароль, поэтому если вы забудете его, мы не сможем расшифровать ваши данные"), "paymentDetails": @@ -1087,7 +1087,7 @@ class MessageLookup extends MessageLookupByLibrary { "paymentFailed": MessageLookupByLibrary.simpleMessage("Сбой платежа"), "paymentFailedMessage": MessageLookupByLibrary.simpleMessage( "К сожалению, ваш платеж не был выполнен. Пожалуйста, свяжитесь со службой поддержки, и мы вам поможем!"), - "paymentFailedTalkToProvider": m38, + "paymentFailedTalkToProvider": m39, "pendingItems": MessageLookupByLibrary.simpleMessage("Отложенные элементы"), "pendingSync": @@ -1116,7 +1116,7 @@ class MessageLookup extends MessageLookupByLibrary { "pinLock": MessageLookupByLibrary.simpleMessage("PIN lock"), "playOnTv": MessageLookupByLibrary.simpleMessage("Воспроизвести альбом на ТВ"), - "playStoreFreeTrialValidTill": m39, + "playStoreFreeTrialValidTill": m40, "playstoreSubscription": MessageLookupByLibrary.simpleMessage("Подписка на PlayStore"), "pleaseCheckYourInternetConnectionAndTryAgain": @@ -1128,12 +1128,12 @@ class MessageLookup extends MessageLookupByLibrary { "pleaseContactSupportIfTheProblemPersists": MessageLookupByLibrary.simpleMessage( "Если проблема не устранена, обратитесь в службу поддержки"), - "pleaseEmailUsAt": m40, + "pleaseEmailUsAt": m41, "pleaseGrantPermissions": MessageLookupByLibrary.simpleMessage("Предоставьте разрешение"), "pleaseLoginAgain": MessageLookupByLibrary.simpleMessage("Пожалуйста, войдите снова"), - "pleaseSendTheLogsTo": m41, + "pleaseSendTheLogsTo": m42, "pleaseTryAgain": MessageLookupByLibrary.simpleMessage( "Пожалуйста, попробуйте ещё раз"), "pleaseVerifyTheCodeYouHaveEntered": @@ -1170,7 +1170,7 @@ class MessageLookup extends MessageLookupByLibrary { "rateTheApp": MessageLookupByLibrary.simpleMessage("Оценить приложение"), "rateUs": MessageLookupByLibrary.simpleMessage("Оцените нас"), - "rateUsOnStore": m42, + "rateUsOnStore": m43, "recover": MessageLookupByLibrary.simpleMessage("Восстановить"), "recoverAccount": MessageLookupByLibrary.simpleMessage("Восстановить аккаунт"), @@ -1205,7 +1205,7 @@ class MessageLookup extends MessageLookupByLibrary { "1. Дайте этот код своим друзьям"), "referralStep2": MessageLookupByLibrary.simpleMessage( "2. Они подписываются на платный план"), - "referralStep3": m43, + "referralStep3": m44, "referrals": MessageLookupByLibrary.simpleMessage("Рефералы"), "referralsAreCurrentlyPaused": MessageLookupByLibrary.simpleMessage( "Рефералы в настоящее время приостановлены"), @@ -1232,7 +1232,7 @@ class MessageLookup extends MessageLookupByLibrary { "removeLink": MessageLookupByLibrary.simpleMessage("Удалить ссылку"), "removeParticipant": MessageLookupByLibrary.simpleMessage("Исключить участника"), - "removeParticipantBody": m44, + "removeParticipantBody": m45, "removePersonLabel": MessageLookupByLibrary.simpleMessage("Удалить метку человека"), "removePublicLink": @@ -1250,7 +1250,7 @@ class MessageLookup extends MessageLookupByLibrary { MessageLookupByLibrary.simpleMessage("Переименовать файл"), "renewSubscription": MessageLookupByLibrary.simpleMessage("Продлить подписку"), - "renewsOn": m45, + "renewsOn": m46, "reportABug": MessageLookupByLibrary.simpleMessage("Сообщить об ошибке"), "reportBug": MessageLookupByLibrary.simpleMessage("Сообщить об ошибке"), @@ -1318,7 +1318,7 @@ class MessageLookup extends MessageLookupByLibrary { "Групповые фотографии, сделанные в некотором радиусе от фотографии"), "searchPeopleEmptySection": MessageLookupByLibrary.simpleMessage( "Пригласите людей, и вы увидите все фотографии, которыми они поделились здесь"), - "searchResultCount": m46, + "searchResultCount": m47, "security": MessageLookupByLibrary.simpleMessage("Безопасность"), "selectALocation": MessageLookupByLibrary.simpleMessage("Выбрать место"), @@ -1344,8 +1344,8 @@ class MessageLookup extends MessageLookupByLibrary { "selectedItemsWillBeDeletedFromAllAlbumsAndMoved": MessageLookupByLibrary.simpleMessage( "Выбранные элементы будут удалены из всех альбомов и перемещены в корзину."), - "selectedPhotos": m47, - "selectedPhotosWithYours": m48, + "selectedPhotos": m48, + "selectedPhotosWithYours": m49, "send": MessageLookupByLibrary.simpleMessage("Отправить"), "sendEmail": MessageLookupByLibrary.simpleMessage( "Отправить электронное письмо"), @@ -1377,16 +1377,16 @@ class MessageLookup extends MessageLookupByLibrary { "shareAnAlbumNow": MessageLookupByLibrary.simpleMessage("Поделиться альбомом сейчас"), "shareLink": MessageLookupByLibrary.simpleMessage("Поделиться ссылкой"), - "shareMyVerificationID": m49, + "shareMyVerificationID": m50, "shareOnlyWithThePeopleYouWant": MessageLookupByLibrary.simpleMessage( "Поделитесь только с теми людьми, с которыми вы хотите"), - "shareTextConfirmOthersVerificationID": m50, + "shareTextConfirmOthersVerificationID": m51, "shareTextRecommendUsingEnte": MessageLookupByLibrary.simpleMessage( "Скачай Ente, чтобы мы могли легко поделиться фотографиями и видео без сжатия\n\nhttps://ente.io"), - "shareTextReferralCode": m51, + "shareTextReferralCode": m52, "shareWithNonenteUsers": MessageLookupByLibrary.simpleMessage( "Поделится с пользователями без Ente"), - "shareWithPeopleSectionTitle": m52, + "shareWithPeopleSectionTitle": m53, "shareYourFirstAlbum": MessageLookupByLibrary.simpleMessage("Поделиться первым альбомом"), "sharedAlbumSectionDescription": MessageLookupByLibrary.simpleMessage( @@ -1397,7 +1397,7 @@ class MessageLookup extends MessageLookupByLibrary { MessageLookupByLibrary.simpleMessage("Новые общие фотографии"), "sharedPhotoNotificationsExplanation": MessageLookupByLibrary.simpleMessage( "Получать уведомления, когда кто-то добавляет фото в общий альбом, в котором вы состоите"), - "sharedWith": m53, + "sharedWith": m54, "sharedWithMe": MessageLookupByLibrary.simpleMessage("Поделиться со мной"), "sharedWithYou": @@ -1413,11 +1413,11 @@ class MessageLookup extends MessageLookupByLibrary { MessageLookupByLibrary.simpleMessage("Выйти из других устройств"), "signUpTerms": MessageLookupByLibrary.simpleMessage( "Я согласен с условиями предоставления услуг и политикой конфиденциальности"), - "singleFileDeleteFromDevice": m54, + "singleFileDeleteFromDevice": m55, "singleFileDeleteHighlight": MessageLookupByLibrary.simpleMessage( "Он будет удален из всех альбомов."), - "singleFileInBothLocalAndRemote": m55, - "singleFileInRemoteOnly": m56, + "singleFileInBothLocalAndRemote": m56, + "singleFileInRemoteOnly": m57, "skip": MessageLookupByLibrary.simpleMessage("Пропустить"), "social": MessageLookupByLibrary.simpleMessage("Соцсети"), "someItemsAreInBothEnteAndYourDevice": MessageLookupByLibrary.simpleMessage( @@ -1461,13 +1461,13 @@ class MessageLookup extends MessageLookupByLibrary { "storage": MessageLookupByLibrary.simpleMessage("Хранилище"), "storageBreakupFamily": MessageLookupByLibrary.simpleMessage("Семья"), "storageBreakupYou": MessageLookupByLibrary.simpleMessage("Вы"), - "storageInGB": m57, + "storageInGB": m58, "storageLimitExceeded": MessageLookupByLibrary.simpleMessage("Превышен предел хранения"), - "storageUsageInfo": m58, + "storageUsageInfo": m59, "strongStrength": MessageLookupByLibrary.simpleMessage("Сильный"), - "subAlreadyLinkedErrMessage": m59, - "subWillBeCancelledOn": m60, + "subAlreadyLinkedErrMessage": m60, + "subWillBeCancelledOn": m61, "subscribe": MessageLookupByLibrary.simpleMessage("Подписаться"), "subscribeToEnableSharing": MessageLookupByLibrary.simpleMessage( "Похоже, ваша подписка истекла. Пожалуйста, подпишитесь, чтобы включить функцию общего доступа."), @@ -1484,7 +1484,7 @@ class MessageLookup extends MessageLookupByLibrary { "suggestFeatures": MessageLookupByLibrary.simpleMessage("Предложить идею"), "support": MessageLookupByLibrary.simpleMessage("Поддержка"), - "syncProgress": m61, + "syncProgress": m62, "syncStopped": MessageLookupByLibrary.simpleMessage("Синхронизация остановлена"), "syncing": MessageLookupByLibrary.simpleMessage("Синхронизация..."), @@ -1514,7 +1514,7 @@ class MessageLookup extends MessageLookupByLibrary { "theseItemsWillBeDeletedFromYourDevice": MessageLookupByLibrary.simpleMessage( "Эти элементы будут удалено с вашего устройства."), - "theyAlsoGetXGb": m62, + "theyAlsoGetXGb": m63, "theyWillBeDeletedFromAllAlbums": MessageLookupByLibrary.simpleMessage( "Они будут удален из всех альбомов."), "thisActionCannotBeUndone": MessageLookupByLibrary.simpleMessage( @@ -1530,7 +1530,7 @@ class MessageLookup extends MessageLookupByLibrary { "Этот адрес электронной почты уже используется"), "thisImageHasNoExifData": MessageLookupByLibrary.simpleMessage( "Это изображение не имеет exif данных"), - "thisIsPersonVerificationId": m63, + "thisIsPersonVerificationId": m64, "thisIsYourVerificationId": MessageLookupByLibrary.simpleMessage( "Это ваш идентификатор подтверждения"), "thisWillLogYouOutOfTheFollowingDevice": @@ -1551,7 +1551,7 @@ class MessageLookup extends MessageLookupByLibrary { "total": MessageLookupByLibrary.simpleMessage("всего"), "totalSize": MessageLookupByLibrary.simpleMessage("Общий размер"), "trash": MessageLookupByLibrary.simpleMessage("Корзина"), - "trashDaysLeft": m64, + "trashDaysLeft": m65, "trim": MessageLookupByLibrary.simpleMessage("Сократить"), "tryAgain": MessageLookupByLibrary.simpleMessage("Попробовать снова"), "turnOnBackupForAutoUpload": MessageLookupByLibrary.simpleMessage( @@ -1606,7 +1606,7 @@ class MessageLookup extends MessageLookupByLibrary { "useSelectedPhoto": MessageLookupByLibrary.simpleMessage("Использовать выбранное фото"), "usedSpace": MessageLookupByLibrary.simpleMessage("Использовано места"), - "validTill": m65, + "validTill": m66, "verificationFailedPleaseTryAgain": MessageLookupByLibrary.simpleMessage( "Проверка не удалась, попробуйте еще раз"), @@ -1615,7 +1615,7 @@ class MessageLookup extends MessageLookupByLibrary { "verify": MessageLookupByLibrary.simpleMessage("Подтвердить"), "verifyEmail": MessageLookupByLibrary.simpleMessage( "Подтвердить электронную почту"), - "verifyEmailID": m66, + "verifyEmailID": m67, "verifyIDLabel": MessageLookupByLibrary.simpleMessage("Подтверждение"), "verifyPasskey": MessageLookupByLibrary.simpleMessage("Подтвердить ключ"), @@ -1651,12 +1651,12 @@ class MessageLookup extends MessageLookupByLibrary { "weDontSupportEditingPhotosAndAlbumsThatYouDont": MessageLookupByLibrary.simpleMessage( "Мы не можем поддержать редактирование фотографий и альбомов, которыми вы не владеете"), - "weHaveSendEmailTo": m67, + "weHaveSendEmailTo": m68, "weakStrength": MessageLookupByLibrary.simpleMessage("Слабый"), "welcomeBack": MessageLookupByLibrary.simpleMessage("С возвращением!"), "whatsNew": MessageLookupByLibrary.simpleMessage("Что нового"), "yearly": MessageLookupByLibrary.simpleMessage("Ежегодно"), - "yearsAgo": m68, + "yearsAgo": m69, "yes": MessageLookupByLibrary.simpleMessage("Да"), "yesCancel": MessageLookupByLibrary.simpleMessage("Да, отменить"), "yesConvertToViewer": @@ -1686,7 +1686,7 @@ class MessageLookup extends MessageLookupByLibrary { "Вы не можете поделиться с самим собой"), "youDontHaveAnyArchivedItems": MessageLookupByLibrary.simpleMessage( "У вас нет архивных элементов."), - "youHaveSuccessfullyFreedUp": m69, + "youHaveSuccessfullyFreedUp": m70, "yourAccountHasBeenDeleted": MessageLookupByLibrary.simpleMessage( "Ваша учетная запись была удалена"), "yourMap": MessageLookupByLibrary.simpleMessage("Ваша карта"), diff --git a/mobile/lib/generated/intl/messages_tr.dart b/mobile/lib/generated/intl/messages_tr.dart new file mode 100644 index 0000000000..061041d69e --- /dev/null +++ b/mobile/lib/generated/intl/messages_tr.dart @@ -0,0 +1,1710 @@ +// DO NOT EDIT. This is code generated via package:intl/generate_localized.dart +// This is a library that provides messages for a tr locale. All the +// messages from the main program should be duplicated here with the same +// function name. + +// Ignore issues from commonly used lints in this file. +// ignore_for_file:unnecessary_brace_in_string_interps, unnecessary_new +// ignore_for_file:prefer_single_quotes,comment_references, directives_ordering +// ignore_for_file:annotate_overrides,prefer_generic_function_type_aliases +// ignore_for_file:unused_import, file_names, avoid_escaping_inner_quotes +// ignore_for_file:unnecessary_string_interpolations, unnecessary_string_escapes + +import 'package:intl/intl.dart'; +import 'package:intl/message_lookup_by_library.dart'; + +final messages = new MessageLookup(); + +typedef String MessageIfAbsent(String messageStr, List args); + +class MessageLookup extends MessageLookupByLibrary { + String get localeName => 'tr'; + + static String m0(count) => + "${Intl.plural(count, zero: 'Ortak çalışan ekle', one: 'Ortak çalışan ekle', other: 'Ortak çalışan ekle')}"; + + static String m2(count) => + "${Intl.plural(count, one: 'Öğeyi taşı', other: 'Öğeleri taşı')}"; + + static String m3(storageAmount, endDate) => + "${storageAmount} eklentiniz ${endDate} tarihine kadar geçerlidir"; + + static String m1(count) => + "${Intl.plural(count, zero: 'Görüntüleyen ekle', one: 'Görüntüleyen ekle', other: 'Görüntüleyen ekle')}"; + + static String m4(emailOrName) => "${emailOrName} tarafından eklendi"; + + static String m5(albumName) => "${albumName} albümüne başarıyla eklendi"; + + static String m6(count) => + "${Intl.plural(count, zero: 'Katılımcı Yok', one: '1 Katılımcı', other: '${count} Katılımcı')}"; + + static String m7(versionValue) => "Sürüm: ${versionValue}"; + + static String m8(freeAmount, storageUnit) => + "${freeAmount} ${storageUnit} free"; + + static String m9(paymentProvider) => + "Lütfen önce mevcut aboneliğinizi ${paymentProvider} adresinden iptal edin"; + + static String m10(user) => + "${user}, bu albüme daha fazla fotoğraf ekleyemeyecek.\n\nAncak, kendi eklediği mevcut fotoğrafları kaldırmaya devam edebilecektir"; + + static String m11(isFamilyMember, storageAmountInGb) => + "${Intl.select(isFamilyMember, { + 'true': 'Şu ana kadar aileniz ${storageAmountInGb} GB aldı', + 'false': 'Şu ana kadar ${storageAmountInGb} GB aldınız', + 'other': 'Şu ana kadar ${storageAmountInGb} GB aldınız!', + })}"; + + static String m12(albumName) => + "${albumName} için ortak çalışma bağlantısı oluşturuldu"; + + static String m13(familyAdminEmail) => + "Aboneliğinizi yönetmek için lütfen ${familyAdminEmail} ile iletişime geçin"; + + static String m14(provider) => + "Lütfen ${provider} aboneliğinizi yönetmek için support@ente.io adresinden bizimle iletişime geçin."; + + static String m15(endpoint) => "${endpoint}\'e bağlanıldı"; + + static String m16(count) => + "${Intl.plural(count, one: 'Delete ${count} item', other: 'Delete ${count} items')}"; + + static String m17(currentlyDeleting, totalCount) => + "Siliniyor ${currentlyDeleting} / ${totalCount}"; + + static String m18(albumName) => + "Bu, \"${albumName}\"e erişim için olan genel bağlantıyı kaldıracaktır."; + + static String m19(supportEmail) => + "Lütfen kayıtlı e-posta adresinizden ${supportEmail} adresine bir e-posta gönderin"; + + static String m20(count, storageSaved) => + "You have cleaned up ${Intl.plural(count, one: '${count} duplicate file', other: '${count} duplicate files')}, saving (${storageSaved}!)"; + + static String m21(count, formattedSize) => + "${count} dosyalar, ${formattedSize} her biri"; + + static String m22(newEmail) => "E-posta ${newEmail} olarak değiştirildi"; + + static String m23(email) => + "${email} does not have an Ente account.\n\nSend them an invite to share photos."; + + static String m24(count, formattedNumber) => + "Bu cihazdaki ${Intl.plural(count, one: '1 file', other: '${formattedNumber} dosya')} güvenli bir şekilde yedeklendi"; + + static String m25(count, formattedNumber) => + "Bu albümdeki ${Intl.plural(count, one: '1 file', other: '${formattedNumber} dosya')} güvenli bir şekilde yedeklendi"; + + static String m26(storageAmountInGB) => + "Birisinin davet kodunuzu uygulayıp ücretli hesap açtığı her seferede ${storageAmountInGB} GB"; + + static String m27(endDate) => "Ücretsiz deneme ${endDate} sona erir"; + + static String m28(count) => + "You can still access ${Intl.plural(count, one: 'it', other: 'them')} on Ente as long as you have an active subscription"; + + static String m29(sizeInMBorGB) => "${sizeInMBorGB} yer açın"; + + static String m30(count, formattedSize) => + "${Intl.plural(count, one: 'Yer açmak için cihazdan silinebilir ${formattedSize}', other: 'Yer açmak için cihazdan silinebilir ${formattedSize}')}"; + + static String m31(currentlyProcessing, totalCount) => + "Siliniyor ${currentlyProcessing} / ${totalCount}"; + + static String m32(count) => + "${Intl.plural(count, one: '${count} öğe', other: '${count} öğeler')}"; + + static String m33(expiryTime) => + "Bu bağlantı ${expiryTime} dan sonra geçersiz olacaktır"; + + static String m34(count, formattedCount) => + "${Intl.plural(count, zero: 'anı yok', one: '${formattedCount} anı', other: '${formattedCount} anılar')}"; + + static String m35(count) => + "${Intl.plural(count, one: 'Öğeyi taşı', other: 'Öğeleri taşı')}"; + + static String m36(albumName) => "${albumName} adlı albüme başarıyla taşındı"; + + static String m37(name) => "Not ${name}?"; + + static String m38(passwordStrengthValue) => + "Şifrenin güçlülük seviyesi: ${passwordStrengthValue}"; + + static String m39(providerName) => + "Sizden ücret alındıysa lütfen ${providerName} destek ekibiyle görüşün"; + + static String m40(endDate) => + "Free trial valid till ${endDate}.\nYou can choose a paid plan afterwards."; + + static String m41(toEmail) => "Lütfen bize ${toEmail} adresinden ulaşın"; + + static String m42(toEmail) => + "Lütfen günlükleri şu adrese gönderin\n${toEmail}"; + + static String m43(storeName) => "Bizi ${storeName} üzerinden değerlendirin"; + + static String m44(storageInGB) => "3. Hepimiz ${storageInGB} GB* bedava alın"; + + static String m45(userEmail) => + "${userEmail} bu paylaşılan albümden kaldırılacaktır\n\nOnlar tarafından eklenen tüm fotoğraflar da albümden kaldırılacaktır"; + + static String m46(endDate) => "Abonelik ${endDate} tarihinde yenilenir"; + + static String m47(count) => + "${Intl.plural(count, one: '${count} yıl önce', other: '${count} yıl önce')}"; + + static String m48(count) => "${count} seçildi"; + + static String m49(count, yourCount) => + "Seçilenler: ${count} (${yourCount} sizin seçiminiz)"; + + static String m50(verificationID) => + "İşte ente.io için doğrulama kimliğim: ${verificationID}."; + + static String m51(verificationID) => + "Merhaba, bu ente.io doğrulama kimliğinizin doğruluğunu onaylayabilir misiniz: ${verificationID}"; + + static String m52(referralCode, referralStorageInGB) => + "Ente referral code: ${referralCode} \n\nApply it in Settings → General → Referrals to get ${referralStorageInGB} GB free after you signup for a paid plan\n\nhttps://ente.io"; + + static String m53(numberOfPeople) => + "${Intl.plural(numberOfPeople, zero: 'Belirli kişilerle paylaş', one: '1 kişiyle paylaşıldı', other: '${numberOfPeople} kişiyle paylaşıldı')}"; + + static String m54(emailIDs) => "${emailIDs} ile paylaşıldı"; + + static String m55(fileType) => "Bu ${fileType}, cihazınızdan silinecek."; + + static String m56(fileType) => + "This ${fileType} is in both Ente and your device."; + + static String m57(fileType) => "This ${fileType} will be deleted from Ente."; + + static String m58(storageAmountInGB) => "${storageAmountInGB} GB"; + + static String m59( + usedAmount, usedStorageUnit, totalAmount, totalStorageUnit) => + "${usedAmount} ${usedStorageUnit} / ${totalAmount} ${totalStorageUnit} kullanıldı"; + + static String m60(id) => + "Your ${id} is already linked to another Ente account.\nIf you would like to use your ${id} with this account, please contact our support\'\'"; + + static String m61(endDate) => + "Aboneliğiniz ${endDate} tarihinde iptal edilecektir"; + + static String m62(completed, total) => "${completed}/${total} anı korundu"; + + static String m63(storageAmountInGB) => + "Aynı zamanda ${storageAmountInGB} GB alıyorlar"; + + static String m64(email) => "Bu, ${email}\'in Doğrulama Kimliği"; + + static String m65(count) => + "${Intl.plural(count, zero: 'gün', one: '1 gün', other: '${count} gün')}"; + + static String m66(endDate) => "${endDate} tarihine kadar geçerli"; + + static String m67(email) => "${email} doğrula"; + + static String m68(email) => + "E-postayı ${email} adresine gönderdik"; + + static String m69(count) => + "${Intl.plural(count, one: '${count} yıl önce', other: '${count} yıl önce')}"; + + static String m70(storageSaved) => + "Başarılı bir şekilde ${storageSaved} alanını boşalttınız!"; + + final messages = _notInlinedMessages(_notInlinedMessages); + static Map _notInlinedMessages(_) => { + "aNewVersionOfEnteIsAvailable": MessageLookupByLibrary.simpleMessage( + "A new version of Ente is available."), + "about": MessageLookupByLibrary.simpleMessage("Hakkında"), + "account": MessageLookupByLibrary.simpleMessage("Hesap"), + "accountWelcomeBack": + MessageLookupByLibrary.simpleMessage("Tekrar hoş geldiniz!"), + "ackPasswordLostWarning": MessageLookupByLibrary.simpleMessage( + "Şifremi kaybedersem, verilerim uçtan uca şifrelendiği için verilerimi kaybedebileceğimi farkındayım."), + "activeSessions": + MessageLookupByLibrary.simpleMessage("Aktif oturumlar"), + "addAName": MessageLookupByLibrary.simpleMessage("Add a name"), + "addANewEmail": + MessageLookupByLibrary.simpleMessage("Yeni e-posta ekle"), + "addCollaborator": + MessageLookupByLibrary.simpleMessage("Düzenleyici ekle"), + "addCollaborators": m0, + "addFromDevice": MessageLookupByLibrary.simpleMessage("Cihazdan ekle"), + "addItem": m2, + "addLocation": MessageLookupByLibrary.simpleMessage("Konum Ekle"), + "addLocationButton": MessageLookupByLibrary.simpleMessage("Ekle"), + "addMore": MessageLookupByLibrary.simpleMessage("Daha fazla ekle"), + "addNew": MessageLookupByLibrary.simpleMessage("Yeni ekle"), + "addOnPageSubtitle": + MessageLookupByLibrary.simpleMessage("Eklentilerin ayrıntıları"), + "addOnValidTill": m3, + "addOns": MessageLookupByLibrary.simpleMessage("Eklentiler"), + "addPhotos": MessageLookupByLibrary.simpleMessage("Fotoğraf ekle"), + "addSelected": MessageLookupByLibrary.simpleMessage("Seçileni ekle"), + "addToAlbum": MessageLookupByLibrary.simpleMessage("Albüme ekle"), + "addToEnte": MessageLookupByLibrary.simpleMessage("Add to Ente"), + "addToHiddenAlbum": + MessageLookupByLibrary.simpleMessage("Gizli albüme ekle"), + "addViewer": MessageLookupByLibrary.simpleMessage("Görüntüleyici ekle"), + "addViewers": m1, + "addYourPhotosNow": MessageLookupByLibrary.simpleMessage( + "Fotoğraflarınızı şimdi ekleyin"), + "addedAs": MessageLookupByLibrary.simpleMessage("Eklendi"), + "addedBy": m4, + "addedSuccessfullyTo": m5, + "addingToFavorites": + MessageLookupByLibrary.simpleMessage("Favorilere ekleniyor..."), + "advanced": MessageLookupByLibrary.simpleMessage("Gelişmiş"), + "advancedSettings": MessageLookupByLibrary.simpleMessage("Gelişmiş"), + "after1Day": MessageLookupByLibrary.simpleMessage("1 gün sonra"), + "after1Hour": MessageLookupByLibrary.simpleMessage("1 saat sonra"), + "after1Month": MessageLookupByLibrary.simpleMessage("1 ay sonra"), + "after1Week": MessageLookupByLibrary.simpleMessage("1 hafta sonra"), + "after1Year": MessageLookupByLibrary.simpleMessage("1 yıl sonra"), + "albumOwner": MessageLookupByLibrary.simpleMessage("Sahip"), + "albumParticipantsCount": m6, + "albumTitle": MessageLookupByLibrary.simpleMessage("Albüm Başlığı"), + "albumUpdated": + MessageLookupByLibrary.simpleMessage("Albüm güncellendi"), + "albums": MessageLookupByLibrary.simpleMessage("Albümler"), + "allClear": MessageLookupByLibrary.simpleMessage("✨ Tamamen temizle"), + "allMemoriesPreserved": + MessageLookupByLibrary.simpleMessage("Tüm anılar saklandı"), + "allowAddPhotosDescription": MessageLookupByLibrary.simpleMessage( + "Bağlantıya sahip olan kişilere, paylaşılan albüme fotoğraf eklemelerine izin ver."), + "allowAddingPhotos": + MessageLookupByLibrary.simpleMessage("Fotoğraf eklemeye izin ver"), + "allowDownloads": + MessageLookupByLibrary.simpleMessage("İndirmeye izin ver"), + "allowPeopleToAddPhotos": MessageLookupByLibrary.simpleMessage( + "Kullanıcıların fotoğraf eklemesine izin ver"), + "androidBiometricHint": + MessageLookupByLibrary.simpleMessage("Kimliği doğrula"), + "androidBiometricNotRecognized": + MessageLookupByLibrary.simpleMessage("Tanınmadı. Tekrar deneyin."), + "androidBiometricRequiredTitle": + MessageLookupByLibrary.simpleMessage("Biyometrik gerekli"), + "androidBiometricSuccess": + MessageLookupByLibrary.simpleMessage("Başarılı"), + "androidCancelButton": MessageLookupByLibrary.simpleMessage("İptal et"), + "androidDeviceCredentialsRequiredTitle": + MessageLookupByLibrary.simpleMessage( + "Cihaz kimlik bilgileri gerekli"), + "androidDeviceCredentialsSetupDescription": + MessageLookupByLibrary.simpleMessage( + "Cihaz kimlik bilgileri gerekmekte"), + "androidGoToSettingsDescription": MessageLookupByLibrary.simpleMessage( + "Biyometrik kimlik doğrulama cihazınızda ayarlanmamış. Biyometrik kimlik doğrulama eklemek için \'Ayarlar > Güvenlik\' bölümüne gidin."), + "androidIosWebDesktop": + MessageLookupByLibrary.simpleMessage("Android, iOS, Web, Masaüstü"), + "androidSignInTitle": + MessageLookupByLibrary.simpleMessage("Kimlik doğrulaması gerekli"), + "appLock": MessageLookupByLibrary.simpleMessage("App lock"), + "appVersion": m7, + "appleId": MessageLookupByLibrary.simpleMessage("Apple kimliği"), + "apply": MessageLookupByLibrary.simpleMessage("Uygula"), + "applyCodeTitle": MessageLookupByLibrary.simpleMessage("Kodu girin"), + "appstoreSubscription": + MessageLookupByLibrary.simpleMessage("PlayStore aboneliği"), + "archive": MessageLookupByLibrary.simpleMessage("Arşiv"), + "archiveAlbum": MessageLookupByLibrary.simpleMessage("Albümü arşivle"), + "archiving": MessageLookupByLibrary.simpleMessage("Arşivleniyor..."), + "areYouSureThatYouWantToLeaveTheFamily": + MessageLookupByLibrary.simpleMessage( + "Aile planından ayrılmak istediğinize emin misiniz?"), + "areYouSureYouWantToCancel": MessageLookupByLibrary.simpleMessage( + "İptal etmek istediğinize emin misiniz?"), + "areYouSureYouWantToChangeYourPlan": + MessageLookupByLibrary.simpleMessage( + "Planı değistirmek istediğinize emin misiniz?"), + "areYouSureYouWantToExit": MessageLookupByLibrary.simpleMessage( + "Çıkmak istediğinden emin misin?"), + "areYouSureYouWantToLogout": MessageLookupByLibrary.simpleMessage( + "Çıkış yapmak istediğinize emin misiniz?"), + "areYouSureYouWantToRenew": MessageLookupByLibrary.simpleMessage( + "Yenilemek istediğinize emin misiniz?"), + "askCancelReason": MessageLookupByLibrary.simpleMessage( + "Aboneliğiniz iptal edilmiştir. Bunun sebebini paylaşmak ister misiniz?"), + "askDeleteReason": MessageLookupByLibrary.simpleMessage( + "Hesabınızı neden silmek istiyorsunuz?"), + "askYourLovedOnesToShare": MessageLookupByLibrary.simpleMessage( + "Sevdiklerinizden paylaşmalarını isteyin"), + "atAFalloutShelter": + MessageLookupByLibrary.simpleMessage("serpinti sığınağında"), + "authToChangeEmailVerificationSetting": + MessageLookupByLibrary.simpleMessage( + "E-posta doğrulamasını değiştirmek için lütfen kimlik doğrulaması yapın"), + "authToChangeLockscreenSetting": MessageLookupByLibrary.simpleMessage( + "Kilit ekranı ayarını değiştirmek için lütfen kimliğinizi doğrulayın"), + "authToChangeYourEmail": MessageLookupByLibrary.simpleMessage( + "E-postanızı değiştirmek için lütfen kimlik doğrulaması yapın"), + "authToChangeYourPassword": MessageLookupByLibrary.simpleMessage( + "Şifrenizi değiştirmek için lütfen kimlik doğrulaması yapın"), + "authToConfigureTwofactorAuthentication": + MessageLookupByLibrary.simpleMessage( + "İki faktörlü kimlik doğrulamayı yapılandırmak için lütfen kimlik doğrulaması yapın"), + "authToInitiateAccountDeletion": MessageLookupByLibrary.simpleMessage( + "Hesap silme işlemini başlatmak için lütfen kimlik doğrulaması yapın"), + "authToViewYourActiveSessions": MessageLookupByLibrary.simpleMessage( + "Aktif oturumlarınızı görüntülemek için lütfen kimliğinizi doğrulayın"), + "authToViewYourHiddenFiles": MessageLookupByLibrary.simpleMessage( + "Gizli dosyalarınızı görüntülemek için kimlik doğrulama yapınız"), + "authToViewYourMemories": MessageLookupByLibrary.simpleMessage( + "Kodlarınızı görmek için lütfen kimlik doğrulaması yapın"), + "authToViewYourRecoveryKey": MessageLookupByLibrary.simpleMessage( + "Kurtarma anahtarınızı görmek için lütfen kimliğinizi doğrulayın"), + "authenticating": + MessageLookupByLibrary.simpleMessage("Kimlik doğrulanıyor..."), + "authenticationFailedPleaseTryAgain": + MessageLookupByLibrary.simpleMessage( + "Kimlik doğrulama başarısız oldu, lütfen tekrar deneyin"), + "authenticationSuccessful": + MessageLookupByLibrary.simpleMessage("Kimlik doğrulama başarılı!"), + "autoCastDialogBody": MessageLookupByLibrary.simpleMessage( + "You\'ll see available Cast devices here."), + "autoCastiOSPermission": MessageLookupByLibrary.simpleMessage( + "Make sure Local Network permissions are turned on for the Ente Photos app, in Settings."), + "autoLogoutMessage": MessageLookupByLibrary.simpleMessage( + "Due to technical glitch, you have been logged out. Our apologies for the inconvenience."), + "autoPair": MessageLookupByLibrary.simpleMessage("Auto pair"), + "autoPairDesc": MessageLookupByLibrary.simpleMessage( + "Auto pair works only with devices that support Chromecast."), + "available": MessageLookupByLibrary.simpleMessage("Mevcut"), + "availableStorageSpace": m8, + "backedUpFolders": + MessageLookupByLibrary.simpleMessage("Yedeklenmiş klasörler"), + "backup": MessageLookupByLibrary.simpleMessage("Yedekle"), + "backupFailed": + MessageLookupByLibrary.simpleMessage("Yedekleme başarısız oldu"), + "backupOverMobileData": + MessageLookupByLibrary.simpleMessage("Mobil veri ile yedekle"), + "backupSettings": + MessageLookupByLibrary.simpleMessage("Yedekleme seçenekleri"), + "backupVideos": + MessageLookupByLibrary.simpleMessage("Videolari yedekle"), + "blackFridaySale": + MessageLookupByLibrary.simpleMessage("Muhteşem Cuma kampanyası"), + "blog": MessageLookupByLibrary.simpleMessage("Blog"), + "cachedData": + MessageLookupByLibrary.simpleMessage("Ön belleğe alınan veri"), + "calculating": MessageLookupByLibrary.simpleMessage("Hesaplanıyor..."), + "canNotUploadToAlbumsOwnedByOthers": + MessageLookupByLibrary.simpleMessage( + "Başkalarına ait albümlere yüklenemez"), + "canOnlyCreateLinkForFilesOwnedByYou": + MessageLookupByLibrary.simpleMessage( + "Yalnızca size ait dosyalar için bağlantı oluşturabilir"), + "canOnlyRemoveFilesOwnedByYou": MessageLookupByLibrary.simpleMessage( + "Yalnızca size ait dosyaları kaldırabilir"), + "cancel": MessageLookupByLibrary.simpleMessage("İptal Et"), + "cancelOtherSubscription": m9, + "cancelSubscription": + MessageLookupByLibrary.simpleMessage("Abonelik iptali"), + "cannotAddMorePhotosAfterBecomingViewer": m10, + "cannotDeleteSharedFiles": + MessageLookupByLibrary.simpleMessage("Dosyalar silinemiyor"), + "castIPMismatchBody": MessageLookupByLibrary.simpleMessage( + "Please make sure you are on the same network as the TV."), + "castIPMismatchTitle": + MessageLookupByLibrary.simpleMessage("Failed to cast album"), + "castInstruction": MessageLookupByLibrary.simpleMessage( + "Eşleştirmek istediğiniz cihazda cast.ente.io adresini ziyaret edin.\n\nAlbümü TV\'nizde oynatmak için aşağıdaki kodu girin."), + "centerPoint": MessageLookupByLibrary.simpleMessage("Merkez noktası"), + "changeEmail": + MessageLookupByLibrary.simpleMessage("E-posta adresini değiştir"), + "changeLocationOfSelectedItems": MessageLookupByLibrary.simpleMessage( + "Seçilen öğelerin konumu değiştirilsin mi?"), + "changePassword": + MessageLookupByLibrary.simpleMessage("Sifrenizi değiştirin"), + "changePasswordTitle": + MessageLookupByLibrary.simpleMessage("Parolanızı değiştirin"), + "changePermissions": + MessageLookupByLibrary.simpleMessage("İzinleri değiştir?"), + "checkForUpdates": + MessageLookupByLibrary.simpleMessage("Güncellemeleri kontol et"), + "checkInboxAndSpamFolder": MessageLookupByLibrary.simpleMessage( + "Lütfen doğrulama işlemini tamamlamak için gelen kutunuzu (ve spam klasörünüzü) kontrol edin"), + "checkStatus": MessageLookupByLibrary.simpleMessage("Check status"), + "checking": MessageLookupByLibrary.simpleMessage("Kontrol ediliyor..."), + "claimFreeStorage": + MessageLookupByLibrary.simpleMessage("Bedava alan talep edin"), + "claimMore": MessageLookupByLibrary.simpleMessage("Arttır!"), + "claimed": MessageLookupByLibrary.simpleMessage("Alındı"), + "claimedStorageSoFar": m11, + "cleanUncategorized": + MessageLookupByLibrary.simpleMessage("Temiz Genel"), + "cleanUncategorizedDescription": MessageLookupByLibrary.simpleMessage( + "Diğer albümlerde bulunan Kategorilenmemiş tüm dosyaları kaldırın"), + "clearCaches": + MessageLookupByLibrary.simpleMessage("Önbellekleri temizle"), + "clearIndexes": MessageLookupByLibrary.simpleMessage("Açık Dizin"), + "click": MessageLookupByLibrary.simpleMessage("• Tıklamak"), + "clickOnTheOverflowMenu": + MessageLookupByLibrary.simpleMessage("• Taşma menüsüne tıklayın"), + "close": MessageLookupByLibrary.simpleMessage("Kapat"), + "clubByCaptureTime": MessageLookupByLibrary.simpleMessage( + "Yakalama zamanına göre kulüp"), + "clubByFileName": + MessageLookupByLibrary.simpleMessage("Dosya adına göre kulüp"), + "clusteringProgress": + MessageLookupByLibrary.simpleMessage("Clustering progress"), + "codeAppliedPageTitle": + MessageLookupByLibrary.simpleMessage("Kod kabul edildi"), + "codeCopiedToClipboard": + MessageLookupByLibrary.simpleMessage("Kodunuz panoya kopyalandı"), + "codeUsedByYou": + MessageLookupByLibrary.simpleMessage("Sizin kullandığınız kod"), + "collabLinkSectionDescription": MessageLookupByLibrary.simpleMessage( + "Create a link to allow people to add and view photos in your shared album without needing an Ente app or account. Great for collecting event photos."), + "collaborativeLink": + MessageLookupByLibrary.simpleMessage("Organizasyon bağlantısı"), + "collaborativeLinkCreatedFor": m12, + "collaborator": MessageLookupByLibrary.simpleMessage("Düzenleyici"), + "collaboratorsCanAddPhotosAndVideosToTheSharedAlbum": + MessageLookupByLibrary.simpleMessage( + "Düzenleyiciler, paylaşılan albüme fotoğraf ve videolar ekleyebilir."), + "collageLayout": MessageLookupByLibrary.simpleMessage("Düzen"), + "collageSaved": MessageLookupByLibrary.simpleMessage( + "Kolajınız galeriye kaydedildi"), + "collectEventPhotos": MessageLookupByLibrary.simpleMessage( + "Etkinlik fotoğraflarını topla"), + "collectPhotos": + MessageLookupByLibrary.simpleMessage("Fotoğrafları topla"), + "color": MessageLookupByLibrary.simpleMessage("Renk"), + "confirm": MessageLookupByLibrary.simpleMessage("Onayla"), + "confirm2FADisable": MessageLookupByLibrary.simpleMessage( + "İki adımlı kimlik doğrulamasını devre dışı bırakmak istediğinize emin misiniz?"), + "confirmAccountDeletion": + MessageLookupByLibrary.simpleMessage("Hesap silme işlemini onayla"), + "confirmDeletePrompt": MessageLookupByLibrary.simpleMessage( + "Evet, bu hesabı ve tüm verileri kalıcı olarak silmek istiyorum."), + "confirmPassword": + MessageLookupByLibrary.simpleMessage("Şifrenizi onaylayın"), + "confirmPlanChange": MessageLookupByLibrary.simpleMessage( + "Plan değişikliğini onaylayın"), + "confirmRecoveryKey": + MessageLookupByLibrary.simpleMessage("Kurtarma anahtarını doğrula"), + "confirmYourRecoveryKey": MessageLookupByLibrary.simpleMessage( + "Kurtarma anahtarını doğrulayın"), + "connectToDevice": + MessageLookupByLibrary.simpleMessage("Connect to device"), + "contactFamilyAdmin": m13, + "contactSupport": + MessageLookupByLibrary.simpleMessage("Destek ile iletişim"), + "contactToManageSubscription": m14, + "contacts": MessageLookupByLibrary.simpleMessage("Kişiler"), + "contents": MessageLookupByLibrary.simpleMessage("İçerikler"), + "continueLabel": MessageLookupByLibrary.simpleMessage("Devam edin"), + "continueOnFreeTrial": + MessageLookupByLibrary.simpleMessage("Ücretsiz denemeye devam et"), + "convertToAlbum": MessageLookupByLibrary.simpleMessage("Albüme taşı"), + "copyEmailAddress": + MessageLookupByLibrary.simpleMessage("E-posta adresini kopyala"), + "copyLink": MessageLookupByLibrary.simpleMessage("Linki kopyala"), + "copypasteThisCodentoYourAuthenticatorApp": + MessageLookupByLibrary.simpleMessage( + "Bu kodu kopyalayın ve kimlik doğrulama uygulamanıza yapıştırın"), + "couldNotBackUpTryLater": MessageLookupByLibrary.simpleMessage( + "Verilerinizi yedekleyemedik.\nDaha sonra tekrar deneyeceğiz."), + "couldNotFreeUpSpace": + MessageLookupByLibrary.simpleMessage("Yer boşaltılamadı"), + "couldNotUpdateSubscription": + MessageLookupByLibrary.simpleMessage("Abonelikler kaydedilemedi"), + "count": MessageLookupByLibrary.simpleMessage("Miktar"), + "crashReporting": + MessageLookupByLibrary.simpleMessage("Çökme raporlaması"), + "create": MessageLookupByLibrary.simpleMessage("Oluştur"), + "createAccount": + MessageLookupByLibrary.simpleMessage("Hesap oluşturun"), + "createAlbumActionHint": MessageLookupByLibrary.simpleMessage( + "Fotoğrafları seçmek için uzun basın ve + düğmesine tıklayarak bir albüm oluşturun"), + "createCollaborativeLink": + MessageLookupByLibrary.simpleMessage("Create collaborative link"), + "createCollage": MessageLookupByLibrary.simpleMessage("Kolaj oluştur"), + "createNewAccount": + MessageLookupByLibrary.simpleMessage("Yeni bir hesap oluşturun"), + "createOrSelectAlbum": + MessageLookupByLibrary.simpleMessage("Albüm oluştur veya seç"), + "createPublicLink": + MessageLookupByLibrary.simpleMessage("Herkese açık link oluştur"), + "creatingLink": + MessageLookupByLibrary.simpleMessage("Bağlantı oluşturuluyor..."), + "criticalUpdateAvailable": + MessageLookupByLibrary.simpleMessage("Kritik güncelleme mevcut"), + "crop": MessageLookupByLibrary.simpleMessage("Crop"), + "currentUsageIs": + MessageLookupByLibrary.simpleMessage("Güncel kullanımınız "), + "custom": MessageLookupByLibrary.simpleMessage("Kişisel"), + "customEndpoint": m15, + "darkTheme": MessageLookupByLibrary.simpleMessage("Karanlık"), + "dayToday": MessageLookupByLibrary.simpleMessage("Bugün"), + "dayYesterday": MessageLookupByLibrary.simpleMessage("Dün"), + "decrypting": + MessageLookupByLibrary.simpleMessage("Şifre çözülüyor..."), + "decryptingVideo": MessageLookupByLibrary.simpleMessage( + "Videonun şifresi çözülüyor..."), + "deduplicateFiles": + MessageLookupByLibrary.simpleMessage("Dosyaları Tekilleştirme"), + "delete": MessageLookupByLibrary.simpleMessage("Sil"), + "deleteAccount": MessageLookupByLibrary.simpleMessage("Hesabı sil"), + "deleteAccountFeedbackPrompt": MessageLookupByLibrary.simpleMessage( + "Aramızdan ayrıldığınız için üzgünüz. Lütfen kendimizi geliştirmemize yardımcı olun. Neden ayrıldığınızı Açıklar mısınız."), + "deleteAccountPermanentlyButton": + MessageLookupByLibrary.simpleMessage("Hesabımı kalıcı olarak sil"), + "deleteAlbum": MessageLookupByLibrary.simpleMessage("Albümü sil"), + "deleteAlbumDialog": MessageLookupByLibrary.simpleMessage( + "Ayrıca bu albümde bulunan fotoğrafları (ve videoları) parçası oldukları tüm diğer albümlerden silebilir miyim?"), + "deleteAlbumsDialogBody": MessageLookupByLibrary.simpleMessage( + "Bu, tüm boş albümleri silecektir. Bu, albüm listenizdeki dağınıklığı azaltmak istediğinizde kullanışlıdır."), + "deleteAll": MessageLookupByLibrary.simpleMessage("Hepsini Sil"), + "deleteConfirmDialogBody": MessageLookupByLibrary.simpleMessage( + "This account is linked to other Ente apps, if you use any. Your uploaded data, across all Ente apps, will be scheduled for deletion, and your account will be permanently deleted."), + "deleteEmailRequest": MessageLookupByLibrary.simpleMessage( + "Lütfen kayıtlı e-posta adresinizden account-deletion@ente.io\'a e-posta gönderiniz."), + "deleteEmptyAlbums": + MessageLookupByLibrary.simpleMessage("Boş albümleri sil"), + "deleteEmptyAlbumsWithQuestionMark": + MessageLookupByLibrary.simpleMessage("Boş albümleri sileyim mi?"), + "deleteFromBoth": + MessageLookupByLibrary.simpleMessage("Her ikisinden de sil"), + "deleteFromDevice": + MessageLookupByLibrary.simpleMessage("Cihazınızdan silin"), + "deleteFromEnte": + MessageLookupByLibrary.simpleMessage("Delete from Ente"), + "deleteItemCount": m16, + "deleteLocation": MessageLookupByLibrary.simpleMessage("Konumu sil"), + "deletePhotos": + MessageLookupByLibrary.simpleMessage("Fotoğrafları sil"), + "deleteProgress": m17, + "deleteReason1": MessageLookupByLibrary.simpleMessage( + "İhtiyacım olan önemli bir özellik eksik"), + "deleteReason2": MessageLookupByLibrary.simpleMessage( + "Uygulama veya bir özellik olması gerektiğini düşündüğüm gibi çalışmıyor"), + "deleteReason3": MessageLookupByLibrary.simpleMessage( + "Daha çok sevdiğim başka bir hizmet buldum"), + "deleteReason4": + MessageLookupByLibrary.simpleMessage("Nedenim listede yok"), + "deleteRequestSLAText": MessageLookupByLibrary.simpleMessage( + "İsteğiniz 72 saat içinde gerçekleştirilecek."), + "deleteSharedAlbum": MessageLookupByLibrary.simpleMessage( + "Paylaşılan albüm silinsin mi?"), + "deleteSharedAlbumDialogBody": MessageLookupByLibrary.simpleMessage( + "Albüm herkes için silinecek\n\nBu albümdeki başkalarına ait paylaşılan fotoğraflara erişiminizi kaybedeceksiniz"), + "descriptions": MessageLookupByLibrary.simpleMessage("Açıklama"), + "deselectAll": + MessageLookupByLibrary.simpleMessage("Tüm seçimi kaldır"), + "designedToOutlive": MessageLookupByLibrary.simpleMessage( + "Hayatta kalmak için tasarlandı"), + "details": MessageLookupByLibrary.simpleMessage("Ayrıntılar"), + "developerSettings": + MessageLookupByLibrary.simpleMessage("Geliştirici ayarları"), + "developerSettingsWarning": MessageLookupByLibrary.simpleMessage( + "Geliştirici ayarlarını değiştirmek istediğinizden emin misiniz?"), + "deviceCodeHint": MessageLookupByLibrary.simpleMessage("Kodu girin"), + "deviceFilesAutoUploading": MessageLookupByLibrary.simpleMessage( + "Files added to this device album will automatically get uploaded to Ente."), + "deviceLock": MessageLookupByLibrary.simpleMessage("Device lock"), + "deviceLockExplanation": MessageLookupByLibrary.simpleMessage( + "Disable the device screen lock when Ente is in the foreground and there is a backup in progress. This is normally not needed, but may help big uploads and initial imports of large libraries complete faster."), + "deviceNotFound": + MessageLookupByLibrary.simpleMessage("Cihaz bulunamadı"), + "didYouKnow": MessageLookupByLibrary.simpleMessage("Biliyor musun?"), + "disableAutoLock": MessageLookupByLibrary.simpleMessage( + "Otomatik kilidi devre dışı bırak"), + "disableDownloadWarningBody": MessageLookupByLibrary.simpleMessage( + "Görüntüleyiciler, hala harici araçlar kullanarak ekran görüntüsü alabilir veya fotoğraflarınızın bir kopyasını kaydedebilir. Lütfen bunu göz önünde bulundurunuz"), + "disableDownloadWarningTitle": + MessageLookupByLibrary.simpleMessage("Lütfen dikkate alın"), + "disableLinkMessage": m18, + "disableTwofactor": MessageLookupByLibrary.simpleMessage( + "İki Aşamalı Doğrulamayı Devre Dışı Bırak"), + "disablingTwofactorAuthentication": + MessageLookupByLibrary.simpleMessage( + "İki aşamalı doğrulamayı devre dışı bırak..."), + "discord": MessageLookupByLibrary.simpleMessage("Discord"), + "dismiss": MessageLookupByLibrary.simpleMessage("Reddet"), + "distanceInKMUnit": MessageLookupByLibrary.simpleMessage("km"), + "doNotSignOut": MessageLookupByLibrary.simpleMessage("Çıkış yapma"), + "doThisLater": MessageLookupByLibrary.simpleMessage("Sonra yap"), + "doYouWantToDiscardTheEditsYouHaveMade": + MessageLookupByLibrary.simpleMessage( + "Yaptığınız düzenlemeleri silmek istiyor musunuz?"), + "done": MessageLookupByLibrary.simpleMessage("Bitti"), + "doubleYourStorage": MessageLookupByLibrary.simpleMessage( + "Depolama alanınızı ikiye katlayın"), + "download": MessageLookupByLibrary.simpleMessage("İndir"), + "downloadFailed": + MessageLookupByLibrary.simpleMessage("İndirme başarısız"), + "downloading": MessageLookupByLibrary.simpleMessage("İndiriliyor..."), + "dropSupportEmail": m19, + "duplicateFileCountWithStorageSaved": m20, + "duplicateItemsGroup": m21, + "edit": MessageLookupByLibrary.simpleMessage("Düzenle"), + "editLocation": MessageLookupByLibrary.simpleMessage("Konumu düzenle"), + "editLocationTagTitle": + MessageLookupByLibrary.simpleMessage("Konumu düzenle"), + "editsSaved": + MessageLookupByLibrary.simpleMessage("Düzenleme kaydedildi"), + "editsToLocationWillOnlyBeSeenWithinEnte": + MessageLookupByLibrary.simpleMessage( + "Konumda yapılan düzenlemeler yalnızca Ente\'de görülecektir"), + "eligible": MessageLookupByLibrary.simpleMessage("uygun"), + "email": MessageLookupByLibrary.simpleMessage("E-Posta"), + "emailChangedTo": m22, + "emailNoEnteAccount": m23, + "emailVerificationToggle": + MessageLookupByLibrary.simpleMessage("E-posta doğrulama"), + "emailYourLogs": MessageLookupByLibrary.simpleMessage( + "Günlüklerinizi e-postayla gönderin"), + "empty": MessageLookupByLibrary.simpleMessage("Boşalt"), + "emptyTrash": + MessageLookupByLibrary.simpleMessage("Çöp kutusu boşaltılsın mı?"), + "enableMaps": + MessageLookupByLibrary.simpleMessage("Haritaları Etkinleştir"), + "enableMapsDesc": MessageLookupByLibrary.simpleMessage( + "Bu, fotoğraflarınızı bir dünya haritasında gösterecektir.\n\nBu harita Open Street Map tarafından barındırılmaktadır ve fotoğraflarınızın tam konumları hiçbir zaman paylaşılmaz.\n\nBu özelliği istediğiniz zaman Ayarlar\'dan devre dışı bırakabilirsiniz."), + "encryptingBackup": + MessageLookupByLibrary.simpleMessage("Yedekleme şifreleniyor..."), + "encryption": MessageLookupByLibrary.simpleMessage("Şifreleme"), + "encryptionKeys": + MessageLookupByLibrary.simpleMessage("Sifreleme anahtarı"), + "endpointUpdatedMessage": MessageLookupByLibrary.simpleMessage( + "Fatura başarıyla güncellendi"), + "endtoendEncryptedByDefault": MessageLookupByLibrary.simpleMessage( + "Varsayılan olarak uçtan uca şifrelenmiş"), + "enteCanEncryptAndPreserveFilesOnlyIfYouGrant": + MessageLookupByLibrary.simpleMessage( + "Ente can encrypt and preserve files only if you grant access to them"), + "entePhotosPerm": MessageLookupByLibrary.simpleMessage( + "Ente needs permission to preserve your photos"), + "enteSubscriptionPitch": MessageLookupByLibrary.simpleMessage( + "Ente preserves your memories, so they\'re always available to you, even if you lose your device."), + "enteSubscriptionShareWithFamily": MessageLookupByLibrary.simpleMessage( + "Aileniz de planınıza eklenebilir."), + "enterAlbumName": + MessageLookupByLibrary.simpleMessage("Bir albüm adı girin"), + "enterCode": MessageLookupByLibrary.simpleMessage("Kodu giriniz"), + "enterCodeDescription": MessageLookupByLibrary.simpleMessage( + "Arkadaşınız tarafından sağlanan kodu girerek hem sizin hem de arkadaşınızın ücretsiz depolamayı talep etmek için girin"), + "enterEmail": + MessageLookupByLibrary.simpleMessage("E-postanızı giriniz"), + "enterFileName": + MessageLookupByLibrary.simpleMessage("Dosya adını girin"), + "enterNewPasswordToEncrypt": MessageLookupByLibrary.simpleMessage( + "Verilerinizi şifrelemek için kullanabileceğimiz yeni bir şifre girin"), + "enterPassword": + MessageLookupByLibrary.simpleMessage("Şifrenizi girin"), + "enterPasswordToEncrypt": MessageLookupByLibrary.simpleMessage( + "Verilerinizi şifrelemek için kullanabileceğimiz bir şifre girin"), + "enterPersonName": + MessageLookupByLibrary.simpleMessage("Enter person name"), + "enterPin": MessageLookupByLibrary.simpleMessage("Enter PIN"), + "enterReferralCode": + MessageLookupByLibrary.simpleMessage("Davet kodunuzu girin"), + "enterThe6digitCodeFromnyourAuthenticatorApp": + MessageLookupByLibrary.simpleMessage( + "Doğrulama uygulamasındaki 6 basamaklı kodu giriniz"), + "enterValidEmail": MessageLookupByLibrary.simpleMessage( + "Lütfen geçerli bir E-posta adresi girin."), + "enterYourEmailAddress": + MessageLookupByLibrary.simpleMessage("E-posta adresinizi girin"), + "enterYourPassword": + MessageLookupByLibrary.simpleMessage("Lütfen şifrenizi giriniz"), + "enterYourRecoveryKey": + MessageLookupByLibrary.simpleMessage("Kurtarma kodunuzu girin"), + "error": MessageLookupByLibrary.simpleMessage("Hata"), + "everywhere": MessageLookupByLibrary.simpleMessage("her yerde"), + "exif": MessageLookupByLibrary.simpleMessage("EXIF"), + "existingUser": + MessageLookupByLibrary.simpleMessage("Mevcut kullanıcı"), + "expiredLinkInfo": MessageLookupByLibrary.simpleMessage( + "Bu bağlantının süresi dolmuştur. Lütfen yeni bir süre belirleyin veya bağlantı süresini devre dışı bırakın."), + "exportLogs": + MessageLookupByLibrary.simpleMessage("Günlüğü dışa aktar"), + "exportYourData": + MessageLookupByLibrary.simpleMessage("Veriyi dışarı aktar"), + "faceRecognition": + MessageLookupByLibrary.simpleMessage("Face recognition"), + "faces": MessageLookupByLibrary.simpleMessage("Yüzler"), + "failedToApplyCode": + MessageLookupByLibrary.simpleMessage("Uygulanırken hata oluştu"), + "failedToCancel": MessageLookupByLibrary.simpleMessage( + "İptal edilirken sorun oluştu"), + "failedToDownloadVideo": + MessageLookupByLibrary.simpleMessage("Video indirilemedi"), + "failedToFetchOriginalForEdit": MessageLookupByLibrary.simpleMessage( + "Düzenleme için orijinal getirilemedi"), + "failedToFetchReferralDetails": MessageLookupByLibrary.simpleMessage( + "Davet ayrıntıları çekilemedi. Iütfen daha sonra deneyin."), + "failedToLoadAlbums": MessageLookupByLibrary.simpleMessage( + "Albüm yüklenirken hata oluştu"), + "failedToRenew": MessageLookupByLibrary.simpleMessage( + "Abonelik yenilenirken hata oluştu"), + "failedToVerifyPaymentStatus": + MessageLookupByLibrary.simpleMessage("Ödeme durumu doğrulanamadı"), + "familyPlanOverview": MessageLookupByLibrary.simpleMessage( + "Add 5 family members to your existing plan without paying extra.\n\nEach member gets their own private space, and cannot see each other\'s files unless they\'re shared.\n\nFamily plans are available to customers who have a paid Ente subscription.\n\nSubscribe now to get started!"), + "familyPlanPortalTitle": MessageLookupByLibrary.simpleMessage("Aile"), + "familyPlans": MessageLookupByLibrary.simpleMessage("Aile Planı"), + "faq": MessageLookupByLibrary.simpleMessage("Sıkça sorulan sorular"), + "faqs": MessageLookupByLibrary.simpleMessage("Sık sorulanlar"), + "favorite": MessageLookupByLibrary.simpleMessage("Favori"), + "feedback": MessageLookupByLibrary.simpleMessage("Geri Bildirim"), + "fileFailedToSaveToGallery": MessageLookupByLibrary.simpleMessage( + "Dosya galeriye kaydedilemedi"), + "fileInfoAddDescHint": + MessageLookupByLibrary.simpleMessage("Bir açıklama ekle..."), + "fileSavedToGallery": + MessageLookupByLibrary.simpleMessage("Video galeriye kaydedildi"), + "fileTypes": MessageLookupByLibrary.simpleMessage("Dosya türü"), + "fileTypesAndNames": + MessageLookupByLibrary.simpleMessage("Dosya türleri ve adları"), + "filesBackedUpFromDevice": m24, + "filesBackedUpInAlbum": m25, + "filesDeleted": + MessageLookupByLibrary.simpleMessage("Dosyalar silinmiş"), + "filesSavedToGallery": + MessageLookupByLibrary.simpleMessage("Files saved to gallery"), + "findPeopleByName": + MessageLookupByLibrary.simpleMessage("Find people quickly by name"), + "flip": MessageLookupByLibrary.simpleMessage("Çevir"), + "forYourMemories": + MessageLookupByLibrary.simpleMessage("anıların için"), + "forgotPassword": + MessageLookupByLibrary.simpleMessage("Şifremi unuttum"), + "foundFaces": MessageLookupByLibrary.simpleMessage("Found faces"), + "freeStorageClaimed": + MessageLookupByLibrary.simpleMessage("Alınan bedava alan"), + "freeStorageOnReferralSuccess": m26, + "freeStorageUsable": + MessageLookupByLibrary.simpleMessage("Kullanılabilir bedava alan"), + "freeTrial": MessageLookupByLibrary.simpleMessage("Ücretsiz deneme"), + "freeTrialValidTill": m27, + "freeUpAccessPostDelete": m28, + "freeUpAmount": m29, + "freeUpDeviceSpace": + MessageLookupByLibrary.simpleMessage("Cihaz alanını boşaltın"), + "freeUpDeviceSpaceDesc": MessageLookupByLibrary.simpleMessage( + "Save space on your device by clearing files that have been already backed up."), + "freeUpSpace": MessageLookupByLibrary.simpleMessage("Boş alan"), + "freeUpSpaceSaving": m30, + "galleryMemoryLimitInfo": MessageLookupByLibrary.simpleMessage( + "Galeride 1000\'e kadar anı gösterilir"), + "general": MessageLookupByLibrary.simpleMessage("Genel"), + "generatingEncryptionKeys": MessageLookupByLibrary.simpleMessage( + "Şifreleme anahtarı oluşturuluyor..."), + "genericProgress": m31, + "goToSettings": MessageLookupByLibrary.simpleMessage("Ayarlara git"), + "googlePlayId": + MessageLookupByLibrary.simpleMessage("Google play kimliği"), + "grantFullAccessPrompt": MessageLookupByLibrary.simpleMessage( + "Lütfen Ayarlar uygulamasında tüm fotoğraflara erişime izin verin"), + "grantPermission": + MessageLookupByLibrary.simpleMessage("İzinleri değiştir"), + "groupNearbyPhotos": MessageLookupByLibrary.simpleMessage( + "Yakındaki fotoğrafları gruplandır"), + "hearUsExplanation": MessageLookupByLibrary.simpleMessage( + "Biz uygulama kurulumlarını takip etmiyoruz. Bizi nereden duyduğunuzdan bahsetmeniz bize çok yardımcı olacak!"), + "hearUsWhereTitle": MessageLookupByLibrary.simpleMessage( + "Ente\'yi nereden duydunuz? (opsiyonel)"), + "help": MessageLookupByLibrary.simpleMessage("Yardım"), + "hidden": MessageLookupByLibrary.simpleMessage("Gizle"), + "hide": MessageLookupByLibrary.simpleMessage("Gizle"), + "hiding": MessageLookupByLibrary.simpleMessage("Gizleniyor..."), + "hostedAtOsmFrance": + MessageLookupByLibrary.simpleMessage("OSM Fransa\'da ağırlandı"), + "howItWorks": MessageLookupByLibrary.simpleMessage("Nasıl çalışır"), + "howToViewShareeVerificationID": MessageLookupByLibrary.simpleMessage( + "Lütfen onlardan ayarlar ekranında e-posta adresine uzun süre basmalarını ve her iki cihazdaki kimliklerin eşleştiğini doğrulamalarını isteyin."), + "iOSGoToSettingsDescription": MessageLookupByLibrary.simpleMessage( + "Cihazınızda biyometrik kimlik doğrulama ayarlanmamış. Lütfen telefonunuzda Touch ID veya Face ID\'yi etkinleştirin."), + "iOSLockOut": MessageLookupByLibrary.simpleMessage( + "Biyometrik kimlik doğrulama devre dışı. Etkinleştirmek için lütfen ekranınızı kilitleyin ve kilidini açın."), + "iOSOkButton": MessageLookupByLibrary.simpleMessage("Tamam"), + "ignoreUpdate": MessageLookupByLibrary.simpleMessage("Yoksay"), + "ignoredFolderUploadReason": MessageLookupByLibrary.simpleMessage( + "Some files in this album are ignored from upload because they had previously been deleted from Ente."), + "importing": + MessageLookupByLibrary.simpleMessage("İçeri aktarılıyor...."), + "incorrectCode": MessageLookupByLibrary.simpleMessage("Yanlış kod"), + "incorrectPasswordTitle": + MessageLookupByLibrary.simpleMessage("Yanlış şifre"), + "incorrectRecoveryKey": + MessageLookupByLibrary.simpleMessage("Yanlış kurtarma kodu"), + "incorrectRecoveryKeyBody": MessageLookupByLibrary.simpleMessage( + "Girdiğiniz kurtarma kod yanlış"), + "incorrectRecoveryKeyTitle": + MessageLookupByLibrary.simpleMessage("Yanlış kurtarma kodu"), + "indexedItems": + MessageLookupByLibrary.simpleMessage("Yeni öğeleri indeksle"), + "indexingIsPaused": MessageLookupByLibrary.simpleMessage( + "Indexing is paused. It will automatically resume when device is ready."), + "insecureDevice": + MessageLookupByLibrary.simpleMessage("Güvenilir olmayan cihaz"), + "installManually": + MessageLookupByLibrary.simpleMessage("Manuel kurulum"), + "invalidEmailAddress": + MessageLookupByLibrary.simpleMessage("Geçersiz e-posta adresi"), + "invalidEndpoint": + MessageLookupByLibrary.simpleMessage("Geçersiz uç nokta"), + "invalidEndpointMessage": MessageLookupByLibrary.simpleMessage( + "Üzgünüz, girdiğiniz uç nokta geçersiz. Lütfen geçerli bir uç nokta girin ve tekrar deneyin."), + "invalidKey": MessageLookupByLibrary.simpleMessage("Gecersiz anahtar"), + "invalidRecoveryKey": MessageLookupByLibrary.simpleMessage( + "Girdiğiniz kurtarma anahtarı geçerli değil. Lütfen anahtarın 24 kelime içerdiğinden ve her bir kelimenin doğru şekilde yazıldığından emin olun.\n\nEğer eski bir kurtarma kodu girdiyseniz, o zaman kodun 64 karakter uzunluğunda olduğunu kontrol edin."), + "invite": MessageLookupByLibrary.simpleMessage("Davet et"), + "inviteToEnte": MessageLookupByLibrary.simpleMessage("Invite to Ente"), + "inviteYourFriends": + MessageLookupByLibrary.simpleMessage("Arkadaşlarını davet et"), + "inviteYourFriendsToEnte": + MessageLookupByLibrary.simpleMessage("Invite your friends to Ente"), + "itLooksLikeSomethingWentWrongPleaseRetryAfterSome": + MessageLookupByLibrary.simpleMessage( + "Bir şeyler ters gitmiş gibi görünüyor. Lütfen bir süre sonra tekrar deneyin. Hata devam ederse, lütfen destek ekibimizle iletişime geçin."), + "itemCount": m32, + "itemsShowTheNumberOfDaysRemainingBeforePermanentDeletion": + MessageLookupByLibrary.simpleMessage( + "Öğeler, kalıcı olarak silinmeden önce kalan gün sayısını gösterir"), + "itemsWillBeRemovedFromAlbum": MessageLookupByLibrary.simpleMessage( + "Seçilen öğeler bu albümden kaldırılacak"), + "joinDiscord": MessageLookupByLibrary.simpleMessage("Discord\'a Katıl"), + "keepPhotos": + MessageLookupByLibrary.simpleMessage("Fotoğrafları sakla"), + "kiloMeterUnit": MessageLookupByLibrary.simpleMessage("km"), + "kindlyHelpUsWithThisInformation": MessageLookupByLibrary.simpleMessage( + "Lütfen bu bilgilerle bize yardımcı olun"), + "language": MessageLookupByLibrary.simpleMessage("Dil"), + "lastUpdated": + MessageLookupByLibrary.simpleMessage("En son güncellenen"), + "leave": MessageLookupByLibrary.simpleMessage("Çıkış yap"), + "leaveAlbum": + MessageLookupByLibrary.simpleMessage("Albümü yeniden adlandır"), + "leaveFamily": + MessageLookupByLibrary.simpleMessage("Aile planından ayrıl"), + "leaveSharedAlbum": MessageLookupByLibrary.simpleMessage( + "Paylaşılan albüm silinsin mi?"), + "left": MessageLookupByLibrary.simpleMessage("Left"), + "light": MessageLookupByLibrary.simpleMessage("Aydınlık"), + "lightTheme": MessageLookupByLibrary.simpleMessage("Aydınlık"), + "linkCopiedToClipboard": + MessageLookupByLibrary.simpleMessage("Link panoya kopyalandı"), + "linkDeviceLimit": MessageLookupByLibrary.simpleMessage("Cihaz limiti"), + "linkEnabled": MessageLookupByLibrary.simpleMessage("Geçerli"), + "linkExpired": MessageLookupByLibrary.simpleMessage("Süresi dolmuş"), + "linkExpiresOn": m33, + "linkExpiry": + MessageLookupByLibrary.simpleMessage("Linkin geçerliliği"), + "linkHasExpired": + MessageLookupByLibrary.simpleMessage("Bağlantının süresi dolmuş"), + "linkNeverExpires": MessageLookupByLibrary.simpleMessage("Asla"), + "livePhotos": MessageLookupByLibrary.simpleMessage("Canlı Fotoğraf"), + "loadMessage1": MessageLookupByLibrary.simpleMessage( + "Aboneliğinizi ailenizle paylaşabilirsiniz"), + "loadMessage2": MessageLookupByLibrary.simpleMessage( + "Şu ana kadar 30 milyondan fazla anıyı koruduk"), + "loadMessage3": MessageLookupByLibrary.simpleMessage( + "Verilerinizin 3 kopyasını saklıyoruz, biri yer altı serpinti sığınağında"), + "loadMessage4": MessageLookupByLibrary.simpleMessage( + "Tüm uygulamalarımız açık kaynaktır"), + "loadMessage5": MessageLookupByLibrary.simpleMessage( + "Kaynak kodumuz ve şifrelememiz harici olarak denetlenmiştir"), + "loadMessage6": MessageLookupByLibrary.simpleMessage( + "Albümlerinizin bağlantılarını sevdiklerinizle paylaşabilirsiniz"), + "loadMessage7": MessageLookupByLibrary.simpleMessage( + "Mobil uygulamalarımız, tıkladığınız yeni fotoğrafları şifrelemek ve yedeklemek için arka planda çalışır"), + "loadMessage8": MessageLookupByLibrary.simpleMessage( + "web.ente.io\'nun mükemmel bir yükleyicisi var"), + "loadMessage9": MessageLookupByLibrary.simpleMessage( + "Verilerinizi güvenli bir şekilde şifrelemek için Xchacha20Poly1305 kullanıyoruz"), + "loadingExifData": + MessageLookupByLibrary.simpleMessage("EXIF verileri yükleniyor..."), + "loadingGallery": + MessageLookupByLibrary.simpleMessage("Galeri yükleniyor..."), + "loadingMessage": MessageLookupByLibrary.simpleMessage( + "Fotoğraflarınız yükleniyor..."), + "loadingModel": + MessageLookupByLibrary.simpleMessage("Modeller indiriliyor..."), + "localGallery": MessageLookupByLibrary.simpleMessage("Yerel galeri"), + "location": MessageLookupByLibrary.simpleMessage("Konum"), + "locationName": MessageLookupByLibrary.simpleMessage("Konum Adı"), + "locationTagFeatureDescription": MessageLookupByLibrary.simpleMessage( + "Bir fotoğrafın belli bir yarıçapında çekilen fotoğrafları gruplandırın"), + "locations": MessageLookupByLibrary.simpleMessage("Konum"), + "lockButtonLabel": MessageLookupByLibrary.simpleMessage("Kilit"), + "lockScreenEnablePreSteps": MessageLookupByLibrary.simpleMessage( + "Kilit ekranını aktif etmek için lütfen cihazın ayarlarından şifreyi ya da ekran kilidini ayarlayın."), + "lockscreen": MessageLookupByLibrary.simpleMessage("Kilit ekranı"), + "logInLabel": MessageLookupByLibrary.simpleMessage("Giriş yap"), + "loggingOut": + MessageLookupByLibrary.simpleMessage("Çıkış yapılıyor..."), + "loginSessionExpired": + MessageLookupByLibrary.simpleMessage("Session expired"), + "loginSessionExpiredDetails": MessageLookupByLibrary.simpleMessage( + "Your session has expired. Please login again."), + "loginTerms": MessageLookupByLibrary.simpleMessage( + "\"Giriş yap\" düğmesine tıklayarak, Hizmet Şartları\'nı ve Gizlilik Politikası\'nı kabul ediyorum"), + "logout": MessageLookupByLibrary.simpleMessage("Çıkış yap"), + "logsDialogBody": MessageLookupByLibrary.simpleMessage( + "Bu, sorununuzu gidermemize yardımcı olmak için günlükleri gönderecektir. Belirli dosyalarla ilgili sorunların izlenmesine yardımcı olmak için dosya adlarının ekleneceğini lütfen unutmayın."), + "longPressAnEmailToVerifyEndToEndEncryption": + MessageLookupByLibrary.simpleMessage( + "Uçtan uca şifrelemeyi doğrulamak için bir e-postaya uzun basın."), + "longpressOnAnItemToViewInFullscreen": + MessageLookupByLibrary.simpleMessage( + "Tam ekranda görüntülemek için bir öğeye uzun basın"), + "lostDevice": + MessageLookupByLibrary.simpleMessage("Cihazı kayıp mı ettiniz?"), + "machineLearning": + MessageLookupByLibrary.simpleMessage("Makine öğrenimi"), + "magicSearch": MessageLookupByLibrary.simpleMessage("Sihirli arama"), + "manage": MessageLookupByLibrary.simpleMessage("Yönet"), + "manageDeviceStorage": + MessageLookupByLibrary.simpleMessage("Cihaz depolamasını yönet"), + "manageFamily": MessageLookupByLibrary.simpleMessage("Aileyi yönet"), + "manageLink": MessageLookupByLibrary.simpleMessage("Linki yönet"), + "manageParticipants": MessageLookupByLibrary.simpleMessage("Yönet"), + "manageSubscription": + MessageLookupByLibrary.simpleMessage("Abonelikleri yönet"), + "manualPairDesc": MessageLookupByLibrary.simpleMessage( + "Pair with PIN works with any screen you wish to view your album on."), + "map": MessageLookupByLibrary.simpleMessage("Harita"), + "maps": MessageLookupByLibrary.simpleMessage("Haritalar"), + "mastodon": MessageLookupByLibrary.simpleMessage("Mastodon"), + "matrix": MessageLookupByLibrary.simpleMessage("Matrix"), + "memoryCount": m34, + "merchandise": MessageLookupByLibrary.simpleMessage("Ürünler"), + "mlIndexingDescription": MessageLookupByLibrary.simpleMessage( + "Please note that machine learning will result in a higher bandwidth and battery usage until all items are indexed."), + "mobileWebDesktop": + MessageLookupByLibrary.simpleMessage("Mobil, Web, Masaüstü"), + "moderateStrength": MessageLookupByLibrary.simpleMessage("Ilımlı"), + "modifyYourQueryOrTrySearchingFor": + MessageLookupByLibrary.simpleMessage( + "Sorgunuzu değiştirin veya aramayı deneyin"), + "moments": MessageLookupByLibrary.simpleMessage("Anlar"), + "monthly": MessageLookupByLibrary.simpleMessage("Aylık"), + "moveItem": m35, + "moveToAlbum": MessageLookupByLibrary.simpleMessage("Albüme taşı"), + "moveToHiddenAlbum": + MessageLookupByLibrary.simpleMessage("Gizli albüme ekle"), + "movedSuccessfullyTo": m36, + "movedToTrash": + MessageLookupByLibrary.simpleMessage("Cöp kutusuna taşı"), + "movingFilesToAlbum": MessageLookupByLibrary.simpleMessage( + "Dosyalar albüme taşınıyor..."), + "name": MessageLookupByLibrary.simpleMessage("İsim"), + "networkConnectionRefusedErr": MessageLookupByLibrary.simpleMessage( + "Ente\'ye bağlanılamıyor. Lütfen bir süre sonra tekrar deneyin. Hata devam ederse lütfen desteğe başvurun."), + "networkHostLookUpErr": MessageLookupByLibrary.simpleMessage( + "Ente\'ye bağlanılamıyor. Lütfen ağ ayarlarınızı kontrol edin ve hata devam ederse destek ekibiyle iletişime geçin."), + "never": MessageLookupByLibrary.simpleMessage("Asla"), + "newAlbum": MessageLookupByLibrary.simpleMessage("Yeni albüm"), + "newToEnte": MessageLookupByLibrary.simpleMessage("New to Ente"), + "newest": MessageLookupByLibrary.simpleMessage("En yeni"), + "next": MessageLookupByLibrary.simpleMessage("Next"), + "no": MessageLookupByLibrary.simpleMessage("Hayır"), + "noAlbumsSharedByYouYet": MessageLookupByLibrary.simpleMessage( + "Henüz paylaştığınız albüm yok"), + "noDeviceFound": + MessageLookupByLibrary.simpleMessage("No device found"), + "noDeviceLimit": MessageLookupByLibrary.simpleMessage("Yok"), + "noDeviceThatCanBeDeleted": MessageLookupByLibrary.simpleMessage( + "Bu cihazda silinebilecek hiçbir dosyanız yok"), + "noDuplicates": + MessageLookupByLibrary.simpleMessage("Yinelenenleri kaldır"), + "noExifData": MessageLookupByLibrary.simpleMessage("EXIF verisi yok"), + "noHiddenPhotosOrVideos": MessageLookupByLibrary.simpleMessage( + "Gizli fotoğraf veya video yok"), + "noImagesWithLocation": + MessageLookupByLibrary.simpleMessage("Konum içeren resim yok"), + "noInternetConnection": + MessageLookupByLibrary.simpleMessage("İnternet bağlantısı yok"), + "noPhotosAreBeingBackedUpRightNow": + MessageLookupByLibrary.simpleMessage( + "Şu anda hiçbir fotoğraf yedeklenmiyor"), + "noPhotosFoundHere": + MessageLookupByLibrary.simpleMessage("Burada fotoğraf bulunamadı"), + "noRecoveryKey": + MessageLookupByLibrary.simpleMessage("Kurtarma kodunuz yok mu?"), + "noRecoveryKeyNoDecryption": MessageLookupByLibrary.simpleMessage( + "Uçtan uca şifreleme protokolümüzün doğası gereği, verileriniz şifreniz veya kurtarma anahtarınız olmadan çözülemez"), + "noResults": MessageLookupByLibrary.simpleMessage("Sonuç bulunamadı"), + "noResultsFound": + MessageLookupByLibrary.simpleMessage("Hiçbir sonuç bulunamadı"), + "noSystemLockFound": + MessageLookupByLibrary.simpleMessage("No system lock found"), + "notPersonLabel": m37, + "nothingSharedWithYouYet": MessageLookupByLibrary.simpleMessage( + "Henüz sizinle paylaşılan bir şey yok"), + "nothingToSeeHere": MessageLookupByLibrary.simpleMessage( + "Burada görülecek bir şey yok! 👀"), + "notifications": MessageLookupByLibrary.simpleMessage("Bildirimler"), + "ok": MessageLookupByLibrary.simpleMessage("Tamam"), + "onDevice": MessageLookupByLibrary.simpleMessage("Bu cihaz"), + "onEnte": MessageLookupByLibrary.simpleMessage( + "ente üzerinde"), + "oops": MessageLookupByLibrary.simpleMessage("Hay aksi"), + "oopsCouldNotSaveEdits": MessageLookupByLibrary.simpleMessage( + "Hata! Düzenlemeler kaydedilemedi"), + "oopsSomethingWentWrong": MessageLookupByLibrary.simpleMessage( + "Hoop, Birşeyler yanlış gitti"), + "openSettings": MessageLookupByLibrary.simpleMessage("Ayarları Açın"), + "openTheItem": MessageLookupByLibrary.simpleMessage("• Öğeyi açın"), + "openstreetmapContributors": MessageLookupByLibrary.simpleMessage( + "© OpenStreetMap katkıda bululanlar"), + "optionalAsShortAsYouLike": MessageLookupByLibrary.simpleMessage( + "İsteğe bağlı, istediğiniz kadar kısa..."), + "orPickAnExistingOne": + MessageLookupByLibrary.simpleMessage("Veya mevcut birini seçiniz"), + "pair": MessageLookupByLibrary.simpleMessage("Eşleştir"), + "pairWithPin": MessageLookupByLibrary.simpleMessage("Pair with PIN"), + "pairingComplete": + MessageLookupByLibrary.simpleMessage("Pairing complete"), + "passKeyPendingVerification": MessageLookupByLibrary.simpleMessage( + "Verification is still pending"), + "passkey": MessageLookupByLibrary.simpleMessage("Parola Anahtarı"), + "passkeyAuthTitle": + MessageLookupByLibrary.simpleMessage("Geçiş anahtarı doğrulaması"), + "password": MessageLookupByLibrary.simpleMessage("Şifre"), + "passwordChangedSuccessfully": MessageLookupByLibrary.simpleMessage( + "Şifreniz başarılı bir şekilde değiştirildi"), + "passwordLock": MessageLookupByLibrary.simpleMessage("Sifre kilidi"), + "passwordStrength": m38, + "passwordWarning": MessageLookupByLibrary.simpleMessage( + "Şifrelerinizi saklamıyoruz, bu yüzden unutursanız, verilerinizi deşifre edemeyiz"), + "paymentDetails": + MessageLookupByLibrary.simpleMessage("Ödeme detayları"), + "paymentFailed": + MessageLookupByLibrary.simpleMessage("Ödeme başarısız oldu"), + "paymentFailedMessage": MessageLookupByLibrary.simpleMessage( + "Maalesef ödemeniz başarısız oldu. Lütfen destekle iletişime geçin, size yardımcı olacağız!"), + "paymentFailedTalkToProvider": m39, + "pendingItems": MessageLookupByLibrary.simpleMessage("Bekleyen Öğeler"), + "pendingSync": + MessageLookupByLibrary.simpleMessage("Senkronizasyon bekleniyor"), + "people": MessageLookupByLibrary.simpleMessage("People"), + "peopleUsingYourCode": + MessageLookupByLibrary.simpleMessage("Kodunuzu kullananlar"), + "permDeleteWarning": MessageLookupByLibrary.simpleMessage( + "Çöp kutusundaki tüm öğeler kalıcı olarak silinecek\n\nBu işlem geri alınamaz"), + "permanentlyDelete": + MessageLookupByLibrary.simpleMessage("Kalıcı olarak sil"), + "permanentlyDeleteFromDevice": MessageLookupByLibrary.simpleMessage( + "Cihazdan kalıcı olarak silinsin mi?"), + "photoDescriptions": + MessageLookupByLibrary.simpleMessage("Fotoğraf Açıklaması"), + "photoGridSize": + MessageLookupByLibrary.simpleMessage("Fotoğraf ızgara boyutu"), + "photoSmallCase": MessageLookupByLibrary.simpleMessage("fotoğraf"), + "photos": MessageLookupByLibrary.simpleMessage("Fotoğraflar"), + "photosAddedByYouWillBeRemovedFromTheAlbum": + MessageLookupByLibrary.simpleMessage( + "Eklediğiniz fotoğraflar albümden kaldırılacak"), + "pickCenterPoint": + MessageLookupByLibrary.simpleMessage("Merkez noktasını seçin"), + "pinAlbum": MessageLookupByLibrary.simpleMessage("Albümü sabitle"), + "pinLock": MessageLookupByLibrary.simpleMessage("PIN lock"), + "playOnTv": MessageLookupByLibrary.simpleMessage("Albümü TV\'de oynat"), + "playStoreFreeTrialValidTill": m40, + "playstoreSubscription": + MessageLookupByLibrary.simpleMessage("PlayStore aboneliği"), + "pleaseCheckYourInternetConnectionAndTryAgain": + MessageLookupByLibrary.simpleMessage( + "Lütfen internet bağlantınızı kontrol edin ve yeniden deneyin."), + "pleaseContactSupportAndWeWillBeHappyToHelp": + MessageLookupByLibrary.simpleMessage( + "Lütfen support@ente.io ile iletişime geçin; size yardımcı olmaktan memnuniyet duyarız!"), + "pleaseContactSupportIfTheProblemPersists": + MessageLookupByLibrary.simpleMessage( + "Bu hata devam ederse lütfen desteğe başvurun"), + "pleaseEmailUsAt": m41, + "pleaseGrantPermissions": + MessageLookupByLibrary.simpleMessage("Lütfen izin ver"), + "pleaseLoginAgain": + MessageLookupByLibrary.simpleMessage("Lütfen tekrar giriş yapın"), + "pleaseSendTheLogsTo": m42, + "pleaseTryAgain": + MessageLookupByLibrary.simpleMessage("Lütfen tekrar deneyiniz"), + "pleaseVerifyTheCodeYouHaveEntered": + MessageLookupByLibrary.simpleMessage( + "Lütfen girdiğiniz kodu doğrulayın"), + "pleaseWait": + MessageLookupByLibrary.simpleMessage("Lütfen bekleyiniz..."), + "pleaseWaitDeletingAlbum": MessageLookupByLibrary.simpleMessage( + "Lütfen bekleyin, albüm siliniyor"), + "pleaseWaitForSometimeBeforeRetrying": + MessageLookupByLibrary.simpleMessage( + "Tekrar denemeden önce lütfen bir süre bekleyin"), + "preparingLogs": + MessageLookupByLibrary.simpleMessage("Günlük hazırlanıyor..."), + "preserveMore": + MessageLookupByLibrary.simpleMessage("Daha fazlasını koruyun"), + "pressAndHoldToPlayVideo": MessageLookupByLibrary.simpleMessage( + "Videoları yönetmek için basılı tutun"), + "pressAndHoldToPlayVideoDetailed": MessageLookupByLibrary.simpleMessage( + "Videoyu oynatmak için resmi basılı tutun"), + "privacy": MessageLookupByLibrary.simpleMessage("Gizlilik"), + "privacyPolicyTitle": + MessageLookupByLibrary.simpleMessage("Mahremiyet Politikası"), + "privateBackups": + MessageLookupByLibrary.simpleMessage("Özel yedeklemeler"), + "privateSharing": MessageLookupByLibrary.simpleMessage("Özel paylaşım"), + "publicLinkCreated": MessageLookupByLibrary.simpleMessage( + "Herkese açık link oluşturuldu"), + "publicLinkEnabled": MessageLookupByLibrary.simpleMessage( + "Herkese açık bağlantı aktive edildi"), + "quickLinks": MessageLookupByLibrary.simpleMessage("Hızlı Erişim"), + "radius": MessageLookupByLibrary.simpleMessage("Yarıçap"), + "raiseTicket": MessageLookupByLibrary.simpleMessage("Bileti artır"), + "rateTheApp": + MessageLookupByLibrary.simpleMessage("Uygulamaya puan verin"), + "rateUs": MessageLookupByLibrary.simpleMessage("Bizi değerlendirin"), + "rateUsOnStore": m43, + "recover": MessageLookupByLibrary.simpleMessage("Kurtarma"), + "recoverAccount": MessageLookupByLibrary.simpleMessage("Hesabı kurtar"), + "recoverButton": MessageLookupByLibrary.simpleMessage("Kurtar"), + "recoveryKey": + MessageLookupByLibrary.simpleMessage("Kurtarma anahtarı"), + "recoveryKeyCopiedToClipboard": MessageLookupByLibrary.simpleMessage( + "Kurtarma anahtarınız panoya kopyalandı"), + "recoveryKeyOnForgotPassword": MessageLookupByLibrary.simpleMessage( + "Şifrenizi unutursanız, verilerinizi kurtarmanın tek yolu bu anahtar olacaktır."), + "recoveryKeySaveDescription": MessageLookupByLibrary.simpleMessage( + "Bu anahtarı saklamıyoruz, lütfen bu 24 kelime anahtarı güvenli bir yerde saklayın."), + "recoveryKeySuccessBody": MessageLookupByLibrary.simpleMessage( + "Harika! Kurtarma anahtarınız geçerlidir. Doğrulama için teşekkür ederim.\n\nLütfen kurtarma anahtarınızı güvenli bir şekilde yedeklediğinizden emin olun."), + "recoveryKeyVerified": + MessageLookupByLibrary.simpleMessage("Kurtarma kodu doğrulandı"), + "recoveryKeyVerifyReason": MessageLookupByLibrary.simpleMessage( + "Eğer şifrenizi unutursanız, fotoğraflarınızı kurtarmanın tek yolu kurtarma anahtarınızdır. Kurtarma anahtarınızı Ayarlar > Güvenlik bölümünde bulabilirsiniz.\n\nLütfen kurtarma anahtarınızı buraya girerek doğru bir şekilde kaydettiğinizi doğrulayın."), + "recoverySuccessful": + MessageLookupByLibrary.simpleMessage("Kurtarma başarılı!"), + "recreatePasswordBody": MessageLookupByLibrary.simpleMessage( + "Cihazınız, şifrenizi doğrulamak için yeterli güce sahip değil, ancak tüm cihazlarda çalışacak şekilde yeniden oluşturabiliriz.\n\nLütfen kurtarma anahtarınızı kullanarak giriş yapın ve şifrenizi yeniden oluşturun (istediğiniz takdirde aynı şifreyi tekrar kullanabilirsiniz)."), + "recreatePasswordTitle": MessageLookupByLibrary.simpleMessage( + "Sifrenizi tekrardan oluşturun"), + "reddit": MessageLookupByLibrary.simpleMessage("Reddit"), + "reenterPassword": + MessageLookupByLibrary.simpleMessage("Re-enter password"), + "reenterPin": MessageLookupByLibrary.simpleMessage("Re-enter PIN"), + "referFriendsAnd2xYourPlan": MessageLookupByLibrary.simpleMessage( + "Arkadaşlarınıza önerin ve planınızı 2 katına çıkarın"), + "referralStep1": MessageLookupByLibrary.simpleMessage( + "1. Bu kodu arkadaşlarınıza verin"), + "referralStep2": MessageLookupByLibrary.simpleMessage( + "2. Ücretli bir plan için kaydolsunlar"), + "referralStep3": m44, + "referrals": MessageLookupByLibrary.simpleMessage("Referanslar"), + "referralsAreCurrentlyPaused": MessageLookupByLibrary.simpleMessage( + "Davetler şu anda durmuş durumda"), + "remindToEmptyDeviceTrash": MessageLookupByLibrary.simpleMessage( + "Ayrıca boşalan alanı talep etmek için \"Ayarlar\" -> \"Depolama\" bölümünden \"Son Silinenler \"i boşaltın"), + "remindToEmptyEnteTrash": MessageLookupByLibrary.simpleMessage( + "Ayrıca boşalan alana sahip olmak için \"Çöp Kutunuzu\" boşaltın"), + "remoteImages": + MessageLookupByLibrary.simpleMessage("Uzaktan Görüntüler"), + "remoteThumbnails": + MessageLookupByLibrary.simpleMessage("Uzak Küçük Resim"), + "remoteVideos": MessageLookupByLibrary.simpleMessage("Uzak videolar"), + "remove": MessageLookupByLibrary.simpleMessage("Kaldır"), + "removeDuplicates": + MessageLookupByLibrary.simpleMessage("Yinelenenleri kaldır"), + "removeDuplicatesDesc": MessageLookupByLibrary.simpleMessage( + "Review and remove files that are exact duplicates."), + "removeFromAlbum": + MessageLookupByLibrary.simpleMessage("Albümden çıkar"), + "removeFromAlbumTitle": + MessageLookupByLibrary.simpleMessage("Albümden çıkarılsın mı?"), + "removeFromFavorite": + MessageLookupByLibrary.simpleMessage("Favorilerimden kaldır"), + "removeLink": MessageLookupByLibrary.simpleMessage("Linki kaldır"), + "removeParticipant": + MessageLookupByLibrary.simpleMessage("Katılımcıyı kaldır"), + "removeParticipantBody": m45, + "removePersonLabel": + MessageLookupByLibrary.simpleMessage("Remove person label"), + "removePublicLink": + MessageLookupByLibrary.simpleMessage("Herkese açık link oluştur"), + "removeShareItemsWarning": MessageLookupByLibrary.simpleMessage( + "Kaldırdığınız öğelerden bazıları başkaları tarafından eklenmiştir ve bunlara erişiminizi kaybedeceksiniz"), + "removeWithQuestionMark": + MessageLookupByLibrary.simpleMessage("Kaldır?"), + "removingFromFavorites": + MessageLookupByLibrary.simpleMessage("Favorilerimden kaldır..."), + "rename": MessageLookupByLibrary.simpleMessage("Yeniden adlandır"), + "renameAlbum": + MessageLookupByLibrary.simpleMessage("Albümü yeniden adlandır"), + "renameFile": + MessageLookupByLibrary.simpleMessage("Dosyayı yeniden adlandır"), + "renewSubscription": + MessageLookupByLibrary.simpleMessage("Abonelik yenileme"), + "renewsOn": m46, + "reportABug": MessageLookupByLibrary.simpleMessage("Hatayı bildir"), + "reportBug": MessageLookupByLibrary.simpleMessage("Hata bildir"), + "resendEmail": + MessageLookupByLibrary.simpleMessage("E-postayı yeniden gönder"), + "resetIgnoredFiles": MessageLookupByLibrary.simpleMessage( + "Yok sayılan dosyaları sıfırla"), + "resetPasswordTitle": + MessageLookupByLibrary.simpleMessage("Parolanızı sıfırlayın"), + "resetToDefault": + MessageLookupByLibrary.simpleMessage("Varsayılana sıfırla"), + "restore": MessageLookupByLibrary.simpleMessage("Yenile"), + "restoreToAlbum": MessageLookupByLibrary.simpleMessage("Albümü yenile"), + "restoringFiles": + MessageLookupByLibrary.simpleMessage("Dosyalar geri yükleniyor..."), + "retry": MessageLookupByLibrary.simpleMessage("Tekrar dene"), + "reviewDeduplicateItems": MessageLookupByLibrary.simpleMessage( + "Lütfen kopya olduğunu düşündüğünüz öğeleri inceleyin ve silin."), + "reviewSuggestions": + MessageLookupByLibrary.simpleMessage("Review suggestions"), + "right": MessageLookupByLibrary.simpleMessage("Right"), + "rotate": MessageLookupByLibrary.simpleMessage("Rotate"), + "rotateLeft": MessageLookupByLibrary.simpleMessage("Sola döndür"), + "rotateRight": MessageLookupByLibrary.simpleMessage("Sağa döndür"), + "safelyStored": + MessageLookupByLibrary.simpleMessage("Güvenle saklanır"), + "save": MessageLookupByLibrary.simpleMessage("Kaydet"), + "saveCollage": MessageLookupByLibrary.simpleMessage("Kolajı kaydet"), + "saveCopy": MessageLookupByLibrary.simpleMessage("Kopyasını kaydet"), + "saveKey": MessageLookupByLibrary.simpleMessage("Anahtarı kaydet"), + "saveYourRecoveryKeyIfYouHaventAlready": + MessageLookupByLibrary.simpleMessage( + "Henüz yapmadıysanız kurtarma anahtarınızı kaydetmeyi unutmayın"), + "saving": MessageLookupByLibrary.simpleMessage("Kaydediliyor..."), + "savingEdits": MessageLookupByLibrary.simpleMessage("Saving edits..."), + "scanCode": MessageLookupByLibrary.simpleMessage("Kodu tarayın"), + "scanThisBarcodeWithnyourAuthenticatorApp": + MessageLookupByLibrary.simpleMessage( + "Kimlik doğrulama uygulamanız ile kodu tarayın"), + "search": MessageLookupByLibrary.simpleMessage("Search"), + "searchAlbumsEmptySection": + MessageLookupByLibrary.simpleMessage("Albümler"), + "searchByAlbumNameHint": + MessageLookupByLibrary.simpleMessage("Albüm adı"), + "searchByExamples": MessageLookupByLibrary.simpleMessage( + "• Albüm adları (ör. \"Kamera\")\n• Dosya türleri (ör. \"Videolar\", \".gif\")\n• Yıllar ve aylar (ör. \"2022\", \"Ocak\")\n• Tatiller (ör. \"Noel\")\n• Fotoğraf açıklamaları (ör. \"#eğlence\")"), + "searchCaptionEmptySection": MessageLookupByLibrary.simpleMessage( + "Fotoğraf bilgilerini burada hızlı bir şekilde bulmak için \"#trip\" gibi açıklamalar ekleyin"), + "searchDatesEmptySection": MessageLookupByLibrary.simpleMessage( + "Tarihe, aya veya yıla göre arama yapın"), + "searchFaceEmptySection": MessageLookupByLibrary.simpleMessage( + "People will be shown here once indexing is done"), + "searchFileTypesAndNamesEmptySection": + MessageLookupByLibrary.simpleMessage("Dosya türleri ve adları"), + "searchHint1": + MessageLookupByLibrary.simpleMessage("Hızlı, cihaz üzerinde arama"), + "searchHint2": MessageLookupByLibrary.simpleMessage( + "Fotoğraf tarihleri, açıklamalar"), + "searchHint3": MessageLookupByLibrary.simpleMessage( + "Albümler, dosya adları ve türleri"), + "searchHint4": MessageLookupByLibrary.simpleMessage("Konum"), + "searchHint5": MessageLookupByLibrary.simpleMessage( + "Çok yakında: Yüzler ve sihirli arama ✨"), + "searchLocationEmptySection": MessageLookupByLibrary.simpleMessage( + "Bir fotoğrafın belli bir yarıçapında çekilen fotoğrafları gruplandırın"), + "searchPeopleEmptySection": MessageLookupByLibrary.simpleMessage( + "İnsanları davet ettiğinizde onların paylaştığı tüm fotoğrafları burada göreceksiniz"), + "searchResultCount": m47, + "security": MessageLookupByLibrary.simpleMessage("Güvenlik"), + "selectALocation": + MessageLookupByLibrary.simpleMessage("Bir konum seçin"), + "selectALocationFirst": + MessageLookupByLibrary.simpleMessage("Önce yeni yer seçin"), + "selectAlbum": MessageLookupByLibrary.simpleMessage("Albüm seçin"), + "selectAll": MessageLookupByLibrary.simpleMessage("Hepsini seç"), + "selectFoldersForBackup": MessageLookupByLibrary.simpleMessage( + "Yedekleme için klasörleri seçin"), + "selectItemsToAdd": + MessageLookupByLibrary.simpleMessage("Eklenecek eşyaları seçin"), + "selectLanguage": MessageLookupByLibrary.simpleMessage("Dil Seçin"), + "selectMorePhotos": + MessageLookupByLibrary.simpleMessage("Daha Fazla Fotoğraf Seç"), + "selectReason": + MessageLookupByLibrary.simpleMessage("Ayrılma nedeninizi seçin"), + "selectYourPlan": + MessageLookupByLibrary.simpleMessage("Planınızı seçin"), + "selectedFilesAreNotOnEnte": MessageLookupByLibrary.simpleMessage( + "Selected files are not on Ente"), + "selectedFoldersWillBeEncryptedAndBackedUp": + MessageLookupByLibrary.simpleMessage( + "Seçilen klasörler şifrelenecek ve yedeklenecektir"), + "selectedItemsWillBeDeletedFromAllAlbumsAndMoved": + MessageLookupByLibrary.simpleMessage( + "Seçilen öğeler tüm albümlerden silinecek ve çöp kutusuna taşınacak."), + "selectedPhotos": m48, + "selectedPhotosWithYours": m49, + "send": MessageLookupByLibrary.simpleMessage("Gönder"), + "sendEmail": MessageLookupByLibrary.simpleMessage("E-posta gönder"), + "sendInvite": MessageLookupByLibrary.simpleMessage("Davet kodu gönder"), + "sendLink": MessageLookupByLibrary.simpleMessage("Link gönder"), + "serverEndpoint": + MessageLookupByLibrary.simpleMessage("Sunucu uç noktası"), + "sessionExpired": + MessageLookupByLibrary.simpleMessage("Oturum süresi doldu"), + "setAPassword": MessageLookupByLibrary.simpleMessage("Şifre ayarla"), + "setAs": MessageLookupByLibrary.simpleMessage("Şu şekilde ayarla"), + "setCover": MessageLookupByLibrary.simpleMessage("Kapak Belirle"), + "setLabel": MessageLookupByLibrary.simpleMessage("Ayarla"), + "setNewPassword": + MessageLookupByLibrary.simpleMessage("Set new password"), + "setNewPin": MessageLookupByLibrary.simpleMessage("Set new PIN"), + "setPasswordTitle": + MessageLookupByLibrary.simpleMessage("Parola ayarlayın"), + "setRadius": MessageLookupByLibrary.simpleMessage("Yarıçapı ayarla"), + "setupComplete": + MessageLookupByLibrary.simpleMessage("Ayarlama işlemi başarılı"), + "share": MessageLookupByLibrary.simpleMessage("Paylaş"), + "shareALink": MessageLookupByLibrary.simpleMessage("Linki paylaş"), + "shareAlbumHint": MessageLookupByLibrary.simpleMessage( + "Bir albüm açın ve paylaşmak için sağ üstteki paylaş düğmesine dokunun."), + "shareAnAlbumNow": + MessageLookupByLibrary.simpleMessage("Şimdi bir albüm paylaşın"), + "shareLink": MessageLookupByLibrary.simpleMessage("Linki paylaş"), + "shareMyVerificationID": m50, + "shareOnlyWithThePeopleYouWant": MessageLookupByLibrary.simpleMessage( + "Yalnızca istediğiniz kişilerle paylaşın"), + "shareTextConfirmOthersVerificationID": m51, + "shareTextRecommendUsingEnte": MessageLookupByLibrary.simpleMessage( + "Download Ente so we can easily share original quality photos and videos\n\nhttps://ente.io"), + "shareTextReferralCode": m52, + "shareWithNonenteUsers": + MessageLookupByLibrary.simpleMessage("Share with non-Ente users"), + "shareWithPeopleSectionTitle": m53, + "shareYourFirstAlbum": + MessageLookupByLibrary.simpleMessage("İlk albümünüzü paylaşın"), + "sharedAlbumSectionDescription": MessageLookupByLibrary.simpleMessage( + "Create shared and collaborative albums with other Ente users, including users on free plans."), + "sharedByMe": + MessageLookupByLibrary.simpleMessage("Benim paylaştıklarım"), + "sharedByYou": MessageLookupByLibrary.simpleMessage("Paylaştıklarınız"), + "sharedPhotoNotifications": MessageLookupByLibrary.simpleMessage( + "Paylaşılan fotoğrafları ekle"), + "sharedPhotoNotificationsExplanation": MessageLookupByLibrary.simpleMessage( + "Birisi sizin de parçası olduğunuz paylaşılan bir albüme fotoğraf eklediğinde bildirim alın"), + "sharedWith": m54, + "sharedWithMe": + MessageLookupByLibrary.simpleMessage("Benimle paylaşılan"), + "sharedWithYou": + MessageLookupByLibrary.simpleMessage("Sizinle paylaşıldı"), + "sharing": MessageLookupByLibrary.simpleMessage("Paylaşılıyor..."), + "showMemories": MessageLookupByLibrary.simpleMessage("Anıları göster"), + "signOutFromOtherDevices": + MessageLookupByLibrary.simpleMessage("Diğer cihazlardan çıkış yap"), + "signOutOtherBody": MessageLookupByLibrary.simpleMessage( + "Eğer başka birisinin parolanızı bildiğini düşünüyorsanız, diğer tüm cihazları hesabınızdan çıkışa zorlayabilirsiniz."), + "signOutOtherDevices": + MessageLookupByLibrary.simpleMessage("Diğer cihazlardan çıkış yap"), + "signUpTerms": MessageLookupByLibrary.simpleMessage( + "Hizmet Şartları\'nı ve Gizlilik Politikası\'nı kabul ediyorum"), + "singleFileDeleteFromDevice": m55, + "singleFileDeleteHighlight": + MessageLookupByLibrary.simpleMessage("Tüm albümlerden silinecek."), + "singleFileInBothLocalAndRemote": m56, + "singleFileInRemoteOnly": m57, + "skip": MessageLookupByLibrary.simpleMessage("Geç"), + "social": MessageLookupByLibrary.simpleMessage("Sosyal Medya"), + "someItemsAreInBothEnteAndYourDevice": + MessageLookupByLibrary.simpleMessage( + "Some items are in both Ente and your device."), + "someOfTheFilesYouAreTryingToDeleteAre": + MessageLookupByLibrary.simpleMessage( + "Silmeye çalıştığınız dosyalardan bazıları yalnızca cihazınızda mevcuttur ve silindiği takdirde kurtarılamaz"), + "someoneSharingAlbumsWithYouShouldSeeTheSameId": + MessageLookupByLibrary.simpleMessage( + "Size albümleri paylaşan biri, kendi cihazında aynı kimliği görmelidir."), + "somethingWentWrong": + MessageLookupByLibrary.simpleMessage("Bazı şeyler yanlış gitti"), + "somethingWentWrongPleaseTryAgain": + MessageLookupByLibrary.simpleMessage( + "Bir şeyler ters gitti, lütfen tekrar deneyin"), + "sorry": MessageLookupByLibrary.simpleMessage("Üzgünüz"), + "sorryCouldNotAddToFavorites": MessageLookupByLibrary.simpleMessage( + "Üzgünüm, favorilere ekleyemedim!"), + "sorryCouldNotRemoveFromFavorites": + MessageLookupByLibrary.simpleMessage( + "Üzgünüm, favorilere ekleyemedim!"), + "sorryTheCodeYouveEnteredIsIncorrect": + MessageLookupByLibrary.simpleMessage( + "Üzgünüz, girdiğiniz kod yanlış"), + "sorryWeCouldNotGenerateSecureKeysOnThisDevicennplease": + MessageLookupByLibrary.simpleMessage( + "Üzgünüm, bu cihazda güvenli anahtarlarını oluşturamadık.\n\nLütfen başka bir cihazdan giriş yapmayı deneyiniz."), + "sortAlbumsBy": MessageLookupByLibrary.simpleMessage("Sırala"), + "sortNewestFirst": + MessageLookupByLibrary.simpleMessage("Yeniden eskiye"), + "sortOldestFirst": MessageLookupByLibrary.simpleMessage("Önce en eski"), + "sparkleSuccess": MessageLookupByLibrary.simpleMessage("✨ Başarılı"), + "startBackup": + MessageLookupByLibrary.simpleMessage("Yedeklemeyi başlat"), + "status": MessageLookupByLibrary.simpleMessage("Durum"), + "stopCastingBody": MessageLookupByLibrary.simpleMessage( + "Do you want to stop casting?"), + "stopCastingTitle": + MessageLookupByLibrary.simpleMessage("Stop casting"), + "storage": MessageLookupByLibrary.simpleMessage("Depolama"), + "storageBreakupFamily": MessageLookupByLibrary.simpleMessage("Aile"), + "storageBreakupYou": MessageLookupByLibrary.simpleMessage("Sen"), + "storageInGB": m58, + "storageLimitExceeded": + MessageLookupByLibrary.simpleMessage("Depolama sınırı aşıldı"), + "storageUsageInfo": m59, + "strongStrength": MessageLookupByLibrary.simpleMessage("Güçlü"), + "subAlreadyLinkedErrMessage": m60, + "subWillBeCancelledOn": m61, + "subscribe": MessageLookupByLibrary.simpleMessage("Abone ol"), + "subscribeToEnableSharing": MessageLookupByLibrary.simpleMessage( + "Aboneliğinizin süresi dolmuş gibi görünüyor. Paylaşımı etkinleştirmek için lütfen abone olun."), + "subscription": MessageLookupByLibrary.simpleMessage("Abonelik"), + "success": MessageLookupByLibrary.simpleMessage("Başarılı"), + "successfullyArchived": + MessageLookupByLibrary.simpleMessage("Başarıyla arşivlendi"), + "successfullyHid": + MessageLookupByLibrary.simpleMessage("Başarıyla saklandı"), + "successfullyUnarchived": MessageLookupByLibrary.simpleMessage( + "Başarıyla arşivden çıkarıldı"), + "successfullyUnhid": MessageLookupByLibrary.simpleMessage( + "Başarıyla arşivden çıkarıldı"), + "suggestFeatures": + MessageLookupByLibrary.simpleMessage("Özellik önerin"), + "support": MessageLookupByLibrary.simpleMessage("Destek"), + "syncProgress": m62, + "syncStopped": + MessageLookupByLibrary.simpleMessage("Senkronizasyon durduruldu"), + "syncing": MessageLookupByLibrary.simpleMessage("Eşitleniyor..."), + "systemTheme": MessageLookupByLibrary.simpleMessage("Sistem"), + "tapToCopy": + MessageLookupByLibrary.simpleMessage("kopyalamak için dokunun"), + "tapToEnterCode": + MessageLookupByLibrary.simpleMessage("Kodu girmek icin tıklayın"), + "tapToUnlock": MessageLookupByLibrary.simpleMessage("Tap to unlock"), + "tempErrorContactSupportIfPersists": MessageLookupByLibrary.simpleMessage( + "Bir şeyler ters gitmiş gibi görünüyor. Lütfen bir süre sonra tekrar deneyin. Hata devam ederse, lütfen destek ekibimizle iletişime geçin."), + "terminate": MessageLookupByLibrary.simpleMessage("Sonlandır"), + "terminateSession": + MessageLookupByLibrary.simpleMessage("Oturumu sonlandır?"), + "terms": MessageLookupByLibrary.simpleMessage("Şartlar"), + "termsOfServicesTitle": MessageLookupByLibrary.simpleMessage("Şartlar"), + "thankYou": MessageLookupByLibrary.simpleMessage("Teşekkürler"), + "thankYouForSubscribing": MessageLookupByLibrary.simpleMessage( + "Abone olduğunuz için teşekkürler!"), + "theDownloadCouldNotBeCompleted": MessageLookupByLibrary.simpleMessage( + "İndirme işlemi tamamlanamadı"), + "theRecoveryKeyYouEnteredIsIncorrect": + MessageLookupByLibrary.simpleMessage( + "Girdiğiniz kurtarma kodu yanlış"), + "theme": MessageLookupByLibrary.simpleMessage("Tema"), + "theseItemsWillBeDeletedFromYourDevice": + MessageLookupByLibrary.simpleMessage( + "Bu öğeler cihazınızdan silinecektir."), + "theyAlsoGetXGb": m63, + "theyWillBeDeletedFromAllAlbums": + MessageLookupByLibrary.simpleMessage("Tüm albümlerden silinecek."), + "thisActionCannotBeUndone": + MessageLookupByLibrary.simpleMessage("Bu eylem geri alınamaz"), + "thisAlbumAlreadyHDACollaborativeLink": + MessageLookupByLibrary.simpleMessage( + "Bu albümde zaten bir ortak çalışma bağlantısı var"), + "thisCanBeUsedToRecoverYourAccountIfYou": + MessageLookupByLibrary.simpleMessage( + "Bu, iki faktörünüzü kaybederseniz hesabınızı kurtarmak için kullanılabilir"), + "thisDevice": MessageLookupByLibrary.simpleMessage("Bu cihaz"), + "thisEmailIsAlreadyInUse": MessageLookupByLibrary.simpleMessage( + "Bu e-posta zaten kullanılıyor"), + "thisImageHasNoExifData": + MessageLookupByLibrary.simpleMessage("Bu görselde exif verisi yok"), + "thisIsPersonVerificationId": m64, + "thisIsYourVerificationId": + MessageLookupByLibrary.simpleMessage("Doğrulama kimliğiniz"), + "thisWillLogYouOutOfTheFollowingDevice": + MessageLookupByLibrary.simpleMessage( + "Bu, sizi aşağıdaki cihazdan çıkış yapacak:"), + "thisWillLogYouOutOfThisDevice": MessageLookupByLibrary.simpleMessage( + "Bu cihazdaki oturumunuz kapatılacak!"), + "toEnableAppLockPleaseSetupDevicePasscodeOrScreen": + MessageLookupByLibrary.simpleMessage( + "To enable app lock, please setup device passcode or screen lock in your system settings."), + "toHideAPhotoOrVideo": MessageLookupByLibrary.simpleMessage( + "Bir fotoğrafı veya videoyu gizlemek için"), + "toResetVerifyEmail": MessageLookupByLibrary.simpleMessage( + "Şifrenizi sıfılamak için lütfen e-postanızı girin."), + "todaysLogs": + MessageLookupByLibrary.simpleMessage("Bugünün günlükleri"), + "tooManyIncorrectAttempts": + MessageLookupByLibrary.simpleMessage("Too many incorrect attempts"), + "total": MessageLookupByLibrary.simpleMessage("total"), + "totalSize": MessageLookupByLibrary.simpleMessage("Toplam boyut"), + "trash": MessageLookupByLibrary.simpleMessage("Cöp kutusu"), + "trashDaysLeft": m65, + "trim": MessageLookupByLibrary.simpleMessage("Trim"), + "tryAgain": MessageLookupByLibrary.simpleMessage("Tekrar deneyiniz"), + "turnOnBackupForAutoUpload": MessageLookupByLibrary.simpleMessage( + "Turn on backup to automatically upload files added to this device folder to Ente."), + "twitter": MessageLookupByLibrary.simpleMessage("Twitter"), + "twoMonthsFreeOnYearlyPlans": MessageLookupByLibrary.simpleMessage( + "Yıllık planlarda 2 ay ücretsiz"), + "twofactor": MessageLookupByLibrary.simpleMessage("İki faktör"), + "twofactorAuthenticationHasBeenDisabled": + MessageLookupByLibrary.simpleMessage( + "İki faktörlü kimlik doğrulama devre dışı"), + "twofactorAuthenticationPageTitle": + MessageLookupByLibrary.simpleMessage("İki faktörlü doğrulama"), + "twofactorAuthenticationSuccessfullyReset": + MessageLookupByLibrary.simpleMessage( + "İki faktörlü kimlik doğrulama başarıyla sıfırlandı"), + "twofactorSetup": + MessageLookupByLibrary.simpleMessage("Cift faktör ayarı"), + "unarchive": MessageLookupByLibrary.simpleMessage("Arşivden cıkar"), + "unarchiveAlbum": + MessageLookupByLibrary.simpleMessage("Arşivden Çıkar"), + "unarchiving": + MessageLookupByLibrary.simpleMessage("Arşivden çıkarılıyor..."), + "uncategorized": MessageLookupByLibrary.simpleMessage("Kategorisiz"), + "unhide": MessageLookupByLibrary.simpleMessage("Gizleme"), + "unhideToAlbum": MessageLookupByLibrary.simpleMessage("Albümü gizleme"), + "unhiding": MessageLookupByLibrary.simpleMessage("Gösteriliyor..."), + "unhidingFilesToAlbum": MessageLookupByLibrary.simpleMessage( + "Albümdeki dosyalar gösteriliyor"), + "unlock": MessageLookupByLibrary.simpleMessage("Kilidi aç"), + "unpinAlbum": MessageLookupByLibrary.simpleMessage( + "Albümün sabitlemesini kaldır"), + "unselectAll": + MessageLookupByLibrary.simpleMessage("Tümünün seçimini kaldır"), + "update": MessageLookupByLibrary.simpleMessage("Güncelle"), + "updateAvailable": + MessageLookupByLibrary.simpleMessage("Güncelleme mevcut"), + "updatingFolderSelection": MessageLookupByLibrary.simpleMessage( + "Klasör seçimi güncelleniyor..."), + "upgrade": MessageLookupByLibrary.simpleMessage("Yükselt"), + "uploadingFilesToAlbum": MessageLookupByLibrary.simpleMessage( + "Dosyalar albüme taşınıyor..."), + "upto50OffUntil4thDec": MessageLookupByLibrary.simpleMessage( + "4 Aralık\'a kadar %50\'ye varan indirim."), + "usableReferralStorageInfo": MessageLookupByLibrary.simpleMessage( + "Kullanılabilir depolama alanı mevcut planınızla sınırlıdır. Talep edilen fazla depolama alanı, planınızı yükselttiğinizde otomatik olarak kullanılabilir hale gelecektir."), + "useAsCover": MessageLookupByLibrary.simpleMessage("Use as cover"), + "usePublicLinksForPeopleNotOnEnte": + MessageLookupByLibrary.simpleMessage( + "Use public links for people not on Ente"), + "useRecoveryKey": + MessageLookupByLibrary.simpleMessage("Kurtarma anahtarını kullan"), + "useSelectedPhoto": + MessageLookupByLibrary.simpleMessage("Seçilen fotoğrafı kullan"), + "usedSpace": MessageLookupByLibrary.simpleMessage("Kullanılan alan"), + "validTill": m66, + "verificationFailedPleaseTryAgain": + MessageLookupByLibrary.simpleMessage( + "Doğrulama başarısız oldu, lütfen tekrar deneyin"), + "verificationId": + MessageLookupByLibrary.simpleMessage("Doğrulama kimliği"), + "verify": MessageLookupByLibrary.simpleMessage("Doğrula"), + "verifyEmail": + MessageLookupByLibrary.simpleMessage("E-posta adresini doğrulayın"), + "verifyEmailID": m67, + "verifyIDLabel": MessageLookupByLibrary.simpleMessage("Doğrula"), + "verifyPasskey": + MessageLookupByLibrary.simpleMessage("Şifrenizi doğrulayın"), + "verifyPassword": + MessageLookupByLibrary.simpleMessage("Şifrenizi doğrulayın"), + "verifying": MessageLookupByLibrary.simpleMessage("Doğrulanıyor..."), + "verifyingRecoveryKey": MessageLookupByLibrary.simpleMessage( + "Kurtarma kodu doğrulanıyor..."), + "videoSmallCase": MessageLookupByLibrary.simpleMessage("video"), + "videos": MessageLookupByLibrary.simpleMessage("Videolar"), + "viewActiveSessions": + MessageLookupByLibrary.simpleMessage("Aktif oturumları görüntüle"), + "viewAddOnButton": + MessageLookupByLibrary.simpleMessage("Eklentileri görüntüle"), + "viewAll": MessageLookupByLibrary.simpleMessage("Tümünü görüntüle"), + "viewAllExifData": MessageLookupByLibrary.simpleMessage( + "Tüm EXIF verilerini görüntüle"), + "viewLargeFiles": MessageLookupByLibrary.simpleMessage("Large files"), + "viewLargeFilesDesc": MessageLookupByLibrary.simpleMessage( + "View files that are consuming the most amount of storage"), + "viewLogs": MessageLookupByLibrary.simpleMessage("Günlükleri göster"), + "viewRecoveryKey": MessageLookupByLibrary.simpleMessage( + "Kurtarma anahtarını görüntüle"), + "viewer": MessageLookupByLibrary.simpleMessage("Görüntüleyici"), + "visitWebToManage": MessageLookupByLibrary.simpleMessage( + "Aboneliğinizi yönetmek için lütfen web.ente.io adresini ziyaret edin"), + "waitingForVerification": + MessageLookupByLibrary.simpleMessage("Doğrulama bekleniyor..."), + "waitingForWifi": + MessageLookupByLibrary.simpleMessage("WiFi bekleniyor..."), + "weAreOpenSource": + MessageLookupByLibrary.simpleMessage("Biz açık kaynağız!"), + "weDontSupportEditingPhotosAndAlbumsThatYouDont": + MessageLookupByLibrary.simpleMessage( + "Henüz sahibi olmadığınız fotoğraf ve albümlerin düzenlenmesini desteklemiyoruz"), + "weHaveSendEmailTo": m68, + "weakStrength": MessageLookupByLibrary.simpleMessage("Zayıf"), + "welcomeBack": + MessageLookupByLibrary.simpleMessage("Tekrardan hoşgeldin!"), + "whatsNew": MessageLookupByLibrary.simpleMessage("What\'s new"), + "yearly": MessageLookupByLibrary.simpleMessage("Yıllık"), + "yearsAgo": m69, + "yes": MessageLookupByLibrary.simpleMessage("Evet"), + "yesCancel": MessageLookupByLibrary.simpleMessage("Evet, iptal et"), + "yesConvertToViewer": MessageLookupByLibrary.simpleMessage( + "Evet, görüntüleyici olarak dönüştür"), + "yesDelete": MessageLookupByLibrary.simpleMessage("Evet, sil"), + "yesDiscardChanges": + MessageLookupByLibrary.simpleMessage("Evet, değişiklikleri sil"), + "yesLogout": + MessageLookupByLibrary.simpleMessage("Evet, oturumu kapat"), + "yesRemove": MessageLookupByLibrary.simpleMessage("Evet, sil"), + "yesRenew": MessageLookupByLibrary.simpleMessage("Evet, yenile"), + "you": MessageLookupByLibrary.simpleMessage("Sen"), + "youAreOnAFamilyPlan": + MessageLookupByLibrary.simpleMessage("Aile planı kullanıyorsunuz!"), + "youAreOnTheLatestVersion": + MessageLookupByLibrary.simpleMessage("En son sürüme sahipsiniz"), + "youCanAtMaxDoubleYourStorage": MessageLookupByLibrary.simpleMessage( + "* Alanınızı en fazla ikiye katlayabilirsiniz"), + "youCanManageYourLinksInTheShareTab": + MessageLookupByLibrary.simpleMessage( + "Bağlantılarınızı paylaşım sekmesinden yönetebilirsiniz."), + "youCanTrySearchingForADifferentQuery": + MessageLookupByLibrary.simpleMessage( + "Farklı bir sorgu aramayı deneyebilirsiniz."), + "youCannotDowngradeToThisPlan": + MessageLookupByLibrary.simpleMessage("Bu plana geçemezsiniz"), + "youCannotShareWithYourself": + MessageLookupByLibrary.simpleMessage("Kendinizle paylaşamazsınız"), + "youDontHaveAnyArchivedItems": + MessageLookupByLibrary.simpleMessage("Arşivlenmiş öğeniz yok."), + "youHaveSuccessfullyFreedUp": m70, + "yourAccountHasBeenDeleted": + MessageLookupByLibrary.simpleMessage("Hesabınız silindi"), + "yourMap": MessageLookupByLibrary.simpleMessage("Haritalarınız"), + "yourPlanWasSuccessfullyDowngraded": + MessageLookupByLibrary.simpleMessage( + "Planınız başarıyla düşürüldü"), + "yourPlanWasSuccessfullyUpgraded": MessageLookupByLibrary.simpleMessage( + "Planınız başarılı şekilde yükseltildi"), + "yourPurchaseWasSuccessful": + MessageLookupByLibrary.simpleMessage("Satın alım başarılı"), + "yourStorageDetailsCouldNotBeFetched": + MessageLookupByLibrary.simpleMessage("Depolama bilgisi alınamadı"), + "yourSubscriptionHasExpired": + MessageLookupByLibrary.simpleMessage("Aboneliğinizin süresi doldu"), + "yourSubscriptionWasUpdatedSuccessfully": + MessageLookupByLibrary.simpleMessage( + "Aboneliğiniz başarıyla güncellendi"), + "yourVerificationCodeHasExpired": MessageLookupByLibrary.simpleMessage( + "Doğrulama kodunuzun süresi doldu"), + "youveNoDuplicateFilesThatCanBeCleared": + MessageLookupByLibrary.simpleMessage( + "Temizlenebilecek yinelenen dosyalarınız yok"), + "youveNoFilesInThisAlbumThatCanBeDeleted": + MessageLookupByLibrary.simpleMessage( + "Bu cihazda silinebilecek hiçbir dosyanız yok"), + "zoomOutToSeePhotos": MessageLookupByLibrary.simpleMessage( + "Fotoğrafları görmek için uzaklaştırın") + }; +} diff --git a/mobile/lib/generated/intl/messages_zh.dart b/mobile/lib/generated/intl/messages_zh.dart index 83636426b0..1fdfafe677 100644 --- a/mobile/lib/generated/intl/messages_zh.dart +++ b/mobile/lib/generated/intl/messages_zh.dart @@ -120,81 +120,83 @@ class MessageLookup extends MessageLookupByLibrary { static String m36(albumName) => "成功移动到 ${albumName}"; - static String m37(passwordStrengthValue) => "密码强度: ${passwordStrengthValue}"; + static String m37(name) => "不是 ${name}?"; - static String m38(providerName) => "如果您被收取费用,请用英语与 ${providerName} 的客服聊天"; + static String m38(passwordStrengthValue) => "密码强度: ${passwordStrengthValue}"; - static String m39(endDate) => "免费试用有效期至 ${endDate}。\n在此之后您可以选择付费计划。"; + static String m39(providerName) => "如果您被收取费用,请用英语与 ${providerName} 的客服聊天"; - static String m40(toEmail) => "请给我们发送电子邮件至 ${toEmail}"; + static String m40(endDate) => "免费试用有效期至 ${endDate}。\n在此之后您可以选择付费计划。"; - static String m41(toEmail) => "请将日志发送至 \n${toEmail}"; + static String m41(toEmail) => "请给我们发送电子邮件至 ${toEmail}"; - static String m42(storeName) => "在 ${storeName} 上给我们评分"; + static String m42(toEmail) => "请将日志发送至 \n${toEmail}"; - static String m43(storageInGB) => "3. 你和朋友都将免费获得 ${storageInGB} GB*"; + static String m43(storeName) => "在 ${storeName} 上给我们评分"; - static String m44(userEmail) => + static String m44(storageInGB) => "3. 你和朋友都将免费获得 ${storageInGB} GB*"; + + static String m45(userEmail) => "${userEmail} 将从这个共享相册中删除\n\nTA们添加的任何照片也将从相册中删除"; - static String m45(endDate) => "在 ${endDate} 前续费"; + static String m46(endDate) => "在 ${endDate} 前续费"; - static String m46(count) => + static String m47(count) => "${Intl.plural(count, other: '已找到 ${count} 个结果')}"; - static String m47(count) => "已选择 ${count} 个"; + static String m48(count) => "已选择 ${count} 个"; - static String m48(count, yourCount) => "选择了 ${count} 个 (您的 ${yourCount} 个)"; + static String m49(count, yourCount) => "选择了 ${count} 个 (您的 ${yourCount} 个)"; - static String m49(verificationID) => "这是我的ente.io 的验证 ID: ${verificationID}。"; + static String m50(verificationID) => "这是我的ente.io 的验证 ID: ${verificationID}。"; - static String m50(verificationID) => + static String m51(verificationID) => "嘿,你能确认这是你的 ente.io 验证 ID吗:${verificationID}"; - static String m51(referralCode, referralStorageInGB) => + static String m52(referralCode, referralStorageInGB) => "Ente 推荐代码:${referralCode}\n\n在 \"设置\"→\"通用\"→\"推荐 \"中应用它,即可在注册付费计划后免费获得 ${referralStorageInGB} GB 存储空间\n\nhttps://ente.io"; - static String m52(numberOfPeople) => + static String m53(numberOfPeople) => "${Intl.plural(numberOfPeople, zero: '与特定人员共享', one: '与 1 人共享', other: '与 ${numberOfPeople} 人共享')}"; - static String m53(emailIDs) => "与 ${emailIDs} 共享"; + static String m54(emailIDs) => "与 ${emailIDs} 共享"; - static String m54(fileType) => "此 ${fileType} 将从您的设备中删除。"; + static String m55(fileType) => "此 ${fileType} 将从您的设备中删除。"; - static String m55(fileType) => "${fileType} 已同时存在于 Ente 和您的设备中。"; + static String m56(fileType) => "${fileType} 已同时存在于 Ente 和您的设备中。"; - static String m56(fileType) => "${fileType} 将从 Ente 中删除。"; + static String m57(fileType) => "${fileType} 将从 Ente 中删除。"; - static String m57(storageAmountInGB) => "${storageAmountInGB} GB"; + static String m58(storageAmountInGB) => "${storageAmountInGB} GB"; - static String m58( + static String m59( usedAmount, usedStorageUnit, totalAmount, totalStorageUnit) => "已使用 ${usedAmount} ${usedStorageUnit} / ${totalAmount} ${totalStorageUnit}"; - static String m59(id) => + static String m60(id) => "您的 ${id} 已链接到另一个 Ente 账户。\n如果您想在此账户中使用您的 ${id} ,请联系我们的支持人员"; - static String m60(endDate) => "您的订阅将于 ${endDate} 取消"; + static String m61(endDate) => "您的订阅将于 ${endDate} 取消"; - static String m61(completed, total) => "已保存的回忆 ${completed}/共 ${total}"; + static String m62(completed, total) => "已保存的回忆 ${completed}/共 ${total}"; - static String m62(storageAmountInGB) => "他们也会获得 ${storageAmountInGB} GB"; + static String m63(storageAmountInGB) => "他们也会获得 ${storageAmountInGB} GB"; - static String m63(email) => "这是 ${email} 的验证ID"; + static String m64(email) => "这是 ${email} 的验证ID"; - static String m64(count) => + static String m65(count) => "${Intl.plural(count, zero: '', one: '1天', other: '${count} 天')}"; - static String m65(endDate) => "有效期至 ${endDate}"; + static String m66(endDate) => "有效期至 ${endDate}"; - static String m66(email) => "验证 ${email}"; + static String m67(email) => "验证 ${email}"; - static String m67(email) => "我们已经发送邮件到 ${email}"; + static String m68(email) => "我们已经发送邮件到 ${email}"; - static String m68(count) => + static String m69(count) => "${Intl.plural(count, one: '${count} 年前', other: '${count} 年前')}"; - static String m69(storageSaved) => "您已成功释放了 ${storageSaved}!"; + static String m70(storageSaved) => "您已成功释放了 ${storageSaved}!"; final messages = _notInlinedMessages(_notInlinedMessages); static Map _notInlinedMessages(_) => { @@ -268,7 +270,7 @@ class MessageLookup extends MessageLookupByLibrary { "androidIosWebDesktop": MessageLookupByLibrary.simpleMessage("安卓, iOS, 网页端, 桌面端"), "androidSignInTitle": MessageLookupByLibrary.simpleMessage("需要身份验证"), - "appLock": MessageLookupByLibrary.simpleMessage("App lock"), + "appLock": MessageLookupByLibrary.simpleMessage("应用锁"), "appVersion": m7, "appleId": MessageLookupByLibrary.simpleMessage("Apple ID"), "apply": MessageLookupByLibrary.simpleMessage("应用"), @@ -507,7 +509,7 @@ class MessageLookup extends MessageLookupByLibrary { "deviceCodeHint": MessageLookupByLibrary.simpleMessage("输入代码"), "deviceFilesAutoUploading": MessageLookupByLibrary.simpleMessage("添加到此设备相册的文件将自动上传到 Ente。"), - "deviceLock": MessageLookupByLibrary.simpleMessage("Device lock"), + "deviceLock": MessageLookupByLibrary.simpleMessage("设备锁"), "deviceLockExplanation": MessageLookupByLibrary.simpleMessage( "当 Ente 置于前台且正在进行备份时将禁用设备屏幕锁定。这通常是不需要的,但可能有助于更快地完成大型上传和大型库的初始导入。"), "deviceNotFound": MessageLookupByLibrary.simpleMessage("未发现设备"), @@ -582,7 +584,7 @@ class MessageLookup extends MessageLookupByLibrary { "enterPasswordToEncrypt": MessageLookupByLibrary.simpleMessage("输入我们可以用来加密您的数据的密码"), "enterPersonName": MessageLookupByLibrary.simpleMessage("输入人物名称"), - "enterPin": MessageLookupByLibrary.simpleMessage("Enter PIN"), + "enterPin": MessageLookupByLibrary.simpleMessage("输入 PIN 码"), "enterReferralCode": MessageLookupByLibrary.simpleMessage("输入推荐代码"), "enterThe6digitCodeFromnyourAuthenticatorApp": MessageLookupByLibrary.simpleMessage("从你的身份验证器应用中\n输入6位数字代码"), @@ -828,7 +830,7 @@ class MessageLookup extends MessageLookupByLibrary { "newAlbum": MessageLookupByLibrary.simpleMessage("新建相册"), "newToEnte": MessageLookupByLibrary.simpleMessage("初来 Ente"), "newest": MessageLookupByLibrary.simpleMessage("最新"), - "next": MessageLookupByLibrary.simpleMessage("Next"), + "next": MessageLookupByLibrary.simpleMessage("下一步"), "no": MessageLookupByLibrary.simpleMessage("否"), "noAlbumsSharedByYouYet": MessageLookupByLibrary.simpleMessage("您尚未共享任何相册"), @@ -851,8 +853,8 @@ class MessageLookup extends MessageLookupByLibrary { "由于我们端到端加密协议的性质,如果没有您的密码或恢复密钥,您的数据将无法解密"), "noResults": MessageLookupByLibrary.simpleMessage("无结果"), "noResultsFound": MessageLookupByLibrary.simpleMessage("未找到任何结果"), - "noSystemLockFound": - MessageLookupByLibrary.simpleMessage("No system lock found"), + "noSystemLockFound": MessageLookupByLibrary.simpleMessage("未找到系统锁"), + "notPersonLabel": m37, "nothingSharedWithYouYet": MessageLookupByLibrary.simpleMessage("尚未与您共享任何内容"), "nothingToSeeHere": MessageLookupByLibrary.simpleMessage("这里空空如也! 👀"), @@ -885,14 +887,14 @@ class MessageLookup extends MessageLookupByLibrary { "passwordChangedSuccessfully": MessageLookupByLibrary.simpleMessage("密码修改成功"), "passwordLock": MessageLookupByLibrary.simpleMessage("密码锁"), - "passwordStrength": m37, + "passwordStrength": m38, "passwordWarning": MessageLookupByLibrary.simpleMessage( "我们不储存这个密码,所以如果忘记, 我们将无法解密您的数据"), "paymentDetails": MessageLookupByLibrary.simpleMessage("付款明细"), "paymentFailed": MessageLookupByLibrary.simpleMessage("支付失败"), "paymentFailedMessage": MessageLookupByLibrary.simpleMessage( "不幸的是,您的付款失败。请联系支持人员,我们将为您提供帮助!"), - "paymentFailedTalkToProvider": m38, + "paymentFailedTalkToProvider": m39, "pendingItems": MessageLookupByLibrary.simpleMessage("待处理项目"), "pendingSync": MessageLookupByLibrary.simpleMessage("正在等待同步"), "people": MessageLookupByLibrary.simpleMessage("人物"), @@ -910,9 +912,9 @@ class MessageLookup extends MessageLookupByLibrary { MessageLookupByLibrary.simpleMessage("您添加的照片将从相册中移除"), "pickCenterPoint": MessageLookupByLibrary.simpleMessage("选择中心点"), "pinAlbum": MessageLookupByLibrary.simpleMessage("置顶相册"), - "pinLock": MessageLookupByLibrary.simpleMessage("PIN lock"), + "pinLock": MessageLookupByLibrary.simpleMessage("PIN 锁定"), "playOnTv": MessageLookupByLibrary.simpleMessage("在电视上播放相册"), - "playStoreFreeTrialValidTill": m39, + "playStoreFreeTrialValidTill": m40, "playstoreSubscription": MessageLookupByLibrary.simpleMessage("PlayStore 订阅"), "pleaseCheckYourInternetConnectionAndTryAgain": @@ -922,10 +924,10 @@ class MessageLookup extends MessageLookupByLibrary { "请用英语联系 support@ente.io ,我们将乐意提供帮助!"), "pleaseContactSupportIfTheProblemPersists": MessageLookupByLibrary.simpleMessage("如果问题仍然存在,请联系支持"), - "pleaseEmailUsAt": m40, + "pleaseEmailUsAt": m41, "pleaseGrantPermissions": MessageLookupByLibrary.simpleMessage("请授予权限"), "pleaseLoginAgain": MessageLookupByLibrary.simpleMessage("请重新登录"), - "pleaseSendTheLogsTo": m41, + "pleaseSendTheLogsTo": m42, "pleaseTryAgain": MessageLookupByLibrary.simpleMessage("请重试"), "pleaseVerifyTheCodeYouHaveEntered": MessageLookupByLibrary.simpleMessage("请验证您输入的代码"), @@ -951,7 +953,7 @@ class MessageLookup extends MessageLookupByLibrary { "raiseTicket": MessageLookupByLibrary.simpleMessage("提升工单"), "rateTheApp": MessageLookupByLibrary.simpleMessage("为此应用评分"), "rateUs": MessageLookupByLibrary.simpleMessage("给我们评分"), - "rateUsOnStore": m42, + "rateUsOnStore": m43, "recover": MessageLookupByLibrary.simpleMessage("恢复"), "recoverAccount": MessageLookupByLibrary.simpleMessage("恢复账户"), "recoverButton": MessageLookupByLibrary.simpleMessage("恢复"), @@ -972,14 +974,13 @@ class MessageLookup extends MessageLookupByLibrary { "当前设备的功能不足以验证您的密码,但我们可以以适用于所有设备的方式重新生成。\n\n请使用您的恢复密钥登录并重新生成您的密码(如果您希望,可以再次使用相同的密码)。"), "recreatePasswordTitle": MessageLookupByLibrary.simpleMessage("重新创建密码"), "reddit": MessageLookupByLibrary.simpleMessage("Reddit"), - "reenterPassword": - MessageLookupByLibrary.simpleMessage("Re-enter password"), - "reenterPin": MessageLookupByLibrary.simpleMessage("Re-enter PIN"), + "reenterPassword": MessageLookupByLibrary.simpleMessage("再次输入密码"), + "reenterPin": MessageLookupByLibrary.simpleMessage("再次输入 PIN 码"), "referFriendsAnd2xYourPlan": MessageLookupByLibrary.simpleMessage("把我们推荐给你的朋友然后获得延长一倍的订阅计划"), "referralStep1": MessageLookupByLibrary.simpleMessage("1. 将此代码提供给您的朋友"), "referralStep2": MessageLookupByLibrary.simpleMessage("2. 他们注册一个付费计划"), - "referralStep3": m43, + "referralStep3": m44, "referrals": MessageLookupByLibrary.simpleMessage("推荐"), "referralsAreCurrentlyPaused": MessageLookupByLibrary.simpleMessage("推荐已暂停"), @@ -1000,7 +1001,7 @@ class MessageLookup extends MessageLookupByLibrary { "removeFromFavorite": MessageLookupByLibrary.simpleMessage("从收藏中移除"), "removeLink": MessageLookupByLibrary.simpleMessage("移除链接"), "removeParticipant": MessageLookupByLibrary.simpleMessage("移除参与者"), - "removeParticipantBody": m44, + "removeParticipantBody": m45, "removePersonLabel": MessageLookupByLibrary.simpleMessage("移除人物标签"), "removePublicLink": MessageLookupByLibrary.simpleMessage("删除公开链接"), "removeShareItemsWarning": @@ -1012,7 +1013,7 @@ class MessageLookup extends MessageLookupByLibrary { "renameAlbum": MessageLookupByLibrary.simpleMessage("重命名相册"), "renameFile": MessageLookupByLibrary.simpleMessage("重命名文件"), "renewSubscription": MessageLookupByLibrary.simpleMessage("续费订阅"), - "renewsOn": m45, + "renewsOn": m46, "reportABug": MessageLookupByLibrary.simpleMessage("报告错误"), "reportBug": MessageLookupByLibrary.simpleMessage("报告错误"), "resendEmail": MessageLookupByLibrary.simpleMessage("重新发送电子邮件"), @@ -1064,7 +1065,7 @@ class MessageLookup extends MessageLookupByLibrary { MessageLookupByLibrary.simpleMessage("在照片的一定半径内拍摄的几组照片"), "searchPeopleEmptySection": MessageLookupByLibrary.simpleMessage("邀请他人,您将在此看到他们分享的所有照片"), - "searchResultCount": m46, + "searchResultCount": m47, "security": MessageLookupByLibrary.simpleMessage("安全"), "selectALocation": MessageLookupByLibrary.simpleMessage("选择一个位置"), "selectALocationFirst": @@ -1084,8 +1085,8 @@ class MessageLookup extends MessageLookupByLibrary { MessageLookupByLibrary.simpleMessage("所选文件夹将被加密并备份"), "selectedItemsWillBeDeletedFromAllAlbumsAndMoved": MessageLookupByLibrary.simpleMessage("所选项目将从所有相册中删除并移动到回收站。"), - "selectedPhotos": m47, - "selectedPhotosWithYours": m48, + "selectedPhotos": m48, + "selectedPhotosWithYours": m49, "send": MessageLookupByLibrary.simpleMessage("发送"), "sendEmail": MessageLookupByLibrary.simpleMessage("发送电子邮件"), "sendInvite": MessageLookupByLibrary.simpleMessage("发送邀请"), @@ -1096,9 +1097,8 @@ class MessageLookup extends MessageLookupByLibrary { "setAs": MessageLookupByLibrary.simpleMessage("设置为"), "setCover": MessageLookupByLibrary.simpleMessage("设置封面"), "setLabel": MessageLookupByLibrary.simpleMessage("设置"), - "setNewPassword": - MessageLookupByLibrary.simpleMessage("Set new password"), - "setNewPin": MessageLookupByLibrary.simpleMessage("Set new PIN"), + "setNewPassword": MessageLookupByLibrary.simpleMessage("设置新密码"), + "setNewPin": MessageLookupByLibrary.simpleMessage("设置新 PIN 码"), "setPasswordTitle": MessageLookupByLibrary.simpleMessage("设置密码"), "setRadius": MessageLookupByLibrary.simpleMessage("设定半径"), "setupComplete": MessageLookupByLibrary.simpleMessage("设置完成"), @@ -1108,16 +1108,16 @@ class MessageLookup extends MessageLookupByLibrary { MessageLookupByLibrary.simpleMessage("打开相册并点击右上角的分享按钮进行分享"), "shareAnAlbumNow": MessageLookupByLibrary.simpleMessage("立即分享相册"), "shareLink": MessageLookupByLibrary.simpleMessage("分享链接"), - "shareMyVerificationID": m49, + "shareMyVerificationID": m50, "shareOnlyWithThePeopleYouWant": MessageLookupByLibrary.simpleMessage("仅与您想要的人分享"), - "shareTextConfirmOthersVerificationID": m50, + "shareTextConfirmOthersVerificationID": m51, "shareTextRecommendUsingEnte": MessageLookupByLibrary.simpleMessage("下载 Ente,让我们轻松共享高质量的原始照片和视频"), - "shareTextReferralCode": m51, + "shareTextReferralCode": m52, "shareWithNonenteUsers": MessageLookupByLibrary.simpleMessage("与非 Ente 用户共享"), - "shareWithPeopleSectionTitle": m52, + "shareWithPeopleSectionTitle": m53, "shareYourFirstAlbum": MessageLookupByLibrary.simpleMessage("分享您的第一个相册"), "sharedAlbumSectionDescription": MessageLookupByLibrary.simpleMessage( @@ -1128,7 +1128,7 @@ class MessageLookup extends MessageLookupByLibrary { MessageLookupByLibrary.simpleMessage("新共享的照片"), "sharedPhotoNotificationsExplanation": MessageLookupByLibrary.simpleMessage("当有人将照片添加到您所属的共享相册时收到通知"), - "sharedWith": m53, + "sharedWith": m54, "sharedWithMe": MessageLookupByLibrary.simpleMessage("与我共享"), "sharedWithYou": MessageLookupByLibrary.simpleMessage("已与您共享"), "sharing": MessageLookupByLibrary.simpleMessage("正在分享..."), @@ -1140,11 +1140,11 @@ class MessageLookup extends MessageLookupByLibrary { "signOutOtherDevices": MessageLookupByLibrary.simpleMessage("登出其他设备"), "signUpTerms": MessageLookupByLibrary.simpleMessage( "我同意 服务条款隐私政策"), - "singleFileDeleteFromDevice": m54, + "singleFileDeleteFromDevice": m55, "singleFileDeleteHighlight": MessageLookupByLibrary.simpleMessage("它将从所有相册中删除。"), - "singleFileInBothLocalAndRemote": m55, - "singleFileInRemoteOnly": m56, + "singleFileInBothLocalAndRemote": m56, + "singleFileInRemoteOnly": m57, "skip": MessageLookupByLibrary.simpleMessage("跳过"), "social": MessageLookupByLibrary.simpleMessage("社交"), "someItemsAreInBothEnteAndYourDevice": @@ -1177,12 +1177,12 @@ class MessageLookup extends MessageLookupByLibrary { "storage": MessageLookupByLibrary.simpleMessage("存储空间"), "storageBreakupFamily": MessageLookupByLibrary.simpleMessage("家庭"), "storageBreakupYou": MessageLookupByLibrary.simpleMessage("您"), - "storageInGB": m57, + "storageInGB": m58, "storageLimitExceeded": MessageLookupByLibrary.simpleMessage("已超出存储限制"), - "storageUsageInfo": m58, + "storageUsageInfo": m59, "strongStrength": MessageLookupByLibrary.simpleMessage("强"), - "subAlreadyLinkedErrMessage": m59, - "subWillBeCancelledOn": m60, + "subAlreadyLinkedErrMessage": m60, + "subWillBeCancelledOn": m61, "subscribe": MessageLookupByLibrary.simpleMessage("订阅"), "subscribeToEnableSharing": MessageLookupByLibrary.simpleMessage("您的订阅似乎已过期。请订阅以启用分享。"), @@ -1195,13 +1195,13 @@ class MessageLookup extends MessageLookupByLibrary { "successfullyUnhid": MessageLookupByLibrary.simpleMessage("已成功取消隐藏"), "suggestFeatures": MessageLookupByLibrary.simpleMessage("建议新功能"), "support": MessageLookupByLibrary.simpleMessage("支持"), - "syncProgress": m61, + "syncProgress": m62, "syncStopped": MessageLookupByLibrary.simpleMessage("同步已停止"), "syncing": MessageLookupByLibrary.simpleMessage("正在同步···"), "systemTheme": MessageLookupByLibrary.simpleMessage("适应系统"), "tapToCopy": MessageLookupByLibrary.simpleMessage("点击以复制"), "tapToEnterCode": MessageLookupByLibrary.simpleMessage("点击以输入代码"), - "tapToUnlock": MessageLookupByLibrary.simpleMessage("Tap to unlock"), + "tapToUnlock": MessageLookupByLibrary.simpleMessage("点击解锁"), "tempErrorContactSupportIfPersists": MessageLookupByLibrary.simpleMessage( "看起来出了点问题。 请稍后重试。 如果错误仍然存在,请联系我们的支持团队。"), @@ -1219,7 +1219,7 @@ class MessageLookup extends MessageLookupByLibrary { "theme": MessageLookupByLibrary.simpleMessage("主题"), "theseItemsWillBeDeletedFromYourDevice": MessageLookupByLibrary.simpleMessage("这些项目将从您的设备中删除。"), - "theyAlsoGetXGb": m62, + "theyAlsoGetXGb": m63, "theyWillBeDeletedFromAllAlbums": MessageLookupByLibrary.simpleMessage("他们将从所有相册中删除。"), "thisActionCannotBeUndone": @@ -1233,7 +1233,7 @@ class MessageLookup extends MessageLookupByLibrary { MessageLookupByLibrary.simpleMessage("这个邮箱地址已经被使用"), "thisImageHasNoExifData": MessageLookupByLibrary.simpleMessage("此图像没有Exif 数据"), - "thisIsPersonVerificationId": m63, + "thisIsPersonVerificationId": m64, "thisIsYourVerificationId": MessageLookupByLibrary.simpleMessage("这是您的验证 ID"), "thisWillLogYouOutOfTheFollowingDevice": @@ -1241,18 +1241,17 @@ class MessageLookup extends MessageLookupByLibrary { "thisWillLogYouOutOfThisDevice": MessageLookupByLibrary.simpleMessage("这将使您在此设备上退出登录!"), "toEnableAppLockPleaseSetupDevicePasscodeOrScreen": - MessageLookupByLibrary.simpleMessage( - "To enable app lock, please setup device passcode or screen lock in your system settings."), + MessageLookupByLibrary.simpleMessage("要启用应用锁,请在系统设置中设置设备密码或屏幕锁定。"), "toHideAPhotoOrVideo": MessageLookupByLibrary.simpleMessage("隐藏照片或视频"), "toResetVerifyEmail": MessageLookupByLibrary.simpleMessage("要重置您的密码,请先验证您的电子邮件。"), "todaysLogs": MessageLookupByLibrary.simpleMessage("当天日志"), "tooManyIncorrectAttempts": - MessageLookupByLibrary.simpleMessage("Too many incorrect attempts"), + MessageLookupByLibrary.simpleMessage("错误尝试次数过多"), "total": MessageLookupByLibrary.simpleMessage("总计"), "totalSize": MessageLookupByLibrary.simpleMessage("总大小"), "trash": MessageLookupByLibrary.simpleMessage("回收站"), - "trashDaysLeft": m64, + "trashDaysLeft": m65, "trim": MessageLookupByLibrary.simpleMessage("修剪"), "tryAgain": MessageLookupByLibrary.simpleMessage("请再试一次"), "turnOnBackupForAutoUpload": MessageLookupByLibrary.simpleMessage( @@ -1291,18 +1290,19 @@ class MessageLookup extends MessageLookupByLibrary { MessageLookupByLibrary.simpleMessage("最高五折优惠,直至12月4日。"), "usableReferralStorageInfo": MessageLookupByLibrary.simpleMessage( "可用存储空间受您当前计划的限制。 当您升级您的计划时,超出要求的存储空间将自动变为可用。"), + "useAsCover": MessageLookupByLibrary.simpleMessage("用作封面"), "usePublicLinksForPeopleNotOnEnte": MessageLookupByLibrary.simpleMessage("对不在 Ente 上的人使用公开链接"), "useRecoveryKey": MessageLookupByLibrary.simpleMessage("使用恢复密钥"), "useSelectedPhoto": MessageLookupByLibrary.simpleMessage("使用所选照片"), "usedSpace": MessageLookupByLibrary.simpleMessage("已用空间"), - "validTill": m65, + "validTill": m66, "verificationFailedPleaseTryAgain": MessageLookupByLibrary.simpleMessage("验证失败,请重试"), "verificationId": MessageLookupByLibrary.simpleMessage("验证 ID"), "verify": MessageLookupByLibrary.simpleMessage("验证"), "verifyEmail": MessageLookupByLibrary.simpleMessage("验证电子邮件"), - "verifyEmailID": m66, + "verifyEmailID": m67, "verifyIDLabel": MessageLookupByLibrary.simpleMessage("验证"), "verifyPasskey": MessageLookupByLibrary.simpleMessage("验证通行密钥"), "verifyPassword": MessageLookupByLibrary.simpleMessage("验证密码"), @@ -1329,12 +1329,12 @@ class MessageLookup extends MessageLookupByLibrary { "weAreOpenSource": MessageLookupByLibrary.simpleMessage("我们是开源的 !"), "weDontSupportEditingPhotosAndAlbumsThatYouDont": MessageLookupByLibrary.simpleMessage("我们不支持编辑您尚未拥有的照片和相册"), - "weHaveSendEmailTo": m67, + "weHaveSendEmailTo": m68, "weakStrength": MessageLookupByLibrary.simpleMessage("弱"), "welcomeBack": MessageLookupByLibrary.simpleMessage("欢迎回来!"), "whatsNew": MessageLookupByLibrary.simpleMessage("更新日志"), "yearly": MessageLookupByLibrary.simpleMessage("每年"), - "yearsAgo": m68, + "yearsAgo": m69, "yes": MessageLookupByLibrary.simpleMessage("是"), "yesCancel": MessageLookupByLibrary.simpleMessage("是的,取消"), "yesConvertToViewer": MessageLookupByLibrary.simpleMessage("是的,转换为查看者"), @@ -1360,7 +1360,7 @@ class MessageLookup extends MessageLookupByLibrary { MessageLookupByLibrary.simpleMessage("莫开玩笑,您不能与自己分享"), "youDontHaveAnyArchivedItems": MessageLookupByLibrary.simpleMessage("您没有任何存档的项目。"), - "youHaveSuccessfullyFreedUp": m69, + "youHaveSuccessfullyFreedUp": m70, "yourAccountHasBeenDeleted": MessageLookupByLibrary.simpleMessage("您的账户已删除"), "yourMap": MessageLookupByLibrary.simpleMessage("您的地图"), diff --git a/mobile/lib/generated/l10n.dart b/mobile/lib/generated/l10n.dart index 017e4378fd..3ae7fb3ded 100644 --- a/mobile/lib/generated/l10n.dart +++ b/mobile/lib/generated/l10n.dart @@ -9123,6 +9123,7 @@ class AppLocalizationDelegate extends LocalizationsDelegate { Locale.fromSubtags(languageCode: 'pl'), Locale.fromSubtags(languageCode: 'pt'), Locale.fromSubtags(languageCode: 'ru'), + Locale.fromSubtags(languageCode: 'tr'), Locale.fromSubtags(languageCode: 'zh'), ]; } diff --git a/mobile/lib/l10n/intl_en.arb b/mobile/lib/l10n/intl_en.arb index fdbada3b8e..1b93430eb8 100644 --- a/mobile/lib/l10n/intl_en.arb +++ b/mobile/lib/l10n/intl_en.arb @@ -1,4 +1,5 @@ { + "@@locale ": "en", "enterYourEmailAddress": "Enter your email address", "accountWelcomeBack": "Welcome back!", "email": "Email", diff --git a/mobile/lib/l10n/intl_tr.arb b/mobile/lib/l10n/intl_tr.arb new file mode 100644 index 0000000000..fab7542695 --- /dev/null +++ b/mobile/lib/l10n/intl_tr.arb @@ -0,0 +1,1279 @@ +{ + "enterYourEmailAddress": "E-posta adresinizi girin", + "accountWelcomeBack": "Tekrar hoş geldiniz!", + "email": "E-Posta", + "cancel": "İptal Et", + "verify": "Doğrula", + "invalidEmailAddress": "Geçersiz e-posta adresi", + "enterValidEmail": "Lütfen geçerli bir E-posta adresi girin.", + "deleteAccount": "Hesabı sil", + "askDeleteReason": "Hesabınızı neden silmek istiyorsunuz?", + "deleteAccountFeedbackPrompt": "Aramızdan ayrıldığınız için üzgünüz. Lütfen kendimizi geliştirmemize yardımcı olun. Neden ayrıldığınızı Açıklar mısınız.", + "feedback": "Geri Bildirim", + "kindlyHelpUsWithThisInformation": "Lütfen bu bilgilerle bize yardımcı olun", + "confirmDeletePrompt": "Evet, bu hesabı ve tüm verileri kalıcı olarak silmek istiyorum.", + "confirmAccountDeletion": "Hesap silme işlemini onayla", + "deleteAccountPermanentlyButton": "Hesabımı kalıcı olarak sil", + "yourAccountHasBeenDeleted": "Hesabınız silindi", + "selectReason": "Ayrılma nedeninizi seçin", + "deleteReason1": "İhtiyacım olan önemli bir özellik eksik", + "deleteReason2": "Uygulama veya bir özellik olması gerektiğini düşündüğüm gibi çalışmıyor", + "deleteReason3": "Daha çok sevdiğim başka bir hizmet buldum", + "deleteReason4": "Nedenim listede yok", + "sendEmail": "E-posta gönder", + "deleteRequestSLAText": "İsteğiniz 72 saat içinde gerçekleştirilecek.", + "deleteEmailRequest": "Lütfen kayıtlı e-posta adresinizden account-deletion@ente.io'a e-posta gönderiniz.", + "entePhotosPerm": "Ente needs permission to preserve your photos", + "ok": "Tamam", + "createAccount": "Hesap oluşturun", + "createNewAccount": "Yeni bir hesap oluşturun", + "password": "Şifre", + "confirmPassword": "Şifrenizi onaylayın", + "activeSessions": "Aktif oturumlar", + "oops": "Hay aksi", + "somethingWentWrongPleaseTryAgain": "Bir şeyler ters gitti, lütfen tekrar deneyin", + "thisWillLogYouOutOfThisDevice": "Bu cihazdaki oturumunuz kapatılacak!", + "thisWillLogYouOutOfTheFollowingDevice": "Bu, sizi aşağıdaki cihazdan çıkış yapacak:", + "terminateSession": "Oturumu sonlandır?", + "terminate": "Sonlandır", + "thisDevice": "Bu cihaz", + "recoverButton": "Kurtar", + "recoverySuccessful": "Kurtarma başarılı!", + "decrypting": "Şifre çözülüyor...", + "incorrectRecoveryKeyTitle": "Yanlış kurtarma kodu", + "incorrectRecoveryKeyBody": "Girdiğiniz kurtarma kod yanlış", + "forgotPassword": "Şifremi unuttum", + "enterYourRecoveryKey": "Kurtarma kodunuzu girin", + "noRecoveryKey": "Kurtarma kodunuz yok mu?", + "sorry": "Üzgünüz", + "noRecoveryKeyNoDecryption": "Uçtan uca şifreleme protokolümüzün doğası gereği, verileriniz şifreniz veya kurtarma anahtarınız olmadan çözülemez", + "verifyEmail": "E-posta adresini doğrulayın", + "toResetVerifyEmail": "Şifrenizi sıfılamak için lütfen e-postanızı girin.", + "checkInboxAndSpamFolder": "Lütfen doğrulama işlemini tamamlamak için gelen kutunuzu (ve spam klasörünüzü) kontrol edin", + "tapToEnterCode": "Kodu girmek icin tıklayın", + "resendEmail": "E-postayı yeniden gönder", + "weHaveSendEmailTo": "E-postayı {email} adresine gönderdik", + "@weHaveSendEmailTo": { + "description": "Text to indicate that we have sent a mail to the user", + "placeholders": { + "email": { + "description": "The email address of the user", + "type": "String", + "example": "example@ente.io" + } + } + }, + "setPasswordTitle": "Parola ayarlayın", + "changePasswordTitle": "Parolanızı değiştirin", + "resetPasswordTitle": "Parolanızı sıfırlayın", + "encryptionKeys": "Sifreleme anahtarı", + "passwordWarning": "Şifrelerinizi saklamıyoruz, bu yüzden unutursanız, verilerinizi deşifre edemeyiz", + "enterPasswordToEncrypt": "Verilerinizi şifrelemek için kullanabileceğimiz bir şifre girin", + "enterNewPasswordToEncrypt": "Verilerinizi şifrelemek için kullanabileceğimiz yeni bir şifre girin", + "weakStrength": "Zayıf", + "strongStrength": "Güçlü", + "moderateStrength": "Ilımlı", + "passwordStrength": "Şifrenin güçlülük seviyesi: {passwordStrengthValue}", + "@passwordStrength": { + "description": "Text to indicate the password strength", + "placeholders": { + "passwordStrengthValue": { + "description": "The strength of the password as a string", + "type": "String", + "example": "Weak or Moderate or Strong" + } + }, + "message": "Password Strength: {passwordStrengthText}" + }, + "passwordChangedSuccessfully": "Şifreniz başarılı bir şekilde değiştirildi", + "generatingEncryptionKeys": "Şifreleme anahtarı oluşturuluyor...", + "pleaseWait": "Lütfen bekleyiniz...", + "continueLabel": "Devam edin", + "insecureDevice": "Güvenilir olmayan cihaz", + "sorryWeCouldNotGenerateSecureKeysOnThisDevicennplease": "Üzgünüm, bu cihazda güvenli anahtarlarını oluşturamadık.\n\nLütfen başka bir cihazdan giriş yapmayı deneyiniz.", + "howItWorks": "Nasıl çalışır", + "encryption": "Şifreleme", + "ackPasswordLostWarning": "Şifremi kaybedersem, verilerim uçtan uca şifrelendiği için verilerimi kaybedebileceğimi farkındayım.", + "privacyPolicyTitle": "Mahremiyet Politikası", + "termsOfServicesTitle": "Şartlar", + "signUpTerms": "Hizmet Şartları'nı ve Gizlilik Politikası'nı kabul ediyorum", + "logInLabel": "Giriş yap", + "loginTerms": "\"Giriş yap\" düğmesine tıklayarak, Hizmet Şartları'nı ve Gizlilik Politikası'nı kabul ediyorum", + "changeEmail": "E-posta adresini değiştir", + "enterYourPassword": "Lütfen şifrenizi giriniz", + "welcomeBack": "Tekrardan hoşgeldin!", + "contactSupport": "Destek ile iletişim", + "incorrectPasswordTitle": "Yanlış şifre", + "pleaseTryAgain": "Lütfen tekrar deneyiniz", + "recreatePasswordTitle": "Sifrenizi tekrardan oluşturun", + "useRecoveryKey": "Kurtarma anahtarını kullan", + "recreatePasswordBody": "Cihazınız, şifrenizi doğrulamak için yeterli güce sahip değil, ancak tüm cihazlarda çalışacak şekilde yeniden oluşturabiliriz.\n\nLütfen kurtarma anahtarınızı kullanarak giriş yapın ve şifrenizi yeniden oluşturun (istediğiniz takdirde aynı şifreyi tekrar kullanabilirsiniz).", + "verifyPassword": "Şifrenizi doğrulayın", + "recoveryKey": "Kurtarma anahtarı", + "recoveryKeyOnForgotPassword": "Şifrenizi unutursanız, verilerinizi kurtarmanın tek yolu bu anahtar olacaktır.", + "recoveryKeySaveDescription": "Bu anahtarı saklamıyoruz, lütfen bu 24 kelime anahtarı güvenli bir yerde saklayın.", + "doThisLater": "Sonra yap", + "saveKey": "Anahtarı kaydet", + "recoveryKeyCopiedToClipboard": "Kurtarma anahtarınız panoya kopyalandı", + "recoverAccount": "Hesabı kurtar", + "recover": "Kurtarma", + "dropSupportEmail": "Lütfen kayıtlı e-posta adresinizden {supportEmail} adresine bir e-posta gönderin", + "@dropSupportEmail": { + "placeholders": { + "supportEmail": { + "description": "The support email address", + "type": "String", + "example": "support@ente.io" + } + } + }, + "twofactorSetup": "Cift faktör ayarı", + "enterCode": "Kodu giriniz", + "scanCode": "Kodu tarayın", + "codeCopiedToClipboard": "Kodunuz panoya kopyalandı", + "copypasteThisCodentoYourAuthenticatorApp": "Bu kodu kopyalayın ve kimlik doğrulama uygulamanıza yapıştırın", + "tapToCopy": "kopyalamak için dokunun", + "scanThisBarcodeWithnyourAuthenticatorApp": "Kimlik doğrulama uygulamanız ile kodu tarayın", + "enterThe6digitCodeFromnyourAuthenticatorApp": "Doğrulama uygulamasındaki 6 basamaklı kodu giriniz", + "confirm": "Onayla", + "setupComplete": "Ayarlama işlemi başarılı", + "saveYourRecoveryKeyIfYouHaventAlready": "Henüz yapmadıysanız kurtarma anahtarınızı kaydetmeyi unutmayın", + "thisCanBeUsedToRecoverYourAccountIfYou": "Bu, iki faktörünüzü kaybederseniz hesabınızı kurtarmak için kullanılabilir", + "twofactorAuthenticationPageTitle": "İki faktörlü doğrulama", + "lostDevice": "Cihazı kayıp mı ettiniz?", + "verifyingRecoveryKey": "Kurtarma kodu doğrulanıyor...", + "recoveryKeyVerified": "Kurtarma kodu doğrulandı", + "recoveryKeySuccessBody": "Harika! Kurtarma anahtarınız geçerlidir. Doğrulama için teşekkür ederim.\n\nLütfen kurtarma anahtarınızı güvenli bir şekilde yedeklediğinizden emin olun.", + "invalidRecoveryKey": "Girdiğiniz kurtarma anahtarı geçerli değil. Lütfen anahtarın 24 kelime içerdiğinden ve her bir kelimenin doğru şekilde yazıldığından emin olun.\n\nEğer eski bir kurtarma kodu girdiyseniz, o zaman kodun 64 karakter uzunluğunda olduğunu kontrol edin.", + "invalidKey": "Gecersiz anahtar", + "tryAgain": "Tekrar deneyiniz", + "viewRecoveryKey": "Kurtarma anahtarını görüntüle", + "confirmRecoveryKey": "Kurtarma anahtarını doğrula", + "recoveryKeyVerifyReason": "Eğer şifrenizi unutursanız, fotoğraflarınızı kurtarmanın tek yolu kurtarma anahtarınızdır. Kurtarma anahtarınızı Ayarlar > Güvenlik bölümünde bulabilirsiniz.\n\nLütfen kurtarma anahtarınızı buraya girerek doğru bir şekilde kaydettiğinizi doğrulayın.", + "confirmYourRecoveryKey": "Kurtarma anahtarını doğrulayın", + "addViewer": "Görüntüleyici ekle", + "addCollaborator": "Düzenleyici ekle", + "addANewEmail": "Yeni e-posta ekle", + "orPickAnExistingOne": "Veya mevcut birini seçiniz", + "collaboratorsCanAddPhotosAndVideosToTheSharedAlbum": "Düzenleyiciler, paylaşılan albüme fotoğraf ve videolar ekleyebilir.", + "enterEmail": "E-postanızı giriniz", + "albumOwner": "Sahip", + "@albumOwner": { + "description": "Role of the album owner" + }, + "you": "Sen", + "collaborator": "Düzenleyici", + "addMore": "Daha fazla ekle", + "@addMore": { + "description": "Button text to add more collaborators/viewers" + }, + "viewer": "Görüntüleyici", + "remove": "Kaldır", + "removeParticipant": "Katılımcıyı kaldır", + "@removeParticipant": { + "description": "menuSectionTitle for removing a participant" + }, + "manage": "Yönet", + "addedAs": "Eklendi", + "changePermissions": "İzinleri değiştir?", + "yesConvertToViewer": "Evet, görüntüleyici olarak dönüştür", + "cannotAddMorePhotosAfterBecomingViewer": "{user}, bu albüme daha fazla fotoğraf ekleyemeyecek.\n\nAncak, kendi eklediği mevcut fotoğrafları kaldırmaya devam edebilecektir", + "allowAddingPhotos": "Fotoğraf eklemeye izin ver", + "@allowAddingPhotos": { + "description": "Switch button to enable uploading photos to a public link" + }, + "allowAddPhotosDescription": "Bağlantıya sahip olan kişilere, paylaşılan albüme fotoğraf eklemelerine izin ver.", + "passwordLock": "Sifre kilidi", + "disableDownloadWarningTitle": "Lütfen dikkate alın", + "disableDownloadWarningBody": "Görüntüleyiciler, hala harici araçlar kullanarak ekran görüntüsü alabilir veya fotoğraflarınızın bir kopyasını kaydedebilir. Lütfen bunu göz önünde bulundurunuz", + "allowDownloads": "İndirmeye izin ver", + "linkDeviceLimit": "Cihaz limiti", + "noDeviceLimit": "Yok", + "@noDeviceLimit": { + "description": "Text to indicate that there is limit on number of devices" + }, + "linkExpiry": "Linkin geçerliliği", + "linkExpired": "Süresi dolmuş", + "linkEnabled": "Geçerli", + "linkNeverExpires": "Asla", + "expiredLinkInfo": "Bu bağlantının süresi dolmuştur. Lütfen yeni bir süre belirleyin veya bağlantı süresini devre dışı bırakın.", + "setAPassword": "Şifre ayarla", + "lockButtonLabel": "Kilit", + "enterPassword": "Şifrenizi girin", + "removeLink": "Linki kaldır", + "manageLink": "Linki yönet", + "linkExpiresOn": "Bu bağlantı {expiryTime} dan sonra geçersiz olacaktır", + "albumUpdated": "Albüm güncellendi", + "never": "Asla", + "custom": "Kişisel", + "@custom": { + "description": "Label for setting custom value for link expiry" + }, + "after1Hour": "1 saat sonra", + "after1Day": "1 gün sonra", + "after1Week": "1 hafta sonra", + "after1Month": "1 ay sonra", + "after1Year": "1 yıl sonra", + "manageParticipants": "Yönet", + "albumParticipantsCount": "{count, plural, =0 {Katılımcı Yok} =1 {1 Katılımcı} other {{count} Katılımcı}}", + "@albumParticipantsCount": { + "placeholders": { + "count": { + "type": "int", + "example": "5" + } + }, + "description": "Number of participants in an album, including the album owner." + }, + "collabLinkSectionDescription": "Create a link to allow people to add and view photos in your shared album without needing an Ente app or account. Great for collecting event photos.", + "collectPhotos": "Fotoğrafları topla", + "collaborativeLink": "Organizasyon bağlantısı", + "shareWithNonenteUsers": "Share with non-Ente users", + "createPublicLink": "Herkese açık link oluştur", + "sendLink": "Link gönder", + "copyLink": "Linki kopyala", + "linkHasExpired": "Bağlantının süresi dolmuş", + "publicLinkEnabled": "Herkese açık bağlantı aktive edildi", + "shareALink": "Linki paylaş", + "sharedAlbumSectionDescription": "Create shared and collaborative albums with other Ente users, including users on free plans.", + "shareWithPeopleSectionTitle": "{numberOfPeople, plural, =0 {Belirli kişilerle paylaş} =1 {1 kişiyle paylaşıldı} other {{numberOfPeople} kişiyle paylaşıldı}}", + "@shareWithPeopleSectionTitle": { + "placeholders": { + "numberOfPeople": { + "type": "int", + "example": "2" + } + } + }, + "thisIsYourVerificationId": "Doğrulama kimliğiniz", + "someoneSharingAlbumsWithYouShouldSeeTheSameId": "Size albümleri paylaşan biri, kendi cihazında aynı kimliği görmelidir.", + "howToViewShareeVerificationID": "Lütfen onlardan ayarlar ekranında e-posta adresine uzun süre basmalarını ve her iki cihazdaki kimliklerin eşleştiğini doğrulamalarını isteyin.", + "thisIsPersonVerificationId": "Bu, {email}'in Doğrulama Kimliği", + "@thisIsPersonVerificationId": { + "placeholders": { + "email": { + "type": "String", + "example": "someone@ente.io" + } + } + }, + "verificationId": "Doğrulama kimliği", + "verifyEmailID": "{email} doğrula", + "emailNoEnteAccount": "{email} does not have an Ente account.\n\nSend them an invite to share photos.", + "shareMyVerificationID": "İşte ente.io için doğrulama kimliğim: {verificationID}.", + "shareTextConfirmOthersVerificationID": "Merhaba, bu ente.io doğrulama kimliğinizin doğruluğunu onaylayabilir misiniz: {verificationID}", + "somethingWentWrong": "Bazı şeyler yanlış gitti", + "sendInvite": "Davet kodu gönder", + "shareTextRecommendUsingEnte": "Download Ente so we can easily share original quality photos and videos\n\nhttps://ente.io", + "done": "Bitti", + "applyCodeTitle": "Kodu girin", + "enterCodeDescription": "Arkadaşınız tarafından sağlanan kodu girerek hem sizin hem de arkadaşınızın ücretsiz depolamayı talep etmek için girin", + "apply": "Uygula", + "failedToApplyCode": "Uygulanırken hata oluştu", + "enterReferralCode": "Davet kodunuzu girin", + "codeAppliedPageTitle": "Kod kabul edildi", + "storageInGB": "{storageAmountInGB} GB", + "claimed": "Alındı", + "@claimed": { + "description": "Used to indicate storage claimed, like 10GB Claimed" + }, + "details": "Ayrıntılar", + "claimMore": "Arttır!", + "theyAlsoGetXGb": "Aynı zamanda {storageAmountInGB} GB alıyorlar", + "freeStorageOnReferralSuccess": "Birisinin davet kodunuzu uygulayıp ücretli hesap açtığı her seferede {storageAmountInGB} GB", + "shareTextReferralCode": "Ente referral code: {referralCode} \n\nApply it in Settings → General → Referrals to get {referralStorageInGB} GB free after you signup for a paid plan\n\nhttps://ente.io", + "claimFreeStorage": "Bedava alan talep edin", + "inviteYourFriends": "Arkadaşlarını davet et", + "failedToFetchReferralDetails": "Davet ayrıntıları çekilemedi. Iütfen daha sonra deneyin.", + "referralStep1": "1. Bu kodu arkadaşlarınıza verin", + "referralStep2": "2. Ücretli bir plan için kaydolsunlar", + "referralStep3": "3. Hepimiz {storageInGB} GB* bedava alın", + "referralsAreCurrentlyPaused": "Davetler şu anda durmuş durumda", + "youCanAtMaxDoubleYourStorage": "* Alanınızı en fazla ikiye katlayabilirsiniz", + "claimedStorageSoFar": "{isFamilyMember, select, true {Şu ana kadar aileniz {storageAmountInGb} GB aldı} false {Şu ana kadar {storageAmountInGb} GB aldınız} other {Şu ana kadar {storageAmountInGb} GB aldınız!}}", + "@claimedStorageSoFar": { + "placeholders": { + "isFamilyMember": { + "type": "String", + "example": "true" + }, + "storageAmountInGb": { + "type": "int", + "example": "10" + } + } + }, + "faq": "Sıkça sorulan sorular", + "help": "Yardım", + "oopsSomethingWentWrong": "Hoop, Birşeyler yanlış gitti", + "peopleUsingYourCode": "Kodunuzu kullananlar", + "eligible": "uygun", + "total": "total", + "codeUsedByYou": "Sizin kullandığınız kod", + "freeStorageClaimed": "Alınan bedava alan", + "freeStorageUsable": "Kullanılabilir bedava alan", + "usableReferralStorageInfo": "Kullanılabilir depolama alanı mevcut planınızla sınırlıdır. Talep edilen fazla depolama alanı, planınızı yükselttiğinizde otomatik olarak kullanılabilir hale gelecektir.", + "removeFromAlbumTitle": "Albümden çıkarılsın mı?", + "removeFromAlbum": "Albümden çıkar", + "itemsWillBeRemovedFromAlbum": "Seçilen öğeler bu albümden kaldırılacak", + "removeShareItemsWarning": "Kaldırdığınız öğelerden bazıları başkaları tarafından eklenmiştir ve bunlara erişiminizi kaybedeceksiniz", + "addingToFavorites": "Favorilere ekleniyor...", + "removingFromFavorites": "Favorilerimden kaldır...", + "sorryCouldNotAddToFavorites": "Üzgünüm, favorilere ekleyemedim!", + "sorryCouldNotRemoveFromFavorites": "Üzgünüm, favorilere ekleyemedim!", + "subscribeToEnableSharing": "Aboneliğinizin süresi dolmuş gibi görünüyor. Paylaşımı etkinleştirmek için lütfen abone olun.", + "subscribe": "Abone ol", + "canOnlyRemoveFilesOwnedByYou": "Yalnızca size ait dosyaları kaldırabilir", + "deleteSharedAlbum": "Paylaşılan albüm silinsin mi?", + "deleteAlbum": "Albümü sil", + "deleteAlbumDialog": "Ayrıca bu albümde bulunan fotoğrafları (ve videoları) parçası oldukları tüm diğer albümlerden silebilir miyim?", + "deleteSharedAlbumDialogBody": "Albüm herkes için silinecek\n\nBu albümdeki başkalarına ait paylaşılan fotoğraflara erişiminizi kaybedeceksiniz", + "yesRemove": "Evet, sil", + "creatingLink": "Bağlantı oluşturuluyor...", + "removeWithQuestionMark": "Kaldır?", + "removeParticipantBody": "{userEmail} bu paylaşılan albümden kaldırılacaktır\n\nOnlar tarafından eklenen tüm fotoğraflar da albümden kaldırılacaktır", + "keepPhotos": "Fotoğrafları sakla", + "deletePhotos": "Fotoğrafları sil", + "inviteToEnte": "Invite to Ente", + "removePublicLink": "Herkese açık link oluştur", + "disableLinkMessage": "Bu, \"{albumName}\"e erişim için olan genel bağlantıyı kaldıracaktır.", + "sharing": "Paylaşılıyor...", + "youCannotShareWithYourself": "Kendinizle paylaşamazsınız", + "archive": "Arşiv", + "createAlbumActionHint": "Fotoğrafları seçmek için uzun basın ve + düğmesine tıklayarak bir albüm oluşturun", + "importing": "İçeri aktarılıyor....", + "failedToLoadAlbums": "Albüm yüklenirken hata oluştu", + "hidden": "Gizle", + "authToViewYourHiddenFiles": "Gizli dosyalarınızı görüntülemek için kimlik doğrulama yapınız", + "trash": "Cöp kutusu", + "uncategorized": "Kategorisiz", + "videoSmallCase": "video", + "photoSmallCase": "fotoğraf", + "singleFileDeleteHighlight": "Tüm albümlerden silinecek.", + "singleFileInBothLocalAndRemote": "This {fileType} is in both Ente and your device.", + "singleFileInRemoteOnly": "This {fileType} will be deleted from Ente.", + "singleFileDeleteFromDevice": "Bu {fileType}, cihazınızdan silinecek.", + "deleteFromEnte": "Delete from Ente", + "yesDelete": "Evet, sil", + "movedToTrash": "Cöp kutusuna taşı", + "deleteFromDevice": "Cihazınızdan silin", + "deleteFromBoth": "Her ikisinden de sil", + "newAlbum": "Yeni albüm", + "albums": "Albümler", + "memoryCount": "{count, plural, zero{anı yok} \none{{formattedCount} anı} \nother{{formattedCount} anılar}}", + "@memoryCount": { + "description": "The text to display the number of memories", + "type": "text", + "placeholders": { + "count": { + "example": "1", + "type": "int" + }, + "formattedCount": { + "type": "String", + "example": "11.513, 11,511" + } + } + }, + "selectedPhotos": "{count} seçildi", + "@selectedPhotos": { + "description": "Display the number of selected photos", + "type": "text", + "placeholders": { + "count": { + "example": "5", + "type": "int" + } + } + }, + "selectedPhotosWithYours": "Seçilenler: {count} ({yourCount} sizin seçiminiz)", + "@selectedPhotosWithYours": { + "description": "Display the number of selected photos, including the number of selected photos owned by the user", + "type": "text", + "placeholders": { + "count": { + "example": "12", + "type": "int" + }, + "yourCount": { + "example": "2", + "type": "int" + } + } + }, + "advancedSettings": "Gelişmiş", + "@advancedSettings": { + "description": "The text to display in the advanced settings section" + }, + "photoGridSize": "Fotoğraf ızgara boyutu", + "manageDeviceStorage": "Cihaz depolamasını yönet", + "machineLearning": "Makine öğrenimi", + "magicSearch": "Sihirli arama", + "mlIndexingDescription": "Please note that machine learning will result in a higher bandwidth and battery usage until all items are indexed.", + "loadingModel": "Modeller indiriliyor...", + "waitingForWifi": "WiFi bekleniyor...", + "status": "Durum", + "indexedItems": "Yeni öğeleri indeksle", + "pendingItems": "Bekleyen Öğeler", + "clearIndexes": "Açık Dizin", + "selectFoldersForBackup": "Yedekleme için klasörleri seçin", + "selectedFoldersWillBeEncryptedAndBackedUp": "Seçilen klasörler şifrelenecek ve yedeklenecektir", + "unselectAll": "Tümünün seçimini kaldır", + "selectAll": "Hepsini seç", + "skip": "Geç", + "updatingFolderSelection": "Klasör seçimi güncelleniyor...", + "itemCount": "{count,plural, one{{count} öğe} other{{count} öğeler}}", + "deleteItemCount": "{count, plural, =1 {Delete {count} item} other {Delete {count} items}}", + "duplicateItemsGroup": "{count} dosyalar, {formattedSize} her biri", + "@duplicateItemsGroup": { + "description": "Display the number of duplicate files and their size", + "type": "text", + "placeholders": { + "count": { + "example": "12", + "type": "int" + }, + "formattedSize": { + "example": "2.3 MB", + "type": "String" + } + } + }, + "showMemories": "Anıları göster", + "yearsAgo": "{count, plural, one{{count} yıl önce} other{{count} yıl önce}}", + "backupSettings": "Yedekleme seçenekleri", + "backupOverMobileData": "Mobil veri ile yedekle", + "backupVideos": "Videolari yedekle", + "disableAutoLock": "Otomatik kilidi devre dışı bırak", + "deviceLockExplanation": "Disable the device screen lock when Ente is in the foreground and there is a backup in progress. This is normally not needed, but may help big uploads and initial imports of large libraries complete faster.", + "about": "Hakkında", + "weAreOpenSource": "Biz açık kaynağız!", + "privacy": "Gizlilik", + "terms": "Şartlar", + "checkForUpdates": "Güncellemeleri kontol et", + "checkStatus": "Check status", + "checking": "Kontrol ediliyor...", + "youAreOnTheLatestVersion": "En son sürüme sahipsiniz", + "account": "Hesap", + "manageSubscription": "Abonelikleri yönet", + "authToChangeYourEmail": "E-postanızı değiştirmek için lütfen kimlik doğrulaması yapın", + "changePassword": "Sifrenizi değiştirin", + "authToChangeYourPassword": "Şifrenizi değiştirmek için lütfen kimlik doğrulaması yapın", + "emailVerificationToggle": "E-posta doğrulama", + "authToChangeEmailVerificationSetting": "E-posta doğrulamasını değiştirmek için lütfen kimlik doğrulaması yapın", + "exportYourData": "Veriyi dışarı aktar", + "logout": "Çıkış yap", + "authToInitiateAccountDeletion": "Hesap silme işlemini başlatmak için lütfen kimlik doğrulaması yapın", + "areYouSureYouWantToLogout": "Çıkış yapmak istediğinize emin misiniz?", + "yesLogout": "Evet, oturumu kapat", + "aNewVersionOfEnteIsAvailable": "A new version of Ente is available.", + "update": "Güncelle", + "installManually": "Manuel kurulum", + "criticalUpdateAvailable": "Kritik güncelleme mevcut", + "updateAvailable": "Güncelleme mevcut", + "ignoreUpdate": "Yoksay", + "downloading": "İndiriliyor...", + "cannotDeleteSharedFiles": "Dosyalar silinemiyor", + "theDownloadCouldNotBeCompleted": "İndirme işlemi tamamlanamadı", + "retry": "Tekrar dene", + "backedUpFolders": "Yedeklenmiş klasörler", + "backup": "Yedekle", + "freeUpDeviceSpace": "Cihaz alanını boşaltın", + "freeUpDeviceSpaceDesc": "Save space on your device by clearing files that have been already backed up.", + "allClear": "✨ Tamamen temizle", + "noDeviceThatCanBeDeleted": "Bu cihazda silinebilecek hiçbir dosyanız yok", + "removeDuplicates": "Yinelenenleri kaldır", + "removeDuplicatesDesc": "Review and remove files that are exact duplicates.", + "viewLargeFiles": "Large files", + "viewLargeFilesDesc": "View files that are consuming the most amount of storage", + "noDuplicates": "Yinelenenleri kaldır", + "youveNoDuplicateFilesThatCanBeCleared": "Temizlenebilecek yinelenen dosyalarınız yok", + "success": "Başarılı", + "rateUs": "Bizi değerlendirin", + "remindToEmptyDeviceTrash": "Ayrıca boşalan alanı talep etmek için \"Ayarlar\" -> \"Depolama\" bölümünden \"Son Silinenler \"i boşaltın", + "youHaveSuccessfullyFreedUp": "Başarılı bir şekilde {storageSaved} alanını boşalttınız!", + "@youHaveSuccessfullyFreedUp": { + "description": "The text to display when the user has successfully freed up storage", + "type": "text", + "placeholders": { + "storageSaved": { + "example": "1.2 GB", + "type": "String" + } + } + }, + "remindToEmptyEnteTrash": "Ayrıca boşalan alana sahip olmak için \"Çöp Kutunuzu\" boşaltın", + "sparkleSuccess": "✨ Başarılı", + "duplicateFileCountWithStorageSaved": "You have cleaned up {count, plural, one{{count} duplicate file} other{{count} duplicate files}}, saving ({storageSaved}!)", + "@duplicateFileCountWithStorageSaved": { + "description": "The text to display when the user has successfully cleaned up duplicate files", + "type": "text", + "placeholders": { + "count": { + "example": "1", + "type": "int" + }, + "storageSaved": { + "example": "1.2 GB", + "type": "String" + } + } + }, + "familyPlans": "Aile Planı", + "referrals": "Referanslar", + "notifications": "Bildirimler", + "sharedPhotoNotifications": "Paylaşılan fotoğrafları ekle", + "sharedPhotoNotificationsExplanation": "Birisi sizin de parçası olduğunuz paylaşılan bir albüme fotoğraf eklediğinde bildirim alın", + "advanced": "Gelişmiş", + "general": "Genel", + "security": "Güvenlik", + "authToViewYourRecoveryKey": "Kurtarma anahtarınızı görmek için lütfen kimliğinizi doğrulayın", + "twofactor": "İki faktör", + "authToConfigureTwofactorAuthentication": "İki faktörlü kimlik doğrulamayı yapılandırmak için lütfen kimlik doğrulaması yapın", + "lockscreen": "Kilit ekranı", + "authToChangeLockscreenSetting": "Kilit ekranı ayarını değiştirmek için lütfen kimliğinizi doğrulayın", + "lockScreenEnablePreSteps": "Kilit ekranını aktif etmek için lütfen cihazın ayarlarından şifreyi ya da ekran kilidini ayarlayın.", + "viewActiveSessions": "Aktif oturumları görüntüle", + "authToViewYourActiveSessions": "Aktif oturumlarınızı görüntülemek için lütfen kimliğinizi doğrulayın", + "disableTwofactor": "İki Aşamalı Doğrulamayı Devre Dışı Bırak", + "confirm2FADisable": "İki adımlı kimlik doğrulamasını devre dışı bırakmak istediğinize emin misiniz?", + "no": "Hayır", + "yes": "Evet", + "social": "Sosyal Medya", + "rateUsOnStore": "Bizi {storeName} üzerinden değerlendirin", + "blog": "Blog", + "merchandise": "Ürünler", + "twitter": "Twitter", + "mastodon": "Mastodon", + "matrix": "Matrix", + "discord": "Discord", + "reddit": "Reddit", + "yourStorageDetailsCouldNotBeFetched": "Depolama bilgisi alınamadı", + "reportABug": "Hatayı bildir", + "reportBug": "Hata bildir", + "suggestFeatures": "Özellik önerin", + "support": "Destek", + "theme": "Tema", + "lightTheme": "Aydınlık", + "darkTheme": "Karanlık", + "systemTheme": "Sistem", + "freeTrial": "Ücretsiz deneme", + "selectYourPlan": "Planınızı seçin", + "enteSubscriptionPitch": "Ente preserves your memories, so they're always available to you, even if you lose your device.", + "enteSubscriptionShareWithFamily": "Aileniz de planınıza eklenebilir.", + "currentUsageIs": "Güncel kullanımınız ", + "@currentUsageIs": { + "description": "This text is followed by storage usage", + "examples": { + "0": "Current usage is 1.2 GB" + }, + "type": "text" + }, + "faqs": "Sık sorulanlar", + "renewsOn": "Abonelik {endDate} tarihinde yenilenir", + "freeTrialValidTill": "Ücretsiz deneme {endDate} sona erir", + "validTill": "{endDate} tarihine kadar geçerli", + "addOnValidTill": "{storageAmount} eklentiniz {endDate} tarihine kadar geçerlidir", + "playStoreFreeTrialValidTill": "Free trial valid till {endDate}.\nYou can choose a paid plan afterwards.", + "subWillBeCancelledOn": "Aboneliğiniz {endDate} tarihinde iptal edilecektir", + "subscription": "Abonelik", + "paymentDetails": "Ödeme detayları", + "manageFamily": "Aileyi yönet", + "contactToManageSubscription": "Lütfen {provider} aboneliğinizi yönetmek için support@ente.io adresinden bizimle iletişime geçin.", + "renewSubscription": "Abonelik yenileme", + "cancelSubscription": "Abonelik iptali", + "areYouSureYouWantToRenew": "Yenilemek istediğinize emin misiniz?", + "yesRenew": "Evet, yenile", + "areYouSureYouWantToCancel": "İptal etmek istediğinize emin misiniz?", + "yesCancel": "Evet, iptal et", + "failedToRenew": "Abonelik yenilenirken hata oluştu", + "failedToCancel": "İptal edilirken sorun oluştu", + "twoMonthsFreeOnYearlyPlans": "Yıllık planlarda 2 ay ücretsiz", + "monthly": "Aylık", + "@monthly": { + "description": "The text to display for monthly plans", + "type": "text" + }, + "yearly": "Yıllık", + "@yearly": { + "description": "The text to display for yearly plans", + "type": "text" + }, + "confirmPlanChange": "Plan değişikliğini onaylayın", + "areYouSureYouWantToChangeYourPlan": "Planı değistirmek istediğinize emin misiniz?", + "youCannotDowngradeToThisPlan": "Bu plana geçemezsiniz", + "cancelOtherSubscription": "Lütfen önce mevcut aboneliğinizi {paymentProvider} adresinden iptal edin", + "@cancelOtherSubscription": { + "description": "The text to display when the user has an existing subscription from a different payment provider", + "type": "text", + "placeholders": { + "paymentProvider": { + "example": "Apple", + "type": "String" + } + } + }, + "optionalAsShortAsYouLike": "İsteğe bağlı, istediğiniz kadar kısa...", + "send": "Gönder", + "askCancelReason": "Aboneliğiniz iptal edilmiştir. Bunun sebebini paylaşmak ister misiniz?", + "thankYouForSubscribing": "Abone olduğunuz için teşekkürler!", + "yourPurchaseWasSuccessful": "Satın alım başarılı", + "yourPlanWasSuccessfullyUpgraded": "Planınız başarılı şekilde yükseltildi", + "yourPlanWasSuccessfullyDowngraded": "Planınız başarıyla düşürüldü", + "yourSubscriptionWasUpdatedSuccessfully": "Aboneliğiniz başarıyla güncellendi", + "googlePlayId": "Google play kimliği", + "appleId": "Apple kimliği", + "playstoreSubscription": "PlayStore aboneliği", + "appstoreSubscription": "PlayStore aboneliği", + "subAlreadyLinkedErrMessage": "Your {id} is already linked to another Ente account.\nIf you would like to use your {id} with this account, please contact our support''", + "visitWebToManage": "Aboneliğinizi yönetmek için lütfen web.ente.io adresini ziyaret edin", + "couldNotUpdateSubscription": "Abonelikler kaydedilemedi", + "pleaseContactSupportAndWeWillBeHappyToHelp": "Lütfen support@ente.io ile iletişime geçin; size yardımcı olmaktan memnuniyet duyarız!", + "paymentFailed": "Ödeme başarısız oldu", + "paymentFailedTalkToProvider": "Sizden ücret alındıysa lütfen {providerName} destek ekibiyle görüşün", + "@paymentFailedTalkToProvider": { + "description": "The text to display when the payment failed", + "type": "text", + "placeholders": { + "providerName": { + "example": "AppStore|PlayStore", + "type": "String" + } + } + }, + "continueOnFreeTrial": "Ücretsiz denemeye devam et", + "areYouSureYouWantToExit": "Çıkmak istediğinden emin misin?", + "thankYou": "Teşekkürler", + "failedToVerifyPaymentStatus": "Ödeme durumu doğrulanamadı", + "pleaseWaitForSometimeBeforeRetrying": "Tekrar denemeden önce lütfen bir süre bekleyin", + "paymentFailedMessage": "Maalesef ödemeniz başarısız oldu. Lütfen destekle iletişime geçin, size yardımcı olacağız!", + "youAreOnAFamilyPlan": "Aile planı kullanıyorsunuz!", + "contactFamilyAdmin": "Aboneliğinizi yönetmek için lütfen {familyAdminEmail} ile iletişime geçin", + "leaveFamily": "Aile planından ayrıl", + "areYouSureThatYouWantToLeaveTheFamily": "Aile planından ayrılmak istediğinize emin misiniz?", + "leave": "Çıkış yap", + "rateTheApp": "Uygulamaya puan verin", + "startBackup": "Yedeklemeyi başlat", + "noPhotosAreBeingBackedUpRightNow": "Şu anda hiçbir fotoğraf yedeklenmiyor", + "preserveMore": "Daha fazlasını koruyun", + "grantFullAccessPrompt": "Lütfen Ayarlar uygulamasında tüm fotoğraflara erişime izin verin", + "openSettings": "Ayarları Açın", + "selectMorePhotos": "Daha Fazla Fotoğraf Seç", + "existingUser": "Mevcut kullanıcı", + "privateBackups": "Özel yedeklemeler", + "forYourMemories": "anıların için", + "endtoendEncryptedByDefault": "Varsayılan olarak uçtan uca şifrelenmiş", + "safelyStored": "Güvenle saklanır", + "atAFalloutShelter": "serpinti sığınağında", + "designedToOutlive": "Hayatta kalmak için tasarlandı", + "available": "Mevcut", + "everywhere": "her yerde", + "androidIosWebDesktop": "Android, iOS, Web, Masaüstü", + "mobileWebDesktop": "Mobil, Web, Masaüstü", + "newToEnte": "New to Ente", + "pleaseLoginAgain": "Lütfen tekrar giriş yapın", + "autoLogoutMessage": "Due to technical glitch, you have been logged out. Our apologies for the inconvenience.", + "yourSubscriptionHasExpired": "Aboneliğinizin süresi doldu", + "storageLimitExceeded": "Depolama sınırı aşıldı", + "upgrade": "Yükselt", + "raiseTicket": "Bileti artır", + "@raiseTicket": { + "description": "Button text for raising a support tickets in case of unhandled errors during backup", + "type": "text" + }, + "backupFailed": "Yedekleme başarısız oldu", + "couldNotBackUpTryLater": "Verilerinizi yedekleyemedik.\nDaha sonra tekrar deneyeceğiz.", + "enteCanEncryptAndPreserveFilesOnlyIfYouGrant": "Ente can encrypt and preserve files only if you grant access to them", + "pleaseGrantPermissions": "Lütfen izin ver", + "grantPermission": "İzinleri değiştir", + "privateSharing": "Özel paylaşım", + "shareOnlyWithThePeopleYouWant": "Yalnızca istediğiniz kişilerle paylaşın", + "usePublicLinksForPeopleNotOnEnte": "Use public links for people not on Ente", + "allowPeopleToAddPhotos": "Kullanıcıların fotoğraf eklemesine izin ver", + "shareAnAlbumNow": "Şimdi bir albüm paylaşın", + "collectEventPhotos": "Etkinlik fotoğraflarını topla", + "sessionExpired": "Oturum süresi doldu", + "loggingOut": "Çıkış yapılıyor...", + "@onDevice": { + "description": "The text displayed above folders/albums stored on device", + "type": "text" + }, + "onDevice": "Bu cihaz", + "@onEnte": { + "description": "The text displayed above albums backed up to Ente", + "type": "text" + }, + "onEnte": "ente üzerinde", + "name": "İsim", + "newest": "En yeni", + "lastUpdated": "En son güncellenen", + "deleteEmptyAlbums": "Boş albümleri sil", + "deleteEmptyAlbumsWithQuestionMark": "Boş albümleri sileyim mi?", + "deleteAlbumsDialogBody": "Bu, tüm boş albümleri silecektir. Bu, albüm listenizdeki dağınıklığı azaltmak istediğinizde kullanışlıdır.", + "deleteProgress": "Siliniyor {currentlyDeleting} / {totalCount}", + "genericProgress": "Siliniyor {currentlyProcessing} / {totalCount}", + "@genericProgress": { + "description": "Generic progress text to display when processing multiple items", + "type": "text", + "placeholders": { + "currentlyProcessing": { + "example": "1", + "type": "int" + }, + "totalCount": { + "example": "10", + "type": "int" + } + } + }, + "permanentlyDelete": "Kalıcı olarak sil", + "canOnlyCreateLinkForFilesOwnedByYou": "Yalnızca size ait dosyalar için bağlantı oluşturabilir", + "publicLinkCreated": "Herkese açık link oluşturuldu", + "youCanManageYourLinksInTheShareTab": "Bağlantılarınızı paylaşım sekmesinden yönetebilirsiniz.", + "linkCopiedToClipboard": "Link panoya kopyalandı", + "restore": "Yenile", + "@restore": { + "description": "Display text for an action which triggers a restore of item from trash", + "type": "text" + }, + "moveToAlbum": "Albüme taşı", + "unhide": "Gizleme", + "unarchive": "Arşivden cıkar", + "favorite": "Favori", + "removeFromFavorite": "Favorilerimden kaldır", + "shareLink": "Linki paylaş", + "createCollage": "Kolaj oluştur", + "saveCollage": "Kolajı kaydet", + "collageSaved": "Kolajınız galeriye kaydedildi", + "collageLayout": "Düzen", + "addToEnte": "Add to Ente", + "addToAlbum": "Albüme ekle", + "delete": "Sil", + "hide": "Gizle", + "share": "Paylaş", + "unhideToAlbum": "Albümü gizleme", + "restoreToAlbum": "Albümü yenile", + "moveItem": "{count, plural, one {Öğeyi taşı} other {Öğeleri taşı}}", + "@moveItem": { + "description": "Page title while moving one or more items to an album" + }, + "addItem": "{count, plural, one {Öğeyi taşı} other {Öğeleri taşı}}", + "@addItem": { + "description": "Page title while adding one or more items to album" + }, + "createOrSelectAlbum": "Albüm oluştur veya seç", + "selectAlbum": "Albüm seçin", + "searchByAlbumNameHint": "Albüm adı", + "albumTitle": "Albüm Başlığı", + "enterAlbumName": "Bir albüm adı girin", + "restoringFiles": "Dosyalar geri yükleniyor...", + "movingFilesToAlbum": "Dosyalar albüme taşınıyor...", + "unhidingFilesToAlbum": "Albümdeki dosyalar gösteriliyor", + "canNotUploadToAlbumsOwnedByOthers": "Başkalarına ait albümlere yüklenemez", + "uploadingFilesToAlbum": "Dosyalar albüme taşınıyor...", + "addedSuccessfullyTo": "{albumName} albümüne başarıyla eklendi", + "movedSuccessfullyTo": "{albumName} adlı albüme başarıyla taşındı", + "thisAlbumAlreadyHDACollaborativeLink": "Bu albümde zaten bir ortak çalışma bağlantısı var", + "collaborativeLinkCreatedFor": "{albumName} için ortak çalışma bağlantısı oluşturuldu", + "askYourLovedOnesToShare": "Sevdiklerinizden paylaşmalarını isteyin", + "invite": "Davet et", + "shareYourFirstAlbum": "İlk albümünüzü paylaşın", + "sharedWith": "{emailIDs} ile paylaşıldı", + "sharedWithMe": "Benimle paylaşılan", + "sharedByMe": "Benim paylaştıklarım", + "doubleYourStorage": "Depolama alanınızı ikiye katlayın", + "referFriendsAnd2xYourPlan": "Arkadaşlarınıza önerin ve planınızı 2 katına çıkarın", + "shareAlbumHint": "Bir albüm açın ve paylaşmak için sağ üstteki paylaş düğmesine dokunun.", + "itemsShowTheNumberOfDaysRemainingBeforePermanentDeletion": "Öğeler, kalıcı olarak silinmeden önce kalan gün sayısını gösterir", + "trashDaysLeft": "{count, plural, =0{gün} =1{1 gün} other{{count} gün}}", + "@trashDaysLeft": { + "description": "Text to indicate number of days remaining before permanent deletion", + "placeholders": { + "count": { + "example": "1|2|3", + "type": "int" + } + } + }, + "deleteAll": "Hepsini Sil", + "renameAlbum": "Albümü yeniden adlandır", + "convertToAlbum": "Albüme taşı", + "setCover": "Kapak Belirle", + "@setCover": { + "description": "Text to set cover photo for an album" + }, + "sortAlbumsBy": "Sırala", + "sortNewestFirst": "Yeniden eskiye", + "sortOldestFirst": "Önce en eski", + "rename": "Yeniden adlandır", + "leaveSharedAlbum": "Paylaşılan albüm silinsin mi?", + "leaveAlbum": "Albümü yeniden adlandır", + "photosAddedByYouWillBeRemovedFromTheAlbum": "Eklediğiniz fotoğraflar albümden kaldırılacak", + "youveNoFilesInThisAlbumThatCanBeDeleted": "Bu cihazda silinebilecek hiçbir dosyanız yok", + "youDontHaveAnyArchivedItems": "Arşivlenmiş öğeniz yok.", + "ignoredFolderUploadReason": "Some files in this album are ignored from upload because they had previously been deleted from Ente.", + "resetIgnoredFiles": "Yok sayılan dosyaları sıfırla", + "deviceFilesAutoUploading": "Files added to this device album will automatically get uploaded to Ente.", + "turnOnBackupForAutoUpload": "Turn on backup to automatically upload files added to this device folder to Ente.", + "noHiddenPhotosOrVideos": "Gizli fotoğraf veya video yok", + "toHideAPhotoOrVideo": "Bir fotoğrafı veya videoyu gizlemek için", + "openTheItem": "• Öğeyi açın", + "clickOnTheOverflowMenu": "• Taşma menüsüne tıklayın", + "click": "• Tıklamak", + "nothingToSeeHere": "Burada görülecek bir şey yok! 👀", + "unarchiveAlbum": "Arşivden Çıkar", + "archiveAlbum": "Albümü arşivle", + "calculating": "Hesaplanıyor...", + "pleaseWaitDeletingAlbum": "Lütfen bekleyin, albüm siliniyor", + "searchByExamples": "• Albüm adları (ör. \"Kamera\")\n• Dosya türleri (ör. \"Videolar\", \".gif\")\n• Yıllar ve aylar (ör. \"2022\", \"Ocak\")\n• Tatiller (ör. \"Noel\")\n• Fotoğraf açıklamaları (ör. \"#eğlence\")", + "youCanTrySearchingForADifferentQuery": "Farklı bir sorgu aramayı deneyebilirsiniz.", + "noResultsFound": "Hiçbir sonuç bulunamadı", + "addedBy": "{emailOrName} tarafından eklendi", + "loadingExifData": "EXIF verileri yükleniyor...", + "viewAllExifData": "Tüm EXIF verilerini görüntüle", + "noExifData": "EXIF verisi yok", + "thisImageHasNoExifData": "Bu görselde exif verisi yok", + "exif": "EXIF", + "noResults": "Sonuç bulunamadı", + "weDontSupportEditingPhotosAndAlbumsThatYouDont": "Henüz sahibi olmadığınız fotoğraf ve albümlerin düzenlenmesini desteklemiyoruz", + "failedToFetchOriginalForEdit": "Düzenleme için orijinal getirilemedi", + "close": "Kapat", + "setAs": "Şu şekilde ayarla", + "fileSavedToGallery": "Video galeriye kaydedildi", + "filesSavedToGallery": "Files saved to gallery", + "fileFailedToSaveToGallery": "Dosya galeriye kaydedilemedi", + "download": "İndir", + "pressAndHoldToPlayVideo": "Videoları yönetmek için basılı tutun", + "pressAndHoldToPlayVideoDetailed": "Videoyu oynatmak için resmi basılı tutun", + "downloadFailed": "İndirme başarısız", + "deduplicateFiles": "Dosyaları Tekilleştirme", + "deselectAll": "Tüm seçimi kaldır", + "reviewDeduplicateItems": "Lütfen kopya olduğunu düşündüğünüz öğeleri inceleyin ve silin.", + "clubByCaptureTime": "Yakalama zamanına göre kulüp", + "clubByFileName": "Dosya adına göre kulüp", + "count": "Miktar", + "totalSize": "Toplam boyut", + "longpressOnAnItemToViewInFullscreen": "Tam ekranda görüntülemek için bir öğeye uzun basın", + "decryptingVideo": "Videonun şifresi çözülüyor...", + "authToViewYourMemories": "Kodlarınızı görmek için lütfen kimlik doğrulaması yapın", + "unlock": "Kilidi aç", + "freeUpSpace": "Boş alan", + "freeUpSpaceSaving": "{count, plural, one {Yer açmak için cihazdan silinebilir {formattedSize}} other {Yer açmak için cihazdan silinebilir {formattedSize}}}", + "filesBackedUpInAlbum": "Bu albümdeki {count, plural, one {1 file} other {{formattedNumber} dosya}} güvenli bir şekilde yedeklendi", + "@filesBackedUpInAlbum": { + "description": "Text to tell user how many files have been backed up in the album", + "placeholders": { + "count": { + "example": "1", + "type": "int" + }, + "formattedNumber": { + "content": "{formattedNumber}", + "example": "1,000", + "type": "String" + } + } + }, + "filesBackedUpFromDevice": "Bu cihazdaki {count, plural, one {1 file} other {{formattedNumber} dosya}} güvenli bir şekilde yedeklendi", + "@filesBackedUpFromDevice": { + "description": "Text to tell user how many files have been backed up from this device", + "placeholders": { + "count": { + "example": "1", + "type": "int" + }, + "formattedNumber": { + "content": "{formattedNumber}", + "example": "1,000", + "type": "String" + } + } + }, + "@freeUpSpaceSaving": { + "description": "Text to tell user how much space they can free up by deleting items from the device" + }, + "freeUpAccessPostDelete": "You can still access {count, plural, one {it} other {them}} on Ente as long as you have an active subscription", + "@freeUpAccessPostDelete": { + "placeholders": { + "count": { + "example": "1", + "type": "int" + } + } + }, + "freeUpAmount": "{sizeInMBorGB} yer açın", + "thisEmailIsAlreadyInUse": "Bu e-posta zaten kullanılıyor", + "incorrectCode": "Yanlış kod", + "authenticationFailedPleaseTryAgain": "Kimlik doğrulama başarısız oldu, lütfen tekrar deneyin", + "verificationFailedPleaseTryAgain": "Doğrulama başarısız oldu, lütfen tekrar deneyin", + "authenticating": "Kimlik doğrulanıyor...", + "authenticationSuccessful": "Kimlik doğrulama başarılı!", + "incorrectRecoveryKey": "Yanlış kurtarma kodu", + "theRecoveryKeyYouEnteredIsIncorrect": "Girdiğiniz kurtarma kodu yanlış", + "twofactorAuthenticationSuccessfullyReset": "İki faktörlü kimlik doğrulama başarıyla sıfırlandı", + "pleaseVerifyTheCodeYouHaveEntered": "Lütfen girdiğiniz kodu doğrulayın", + "pleaseContactSupportIfTheProblemPersists": "Bu hata devam ederse lütfen desteğe başvurun", + "twofactorAuthenticationHasBeenDisabled": "İki faktörlü kimlik doğrulama devre dışı", + "sorryTheCodeYouveEnteredIsIncorrect": "Üzgünüz, girdiğiniz kod yanlış", + "yourVerificationCodeHasExpired": "Doğrulama kodunuzun süresi doldu", + "emailChangedTo": "E-posta {newEmail} olarak değiştirildi", + "verifying": "Doğrulanıyor...", + "disablingTwofactorAuthentication": "İki aşamalı doğrulamayı devre dışı bırak...", + "allMemoriesPreserved": "Tüm anılar saklandı", + "loadingGallery": "Galeri yükleniyor...", + "syncing": "Eşitleniyor...", + "encryptingBackup": "Yedekleme şifreleniyor...", + "syncStopped": "Senkronizasyon durduruldu", + "syncProgress": "{completed}/{total} anı korundu", + "@syncProgress": { + "description": "Text to tell user how many memories have been preserved", + "placeholders": { + "completed": { + "type": "String" + }, + "total": { + "type": "String" + } + } + }, + "archiving": "Arşivleniyor...", + "unarchiving": "Arşivden çıkarılıyor...", + "successfullyArchived": "Başarıyla arşivlendi", + "successfullyUnarchived": "Başarıyla arşivden çıkarıldı", + "renameFile": "Dosyayı yeniden adlandır", + "enterFileName": "Dosya adını girin", + "filesDeleted": "Dosyalar silinmiş", + "selectedFilesAreNotOnEnte": "Selected files are not on Ente", + "thisActionCannotBeUndone": "Bu eylem geri alınamaz", + "emptyTrash": "Çöp kutusu boşaltılsın mı?", + "permDeleteWarning": "Çöp kutusundaki tüm öğeler kalıcı olarak silinecek\n\nBu işlem geri alınamaz", + "empty": "Boşalt", + "couldNotFreeUpSpace": "Yer boşaltılamadı", + "permanentlyDeleteFromDevice": "Cihazdan kalıcı olarak silinsin mi?", + "someOfTheFilesYouAreTryingToDeleteAre": "Silmeye çalıştığınız dosyalardan bazıları yalnızca cihazınızda mevcuttur ve silindiği takdirde kurtarılamaz", + "theyWillBeDeletedFromAllAlbums": "Tüm albümlerden silinecek.", + "someItemsAreInBothEnteAndYourDevice": "Some items are in both Ente and your device.", + "selectedItemsWillBeDeletedFromAllAlbumsAndMoved": "Seçilen öğeler tüm albümlerden silinecek ve çöp kutusuna taşınacak.", + "theseItemsWillBeDeletedFromYourDevice": "Bu öğeler cihazınızdan silinecektir.", + "itLooksLikeSomethingWentWrongPleaseRetryAfterSome": "Bir şeyler ters gitmiş gibi görünüyor. Lütfen bir süre sonra tekrar deneyin. Hata devam ederse, lütfen destek ekibimizle iletişime geçin.", + "error": "Hata", + "tempErrorContactSupportIfPersists": "Bir şeyler ters gitmiş gibi görünüyor. Lütfen bir süre sonra tekrar deneyin. Hata devam ederse, lütfen destek ekibimizle iletişime geçin.", + "networkHostLookUpErr": "Ente'ye bağlanılamıyor. Lütfen ağ ayarlarınızı kontrol edin ve hata devam ederse destek ekibiyle iletişime geçin.", + "networkConnectionRefusedErr": "Ente'ye bağlanılamıyor. Lütfen bir süre sonra tekrar deneyin. Hata devam ederse lütfen desteğe başvurun.", + "cachedData": "Ön belleğe alınan veri", + "clearCaches": "Önbellekleri temizle", + "remoteImages": "Uzaktan Görüntüler", + "remoteVideos": "Uzak videolar", + "remoteThumbnails": "Uzak Küçük Resim", + "pendingSync": "Senkronizasyon bekleniyor", + "localGallery": "Yerel galeri", + "todaysLogs": "Bugünün günlükleri", + "viewLogs": "Günlükleri göster", + "logsDialogBody": "Bu, sorununuzu gidermemize yardımcı olmak için günlükleri gönderecektir. Belirli dosyalarla ilgili sorunların izlenmesine yardımcı olmak için dosya adlarının ekleneceğini lütfen unutmayın.", + "preparingLogs": "Günlük hazırlanıyor...", + "emailYourLogs": "Günlüklerinizi e-postayla gönderin", + "pleaseSendTheLogsTo": "Lütfen günlükleri şu adrese gönderin\n{toEmail}", + "copyEmailAddress": "E-posta adresini kopyala", + "exportLogs": "Günlüğü dışa aktar", + "pleaseEmailUsAt": "Lütfen bize {toEmail} adresinden ulaşın", + "dismiss": "Reddet", + "didYouKnow": "Biliyor musun?", + "loadingMessage": "Fotoğraflarınız yükleniyor...", + "loadMessage1": "Aboneliğinizi ailenizle paylaşabilirsiniz", + "loadMessage2": "Şu ana kadar 30 milyondan fazla anıyı koruduk", + "loadMessage3": "Verilerinizin 3 kopyasını saklıyoruz, biri yer altı serpinti sığınağında", + "loadMessage4": "Tüm uygulamalarımız açık kaynaktır", + "loadMessage5": "Kaynak kodumuz ve şifrelememiz harici olarak denetlenmiştir", + "loadMessage6": "Albümlerinizin bağlantılarını sevdiklerinizle paylaşabilirsiniz", + "loadMessage7": "Mobil uygulamalarımız, tıkladığınız yeni fotoğrafları şifrelemek ve yedeklemek için arka planda çalışır", + "loadMessage8": "web.ente.io'nun mükemmel bir yükleyicisi var", + "loadMessage9": "Verilerinizi güvenli bir şekilde şifrelemek için Xchacha20Poly1305 kullanıyoruz", + "photoDescriptions": "Fotoğraf Açıklaması", + "fileTypesAndNames": "Dosya türleri ve adları", + "location": "Konum", + "moments": "Anlar", + "searchFaceEmptySection": "People will be shown here once indexing is done", + "searchDatesEmptySection": "Tarihe, aya veya yıla göre arama yapın", + "searchLocationEmptySection": "Bir fotoğrafın belli bir yarıçapında çekilen fotoğrafları gruplandırın", + "searchPeopleEmptySection": "İnsanları davet ettiğinizde onların paylaştığı tüm fotoğrafları burada göreceksiniz", + "searchAlbumsEmptySection": "Albümler", + "searchFileTypesAndNamesEmptySection": "Dosya türleri ve adları", + "searchCaptionEmptySection": "Fotoğraf bilgilerini burada hızlı bir şekilde bulmak için \"#trip\" gibi açıklamalar ekleyin", + "language": "Dil", + "selectLanguage": "Dil Seçin", + "locationName": "Konum Adı", + "addLocation": "Konum Ekle", + "groupNearbyPhotos": "Yakındaki fotoğrafları gruplandır", + "kiloMeterUnit": "km", + "addLocationButton": "Ekle", + "radius": "Yarıçap", + "locationTagFeatureDescription": "Bir fotoğrafın belli bir yarıçapında çekilen fotoğrafları gruplandırın", + "galleryMemoryLimitInfo": "Galeride 1000'e kadar anı gösterilir", + "save": "Kaydet", + "centerPoint": "Merkez noktası", + "pickCenterPoint": "Merkez noktasını seçin", + "useSelectedPhoto": "Seçilen fotoğrafı kullan", + "resetToDefault": "Varsayılana sıfırla", + "@resetToDefault": { + "description": "Button text to reset cover photo to default" + }, + "edit": "Düzenle", + "deleteLocation": "Konumu sil", + "rotateLeft": "Sola döndür", + "flip": "Çevir", + "rotateRight": "Sağa döndür", + "saveCopy": "Kopyasını kaydet", + "light": "Aydınlık", + "color": "Renk", + "yesDiscardChanges": "Evet, değişiklikleri sil", + "doYouWantToDiscardTheEditsYouHaveMade": "Yaptığınız düzenlemeleri silmek istiyor musunuz?", + "saving": "Kaydediliyor...", + "editsSaved": "Düzenleme kaydedildi", + "oopsCouldNotSaveEdits": "Hata! Düzenlemeler kaydedilemedi", + "distanceInKMUnit": "km", + "@distanceInKMUnit": { + "description": "Unit for distance in km" + }, + "dayToday": "Bugün", + "dayYesterday": "Dün", + "storage": "Depolama", + "usedSpace": "Kullanılan alan", + "storageBreakupFamily": "Aile", + "storageBreakupYou": "Sen", + "@storageBreakupYou": { + "description": "Label to indicate how much storage you are using when you are part of a family plan" + }, + "storageUsageInfo": "{usedAmount} {usedStorageUnit} / {totalAmount} {totalStorageUnit} kullanıldı", + "@storageUsageInfo": { + "description": "Example: 1.2 GB of 2 GB used or 100 GB or 2TB used" + }, + "availableStorageSpace": "{freeAmount} {storageUnit} free", + "appVersion": "Sürüm: {versionValue}", + "verifyIDLabel": "Doğrula", + "fileInfoAddDescHint": "Bir açıklama ekle...", + "editLocationTagTitle": "Konumu düzenle", + "setLabel": "Ayarla", + "@setLabel": { + "description": "Label of confirm button to add a new custom radius to the radius selector of a location tag" + }, + "setRadius": "Yarıçapı ayarla", + "familyPlanPortalTitle": "Aile", + "familyPlanOverview": "Add 5 family members to your existing plan without paying extra.\n\nEach member gets their own private space, and cannot see each other's files unless they're shared.\n\nFamily plans are available to customers who have a paid Ente subscription.\n\nSubscribe now to get started!", + "androidBiometricHint": "Kimliği doğrula", + "@androidBiometricHint": { + "description": "Hint message advising the user how to authenticate with biometrics. It is used on Android side. Maximum 60 characters." + }, + "androidBiometricNotRecognized": "Tanınmadı. Tekrar deneyin.", + "@androidBiometricNotRecognized": { + "description": "Message to let the user know that authentication was failed. It is used on Android side. Maximum 60 characters." + }, + "androidBiometricSuccess": "Başarılı", + "@androidBiometricSuccess": { + "description": "Message to let the user know that authentication was successful. It is used on Android side. Maximum 60 characters." + }, + "androidCancelButton": "İptal et", + "@androidCancelButton": { + "description": "Message showed on a button that the user can click to leave the current dialog. It is used on Android side. Maximum 30 characters." + }, + "androidSignInTitle": "Kimlik doğrulaması gerekli", + "@androidSignInTitle": { + "description": "Message showed as a title in a dialog which indicates the user that they need to scan biometric to continue. It is used on Android side. Maximum 60 characters." + }, + "androidBiometricRequiredTitle": "Biyometrik gerekli", + "@androidBiometricRequiredTitle": { + "description": "Message showed as a title in a dialog which indicates the user has not set up biometric authentication on their device. It is used on Android side. Maximum 60 characters." + }, + "androidDeviceCredentialsRequiredTitle": "Cihaz kimlik bilgileri gerekli", + "@androidDeviceCredentialsRequiredTitle": { + "description": "Message showed as a title in a dialog which indicates the user has not set up credentials authentication on their device. It is used on Android side. Maximum 60 characters." + }, + "androidDeviceCredentialsSetupDescription": "Cihaz kimlik bilgileri gerekmekte", + "@androidDeviceCredentialsSetupDescription": { + "description": "Message advising the user to go to the settings and configure device credentials on their device. It shows in a dialog on Android side." + }, + "goToSettings": "Ayarlara git", + "@goToSettings": { + "description": "Message showed on a button that the user can click to go to settings pages from the current dialog. It is used on both Android and iOS side. Maximum 30 characters." + }, + "androidGoToSettingsDescription": "Biyometrik kimlik doğrulama cihazınızda ayarlanmamış. Biyometrik kimlik doğrulama eklemek için 'Ayarlar > Güvenlik' bölümüne gidin.", + "@androidGoToSettingsDescription": { + "description": "Message advising the user to go to the settings and configure biometric on their device. It shows in a dialog on Android side." + }, + "iOSLockOut": "Biyometrik kimlik doğrulama devre dışı. Etkinleştirmek için lütfen ekranınızı kilitleyin ve kilidini açın.", + "@iOSLockOut": { + "description": "Message advising the user to re-enable biometrics on their device. It shows in a dialog on iOS side." + }, + "iOSGoToSettingsDescription": "Cihazınızda biyometrik kimlik doğrulama ayarlanmamış. Lütfen telefonunuzda Touch ID veya Face ID'yi etkinleştirin.", + "@iOSGoToSettingsDescription": { + "description": "Message advising the user to go to the settings and configure Biometrics for their device. It shows in a dialog on iOS side." + }, + "iOSOkButton": "Tamam", + "@iOSOkButton": { + "description": "Message showed on a button that the user can click to leave the current dialog. It is used on iOS side. Maximum 30 characters." + }, + "openstreetmapContributors": "© OpenStreetMap katkıda bululanlar", + "hostedAtOsmFrance": "OSM Fransa'da ağırlandı", + "map": "Harita", + "@map": { + "description": "Label for the map view" + }, + "maps": "Haritalar", + "enableMaps": "Haritaları Etkinleştir", + "enableMapsDesc": "Bu, fotoğraflarınızı bir dünya haritasında gösterecektir.\n\nBu harita Open Street Map tarafından barındırılmaktadır ve fotoğraflarınızın tam konumları hiçbir zaman paylaşılmaz.\n\nBu özelliği istediğiniz zaman Ayarlar'dan devre dışı bırakabilirsiniz.", + "quickLinks": "Hızlı Erişim", + "selectItemsToAdd": "Eklenecek eşyaları seçin", + "addSelected": "Seçileni ekle", + "addFromDevice": "Cihazdan ekle", + "addPhotos": "Fotoğraf ekle", + "noPhotosFoundHere": "Burada fotoğraf bulunamadı", + "zoomOutToSeePhotos": "Fotoğrafları görmek için uzaklaştırın", + "noImagesWithLocation": "Konum içeren resim yok", + "unpinAlbum": "Albümün sabitlemesini kaldır", + "pinAlbum": "Albümü sabitle", + "create": "Oluştur", + "viewAll": "Tümünü görüntüle", + "nothingSharedWithYouYet": "Henüz sizinle paylaşılan bir şey yok", + "noAlbumsSharedByYouYet": "Henüz paylaştığınız albüm yok", + "sharedWithYou": "Sizinle paylaşıldı", + "sharedByYou": "Paylaştıklarınız", + "inviteYourFriendsToEnte": "Invite your friends to Ente", + "failedToDownloadVideo": "Video indirilemedi", + "hiding": "Gizleniyor...", + "unhiding": "Gösteriliyor...", + "successfullyHid": "Başarıyla saklandı", + "successfullyUnhid": "Başarıyla arşivden çıkarıldı", + "crashReporting": "Çökme raporlaması", + "addToHiddenAlbum": "Gizli albüme ekle", + "moveToHiddenAlbum": "Gizli albüme ekle", + "fileTypes": "Dosya türü", + "deleteConfirmDialogBody": "This account is linked to other Ente apps, if you use any. Your uploaded data, across all Ente apps, will be scheduled for deletion, and your account will be permanently deleted.", + "hearUsWhereTitle": "Ente'yi nereden duydunuz? (opsiyonel)", + "hearUsExplanation": "Biz uygulama kurulumlarını takip etmiyoruz. Bizi nereden duyduğunuzdan bahsetmeniz bize çok yardımcı olacak!", + "viewAddOnButton": "Eklentileri görüntüle", + "addOns": "Eklentiler", + "addOnPageSubtitle": "Eklentilerin ayrıntıları", + "yourMap": "Haritalarınız", + "modifyYourQueryOrTrySearchingFor": "Sorgunuzu değiştirin veya aramayı deneyin", + "blackFridaySale": "Muhteşem Cuma kampanyası", + "upto50OffUntil4thDec": "4 Aralık'a kadar %50'ye varan indirim.", + "photos": "Fotoğraflar", + "videos": "Videolar", + "livePhotos": "Canlı Fotoğraf", + "searchHint1": "Hızlı, cihaz üzerinde arama", + "searchHint2": "Fotoğraf tarihleri, açıklamalar", + "searchHint3": "Albümler, dosya adları ve türleri", + "searchHint4": "Konum", + "searchHint5": "Çok yakında: Yüzler ve sihirli arama ✨", + "addYourPhotosNow": "Fotoğraflarınızı şimdi ekleyin", + "searchResultCount": "{count, plural, one{{count} yıl önce} other{{count} yıl önce}}", + "@searchResultCount": { + "description": "Text to tell user how many results were found for their search query", + "placeholders": { + "count": { + "example": "1|2|3", + "type": "int" + } + } + }, + "faces": "Yüzler", + "people": "People", + "contents": "İçerikler", + "addNew": "Yeni ekle", + "@addNew": { + "description": "Text to add a new item (location tag, album, caption etc)" + }, + "contacts": "Kişiler", + "noInternetConnection": "İnternet bağlantısı yok", + "pleaseCheckYourInternetConnectionAndTryAgain": "Lütfen internet bağlantınızı kontrol edin ve yeniden deneyin.", + "signOutFromOtherDevices": "Diğer cihazlardan çıkış yap", + "signOutOtherBody": "Eğer başka birisinin parolanızı bildiğini düşünüyorsanız, diğer tüm cihazları hesabınızdan çıkışa zorlayabilirsiniz.", + "signOutOtherDevices": "Diğer cihazlardan çıkış yap", + "doNotSignOut": "Çıkış yapma", + "editLocation": "Konumu düzenle", + "selectALocation": "Bir konum seçin", + "selectALocationFirst": "Önce yeni yer seçin", + "changeLocationOfSelectedItems": "Seçilen öğelerin konumu değiştirilsin mi?", + "editsToLocationWillOnlyBeSeenWithinEnte": "Konumda yapılan düzenlemeler yalnızca Ente'de görülecektir", + "cleanUncategorized": "Temiz Genel", + "cleanUncategorizedDescription": "Diğer albümlerde bulunan Kategorilenmemiş tüm dosyaları kaldırın", + "waitingForVerification": "Doğrulama bekleniyor...", + "passkey": "Parola Anahtarı", + "passkeyAuthTitle": "Geçiş anahtarı doğrulaması", + "passKeyPendingVerification": "Verification is still pending", + "loginSessionExpired": "Session expired", + "loginSessionExpiredDetails": "Your session has expired. Please login again.", + "verifyPasskey": "Şifrenizi doğrulayın", + "playOnTv": "Albümü TV'de oynat", + "pair": "Eşleştir", + "deviceNotFound": "Cihaz bulunamadı", + "castInstruction": "Eşleştirmek istediğiniz cihazda cast.ente.io adresini ziyaret edin.\n\nAlbümü TV'nizde oynatmak için aşağıdaki kodu girin.", + "deviceCodeHint": "Kodu girin", + "joinDiscord": "Discord'a Katıl", + "locations": "Konum", + "descriptions": "Açıklama", + "addAName": "Add a name", + "findPeopleByName": "Find people quickly by name", + "addViewers": "{count, plural, zero {Görüntüleyen ekle} one {Görüntüleyen ekle} other {Görüntüleyen ekle}}", + "addCollaborators": "{count, plural, zero {Ortak çalışan ekle} one {Ortak çalışan ekle} other {Ortak çalışan ekle}}", + "longPressAnEmailToVerifyEndToEndEncryption": "Uçtan uca şifrelemeyi doğrulamak için bir e-postaya uzun basın.", + "developerSettingsWarning": "Geliştirici ayarlarını değiştirmek istediğinizden emin misiniz?", + "developerSettings": "Geliştirici ayarları", + "serverEndpoint": "Sunucu uç noktası", + "invalidEndpoint": "Geçersiz uç nokta", + "invalidEndpointMessage": "Üzgünüz, girdiğiniz uç nokta geçersiz. Lütfen geçerli bir uç nokta girin ve tekrar deneyin.", + "endpointUpdatedMessage": "Fatura başarıyla güncellendi", + "customEndpoint": "{endpoint}'e bağlanıldı", + "createCollaborativeLink": "Create collaborative link", + "search": "Search", + "enterPersonName": "Enter person name", + "removePersonLabel": "Remove person label", + "autoPairDesc": "Auto pair works only with devices that support Chromecast.", + "manualPairDesc": "Pair with PIN works with any screen you wish to view your album on.", + "connectToDevice": "Connect to device", + "autoCastDialogBody": "You'll see available Cast devices here.", + "autoCastiOSPermission": "Make sure Local Network permissions are turned on for the Ente Photos app, in Settings.", + "noDeviceFound": "No device found", + "stopCastingTitle": "Stop casting", + "stopCastingBody": "Do you want to stop casting?", + "castIPMismatchTitle": "Failed to cast album", + "castIPMismatchBody": "Please make sure you are on the same network as the TV.", + "pairingComplete": "Pairing complete", + "savingEdits": "Saving edits...", + "autoPair": "Auto pair", + "pairWithPin": "Pair with PIN", + "faceRecognition": "Face recognition", + "foundFaces": "Found faces", + "clusteringProgress": "Clustering progress", + "indexingIsPaused": "Indexing is paused. It will automatically resume when device is ready.", + "trim": "Trim", + "crop": "Crop", + "rotate": "Rotate", + "left": "Left", + "right": "Right", + "whatsNew": "What's new", + "reviewSuggestions": "Review suggestions", + "useAsCover": "Use as cover", + "notPersonLabel": "Not {name}?", + "@notPersonLabel": { + "description": "Label to indicate that the person in the photo is not the person whose name is mentioned", + "placeholders": { + "name": { + "content": "{name}", + "type": "String" + } + } + }, + "reenterPassword": "Re-enter password", + "reenterPin": "Re-enter PIN", + "deviceLock": "Device lock", + "pinLock": "PIN lock", + "next": "Next", + "setNewPassword": "Set new password", + "enterPin": "Enter PIN", + "setNewPin": "Set new PIN", + "appLock": "App lock", + "noSystemLockFound": "No system lock found", + "toEnableAppLockPleaseSetupDevicePasscodeOrScreen": "To enable app lock, please setup device passcode or screen lock in your system settings.", + "tapToUnlock": "Tap to unlock", + "tooManyIncorrectAttempts": "Too many incorrect attempts" +} \ No newline at end of file diff --git a/mobile/pubspec.lock b/mobile/pubspec.lock index 15a0ac68b3..01969b46d7 100644 --- a/mobile/pubspec.lock +++ b/mobile/pubspec.lock @@ -5,10 +5,10 @@ packages: dependency: transitive description: name: _fe_analyzer_shared - sha256: ae92f5d747aee634b87f89d9946000c2de774be1d6ac3e58268224348cd0101a + sha256: "0b2f2bd91ba804e53a61d757b986f89f1f9eaed5b11e4b2f5a2468d86d6c9fc7" url: "https://pub.dev" source: hosted - version: "61.0.0" + version: "67.0.0" _flutterfire_internals: dependency: transitive description: @@ -29,10 +29,10 @@ packages: dependency: transitive description: name: analyzer - sha256: ea3d8652bda62982addfd92fdc2d0214e5f82e43325104990d4f4c4a2a313562 + sha256: "37577842a27e4338429a1cbc32679d508836510b056f1eedf0c8d20e39c1383d" url: "https://pub.dev" source: hosted - version: "5.13.0" + version: "6.4.1" animate_do: dependency: "direct main" description: @@ -1236,6 +1236,14 @@ packages: url: "https://pub.dev" source: hosted version: "0.18.1" + intl_utils: + dependency: "direct dev" + description: + name: intl_utils + sha256: c2b1f5c72c25512cbeef5ab015c008fc50fe7e04813ba5541c25272300484bf4 + url: "https://pub.dev" + source: hosted + version: "2.8.7" io: dependency: transitive description: diff --git a/mobile/pubspec.yaml b/mobile/pubspec.yaml index 8b2cbcfe43..8608b20fb8 100644 --- a/mobile/pubspec.yaml +++ b/mobile/pubspec.yaml @@ -198,6 +198,7 @@ flutter_intl: dev_dependencies: build_runner: ^2.4.7 + intl_utils: ^2.8.7 flutter_lints: ^2.0.1 flutter_test: sdk: flutter From 7640789f0845c2dc67bab4a464e66968f998a1d4 Mon Sep 17 00:00:00 2001 From: Neeraj Gupta <254676+ua741@users.noreply.github.com> Date: Fri, 12 Jul 2024 14:04:19 +0530 Subject: [PATCH 67/67] [mob] Fix dependencies order --- mobile/pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mobile/pubspec.yaml b/mobile/pubspec.yaml index 8608b20fb8..b187f3c09a 100644 --- a/mobile/pubspec.yaml +++ b/mobile/pubspec.yaml @@ -198,13 +198,13 @@ flutter_intl: dev_dependencies: build_runner: ^2.4.7 - intl_utils: ^2.8.7 flutter_lints: ^2.0.1 flutter_test: sdk: flutter freezed: ^2.5.2 integration_test: sdk: flutter + intl_utils: ^2.8.7 json_serializable: ^6.6.1 test: ^1.22.0