From 43a1c115c5ae709e41bee1b0f11194f027ddb370 Mon Sep 17 00:00:00 2001 From: ildyria Date: Sun, 22 Mar 2026 09:48:46 +0100 Subject: [PATCH 01/10] Frontend wip --- lang/en/people.php | 58 +++++ .../js/components/gallery/PersonCard.vue | 36 +++ .../gallery/photoModule/FaceOverlay.vue | 66 +++++ .../gallery/photoModule/PhotoPanel.vue | 8 + .../components/modals/FaceAssignmentModal.vue | 168 +++++++++++++ resources/js/lychee.d.ts | 30 +++ .../js/services/face-detection-service.ts | 33 +++ resources/js/services/people-service.ts | 56 +++++ resources/js/views/People.vue | 86 +++++++ resources/js/views/PersonDetail.vue | 234 ++++++++++++++++++ 10 files changed, 775 insertions(+) create mode 100644 lang/en/people.php create mode 100644 resources/js/components/gallery/PersonCard.vue create mode 100644 resources/js/components/gallery/photoModule/FaceOverlay.vue create mode 100644 resources/js/components/modals/FaceAssignmentModal.vue create mode 100644 resources/js/services/face-detection-service.ts create mode 100644 resources/js/services/people-service.ts create mode 100644 resources/js/views/People.vue create mode 100644 resources/js/views/PersonDetail.vue diff --git a/lang/en/people.php b/lang/en/people.php new file mode 100644 index 00000000000..7f5dc009ce0 --- /dev/null +++ b/lang/en/people.php @@ -0,0 +1,58 @@ + 'People', + 'description' => 'Browse photos by the people in them.', + 'no_people' => 'No people found yet. Scan some photos to detect faces.', + 'photos_label' => 'photo(s)', + 'faces_label' => 'face(s)', + 'hidden_faces' => 'face(s) hidden for privacy', + 'unknown' => 'Unknown', + 'confidence' => 'Confidence', + 'assign_face' => 'Assign face', + 'dismiss_face' => 'Dismiss face', + 'undismiss_face' => 'Undismiss face', + 'scan_faces' => 'Scan for faces', + 'scanning' => 'Scanning for faces…', + 'scan_success' => 'Face scan queued successfully.', + 'not_searchable' => 'Hidden', + 'searchable' => 'Visible', + 'claim_by_selfie' => 'Find me in photos', + 'claim_by_selfie_description' => 'Upload a selfie to find and link your person profile.', + 'claims' => [ + 'success' => 'Successfully linked to your profile.', + 'no_face' => 'No face detected in the selfie.', + 'no_match' => 'No matching person found.', + 'already_claimed' => 'This person is already linked to another user.', + 'low_confidence' => 'Match confidence too low. Please try a clearer photo.', + ], + 'person' => [ + 'edit' => 'Edit', + 'delete' => 'Delete', + 'merge' => 'Merge into…', + 'toggle_searchable' => 'Toggle visibility', + 'claim' => 'This is me', + 'unclaim' => 'Unlink from me', + 'photos_title' => 'Photos of %s', + ], + 'assignment' => [ + 'title' => 'Assign face to person', + 'select_person' => 'Select existing person…', + 'new_person' => 'Or create new person', + 'new_person_placeholder' => 'New person name…', + 'confirm' => 'Assign', + 'cancel' => 'Cancel', + 'success' => 'Face assigned successfully.', + ], +]; diff --git a/resources/js/components/gallery/PersonCard.vue b/resources/js/components/gallery/PersonCard.vue new file mode 100644 index 00000000000..9a96f28b058 --- /dev/null +++ b/resources/js/components/gallery/PersonCard.vue @@ -0,0 +1,36 @@ + + + + diff --git a/resources/js/components/gallery/photoModule/FaceOverlay.vue b/resources/js/components/gallery/photoModule/FaceOverlay.vue new file mode 100644 index 00000000000..023d85c1900 --- /dev/null +++ b/resources/js/components/gallery/photoModule/FaceOverlay.vue @@ -0,0 +1,66 @@ + + + diff --git a/resources/js/components/gallery/photoModule/PhotoPanel.vue b/resources/js/components/gallery/photoModule/PhotoPanel.vue index 467b548e817..5b449436e1e 100644 --- a/resources/js/components/gallery/photoModule/PhotoPanel.vue +++ b/resources/js/components/gallery/photoModule/PhotoPanel.vue @@ -27,6 +27,13 @@ /> + + +
+ +
+ Face crop +
+ +
+
+
+ {{ $t("people.confidence") }}: {{ Math.round(face.confidence * 100) }}% +
+ + +
+
Suggestions
+
+ +
+
+ + +
+ +