diff --git a/.changeset/eight-pumpkins-pull.md b/.changeset/eight-pumpkins-pull.md new file mode 100644 index 000000000..3a68a47c4 --- /dev/null +++ b/.changeset/eight-pumpkins-pull.md @@ -0,0 +1,5 @@ +--- +"@tma.js/sdk": patch +--- + +When opening QrScanner, update the isOpened flag. Listen to its changes to resolve the promise. After the promise was resolved, update the flag again. diff --git a/packages/sdk/src/features/QrScanner/QrScanner.ts b/packages/sdk/src/features/QrScanner/QrScanner.ts index efa532ac9..86c50c5db 100644 --- a/packages/sdk/src/features/QrScanner/QrScanner.ts +++ b/packages/sdk/src/features/QrScanner/QrScanner.ts @@ -74,7 +74,7 @@ export class QrScanner { const wrapSupportedTask = createWithChecksFp({ ...wrapOptions, returns: 'task' }); const isOpened = signal(false); - const toggleClosed = () => { + const setClosed = () => { isOpened.set(false); }; @@ -97,25 +97,37 @@ export class QrScanner { ); }); this.closeFp = wrapSupportedEither(() => { - return pipe(postEvent('web_app_close_scan_qr_popup'), E.map(toggleClosed)); + return pipe(postEvent('web_app_close_scan_qr_popup'), E.map(setClosed)); }); this.openFp = wrapSupportedTask(options => { return pipe( - this.isOpened() + isOpened() ? TE.left(new ConcurrentCallError('The QR Scanner is already opened')) : async () => postEvent('web_app_open_scan_qr_popup', { text: options.text }), TE.chainW(() => { + isOpened.set(true); const [addToCleanup, cleanup] = createCbCollector(); - const withCleanup = (value: T): T => { + const onSettled = (value: T): T => { cleanup(); + isOpened.set(false); return value; }; return pipe( BetterTaskEither(resolve => { - addToCleanup(onClosed(resolve), onTextReceived(options.onCaptured)); + addToCleanup( + // The scanner was closed externally. + onClosed(resolve), + // The scanner was closed internally. + isOpened.sub(isOpenedValue => { + if (!isOpenedValue) { + resolve(); + } + }), + onTextReceived(options.onCaptured), + ); }, options), - TE.mapBoth(withCleanup, withCleanup), + TE.mapBoth(onSettled, onSettled), ); }), );