Skip to content

Show loading state when VIP link is unavailable and fix error handling#122

Merged
Yashb404 merged 7 commits into
feat/keys-freshfrom
copilot/sub-pr-116-please-work
Feb 11, 2026
Merged

Show loading state when VIP link is unavailable and fix error handling#122
Yashb404 merged 7 commits into
feat/keys-freshfrom
copilot/sub-pr-116-please-work

Conversation

Copy link
Copy Markdown

Copilot AI commented Feb 11, 2026

Addresses feedback to replace empty input field with helpful message when embed_key is not yet generated, and fixes error handling issues identified in code review.

Changes

VIP Link Loading State (Original Scope)

Modified client/src/components/modal.rs:

  • Added conditional rendering in VIP link section based on vip_link state
  • When empty: displays centered loading state with generation message and refresh instructions
  • When available: displays input field with copy button as before

Error Handling Improvements (Code Review Feedback)

Modified client/src/pages/dashboard.rs:

  • Handle JSON parse failure explicitly when fetching user data
  • Set loading state to false and show error message to prevent stuck spinner
  • Added match statement to properly handle parse errors

Modified client/src/pages/create.rs:

  • Added separate spawn_error signal to track environment spawn failures
  • Display explicit error message instead of attempting WebSocket connection with invalid container ID
  • Prevents confusing WebSocket errors when spawn fails
  • Uses CSS variables for consistent styling

Formatting Changes

Multiple client files:

  • Applied cargo fmt for consistent code style across the codebase
  • Reordered imports following Rust conventions
  • Minor whitespace adjustments

Implementation

VIP Link Loading State

Uses Leptos reactive signals to switch between states:

{move || {
    let link = vip_link.get();
    if link.is_empty() {
        view! {
            <div style="...">
                <p>"🔒 VIP link is being generated..."</p>
                <p>"Refresh this page to see your private VIP link once it's ready."</p>
            </div>
        }.into_view()
    } else {
        view! { /* input field with copy button */ }.into_view()
    }
}}

Error Handling

  • Dashboard: Explicit JSON parse error handling prevents infinite loading spinner
  • Create page: Separate error state ensures clear error messages and prevents invalid WebSocket connections

All changes ensure users see clear error messages instead of stuck loading states or cryptic connection failures.


💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

Copilot AI and others added 2 commits February 11, 2026 04:51
Co-authored-by: Yashb404 <139128977+Yashb404@users.noreply.github.com>
Co-authored-by: Yashb404 <139128977+Yashb404@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix secure embed authorization with loading state improvement Show loading state when VIP link is unavailable Feb 11, 2026
Copilot AI requested a review from Yashb404 February 11, 2026 05:00
@Yashb404 Yashb404 marked this pull request as ready for review February 11, 2026 05:38
@Yashb404 Yashb404 requested a review from Copilot February 11, 2026 05:38
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR improves the “Share / Embed” modal UX by showing a helpful loading/message state when the VIP link (embed_key) hasn’t been generated yet, instead of rendering an empty input. It also includes broad formatting/import reordering changes across the client UI.

Changes:

  • Add conditional rendering in the VIP link section to show a “being generated” message when vip_link is empty.
  • Reformat/reorder imports and adjust whitespace across many Leptos page/component files (rustfmt-style cleanup).
  • Minor request/closure formatting changes in several pages/components touched by the formatting sweep.

Reviewed changes

