Front-end for subalbums - #4711
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Team Run ID: 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
Included review availability: Your plan provides up to 8 included reviews per hour; 6 remain after this review. 📝 WalkthroughWalkthroughChangesAlbum timeline and root-gallery adoption
Estimated code review effort: 5 (Critical) | ~120 minutes Merge Risk: 🟡 Moderate · up to The subalbum front end can show incorrectly scoped shared albums and has several selection and interaction defects; unresolved conflict markers and inconsistent feature records also leave the change not ready to merge. Resolve these issues before merging. Poem
🚥 Pre-merge checks | ❌ 1❌ Failed checks (1 warning)
Full details: Docstring CoverageExplanation Docstring coverage is 60.61% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 33 functions across 27 files. (1 skipped: 1 unsupported.)
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 |
… feature-63/bucket-album-front-end
… feature-63/bucket-album-front-end
… feature-63/bucket-album-front-end
… feature-63/bucket-album-front-end
… feature-63/bucket-album-front-end
… feature-63/bucket-album-front-end
|
@coderabbitai review please. |
There was a problem hiding this comment.
Actionable comments posted: 20
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
resources/js/stores/AlbumsState.ts (1)
63-63: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick winInclude V3 shared tiles in
selectableAlbums.
sharedAlbumsV3is excluded from this getter. Under struct-of-array mode, shared albums cannot participate in operations that useselectableAlbums, andhasHiddendoes not inspect them.Proposed fix
- return state.pinnedAlbums.concat(state.albums.concat(state.sharedAlbums.map((album) => album.data).flat())).filter((a) => { + return state.pinnedAlbums.concat(state.albums, state.sharedAlbumsV3, state.sharedAlbums.map((album) => album.data).flat()).filter((a) => {docs/specs/4-architecture/features/063-album-timeline-buckets-adoption/plan.md (1)
251-251: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick winAdd the required Markdown footer to both documents.
Append this content after the final document section:
--- *Last updated: 2026-09-04*
docs/specs/4-architecture/features/063-album-timeline-buckets-adoption/plan.md#L251-L251: append the footer after the follow-ups.docs/specs/4-architecture/features/063-album-timeline-buckets-adoption/tasks.md#L261-L261: append the footer after the notes.As per coding guidelines, documentation files must end with a horizontal rule and the update date.
Source: Coding guidelines
🧹 Nitpick comments (1)
docs/specs/4-architecture/features/063-album-timeline-buckets-adoption/tasks.md (1)
76-78: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winAlign the breakpoint notes with the active v8 model.
resources/sass/app-v8.cssdefines3xland4xlthresholds, andalbumTileWidth.tsmodels them with matching formulas (plus5xland6xl). Remove the stale “dead” and “five breakpoints” notes from the task, plan, and open-question entries. Keep the3xl/4xlimplementation and verification requirements.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Team
Run ID: e9590f93-d9b5-41c1-bd13-76622d7612dc
📒 Files selected for processing (56)
docs/specs/4-architecture/features/063-album-timeline-buckets-adoption/plan.mddocs/specs/4-architecture/features/063-album-timeline-buckets-adoption/spec.mddocs/specs/4-architecture/features/063-album-timeline-buckets-adoption/tasks.mddocs/specs/4-architecture/open-questions.mddocs/specs/4-architecture/roadmap.mdresources/js/app-v8.tsresources/js/composables/album/dragAndSelect.tsresources/js/composables/toast-contract.tsresources/js/router/paths.tsresources/js/services/album-category-v3-service.tsresources/js/services/album-children-v3-service.tsresources/js/services/album-service.tsresources/js/services/auth-service.tsresources/js/services/init-service.tsresources/js/stores/AlbumState.tsresources/js/stores/AlbumsState.tsresources/js/v7/views/BulkAlbumEdit.vueresources/js/v8/components/drawers/AlbumEdit.vueresources/js/v8/components/forms/album/SearchTargetAlbum.vueresources/js/v8/components/gallery/albumModule/AlbumListItem.vueresources/js/v8/components/gallery/albumModule/AlbumPanel.vueresources/js/v8/components/gallery/albumModule/AlbumThumbPanel.vueresources/js/v8/components/gallery/albumModule/Virtualized/AlbumListItemVirtual.vueresources/js/v8/components/gallery/albumModule/Virtualized/AlbumListViewVirtual.vueresources/js/v8/components/gallery/albumModule/Virtualized/AlbumRootGridVirtual.vueresources/js/v8/components/gallery/albumModule/Virtualized/AlbumRootListViewVirtual.vueresources/js/v8/components/gallery/albumModule/Virtualized/AlbumRootPanelVirtual.vueresources/js/v8/components/gallery/albumModule/Virtualized/AlbumThumbGridVirtual.vueresources/js/v8/components/gallery/albumModule/Virtualized/AlbumThumbPanelVirtual.vueresources/js/v8/components/gallery/albumModule/Virtualized/AlbumThumbVirtual.vueresources/js/v8/components/gallery/albumModule/thumbs/AlbumThumb.vueresources/js/v8/components/gallery/albumModule/thumbs/AlbumThumbImage.vueresources/js/v8/components/modals/SpotlightSearch.vueresources/js/v8/components/thumbs/Thumb.vueresources/js/v8/composables/album/albumTileWidth.tsresources/js/v8/composables/album/virtualAlbumRows.tsresources/js/v8/composables/landing/useLandingAnimation.tsresources/js/v8/composables/spotlight/useSpotlightGalleryActions.tsresources/js/v8/composables/useAppToast.tsresources/js/v8/composables/useConfirmDialog.tsresources/js/v8/composables/useScrollReveal.tsresources/js/v8/icons.tsresources/js/v8/menus/LeftMenu.vueresources/js/v8/router/routes.tsresources/js/v8/services/track-service.tsresources/js/v8/utils/adaptAlbumChildTile.tsresources/js/v8/utils/adaptCategoryTile.tsresources/js/v8/utils/albumBucketBoundaries.tsresources/js/v8/utils/aspectRatioNumber.tsresources/js/v8/utils/phpDateFormat.tsresources/js/v8/utils/resolveCssLengthPx.tsresources/js/v8/views/BulkAlbumEdit.vueresources/js/v8/views/Error.vueresources/js/v8/views/gallery-panels/Albums.vueresources/js/v8/views/gallery-panels/Map.vueresources/sass/app-v8.css
Included review availability: Your plan provides up to 8 included reviews per hour; 7 remain after this review.
|
|
||
| function dayOfYear(date: Date): number { | ||
| const start = new Date(date.getFullYear(), 0, 1); | ||
| return Math.floor((date.getTime() - start.getTime()) / 86400000); |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
🔎 Supported by static analysis
🌐 Web query:
In ECMAScript, can subtracting two local-midnight Date values across a daylight-saving transition produce a non-integral number of 24-hour days?
💡 Result:
Yes, in ECMAScript, subtracting two local-midnight Date values across a daylight-saving time (DST) transition can produce a non-integral number of 24-hour days [1][2][3]. When you subtract two Date objects in JavaScript, the operation implicitly converts them to their underlying UTC-based millisecond timestamp values and returns the difference [4][5]. Because ECMAScript Date objects represent local time by applying a system-specific timezone offset and daylight saving adjustment to a UTC base [6][7][8], the number of milliseconds between two "local midnight" moments is not necessarily a multiple of 86,400,000 milliseconds (the number of milliseconds in a standard 24-hour day) [2][3]. If a DST transition occurs between the two dates (e.g., a "spring forward" or "fall back" event), the local timezone offset changes [9][10]. Consequently, the elapsed wall-clock time between two consecutive local midnights will be 23 hours, 25 hours, or some other duration depending on the specific timezone rules [2]. When this millisecond difference is divided by the standard constant for a 24-hour day, the result is a non-integral number of days [1][3]. To perform calendar-based arithmetic that ignores DST and treats "days" as calendar dates, developers typically use UTC-based methods (e.g., Date.UTC) to bypass local timezone offsets [1][2] or rely on specialized libraries designed to handle DST-aware duration calculations [11][9].
Citations:
- 1: https://stackoverflow.com/questions/35028259/peculiar-javascript-date-comparison-output
- 2: https://synyx.de/blog/properly-calculating-time-differences-in-javascript
- 3: https://stackoverflow.com/questions/7375278/timezone-problems-when-calculating-the-difference-between-two-dates-in-javascrip
- 4: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date
- 5: https://stackoverflow.com/questions/50792994/why-can-i-do-math-with-date-objects
- 6: http://www.xahlee.info/js_es2011/JavaScript_15.9_date.html
- 7: https://tc39.es/ecma262/multipage/numbers-and-dates.html
- 8: https://stackoverflow.com/questions/18897658/invalid-times-at-the-start-of-daylight-saving-time
- 9: https://flaviocopes.com/javascript-dates/
- 10: https://stackoverflow.com/questions/31773115/javascript-subtract-two-dates-in-milliseconds-considering-daylight-time-saving
- 11: GitHub pull request 6354 in moment/moment (link omitted to avoid creating a cross-reference)
Calculate z from calendar dates.
When the local time zone crosses a daylight-saving transition, the elapsed time between January 1 and date can be 23 or 25 hours for a calendar day. Math.floor(... / 86400000) can therefore return an incorrect day-of-year value. Use UTC calendar components for this calculation.
Proposed fix
function dayOfYear(date: Date): number {
- const start = new Date(date.getFullYear(), 0, 1);
- return Math.floor((date.getTime() - start.getTime()) / 86400000);
+ const start = Date.UTC(date.getFullYear(), 0, 1);
+ const current = Date.UTC(date.getFullYear(), date.getMonth(), date.getDate());
+ return Math.floor((current - start) / 86400000);
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| return Math.floor((date.getTime() - start.getTime()) / 86400000); | |
| function dayOfYear(date: Date): number { | |
| const start = Date.UTC(date.getFullYear(), 0, 1); | |
| const current = Date.UTC(date.getFullYear(), date.getMonth(), date.getDate()); | |
| return Math.floor((current - start) / 86400000); | |
| } |
| default: | ||
| // Unrecognized character: pass through literally, matching | ||
| // PHP's own date() behavior for an unknown format character. | ||
| result += char; |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | 🏗️ Heavy lift
🔎 Supported by static analysis
🌐 Web query:
What format characters does PHP date() recognize, including ISO week-year, timezone, and daylight-saving tokens?
💡 Result:
The PHP date function—and the shared DateTimeInterface::format method—recognize a specific set of format characters to represent date and time components [1][2][3]. ISO Week-Year and Week Tokens To correctly handle ISO 8601 week dates, PHP provides the following characters [3][4]: - W: ISO 8601 week number of year (weeks starting on Monday; 01 through 53) [3]. - o: ISO 8601 week-numbering year. This is similar to Y, but if the ISO week number (W) belongs to the previous or next year, that year is used instead [3]. Timezone Tokens The following tokens are used for timezone information [5][2]: - e: Timezone identifier (e.g., UTC, Atlantic/Azores) [2]. - I (uppercase i): Whether or not the date is in daylight saving time (1 if it is, 0 otherwise) [2]. - O: Difference to Greenwich time (GMT) in hours and minutes (e.g., +0200) [2]. - P: Difference to Greenwich time (GMT) with a colon between hours and minutes (e.g., +02:00) [2]. - p: The same as P, but returns Z for UTC (e.g., +02:00 or Z) [2]. - T: Timezone abbreviation (e.g., UTC, EST, MDT) [5][2]. - Z: Timezone offset in seconds. The offset for timezones west of UTC is always negative, and for those east of UTC is always positive (e.g., -43200 through 50400) [2]. Other Common Format Characters - Day: d (01-31), D (Mon-Sun), j (1-31), l (full weekday name), N (1 for Monday-7 for Sunday), S (ordinal suffix), w (0 for Sunday-6 for Saturday), z (0-365) [2][3]. - Month: F (full name), m (01-12), M (Jan-Dec), n (1-12), t (days in month) [2][3]. - Year: L (leap year check: 1 or 0), Y (4-digit year), y (2-digit year), X/x (expanded year representations) [2][3]. - Time: a/A (am/pm), B (Swatch Internet time), g/G (12/24-hour, no leading zero), h/H (12/24-hour, with leading zero), i (minutes), s (seconds), u (microseconds), v (milliseconds) [2][6][3]. Important Implementation Notes - Escape Characters: Any recognized character can be prevented from being expanded by preceding it with a backslash () [1][5]. - Unix Timestamps: The date function operates on integer Unix timestamps, which do not inherently include timezone information [5][7]. To format timezone-aware dates, you should use the DateTimeImmutable class and its format method instead [7].
Citations:
- 1: https://www.php.net/date()
- 2: https://www.php.net/datetime.format
- 3: https://www.php.net/manual/en/datetime.format.php
- 4: https://derickrethans.nl/iso-8601-weeks.html
- 5: https://www.php.net/manual/en/function.date.php
- 6: https://doc.bccnsoft.com/docs/php-docs-7.4-en/function.date.html
- 7: https://mirror.math.princeton.edu/pub/php/manual/en/function.date.php
🤖 get_repo_knowledge executed:
get_repo_knowledge LycheeOrg/Lychee /tmp/coderabbit-repo-knowledge/lycheeorg-lychee-cc271fdf/conventions /tmp/coderabbit-repo-knowledge/lycheeorg-lychee-cc271fdf/learnings
Length of output: 32004
🏁 Script executed:
#!/bin/bash
set -eu
file="resources/js/v8/utils/phpDateFormat.ts"
printf '%s\n' '--- target file ---'
cat -n "$file" | sed -n '1,280p'
printf '%s\n' '--- direct references ---'
rg -n --glob '!vendor' --glob '!node_modules' 'phpDateFormat|formatMinMaxDate|date_format|dateFormat|date format' resources app config tests 2>/dev/null | head -200Repository: LycheeOrg/Lychee
Length of output: 23053
🏁 Script executed:
#!/bin/bash
set -eu
printf '%s\n' '--- configuration definitions ---'
rg -n -C 8 --glob '*.php' "date_format_album_thumb|date_format_hero_created_at|date_format_hero_min_max|date_format_flow_min_max" config app database resources | head -240
printf '%s\n' '--- server formatting path ---'
cat -n app/Http/Resources/Models/ThumbAlbumResource.php | sed -n '45,145p'
printf '%s\n' '--- client call path ---'
cat -n resources/js/v8/utils/adaptAlbumChildTile.ts | sed -n '125,175p'Repository: LycheeOrg/Lychee
Length of output: 32736
Support the PHP format tokens used by date_format_album_thumb.
phpDateFormat() emits omitted recognized tokens such as o, O, and T literally. The date_format_album_thumb setting accepts free-text PHP date formats, while ThumbAlbumResource formats the same setting with PHP. Valid formats using these tokens can therefore produce incorrect v8 album metadata. Support the configured PHP token set or reject unsupported tokens.
| const minFormatted = phpDateFormat(format, new Date(minTakenAt)); | ||
| const maxFormatted = phpDateFormat(format, new Date(maxTakenAt)); |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
🔎 Supported by static analysis
🏁 Script executed:
#!/bin/bash
set -euo pipefail
fd -t f 'ThumbAlbumResource.php' app
fd -t f 'AlbumDataResource.php' app
rg -n -C 8 'formatMinMaxDate|min_taken_at|max_taken_at|date_format_album_thumb|timezone' appRepository: LycheeOrg/Lychee
Length of output: 50373
🤖 get_repo_knowledge executed:
get_repo_knowledge LycheeOrg/Lychee /tmp/coderabbit-repo-knowledge/lycheeorg-lychee-cc271fdf/learnings /tmp/coderabbit-repo-knowledge/lycheeorg-lychee-cc271fdf/conventions
Length of output: 13682
🏁 Script executed:
#!/bin/bash
set -euo pipefail
resource=$(fd -t f 'ThumbAlbumResource.php' app | head -n 1)
printf '%s\n' "== $resource =="
cat -n "$resource"
printf '%s\n' '== date-format call sites and definitions =='
rg -n -C 5 'formatMinMaxDate|phpDateFormat|date_format_album_thumb|min_taken_at|max_taken_at' resources/js app/Http/Resources app/Actions/AlbumRepository: LycheeOrg/Lychee
Length of output: 50372
🏁 Script executed:
#!/bin/bash
set -euo pipefail
resource=$(fd -t f 'ThumbAlbumResource.php' app | head -n 1)
cat -n "$resource"
printf '%s\n' '== relevant JavaScript references =='
rg -n -C 6 'formatMinMaxDate|phpDateFormat|date_format_album_thumb|min_taken_at|max_taken_at' resources/jsRepository: LycheeOrg/Lychee
Length of output: 29051
🏁 Script executed:
#!/bin/bash
set -euo pipefail
printf '%s\n' '== V3 producer =='
cat -n app/Actions/Album/StructOfArrays/BuildAlbumDataResource.php | sed -n '60,160p'
printf '%s\n' '== V3 resource =='
cat -n app/Http/Resources/V3/AlbumDataResource.php | sed -n '45,90p'
printf '%s\n' '== client formatter =='
cat -n resources/js/v8/utils/phpDateFormat.ts | sed -n '90,110p;219,260p'
printf '%s\n' '== UTC model contracts and configuration =='
rg -n -C 5 'DB_TIMEZONE_NAME|date_default_timezone_set|app.*timezone|timezone.*app|class PatchedBaseModel|HasUTCBasedTimes' app config bootstrapRepository: LycheeOrg/Lychee
Length of output: 40294
Parse album timestamps in the server timezone. The V3 resource passes raw UTC database strings to formatMinMaxDate(). new Date() interprets timezone-less date-time strings in the visitor’s local timezone, while ThumbAlbumResource formats the corresponding Carbon values in the application timezone. Date ranges near a day, month, or year boundary can differ. Add an explicit timezone to the client parsing or send timezone-qualified timestamps.
| <AlbumRootPanelVirtual | ||
| v-if="is_struct_of_array_enabled" | ||
| scope="own" | ||
| header="gallery.albums" | ||
| :selected-albums="selectedAlbumsIds" | ||
| @clicked="albumSelect" | ||
| @contexted="contextMenuAlbumOpen" | ||
| /> |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
Forward selected from every virtual root panel.
AlbumRootPanelVirtual relays selected, but these call sites do not handle it. In touch selection mode, AlbumListItemVirtual emits only selected, so root albums cannot be selected.
resources/js/v8/views/gallery-panels/Albums.vue#L55-L62: add@selected="albumSelect".resources/js/v8/views/gallery-panels/Albums.vue#L76-L82: add@selected="albumSelect".resources/js/v8/views/gallery-panels/Albums.vue#L111-L118: add@selected="albumSelect".resources/js/v8/views/gallery-panels/Albums.vue#L130-L136: add@selected="albumSelect".
📍 Affects 1 file
resources/js/v8/views/gallery-panels/Albums.vue#L55-L62(this comment)resources/js/v8/views/gallery-panels/Albums.vue#L76-L82resources/js/v8/views/gallery-panels/Albums.vue#L111-L118resources/js/v8/views/gallery-panels/Albums.vue#L130-L136
| if (is_struct_of_array_enabled.value) { | ||
| if (sharedAlbumsVisibilityMode.value === "separate_shared_only") { | ||
| return albumsStore.sharedAlbumsV3.some((album) => !album.is_public); | ||
| } | ||
| return albumsStore.sharedAlbumsV3.length > 0; |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | 🏗️ Heavy lift
Do not render public albums in separate_shared_only mode.
This condition only decides whether to show the shared panel. AlbumRootPanelVirtual still renders the full sharedAlbumsV3 collection. Therefore, struct-of-array mode shows public albums that the legacy displaySharedAlbums path removes.
Pass a filtered V3 collection to the virtual panel and recompute its bucket boundaries, or make the V3 endpoint return the required subset.
🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -euo pipefail
echo '=== Changed files ==='
git diff --name-status HEAD^ HEAD
echo '=== Conflict markers ==='
rg -n '^(<<<<<<<|=======|>>>>>>>)' . \
-g '!vendor/**' -g '!node_modules/**' || true
echo '=== Diff stat ==='
git diff --stat HEAD^ HEAD
echo '=== Key module outlines ==='
for f in \
resources/js/stores/AlbumState.ts \
resources/js/stores/AlbumsState.ts \
resources/js/composables/album/dragAndSelect.ts \
resources/js/v8/composables/album/virtualAlbumRows.ts \
resources/js/v8/utils/albumBucketBoundaries.ts \
resources/js/v8/composables/album/albumTileWidth.ts \
resources/js/v8/utils/adaptAlbumChildTile.ts \
resources/js/v8/utils/adaptCategoryTile.ts
do
if [ -f "$f" ]; then
echo "--- $f ---"
ast-grep outline "$f" --items all || true
fi
done
echo '=== High-risk implementation diff ==='
git diff --unified=60 HEAD^ HEAD -- \
resources/js/stores/AlbumState.ts \
resources/js/stores/AlbumsState.ts \
resources/js/composables/album/dragAndSelect.ts \
resources/js/v8/composables/album/virtualAlbumRows.ts \
resources/js/v8/utils/albumBucketBoundaries.ts \
resources/js/v8/composables/album/albumTileWidth.ts \
resources/js/v8/utils/adaptAlbumChildTile.ts \
resources/js/v8/utils/adaptCategoryTile.ts
echo '=== Virtual component diff ==='
git diff --unified=35 HEAD^ HEAD -- \
resources/js/v8/components/gallery/albumModule/Virtualized \
resources/js/v8/components/gallery/albumModule/AlbumPanel.vue \
resources/js/v8/views/gallery-panels/Albums.vueLength of output: 17333 🏁 Script executed: #!/bin/bash
set -euo pipefail
echo '=== Refs and merge base ==='
git branch -a --no-color
git remote -v
git merge-base HEAD origin/feature-62/bucket-album-approach-tags-owners-root || true
BASE="$(git merge-base HEAD origin/feature-62/bucket-album-approach-tags-owners-root)"
printf 'BASE=%s\n' "$BASE"
echo '=== Complete PR changed files ==='
git diff --name-status "$BASE"...HEAD
git diff --stat "$BASE"...HEAD
echo '=== Complete PR conflict-marker diff and provenance ==='
git diff --unified=12 "$BASE"...HEAD -- docs/specs/4-architecture/open-questions.md docs/specs/_current-session.md
git blame -L 160,225 -- docs/specs/4-architecture/open-questions.md || true
git blame -L 560,730 -- docs/specs/4-architecture/open-questions.md || true
echo '=== Store and utility implementations ==='
for f in \
resources/js/stores/AlbumState.ts \
resources/js/stores/AlbumsState.ts \
resources/js/composables/album/dragAndSelect.ts \
resources/js/v8/composables/album/virtualAlbumRows.ts \
resources/js/v8/utils/albumBucketBoundaries.ts \
resources/js/v8/utils/adaptAlbumChildTile.ts \
resources/js/v8/utils/adaptCategoryTile.ts
do
echo "--- $f ---"
cat -n "$f"
done
echo '=== Services and virtualized component outlines ==='
for f in \
resources/js/services/album-category-v3-service.ts \
resources/js/services/album-children-v3-service.ts \
resources/js/services/album-service.ts \
resources/js/v8/components/gallery/albumModule/Virtualized/AlbumThumbGridVirtual.vue \
resources/js/v8/components/gallery/albumModule/Virtualized/AlbumRootGridVirtual.vue \
resources/js/v8/components/gallery/albumModule/Virtualized/AlbumListViewVirtual.vue \
resources/js/v8/components/gallery/albumModule/Virtualized/AlbumRootListViewVirtual.vue \
resources/js/v8/components/gallery/albumModule/Virtualized/AlbumThumbVirtual.vue
do
echo "--- $f ---"
ast-grep outline "$f" --items all || true
doneLength of output: 2653 🏁 Script executed: #!/bin/bash
set -u
REPO="LycheeOrg/Lychee"
PR="4711"
echo '=== Pull request metadata ==='
gh api "repos/${REPO}/pulls/${PR}" \
--jq '{number, base: {ref: .base.ref, sha: .base.sha}, head: {ref: .head.ref, sha: .head.sha}, mergeable_state, changed_files, commits, additions, deletions}'
echo '=== Pull request file list ==='
gh api --paginate "repos/${REPO}/pulls/${PR}/files?per_page=100" \
--jq '.[] | [.status, .filename, .additions, .deletions] | `@tsv`'
echo '=== Fetch target branch for comparison ==='
git fetch --no-tags --depth=1 origin \
"feature-62/bucket-album-approach-tags-owners-root:refs/remotes/origin/pr-base-4711" || true
if git rev-parse --verify -q origin/pr-base-4711 >/dev/null; then
BASE="$(git merge-base HEAD origin/pr-base-4711)"
echo "BASE=$BASE"
echo '=== Full PR stat ==='
git diff --stat "$BASE"...HEAD
echo '=== Documentation conflict-marker diff ==='
git diff --unified=15 "$BASE"...HEAD -- \
docs/specs/4-architecture/open-questions.md \
docs/specs/_current-session.md
fi
echo '=== Current conflict-marker provenance ==='
git log -S'<<<<<<< HEAD' --format='%H %s' --all -- \
docs/specs/4-architecture/open-questions.md \
docs/specs/_current-session.md || true
echo '=== Selected sources ==='
for f in \
resources/js/stores/AlbumState.ts \
resources/js/stores/AlbumsState.ts \
resources/js/composables/album/dragAndSelect.ts \
resources/js/v8/composables/album/virtualAlbumRows.ts \
resources/js/v8/utils/albumBucketBoundaries.ts \
resources/js/v8/utils/adaptAlbumChildTile.ts \
resources/js/v8/utils/adaptCategoryTile.ts \
resources/js/services/album-category-v3-service.ts \
resources/js/services/album-children-v3-service.ts
do
echo "--- $f ---"
cat -n "$f"
doneLength of output: 175400 🏁 Script executed: #!/bin/bash
set -euo pipefail
BASE="52d8f208083f1cf421120b05f7b80d890ee3ad38"
echo '=== selectableAlbums definitions and consumers ==='
rg -n -C 5 '\bselectableAlbums\b' resources/js
echo '=== v3 shared-root state consumers ==='
rg -n -C 4 '\bsharedAlbumsV3\b|\bsharedAlbums\b' \
resources/js/v8 resources/js/composables resources/js/stores
echo '=== Complete diffs for affected stores and drag selection ==='
git diff --unified=25 "$BASE"...HEAD -- \
resources/js/stores/AlbumsState.ts \
resources/js/stores/AlbumState.ts \
resources/js/composables/album/dragAndSelect.ts \
resources/js/services/album-service.ts
echo '=== Virtual component sources ==='
for f in \
resources/js/v8/components/gallery/albumModule/Virtualized/AlbumThumbGridVirtual.vue \
resources/js/v8/components/gallery/albumModule/Virtualized/AlbumRootGridVirtual.vue \
resources/js/v8/components/gallery/albumModule/Virtualized/AlbumListViewVirtual.vue \
resources/js/v8/components/gallery/albumModule/Virtualized/AlbumRootListViewVirtual.vue \
resources/js/v8/components/gallery/albumModule/Virtualized/AlbumRootPanelVirtual.vue \
resources/js/v8/components/gallery/albumModule/Virtualized/AlbumThumbPanelVirtual.vue \
resources/js/v8/views/gallery-panels/Albums.vue \
resources/js/v8/components/gallery/albumModule/AlbumPanel.vue
do
echo "--- $f ---"
cat -n "$f"
done
echo '=== Tests for new helpers or V3 stores ==='
fd -t f . resources/js | rg '(test|spec)\.(ts|tsx|vue)$' | head -200
rg -n -C 2 'computeBucketBoundaries|buildVirtualAlbumRows|adaptAlbumChildTile|loadAlbumsV3|loadRootAlbumsV3' \
. -g '*.{test,spec}.{ts,tsx,js}' -g '!node_modules/**' || trueLength of output: 169475
|
Summary by CodeRabbit
New Features
Bug Fixes