Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
6c4e1f2
Similar Images Cleanup for Desktop/Web initial/naive implementation
korjavin Dec 27, 2025
e48e083
Add caching between page opening.
korjavin Dec 27, 2025
78f8c78
Fix codex suggestions
korjavin Dec 27, 2025
ed73fa8
Implement incremental HNSW index updates for Similar Images
korjavin Jan 5, 2026
bccd7a3
Similar Images Cleanup for Desktop/Web initial/naive implementation
korjavin Dec 27, 2025
d6a8dd2
Add caching between page opening.
korjavin Dec 27, 2025
909d322
Fix codex suggestions
korjavin Dec 27, 2025
db15050
Implement incremental HNSW index updates for Similar Images
korjavin Jan 5, 2026
a4b4185
chore: add sandbox scripts for safer desktop development
korjavin Jan 5, 2026
63f7eb1
feat(desktop): improve similar images UI
korjavin Jan 5, 2026
3441f20
Merge feature/desktop-similar-embeddings into main
korjavin Jan 5, 2026
d34cfaf
chore: remove similar images link from help menu
korjavin Jan 5, 2026
4697968
chore: remove similar images from system help menu
korjavin Jan 5, 2026
9a63c10
fix: allow undefined success return from HNSW readIndex
korjavin Jan 5, 2026
1c283cb
Clean-up
korjavin Jan 7, 2026
07730dc
fix: align similar images threshold values with mobile
claude Jan 14, 2026
ca82576
feat: implement 'Best Photo' logic for similar images retention
claude Jan 14, 2026
fc7e94f
fix: respect item.isSelected and protect favorited files from deletion
claude Jan 14, 2026
69b8dcf
feat: improve empty state messages for similar images categories
claude Jan 14, 2026
94ec604
test: update similar images tests to match new threshold values
claude Jan 14, 2026
018b6f4
docs: clarify readIndex return value handling for HNSW
claude Jan 14, 2026
a930cbb
feat: add loading overlay during similar images deletion
claude Jan 14, 2026
e73b5da
fix(web): add sx prop to ItemCard for styling overrides
korjavin Jan 14, 2026
01cf63c
fix(web): resolve 'collections' variable redeclaration in delete service
korjavin Jan 14, 2026
a3e3954
fix(web): remove unused variables and align similarity threshold to 0.04
korjavin Jan 14, 2026
3f6e0a3
feat(web): implement 'Best Photo' sorting logic for similar groups
korjavin Jan 14, 2026
2ada41a
fix(web): restore missing props destructuring in ItemCard
korjavin Jan 14, 2026
33b93e2
fix(web): use correct 'body' typography variant instead of 'body2'
korjavin Jan 14, 2026
46c1df8
fix(web): resolve ESLint errors and type issues
korjavin Jan 14, 2026
01ba944
Merge pull request #1 from korjavin/claude/address-pr-review-comments…
korjavin Jan 14, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,3 @@
# macOS
.DS_Store

# Ignore CLAUDE.local.md files anywhere in the repository
CLAUDE.local.md
4 changes: 3 additions & 1 deletion desktop/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@
"build:quick": "yarn build-renderer && yarn build-main:quick",
"dev": "concurrently --kill-others --success first --names 'main,rndr' \"yarn dev-main\" \"yarn dev-renderer\"",
"dev-main": "tsc && electron .",
"dev-main:sandbox": "tsc && electron . --user-data-dir=./.sandbox-data",
"dev-renderer": "cross-env-shell _ENTE_IS_DESKTOP=1 \"cd ../web && yarn install && yarn workspace photos next dev -p 3008\"",
"dev:sandbox": "concurrently --kill-others --success first --names 'main,rndr' \"yarn dev-main:sandbox\" \"yarn dev-renderer\"",
"postinstall": "electron-builder install-app-deps",
"lint": "yarn prettier --check --log-level warn . && yarn eslint && yarn tsc",
"lint-fix": "yarn prettier --write --log-level warn . && yarn eslint && yarn tsc",
Expand Down Expand Up @@ -57,4 +59,4 @@
},
"packageManager": "[email protected]",
"productName": "ente"
}
}
7 changes: 6 additions & 1 deletion desktop/src/main/menu.ts
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,12 @@ export const createApplicationMenu = (mainWindow: BrowserWindow) => {
]),
],
},
{ label: "Help", submenu: [{ label: "Ente Help", click: handleHelp }] },
{
label: "Help",
submenu: [
{ label: "Ente Help", click: handleHelp },
],
},
]);
};

