Conversation
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughThe PR adds the Lychee v8 design system, configurable semantic theme colors, a design-system showcase, shared loading components, improved loading-state handling, face-review workflows, and related interface updates. ChangesLychee v8 design system
Loading and interface behavior
Face workflows
Estimated code review effort: 5 (Critical) | ~120 minutes Poem
🚥 Pre-merge checks | ✅ 1✅ Passed checks (1 passed)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 8
Note
Due to the large number of review comments, Critical, Major severity comments were prioritized as inline comments.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
DESIGN.md (1)
186-189: 📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick winAdd the required "Last updated" footer.
This file is documentation under
**/*.md. Add an hr line followed by "Last updated: [date]" at the bottom of the file. This file currently ends without it.As per coding guidelines: "Use Markdown format for documentation. At the bottom of documentation files, add an hr line followed by "Last updated: [date of the update]"".
📝 Proposed fix
- **Don't** let the interface read as a generic self-hosted admin panel — boxy unstyled tables, default form chrome, or dashboard sprawl for its own sake is the thing this system is explicitly designed against. + +--- +*Last updated: 2026-07-28*Source: Coding guidelines
🟡 Minor comments (14)
ui.todo-52-52 (1)
52-52: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick winFix the typo "LigtBox".
Line 52 has a typo: "LigtBox (lightbox)". Correct it to "LightBox" if that is the actual component name, or align it with the actual component name used in the codebase.
✏️ Proposed fix
-- [ ] Flow view (/flow, /flow/:albumId/:photoId): AlbumCard, CarouselImages, LigtBox (lightbox), +- [ ] Flow view (/flow, /flow/:albumId/:photoId): AlbumCard, CarouselImages, LightBox (lightbox),ui.todo-1-2 (1)
1-2: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick winAdd
NUXT_UI_ENABLEDas a real, testable environment/config entry.
config/features.phpdefines thenuxt_uifeature behindenv('NUXT_UI_ENABLED', false), but there is no usableNUXT_UI_ENABLEDentry in the repo for non-spec files. Add it to.env.exampleor.envso testers can follow the checklist instead of hunting behind the spec docs.Source: Coding guidelines
resources/js/v8/views/App.vue-49-64 (1)
49-64: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick winHonor the reduced-motion preference.
The route transition still runs for users who set
prefers-reduced-motion: reduce. Disable the opacity and transform transition in that media query.Proposed fix
+.@media (prefers-reduced-motion: reduce) { + .lychee-page-enter-active, + .lychee-page-leave-active { + transition: none; + } +}DESIGN.md-27-32 (1)
27-32: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick winFix the inconsistent
lineHeightunit for the label typography token.The
titleandbodytokens use unitless line-height multipliers (1.4, 1.5). Thelabeltoken uses0.8rem, a length value. Use the same unit convention forlineHeightacross all typography tokens.DESIGN.md-4-15 (1)
4-15: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick winAdd the missing flag color to the front-matter
colorsblock.The prose at line 98 describes 5 flag roles: nsfw, trophy, person, rated, and link (public-hidden,
#fb923c). The front-mattercolorsblock only listsflag-nsfw,flag-trophy,flag-person, andflag-rated. Add the missinglink/public-hidden entry so the structured token list matches the documented flag palette.lang/en/all_settings.php-398-405 (1)
398-405: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick winRename the visible
accentterminology.These entries configure
primary_color, but their labels and help text still describe an accent color. Use primary-color terminology consistently.
lang/en/all_settings.php#L398-L405: RenameAccent color.toPrimary color.lang/en/all_settings.php#L795-L802: Replace staleaccent colorreferences withprimary color.lang/en/all_settings.php#L864-L864: Refer to the primary color above.lang/de/all_settings.php#L396-L403: RenameAccent color.toPrimary color.lang/de/all_settings.php#L793-L800: Replace staleaccent colorreferences withprimary color.lang/de/all_settings.php#L860-L860: Refer to the primary color above.lang/el/all_settings.php#L398-L405: RenameAccent color.toPrimary color.lang/el/all_settings.php#L795-L802: Replace staleaccent colorreferences withprimary color.lang/el/all_settings.php#L864-L864: Refer to the primary color above.lang/es/all_settings.php#L396-L403: RenameAccent color.toPrimary color.lang/es/all_settings.php#L793-L800: Replace staleaccent colorreferences withprimary color.lang/es/all_settings.php#L860-L860: Refer to the primary color above.The provided backend context maps the
primarytoken toprimary_color.resources/js/v8/components/LycheeLoadingIcon.vue-55-130 (1)
55-130: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick winHonor reduced-motion preferences.
The loading icon animates indefinitely when the user requests reduced motion. Add a reduced-motion rule that stops the animation and keeps every stage visible.
Proposed fix
+@media (prefers-reduced-motion: reduce) { + .lychee-loading-stage { + animation: none; + opacity: 1; + } +}lang/sk/all_settings.php-833-833 (1)
833-833: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick winUse a snake_case config category key for
Theme Colors.
lang/en/all_settings.phpand each locale duplicate theTheme Colorskey directly fromdatabase/migrations/2026_08_01_000000_add_theme_colors.php::CAT. Rename the sourceCATtotheme_colors, then update the migration and alllang/<locale>/all_settings.phpentries so translation source keys follow the PHP coding-convention requirement.Source: Coding guidelines
lang/zh_TW/all_settings.php-398-398 (1)
398-398: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick winUse
Primary colorconsistently.The key is
primary_color, but Line [398] still displaysAccent color.. Line [795] still describes the fallback as thedefault accent color. This makes the renamed setting ambiguous for administrators. Update both strings to useprimary color, or keep the key nameaccent_colorin every producer and consumer.Proposed wording fix
- 'primary_color' => 'Accent color.', + 'primary_color' => 'Primary color', - 'primary_color' => 'Pick a colour, the nearest colour palette will be used. If you leave this empty, the default accent color will be used.<br>Note: you will need to refresh the page to see the changes.', + 'primary_color' => 'Pick a colour, the nearest colour palette will be used. If you leave this empty, the default primary color will be used.<br>Note: you will need to refresh the page to see the changes.',Also applies to: 795-795
resources/js/v8/components/loading/LoadingProgress.vue-5-5 (1)
5-5: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick winUse standard Tailwind classes for the overlay background and blur.
LoadingProgress.vueuseslight:bg-white/60andbackdrop:backdrop-blur-2xl, butresources/sass/app-v8.cssdoes not definelightorbackdropcustom variants. The v7 imports keep their own variants, so this v8 overlay component will miss the light-mode background and blur. Usebg-white/60 dark:bg-black/60 backdrop-blur-2xlinstead.resources/js/v8/views/gallery-panels/Flow.vue-22-22 (1)
22-22: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win
flex justify-centeris applied to the loading icon instead of a container.LycheeLoadingIconuses an<svg>as its root element, so class bindings land on that<svg>.justify-contentaffects only that element's own children, so the icon is not centered. Wrap the icon in a centering container at both sites.
resources/js/v8/views/gallery-panels/Flow.vue#L22-L22: moveflex justify-centerto a wrapperdivthat carries thev-if, and give the icon an explicit size such astext-2xl.resources/js/v8/views/gallery-panels/Timeline.vue#L55-L55: moveflex justify-centerto a wrapperdivthat carries thev-if, and keeptext-2xlon the icon.resources/js/v8/views/webshop/BasketList.vue-2-2 (1)
2-2: 🩺 Stability & Availability | 🟡 Minor | ⚡ Quick winHandle failed loading in loading sentinels.
LoadingProgressstays active whenorderoroptionsremainsundefined.lycheeStateStore.load()clears through.catch(), but the new shop loaders do not:useStepOne.loadCheckoutOptions()only assigns data on success, andorderStore.load()only assignsthis.orderon success. Make these load failures reach a terminal false state in the loaded flags, so rejected requests do not leave the overlay showing forever.resources/js/v8/components/forms/settings/ColorField.vue-5-5 (1)
5-5: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick winReplace
<UChip>with a documented design-system exception.
docs/specs/3-reference/coding-conventions.mdrequires<template>first, then<script lang="ts">; move<script>before<style>. ThegetDefaultColor(key)helper also usesprops.config.keyfor the current selection.Source: Coding guidelines
resources/js/v8/components/forms/settings/ColorField.vue-63-68 (1)
63-68: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick winGive the
neutral_colorcase its own lexical scope.
const bodyis declared directly in theswitchbody here, and Biome’snoSwitchDeclarationsrule treats switch cases as a shared scope. Wrap this case in braces so thebodyquery variable cannot leak or collide with other cases.Proposed fix
- case "neutral_color": - const b = document.querySelector("body"); - if (b?.classList.contains("dark")) { + case "neutral_color": { + const body = document.querySelector("body"); + if (body?.classList.contains("dark")) { return "`#71717b`"; // dark mode: zinc color } return "`#62748e`"; // or slate color + }Source: Linters/SAST tools
🧹 Nitpick comments (4)
app/View/Components/Style.php (1)
41-56: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick winConsider batching the palette cache lookups.
This constructor now performs up to 7 separate
Cache::rememberForevercalls per request instead of 1. Since this component renders on most page loads, this adds cache round-trips per request. Collect the non-empty colors first, then fetch them withCache::many()and generate and store only the missing palettes in one batch, instead of looking up each token individually.resources/js/v8/views/admin/DesignSystem.vue (1)
281-302: 🎯 Functional Correctness | 🔵 Trivial | 💤 Low valueResolved hex values do not refresh after a theme change.
registerSwatchreads the computed background color one time, when Vue binds the element ref. If a palette custom property changes while this view stays mounted, the swatch color updates through CSS, but the printed hex text stays stale. Consider recomputing on demand, for example insideonMountedplus a watcher on the palette source.resources/js/v8/views/face-recog/FaceClusters.vue (1)
383-396: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueReplace
async/awaitwith promise chaining.
fetchAllClusterFaceIdsusesasyncandawait. The project guidelines require.then()in Vue 3 code. Convert the paging loop to a recursive promise chain.As per coding guidelines: "Do not use await async calls in Vue3, use .then() instead".
Source: Coding guidelines
resources/js/v8/components/forms/settings/ColorField.vue (1)
78-83: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick winUse the supplied configuration for the default lookup.
stringToBlossomColorPickerValueacceptsconfig, but the fallback still readsprops.config.key. Useconfig.keyso the helper remains correct when it receives a different configuration object.Proposed fix
- color = getDefaultColor(props.config.key); + color = getDefaultColor(config.key);
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 110ed523-55e1-4882-8756-9200240f1343
⛔ Files ignored due to path filters (2)
public/img/logo4.svgis excluded by!**/*.svgresources/img/logo4.svgis excluded by!**/*.svg
📒 Files selected for processing (135)
DESIGN.mdapp/Http/Controllers/Admin/SettingsController.phpapp/Http/Resources/Rights/ModulesRightsResource.phpapp/View/Components/Style.phpdatabase/migrations/2026_07_23_000000_add_accent_color.phpdatabase/migrations/2026_08_01_000000_add_theme_colors.phplang/ar/all_settings.phplang/ar/people.phplang/bg/all_settings.phplang/bg/people.phplang/cz/all_settings.phplang/cz/people.phplang/de/all_settings.phplang/de/people.phplang/el/all_settings.phplang/el/people.phplang/en/all_settings.phplang/en/design-system.phplang/en/people.phplang/es/all_settings.phplang/es/people.phplang/fa/all_settings.phplang/fa/people.phplang/fr/all_settings.phplang/fr/people.phplang/hu/all_settings.phplang/hu/people.phplang/it/all_settings.phplang/it/people.phplang/ja/all_settings.phplang/ja/people.phplang/nl/all_settings.phplang/nl/people.phplang/no/all_settings.phplang/no/people.phplang/pl/all_settings.phplang/pl/people.phplang/pt/all_settings.phplang/pt/people.phplang/ru/all_settings.phplang/ru/people.phplang/sk/all_settings.phplang/sk/people.phplang/sv/all_settings.phplang/sv/people.phplang/tr/all_settings.phplang/tr/people.phplang/vi/all_settings.phplang/vi/people.phplang/zh_CN/all_settings.phplang/zh_CN/people.phplang/zh_TW/all_settings.phplang/zh_TW/people.phpresources/js/lychee.d.tsresources/js/router/paths.tsresources/js/v8/components/LycheeLoadingIcon.vueresources/js/v8/components/Spinner.vueresources/js/v8/components/drawers/PhotoDetails.vueresources/js/v8/components/footers/GalleryFooter.vueresources/js/v8/components/forms/album/AlbumShare.vueresources/js/v8/components/forms/album/AlbumVisibility.vueresources/js/v8/components/forms/album/ApplyRenamerDialog.vueresources/js/v8/components/forms/basic/InputPassword.vueresources/js/v8/components/forms/people/RemovePhotoFromPersonDialog.vueresources/js/v8/components/forms/settings/ColorField.vueresources/js/v8/components/gallery/PersonCard.vueresources/js/v8/components/gallery/albumModule/AlbumPanel.vueresources/js/v8/components/gallery/photoModule/PhotoRatingWidget.vueresources/js/v8/components/loading/LoadingProgress.vueresources/js/v8/components/maintenance/DuplicateLine.vueresources/js/v8/components/maintenance/MaintenanceBackfillAlbumSizes.vueresources/js/v8/components/maintenance/MaintenanceBulkScanFaces.vueresources/js/v8/components/maintenance/MaintenanceBulkScanNsfw.vueresources/js/v8/components/maintenance/MaintenanceCleaning.vueresources/js/v8/components/maintenance/MaintenanceDestroyDismissedFaces.vueresources/js/v8/components/maintenance/MaintenanceDuplicateChecker.vueresources/js/v8/components/maintenance/MaintenanceFilesize.vueresources/js/v8/components/maintenance/MaintenanceFixJobs.vueresources/js/v8/components/maintenance/MaintenanceFixTree.vueresources/js/v8/components/maintenance/MaintenanceFlushCache.vueresources/js/v8/components/maintenance/MaintenanceFlushQueue.vueresources/js/v8/components/maintenance/MaintenanceFulfillOrders.vueresources/js/v8/components/maintenance/MaintenanceFulfillPrecompute.vueresources/js/v8/components/maintenance/MaintenanceGenSizevariants.vueresources/js/v8/components/maintenance/MaintenanceMissingPalettes.vueresources/js/v8/components/maintenance/MaintenanceOldOrders.vueresources/js/v8/components/maintenance/MaintenanceOptimize.vueresources/js/v8/components/maintenance/MaintenanceResetFaceScanStatus.vueresources/js/v8/components/maintenance/MaintenanceRunClustering.vueresources/js/v8/components/maintenance/MaintenanceSyncFaceEmbeddings.vueresources/js/v8/components/maintenance/StatisticsIntegrity.vueresources/js/v8/components/modals/CameraCapture.vueresources/js/v8/components/modals/ImportFromServer.vueresources/js/v8/components/modals/faceRecog/SelfieClaimModal.vueresources/js/v8/components/pagination/PaginationInfiniteScroll.vueresources/js/v8/components/settings/General.vueresources/js/v8/composables/useAdminTiles.tsresources/js/v8/router/routes.tsresources/js/v8/views/AdminSetupPage.vueresources/js/v8/views/App.vueresources/js/v8/views/BulkAlbumEdit.vueresources/js/v8/views/ChangeLogs.vueresources/js/v8/views/Landing.vueresources/js/v8/views/LoginPage.vueresources/js/v8/views/Permissions.vueresources/js/v8/views/RegisterPage.vueresources/js/v8/views/RenamerRules.vueresources/js/v8/views/Sharing.vueresources/js/v8/views/TagsManagement.vueresources/js/v8/views/admin/AdminDashboard.vueresources/js/v8/views/admin/ContactMessages.vueresources/js/v8/views/admin/DesignSystem.vueresources/js/v8/views/admin/Moderation.vueresources/js/v8/views/admin/NsfwConfig.vueresources/js/v8/views/admin/Settings.vueresources/js/v8/views/admin/UserGroups.vueresources/js/v8/views/admin/Users.vueresources/js/v8/views/admin/Webhooks.vueresources/js/v8/views/face-recog/FaceClusters.vueresources/js/v8/views/face-recog/FaceMaintenance.vueresources/js/v8/views/face-recog/People.vueresources/js/v8/views/face-recog/PersonDetail.vueresources/js/v8/views/gallery-panels/Favourites.vueresources/js/v8/views/gallery-panels/Flow.vueresources/js/v8/views/gallery-panels/Map.vueresources/js/v8/views/gallery-panels/Timeline.vueresources/js/v8/views/webshop/BasketList.vueresources/js/v8/views/webshop/CheckoutPage.vueresources/js/v8/views/webshop/OrderDownload.vueresources/sass/app-v8.cssresources/views/components/meta.blade.phpresources/views/components/style.blade.phpresources/views/vueapp.blade.phproutes/web_v2.phpui.todo
💤 Files with no reviewable changes (1)
- resources/js/v8/components/Spinner.vue
Codecov Report✅ All modified and coverable lines are covered by tests. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Actionable comments posted: 2
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
resources/js/v8/views/face-recog/FaceClusters.vue (1)
600-606: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
openQueuetriggersloadQueueClusterFacestwice.
openQueuesetsqueueIndex.value = idx, then callsloadQueueClusterFaces()directly. SettingqueueIndex.valuealso changes it fromnulltoidx. Thewatch(queueIndex, ...)at Line 719 fires becausequeueVisible.valueis alreadytrueby the time the watcher runs (both assignments inopenQueuecomplete synchronously before the pre-flush watcher executes). The watcher then callsloadQueueClusterFaces()again.Each call resets
detailFaces.value,detailCurrentPage.value, and issues a newgetClusterFacesrequest. Every queue open fires two identical requests instead of one.Remove the direct call in
openQueueand let the watcher handle it, sinceskipQueueClusteralready relies solely on the watcher for this purpose.🐛 Proposed fix to remove the redundant call
function openQueue(cluster: App.Http.Resources.Models.ClusterPreviewResource) { const idx = clusters.value.findIndex((c) => c.cluster_label === cluster.cluster_label); if (idx === -1) return; queueIndex.value = idx; queueVisible.value = true; - loadQueueClusterFaces(); }Also applies to: 719-723
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: fd978c93-76e4-446b-85db-ee90bf1957bf
📒 Files selected for processing (19)
resources/js/v8/components/forms/album/AlbumShare.vueresources/js/v8/components/forms/settings/ColorField.vueresources/js/v8/components/loading/LoadingProgress.vueresources/js/v8/components/renamer/RenamerRuleLine.vueresources/js/v8/components/settings/ConfirmSave.vueresources/js/v8/components/settings/CssJs.vueresources/js/v8/components/settings/General.vueresources/js/v8/views/Landing.vueresources/js/v8/views/LoginPage.vueresources/js/v8/views/Permissions.vueresources/js/v8/views/RegisterPage.vueresources/js/v8/views/Sharing.vueresources/js/v8/views/admin/Settings.vueresources/js/v8/views/admin/Users.vueresources/js/v8/views/face-recog/FaceClusters.vueresources/js/v8/views/gallery-panels/Flow.vueresources/js/v8/views/gallery-panels/Map.vueresources/js/v8/views/gallery-panels/Timeline.vueresources/js/v8/views/webshop/BasketList.vue
🚧 Files skipped from review as they are similar to previous changes (11)
- resources/js/v8/components/forms/album/AlbumShare.vue
- resources/js/v8/components/loading/LoadingProgress.vue
- resources/js/v8/views/gallery-panels/Timeline.vue
- resources/js/v8/views/Permissions.vue
- resources/js/v8/views/Sharing.vue
- resources/js/v8/views/admin/Settings.vue
- resources/js/v8/views/admin/Users.vue
- resources/js/v8/components/settings/General.vue
- resources/js/v8/components/forms/settings/ColorField.vue
- resources/js/v8/views/gallery-panels/Flow.vue
- resources/js/v8/views/gallery-panels/Map.vue
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (3)
resources/js/v8/views/face-recog/FaceClusters.vue (3)
135-171: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick winBlock repeated face toggles while a request is pending.
The face-removal control stays enabled while
dismissSingleFacewaits forFaceDetectionService.toggleDismissed. A double click can send two toggle requests. The second request can restore the face after the first request dismisses it, while both success handlers remove the face and decrementface_count.Track pending face IDs. Disable the remove control and the undo action until the corresponding request completes.
The supplied dismissal flow and
FaceDetectionServiceconfirm that this action toggles dismissed state. (raw.githubusercontent.com)Also applies to: 727-800
Source: MCP tools
606-622: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick winGuard queue face loads against stale responses.
openQueuestarts a queue load immediately, while thequeueIndexwatcher starts another load afterqueueIndex.value = idxchanges.skipQueueClusterstarts a new cluster load before the previous load resolves.loadQueueClusterFaces()then applies each response todetailFaces,detailCurrentPage, anddetailHasMorePageswithout checking that the response still matches the requestedcluster_label, so slow responses can replace the current cluster’s face list with stale faces.Correlate pending face loads with
queueCluster.value.cluster_labelbefore applying success updates and before enabling pagination/loading flags infinally.Source: MCP tools
361-508: 🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy liftReconcile partial batch mutations.
performBatchDismissusesPromise.allfor per-cluster fetches and dismisses, whileundoDismissusesPromise.allfor per-face restores. Any failure can leave dismissed/undismissed faces out of sync with the local queue, andconfirmDismissstill closes the dialog. Use an atomic bulk operation, or handle each operation withPromise.allSettled, reconcile successful changes before closing, and add a test for one success with one failure.Source: MCP tools
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 277e2ae3-0407-4864-a419-36e4080de820
📒 Files selected for processing (65)
resources/js/v8/components/forms/group/AddUserGroupModal.vueresources/js/v8/components/forms/photo/PhotoTagDialog.vueresources/js/v8/components/forms/tags/TagDeleteDialog.vueresources/js/v8/components/gallery/albumModule/AlbumHeaderPanel.vueresources/js/v8/components/maintenance/MaintenanceDuplicateChecker.vueresources/js/v8/components/maintenance/MaintenanceFixJobs.vueresources/js/v8/components/maintenance/MaintenanceFixTree.vueresources/js/v8/components/maintenance/MaintenanceFlushCache.vueresources/js/v8/components/maintenance/MaintenanceFlushQueue.vueresources/js/v8/components/maintenance/MaintenanceFulfillOrders.vueresources/js/v8/components/maintenance/MaintenanceFulfillPrecompute.vueresources/js/v8/components/maintenance/MaintenanceGenSizevariants.vueresources/js/v8/components/maintenance/MaintenanceMissingPalettes.vueresources/js/v8/components/maintenance/MaintenanceOldOrders.vueresources/js/v8/components/maintenance/MaintenanceOptimize.vueresources/js/v8/components/maintenance/MaintenanceResetFaceScanStatus.vueresources/js/v8/components/maintenance/MaintenanceRunClustering.vueresources/js/v8/components/maintenance/MaintenanceSyncFaceEmbeddings.vueresources/js/v8/components/maintenance/MaintenanceUpdate.vueresources/js/v8/components/maintenance/StatisticsIntegrity.vueresources/js/v8/components/modals/AboutLychee.vueresources/js/v8/components/modals/CameraCapture.vueresources/js/v8/components/modals/ConfirmModalHost.vueresources/js/v8/components/modals/DownloadAlbum.vueresources/js/v8/components/modals/DownloadPhoto.vueresources/js/v8/components/modals/ImportFromLink.vueresources/js/v8/components/modals/ImportFromServer.vueresources/js/v8/components/modals/RegisterLychee.vueresources/js/v8/components/modals/SecurityAdvisoriesModal.vueresources/js/v8/components/modals/SessionExpiredReload.vueresources/js/v8/components/modals/UploadPanel.vueresources/js/v8/components/modals/WebauthnModal.vueresources/js/v8/components/modals/faceRecog/BatchFaceAssignmentModal.vueresources/js/v8/components/modals/faceRecog/FaceAssignmentModal.vueresources/js/v8/components/modals/faceRecog/MergePersonModal.vueresources/js/v8/components/modals/faceRecog/SelfieClaimModal.vueresources/js/v8/components/pagination/PaginationLoadMore.vueresources/js/v8/components/renamer/RenamerRuleModal.vueresources/js/v8/components/settings/ConfirmSave.vueresources/js/v8/components/settings/General.vueresources/js/v8/components/webshop/Disclaimer.vueresources/js/v8/components/webshop/InfoSection.vueresources/js/v8/components/webshop/ThankYou.vueresources/js/v8/views/AdminSetupPage.vueresources/js/v8/views/BulkAlbumEdit.vueresources/js/v8/views/Contact.vueresources/js/v8/views/DuplicatesFinder.vueresources/js/v8/views/FixTree.vueresources/js/v8/views/RegisterPage.vueresources/js/v8/views/RenamerRules.vueresources/js/v8/views/Sharing.vueresources/js/v8/views/admin/ContactMessages.vueresources/js/v8/views/admin/Moderation.vueresources/js/v8/views/admin/UserGroups.vueresources/js/v8/views/admin/Users.vueresources/js/v8/views/admin/WatermarkPreview.vueresources/js/v8/views/admin/Webhooks.vueresources/js/v8/views/admin/shop/PrintPixelSizesAdmin.vueresources/js/v8/views/face-recog/FaceClusters.vueresources/js/v8/views/face-recog/FaceMaintenance.vueresources/js/v8/views/face-recog/People.vueresources/js/v8/views/webshop/BasketList.vueresources/js/v8/views/webshop/CheckoutPage.vueresources/js/v8/views/webshop/OrderDownload.vueresources/js/v8/views/webshop/OrderList.vue
🚧 Files skipped from review as they are similar to previous changes (34)
- resources/js/v8/views/admin/Users.vue
- resources/js/v8/components/maintenance/MaintenanceFixTree.vue
- resources/js/v8/components/modals/ImportFromServer.vue
- resources/js/v8/components/forms/group/AddUserGroupModal.vue
- resources/js/v8/views/RegisterPage.vue
- resources/js/v8/components/maintenance/StatisticsIntegrity.vue
- resources/js/v8/components/maintenance/MaintenanceMissingPalettes.vue
- resources/js/v8/components/modals/faceRecog/SelfieClaimModal.vue
- resources/js/v8/views/RenamerRules.vue
- resources/js/v8/views/admin/Webhooks.vue
- resources/js/v8/components/maintenance/MaintenanceRunClustering.vue
- resources/js/v8/views/admin/Moderation.vue
- resources/js/v8/components/maintenance/MaintenanceFulfillOrders.vue
- resources/js/v8/components/maintenance/MaintenanceGenSizevariants.vue
- resources/js/v8/views/face-recog/People.vue
- resources/js/v8/components/maintenance/MaintenanceOptimize.vue
- resources/js/v8/views/admin/UserGroups.vue
- resources/js/v8/components/maintenance/MaintenanceOldOrders.vue
- resources/js/v8/components/maintenance/MaintenanceFlushQueue.vue
- resources/js/v8/views/AdminSetupPage.vue
- resources/js/v8/components/maintenance/MaintenanceResetFaceScanStatus.vue
- resources/js/v8/components/maintenance/MaintenanceFulfillPrecompute.vue
- resources/js/v8/components/maintenance/MaintenanceFlushCache.vue
- resources/js/v8/components/modals/CameraCapture.vue
- resources/js/v8/views/Sharing.vue
- resources/js/v8/components/maintenance/MaintenanceDuplicateChecker.vue
- resources/js/v8/views/webshop/OrderDownload.vue
- resources/js/v8/components/settings/ConfirmSave.vue
- resources/js/v8/views/BulkAlbumEdit.vue
- resources/js/v8/views/webshop/BasketList.vue
- resources/js/v8/components/settings/General.vue
- resources/js/v8/components/maintenance/MaintenanceSyncFaceEmbeddings.vue
- resources/js/v8/components/maintenance/MaintenanceFixJobs.vue
- resources/js/v8/views/face-recog/FaceMaintenance.vue
Summary by CodeRabbit
New Features
Improvements