diff --git a/infrastructure/eid-wallet/src/routes/(app)/scan-qr/+page.svelte b/infrastructure/eid-wallet/src/routes/(app)/scan-qr/+page.svelte index e4f24ddc..815e472d 100644 --- a/infrastructure/eid-wallet/src/routes/(app)/scan-qr/+page.svelte +++ b/infrastructure/eid-wallet/src/routes/(app)/scan-qr/+page.svelte @@ -51,14 +51,13 @@ let signingSessionId = $state(null); let signingData = $state(null); let isSigningRequest = $state(false); - let signingSuccess = $state(false); + let showSigningSuccess = $state(false); // Blind voting specific state let isBlindVotingRequest = $state(false); let selectedBlindVoteOption = $state(null); let blindVoteError = $state(null); // Add error state let isSubmittingBlindVote = $state(false); // Add loading state - let blindVoteSuccess = $state(false); // Add success state // Reveal vote specific state let isRevealRequest = $state(false); @@ -510,15 +509,18 @@ throw new Error("Failed to submit signed payload"); } - // Close the signing drawer and show success - signingDrawerOpen = false; - signingSuccess = true; + // Stop the camera and show success state in the drawer + if (scanning) { + cancelScan(); + } + showSigningSuccess = true; console.log( signingData.pollId ? "Vote signed successfully!" : "Message signed successfully!", ); + // Check if this was from a deep link const deepLinkData = sessionStorage.getItem("deepLinkData"); if (deepLinkData) { @@ -526,11 +528,8 @@ const data = JSON.parse(deepLinkData); if (data.type === "sign") { console.log("Signing completed via deep link"); - // Show success message briefly, then continue - setTimeout(() => { - signingSuccess = false; - startScan(); - }, 1500); // Give user time to see success message + // For deep links, just continue scanning + startScan(); return; } } catch (error) { @@ -538,11 +537,7 @@ } } - // Not from deep link, continue scanning after a short delay - setTimeout(() => { - signingSuccess = false; - startScan(); - }, 1500); + // Not from deep link, show success state (drawer will handle the redirect) } catch (error) { console.error("Error signing vote:", error); } finally { @@ -879,34 +874,15 @@ if (response.status >= 200 && response.status < 300) { console.log("✅ Blind vote submitted successfully"); - // Set success state for proper UI feedback - blindVoteSuccess = true; - // Reset states gradually to avoid white screen blindVoteError = null; isSubmittingBlindVote = false; - blindVoteSuccess = true; // Set success state - - // Close the signing drawer - signingDrawerOpen = false; - - // Reset blind voting specific states - isBlindVotingRequest = false; - selectedBlindVoteOption = null; - signingData = null; - - // Ensure we're back to scanning mode - setTimeout(() => { - // Reset all drawer states to ensure camera view is shown - codeScannedDrawerOpen = false; - loggedInDrawerOpen = false; - signingDrawerOpen = false; - signingSuccess = false; - blindVoteSuccess = false; // Reset success state - - // Start scanning again - startScan(); - }, 100); // Small delay to ensure state transitions complete + + // Stop the camera and show success state for blind voting + if (scanning) { + cancelScan(); + } + showSigningSuccess = true; } else { console.error("❌ Failed to submit blind vote"); blindVoteError = @@ -930,14 +906,37 @@ } function closeDrawer() { + // Stop the camera if it's running + if (scanning) { + cancelScan(); + } + codeScannedDrawerOpen = false; loggedInDrawerOpen = false; signingDrawerOpen = false; - signingSuccess = false; isBlindVotingRequest = false; selectedBlindVoteOption = null; signingData = null; signingSessionId = null; + showSigningSuccess = false; + } + + function handleSuccessOkay() { + // Stop the camera if it's running + if (scanning) { + cancelScan(); + } + + // Reset all states + showSigningSuccess = false; + signingDrawerOpen = false; + isBlindVotingRequest = false; + selectedBlindVoteOption = null; + signingData = null; + signingSessionId = null; + + // Redirect to main page + goto("/main"); } onMount(async () => { @@ -971,6 +970,26 @@ console.log("Redirect:", data.redirect); console.log("Redirect URI:", data.redirect_uri); + // Prevent duplicate processing by checking if we're already handling this type of request + if (data.type === "auth" && codeScannedDrawerOpen) { + console.log( + "Auth request already in progress, ignoring duplicate", + ); + return; + } + if (data.type === "sign" && signingDrawerOpen) { + console.log( + "Signing request already in progress, ignoring duplicate", + ); + return; + } + if (data.type === "reveal" && isRevealRequest) { + console.log( + "Reveal request already in progress, ignoring duplicate", + ); + return; + } + if (data.type === "auth") { console.log("Handling auth deep link"); // Handle auth deep link @@ -1125,6 +1144,12 @@ } // Listen for deep link events when already on the page + const handleDeepLinkReceived = async (event: CustomEvent) => { + console.log("Received deepLinkReceived event:", event.detail); + await handleDeepLinkData(event.detail); + }; + + // Also listen for the legacy events as backup const handleAuthEvent = async (event: CustomEvent) => { console.log("Received deepLinkAuth event:", event.detail); await handleDeepLinkData({ @@ -1141,6 +1166,13 @@ }); }; + // Listen for the new global deep link event + window.addEventListener("deepLinkReceived", (event) => { + console.log("Scan page received deepLinkReceived event:", event); + handleDeepLinkReceived(event as CustomEvent); + }); + + // Listen for legacy deep link events window.addEventListener("deepLinkAuth", (event) => handleAuthEvent(event as CustomEvent), ); @@ -1150,6 +1182,9 @@ // Cleanup event listeners onDestroy(() => { + window.removeEventListener("deepLinkReceived", (event) => + handleDeepLinkReceived(event as CustomEvent), + ); window.removeEventListener("deepLinkAuth", (event) => handleAuthEvent(event as CustomEvent), ); @@ -1472,218 +1507,262 @@ -
+ {#if showSigningSuccess} +
-
- -
+ class="flex justify-center mb-4 relative items-center overflow-hidden bg-green-100 rounded-xl p-4 h-[72px] w-[72px]" + > +
+
+ + -

- {isBlindVotingRequest - ? "Blind Vote Request" - : signingData?.pollId - ? "Sign Vote Request" - : "Sign Message Request"} -

-

- {isBlindVotingRequest - ? "You're being asked to submit a blind vote for the following poll" - : signingData?.pollId - ? "You're being asked to sign a vote for the following poll" - : "You're being asked to sign the following message"} -

- - {#if signingData?.pollId && signingData?.voteData} - -
-

Poll ID

-

- {signingData?.pollId ?? "Unknown"} -

+

+ {isBlindVotingRequest + ? "Blind Vote Submitted Successfully!" + : signingData?.pollId + ? "Vote Signed Successfully!" + : "Message Signed Successfully!"} +

+

+ {isBlindVotingRequest + ? "Your blind vote has been submitted and is now completely hidden using cryptographic commitments." + : signingData?.pollId + ? "Your vote has been signed and submitted to the voting system." + : "Your message has been signed and submitted successfully."} +

+ +
+ + Okay +
- {:else if isBlindVotingRequest && signingData?.pollDetails} - -
-

Blind Voting

- - - {#if blindVoteError} -
-
-
- - - -
-
-

- Error -

-
- {blindVoteError} + {:else} + +
+
+
+ +
+ +

+ {isBlindVotingRequest + ? "Blind Vote Request" + : signingData?.pollId + ? "Sign Vote Request" + : "Sign Message Request"} +

+

+ {isBlindVotingRequest + ? "You're being asked to submit a blind vote for the following poll" + : signingData?.pollId + ? "You're being asked to sign a vote for the following poll" + : "You're being asked to sign the following message"} +

+ + {#if signingData?.pollId && signingData?.voteData} + +
+

Poll ID

+

+ {signingData?.pollId ?? "Unknown"} +

+
+ {:else if isBlindVotingRequest && signingData?.pollDetails} + +
+

Blind Voting

+ + + {#if blindVoteError} +
+
+
+ + + +
+
+

+ Error +

+
+ {blindVoteError} +
+ {/if} + + +
+

+ Poll: {signingData.pollDetails?.title || "Unknown"} +

+

+ Creator: {signingData.pollDetails?.creatorName || + "Unknown"} +

- {/if} - -
-

- Poll: {signingData.pollDetails?.title || "Unknown"} -

-

- Creator: {signingData.pollDetails?.creatorName || "Unknown"} -

-
+ +
+ + {#each signingData.pollDetails?.options || [] as option, index} + + {/each} +
- -
- + +
+ {:else} + +
+

Message

+

+ {signingData?.message ?? "No message provided"} +

- - -
- {:else} - -
-

Message

-

- {signingData?.message ?? "No message provided"} -

-
+
+

Session ID

+

+ {signingData?.sessionId?.slice(0, 8) ?? "Unknown"}... +

+
+ {/if} -
-

Session ID

-

- {signingData?.sessionId?.slice(0, 8) ?? "Unknown"}... -

+
+ {#if !isBlindVotingRequest} + { + signingDrawerOpen = false; + startScan(); + }} + > + Decline + + {/if} + {#if !isBlindVotingRequest} + + {loading + ? "Signing..." + : signingData?.pollId + ? "Sign Vote" + : "Sign Message"} + + {/if}
{/if} - -
- {#if !isBlindVotingRequest} - { - signingDrawerOpen = false; - startScan(); - }} - > - Decline - - {/if} - {#if !isBlindVotingRequest} - - {loading - ? "Signing..." - : signingData?.pollId - ? "Sign Vote" - : "Sign Message"} - - {/if} -
- -
-

- After signing, you'll be redirected back to the platform -

-
@@ -1784,55 +1863,3 @@ -{#if signingSuccess} -
-
-
- -
-

- {isBlindVotingRequest - ? "Blind Vote Submitted Successfully!" - : signingData?.pollId - ? "Vote Signed Successfully!" - : "Message Signed Successfully!"} -

-

- {isBlindVotingRequest - ? "Your blind vote has been submitted and is now completely hidden using cryptographic commitments." - : signingData?.pollId - ? "Your vote has been signed and submitted to the voting system." - : "Your message has been signed and submitted successfully."} -

- - {#if redirect} -
- { - try { - if (redirect) { - window.location.href = redirect; - } - } catch (error) { - console.error("Manual redirect failed:", error); - } - }} - class="w-full" - > - Return to Platform Now - -
- {/if} -
-
-{/if} diff --git a/infrastructure/eid-wallet/src/routes/+layout.svelte b/infrastructure/eid-wallet/src/routes/+layout.svelte index f60c1526..071b3c43 100644 --- a/infrastructure/eid-wallet/src/routes/+layout.svelte +++ b/infrastructure/eid-wallet/src/routes/+layout.svelte @@ -1,6 +1,6 @@