Files
podsteadr-player/src/components/ConnectSignerModal.vue
T

52 lines
1.7 KiB
Vue
Raw Normal View History

<script setup lang="ts">
import { onMounted, ref } from 'vue';
import QRCode from 'qrcode';
import { connectNip46ViaQr } from '../lib/signer';
const emit = defineEmits<{
connected: [pubkey: string];
close: [];
}>();
const qrDataUrl = ref<string | null>(null);
const connecting = ref(true);
const error = ref<string | null>(null);
async function start(): Promise<void> {
connecting.value = true;
error.value = null;
qrDataUrl.value = null;
try {
const pubkey = await connectNip46ViaQr(async (uri) => {
qrDataUrl.value = await QRCode.toDataURL(uri, { margin: 1, width: 320 });
});
emit('connected', pubkey);
} catch (err) {
error.value = (err as Error).message;
} finally {
connecting.value = false;
}
}
onMounted(start);
</script>
<template>
<div class="fixed inset-0 z-50 flex items-center justify-center bg-black/70 p-4">
<div class="card w-full max-w-sm space-y-4 text-center">
<h2 class="text-lg font-semibold text-white">Connect a remote signer</h2>
<p class="text-sm text-white/60">Scan this with Primal (or any NIP-46-compatible signer app) to sign in without a browser extension.</p>
<img v-if="qrDataUrl" :src="qrDataUrl" alt="Nostr Connect QR code" class="mx-auto rounded-lg" />
<p v-if="connecting && !error" class="text-xs text-white/50">Waiting for approval</p>
<p v-if="error" class="text-sm text-red-400">{{ error }}</p>
<div class="flex gap-2">
<button type="button" class="btn-secondary flex-1" @click="emit('close')">Cancel</button>
<button v-if="error" type="button" class="btn-primary flex-1" @click="start">Retry</button>
</div>
</div>
</div>
</template>