Fix admin cache hydration cycle and guard QR code Android detection

This commit is contained in:
thePR0M3TH3AN committed 2025-10-21 19:47:05 -04:00
1 parent 677e673e1f
commit 6d7d5fc7ff
4 files changed
+134 -40

No files matched your search

+19 -4
View File
@@ -10,9 +10,9 @@ import {
isDevMode,
} from "./config.js";
import {
nostrClient,
getRegisteredNostrClient,
requestDefaultExtensionPermissions,
} from "./nostr.js";
} from "./nostrClientRegistry.js";
import { devLogger, userLogger } from "./utils/logger.js";
import {
buildAdminListEvent,
@@ -40,6 +40,17 @@ function createError(code, message, cause) {
return error;
}
function requireNostrClient() {
const client = getRegisteredNostrClient();
if (!client) {
throw createError(
"nostr-unavailable",
"Nostr relay pool is not initialized.",
);
}
return client;
}
function normalizeNpub(value) {
return typeof value === "string" ? value.trim() : "";
}
@@ -350,10 +361,12 @@ function clearLegacyStorageFor(listKey) {
}
function ensureNostrReady() {
if (!nostrClient || !nostrClient.pool) {
const nostrClient = requireNostrClient();
if (!nostrClient.pool) {
throw createError(
"nostr-unavailable",
"Nostr relay pool is not initialized."
"Nostr relay pool is not initialized.",
);
}
@@ -578,6 +591,7 @@ function extractNpubsFromEvent(event) {
}
async function fetchLatestListEvent(filter, contextLabel = "admin-list") {
const nostrClient = requireNostrClient();
const relays = ensureNostrReady();
const normalizedFilter = {};
@@ -876,6 +890,7 @@ function publishListWithFirstAcceptance(pool, relays, event, options = {}) {
}
async function persistNostrState(actorNpub, updates = {}) {
const nostrClient = requireNostrClient();
ensureNostrReady();
const permissionResult = await requestDefaultExtensionPermissions();
if (!permissionResult.ok) {
+10 -1
View File
@@ -21,6 +21,10 @@ import {
VIEW_FILTER_INCLUDE_LEGACY_VIDEO,
} from "./constants.js";
import { accessControl } from "./accessControl.js";
import {
registerNostrClient,
requestDefaultExtensionPermissions as requestRegisteredPermissions,
} from "./nostrClientRegistry.js";
// 🔧 merged conflicting changes from codex/update-video-publishing-and-parsing-logic vs unstable
import { deriveTitleFromEvent, magnetFromText } from "./videoEventUtils.js";
import { extractMagnetHints } from "./magnet.js";
@@ -12011,8 +12015,13 @@ function isNip04EncryptedWatchHistoryEvent(pointerEvent, ciphertext) {
export const nostrClient = new NostrClient();
registerNostrClient(nostrClient, {
requestPermissions: () =>
nostrClient.ensureExtensionPermissions(DEFAULT_NIP07_PERMISSION_METHODS),
});
export function requestDefaultExtensionPermissions() {
return nostrClient.ensureExtensionPermissions(
return requestRegisteredPermissions(
DEFAULT_NIP07_PERMISSION_METHODS,
);
}
+50
View File
@@ -0,0 +1,50 @@
// js/nostrClientRegistry.js
let registeredNostrClient = null;
let requestPermissionsDelegate = null;
export function registerNostrClient(client, options = {}) {
registeredNostrClient = client || null;
if (typeof options.requestPermissions === "function") {
requestPermissionsDelegate = options.requestPermissions;
return;
}
if (
registeredNostrClient &&
typeof registeredNostrClient.ensureExtensionPermissions === "function"
) {
requestPermissionsDelegate = (...args) =>
registeredNostrClient.ensureExtensionPermissions(...args);
return;
}
requestPermissionsDelegate = null;
}
export function getRegisteredNostrClient() {
return registeredNostrClient;
}
export function clearNostrClientRegistration() {
registeredNostrClient = null;
requestPermissionsDelegate = null;
}
export function requestDefaultExtensionPermissions(...args) {
if (typeof requestPermissionsDelegate === "function") {
try {
return requestPermissionsDelegate(...args);
} catch (error) {
return Promise.resolve({ ok: false, error });
}
}
const error = new Error("Nostr client is not registered.");
return Promise.resolve({ ok: false, error });
}
export const __nostrClientRegistryTestHooks = {
clearNostrClientRegistration,
};
+55 -35
View File
@@ -156,21 +156,25 @@ var QRCode;
}
// android 2.x doesn't support Data-URI spec
function _getAndroid() {
var android = false;
var sAgent = navigator.userAgent;
if (/android/i.test(sAgent)) { // android
android = true;
var aMat = sAgent.toString().match(/android ([0-9]\.[0-9])/i);
if (aMat && aMat[1]) {
android = parseFloat(aMat[1]);
}
}
return android;
}
function _getAndroid() {
if (typeof navigator === "undefined" || !navigator.userAgent) {
return false;
}
var android = false;
var sAgent = navigator.userAgent;
if (/android/i.test(sAgent)) { // android
android = true;
var aMat = sAgent.toString().match(/android ([0-9]\.[0-9])/i);
if (aMat && aMat[1]) {
android = parseFloat(aMat[1]);
}
}
return android;
}
var svgDrawer = (function() {
@@ -279,26 +283,42 @@ var QRCode;
this._elCanvas.style.display = "none";
}
// Android 2.1 bug workaround
// http://code.google.com/p/android/issues/detail?id=5141
if (this._android && this._android <= 2.1) {
var factor = 1 / window.devicePixelRatio;
var drawImage = CanvasRenderingContext2D.prototype.drawImage;
CanvasRenderingContext2D.prototype.drawImage = function (image, sx, sy, sw, sh, dx, dy, dw, dh) {
if (("nodeName" in image) && /img/i.test(image.nodeName)) {
for (var i = arguments.length - 1; i >= 1; i--) {
arguments[i] = arguments[i] * factor;
}
} else if (typeof dw == "undefined") {
arguments[1] *= factor;
arguments[2] *= factor;
arguments[3] *= factor;
arguments[4] *= factor;
}
drawImage.apply(this, arguments);
};
}
// Android 2.1 bug workaround
// http://code.google.com/p/android/issues/detail?id=5141
var legacyAndroidVersion = (function () {
try {
return _getAndroid();
} catch (error) {
return false;
}
})();
if (
legacyAndroidVersion &&
legacyAndroidVersion <= 2.1 &&
typeof CanvasRenderingContext2D !== "undefined"
) {
var pixelRatio =
typeof window !== "undefined" && window.devicePixelRatio
? window.devicePixelRatio
: 1;
var factor = pixelRatio ? 1 / pixelRatio : 1;
var drawImage = CanvasRenderingContext2D.prototype.drawImage;
CanvasRenderingContext2D.prototype.drawImage = function (image, sx, sy, sw, sh, dx, dy, dw, dh) {
if (("nodeName" in image) && /img/i.test(image.nodeName)) {
for (var i = arguments.length - 1; i >= 1; i--) {
arguments[i] = arguments[i] * factor;
}
} else if (typeof dw == "undefined") {
arguments[1] *= factor;
arguments[2] *= factor;
arguments[3] *= factor;
arguments[4] *= factor;
}
drawImage.apply(this, arguments);
};
}
/**
* Check whether the user's browser supports Data URI or not