Expand Down
11 changes: 11 additions & 0 deletions web/apps/photos/src/components/Sidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,7 @@ export const Sidebar: React.FC<SidebarProps> = ({
onShowExport,
onLogout: handleLogout,
onRouteToDeduplicate: () => router.push("/duplicates"),
onRouteToSimilarImages: () => router.push("/similar-images"),
onShowWatchFolder: handleOpenWatchFolder,
pseudoIDs: {
uncategorized: uncategorizedCollectionSummaryID,
Expand Down Expand Up @@ -380,6 +381,9 @@ export const Sidebar: React.FC<SidebarProps> = ({
onRouteToDeduplicate: () => {
void router.push("/duplicates");
},
onRouteToSimilarImages: () => {
void router.push("/similar-images");
},
}}
/>
<Divider sx={{ my: "2px" }} />
Expand Down Expand Up @@ -768,6 +772,7 @@ type UtilitySectionProps = SectionProps &
pendingHelpAction?: HelpAction;
onHelpActionHandled: (action?: HelpAction) => void;
onRouteToDeduplicate: () => void;
onRouteToSimilarImages: () => void;
};

const UtilitySection: React.FC<UtilitySectionProps> = ({
Expand All @@ -790,6 +795,7 @@ const UtilitySection: React.FC<UtilitySectionProps> = ({
pendingHelpAction,
onHelpActionHandled,
onRouteToDeduplicate,
onRouteToSimilarImages,
}) => {
const { showMiniDialog } = useBaseContext();

Expand Down Expand Up @@ -817,6 +823,11 @@ const UtilitySection: React.FC<UtilitySectionProps> = ({
label={t("deduplicate_files")}
onClick={onRouteToDeduplicate}
/>
<RowButton
variant="secondary"
label={t("similar_images")}
onClick={onRouteToSimilarImages}
/>
<RowButton
variant="secondary"
label={t("preferences")}
Expand Down
1 change: 1 addition & 0 deletions web/apps/photos/src/pages/similar-images.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from "ente-new/photos/pages/similar-images";
23 changes: 22 additions & 1 deletion web/packages/base/locales/en-US/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -727,5 +727,26 @@
"continuous": "Continuous",
"trip": "Trip",
"album_layout": "Album layout",
"maps_privacy_notice": "Approximate coordinates will be sent to privacy conscious third parties like OpenStreetMap to show the map and location."
"maps_privacy_notice": "Approximate coordinates will be sent to privacy conscious third parties like OpenStreetMap to show the map and location.",
"similar_images": "Similar images",
"find_similar_images": "Find similar images",
"no_similar_images_found": "No similar images found",
"your_photos_look_unique": "Your photos look unique",
"similar_groups_found": "{{count, number}} groups found",
"review_and_remove_similar_images": "Review and remove similar images",
"delete_photos_with_size": "Delete {{count, number}} photos ({{size}})",
"similar_images_count": "{{count, number}} similar images",
"similarity": "Similarity",
"analyzing_photos_locally": "Analyzing your photos locally...",
"close_by": "Close by",
"similar": "Similar",
"related": "Related",
"similarity_threshold": "Similarity threshold",
"photos": "photos",
"more": "more",
"remove": "Remove",
"keep": "Keep",
"deleting": "Deleting...",
"select_all_in_groups": "Select all",
"deselect_all_groups": "Deselect all"
}
1 change: 1 addition & 0 deletions web/packages/new/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
"ente-base": "*",
"ente-gallery": "*",
"ente-utils": "*",
"hnswlib-wasm": "^0.8.2",
"react": "^19.2.0",
"react-dom": "^19.2.0"
},
Expand Down
15 changes: 13 additions & 2 deletions web/packages/new/photos/components/Tiles.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
import AddIcon from "@mui/icons-material/Add";
import { Stack, styled, Typography } from "@mui/material";
import {
Stack,
styled,
Typography,
type SxProps,
type Theme,
} from "@mui/material";
import { CenteredFill, Overlay } from "ente-base/components/containers";
import type { ButtonishProps } from "ente-base/components/mui";
import log from "ente-base/log";
Expand Down Expand Up @@ -39,6 +45,10 @@ interface ItemCardProps {
* Optional click handler.
*/
onClick?: () => void;
/**
* Optional styling overrides.
*/
sx?: SxProps<Theme>;
}

/**
Expand All @@ -61,6 +71,7 @@ export const ItemCard: React.FC<React.PropsWithChildren<ItemCardProps>> = ({
coverFaceID,
isScrolling,
onClick,
sx,
children,
}) => {
const [coverImageURL, setCoverImageURL] = useState<string | undefined>();
Expand Down Expand Up @@ -89,7 +100,7 @@ export const ItemCard: React.FC<React.PropsWithChildren<ItemCardProps>> = ({
}, [coverFile, coverFaceID, isScrolling]);

return (
<TileComponent {...{ onClick }}>
<TileComponent {...{ onClick, sx }}>
{coverFile?.metadata.hasStaticThumbnail ? (
<StaticThumbnail fileType={coverFile.metadata.fileType} />
) : coverImageURL ? (
Expand Down
Loading