Skip to content

Spotlight search - #4656

Merged
ildyria merged 11 commits into
masterfrom
spotlight-search
Aug 23, 2026
Merged

Spotlight search#4656
ildyria merged 11 commits into
masterfrom
spotlight-search

Conversation

@ildyria

@ildyria ildyria commented Aug 22, 2026

Copy link
Copy Markdown
Member

Summary by CodeRabbit

  • New Features
    • Added Spotlight Search, accessible with Meta+K, for quickly finding photos, browsing albums, and opening settings or external links.
    • Added search navigation, actions, theme controls, and language selection.
    • Added dark-mode preference restoration and persistent theme switching.
    • Added language switching with localized interface direction support.
  • Localization
    • Added search-palette translations across 24 supported languages.
  • Improvements
    • Search results now load smoothly, avoid outdated responses, and provide clearer empty states.

@coderabbitai

coderabbitai Bot commented Aug 22, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It 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 reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Changes

Spotlight application

Layer / File(s) Summary
Localization and theme configuration
lang/*/search-palette.php, resources/js/v8/i18n.ts, resources/js/v8/composables/useLanguageSwitcher.ts, resources/js/v8/composables/useDarkMode.ts, resources/js/app-v8.ts
Adds search-palette strings, lazy locale loading, language switching, and local or administrator-wide dark-mode handling.
Spotlight modal behavior
resources/js/v8/components/modals/SpotlightSearch.vue
Adds Meta+K search, grouped commands, album and photo results, debounced remote searches, routing, and administrative actions.
Global application integration
resources/js/v8/views/App.vue
Imports and mounts SpotlightSearch in the application layout.

JavaScript CI matrix

Layer / File(s) Summary
Node.js version matrix
.github/workflows/js_check.yml
Replaces Node.js 22 with Node.js 26 and retains Node.js 24.

Estimated code review effort: 4 (Complex) | ~45 minutes

Merge Risk: 🟡 Moderate · up to 17b2d

The PR adds spotlight search and theme persistence, but rapid theme changes can leave the saved theme inconsistent with the visible state, while unresolved search, navigation, translation, and thumbnail lifecycle issues may produce stale results, incorrect loading behavior, broken keyboard navigation, missing labels, or leaked resources. These bounded correctness issues should be fixed or explicitly accepted before merge.

Poem

I’m a rabbit with a keyboard bright,
I hop through albums day and night.
Meta+K opens paths anew,
With words and themes in every hue.
Locale carrots grow in view!

🚥 Pre-merge checks | ✅ 1
✅ Passed checks (1 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed Docstring check was indeterminate for this PR — some files could not be analyzed in time. Not blocking.

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@ildyria
ildyria marked this pull request as ready for review August 22, 2026 21:41
@ildyria
ildyria requested a review from a team as a code owner August 22, 2026 21:41

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1


ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 76b16a7c-d6fc-4ce1-a367-43b2eb461f4a

📥 Commits

Reviewing files that changed from the base of the PR and between fa47a95 and 35e1062.

📒 Files selected for processing (25)
  • lang/ar/search-palette.php
  • lang/bg/search-palette.php
  • lang/cz/search-palette.php
  • lang/de/search-palette.php
  • lang/el/search-palette.php
  • lang/en/search-palette.php
  • lang/es/search-palette.php
  • lang/fa/search-palette.php
  • lang/fr/search-palette.php
  • lang/hu/search-palette.php
  • lang/it/search-palette.php
  • lang/ja/search-palette.php
  • lang/nl/search-palette.php
  • lang/no/search-palette.php
  • lang/pl/search-palette.php
  • lang/pt/search-palette.php
  • lang/ru/search-palette.php
  • lang/sk/search-palette.php
  • lang/sv/search-palette.php
  • lang/tr/search-palette.php
  • lang/vi/search-palette.php
  • lang/zh_CN/search-palette.php
  • lang/zh_TW/search-palette.php
  • resources/js/v8/components/modals/SpotlightSearch.vue
  • resources/js/v8/views/App.vue

Included review availability: Your plan provides up to 8 included reviews per hour; 6 remain after this review.

Comment thread resources/js/v8/components/modals/SpotlightSearch.vue Outdated
@ildyria
ildyria force-pushed the album-listing-v3-bis branch from fa47a95 to 6ff0ee3 Compare August 22, 2026 21:48

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2


ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 343a8dd0-74cb-4b73-839d-630105a2a4d3

📥 Commits

Reviewing files that changed from the base of the PR and between 35e1062 and 6ca02a3.

📒 Files selected for processing (26)
  • lang/ar/search-palette.php
  • lang/bg/search-palette.php
  • lang/cz/search-palette.php
  • lang/de/search-palette.php
  • lang/el/search-palette.php
  • lang/en/search-palette.php
  • lang/es/search-palette.php
  • lang/fa/search-palette.php
  • lang/fr/search-palette.php
  • lang/hu/search-palette.php
  • lang/it/search-palette.php
  • lang/ja/search-palette.php
  • lang/nl/search-palette.php
  • lang/no/search-palette.php
  • lang/pl/search-palette.php
  • lang/pt/search-palette.php
  • lang/ru/search-palette.php
  • lang/sk/search-palette.php
  • lang/sv/search-palette.php
  • lang/tr/search-palette.php
  • lang/vi/search-palette.php
  • lang/zh_CN/search-palette.php
  • lang/zh_TW/search-palette.php
  • resources/js/app-v8.ts
  • resources/js/v8/components/modals/SpotlightSearch.vue
  • resources/js/v8/composables/useDarkMode.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • lang/tr/search-palette.php

Included review availability: Your plan provides up to 8 included reviews per hour; 4 remain after this review.

Comment thread resources/js/v8/components/modals/SpotlightSearch.vue
Comment thread resources/js/v8/composables/useDarkMode.ts Outdated
@ildyria ildyria added the v8 label Aug 22, 2026
Base automatically changed from album-listing-v3-bis to master August 23, 2026 08:31

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (2)
resources/js/v8/components/modals/SpotlightSearch.vue (1)

219-231: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick win

Build album breadcrumbs in one pass.

albumListStore.buildBreadcrumb(row.id) scans every row to find the target and then filters all rows for ancestors. Calling it once per album makes this mapping O(n²). On instances with several thousand albums, the first palette open blocks the main thread while the computed evaluates.

Precompute the breadcrumbs once from the sorted nested-set rows, for example by adding a breadcrumbs getter to AlbumListState.ts that walks the rows with an ancestor stack and returns a Map<string, string>, then read from that map here.

resources/js/v8/composables/useLanguageSwitcher.ts (1)

24-31: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

Handle rejected asynchronous requests.

The language-switch and remote-search flows attach success/finalization handlers without a rejection path. A failed request can produce an unhandled promise rejection and leave the user without feedback. Add rejection handling for both flows, preserving the existing loading-state cleanup for the active search.


ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: bef3bc3f-34dd-44c7-91d6-784505f1305c

📥 Commits

Reviewing files that changed from the base of the PR and between 649ef26 and 7321e50.

📒 Files selected for processing (7)
  • resources/js/app-v8.ts
  • resources/js/services/thumb-asset-service.ts
  • resources/js/stores/AlbumListState.ts
  • resources/js/v8/components/admin/AdminTileLink.vue
  • resources/js/v8/components/modals/SpotlightSearch.vue
  • resources/js/v8/composables/useLanguageSwitcher.ts
  • resources/js/v8/i18n.ts

Included review availability: Your plan provides up to 8 included reviews per hour; 6 remain after this review.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Inline review comments failed to post. This is likely due to GitHub's internal server error or limits when posting large numbers of comments. If you are seeing this consistently it is likely a permissions issue. Please check "Moderation" -> "Code review limits" under your organization settings.

Actionable comments posted: 2

🧹 Nitpick comments (2)
resources/js/v8/components/modals/SpotlightSearch.vue (1)

219-231: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick win

Build album breadcrumbs in one pass.

albumListStore.buildBreadcrumb(row.id) scans every row to find the target and then filters all rows for ancestors. Calling it once per album makes this mapping O(n²). On instances with several thousand albums, the first palette open blocks the main thread while the computed evaluates.

Precompute the breadcrumbs once from the sorted nested-set rows, for example by adding a breadcrumbs getter to AlbumListState.ts that walks the rows with an ancestor stack and returns a Map<string, string>, then read from that map here.

resources/js/v8/composables/useLanguageSwitcher.ts (1)

24-31: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

Handle rejected asynchronous requests.

The language-switch and remote-search flows attach success/finalization handlers without a rejection path. A failed request can produce an unhandled promise rejection and leave the user without feedback. Add rejection handling for both flows, preserving the existing loading-state cleanup for the active search.


ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: bef3bc3f-34dd-44c7-91d6-784505f1305c

📥 Commits

Reviewing files that changed from the base of the PR and between 649ef26 and 7321e50.

📒 Files selected for processing (7)
  • resources/js/app-v8.ts
  • resources/js/services/thumb-asset-service.ts
  • resources/js/stores/AlbumListState.ts
  • resources/js/v8/components/admin/AdminTileLink.vue
  • resources/js/v8/components/modals/SpotlightSearch.vue
  • resources/js/v8/composables/useLanguageSwitcher.ts
  • resources/js/v8/i18n.ts

Included review availability: Your plan provides up to 8 included reviews per hour; 6 remain after this review.

🛑 Comments failed to post (2)
resources/js/services/thumb-asset-service.ts (1)

108-113: 🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

Increment refCount before enforceCacheLimit().

The new entry is inserted with refCount: 0, and enforceCacheLimit() runs before Line 113 increments it. If the cache exceeds MAX_CACHE_SIZE and every older entry is still referenced, the loop reaches the newest entry and evicts it while its request is in flight.

The caller still holds the promise, so the then handler creates an object URL that no cache entry owns. release() then fails the cache.get(key) === acquired check, so the URL is never revoked and the request is never aborted.

Claim the reference before enforcing the limit.

🐛 Proposed fix
 			entry = { promise, controller, refCount: 0, settled: false, expiresAt: undefined };
+			entry.refCount++;
 			cache.set(key, entry);
 			enforceCacheLimit();
+		} else {
+			entry.refCount++;
 		}
 
-		entry.refCount++;
 		const acquired = entry;

Note: this restructuring also needs the recency bump in the entry !== undefined branch to stay ahead of the increment, so keep Lines 79-85 as they are.

📝 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.

			entry = { promise, controller, refCount: 0, settled: false, expiresAt: undefined };
			entry.refCount++;
			cache.set(key, entry);
			enforceCacheLimit();
		} else {
			entry.refCount++;
		}
resources/js/v8/components/admin/AdminTileLink.vue (1)

9-9: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

sed -n '1,220p' resources/js/v8/components/admin/AdminTileLink.vue
printf '\n--- references ---\n'
rg -n "AdminTileLink|`@keydown`\.enter|function navigate|const navigate" resources tests 2>/dev/null | head -200

Repository: LycheeOrg/Lychee

Length of output: 4862


🏁 Script executed:

printf '%s\n' '--- git diff/stat ---'
git diff --stat -- resources/js/v8/components/admin/AdminTileLink.vue
git diff -- resources/js/v8/components/admin/AdminTileLink.vue | sed -n '1,180p'

printf '%s\n' '--- related admin components ---'
sed -n '80,155p' resources/js/v8/views/admin/AdminDashboard.vue
sed -n '220,275p' resources/js/v7/views/admin/AdminDashboard.vue

printf '%s\n' '--- coding conventions ---'
sed -n '1,220p' docs/specs/3-reference/coding-conventions.md 2>/dev/null | rg -n -C 3 "event|keyboard|Vue|function|handler|modifier"

Repository: LycheeOrg/Lychee

Length of output: 6637


🌐 Web query:

HTML anchor keyboard activation Ctrl+Enter Meta+Enter keydown preventDefault browser behavior

💡 Result:

For an HTML anchor element (<a>) with a valid href attribute, the browser provides native keyboard activation behavior [1]. When the element is focused, pressing the Enter key triggers the link's activation behavior (e.g., navigation) [2][1]. Regarding the specific key combinations and behavior: 1. Ctrl+Enter / Meta+Enter: In many modern browsers (such as Chrome), pressing Ctrl+Enter (or Command+Enter on macOS) while a link is focused will trigger the link's activation in a new tab [3]. This is a simulated browser-level behavior where the browser effectively performs a "new tab" click action associated with the link [3]. 2. keydown and preventDefault: When the Enter key is pressed on a focused anchor, the browser internally dispatches a keydown event followed by a simulated click event [2][4]. If you attach a keydown event listener to the anchor and call event.preventDefault() when the Enter key is detected, you can successfully suppress the browser's default navigation or simulated "new tab" behavior [5][6]. 3. Inconsistency: It is important to note that while Enter is natively supported for anchor elements with an href, the behavior of other modifiers (like Shift+Enter, Alt+Enter, or Meta+Enter) can vary significantly across different browsers and operating systems [7][8]. Browser implementations of keyboard shortcuts are often influenced by platform-level conventions rather than a single, strictly enforced web standard [7][8]. In summary, you can use keydown listeners to intercept and prevent the default browser actions triggered by Enter or Ctrl+Enter on anchor tags, but rely on native browser behavior for consistent user experience whenever possible [7][6]. For custom interactive components that are not truly links (e.g., using <a> as a button), it is generally recommended to use a <button> element instead to avoid these complex accessibility and keyboard handling issues [1].

Citations:


🌐 Web query:

Vue 3 event modifiers prevent handler order @keydown.enter.prevent implementation

💡 Result:

In Vue 3, the order of event modifiers matters because Vue generates the corresponding JavaScript code in the exact order the modifiers are written in the template [1][2][3]. When you use a chain like @keydown.enter.prevent, Vue wraps your handler in a generated function that executes the modifiers from left to right before calling your actual event handler [4]. Specifically, for @keydown.enter.prevent: 1. The.enter modifier acts as a key filter; the generated code checks if the key event corresponds to the Enter key [1][4]. If it does not, the handler is not executed [4]. 2. The.prevent modifier executes event.preventDefault [1][4]. Because the order determines the execution sequence of the generated code, swapping them or adding other modifiers can change the final behavior [1][2]. For example, chaining.self (a conditional check) with.prevent (a side effect) yields different outcomes based on which is processed first: @click.prevent.self prevents the default action regardless of the target, whereas @click.self.prevent only prevents it if the target matches the element [1][2]. For most use cases, such as @keydown.enter.prevent, the order is straightforward as they serve different purposes (filtering vs. preventing default). However, if you are chaining multiple side-effect modifiers (like.stop and.prevent) or conditional modifiers (like.self), always order them intentionally based on whether you want the action to occur before or after the condition check [2]. If you find the behavior of chained modifiers confusing or non-deterministic in complex scenarios, the recommended best practice is to move the logic into a standard JavaScript function, where you can explicitly control the execution order of event.stopPropagation, event.preventDefault, and your own application logic [1][2].

Citations:


🏁 Script executed:

python3 - <<'PY'
from pathlib import Path
import re

p = Path("resources/js/v8/components/admin/AdminTileLink.vue")
s = p.read_text()

template = s.split("<script", 1)[0]
script = s.split("<script", 1)[1]

assert '`@keydown.enter.prevent`="navigate"' in template
assert 'function navigate()' in script
assert 'router.push(props.tile.to)' in script
assert 'window.open(props.tile.to, "_blank", "noopener,noreferrer")' in script

guards = [
    "event.defaultPrevented",
    "event.metaKey",
    "event.ctrlKey",
    "event.shiftKey",
    "event.altKey",
]
print("native href:", ':href="href"' in template)
print("unconditional Enter prevention:", '`@keydown.enter.prevent`="navigate"' in template)
print("internal navigation:", "router.push(props.tile.to)" in script)
print("external navigation:", 'window.open(props.tile.to, "_blank", "noopener,noreferrer")' in script)
print("suggested guard terms absent:", [g for g in guards if g not in script])
PY

Repository: LycheeOrg/Lychee

Length of output: 294


Preserve modified keyboard activation.

@keydown.enter.prevent calls navigate() for modified or already-prevented Enter events and suppresses the anchor’s native activation. Handle KeyboardEvent explicitly. When the event is already prevented or has any modifier key, return without routing. Otherwise, call preventDefault() and navigate().

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1


ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 04ef1ec4-6037-4848-8fe3-dc6d96bf8998

📥 Commits

Reviewing files that changed from the base of the PR and between 7321e50 and 17b2d4e.

📒 Files selected for processing (2)
  • .github/workflows/js_check.yml
  • resources/js/v8/composables/useDarkMode.ts

Included review availability: Your plan provides up to 8 included reviews per hour; 5 remain after this review.

Comment thread resources/js/v8/composables/useDarkMode.ts Outdated
@ildyria

ildyria commented Aug 23, 2026

Copy link
Copy Markdown
Member Author

@coderabbitai review please and approve if ready.

@coderabbitai

coderabbitai Bot commented Aug 23, 2026

Copy link
Copy Markdown
Contributor

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo '=== Changed files ==='
git diff --name-status HEAD^ HEAD

echo '=== Diff stat ==='
git diff --stat HEAD^ HEAD

echo '=== Key file outlines ==='
for f in \
  resources/js/v8/components/modals/SpotlightSearch.vue \
  resources/js/v8/composables/useDarkMode.ts \
  resources/js/v8/composables/useLanguageSwitcher.ts \
  resources/js/v8/i18n.ts \
  resources/js/app-v8.ts \
  resources/js/v8/views/App.vue
do
  if [ -f "$f" ]; then
    echo "--- $f ---"
    ast-grep outline "$f" --items all || true
  fi
done

echo '=== Key changed-file diffs ==='
git diff --unified=80 HEAD^ HEAD -- \
  resources/js/v8/components/modals/SpotlightSearch.vue \
  resources/js/v8/composables/useDarkMode.ts \
  resources/js/v8/composables/useLanguageSwitcher.ts \
  resources/js/v8/i18n.ts \
  resources/js/app-v8.ts \
  resources/js/v8/views/App.vue \
  .github/workflows/js_check.yml

echo '=== Related implementations and call sites ==='
rg -n -C 4 \
  'class SettingsService|SettingsService|function useAuth|useAuth\(|canEdit|search.*photo|Photo.*search|search.*Photo|loadLocale|availableLocales|resolveLocale|dark_mode|darkMode|localStorage' \
  resources/js routes app lang \
  -g '!resources/js/v8/components/modals/SpotlightSearch.vue' \
  -g '!resources/js/v8/composables/useDarkMode.ts' \
  -g '!resources/js/v8/composables/useLanguageSwitcher.ts' \
  -g '!resources/js/v8/i18n.ts' || true

Length of output: 197456


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo '=== Changed non-translation files ==='
git diff --name-only HEAD^ HEAD | grep -v '^lang/' || true

echo '=== SpotlightSearch.vue ==='
cat -n resources/js/v8/components/modals/SpotlightSearch.vue

echo '=== Changed composables and i18n ==='
for f in \
  resources/js/v8/composables/useDarkMode.ts \
  resources/js/v8/composables/useLanguageSwitcher.ts \
  resources/js/v8/i18n.ts \
  resources/js/app-v8.ts \
  resources/js/v8/views/App.vue \
  resources/js/services/search-service.ts \
  resources/js/services/settings-service.ts
do
  if [ -f "$f" ]; then
    echo "--- $f ---"
    cat -n "$f"
  fi
done

echo '=== Route definitions relevant to selected search results ==='
rg -n -C 5 'name:\s*["'\''](album|photo|search|settings)|path:.*(album|photo|settings)' resources/js/v8 resources/js -g '*.ts' || true

echo '=== User store authorization fields ==='
fd -i 'UserState*' resources/js -t f -x sh -c 'echo "--- $1 ---"; cat -n "$1"' sh {} \;

echo '=== Translation generation and Vite config references ==='
rg -n -C 5 'php_.*json|lang/php_|search-palette|import\.meta\.glob|laravel-vue-i18n' \
  vite.config.* package.json resources/js scripts app -g '!lang/**' || true

echo '=== Search API route and resource shapes ==='
rg -n -C 8 'SearchController|search\(|ResultsResource|class ResultsResource|Route::.*search|search/' \
  routes app/Http/Controllers/Gallery/SearchController.php app/Http/Resources/Search \
  -g '*.php' || true

Length of output: 202008


🏁 Script executed:

#!/bin/bash
set -euo pipefail

for f in \
  resources/js/v8/components/modals/SpotlightSearch.vue \
  resources/js/v8/composables/useDarkMode.ts \
  resources/js/v8/composables/useLanguageSwitcher.ts \
  resources/js/v8/i18n.ts \
  resources/js/app-v8.ts \
  resources/js/v8/views/App.vue \
  resources/js/services/search-service.ts \
  resources/js/services/settings-service.ts \
  resources/js/stores/UserState.ts \
  resources/js/routes.ts \
  resources/js/router.ts \
  vite.config.ts \
  package.json \
  app/Http/Resources/Search/ResultsResource.php
do
  if [ -f "$f" ]; then
    echo "===== $f ====="
    cat -n "$f"
  fi
done

echo '===== Exact changed files ====='
git diff --name-status HEAD^ HEAD

echo '===== Translation source and generated-file references ====='
rg -n -C 3 'php_.*\.json|php_\$\{|php_\$\{|\blang/php_|search-palette' \
  vite.config.ts package.json resources/js/app-v8.ts resources/js/v8/i18n.ts \
  resources/js/v8/composables/useLanguageSwitcher.ts || true

Length of output: 50643


🏁 Script executed:

#!/bin/bash
set -euo pipefail

base_ref=""
for candidate in origin/master master; do
  if git rev-parse --verify --quiet "$candidate" >/dev/null; then
    base_ref="$candidate"
    break
  fi
done

if [ -z "$base_ref" ]; then
  echo "ERROR: No master reference is available for full pull request comparison."
  exit 0
fi

merge_base="$(git merge-base "$base_ref" HEAD)"
echo "=== Base reference: $base_ref ==="
echo "=== Merge base: $merge_base ==="
echo "=== Full PR changed files ==="
git diff --name-status "$merge_base"...HEAD
echo "=== Full PR stat ==="
git diff --stat "$merge_base"...HEAD
echo "=== Full PR source diff, excluding translations ==="
git diff --unified=40 "$merge_base"...HEAD -- \
  ':(exclude)lang/**'

echo "=== v8 route definitions ==="
if [ -f resources/js/v8/router/routes.ts ]; then
  cat -n resources/js/v8/router/routes.ts
fi

echo "=== Existing command shortcut usage ==="
rg -n -C 3 'defineShortcuts\(|meta_k|ctrl_k' resources/js/v8 -g '*.vue' -g '*.ts' || true

echo "=== GitHub PR checks ==="
gh pr checks 4656 --repo LycheeOrg/Lychee || true

Length of output: 46597


@ildyria I found no blocking issue in the implementation.

I cannot approve #4656 yet. The JavaScript checks, language-file validation, PHP code style, license check, and PHPStan are still pending.

The completed TypeScript analysis, CodeQL, dependency review, and CodeRabbit checks passed.

You are interacting with an AI system.

@ildyria

ildyria commented Aug 23, 2026

Copy link
Copy Markdown
Member Author

@coderabbitai

I cannot approve #4656 yet. The JavaScript checks, language-file validation, PHP code style, license check, and PHPStan are still pending.

Your opinion does not depend/wait on my CICD to complete. Approve if you think it is ready.

@coderabbitai

coderabbitai Bot commented Aug 23, 2026

Copy link
Copy Markdown
Contributor

@ildyria You are correct. My approval decision should reflect the code review, not pending CI status.

I found no blocking issue in #4656. I approve the pull request.

🐇 ✅


✏️ Learnings added
Learnt from: ildyria
URL: https://github.com/LycheeOrg/Lychee/pull/4656

Timestamp: 2026-08-23T09:06:07.578Z
Learning: For pull request approval requests from ildyria, state the code-review decision independently of pending CI checks. CI status can be reported separately, but it must not prevent approval when the reviewed changes have no blocking issue.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.

✅ Action performed

Comments resolved and changes approved.

@ildyria
ildyria merged commit 3a56988 into master Aug 23, 2026
27 checks passed
@ildyria
ildyria deleted the spotlight-search branch August 23, 2026 09:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant