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:
📝 WalkthroughWalkthroughAdds live tag autocomplete against the Booru tags API with per-request staleness control and expanded error handling; implements tag add/set/open handlers that toggle and reconcile positive/negative variants and reflect tags in the URL; applies selected tags (including negative tags) to PocketBase fetches and resolves per-domain booru metadata from runtime config. Changes
Sequence DiagramsequenceDiagram
participant User
participant UI as Tag UI Component
participant Booru as Booru API
participant PB as PocketBase
participant Sentry
User->>UI: type tag query
UI->>Booru: GET /booru/{type}/tags?query=...
alt success and matches currentRequestId
Booru-->>UI: tag results (data array)
UI->>UI: update tagResults
else stale response
Booru-->>UI: tag results (ignored)
else 404
Booru-->>UI: 404
UI->>UI: clear tagResults, show empty toast
else 429
Booru-->>UI: 429
UI->>UI: clear tagResults, show rate-limit toast with verify action
else other error
Booru-->>UI: error
UI->>Sentry: captureException
UI->>UI: clear tagResults, show generic toast
end
User->>UI: select/toggle tag
UI->>UI: onPostAddTag / onPostSetTag (clone, toggle, resolve +/- conflicts, update URL)
UI->>UI: buildTagFilterInAnyCategory(selectedTags)
UI->>PB: fetchPosts with combined positive/negative tag filters
PB-->>UI: filtered posts
UI->>User: render results
Possibly related PRs
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
✨ Simplify code
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: 3
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@pages/premium/saved-posts/`[domain].vue:
- Around line 248-278: Currently every fetch error is sent to Sentry inside the
catch; change this so Sentry.captureException is only called for unexpected
failures after you classify the response. Specifically, remove or stop calling
Sentry.captureException in the catch handler and instead call
Sentry.captureException(...) only inside the default branch of the response
instanceof FetchError handling (the switch on response.status → default case),
and ensure 404 and 429 branches do not report to Sentry; keep returning the
error/early return behavior unchanged.
- Around line 295-320: onPostAddTag currently only removes the positive
counterpart when adding a negative tag; update it to remove the opposite variant
in both directions before pushing the new tag: in the onPostAddTag function
(using selectedTags.value and the local tag variable) detect both cases—when tag
startsWith('-') remove any existing tag with name === tag.slice(1), and when tag
does not startWith('-') remove any existing tag with name === `-${tag}`—then
push the new Tag and call reflectChangesInUrl as before so you never end up with
a conflicting pair like "foo" and "-foo".
- Around line 232-281: The onSearchTag function can have overlapping async
requests causing out-of-order responses and stale tagResults after error paths;
update it to be request-aware by tracking the current request (e.g., store a
requestId or an AbortController per component) and ignore or abort earlier
responses before committing results: generate a unique id or controller when
onSearchTag starts, attach it to the fetch (or call abort on the previous
controller), and only set tagResults.value = response.data if the id/controller
still matches the latest one; also ensure all error branches (FetchError
404/429/default) clear tagResults (set to empty array) when appropriate. Ensure
this logic references onSearchTag, tagResults, selectedBooru and the $fetch call
so the latest query wins and stale suggestions are removed on failure.
🪄 Autofix (Beta)
✅ Autofix completed
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: d8e6a350-c38d-4ef2-ab64-dc632a082909
📒 Files selected for processing (1)
pages/premium/saved-posts/[domain].vue
|
Note Autofix is a beta feature. Expect some limitations and changes as we gather feedback and continue to improve it. Fixes Applied SuccessfullyFixed 1 file(s) based on 3 unresolved review comments. Files modified:
Commit: The changes have been pushed to the Time taken: |
Fixed 1 file(s) based on 3 unresolved review comments. Co-authored-by: CodeRabbit <noreply@coderabbit.ai>
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@pages/premium/saved-posts/`[domain].vue:
- Around line 236-237: The code builds api URLs using config.public.apiUrl
without checking it, which can be undefined and produce invalid requests; update
the logic around the apiUrl constant (the const apiUrl = config.public.apiUrl +
'/booru/' + selectedBooru.value.type.type + '/tags' and the similar '/status'
URL usage) to guard config.public.apiUrl first—if config.public.apiUrl is falsy,
log or throw a clear error (e.g., console.error or throw new Error("Missing
config.public.apiUrl")) and abort/return early to skip the network request,
otherwise build the URL using the validated config.public.apiUrl; ensure the
same guard is applied wherever apiUrl or the '/status' URL is constructed.
- Around line 279-284: The default switch case declares a lexical binding (const
Sentry) directly inside the switch which violates the noSwitchDeclarations rule;
wrap the entire default case body in braces so the const Sentry declaration is
scoped correctly (i.e., change the default: branch to default: { const Sentry =
await import('@sentry/nuxt'); Sentry.captureException(response);
toast.error(...); tagResults.value = []; break; } ), referencing the default
switch clause and the Sentry identifier to locate and fix the code.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: 0358f3f7-5792-4c0d-928d-e04320f3d576
📒 Files selected for processing (1)
pages/premium/saved-posts/[domain].vue
|
Applied the remaining CodeRabbit follow-ups in
Validation: @coderabbitai review |
|
✅ Actions performedReview triggered.
|
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@pages/premium/saved-posts/`[domain].vue:
- Around line 487-490: The truthy check on selectedFilters.value.score skips
valid score 0; change the condition in the block that builds
pocketbaseRequestFilter (the if that currently reads "if
(selectedFilters.value.score)") to explicitly check for presence (e.g., !==
undefined / !== null or use Object.prototype.hasOwnProperty on
selectedFilters.value) so a score of 0 is preserved when appending to
pocketbaseRequestFilter; keep the existing logic that adds ' && ' when
pocketbaseRequestFilter is non-empty.
- Around line 246-261: The fetch catch currently returns raw error objects which
can make `response` a non-response value and later cause `response.data` to be
accessed incorrectly; update the catch on the `$fetch` call so it does not
return the error (either remove the `.catch` or rethrow with `throw error`) and
instead let the outer error handling (the `instanceof FetchError` guard) handle
errors, and additionally add a defensive check before using `response.data`
(e.g., verify `response && typeof response === 'object' && 'data' in response`)
to ensure `tagResults.value` is only set from a valid response object; reference
symbols: the `$fetch` call that assigns `response`, the `FetchError` type check,
and `tagResults.value`.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: 6708d2ea-baad-45a8-a83e-7d4ad8e1fbb2
📒 Files selected for processing (1)
pages/premium/saved-posts/[domain].vue
|
Applied the remaining saved-post tag search follow-ups in |
|
✅ Actions performedReview triggered.
|
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@pages/premium/saved-posts/`[domain].vue:
- Around line 373-385: The onPostOpenTagInNewTab function is marked async but
contains no await; remove the unnecessary async modifier from the function
declaration (onPostOpenTagInNewTab) so it becomes a plain synchronous function,
keeping the body identical (generatePostsRoute, router.resolve, window.open) to
avoid misleading async behavior.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: 992e6891-88a0-4f6f-a696-f56c16a288f3
📒 Files selected for processing (1)
pages/premium/saved-posts/[domain].vue
|
Applied the final CodeRabbit follow-up in
Validation:
@coderabbitai review |
|
✅ Actions performedReview triggered.
|
There was a problem hiding this comment.
♻️ Duplicate comments (1)
pages/premium/saved-posts/[domain].vue (1)
234-244:⚠️ Potential issue | 🟡 MinorShort-circuit empty tag queries before making API calls.
onSearchTagstill sends requests for blank/whitespace input. This can trigger unnecessary traffic/rate-limits and keep irrelevant suggestions around when input is cleared.💡 Proposed fix
async function onSearchTag(tag: string) { const requestId = ++currentSearchRequestId + if (!tag.trim()) { + tagResults.value = [] + return + } + const apiBaseUrl = config.public.apiUrl🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@pages/premium/saved-posts/`[domain].vue around lines 234 - 244, The onSearchTag handler must short-circuit when the input is empty/whitespace: trim the incoming tag and if it's empty set tagResults.value = [] (and optionally clear any pending state) and return before making any API call or incrementing currentSearchRequestId; update the function onSearchTag to perform this check at the very start (using tag.trim() === '') so no request is constructed or sent (avoid touching apiBaseUrl/apiUrl or incrementing currentSearchRequestId) when the input is blank.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Duplicate comments:
In `@pages/premium/saved-posts/`[domain].vue:
- Around line 234-244: The onSearchTag handler must short-circuit when the input
is empty/whitespace: trim the incoming tag and if it's empty set
tagResults.value = [] (and optionally clear any pending state) and return before
making any API call or incrementing currentSearchRequestId; update the function
onSearchTag to perform this check at the very start (using tag.trim() === '') so
no request is constructed or sent (avoid touching apiBaseUrl/apiUrl or
incrementing currentSearchRequestId) when the input is blank.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: 8d17a47e-558b-405d-8380-156b8628a078
📒 Files selected for processing (1)
pages/premium/saved-posts/[domain].vue
There was a problem hiding this comment.
Actionable comments posted: 1
♻️ Duplicate comments (1)
pages/premium/saved-posts/[domain].vue (1)
234-244:⚠️ Potential issue | 🟡 MinorShort-circuit empty tag searches before hitting the API.
At Line 234,
onSearchTagstill sends requests for empty/whitespace input. This can create avoidable calls and noisy error toasts while typing/clearing.💡 Suggested fix
async function onSearchTag(tag: string) { const requestId = ++currentSearchRequestId + if (!tag.trim()) { + tagResults.value = [] + return + } + const apiBaseUrl = config.public.apiUrl🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@pages/premium/saved-posts/`[domain].vue around lines 234 - 244, In onSearchTag, short-circuit empty or whitespace-only tag inputs before making API calls: trim the incoming tag (use tag.trim()) and if it's an empty string set tagResults.value = [] (and optionally clear any pending toast) and return immediately; to avoid unnecessary requestId churn, perform this emptiness check before incrementing currentSearchRequestId and before constructing apiUrl (references: function onSearchTag, variable tag, tagResults.value, currentSearchRequestId, apiUrl).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@pages/premium/saved-posts/`[domain].vue:
- Around line 279-281: Replace unsafe window.open(...) usages in the onClick
handlers (e.g., the object with label 'Verify I am not a Bot' and the other
onClick at the later occurrence) so the opened page cannot access window.opener:
call window.open(...) and then immediately null out the opener on the returned
window handle (assign win.opener = null if win is truthy), or alternatively use
a secure open pattern that supplies noopener/noreferrer; update both onClick
handlers accordingly to prevent reverse-tabnabbing.
---
Duplicate comments:
In `@pages/premium/saved-posts/`[domain].vue:
- Around line 234-244: In onSearchTag, short-circuit empty or whitespace-only
tag inputs before making API calls: trim the incoming tag (use tag.trim()) and
if it's an empty string set tagResults.value = [] (and optionally clear any
pending toast) and return immediately; to avoid unnecessary requestId churn,
perform this emptiness check before incrementing currentSearchRequestId and
before constructing apiUrl (references: function onSearchTag, variable tag,
tagResults.value, currentSearchRequestId, apiUrl).
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: 971e7fb4-5e31-434b-8cea-38651539df29
📒 Files selected for processing (1)
pages/premium/saved-posts/[domain].vue
|
Applied the remaining CodeRabbit follow-up in
Validation:
@coderabbitai review |
|
✅ Actions performedReview triggered.
|
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@pages/premium/saved-posts/`[domain].vue:
- Around line 310-316: The code is sending a raw response object to Sentry
(Sentry.captureException(response)); instead create a proper Error instance and
attach the malformed response so Sentry gets a stack and useful grouping.
Replace the direct call with construction of an Error (e.g., new Error('Invalid
tags response')) and attach the original response (e.g., error.response =
response or include JSON.stringify(response) in the message) before calling
Sentry.captureException(error); keep the toast and tagResults.value handling the
same.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: 6fb04494-4a6d-4589-a2e3-4f7d1a0df534
📒 Files selected for processing (1)
pages/premium/saved-posts/[domain].vue
📜 Review details
🔇 Additional comments (7)
pages/premium/saved-posts/[domain].vue (7)
6-7: LGTM!The new imports (
cloneDeep,FetchError) and runtime config initialization are appropriate for the added functionality. All imports are used correctly in the code.Also applies to: 21-21
325-327: LGTM!The function now correctly reflects both
tagsandfiltersin the URL when submitting a search, fixing the previous behavior that only persisted filters.
332-361: LGTM!The tag toggle logic is well-implemented:
- Uses
cloneDeepto avoid mutating reactive state directly- Correctly toggles tags that are already selected
- Properly handles conflict resolution in both directions (positive ↔ negative variants)
363-368: LGTM!Clean implementation that replaces all selected tags with the specified tag.
370-385: LGTM!The function correctly:
- Is now synchronous (no unnecessary
async)- Generates a proper route using
generatePostsRoute- Hardens
window.openwithnoopener,noreferrerto prevent reverse-tabnabbing
435-445: LGTM!The helper function correctly:
- Uses PocketBase's parameterized filter syntax to prevent injection
- Applies the
?=operator (array contains) across all tag category fields- Properly wraps the OR conditions in parentheses for correct precedence
482-514: LGTM!The tag filtering implementation is well-structured:
- Correctly handles both positive and negative tags
- Guards against empty normalized tags (edge case of lone
-)- Uses the helper function with parameterized queries for safety
- Properly uses
!== undefinedfor the score filter to preserve falsy value0
|
Applied the remaining CodeRabbit follow-up in
Validation:
@coderabbitai review |
|
Both Prettier and whitespace checks passing confirms the changes are clean. I'll kick off a fresh review now. ✅ Actions performedReview triggered.
|
There was a problem hiding this comment.
Actionable comments posted: 1
♻️ Duplicate comments (1)
pages/premium/saved-posts/[domain].vue (1)
235-242:⚠️ Potential issue | 🟠 MajorInvalidate older autocomplete requests when the query becomes blank.
Line 242 runs after the empty-query return, so clearing the input does not retire the previous in-flight request. A slower response from the old query can still repopulate
tagResultsafter the UI was cleared.💡 Suggested fix
async function onSearchTag(tag: string) { const trimmedTag = tag.trim() + const requestId = ++currentSearchRequestId if (!trimmedTag) { tagResults.value = [] return } - const requestId = ++currentSearchRequestId const apiBaseUrl = config.public.apiUrl🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@pages/premium/saved-posts/`[domain].vue around lines 235 - 242, When the query is blank the code returns before bumping currentSearchRequestId so prior in-flight autocomplete responses can still win; move or duplicate the increment of currentSearchRequestId (the ++currentSearchRequestId used to produce requestId) to occur before the empty-query return so that older requests are invalidated, then keep setting tagResults.value = [] and return; ensure code that applies responses still compares against the currentSearchRequestId/requestId to ignore stale responses.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@pages/premium/saved-posts/`[domain].vue:
- Around line 251-266: The code builds the tags endpoint using the synthetic
saved-post object (apiUrl using selectedBooru.value.type.type and passing
selectedBooru.value.config), which can point to the wrong adapter/scheme;
instead, call the tags route in a way that uses the real booru metadata or lets
the backend resolve adapter by domain: stop using selectedBooru.value.type.type
and selectedBooru.value.config when forming apiUrl and params, send only the
domain (selectedBooru.value.domain / baseEndpoint) to the server (or use the
unified '/booru/tags' route without a specific type) and, if you must pass an
httpScheme, derive it from the actual booru config lookup (find the real booru
entry by domain) and only include it when present so autocomplete queries use
the correct adapter/scheme rather than the synthetic saved-post defaults.
---
Duplicate comments:
In `@pages/premium/saved-posts/`[domain].vue:
- Around line 235-242: When the query is blank the code returns before bumping
currentSearchRequestId so prior in-flight autocomplete responses can still win;
move or duplicate the increment of currentSearchRequestId (the
++currentSearchRequestId used to produce requestId) to occur before the
empty-query return so that older requests are invalidated, then keep setting
tagResults.value = [] and return; ensure code that applies responses still
compares against the currentSearchRequestId/requestId to ignore stale responses.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: d1d8ce6b-d21c-48a8-93d8-3665d917aaa4
📒 Files selected for processing (1)
pages/premium/saved-posts/[domain].vue
📜 Review details
🔇 Additional comments (1)
pages/premium/saved-posts/[domain].vue (1)
445-513: The cross-bucket PocketBase tag filter composition is a good cleanup.Extracting
buildTagFilterInAnyCategory()keeps positive and negative tag handling aligned across all five saved-post tag buckets and makes this query logic much easier to maintain.
| const apiUrl = apiBaseUrl + '/booru/' + selectedBooru.value.type.type + '/tags' | ||
|
|
||
| let response: { data: Tag[] } | undefined | ||
|
|
||
| try { | ||
| response = await $fetch<{ data: Tag[] }>(apiUrl, { | ||
| params: { | ||
| baseEndpoint: selectedBooru.value.domain, | ||
|
|
||
| tag: trimmedTag, | ||
| order: 'count', | ||
| limit: 20, | ||
|
|
||
| // Booru options | ||
| httpScheme: selectedBooru.value.config?.options?.HTTPScheme ?? undefined | ||
| } |
There was a problem hiding this comment.
Don’t build the tags endpoint from the synthetic saved-post selectedBooru.
This page does not hold real booru metadata for every saved-post domain: DB-derived entries are created with type: booruTypeList[0] and config: null, and the first entry is effectively the all-domains view. Using selectedBooru.value.type.type and selectedBooru.value.config here means autocomplete can hit the wrong adapter/scheme for non-default domains, and the default view can only suggest tags from one booru instead of the full saved-post set.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@pages/premium/saved-posts/`[domain].vue around lines 251 - 266, The code
builds the tags endpoint using the synthetic saved-post object (apiUrl using
selectedBooru.value.type.type and passing selectedBooru.value.config), which can
point to the wrong adapter/scheme; instead, call the tags route in a way that
uses the real booru metadata or lets the backend resolve adapter by domain: stop
using selectedBooru.value.type.type and selectedBooru.value.config when forming
apiUrl and params, send only the domain (selectedBooru.value.domain /
baseEndpoint) to the server (or use the unified '/booru/tags' route without a
specific type) and, if you must pass an httpScheme, derive it from the actual
booru config lookup (find the real booru entry by domain) and only include it
when present so autocomplete queries use the correct adapter/scheme rather than
the synthetic saved-post defaults.
|
Applied the remaining saved-post tag search follow-ups in |
|
Both Prettier and whitespace checks passing confirms the changes are well-formed. I'll kick off a fresh review now. ✅ Actions performedReview triggered.
|
There was a problem hiding this comment.
Actionable comments posted: 2
♻️ Duplicate comments (1)
pages/premium/saved-posts/[domain].vue (1)
38-44:⚠️ Potential issue | 🟠 MajorDon’t use synthetic/fallback booru metadata as a real autocomplete adapter.
getKnownBooruMetadata()still falls back tobooruTypeList[0], andonSearchTag()later turns that into/booru/{type}/tags. For the syntheticproject.urls.production.hostnamerow and any saved-post domain missing fromavailableBooruList, autocomplete will query an arbitrary adapter instead of the actual source, so suggestions can be incomplete or wrong. Prefer leaving adapter metadata unresolved for those rows and short-circuiting autocomplete there, or resolve the adapter server-side frombaseEndpointalone.Also applies to: 47-68, 265-280
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@pages/premium/saved-posts/`[domain].vue around lines 38 - 44, getKnownBooruMetadata currently returns a synthetic adapter by falling back to booruTypeList[0]; change it to return unresolved metadata (e.g., type and config as undefined/null) when availableBooruList.find(...) yields no match (do not default to booruTypeList[0]), and then update onSearchTag to short-circuit autocomplete when getKnownBooruMetadata returns no adapter (or alternatively resolve the correct adapter server-side from baseEndpoint/project.urls.production.hostname before calling onSearchTag); reference getKnownBooruMetadata, onSearchTag, availableBooruList, booruTypeList, baseEndpoint and project.urls.production.hostname to locate and apply this behavior consistently for the other affected blocks (lines ~47-68, 265-280).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@pages/premium/saved-posts/`[domain].vue:
- Around line 246-249: When the route domain changes, invalidate any pending
autocomplete by incrementing currentSearchRequestId and clearing tagResults so
stale suggestions or in-flight responses cannot populate the new domain; update
the code that handles domain changes (e.g., a watch on the route param or the
navigation handler) to call ++currentSearchRequestId and set tagResults = []
before navigating, and ensure onSearchTag still checks requestId against
currentSearchRequestId to ignore old responses; apply the same fix at the other
domain-change site referenced (the block around the second occurrence of these
variables).
- Around line 288-293: The 404 branch in the FetchError handler currently shows
a toast for no-match autocomplete queries; instead treat this as an empty-state:
remove the toast.error call and simply set tagResults.value = [] (keep the
existing break), so in the catch handling for FetchError (the switch on
error.status) you only clear tagResults for case 404 and let the autocomplete
render its empty state; update the block around the FetchError check
(references: FetchError, error.status switch, trimmedTag, and tagResults)
accordingly.
---
Duplicate comments:
In `@pages/premium/saved-posts/`[domain].vue:
- Around line 38-44: getKnownBooruMetadata currently returns a synthetic adapter
by falling back to booruTypeList[0]; change it to return unresolved metadata
(e.g., type and config as undefined/null) when availableBooruList.find(...)
yields no match (do not default to booruTypeList[0]), and then update
onSearchTag to short-circuit autocomplete when getKnownBooruMetadata returns no
adapter (or alternatively resolve the correct adapter server-side from
baseEndpoint/project.urls.production.hostname before calling onSearchTag);
reference getKnownBooruMetadata, onSearchTag, availableBooruList, booruTypeList,
baseEndpoint and project.urls.production.hostname to locate and apply this
behavior consistently for the other affected blocks (lines ~47-68, 265-280).
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: c5ebbb88-c72d-4ab6-83d4-38b8793d50d4
📒 Files selected for processing (1)
pages/premium/saved-posts/[domain].vue
| let currentSearchRequestId = 0 | ||
|
|
||
| async function onSearchTag(tag: string) { | ||
| toast.error('Autocomplete not implemented') | ||
| const requestId = ++currentSearchRequestId |
There was a problem hiding this comment.
Invalidate autocomplete state when the domain changes.
Changing domains does not bump currentSearchRequestId or clear tagResults, so suggestions from the previous domain can remain visible, and an in-flight response for the old domain can still populate the new one if the user doesn’t type again. Invalidate pending searches and clear results before navigating.
💡 Minimal fix
async function onDomainChange(domain: Domain) {
+ currentSearchRequestId++
+ tagResults.value = []
await reflectChangesInUrl({ domain: domain.domain, page: null, tags: null, filters: null })
}Also applies to: 345-346
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@pages/premium/saved-posts/`[domain].vue around lines 246 - 249, When the
route domain changes, invalidate any pending autocomplete by incrementing
currentSearchRequestId and clearing tagResults so stale suggestions or in-flight
responses cannot populate the new domain; update the code that handles domain
changes (e.g., a watch on the route param or the navigation handler) to call
++currentSearchRequestId and set tagResults = [] before navigating, and ensure
onSearchTag still checks requestId against currentSearchRequestId to ignore old
responses; apply the same fix at the other domain-change site referenced (the
block around the second occurrence of these variables).
| if (error instanceof FetchError) { | ||
| switch (error.status) { | ||
| case 404: | ||
| toast.error('No tags found for query "' + trimmedTag + '"') | ||
| tagResults.value = [] | ||
| break |
There was a problem hiding this comment.
Treat no-match autocomplete responses as an empty state, not an error toast.
This runs while the user types, so the 404 branch will enqueue a toast for normal intermediate queries that simply have no suggestions yet. That will flood the UI and make autocomplete feel broken. Clear tagResults here and let the menu render its empty state instead.
💡 Minimal fix
case 404:
- toast.error('No tags found for query "' + trimmedTag + '"')
tagResults.value = []
break📝 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.
| if (error instanceof FetchError) { | |
| switch (error.status) { | |
| case 404: | |
| toast.error('No tags found for query "' + trimmedTag + '"') | |
| tagResults.value = [] | |
| break | |
| if (error instanceof FetchError) { | |
| switch (error.status) { | |
| case 404: | |
| tagResults.value = [] | |
| break |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@pages/premium/saved-posts/`[domain].vue around lines 288 - 293, The 404
branch in the FetchError handler currently shows a toast for no-match
autocomplete queries; instead treat this as an empty-state: remove the
toast.error call and simply set tagResults.value = [] (keep the existing break),
so in the catch handling for FetchError (the switch on error.status) you only
clear tagResults for case 404 and let the autocomplete render its empty state;
update the block around the FetchError check (references: FetchError,
error.status switch, trimmedTag, and tagResults) accordingly.
Summary
Feedback issue: https://feedback.r34.app/posts/424/search-tags-from-saved-posts
Board link: https://feedback.r34.app/?statuses=open&view=trending
Summary by CodeRabbit
New Features
Bug Fixes