11<script lang =" ts" >
2- import AppNav from " $lib/fragments/AppNav/AppNav.svelte" ;
3- import { Drawer } from " $lib/ui" ;
4- import * as Button from " $lib/ui/Button" ;
5- import {
6- FlashlightIcon ,
7- Image02Icon ,
8- QrCodeIcon ,
9- } from " @hugeicons/core-free-icons" ;
10- import { HugeiconsIcon } from " @hugeicons/svelte" ;
11- import {
12- Format ,
13- type PermissionState ,
14- type Scanned ,
15- cancel ,
16- checkPermissions ,
17- requestPermissions ,
18- scan ,
19- } from " @tauri-apps/plugin-barcode-scanner" ;
20- import { onDestroy , onMount } from " svelte" ;
21- import type { SVGAttributes } from " svelte/elements" ;
22-
23- const pathProps: SVGAttributes <SVGPathElement > = {
24- stroke: " white" ,
25- " stroke-width" : 7 ,
26- " stroke-linecap" : " round" ,
27- " stroke-linejoin" : " round" ,
28- };
29-
30- let codeScannedDrawerOpen = $state (false );
31- let loggedInDrawerOpen = $state (false );
32- let flashlightOn = $state (false );
33-
34- let scannedData: Scanned | undefined = $state (undefined );
35-
36- let scanning = false ;
37- let loading = false ;
38-
39- let permissions_nullable: PermissionState | null ;
40-
41- async function startScan() {
42- let permissions = await checkPermissions ()
43- .then ((permissions ) => {
44- return permissions ;
45- })
46- .catch (() => {
47- return null ; // possibly return "denied"? or does that imply that the check has been successful, but was actively denied?
48- });
49-
50- // TODO: handle receiving "prompt-with-rationale" (issue: https://github.com/tauri-apps/plugins-workspace/issues/979)
51- if (permissions === " prompt" ) {
52- permissions = await requestPermissions (); // handle in more detail?
53- }
54-
55- permissions_nullable = permissions ;
56-
57- if (permissions === " granted" ) {
58- // Scanning parameters
59- const formats = [Format .QRCode ];
60- const windowed = true ;
61-
62- if (scanning ) return ;
63- scanning = true ;
64- scan ({ formats , windowed })
65- .then ((res ) => {
66- console .log (" Scan result:" , res );
67- scannedData = res ;
68- codeScannedDrawerOpen = true ;
69- })
70- .catch ((error ) => {
71- // TODO: display error to user
72- console .error (" Scan error:" , error );
2+ import { PUBLIC_PROVISIONER_URL } from " $env/static/public" ;
3+ import AppNav from " $lib/fragments/AppNav/AppNav.svelte" ;
4+ import { Drawer } from " $lib/ui" ;
5+ import * as Button from " $lib/ui/Button" ;
6+ import { QrCodeIcon } from " @hugeicons/core-free-icons" ;
7+ import { HugeiconsIcon } from " @hugeicons/svelte" ;
8+ import {
9+ Format ,
10+ type PermissionState ,
11+ type Scanned ,
12+ cancel ,
13+ checkPermissions ,
14+ requestPermissions ,
15+ scan ,
16+ } from " @tauri-apps/plugin-barcode-scanner" ;
17+ import { getContext , onDestroy , onMount } from " svelte" ;
18+ import type { SVGAttributes } from " svelte/elements" ;
19+ import type { GlobalState } from " $lib/global" ;
20+ import axios from " axios" ;
21+
22+ const globalState = getContext <() => GlobalState >(" globalState" )();
23+ const pathProps: SVGAttributes <SVGPathElement > = {
24+ stroke: " white" ,
25+ " stroke-width" : 7 ,
26+ " stroke-linecap" : " round" ,
27+ " stroke-linejoin" : " round" ,
28+ };
29+
30+ let platform = $state ();
31+ let hostname = $state ();
32+ let session = $state ();
33+ let codeScannedDrawerOpen = $state (false );
34+ let loggedInDrawerOpen = $state (false );
35+ let scannedData: Scanned | undefined = $state (undefined );
36+ let scanning = false ;
37+ let loading = false ;
38+ let redirect = $state ();
39+ let permissions_nullable: PermissionState | null ;
40+
41+ async function startScan() {
42+ let permissions = await checkPermissions ()
43+ .then ((permissions ) => {
44+ return permissions ;
7345 })
74- .finally (() => {
75- scanning = false ;
46+ .catch (() => {
47+ return null ;
7648 });
49+
50+ if (permissions === " prompt" ) {
51+ permissions = await requestPermissions ();
52+ }
53+
54+ permissions_nullable = permissions ;
55+
56+ if (permissions === " granted" ) {
57+ const formats = [Format .QRCode ];
58+ const windowed = true ;
59+
60+ if (scanning ) return ;
61+ scanning = true ;
62+ scan ({ formats , windowed })
63+ .then ((res ) => {
64+ scannedData = res ;
65+ const url = new URL (res .content );
66+ platform = url .searchParams .get (" platform" );
67+ const redirectUrl = new URL (
68+ url .searchParams .get (" redirect" ) || " " ,
69+ );
70+ redirect = url .searchParams .get (" redirect" );
71+ session = url .searchParams .get (" session" );
72+ hostname = redirectUrl .hostname ;
73+ codeScannedDrawerOpen = true ;
74+ })
75+ .catch ((error ) => {
76+ console .error (" Scan error:" , error );
77+ })
78+ .finally (() => {
79+ scanning = false ;
80+ });
81+ }
7782 }
7883
79- console .error (" Permission denied or not granted" );
80- // TODO: consider handling GUI for permission denied
81- }
84+ async function handleAuth() {
85+ const vault = await globalState .vaultController .vault ;
86+ if (! vault || ! redirect ) return ;
87+ await axios .post (redirect , { ename: vault .ename , session });
88+ codeScannedDrawerOpen = false ;
89+ loggedInDrawerOpen = true ;
90+ startScan ();
91+ }
8292
83- async function cancelScan() {
84- await cancel ();
85- scanning = false ;
86- }
93+ async function cancelScan() {
94+ await cancel ();
95+ scanning = false ;
96+ }
8797
88- onMount (async () => {
89- startScan ();
90- });
98+ onMount (async () => {
99+ startScan ();
100+ });
91101
92- onDestroy (async () => {
93- await cancelScan ();
94- });
102+ onDestroy (async () => {
103+ await cancelScan ();
104+ });
95105 </script >
96106
97107<AppNav title =" Scan QR Code" titleClasses =" text-white" iconColor =" white" />
@@ -116,27 +126,7 @@ onDestroy(async () => {
116126
117127<div
118128 class =" fixed bottom-2 left-1/2 -translate-x-1/2 z-10 flex gap-8 justify-center items-center"
119- >
120- <Button .Icon icon ={Image02Icon } bgColor =" white" bgSize =" md" />
121- <Button .Icon
122- icon ={QrCodeIcon }
123- bgColor =" white"
124- bgSize =" lg"
125- iconSize =" lg"
126- callback ={() => {
127- codeScannedDrawerOpen = true ;
128- }}
129- />
130- <Button .Icon
131- icon ={FlashlightIcon }
132- aria-label =" Toggle flashlight"
133- bgSize =" md"
134- iconSize ={32 }
135- bgColor ={flashlightOn ? " white" : " secondary" }
136- iconColor =" black"
137- onclick ={() => (flashlightOn = ! flashlightOn )}
138- />
139- </div >
129+ ></div >
140130
141131<!-- code scanned drawer -->
142132<Drawer
@@ -166,9 +156,16 @@ onDestroy(async () => {
166156 <p class =" text-black-700" >You're trying to access the following site</p >
167157
168158 <div class =" bg-gray rounded-2xl w-full p-4 mt-4" >
159+ <h4 class =" text-base text-black-700" >Platform Name</h4 >
160+ <p class =" text-black-700 font-normal capitalize" >
161+ {platform ?? " Unable to get name" }
162+ </p >
163+ </div >
164+
165+ <div class =" bg-gray rounded-2xl w-full p-4" >
169166 <h4 class =" text-base text-black-700" >Website URL</h4 >
170- <p class =" text-black-700 font-normal underline " >
171- {scannedData ?.content }
167+ <p class =" text-black-700 font-normal" >
168+ {hostname ?? scannedData ?.content }
172169 </p >
173170 </div >
174171 <div class =" flex justify-center gap-3 items-center mt-4" >
@@ -182,15 +179,7 @@ onDestroy(async () => {
182179 >
183180 Decline
184181 </Button .Action >
185- <Button .Action
186- variant =" solid"
187- class =" w-full"
188- callback ={() => {
189- codeScannedDrawerOpen = false ;
190- loggedInDrawerOpen = true ;
191- startScan ();
192- }}
193- >
182+ <Button .Action variant ="solid" class ="w-full" callback ={handleAuth }>
194183 Confirm
195184 </Button .Action >
196185 </div >
@@ -221,7 +210,7 @@ onDestroy(async () => {
221210 </div >
222211
223212 <h4 >You're logged in!</h4 >
224- <p class =" text-black-700" >You're now connected to this service' </p >
213+ <p class ="text-black-700" >You're now connected to { platform } </p >
225214
226215 <div class =" flex justify-center items-center mt-4" >
227216 <Button .Action
@@ -236,10 +225,3 @@ onDestroy(async () => {
236225 </Button .Action >
237226 </div >
238227</Drawer >
239-
240- <style >
241- :global(body , * :not (button )) {
242- background-color : #00000000 ;
243- overflow-y : hidden ;
244- }
245- </style >
0 commit comments