Skip to content

Commit

Permalink
🦋 Add (optional) be-BOP logo on PoS QR code #1614 (#1619)
Browse files Browse the repository at this point in the history
Co-authored-by: Christophe GERARD <50206014+Tirodem@users.noreply.github.com>
Co-authored-by: coyotte508 <coyotte508@protonmail.com>
  • Loading branch information
3 people authored Dec 6, 2024
1 parent 0f6968f commit 6d2599e
Show file tree
Hide file tree
Showing 7 changed files with 98 additions and 4 deletions.
41 changes: 41 additions & 0 deletions assets/bebop-b.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions src/lib/server/runtime-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,7 @@ const baseConfig = {
'wss://nos.lol',
'wss://relay.snort.social'
],
removeBebopLogoPOS: false,
contactModes: ['email', 'nostr'],
posTouchTag: [] as Tag['_id'][],
hideCreditCardQrCode: false,
Expand Down Expand Up @@ -317,6 +318,9 @@ if (!building) {
}
process.on('SIGINT', () => {
changeStream?.close().catch(console.error);

// Todo: keep track of everything instead and close ASAP
setTimeout(() => process.exit(0), 8000);
});

async function refresh(item?: ChangeStreamDocument<RuntimeConfigItem>): Promise<void> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ export async function load(event) {
disableLanguageSelector: runtimeConfig.disableLanguageSelector,
defaultOnLocation: runtimeConfig.defaultOnLocation,
cartPreviewInteractive: runtimeConfig.cartPreviewInteractive,
removeBebopLogoPOS: runtimeConfig.removeBebopLogoPOS,
overwriteCreditCardSvgColor: runtimeConfig.overwriteCreditCardSvgColor,
hideCreditCardQrCode: runtimeConfig.hideCreditCardQrCode
};
Expand Down Expand Up @@ -93,6 +94,7 @@ export const actions = {
disableLanguageSelector: z.boolean({ coerce: true }),
contactModes: z.string().array(),
cartPreviewInteractive: z.boolean({ coerce: true }),
removeBebopLogoPOS: z.boolean({ coerce: true }),
hideCreditCardQrCode: z.boolean({ coerce: true }),
overwriteCreditCardSvgColor: z.boolean({ coerce: true })
})
Expand Down
9 changes: 9 additions & 0 deletions src/routes/(app)/admin[[hash=admin_hash]]/config/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,15 @@
/>
Default enable "this is a fully-paid on-location physical order"
</label>
<label class="checkbox-label">
<input
type="checkbox"
name="removeBebopLogoPOS"
class="form-checkbox"
checked={data.removeBebopLogoPOS}
/>
Remove be-BOP logo from POS QR code
</label>

{#if hasCartLimitProductLine}
<label class="form-label">
Expand Down
40 changes: 38 additions & 2 deletions src/routes/(app)/order/[id]/payment/[paymentId]/qrcode/+server.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,17 @@
import { collections } from '$lib/server/database';
import { rootDir } from '$lib/server/root-dir';
import { bitcoinPaymentQrCodeString } from '$lib/types/Order';
import { error } from '@sveltejs/kit';
import qrcode from 'qrcode';
import { readFileSync } from 'node:fs';
import { join } from 'node:path';
import { building } from '$app/environment';

export async function GET({ params }) {
const bebopLogoSvg = building ? '' : readFileSync(join(rootDir, 'assets/bebop-b.svg'), 'utf-8');

const BEBOP_LOGO_RATIO = 0.2;

export async function GET({ params, url }) {
const order = await collections.orders.findOne({ _id: params.id });

if (!order) {
Expand All @@ -28,7 +36,35 @@ export async function GET({ params }) {
? bitcoinPaymentQrCodeString(payment.address, payment.price.amount, payment.price.currency)
: payment.address;

return new Response(await qrcode.toString(address, { type: 'svg' }), {
let qrcodeString = (await qrcode.toString(address, { type: 'svg' })).trim();

const showLogo = url.searchParams.get('logo') === 'true';

if (showLogo) {
const viewBox = qrcodeString.match(/viewBox="([^"]+)"/)?.[1];
const logoViewBox = bebopLogoSvg.match(/viewBox="([^"]+)"/)?.[1];
const logoWidgth = Number(bebopLogoSvg.match(/width="([^"]+)"/)?.[1]);
const logoHeight = Number(bebopLogoSvg.match(/height="([^"]+)"/)?.[1]);

if (viewBox && logoViewBox && !isNaN(logoWidgth) && !isNaN(logoHeight)) {
const [x, y, width, height] = viewBox.split(' ').map(Number);
// add logo to SVG

const logoScale = Math.max(width / logoWidgth, height / logoHeight) * BEBOP_LOGO_RATIO;
const logoX = x + (width - Number(logoWidgth) * logoScale) / 2;
const logoY = y + (height - Number(logoHeight) * logoScale) / 2;

const logoSvg = `<g transform="translate(${logoX},${logoY}) scale(${logoScale})">${bebopLogoSvg}</g>`;
const whiteRectBg = `<rect x="${logoX}" y="${logoY}" width="${
logoWidgth * logoScale
}" height="${logoHeight * logoScale}" fill="white"/>`;
if (qrcodeString.endsWith('</svg>')) {
qrcodeString = qrcodeString.slice(0, -'</svg>'.length) + whiteRectBg + logoSvg + '</svg>';
}
}
}

return new Response(qrcodeString, {
headers: { 'content-type': 'image/svg+xml' },
status: 200
});
Expand Down
4 changes: 3 additions & 1 deletion src/routes/(app)/pos/session/+page.server.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { collections } from '$lib/server/database';
import { redirect } from '@sveltejs/kit';
import { formatCart, formatOrder } from './formatCartOrder.js';
import { runtimeConfig } from '$lib/server/runtime-config.js';

export const load = async ({ locals }) => {
if (!locals.user) {
Expand All @@ -22,6 +23,7 @@ export const load = async ({ locals }) => {
return {
cart: formattedCart,
order: order && formatOrder(order),
layoutReset: true
layoutReset: true,
removeBebopLogoPOS: runtimeConfig.removeBebopLogoPOS
};
};
2 changes: 1 addition & 1 deletion src/routes/(app)/pos/session/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@
<div class="flex flex-col items-center gap-3">
<h1 class="text-3xl text-center">{t('order.singleTitle', { number: order?.number })}</h1>
<img
src="/order/{order?._id}/payment/{payment?.id}/qrcode"
src="/order/{order?._id}/payment/{payment?.id}/qrcode?logo={!data.removeBebopLogoPOS}"
alt="QR code"
class="h-96 w-96"
/>
Expand Down

0 comments on commit 6d2599e

Please sign in to comment.