Copilot reviewed 15 out of 18 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
client/src/types.rs Formatting cleanup only.
client/src/pages/view.rs Import/formatting cleanup; still sets vip_link empty when embed_key missing.
client/src/pages/policy.rs Import/formatting cleanup.
client/src/pages/home.rs Import/formatting cleanup.
client/src/pages/embed.rs Import/formatting cleanup.
client/src/pages/docs.rs Import/formatting cleanup.
client/src/pages/dashboard.rs Formatting + touched auth/projects loading logic (see comments).
client/src/pages/create.rs Formatting; spawn error handling currently overloads container_id (see comments).
client/src/pages/blogs.rs Import/formatting cleanup.
client/src/pages/analytics.rs Import/formatting cleanup.
client/src/pages/admin.rs Import/formatting cleanup.
client/src/lib.rs Module ordering/formatting cleanup.
client/src/components/terminal.rs Import/formatting cleanup.
client/src/components/protected.rs Import/formatting cleanup.
client/src/components/modal.rs Functional change: VIP link empty state now shows a centered message instead of empty input.
client/src/components/limit.rs Formatting cleanup.
client/src/app.rs Import formatting cleanup.
client/src/api.rs Comment whitespace cleanup.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread client/src/pages/dashboard.rs Outdated
Comment on lines +31 to +36
if resp.ok() {
if let Ok(u) = resp.json::<User>().await {
// user authenticated
set_user.set(Some(u.clone()));

let proj_url = format!("{}/api/my-projects", api_base());
let projects_req = Request::get(&proj_url)
.credentials(RequestCredentials::Include)
.send()
.await;
let proj_url = format!("{}/api/my-projects", api_base());
Copy link

Copilot AI Feb 11, 2026

Choose a reason for hiding this comment

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

In the auth resource, if resp.ok() is true but resp.json::<User>().await fails, set_loading is never set to false and no error is surfaced, leaving the dashboard stuck on the spinner. Handle the JSON parse failure explicitly (set an error message and set loading to false) so the UI can exit the loading state.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Fixed in commit f149003. Now explicitly handles JSON parse failure with a match statement, setting loading to false and displaying "Failed to parse user data" error message to prevent stuck spinner.

Comment thread client/src/components/modal.rs Outdated
Comment on lines +137 to +144
{move || {
let link = vip_link.get();
let vip_link_for_input = vip_link.clone();
let vip_link_for_button = vip_link_for_click.clone();
if link.is_empty() {
view! {
<div style="background: var(--bg-secondary); border: 1px solid var(--border); border-radius: 8px; padding: 16px; text-align: center;">
<p style="color: var(--text-muted); font-size: 0.85rem; margin: 0;">
Copy link

Copilot AI Feb 11, 2026

Choose a reason for hiding this comment

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

The PR description says only client/src/components/modal.rs was modified, but this PR also includes widespread formatting/import reordering across many client/src/pages/* files. Please update the PR description to reflect the additional scope or split the formatting-only changes into a separate PR to keep the behavioral change reviewable.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Updated the PR description to accurately reflect all changes including the formatting/import reordering that was applied via cargo fmt, along with the error handling improvements added based on code review feedback.

Comment on lines +186 to +194
} else {
let status = spawn_resp.status();
let text = spawn_resp.text().await.unwrap_or_default();
set_container_id.set(format!("ERROR {}: {}", status, text));
}
} else {
let status = spawn_resp.status();
let text = spawn_resp.text().await.unwrap_or_default();
set_container_id.set(format!("ERROR {}: {}", status, text));
}
}
Err(e) => {
set_container_id.set(format!("NETWORK_FAIL: {}", e));
Err(e) => {
set_container_id.set(format!("NETWORK_FAIL: {}", e));
}
Copy link

Copilot AI Feb 11, 2026

Choose a reason for hiding this comment

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

container_id is used to decide when to render TerminalView, but on spawn failures it is set to strings like "ERROR ..." / "NETWORK_FAIL ...". That makes the UI attempt to open a WebSocket for an invalid session id, obscuring the real spawn error. Keep container_id as an actual id (or Option<String>) and track spawn errors in a separate signal so you can render an explicit error state instead of TerminalView.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Fixed in commits f149003 and 33a77cb. Added separate spawn_error signal to track spawn failures. Now displays explicit error message instead of attempting WebSocket connection with invalid container ID. Error state shows:

⚠️ Environment Spawn Error
[error details]

This prevents confusing WebSocket errors and clearly communicates spawn failures to users.

@Yashb404
Copy link
Copy Markdown
Member

@copilot apply changes based on the comments in this thread

Copilot AI and others added 3 commits February 11, 2026 06:42
- dashboard.rs: Handle JSON parse failure explicitly to prevent stuck loading state
- create.rs: Separate spawn error state from container_id to avoid invalid WebSocket connections

Co-authored-by: Yashb404 <139128977+Yashb404@users.noreply.github.com>
Co-authored-by: Yashb404 <139128977+Yashb404@users.noreply.github.com>
Co-authored-by: Yashb404 <139128977+Yashb404@users.noreply.github.com>
Copy link
Copy Markdown
Author

Copilot AI commented Feb 11, 2026

@copilot apply changes based on the comments in this thread

Applied all changes from the review thread:

  1. Dashboard error handling (f149003): Fixed JSON parse failure handling to prevent stuck loading spinner
  2. Create page error handling (f149003, 33a77cb): Added separate error state to avoid invalid WebSocket connections on spawn failures
  3. PR description updated: Now reflects all changes including formatting scope

All issues identified in the review have been addressed.

Copilot AI changed the title Show loading state when VIP link is unavailable Show loading state when VIP link is unavailable and fix error handling Feb 11, 2026
@Yashb404 Yashb404 merged commit eb0424e into feat/keys-fresh Feb 11, 2026
@Yashb404 Yashb404 deleted the copilot/sub-pr-116-please-work branch February 11, 2026 07:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants