64 lines
1.4 KiB
TypeScript
64 lines
1.4 KiB
TypeScript
import { computed, ref, watch, type ComputedRef } from 'vue'
|
|
|
|
/**
|
|
* Shared QR code display logic: renders the base64 QR image, tracks its
|
|
* natural width after load, and derives display/preview widths.
|
|
*/
|
|
export function useSessionQrDisplay(options: {
|
|
session: ComputedRef<{ qrImageBase64?: string } | null>
|
|
}) {
|
|
const { session } = options
|
|
|
|
const qrImageNaturalWidth = ref(0)
|
|
|
|
const qrImage = computed(() =>
|
|
session.value?.qrImageBase64 ? `data:image/png;base64,${session.value.qrImageBase64}` : '',
|
|
)
|
|
|
|
watch(qrImage, () => {
|
|
qrImageNaturalWidth.value = 0
|
|
})
|
|
|
|
function handleQrImageLoad(event: Event) {
|
|
const target = event.target
|
|
|
|
if (!(target instanceof HTMLImageElement)) {
|
|
return
|
|
}
|
|
|
|
qrImageNaturalWidth.value = target.naturalWidth || 0
|
|
}
|
|
|
|
const qrDisplayWidth = computed(() => {
|
|
const naturalWidth = qrImageNaturalWidth.value
|
|
|
|
if (!naturalWidth) {
|
|
return 220
|
|
}
|
|
|
|
if (naturalWidth < 160) {
|
|
return Math.min(naturalWidth * 2, 220)
|
|
}
|
|
|
|
return Math.min(naturalWidth, 240)
|
|
})
|
|
|
|
const qrFigureStyle = computed(() => ({
|
|
width: `${qrDisplayWidth.value}px`,
|
|
maxWidth: '100%',
|
|
}))
|
|
|
|
const qrPreviewWidth = computed(
|
|
() => `${Math.min(Math.max(qrDisplayWidth.value + 120, 360), 480)}px`,
|
|
)
|
|
|
|
return {
|
|
qrImage,
|
|
qrImageNaturalWidth,
|
|
qrDisplayWidth,
|
|
qrFigureStyle,
|
|
qrPreviewWidth,
|
|
handleQrImageLoad,
|
|
}
|
|
}
|