- License: AGPL-3.0-or-later (LICENSE, every package.json, README). - MUSICSHARE_FOSS=1 builds leave out the only closed-source code, Google's ML Kit / Play Services barcode scanner bundled by expo-camera; the scan screen then decodes small camera snapshots with jsQR instead. - Expo modules build from source rather than from precompiled AARs, as F-Droid requires (that's also what makes the scanner switch take effect). Verified: a FOSS build contains no ML Kit or Play Services classes. - Release builds default to the production server, and come out unsigned without our upload key (F-Droid signs with its own). versionCode 1. - Store listing in fastlane/metadata/android, a draft fdroiddata recipe in fdroid/, and docs/FDROID.md with the submission steps. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MzFywujuH9TiuXbr9vjoX8
This commit is contained in:
@@ -0,0 +1,25 @@
|
||||
import jpeg from 'jpeg-js';
|
||||
import jsQR from 'jsqr';
|
||||
|
||||
/**
|
||||
* Reads a QR code from a small JPEG snapshot (base64), entirely in JS. Used by
|
||||
* F-Droid builds, which leave out Google's ML Kit scanner. Returns the code's
|
||||
* text, or null if there isn't one.
|
||||
*/
|
||||
export function decodeQrFromJpeg(base64: string): string | null {
|
||||
const bytes = Uint8Array.from(atob(base64), (c) => c.charCodeAt(0));
|
||||
const image = jpeg.decode(bytes, { useTArray: true, formatAsRGBA: true, maxResolutionInMP: 4 });
|
||||
const code = jsQR(new Uint8ClampedArray(image.data.buffer, image.data.byteOffset, image.data.length), image.width, image.height, {
|
||||
inversionAttempts: 'dontInvert',
|
||||
});
|
||||
return code?.data ?? null;
|
||||
}
|
||||
|
||||
/** The smallest snapshot size that still reads a QR code held at arm's length. */
|
||||
export function pickSnapshotSize(sizes: string[]): string | undefined {
|
||||
const parsed = sizes
|
||||
.map((s) => ({ s, w: Number(s.split('x')[0]), h: Number(s.split('x')[1]) }))
|
||||
.filter((p) => p.w > 0 && p.h > 0)
|
||||
.sort((a, b) => a.w * a.h - b.w * b.h);
|
||||
return (parsed.find((p) => Math.min(p.w, p.h) >= 480) ?? parsed.at(-1))?.s;
|
||||
}
|
||||
Reference in New Issue
Block a user