Refactor logging to centralized logger

This commit is contained in:
thePR0M3TH3AN committed 2025-10-15 11:11:14 -04:00
1 parent 08d770162b
commit 37ba57aa37
67 files changed
+1130 -798

No files matched your search

@@ -225,6 +225,26 @@
</div>
<script>
document.addEventListener("DOMContentLoaded", () => {
const fallbackChannel = {
log: () => {},
info: () => {},
warn: () => {},
error: () => {},
};
const embeddedLogger =
(typeof window !== "undefined" && window.bitvidLogger) || {};
const devChannel = embeddedLogger.dev || fallbackChannel;
const userChannel = embeddedLogger.user || fallbackChannel;
const emitDev = (method, ...args) => {
if (typeof devChannel[method] === "function") {
devChannel[method](...args);
}
};
const emitUser = (method, ...args) => {
if (typeof userChannel[method] === "function") {
userChannel[method](...args);
}
};
// Logging functions for both on-page and console output.
function log(msg, type = "info") {
const div = document.createElement("div");
@@ -234,7 +254,14 @@
if (type === "warn") div.classList.add("warn");
div.textContent = msg;
document.getElementById("status").appendChild(div);
console.log(`[${type.toUpperCase()}] ${msg}`);
const normalized = type.toLowerCase();
if (normalized === "error") {
emitUser("error", `[${type.toUpperCase()}] ${msg}`);
} else if (normalized === "warn") {
emitUser("warn", `[${type.toUpperCase()}] ${msg}`);
} else {
emitDev("info", `[${type.toUpperCase()}] ${msg}`);
}
}
function clear() {
document.getElementById("status").innerHTML = "";
@@ -457,7 +484,7 @@ For further questions, contact us through bitvid’s Nostr support channels.
);
} catch (err) {
log("Error: " + err.message, "error");
console.error(err);
emitUser("error", err);
}
});
});
@@ -208,6 +208,26 @@
</div>
<script>
document.addEventListener("DOMContentLoaded", () => {
const fallbackChannel = {
log: () => {},
info: () => {},
warn: () => {},
error: () => {},
};
const embeddedLogger =
(typeof window !== "undefined" && window.bitvidLogger) || {};
const devChannel = embeddedLogger.dev || fallbackChannel;
const userChannel = embeddedLogger.user || fallbackChannel;
const emitDev = (method, ...args) => {
if (typeof devChannel[method] === "function") {
devChannel[method](...args);
}
};
const emitUser = (method, ...args) => {
if (typeof userChannel[method] === "function") {
userChannel[method](...args);
}
};
// Logging functions for both on-page and console output.
function log(msg, type = "info") {
const div = document.createElement("div");
@@ -217,7 +237,14 @@
if (type === "warn") div.classList.add("warn");
div.textContent = msg;
document.getElementById("status").appendChild(div);
console.log(`[${type.toUpperCase()}] ${msg}`);
const normalized = type.toLowerCase();
if (normalized === "error") {
emitUser("error", `[${type.toUpperCase()}] ${msg}`);
} else if (normalized === "warn") {
emitUser("warn", `[${type.toUpperCase()}] ${msg}`);
} else {
emitDev("info", `[${type.toUpperCase()}] ${msg}`);
}
}
function clear() {
document.getElementById("status").innerHTML = "";
@@ -438,7 +465,7 @@ For urgent issues, contact us through bitvid’s Nostr support channels.
);
} catch (err) {
log("Error: " + err.message, "error");
console.error(err);
emitUser("error", err);
}
});
});
@@ -142,6 +142,26 @@
</div>
<script>
document.addEventListener("DOMContentLoaded", () => {
const fallbackChannel = {
log: () => {},
info: () => {},
warn: () => {},
error: () => {},
};
const embeddedLogger =
(typeof window !== "undefined" && window.bitvidLogger) || {};
const devChannel = embeddedLogger.dev || fallbackChannel;
const userChannel = embeddedLogger.user || fallbackChannel;
const emitDev = (method, ...args) => {
if (typeof devChannel[method] === "function") {
devChannel[method](...args);
}
};
const emitUser = (method, ...args) => {
if (typeof userChannel[method] === "function") {
userChannel[method](...args);
}
};
// Logging functions for both on-page and console output.
function log(msg, type = "info") {
const div = document.createElement("div");
@@ -151,7 +171,14 @@
if (type === "warn") div.classList.add("warn");
div.textContent = msg;
document.getElementById("status").appendChild(div);
console.log(`[${type.toUpperCase()}] ${msg}`);
const normalized = type.toLowerCase();
if (normalized === "error") {
emitUser("error", `[${type.toUpperCase()}] ${msg}`);
} else if (normalized === "warn") {
emitUser("warn", `[${type.toUpperCase()}] ${msg}`);
} else {
emitDev("info", `[${type.toUpperCase()}] ${msg}`);
}
}
function clear() {
document.getElementById("status").innerHTML = "";
@@ -354,7 +381,7 @@ For further questions, reach out through bitvid’s Nostr support channels.
);
} catch (err) {
log("Error: " + err.message, "error");
console.error(err);
emitUser("error", err);
}
});
});
@@ -144,6 +144,26 @@
</div>
<script>
document.addEventListener("DOMContentLoaded", () => {
const fallbackChannel = {
log: () => {},
info: () => {},
warn: () => {},
error: () => {},
};
const embeddedLogger =
(typeof window !== "undefined" && window.bitvidLogger) || {};
const devChannel = embeddedLogger.dev || fallbackChannel;
const userChannel = embeddedLogger.user || fallbackChannel;
const emitDev = (method, ...args) => {
if (typeof devChannel[method] === "function") {
devChannel[method](...args);
}
};
const emitUser = (method, ...args) => {
if (typeof userChannel[method] === "function") {
userChannel[method](...args);
}
};
// Logging function for on-page and console output.
function log(msg, type = "info") {
const div = document.createElement("div");
@@ -153,7 +173,14 @@
if (type === "warn") div.classList.add("warn");
div.textContent = msg;
document.getElementById("status").appendChild(div);
console.log(`[${type.toUpperCase()}] ${msg}`);
const normalized = type.toLowerCase();
if (normalized === "error") {
emitUser("error", `[${type.toUpperCase()}] ${msg}`);
} else if (normalized === "warn") {
emitUser("warn", `[${type.toUpperCase()}] ${msg}`);
} else {
emitDev("info", `[${type.toUpperCase()}] ${msg}`);
}
}
function clear() {
document.getElementById("status").innerHTML = "";
@@ -337,7 +364,7 @@ For additional discussions, reach out via bitvid’s Nostr support channels.
);
} catch (err) {
log("Error: " + err.message, "error");
console.error(err);
emitUser("error", err);
}
});
});
@@ -167,6 +167,26 @@
</div>
<script>
document.addEventListener("DOMContentLoaded", () => {
const fallbackChannel = {
log: () => {},
info: () => {},
warn: () => {},
error: () => {},
};
const embeddedLogger =
(typeof window !== "undefined" && window.bitvidLogger) || {};
const devChannel = embeddedLogger.dev || fallbackChannel;
const userChannel = embeddedLogger.user || fallbackChannel;
const emitDev = (method, ...args) => {
if (typeof devChannel[method] === "function") {
devChannel[method](...args);
}
};
const emitUser = (method, ...args) => {
if (typeof userChannel[method] === "function") {
userChannel[method](...args);
}
};
// Logging function
function log(msg, type = "info") {
const div = document.createElement("div");
@@ -176,7 +196,14 @@
if (type === "warn") div.classList.add("warn");
div.textContent = msg;
document.getElementById("status").appendChild(div);
console.log(`[${type.toUpperCase()}] ${msg}`);
const normalized = type.toLowerCase();
if (normalized === "error") {
emitUser("error", `[${type.toUpperCase()}] ${msg}`);
} else if (normalized === "warn") {
emitUser("warn", `[${type.toUpperCase()}] ${msg}`);
} else {
emitDev("info", `[${type.toUpperCase()}] ${msg}`);
}
}
function clear() {
document.getElementById("status").innerHTML = "";
@@ -379,7 +406,7 @@ For further discussions, reach out through bitvid’s Nostr support channels.
);
} catch (err) {
log("Error: " + err.message, "error");
console.error(err);
emitUser("error", err);
}
});
});
+3 -2
View File
@@ -1,3 +1,4 @@
import { userLogger } from "./utils/logger.js";
// js/accessControl.js
import {
@@ -126,7 +127,7 @@ class AccessControl {
const operation = this._performRefresh();
const tracked = operation.catch((error) => {
console.error("Failed to refresh admin lists:", error);
userLogger.error("Failed to refresh admin lists:", error);
throw error;
});
this._refreshPromise = tracked;
@@ -410,4 +411,4 @@ export {
ADMIN_WHITELIST_MODE_STORAGE_KEY,
normalizeNpub,
isValidNpub,
};
};
+14 -13
View File
@@ -1,3 +1,4 @@
import { userLogger } from "./utils/logger.js";
// js/adminListStore.js
import {
@@ -151,7 +152,7 @@ function readJsonListFromStorage(key) {
return Array.isArray(parsed) ? parsed : null;
} catch (error) {
if (isDevMode) {
console.warn(`[adminListStore] Failed to parse legacy list for ${key}:`, error);
userLogger.warn(`[adminListStore] Failed to parse legacy list for ${key}:`, error);
}
return null;
}
@@ -199,7 +200,7 @@ function clearLegacyStorageFor(listKey) {
localStorage.removeItem(key);
} catch (error) {
if (isDevMode) {
console.warn(`[adminListStore] Failed to clear legacy storage for ${key}:`, error);
userLogger.warn(`[adminListStore] Failed to clear legacy storage for ${key}:`, error);
}
}
}
@@ -245,7 +246,7 @@ function encodeHexToNpub(hex) {
return window?.NostrTools?.nip19?.npubEncode(hex) || "";
} catch (error) {
if (isDevMode) {
console.warn("Failed to encode hex pubkey to npub:", error);
userLogger.warn("Failed to encode hex pubkey to npub:", error);
}
return "";
}
@@ -334,7 +335,7 @@ async function loadNostrList(identifier) {
}
} catch (error) {
if (isDevMode) {
console.warn(
userLogger.warn(
`[adminListStore] Combined relay fetch failed for ${identifier}:`,
error
);
@@ -349,7 +350,7 @@ async function loadNostrList(identifier) {
return Array.isArray(result) ? result : [];
} catch (error) {
if (isDevMode) {
console.warn(
userLogger.warn(
`[adminListStore] Relay fetch failed for ${identifier} on ${url}:`,
error
);
@@ -395,7 +396,7 @@ function buildListEvent(listKey, npubs, actorHex) {
return decodeNpubToHex(npub);
} catch (error) {
if (isDevMode) {
console.warn(
userLogger.warn(
`[adminListStore] Failed to decode npub while publishing ${listKey}:`,
error
);
@@ -413,7 +414,7 @@ function buildListEvent(listKey, npubs, actorHex) {
}
} catch (error) {
if (isDevMode) {
console.warn("Failed to ensure super admin presence:", error);
userLogger.warn("Failed to ensure super admin presence:", error);
}
}
}
@@ -458,7 +459,7 @@ function publishToRelay(url, signedEvent, listKey) {
return true;
} catch (error) {
if (isDevMode) {
console.warn(
userLogger.warn(
`[adminListStore] Relay publish rejected ${eventName} listener:`,
error
);
@@ -500,7 +501,7 @@ function publishToRelay(url, signedEvent, listKey) {
finalize(true);
}).then((result) => {
if (!result.success && isDevMode) {
console.warn(
userLogger.warn(
`[adminListStore] Publish failed for ${listKey} on ${result.url}:`,
result.error
);
@@ -605,7 +606,7 @@ async function persistNostrState(actorNpub, updates = {}) {
export async function loadAdminState() {
if (ADMIN_LIST_MODE !== "nostr" && isDevMode) {
console.warn(
userLogger.warn(
`[adminListStore] ADMIN_LIST_MODE "${ADMIN_LIST_MODE}" is deprecated. Defaulting to remote Nostr lists.`
);
}
@@ -614,7 +615,7 @@ export async function loadAdminState() {
if (!hasAnyEntries(state)) {
const legacy = loadLegacyAdminState();
if (legacy && isDevMode) {
console.warn(
userLogger.warn(
"[adminListStore] Ignoring legacy admin lists because remote mode is enforced. Publish them to Nostr to retain access.",
legacy
);
@@ -626,7 +627,7 @@ export async function loadAdminState() {
export async function persistAdminState(actorNpub, updates) {
if (ADMIN_LIST_MODE !== "nostr" && isDevMode) {
console.warn(
userLogger.warn(
`[adminListStore] ADMIN_LIST_MODE "${ADMIN_LIST_MODE}" is deprecated. Remote lists are enforced.`
);
}
@@ -637,4 +638,4 @@ export async function persistAdminState(actorNpub, updates) {
export const __adminListStoreTestHooks = Object.freeze({
extractNpubsFromEvent,
normalizeParticipantTagValue,
});
});
+4 -3
View File
@@ -1,3 +1,4 @@
import { userLogger } from "./utils/logger.js";
// js/analytics.js
import { ANALYTICS_CONFIG } from "./analyticsConfig.js";
@@ -30,7 +31,7 @@ function flushPendingCalls() {
try {
fn.apply(umami, args);
} catch (err) {
console.warn("[analytics] Failed to call", method, err);
userLogger.warn("[analytics] Failed to call", method, err);
}
}
}
@@ -103,7 +104,7 @@ function invokeUmami(method, args) {
try {
umami[method].apply(umami, args);
} catch (err) {
console.warn("[analytics] Failed to call", method, err);
userLogger.warn("[analytics] Failed to call", method, err);
}
return;
}
@@ -191,4 +192,4 @@ export function trackVideoView({
// Immediately queue the analytics script so page views are captured early.
if (isBrowserEnvironment()) {
ensureAnalyticsLoaded();
}
}
+165 -192
View File
File diff suppressed because it is too large. Load diff
+3 -2
View File
@@ -1,3 +1,4 @@
import { userLogger } from "../utils/logger.js";
function toArray(value) {
if (!value) {
return [];
@@ -196,7 +197,7 @@ export function destroyCarousel(state) {
try {
dispose();
} catch (error) {
console.warn('Failed to dispose carousel listener', error);
userLogger.warn('Failed to dispose carousel listener', error);
}
});
state.cleanup = [];
@@ -228,4 +229,4 @@ export function destroyCarousel(state) {
delete slide.dataset.inert;
slide.setAttribute('aria-hidden', 'false');
});
}
}
+9 -9
View File
@@ -1,5 +1,6 @@
import { createCarousel, advanceSlide, destroyCarousel } from './carousel.js';
import { mountProgressBar } from './progressBar.js';
import { userLogger } from "../utils/logger.js";
import { initZapthreadsEmbed as defaultInitZapthreadsEmbed } from './zapthreadsEmbed.js';
const CAROUSEL_AUTOPLAY_INTERVAL = 8000;
@@ -499,7 +500,7 @@ function initializeZapthreads({ registerCleanup, isDestroyed, initZapthreadsEmbe
try {
dispose();
} catch (error) {
console.error('[blog] zapthreads cleanup failed', error);
userLogger.error('[blog] zapthreads cleanup failed', error);
}
return;
}
@@ -507,12 +508,12 @@ function initializeZapthreads({ registerCleanup, isDestroyed, initZapthreadsEmbe
try {
dispose();
} catch (error) {
console.error('[blog] zapthreads cleanup failed', error);
userLogger.error('[blog] zapthreads cleanup failed', error);
}
});
})
.catch((error) => {
console.error('[blog] failed to initialise zapthreads embed', error);
userLogger.error('[blog] failed to initialise zapthreads embed', error);
});
return;
}
@@ -522,7 +523,7 @@ function initializeZapthreads({ registerCleanup, isDestroyed, initZapthreadsEmbe
try {
maybeDispose();
} catch (error) {
console.error('[blog] zapthreads cleanup failed', error);
userLogger.error('[blog] zapthreads cleanup failed', error);
}
return;
}
@@ -530,12 +531,12 @@ function initializeZapthreads({ registerCleanup, isDestroyed, initZapthreadsEmbe
try {
maybeDispose();
} catch (error) {
console.error('[blog] zapthreads cleanup failed', error);
userLogger.error('[blog] zapthreads cleanup failed', error);
}
});
}
} catch (error) {
console.error('[blog] failed to start zapthreads embed', error);
userLogger.error('[blog] failed to start zapthreads embed', error);
}
});
}
@@ -555,7 +556,7 @@ function mountBlogApp({ initZapthreadsEmbed = defaultInitZapthreadsEmbed } = {})
try {
callback();
} catch (error) {
console.error('[blog] cleanup callback failed', error);
userLogger.error('[blog] cleanup callback failed', error);
}
return () => {};
}
@@ -574,7 +575,7 @@ function mountBlogApp({ initZapthreadsEmbed = defaultInitZapthreadsEmbed } = {})
try {
callback();
} catch (error) {
console.error('[blog] cleanup callback failed', error);
userLogger.error('[blog] cleanup callback failed', error);
}
});
runtime.cleanupCallbacks.clear();
@@ -756,4 +757,3 @@ export function teardownBlog() {
activeTeardown();
}
}
+5 -4
View File
@@ -1,3 +1,4 @@
import { userLogger } from "../utils/logger.js";
import { escapeHTML } from '../utils/domUtils.js';
/**
@@ -492,7 +493,7 @@ export function parseRelayList(relayList = '') {
try {
relays.push(new URL(trimmed).toString());
} catch (error) {
console.warn('[zapthreads] ignored invalid relay input', trimmed, error);
userLogger.warn('[zapthreads] ignored invalid relay input', trimmed, error);
}
}
@@ -1161,7 +1162,7 @@ export async function initZapthreadsEmbed({
try {
callback();
} catch (error) {
console.error('[zapthreads] cleanup failed', error);
userLogger.error('[zapthreads] cleanup failed', error);
}
});
disposeCallbacks.clear();
@@ -1194,7 +1195,7 @@ export async function initZapthreadsEmbed({
try {
currentSubscription.close();
} catch (error) {
console.error('[zapthreads] failed to close subscription', error);
userLogger.error('[zapthreads] failed to close subscription', error);
}
}
currentSubscription = null;
@@ -1276,7 +1277,7 @@ export async function initZapthreadsEmbed({
try {
callback();
} catch (error) {
console.error('[zapthreads] cleanup failed', error);
userLogger.error('[zapthreads] cleanup failed', error);
}
});
disposeCallbacks.clear();
+25 -24
View File
@@ -1,3 +1,4 @@
import { userLogger } from "./utils/logger.js";
// js/channelProfile.js
import {
@@ -109,7 +110,7 @@ function logZapError(stage, details = {}, error) {
? details.retryAttempt
: undefined
};
console.error("[zap] Channel zap failure", summary, error);
userLogger.error("[zap] Channel zap failure", summary, error);
}
let currentChannelProfileEvent = null;
@@ -1289,7 +1290,7 @@ function buildChannelShareUrl() {
url.hash = `#view=channel-profile&npub=${currentChannelNpub}`;
return url.toString();
} catch (error) {
console.warn("Falling back to basic channel share URL:", error);
userLogger.warn("Falling back to basic channel share URL:", error);
const origin = window.location?.origin || "";
const pathname = window.location?.pathname || "";
if (!origin && !pathname) {
@@ -1361,7 +1362,7 @@ async function updateChannelMenuState() {
try {
await accessControl.ensureReady();
} catch (error) {
console.warn("Failed to refresh moderation lists for channel menu:", error);
userLogger.warn("Failed to refresh moderation lists for channel menu:", error);
}
const canBlacklist =
@@ -1431,7 +1432,7 @@ export async function initChannelProfileView() {
const hashParams = new URLSearchParams(window.location.hash.slice(1));
const npub = hashParams.get("npub");
if (!npub) {
console.error(
userLogger.error(
"No npub found in hash (e.g. #view=channel-profile&npub=...)"
);
return;
@@ -1456,7 +1457,7 @@ export async function initChannelProfileView() {
throw new Error("Invalid npub decoding result.");
}
} catch (err) {
console.error("Error decoding npub:", err);
userLogger.error("Error decoding npub:", err);
return;
}
@@ -1469,7 +1470,7 @@ export async function initChannelProfileView() {
setupChannelMoreMenu();
const initialMenuRefresh = updateChannelMenuState().catch((error) => {
console.error("Failed to prepare channel menu state:", error);
userLogger.error("Failed to prepare channel menu state:", error);
});
let subscriptionsTask = null;
@@ -1478,7 +1479,7 @@ export async function initChannelProfileView() {
subscriptionsTask = subscriptions
.loadSubscriptions(app.pubkey)
.catch((error) => {
console.error("Failed to load subscriptions for channel view:", error);
userLogger.error("Failed to load subscriptions for channel view:", error);
})
.finally(() => {
renderSubscribeButton(hexPub);
@@ -1495,14 +1496,14 @@ export async function initChannelProfileView() {
const profilePromise = loadUserProfile(hexPub)
.then(() => updateChannelMenuState())
.catch((error) => {
console.error("Failed to load channel profile:", error);
userLogger.error("Failed to load channel profile:", error);
})
.finally(() => {
syncChannelShareButtonState();
});
const videosPromise = loadUserVideos(hexPub).catch((error) => {
console.error("Failed to load channel videos:", error);
userLogger.error("Failed to load channel videos:", error);
});
const pendingTasks = [profilePromise, videosPromise];
@@ -1609,7 +1610,7 @@ function renderSubscribeButton(channelHex) {
if (toggleBtn) {
toggleBtn.addEventListener("click", async () => {
if (!app?.pubkey) {
console.error("Not logged in => cannot subscribe/unsubscribe.");
userLogger.error("Not logged in => cannot subscribe/unsubscribe.");
return;
}
try {
@@ -1621,7 +1622,7 @@ function renderSubscribeButton(channelHex) {
// Re-render the button so it toggles state
renderSubscribeButton(channelHex);
} catch (err) {
console.error("Failed to update subscription:", err);
userLogger.error("Failed to update subscription:", err);
}
});
}
@@ -1905,7 +1906,7 @@ function renderChannelVideosFromList({
description: detail.video?.description
})
).catch((error) => {
console.error("Failed to play channel video via event id:", error);
userLogger.error("Failed to play channel video via event id:", error);
if (typeof app?.playVideoWithFallback === "function") {
app.playVideoWithFallback({
url: detail.url,
@@ -1920,7 +1921,7 @@ function renderChannelVideosFromList({
Promise.resolve(
app.playVideoWithFallback({ url: detail.url, magnet: detail.magnet })
).catch((error) => {
console.error(
userLogger.error(
"Failed to start fallback playback for channel video:",
error
);
@@ -2235,7 +2236,7 @@ async function fetchChannelProfileFromRelays(pubkey) {
try {
await nostrClient.ensurePool();
} catch (error) {
console.error("Failed to initialize relay pool for channel profile:", error);
userLogger.error("Failed to initialize relay pool for channel profile:", error);
return { event: null, profile: {} };
}
@@ -2271,7 +2272,7 @@ async function fetchChannelProfileFromRelays(pubkey) {
const meta = JSON.parse(newestEvent.content);
return { event: newestEvent, profile: meta };
} catch (error) {
console.warn("Failed to parse channel metadata payload:", error);
userLogger.warn("Failed to parse channel metadata payload:", error);
return { event: newestEvent, profile: {} };
}
}
@@ -2343,7 +2344,7 @@ async function loadUserProfile(pubkey) {
""
});
} catch (error) {
console.warn(
userLogger.warn(
"Failed to persist channel profile metadata to cache:",
error
);
@@ -2359,7 +2360,7 @@ async function loadUserProfile(pubkey) {
});
} catch (error) {
if (loadToken === currentProfileLoadToken) {
console.error("Failed to fetch user profile data:", error);
userLogger.error("Failed to fetch user profile data:", error);
const lnEl = document.getElementById("channelLightning");
if (lnEl && !currentChannelLightningAddress) {
lnEl.textContent = "No lightning address found.";
@@ -2416,7 +2417,7 @@ async function loadUserVideos(pubkey) {
}
const ensureAccessPromise = accessControl.ensureReady().catch((error) => {
console.warn(
userLogger.warn(
"Failed to ensure admin lists were loaded before channel fetch:",
error
);
@@ -2448,7 +2449,7 @@ async function loadUserVideos(pubkey) {
events.push(...fallbackEvents);
}
} catch (error) {
console.error("Relay error (default pool):", error);
userLogger.error("Relay error (default pool):", error);
}
} else {
const relayPromises = relayList.map((url) =>
@@ -2466,7 +2467,7 @@ async function loadUserVideos(pubkey) {
}
if (result.reason) {
console.error(`Relay error (${relayUrl}):`, result.reason);
userLogger.error(`Relay error (${relayUrl}):`, result.reason);
}
});
}
@@ -2478,7 +2479,7 @@ async function loadUserVideos(pubkey) {
}
if (!container) {
console.warn("channelVideoList element not found in DOM.");
userLogger.warn("channelVideoList element not found in DOM.");
return;
}
@@ -2503,7 +2504,7 @@ async function loadUserVideos(pubkey) {
<p class="text-critical">Failed to load videos. Please try again.</p>
`;
}
console.error("Error loading user videos:", err);
userLogger.error("Error loading user videos:", err);
} finally {
await ensureAccessPromise;
if (loadToken === currentVideoLoadToken && container) {
@@ -2528,7 +2529,7 @@ window.addEventListener("bitvid:access-control-updated", () => {
}
loadUserVideos(currentChannelHex).catch((error) => {
console.error(
userLogger.error(
"Failed to refresh channel videos after admin update:",
error
);
@@ -2548,4 +2549,4 @@ function dedupeToNewestByRoot(videos) {
}
}
return Array.from(map.values());
}
}
+25 -3
View File
@@ -53,6 +53,28 @@ export { ALLOW_NSFW_CONTENT };
const WHITELIST_MODE_KEY = ADMIN_WHITELIST_MODE_STORAGE_KEY;
const DEFAULT_WHITELIST_ENABLED = DEFAULT_WHITELIST_MODE_ENABLED;
const fallbackConsole =
(typeof globalThis !== "undefined" && globalThis["console"]) || null;
const fallbackWarn = (...args) => {
if (fallbackConsole && typeof fallbackConsole.warn === "function") {
fallbackConsole.warn(...args);
}
};
const embeddedUserLogger =
(typeof globalThis !== "undefined" &&
globalThis.bitvidLogger &&
globalThis.bitvidLogger.user) ||
null;
const configLogger = {
warn: (...args) => {
if (embeddedUserLogger && typeof embeddedUserLogger.warn === "function") {
embeddedUserLogger.warn(...args);
return;
}
fallbackWarn(...args);
},
};
export function getWhitelistMode() {
try {
const raw = localStorage.getItem(WHITELIST_MODE_KEY);
@@ -61,7 +83,7 @@ export function getWhitelistMode() {
}
return raw === "true";
} catch (error) {
console.warn("Failed to read whitelist mode from storage:", error);
configLogger.warn("Failed to read whitelist mode from storage:", error);
return DEFAULT_WHITELIST_ENABLED;
}
}
@@ -70,7 +92,7 @@ export function setWhitelistMode(enabled) {
try {
localStorage.setItem(WHITELIST_MODE_KEY, enabled ? "true" : "false");
} catch (error) {
console.warn("Failed to persist whitelist mode to storage:", error);
configLogger.warn("Failed to persist whitelist mode to storage:", error);
}
}
@@ -92,4 +114,4 @@ export { WATCH_HISTORY_CACHE_TTL_MS };
export { VIEW_COUNT_DEDUPE_WINDOW_SECONDS };
export { VIEW_COUNT_BACKFILL_MAX_DAYS };
export { VIEW_COUNT_CACHE_TTL_MS };
export { ENSURE_PRESENCE_REBROADCAST_COOLDOWN_SECONDS };
export { ENSURE_PRESENCE_REBROADCAST_COOLDOWN_SECONDS };
+4 -3
View File
@@ -1,3 +1,4 @@
import { userLogger } from "./utils/logger.js";
const NEW_MODE = "new";
const FALLBACK_CONTEXT = Object.freeze({
@@ -87,8 +88,8 @@ export function applyDesignSystemAttributes(root = null) {
try {
element.setAttribute("data-ds", mode);
} catch (error) {
if (typeof console !== "undefined" && console && console.warn) {
console.warn("[design-system] Failed to set data-ds attribute:", error);
if (typeof console !== "undefined" && console && userLogger.warn) {
userLogger.warn("[design-system] Failed to set data-ds attribute:", error);
}
}
});
@@ -99,4 +100,4 @@ export function applyDesignSystemAttributes(root = null) {
export function subscribeToDesignSystemChanges(listener) {
void listener;
return () => {};
}
}
+6 -5
View File
@@ -1,3 +1,4 @@
import { userLogger } from "../utils/logger.js";
const DEFAULT_CARD_SELECTOR = ".card[data-video-id]";
function defaultIsCardVisible(entry) {
@@ -78,7 +79,7 @@ export function createCardObserver(options = {}) {
return prepared;
}
} catch (err) {
console.warn("[cardObserver] prepareEntries failed", err);
userLogger.warn("[cardObserver] prepareEntries failed", err);
}
}
@@ -122,7 +123,7 @@ export function createCardObserver(options = {}) {
state: state.customState,
}));
} catch (err) {
console.warn("[cardObserver] isCardVisible failed", err);
userLogger.warn("[cardObserver] isCardVisible failed", err);
visible = false;
}
@@ -142,7 +143,7 @@ export function createCardObserver(options = {}) {
},
});
} catch (err) {
console.warn("[cardObserver] onCardVisible failed", err);
userLogger.warn("[cardObserver] onCardVisible failed", err);
}
});
}
@@ -170,7 +171,7 @@ export function createCardObserver(options = {}) {
context: { container },
});
} catch (err) {
console.warn("[cardObserver] onCardRegister failed", err);
userLogger.warn("[cardObserver] onCardRegister failed", err);
}
}
state.observer.observe(card);
@@ -205,4 +206,4 @@ export function createCardObserver(options = {}) {
refresh,
getState,
};
}
}
+3 -2
View File
@@ -1,3 +1,4 @@
import { userLogger } from "../utils/logger.js";
// js/feedEngine/engine.js
import { isPlainObject } from "./utils.js";
@@ -93,7 +94,7 @@ function createExecutionContext(entry, { config, hooks, runtime, logger }) {
try {
resolvedLogger(`[feed:${entry.name}]`, ...args);
} catch (error) {
console.warn(`[feed:${entry.name}] logger threw`, error);
userLogger.warn(`[feed:${entry.name}] logger threw`, error);
}
},
addWhy: (detail) => {
@@ -229,4 +230,4 @@ export function createFeedEngine({ logger } = {}) {
};
}
export { DEFAULT_FEED_CONFIG, DEFAULT_CONFIG_SCHEMA };
export { DEFAULT_FEED_CONFIG, DEFAULT_CONFIG_SCHEMA };
+3 -2
View File
@@ -1,6 +1,7 @@
import { createCardObserver } from "./dom/cardObserver.js";
import { infoHashFromMagnet } from "./magnets.js";
import { updateVideoCardSourceVisibility } from "./utils/cardSourceVisibility.js";
import { userLogger } from "./utils/logger.js";
import { TorrentClient, torrentClient } from "./webtorrent.js";
const badgeUpdateListeners = new Set();
@@ -17,7 +18,7 @@ function notifyBadgeUpdate(payload) {
try {
listener(payload);
} catch (err) {
console.warn("[gridHealth] badge listener failed", err);
userLogger.warn("[gridHealth] badge listener failed", err);
}
});
}
@@ -581,7 +582,7 @@ function handleCardVisible({ card, pendingByCard, priority = 0 }) {
setBadge(card, "unhealthy", result);
})
.catch((err) => {
console.warn("[gridHealth] probe failed", err);
userLogger.warn("[gridHealth] probe failed", err);
pendingByCard.delete(card);
if (!card.isConnected) {
return;
+2 -1
View File
@@ -1,6 +1,7 @@
import PQueue from "https://esm.sh/[email protected]";
import { trackerPing } from "./trackerPing.js";
import { infoHashFromMagnet } from "./magnets.js";
import { userLogger } from "./utils/logger.js";
import { HEALTH_TTL_MS, CONCURRENCY } from "./trackerConfig.js";
const queue = new PQueue({ concurrency: CONCURRENCY });
@@ -72,7 +73,7 @@ export function queueHealthCheck(magnet, onResult) {
setHealthCache(infoHash, health);
return health;
} catch (err) {
console.warn("trackerPing failed", err);
userLogger.warn("trackerPing failed", err);
return getDefaultHealth();
}
})
+18 -17
View File
@@ -1,3 +1,4 @@
import { userLogger } from "./utils/logger.js";
// js/historyView.js
import watchHistoryService from "./watchHistoryService.js";
@@ -53,7 +54,7 @@ function resolveElement(selector) {
try {
return document.querySelector(selector);
} catch (error) {
console.warn("[historyView] Failed to query selector:", selector, error);
userLogger.warn("[historyView] Failed to query selector:", selector, error);
return null;
}
}
@@ -264,7 +265,7 @@ async function defaultRemoveHandler({
}
} catch (error) {
if (isDevEnv) {
console.warn("[historyView] Failed to update watch history list:", error);
userLogger.warn("[historyView] Failed to update watch history list:", error);
}
throw error;
}
@@ -307,7 +308,7 @@ function writePreference(key, value) {
storage.setItem(key, value);
} catch (error) {
if (isDevEnv) {
console.warn("[historyView] Failed to persist preference:", error);
userLogger.warn("[historyView] Failed to persist preference:", error);
}
}
}
@@ -732,7 +733,7 @@ export function createWatchHistoryRenderer(config = {}) {
unsubscribe();
} catch (error) {
if (isDevEnv) {
console.warn(
userLogger.warn(
"[historyView] Failed to unsubscribe from watch history event:",
error
);
@@ -1133,7 +1134,7 @@ export function createWatchHistoryRenderer(config = {}) {
return result.trim();
}
} catch (error) {
console.warn(
userLogger.warn(
"[historyView] Failed to resolve actor via getActor:",
error
);
@@ -1177,7 +1178,7 @@ export function createWatchHistoryRenderer(config = {}) {
watchHistoryService.getLocalMetadata(pointerKeyValue) || null;
} catch (error) {
if (isDevEnv) {
console.warn(
userLogger.warn(
"[historyView] Failed to read stored metadata for pointer:",
pointerKeyValue,
error
@@ -1213,7 +1214,7 @@ export function createWatchHistoryRenderer(config = {}) {
});
} catch (error) {
if (isDevEnv) {
console.warn(
userLogger.warn(
"[historyView] Failed to persist metadata for pointer:",
pointerKeyValue,
error
@@ -1227,7 +1228,7 @@ export function createWatchHistoryRenderer(config = {}) {
watchHistoryService.removeLocalMetadata(pointerKeyValue);
} catch (error) {
if (isDevEnv) {
console.warn(
userLogger.warn(
"[historyView] Failed to remove cached metadata for pointer:",
pointerKeyValue,
error
@@ -1268,7 +1269,7 @@ export function createWatchHistoryRenderer(config = {}) {
} catch (error) {
state.isRendering = false;
if (isDevEnv) {
console.warn("[historyView] Failed to hydrate batch:", error);
userLogger.warn("[historyView] Failed to hydrate batch:", error);
}
return;
}
@@ -1441,7 +1442,7 @@ export function createWatchHistoryRenderer(config = {}) {
watchHistoryService.clearLocalMetadata?.();
} catch (error) {
if (isDevEnv) {
console.warn(
userLogger.warn(
"[historyView] Failed to clear stored metadata while resetting progress:",
error
);
@@ -1484,7 +1485,7 @@ export function createWatchHistoryRenderer(config = {}) {
const app = getAppInstance();
app?.showError?.("Failed to publish watch history. Try again later.");
if (isDevEnv) {
console.warn("[historyView] Republish failed:", error);
userLogger.warn("[historyView] Republish failed:", error);
}
}
};
@@ -1560,7 +1561,7 @@ export function createWatchHistoryRenderer(config = {}) {
}
} catch (error) {
if (isDevEnv) {
console.warn(
userLogger.warn(
"[historyView] Failed to set metadata preference:",
error
);
@@ -1576,7 +1577,7 @@ export function createWatchHistoryRenderer(config = {}) {
watchHistoryService.clearLocalMetadata?.();
} catch (error) {
if (isDevEnv) {
console.warn(
userLogger.warn(
"[historyView] Failed to clear stored metadata after disabling preference:",
error
);
@@ -1909,7 +1910,7 @@ export function createWatchHistoryRenderer(config = {}) {
watchHistoryService.removeLocalMetadata?.(pointerKeyValue);
} catch (error) {
if (isDevEnv) {
console.warn(
userLogger.warn(
"[historyView] Failed to drop cached metadata for pointer:",
pointerKeyValue,
error
@@ -1948,7 +1949,7 @@ export function createWatchHistoryRenderer(config = {}) {
app?.showError?.("Failed to remove from history. Reloading list.");
}
if (isDevEnv) {
console.warn("[historyView] Removal failed:", error);
userLogger.warn("[historyView] Removal failed:", error);
}
} finally {
if (parentDay instanceof HTMLElement) {
@@ -1959,7 +1960,7 @@ export function createWatchHistoryRenderer(config = {}) {
await this.refresh({ force: true });
} catch (error) {
if (isDevEnv) {
console.warn(
userLogger.warn(
"[historyView] Failed to refresh watch history after removal:",
error
);
@@ -1993,4 +1994,4 @@ if (typeof window !== "undefined") {
window.bitvid = window.bitvid || {};
window.bitvid.initHistoryView = initHistoryView;
window.bitvid.watchHistoryRenderer = watchHistoryRenderer;
}
}
+21 -20
View File
@@ -1,3 +1,4 @@
import { devLogger, userLogger } from "./utils/logger.js";
// js/index.js
import { validateInstanceConfig } from "../config/validate-config.js";
@@ -53,7 +54,7 @@ function startApplication() {
setApplicationReady(startupPromise);
startupPromise.catch((error) => {
console.error("Application failed to initialize:", error);
userLogger.error("Application failed to initialize:", error);
});
return startupPromise;
@@ -149,9 +150,9 @@ async function loadModal(url) {
applyDesignSystemAttributes(modalContainer);
refreshThemeControls(modalContainer);
}
console.log(url, "loaded");
devLogger.log(url, "loaded");
} catch (err) {
console.error(err);
userLogger.error(err);
}
}
@@ -165,9 +166,9 @@ async function loadSidebar(url, containerId) {
applyDesignSystemAttributes(container);
refreshThemeControls(container);
}
console.log(url, "loaded into", containerId);
devLogger.log(url, "loaded into", containerId);
} catch (err) {
console.error(err);
userLogger.error(err);
}
}
@@ -181,9 +182,9 @@ async function loadDisclaimer(url, containerId) {
applyDesignSystemAttributes(container);
refreshThemeControls(container);
}
console.log(url, "disclaimer loaded into", containerId);
devLogger.log(url, "disclaimer loaded into", containerId);
} catch (err) {
console.error(err);
userLogger.error(err);
}
}
@@ -197,7 +198,7 @@ async function bootstrapInterface() {
loadModal("components/bug-fix-form.html"),
]);
console.log("Modals loaded.");
devLogger.log("Modals loaded.");
[
"loginModal",
@@ -211,7 +212,7 @@ async function bootstrapInterface() {
});
await loadSidebar("components/sidebar.html", "sidebarContainer");
console.log("Sidebar loaded.");
devLogger.log("Sidebar loaded.");
const sidebar = document.getElementById("sidebar");
const collapseToggle = document.getElementById("sidebarCollapseToggle");
@@ -219,7 +220,7 @@ async function bootstrapInterface() {
sidebar.setAttribute("data-footer-state", "collapsed");
}
if (!collapseToggle) {
console.warn("Sidebar collapse toggle not found; skipping density controls.");
userLogger.warn("Sidebar collapse toggle not found; skipping density controls.");
}
const mobileMenuBtn = document.getElementById("mobileMenuBtn");
@@ -241,7 +242,7 @@ async function bootstrapInterface() {
}
return storedValue === "true";
} catch (error) {
console.warn("Unable to read sidebar collapse state from storage:", error);
userLogger.warn("Unable to read sidebar collapse state from storage:", error);
return DEFAULT_SIDEBAR_COLLAPSED;
}
};
@@ -253,7 +254,7 @@ async function bootstrapInterface() {
collapsed ? "true" : "false",
);
} catch (error) {
console.warn("Unable to persist sidebar collapse state:", error);
userLogger.warn("Unable to persist sidebar collapse state:", error);
}
};
@@ -469,11 +470,11 @@ async function bootstrapInterface() {
sidebarModule.setupSidebarNavigation({ closeSidebar });
}
} catch (error) {
console.error("Failed to set up sidebar navigation:", error);
userLogger.error("Failed to set up sidebar navigation:", error);
}
await loadDisclaimer("components/disclaimer.html", "modalContainer");
console.log("Disclaimer loaded.");
devLogger.log("Disclaimer loaded.");
prepareStaticModal({ id: "disclaimerModal" });
const loginNavBtn = document.getElementById("loginButton");
@@ -538,13 +539,13 @@ async function initializeInterface() {
try {
await bootstrapInterface();
} catch (error) {
console.error("Failed to bootstrap bitvid interface:", error);
userLogger.error("Failed to bootstrap bitvid interface:", error);
}
}
function onDomReady() {
initializeInterface().catch((error) => {
console.error("Unhandled error during bitvid initialization:", error);
userLogger.error("Unhandled error during bitvid initialization:", error);
});
}
@@ -676,12 +677,12 @@ function handleQueryParams() {
}
async function handleHashChange() {
console.log("handleHashChange called, current hash =", window.location.hash);
devLogger.log("handleHashChange called, current hash =", window.location.hash);
try {
await applicationReadyPromise;
} catch (error) {
console.warn(
userLogger.warn(
"Proceeding with hash handling despite application initialization failure:",
error
);
@@ -715,6 +716,6 @@ async function handleHashChange() {
await initFn();
}
} catch (error) {
console.error("Failed to handle hash change:", error);
userLogger.error("Failed to handle hash change:", error);
}
}
}
+176 -175
View File
File diff suppressed because it is too large. Load diff
+6 -5
View File
@@ -1,3 +1,4 @@
import { userLogger } from "./utils/logger.js";
import {
ADMIN_LIST_NAMESPACE,
isDevMode,
@@ -47,7 +48,7 @@ function ensureValidUtf8Content(value) {
normalized = typeof stringified === "string" ? stringified : "";
} catch (error) {
if (isDevMode) {
console.warn(
userLogger.warn(
"[nostrEventSchemas] Failed to serialize view event content:",
error
);
@@ -67,7 +68,7 @@ function ensureValidUtf8Content(value) {
cachedUtf8Encoder.encode(normalized);
} catch (error) {
if (isDevMode) {
console.warn(
userLogger.warn(
"[nostrEventSchemas] Dropping invalid UTF-8 characters from event content",
error
);
@@ -83,7 +84,7 @@ function ensureValidUtf8Content(value) {
normalized = sanitized;
} catch (encodeError) {
if (isDevMode) {
console.warn(
userLogger.warn(
"[nostrEventSchemas] Failed to normalize view event content; defaulting to empty string",
encodeError
);
@@ -836,7 +837,7 @@ export function buildAdminListEvent(listKey, { pubkey, created_at, hexPubkeys =
const schema = getNostrEventSchema(resolveAdminNoteType(listKey));
if (!schema) {
if (isDevMode) {
console.warn(`[nostrEventSchemas] Unknown admin list key: ${listKey}`);
userLogger.warn(`[nostrEventSchemas] Unknown admin list key: ${listKey}`);
}
return {
kind: 30000,
@@ -874,4 +875,4 @@ if (typeof window !== "undefined") {
getAllSchemas: getAllNostrEventSchemas,
setOverrides: setNostrEventSchemaOverrides,
};
}
}
+2 -1
View File
@@ -1,3 +1,4 @@
import { userLogger } from "./utils/logger.js";
import { isDevMode } from "./config.js";
export const RELAY_PUBLISH_TIMEOUT_MS = 10_000;
@@ -89,7 +90,7 @@ export function publishEventToRelay(pool, url, event, options = {}) {
return true;
} catch (error) {
if (isDevMode) {
console.warn(
userLogger.warn(
`[nostrPublish] Relay publish handle rejected ${eventName} listener:`,
error,
);
+6 -5
View File
@@ -1,3 +1,4 @@
import { devLogger, userLogger } from "./utils/logger.js";
const REMOTE_IMPORT_TIMEOUT = 4500;
const LOCAL_IMPORT_TIMEOUT = 2500;
const NODE_IMPORT_TIMEOUT = 1500;
@@ -416,7 +417,7 @@ export function bootstrapNostrTools() {
reason: "Failed to resolve any nostr-tools helpers.",
attempts,
};
console.warn("[bitvid] nostr-tools bootstrap failed", failure);
userLogger.warn("[bitvid] nostr-tools bootstrap failed", failure);
return failure;
}
@@ -446,9 +447,9 @@ export function bootstrapNostrTools() {
if (resolvedNip04) {
canonicalTools.nip04 = resolvedNip04;
console.info("[bitvid] Initialized nostr nip04 helpers.");
devLogger.info("[bitvid] Initialized nostr nip04 helpers.");
} else {
console.warn(
userLogger.warn(
"[bitvid] NIP-04 helpers unavailable after bootstrap attempts."
);
}
@@ -507,7 +508,7 @@ export function bootstrapNostrTools() {
},
});
} catch (error) {
console.warn("[bitvid] Failed to install NostrTools guard.", error);
userLogger.warn("[bitvid] Failed to install NostrTools guard.", error);
}
applyActive(existingGlobalTools);
@@ -531,4 +532,4 @@ const nostrToolsReady = bootstrapNostrTools();
export { nostrToolsReady };
export default nostrToolsReady;
await nostrToolsReady;
await nostrToolsReady;
+5 -4
View File
@@ -1,3 +1,4 @@
import { userLogger } from "./utils/logger.js";
const DB_NAME = "bitvidSettings";
const DB_VERSION = 1;
const STORE_NAME = "kv";
@@ -183,20 +184,20 @@ function emitToast(message, { variant = "error", error } = {}) {
})
);
} catch (eventError) {
console.warn("[nwcSettings] Failed to dispatch toast event", eventError);
userLogger.warn("[nwcSettings] Failed to dispatch toast event", eventError);
}
}
}
function notifyFailure(message, error) {
const text = message || "NWC settings storage error.";
console.warn(`[nwcSettings] ${text}`, error);
userLogger.warn(`[nwcSettings] ${text}`, error);
emitToast(text, { variant: "error", error });
}
function notifyWarning(message, error) {
const text = message || "NWC settings storage warning.";
console.warn(`[nwcSettings] ${text}`, error);
userLogger.warn(`[nwcSettings] ${text}`, error);
emitToast(text, { variant: "warning", error });
}
@@ -365,4 +366,4 @@ export async function clearNwcSettings(pubkey) {
}
return true;
}
}
+15 -14
View File
@@ -1,3 +1,4 @@
import { userLogger } from "../utils/logger.js";
// js/payments/nwcClient.js
import { nostrToolsReady } from "../nostrToolsBootstrap.js";
@@ -119,7 +120,7 @@ let cachedNostrTools = __nwcNostrToolsBootstrap.toolkit || null;
const nostrToolsInitializationFailure = __nwcNostrToolsBootstrap.failure || null;
if (!cachedNostrTools && nostrToolsInitializationFailure) {
console.warn(
userLogger.warn(
"[nwcClient] nostr-tools helpers unavailable after bootstrap.",
nostrToolsInitializationFailure
);
@@ -150,7 +151,7 @@ async function ensureNostrTools() {
const result = await nostrToolsReadySource;
rememberNostrTools(result);
} catch (error) {
console.warn("[nwcClient] Failed to resolve nostr-tools helpers.", error);
userLogger.warn("[nwcClient] Failed to resolve nostr-tools helpers.", error);
}
if (!cachedNostrTools) {
rememberNostrTools(readToolkitFromScope());
@@ -200,7 +201,7 @@ function assertNostrTools(methods = []) {
const available = Array.isArray(Object.keys(tools))
? Object.keys(tools)
: [];
console.error(
userLogger.error(
"[nwcClient] Required NostrTools capability is missing.",
{
missingMethod: method,
@@ -208,7 +209,7 @@ function assertNostrTools(methods = []) {
}
);
} catch (loggingError) {
console.error(
userLogger.error(
"[nwcClient] Failed to enumerate available NostrTools methods.",
loggingError
);
@@ -454,7 +455,7 @@ function createNip44Encryption(context) {
const secretBytes = hexToBytesCompat(context.secretKey);
cachedKey = resolved.getConversationKey(secretBytes, context.walletPubkey);
} catch (error) {
console.warn("[nwcClient] Failed to derive nip44 conversation key", error);
userLogger.warn("[nwcClient] Failed to derive nip44 conversation key", error);
throw error;
}
}
@@ -527,7 +528,7 @@ function settleInfoRequest(result) {
try {
resolver(result || null);
} catch (error) {
console.warn("[nwcClient] Failed to resolve wallet info request", error);
userLogger.warn("[nwcClient] Failed to resolve wallet info request", error);
}
}
}
@@ -571,7 +572,7 @@ function requestInfoEvent(context) {
try {
socket.send(JSON.stringify(["REQ", infoSubscriptionId, filters]));
} catch (error) {
console.warn("[nwcClient] Failed to request wallet info event", error);
userLogger.warn("[nwcClient] Failed to request wallet info event", error);
settleInfoRequest(null);
return Promise.resolve(null);
}
@@ -619,7 +620,7 @@ async function ensureEncryption(context) {
try {
infoEvent = await requestInfoEvent(context);
} catch (error) {
console.warn("[nwcClient] Failed to load wallet info event", error);
userLogger.warn("[nwcClient] Failed to load wallet info event", error);
}
if (infoEvent) {
context.infoEvent = infoEvent;
@@ -735,12 +736,12 @@ function isSocketOpen() {
}
function handleSocketError(error) {
console.warn("[nwcClient] WebSocket error", error);
userLogger.warn("[nwcClient] WebSocket error", error);
closeSocket({ keepState: true });
}
function handleSocketClose() {
console.warn("[nwcClient] Wallet connection closed.");
userLogger.warn("[nwcClient] Wallet connection closed.");
closeSocket({ keepState: true });
}
@@ -782,7 +783,7 @@ async function handleSocketMessage(messageEvent) {
try {
payload = JSON.parse(messageEvent.data);
} catch (error) {
console.warn("[nwcClient] Failed to parse relay message", error);
userLogger.warn("[nwcClient] Failed to parse relay message", error);
return;
}
@@ -815,7 +816,7 @@ async function handleSocketMessage(messageEvent) {
finalizePendingRequest(pending);
pending.reject(error);
} else {
console.warn("[nwcClient] Failed to decrypt wallet response", error);
userLogger.warn("[nwcClient] Failed to decrypt wallet response", error);
}
return;
}
@@ -860,7 +861,7 @@ async function handleSocketMessage(messageEvent) {
}
if (type === "NOTICE" && payload.length >= 2) {
console.warn("[nwcClient] Relay notice:", payload[1]);
userLogger.warn("[nwcClient] Relay notice:", payload[1]);
return;
}
}
@@ -1127,4 +1128,4 @@ export const __TESTING__ = Object.freeze({
buildPayInvoiceParams,
getActiveState: () => activeState,
ensureEncryptionForContext: ensureEncryption,
});
});
+8 -7
View File
@@ -1,3 +1,4 @@
import { userLogger } from "../utils/logger.js";
// js/payments/platformAddress.js
import { PLATFORM_LUD16_OVERRIDE, ADMIN_SUPER_NPUB } from "../config.js";
@@ -106,7 +107,7 @@ const nostrToolsInitializationFailure =
__platformNostrToolsBootstrap.failure || null;
if (!cachedNostrTools && nostrToolsInitializationFailure) {
console.warn(
userLogger.warn(
"[platformAddress] nostr-tools helpers unavailable after bootstrap.",
nostrToolsInitializationFailure
);
@@ -137,7 +138,7 @@ async function ensureNostrTools() {
const result = await nostrToolsReadySource;
rememberNostrTools(result);
} catch (error) {
console.warn(
userLogger.warn(
"[platformAddress] Failed to resolve nostr-tools helpers.",
error
);
@@ -198,7 +199,7 @@ function decodeAdminPubkey() {
}
}
} catch (error) {
console.warn("[platformAddress] Failed to decode ADMIN_SUPER_NPUB", error);
userLogger.warn("[platformAddress] Failed to decode ADMIN_SUPER_NPUB", error);
}
}
@@ -233,7 +234,7 @@ async function fetchAdminMetadata(adminPubkey) {
try {
pool = await nostrClient.ensurePool();
} catch (error) {
console.warn("[platformAddress] Failed to initialize Nostr pool", error);
userLogger.warn("[platformAddress] Failed to initialize Nostr pool", error);
return null;
}
@@ -245,7 +246,7 @@ async function fetchAdminMetadata(adminPubkey) {
? nostrClient.relays
: [];
if (relayUrls.length === 0) {
console.warn("[platformAddress] Nostr client is not ready.");
userLogger.warn("[platformAddress] Nostr client is not ready.");
return null;
}
@@ -286,7 +287,7 @@ async function fetchAdminMetadata(adminPubkey) {
return lightningAddress || null;
} catch (error) {
console.warn("[platformAddress] Failed to fetch admin metadata", error);
userLogger.warn("[platformAddress] Failed to fetch admin metadata", error);
return null;
}
}
@@ -322,4 +323,4 @@ export async function getPlatformLightningAddress({ forceRefresh = false } = {})
export function __resetPlatformAddressCache() {
cachedAddress = null;
}
}
+4 -3
View File
@@ -1,3 +1,4 @@
import { userLogger } from "../utils/logger.js";
// js/payments/zapSplit.js
import { ADMIN_SUPER_NPUB } from "../config.js";
@@ -124,7 +125,7 @@ let cachedNostrTools = __zapNostrToolsBootstrap.toolkit || null;
const nostrToolsInitializationFailure = __zapNostrToolsBootstrap.failure || null;
if (!cachedNostrTools && nostrToolsInitializationFailure) {
console.warn(
userLogger.warn(
"[zapSplit] nostr-tools helpers unavailable after bootstrap.",
nostrToolsInitializationFailure
);
@@ -155,7 +156,7 @@ async function ensureNostrTools() {
const result = await nostrToolsReadySource;
rememberNostrTools(result);
} catch (error) {
console.warn("[zapSplit] Failed to resolve nostr-tools helpers.", error);
userLogger.warn("[zapSplit] Failed to resolve nostr-tools helpers.", error);
}
if (!cachedNostrTools) {
rememberNostrTools(readToolkitFromScope());
@@ -461,4 +462,4 @@ export const __TESTING__ = Object.freeze({
mergeDependencies,
parsePercentValue,
clampPercent,
});
});
+9 -8
View File
@@ -1,4 +1,5 @@
import { buildR2Key, buildPublicUrl } from "./r2.js";
import { userLogger } from "./utils/logger.js";
import {
sanitizeBucketName,
ensureBucket,
@@ -46,7 +47,7 @@ function loadSavedSettings() {
}
return parsed;
} catch (err) {
console.warn("Failed to read quick R2 settings:", err);
userLogger.warn("Failed to read quick R2 settings:", err);
return null;
}
}
@@ -55,7 +56,7 @@ function persistSettings(settings) {
try {
localStorage.setItem(STORAGE_KEY, JSON.stringify(settings));
} catch (err) {
console.warn("Failed to store quick R2 settings:", err);
userLogger.warn("Failed to store quick R2 settings:", err);
}
}
@@ -63,7 +64,7 @@ function clearSavedSettings() {
try {
localStorage.removeItem(STORAGE_KEY);
} catch (err) {
console.warn("Failed to clear quick R2 settings:", err);
userLogger.warn("Failed to clear quick R2 settings:", err);
}
}
@@ -258,7 +259,7 @@ export function initQuickR2Upload(app) {
origins: getCorsOrigins(),
});
} catch (corsErr) {
console.warn("Quick R2 CORS update failed:", corsErr);
userLogger.warn("Quick R2 CORS update failed:", corsErr);
}
}
@@ -292,7 +293,7 @@ export function initQuickR2Upload(app) {
enabled: false,
});
} catch (disableErr) {
console.warn("Quick R2 managed domain disable failed:", disableErr);
userLogger.warn("Quick R2 managed domain disable failed:", disableErr);
}
} else {
setStatus(
@@ -302,7 +303,7 @@ export function initQuickR2Upload(app) {
);
}
} catch (err) {
console.warn("Quick R2 custom domain error:", err);
userLogger.warn("Quick R2 custom domain error:", err);
setStatus(
elements.status,
err?.message
@@ -332,7 +333,7 @@ export function initQuickR2Upload(app) {
usedManagedFallback = true;
}
} catch (err) {
console.warn("Quick R2 managed domain enable failed:", err);
userLogger.warn("Quick R2 managed domain enable failed:", err);
setStatus(
elements.status,
err?.message
@@ -393,7 +394,7 @@ export function initQuickR2Upload(app) {
elements.form.requestSubmit();
}
} catch (err) {
console.error("Quick R2 upload failed:", err);
userLogger.error("Quick R2 upload failed:", err);
setStatus(
elements.status,
err?.message ? `Upload failed: ${err.message}` : "Upload failed.",
+7 -6
View File
@@ -1,3 +1,4 @@
import { userLogger } from "./utils/logger.js";
const DB_NAME = "bitvidSettings";
const DB_VERSION = 1;
const STORE_NAME = "kv";
@@ -104,7 +105,7 @@ export async function loadR2Settings() {
});
}
} catch (err) {
console.warn("Failed to open IndexedDB for settings, falling back:", err);
userLogger.warn("Failed to open IndexedDB for settings, falling back:", err);
}
try {
@@ -115,7 +116,7 @@ export async function loadR2Settings() {
}
}
} catch (err) {
console.warn("Failed to read fallback settings:", err);
userLogger.warn("Failed to read fallback settings:", err);
}
return normalizeSettings(null);
@@ -128,7 +129,7 @@ export async function saveR2Settings(settings) {
try {
db = await openSettingsDb();
} catch (err) {
console.warn("Unable to open IndexedDB, continuing with fallback:", err);
userLogger.warn("Unable to open IndexedDB, continuing with fallback:", err);
}
if (db) {
@@ -165,7 +166,7 @@ export async function clearR2Settings() {
cleared = true;
}
} catch (err) {
console.warn("Failed to clear IndexedDB settings:", err);
userLogger.warn("Failed to clear IndexedDB settings:", err);
}
try {
@@ -174,7 +175,7 @@ export async function clearR2Settings() {
cleared = true;
}
} catch (err) {
console.warn("Failed to clear fallback settings:", err);
userLogger.warn("Failed to clear fallback settings:", err);
}
return cleared;
@@ -255,4 +256,4 @@ export function buildPublicUrl(baseUrl, key) {
return `${sanitizedBase}/${encodedKey}`;
}
export { sanitizeBaseDomain };
export { sanitizeBaseDomain };
+8 -7
View File
@@ -1,6 +1,7 @@
import { isDevMode } from "./config.js";
import { DEFAULT_RELAY_URLS, nostrClient } from "./nostr.js";
import { buildRelayListEvent } from "./nostrEventSchemas.js";
import { userLogger } from "./utils/logger.js";
import {
publishEventToRelays,
assertAnyRelayAccepted,
@@ -538,12 +539,12 @@ class RelayPreferencesManager {
const reason = outcome.reason;
if (reason?.code === "timeout") {
if (isDevMode) {
console.warn(
userLogger.warn(
`[relayManager] Relay ${reason.relay} timed out while loading relay list (${reason.timeoutMs}ms)`
);
}
} else if (isDevMode) {
console.warn(
userLogger.warn(
`[relayManager] Relay ${reason?.relay || "unknown"} failed while loading relay list:`,
reason
);
@@ -559,7 +560,7 @@ class RelayPreferencesManager {
})
.catch((error) => {
if (isDevMode) {
console.warn("[relayManager] Background relay refresh failed", error);
userLogger.warn("[relayManager] Background relay refresh failed", error);
}
});
@@ -571,13 +572,13 @@ class RelayPreferencesManager {
if (error instanceof AggregateError) {
error.errors?.forEach((err) => {
if (err?.code === "timeout" && isDevMode) {
console.warn(
userLogger.warn(
`[relayManager] Relay ${err.relay} timed out while loading relay list (${err.timeoutMs}ms)`
);
}
});
} else if (isDevMode) {
console.warn("[relayManager] Fast relay fetch failed", error);
userLogger.warn("[relayManager] Fast relay fetch failed", error);
}
}
}
@@ -657,7 +658,7 @@ class RelayPreferencesManager {
if (publishError?.relayFailures?.length) {
publishError.relayFailures.forEach(
({ url, error: relayError, reason }) => {
console.error(
userLogger.error(
`[RelayPreferencesManager] Relay ${url} rejected relay list: ${reason}`,
relayError || reason
);
@@ -675,7 +676,7 @@ class RelayPreferencesManager {
: relayError
? String(relayError)
: "publish failed";
console.warn(
userLogger.warn(
`[RelayPreferencesManager] Relay ${url} did not acknowledge relay list: ${reason}`,
relayError
);
+4 -3
View File
@@ -1,3 +1,4 @@
import { userLogger } from "../utils/logger.js";
// js/services/authService.js
import {
@@ -94,7 +95,7 @@ export default class AuthService {
try {
this.logger(message, error);
} catch (logError) {
console.warn("[AuthService] logger threw", logError);
userLogger.warn("[AuthService] logger threw", logError);
}
});
}
@@ -103,7 +104,7 @@ export default class AuthService {
try {
this.logger(...args);
} catch (error) {
console.warn("[AuthService] logger threw", error);
userLogger.warn("[AuthService] logger threw", error);
}
}
@@ -951,4 +952,4 @@ export default class AuthService {
this.emitProfileList("hydrate");
return result;
}
}
}
+12 -11
View File
@@ -1,3 +1,4 @@
import { userLogger } from "../utils/logger.js";
import {
nostrClient,
convertEventToVideo,
@@ -53,7 +54,7 @@ class SimpleEventEmitter {
try {
this.logger(`nostrService listener for "${eventName}" threw`, error);
} catch (logError) {
console.warn("[nostrService] listener logger threw", logError);
userLogger.warn("[nostrService] listener logger threw", logError);
}
}
}
@@ -108,7 +109,7 @@ export class NostrService {
try {
this.logger(message, error);
} catch (logError) {
console.warn("[nostrService] logger threw", logError);
userLogger.warn("[nostrService] logger threw", logError);
}
});
this.videosMap = null;
@@ -118,7 +119,7 @@ export class NostrService {
try {
this.logger(...args);
} catch (error) {
console.warn("[nostrService] logger threw", error);
userLogger.warn("[nostrService] logger threw", error);
}
}
@@ -164,7 +165,7 @@ export class NostrService {
try {
current.unsub();
} catch (error) {
console.warn("[nostrService] Failed to unsubscribe from video feed:", error);
userLogger.warn("[nostrService] Failed to unsubscribe from video feed:", error);
}
}
this.setVideoSubscription(null);
@@ -209,7 +210,7 @@ export class NostrService {
return false;
}
} catch (error) {
console.warn("[nostrService] isAuthorBlocked handler threw", error);
userLogger.warn("[nostrService] isAuthorBlocked handler threw", error);
}
}
@@ -223,7 +224,7 @@ export class NostrService {
return false;
}
} catch (error) {
console.warn("[nostrService] access control check failed", error);
userLogger.warn("[nostrService] access control check failed", error);
return false;
}
}
@@ -254,7 +255,7 @@ export class NostrService {
try {
await this.accessControl.ensureReady();
} catch (error) {
console.warn(
userLogger.warn(
"[nostrService] Failed to ensure access control lists are ready:",
error
);
@@ -288,7 +289,7 @@ export class NostrService {
try {
onVideos(filtered, { reason });
} catch (error) {
console.warn("[nostrService] onVideos handler threw", error);
userLogger.warn("[nostrService] onVideos handler threw", error);
}
}
this.emit("videos:updated", { videos: filtered, reason });
@@ -318,7 +319,7 @@ export class NostrService {
this.emit("videos:fetched", { videos: filtered });
return filtered;
} catch (error) {
console.error("[nostrService] Failed to fetch videos:", error);
userLogger.error("[nostrService] Failed to fetch videos:", error);
return [];
}
}
@@ -362,11 +363,11 @@ export class NostrService {
collected.set(video.id, video);
this.nostrClient.allEvents.set(video.id, video);
} catch (error) {
console.warn("[nostrService] Failed to convert older event", error);
userLogger.warn("[nostrService] Failed to convert older event", error);
}
}
} catch (error) {
console.error("[nostrService] Failed to load older videos:", error);
userLogger.error("[nostrService] Failed to load older videos:", error);
return [];
}
+3 -2
View File
@@ -1,3 +1,4 @@
import { userLogger } from "../utils/logger.js";
// js/services/playbackService.js
class SimpleEventEmitter {
@@ -73,7 +74,7 @@ export class PlaybackService {
try {
this.logger(...args);
} catch (err) {
console.warn("[PlaybackService] logger threw", err);
userLogger.warn("[PlaybackService] logger threw", err);
}
}
@@ -765,4 +766,4 @@ class PlaybackSession extends SimpleEventEmitter {
}
}
export default PlaybackService;
export default PlaybackService;
+16 -15
View File
@@ -1,3 +1,4 @@
import { userLogger } from "../utils/logger.js";
import {
loadR2Settings,
saveR2Settings,
@@ -69,7 +70,7 @@ class R2Service {
try {
handler(detail);
} catch (err) {
console.error("[r2Service] Listener error for", event, err);
userLogger.error("[r2Service] Listener error for", event, err);
}
}
}
@@ -225,7 +226,7 @@ class R2Service {
this.populateCloudflareSettingsInputs(settings);
return settings;
} catch (err) {
console.error("Failed to load Cloudflare settings:", err);
userLogger.error("Failed to load Cloudflare settings:", err);
this.setSettings(createDefaultSettings());
this.populateCloudflareSettingsInputs(this.getSettings());
this.setCloudflareSettingsStatus(
@@ -285,7 +286,7 @@ class R2Service {
}
return true;
} catch (err) {
console.error("Failed to save Cloudflare settings:", err);
userLogger.error("Failed to save Cloudflare settings:", err);
if (!quiet) {
this.setCloudflareSettingsStatus(
"Failed to save settings. Check console for details.",
@@ -310,7 +311,7 @@ class R2Service {
this.setCloudflareSettingsStatus("Settings cleared.", "success");
return true;
} catch (err) {
console.error("Failed to clear Cloudflare settings:", err);
userLogger.error("Failed to clear Cloudflare settings:", err);
this.setCloudflareSettingsStatus("Failed to clear settings.", "error");
return false;
}
@@ -338,7 +339,7 @@ class R2Service {
try {
return deriveShortSubdomain(npub);
} catch (err) {
console.warn("Failed to derive short subdomain, falling back:", err);
userLogger.warn("Failed to derive short subdomain, falling back:", err);
}
const base = String(npub || "user")
@@ -382,7 +383,7 @@ class R2Service {
origins: corsOrigins,
});
} catch (err) {
console.warn("Failed to refresh bucket configuration:", err);
userLogger.warn("Failed to refresh bucket configuration:", err);
}
} else if (accessKeyId && secretAccessKey && corsOrigins.length > 0) {
try {
@@ -397,7 +398,7 @@ class R2Service {
origins: corsOrigins,
});
} catch (err) {
console.warn("Failed to refresh bucket CORS via access keys:", err);
userLogger.warn("Failed to refresh bucket CORS via access keys:", err);
}
}
return {
@@ -444,7 +445,7 @@ class R2Service {
origins: corsOrigins,
});
} catch (corsErr) {
console.warn(
userLogger.warn(
"Failed to ensure R2 CORS rules via access keys. Configure the bucket's CORS policy manually if uploads continue to fail.",
corsErr
);
@@ -485,7 +486,7 @@ class R2Service {
origins: corsOrigins,
});
} catch (err) {
console.warn("Failed to apply R2 CORS rules:", err);
userLogger.warn("Failed to apply R2 CORS rules:", err);
}
let publicBaseUrl = entry?.publicBaseUrl || "";
@@ -517,7 +518,7 @@ class R2Service {
enabled: false,
});
} catch (disableErr) {
console.warn("Failed to disable managed domain:", disableErr);
userLogger.warn("Failed to disable managed domain:", disableErr);
}
} else {
usedManagedFallback = true;
@@ -535,10 +536,10 @@ class R2Service {
enabled: false,
});
} catch (disableErr) {
console.warn("Failed to disable managed domain:", disableErr);
userLogger.warn("Failed to disable managed domain:", disableErr);
}
} else {
console.warn("Failed to attach custom domain, falling back:", err);
userLogger.warn("Failed to attach custom domain, falling back:", err);
usedManagedFallback = true;
customDomainStatus = "error";
}
@@ -699,7 +700,7 @@ class R2Service {
try {
bucketResult = await this.ensureBucketConfigForNpub(npub);
} catch (err) {
console.error("Failed to prepare R2 bucket:", err);
userLogger.error("Failed to prepare R2 bucket:", err);
this.setCloudflareUploadStatus(
err?.message ? `Bucket setup failed: ${err.message}` : "Bucket setup failed.",
"error"
@@ -760,7 +761,7 @@ class R2Service {
let publishOutcome = true;
if (typeof publishVideoNote !== "function") {
console.warn(
userLogger.warn(
"publishVideoNote handler missing; skipping publish step."
);
publishOutcome = false;
@@ -805,7 +806,7 @@ class R2Service {
return publishOutcome;
} catch (err) {
console.error("Cloudflare upload failed:", err);
userLogger.error("Cloudflare upload failed:", err);
this.setCloudflareUploadStatus(
err?.message ? `Upload failed: ${err.message}` : "Upload failed.",
"error"
+13 -12
View File
@@ -1,5 +1,6 @@
import { isDevMode } from "../config.js";
import { pointerArrayToKey } from "../utils/pointer.js";
import { userLogger } from "../utils/logger.js";
import {
ingestLocalViewEvent as defaultIngestLocalViewEvent,
} from "../viewCounter.js";
@@ -109,7 +110,7 @@ export default class WatchHistoryTelemetry {
this.watchHistoryService?.clearLocalMetadata?.();
} catch (error) {
if (isDevMode) {
console.warn(
userLogger.warn(
"[watchHistoryTelemetry] Failed to clear cached metadata after toggle off:",
error,
);
@@ -123,7 +124,7 @@ export default class WatchHistoryTelemetry {
}
} catch (error) {
if (isDevMode) {
console.warn(
userLogger.warn(
"[watchHistoryTelemetry] Failed to subscribe to metadata preference changes:",
error,
);
@@ -154,7 +155,7 @@ export default class WatchHistoryTelemetry {
}
} catch (error) {
if (isDevMode) {
console.warn(
userLogger.warn(
"[watchHistoryTelemetry] Failed to read metadata settings:",
error,
);
@@ -169,7 +170,7 @@ export default class WatchHistoryTelemetry {
this.watchHistoryService?.clearLocalMetadata?.();
} catch (error) {
if (isDevMode) {
console.warn(
userLogger.warn(
"[watchHistoryTelemetry] Failed to purge metadata cache while preference disabled:",
error,
);
@@ -206,7 +207,7 @@ export default class WatchHistoryTelemetry {
this.watchHistoryService.setLocalMetadata(pointerInfo.key, metadata);
} catch (error) {
if (isDevMode) {
console.warn(
userLogger.warn(
"[watchHistoryTelemetry] Failed to persist local metadata for pointer:",
pointerInfo.key,
error,
@@ -228,7 +229,7 @@ export default class WatchHistoryTelemetry {
this.watchHistoryService.removeLocalMetadata(pointerKey);
} catch (error) {
if (isDevMode) {
console.warn(
userLogger.warn(
"[watchHistoryTelemetry] Failed to remove cached metadata for pointer:",
pointerKey,
error,
@@ -278,7 +279,7 @@ export default class WatchHistoryTelemetry {
state.videoEl.removeEventListener(eventName, handler);
} catch (error) {
if (isDevMode) {
console.warn(
userLogger.warn(
`[watchHistoryTelemetry] Failed to detach ${eventName} listener:`,
error,
);
@@ -424,7 +425,7 @@ export default class WatchHistoryTelemetry {
}
} catch (error) {
if (isDevMode) {
console.warn(
userLogger.warn(
"[watchHistoryTelemetry] Exception while recording video view:",
error,
);
@@ -452,7 +453,7 @@ export default class WatchHistoryTelemetry {
});
} catch (error) {
if (isDevMode) {
console.warn(
userLogger.warn(
"[watchHistoryTelemetry] Failed to ingest local view event:",
error,
);
@@ -460,14 +461,14 @@ export default class WatchHistoryTelemetry {
}
}
} else if (isDevMode && viewResult) {
console.warn(
userLogger.warn(
"[watchHistoryTelemetry] View event rejected by relays:",
viewResult,
);
}
})().catch((error) => {
if (isDevMode) {
console.warn(
userLogger.warn(
"[watchHistoryTelemetry] Unexpected error while recording video view:",
error,
);
@@ -581,7 +582,7 @@ export default class WatchHistoryTelemetry {
try {
this.watchHistoryPreferenceUnsubscribe();
} catch (error) {
console.warn(
userLogger.warn(
"[watchHistoryTelemetry] Failed to unsubscribe watch history preference:",
error,
);
+5 -4
View File
@@ -1,3 +1,4 @@
import { userLogger } from "../utils/logger.js";
const state = {
pubkey: null,
currentUserNpub: null,
@@ -29,7 +30,7 @@ function notifyKey(key, value, previousValue) {
try {
callback(value, previousValue, createSnapshot());
} catch (error) {
console.warn(`[appState] subscriber for key "${key}" threw:`, error);
userLogger.warn(`[appState] subscriber for key "${key}" threw:`, error);
}
}
}
@@ -40,7 +41,7 @@ function notifyKey(key, value, previousValue) {
try {
callback(snapshot, { key, value, previousValue });
} catch (error) {
console.warn("[appState] global subscriber threw:", error);
userLogger.warn("[appState] global subscriber threw:", error);
}
}
}
@@ -158,7 +159,7 @@ function notifyModal(name, value, previousValue) {
try {
callback(value, previousValue, createSnapshot());
} catch (error) {
console.warn(`[appState] modal subscriber for "${name}" threw:`, error);
userLogger.warn(`[appState] modal subscriber for "${name}" threw:`, error);
}
}
}
@@ -218,4 +219,4 @@ export function resetAppState() {
state.videoSubscription,
previous.videoSubscription
);
}
}
+9 -8
View File
@@ -1,3 +1,4 @@
import { userLogger } from "../utils/logger.js";
import {
readUrlHealthFromStorage,
removeUrlHealthFromStorage,
@@ -187,7 +188,7 @@ export function readSavedProfilesPayloadFromStorage() {
}
return parsed;
} catch (error) {
console.warn(
userLogger.warn(
"[cache.readSavedProfilesPayloadFromStorage] Failed to parse payload:",
error
);
@@ -210,12 +211,12 @@ function writeSavedProfilesPayloadToStorage(payload) {
error.code === 22 ||
error.code === 1014);
if (isQuotaError) {
console.warn(
userLogger.warn(
"[cache.writeSavedProfilesPayloadToStorage] Storage quota exceeded; keeping in-memory copy only.",
error
);
} else {
console.warn(
userLogger.warn(
"[cache.writeSavedProfilesPayloadToStorage] Failed to persist saved profiles:",
error
);
@@ -232,7 +233,7 @@ export function persistSavedProfiles({ persistActive = true } = {}) {
try {
localStorage.removeItem(SAVED_PROFILES_STORAGE_KEY);
} catch (error) {
console.warn(
userLogger.warn(
"[cache.persistSavedProfiles] Failed to remove empty payload:",
error
);
@@ -349,7 +350,7 @@ export function loadSavedProfilesFromStorage() {
needsRewrite = true;
}
} catch (error) {
console.warn("[cache.loadSavedProfilesFromStorage] Failed to parse payload:", error);
userLogger.warn("[cache.loadSavedProfilesFromStorage] Failed to parse payload:", error);
needsRewrite = true;
}
@@ -493,7 +494,7 @@ export function loadProfileCacheFromStorage() {
});
}
} catch (error) {
console.warn("[cache.loadProfileCacheFromStorage] Failed to parse payload:", error);
userLogger.warn("[cache.loadProfileCacheFromStorage] Failed to parse payload:", error);
}
}
@@ -532,7 +533,7 @@ export function persistProfileCacheToStorage() {
try {
localStorage.removeItem(PROFILE_CACHE_STORAGE_KEY);
} catch (error) {
console.warn(
userLogger.warn(
"[cache.persistProfileCacheToStorage] Failed to clear storage:",
error
);
@@ -543,7 +544,7 @@ export function persistProfileCacheToStorage() {
try {
localStorage.setItem(PROFILE_CACHE_STORAGE_KEY, JSON.stringify(payload));
} catch (error) {
console.warn("[cache.persistProfileCacheToStorage] Failed to persist cache:", error);
userLogger.warn("[cache.persistProfileCacheToStorage] Failed to persist cache:", error);
}
}
+19 -18
View File
@@ -1,3 +1,4 @@
import { devLogger, userLogger } from "./utils/logger.js";
// js/subscriptions.js
import {
nostrClient,
@@ -40,7 +41,7 @@ class SubscriptionsManager {
*/
async loadSubscriptions(userPubkey) {
if (!userPubkey) {
console.warn("[SubscriptionsManager] No pubkey => cannot load subs.");
userLogger.warn("[SubscriptionsManager] No pubkey => cannot load subs.");
return;
}
try {
@@ -59,7 +60,7 @@ class SubscriptionsManager {
events.push(...result);
}
} catch (err) {
console.error(`[SubscriptionsManager] Relay error at ${url}`, err);
userLogger.error(`[SubscriptionsManager] Relay error at ${url}`, err);
}
}
@@ -82,7 +83,7 @@ class SubscriptionsManager {
newest.content
);
} catch (errDecrypt) {
console.error("[SubscriptionsManager] Decryption failed:", errDecrypt);
userLogger.error("[SubscriptionsManager] Decryption failed:", errDecrypt);
this.subscribedPubkeys.clear();
this.subsEventId = null;
this.loaded = true;
@@ -97,7 +98,7 @@ class SubscriptionsManager {
this.loaded = true;
} catch (err) {
console.error("[SubscriptionsManager] Failed to load subs:", err);
userLogger.error("[SubscriptionsManager] Failed to load subs:", err);
}
}
@@ -114,14 +115,14 @@ class SubscriptionsManager {
throw new Error("No user pubkey => cannot addChannel.");
}
if (this.subscribedPubkeys.has(channelHex)) {
console.log("Already subscribed to", channelHex);
devLogger.log("Already subscribed to", channelHex);
return;
}
this.subscribedPubkeys.add(channelHex);
await this.publishSubscriptionList(userPubkey);
this.refreshActiveFeed({ reason: "subscription-update" }).catch((error) => {
if (typeof console !== "undefined") {
console.warn(
userLogger.warn(
"[SubscriptionsManager] Failed to refresh after adding subscription:",
error
);
@@ -134,14 +135,14 @@ class SubscriptionsManager {
throw new Error("No user pubkey => cannot removeChannel.");
}
if (!this.subscribedPubkeys.has(channelHex)) {
console.log("Channel not found in subscription list:", channelHex);
devLogger.log("Channel not found in subscription list:", channelHex);
return;
}
this.subscribedPubkeys.delete(channelHex);
await this.publishSubscriptionList(userPubkey);
this.refreshActiveFeed({ reason: "subscription-update" }).catch((error) => {
if (typeof console !== "undefined") {
console.warn(
userLogger.warn(
"[SubscriptionsManager] Failed to refresh after removing subscription:",
error
);
@@ -173,7 +174,7 @@ class SubscriptionsManager {
try {
cipherText = await window.nostr.nip04.encrypt(userPubkey, plainStr);
} catch (err) {
console.error("Encryption failed:", err);
userLogger.error("Encryption failed:", err);
throw err;
}
@@ -187,7 +188,7 @@ class SubscriptionsManager {
try {
signedEvent = await window.nostr.signEvent(evt);
} catch (signErr) {
console.error("Failed to sign subscription list:", signErr);
userLogger.error("Failed to sign subscription list:", signErr);
throw signErr;
}
@@ -206,7 +207,7 @@ class SubscriptionsManager {
if (publishError?.relayFailures?.length) {
publishError.relayFailures.forEach(
({ url, error: relayError, reason }) => {
console.error(
userLogger.error(
`[SubscriptionsManager] Subscription list rejected by ${url}: ${reason}`,
relayError || reason
);
@@ -224,7 +225,7 @@ class SubscriptionsManager {
: relayError
? String(relayError)
: "publish failed";
console.warn(
userLogger.warn(
`[SubscriptionsManager] Subscription list not accepted by ${url}: ${reason}`,
relayError
);
@@ -233,7 +234,7 @@ class SubscriptionsManager {
this.subsEventId = signedEvent.id;
const acceptedUrls = publishSummary.accepted.map(({ url }) => url);
console.log(
devLogger.log(
"Subscription list published, event id:",
signedEvent.id,
"accepted relays:",
@@ -348,7 +349,7 @@ class SubscriptionsManager {
this.renderSameGridStyle(result, containerId, { limit, reason });
return result;
} catch (error) {
console.error(
userLogger.error(
"[SubscriptionsManager] Failed to run subscriptions feed:",
error
);
@@ -365,7 +366,7 @@ class SubscriptionsManager {
try {
app.registerSubscriptionsFeed();
} catch (error) {
console.warn(
userLogger.warn(
"[SubscriptionsManager] Failed to register subscriptions feed:",
error
);
@@ -607,7 +608,7 @@ class SubscriptionsManager {
magnet: detail.magnet
})
).catch((error) => {
console.error(
userLogger.error(
"[SubscriptionsManager] Failed to play by event id:",
error
);
@@ -617,7 +618,7 @@ class SubscriptionsManager {
Promise.resolve(
app?.playVideoWithFallback?.({ url: detail.url, magnet: detail.magnet })
).catch((error) => {
console.error(
userLogger.error(
"[SubscriptionsManager] Failed to start playback:",
error
);
@@ -714,4 +715,4 @@ class SubscriptionsManager {
}
}
export const subscriptions = new SubscriptionsManager();
export const subscriptions = new SubscriptionsManager();
+5 -5
View File
@@ -1,3 +1,4 @@
import { userLogger } from "./utils/logger.js";
const STORAGE_KEY = "bitvid:theme";
const FALLBACK_THEME = "dark";
const VALID_THEMES = new Set(["light", "dark"]);
@@ -42,7 +43,7 @@ const readStoredTheme = () => {
const stored = window.localStorage.getItem(STORAGE_KEY);
return normalizeTheme(stored);
} catch (error) {
console.warn("Unable to read stored theme preference:", error);
userLogger.warn("Unable to read stored theme preference:", error);
return null;
}
};
@@ -54,7 +55,7 @@ const persistTheme = (theme) => {
try {
window.localStorage.setItem(STORAGE_KEY, theme);
} catch (error) {
console.warn("Unable to persist theme preference:", error);
userLogger.warn("Unable to persist theme preference:", error);
}
};
@@ -92,7 +93,7 @@ const updateThemeColorMeta = (theme) => {
.trim();
}
} catch (error) {
console.warn("Unable to compute theme color token:", error);
userLogger.warn("Unable to compute theme color token:", error);
}
const fallback = FALLBACK_META_COLORS[theme] || FALLBACK_META_COLORS[FALLBACK_THEME];
@@ -179,7 +180,7 @@ const collectToggleElements = (root = document) => {
}
});
} catch (error) {
console.warn(`Invalid selector for theme toggle: ${selector}`, error);
userLogger.warn(`Invalid selector for theme toggle: ${selector}`, error);
}
});
@@ -269,4 +270,3 @@ export const initThemeController = () => {
applyTheme(initialTheme, { persist: true });
refreshThemeControls(document);
};
+8 -7
View File
@@ -1,3 +1,4 @@
import { userLogger } from "../../utils/logger.js";
// NOTE: Keep the Upload, Edit, and Revert modals in lockstep when updating NIP-71 form features.
import { createModalAccessibility } from "./modalAccessibility.js";
@@ -439,7 +440,7 @@ export class UploadModal {
unsubscribe();
}
} catch (error) {
console.warn("[UploadModal] Failed to remove R2 listener", error);
userLogger.warn("[UploadModal] Failed to remove R2 listener", error);
}
});
}
@@ -855,7 +856,7 @@ export class UploadModal {
await this.refreshCloudflareBucketPreview();
}
} catch (error) {
console.error("[UploadModal] Failed to save Cloudflare settings", error);
userLogger.error("[UploadModal] Failed to save Cloudflare settings", error);
}
}
@@ -869,7 +870,7 @@ export class UploadModal {
await this.refreshCloudflareBucketPreview();
}
} catch (error) {
console.error("[UploadModal] Failed to clear Cloudflare settings", error);
userLogger.error("[UploadModal] Failed to clear Cloudflare settings", error);
}
}
@@ -934,7 +935,7 @@ export class UploadModal {
onReset: () => this.resetCloudflareUploadForm()
});
} catch (error) {
console.error("[UploadModal] Cloudflare upload failed", error);
userLogger.error("[UploadModal] Cloudflare upload failed", error);
}
}
@@ -953,7 +954,7 @@ export class UploadModal {
cleanup();
}
} catch (error) {
console.warn("[UploadModal] Failed to remove handler", error);
userLogger.warn("[UploadModal] Failed to remove handler", error);
}
});
this.cleanupHandlers = [];
@@ -966,10 +967,10 @@ export class UploadModal {
unsubscribe();
}
} catch (error) {
console.warn("[UploadModal] Failed to cleanup R2 listener", error);
userLogger.warn("[UploadModal] Failed to cleanup R2 listener", error);
}
});
}
this.r2Unsubscribes = [];
}
}
}
+2 -1
View File
@@ -1,6 +1,7 @@
import { normalizeDesignSystemContext } from "../../designSystem.js";
import { updateVideoCardSourceVisibility } from "../../utils/cardSourceVisibility.js";
import positionFloatingPanel from "../utils/positionFloatingPanel.js";
import { userLogger } from "../../utils/logger.js";
import { createFloatingPanelStyles } from "../utils/floatingPanelStyles.js";
import {
getPopupOffsetPx,
@@ -1567,7 +1568,7 @@ export class VideoCard {
return typeof formatted === "string" ? formatted : "";
} catch (error) {
if (this.window?.console?.warn) {
this.window.console.warn(
this.window.userLogger.warn(
"[VideoCard] formatTimeAgo formatter threw",
error
);
+2 -1
View File
@@ -2,6 +2,7 @@ import { createModalAccessibility } from "./modalAccessibility.js";
import positionFloatingPanel from "../utils/positionFloatingPanel.js";
import { createFloatingPanelStyles } from "../utils/floatingPanelStyles.js";
import { applyDesignSystemAttributes } from "../../designSystem.js";
import { devLogger } from "../../utils/logger.js";
import {
getPopupOffsetPx,
getPopupViewportPaddingPx,
@@ -101,7 +102,7 @@ export class VideoModal {
this.logger(message, ...args);
return;
}
console.log(message, ...args);
devLogger.log(message, ...args);
}
addEventListener(type, listener, options) {
+2 -2
View File
@@ -1,3 +1,4 @@
import { userLogger } from "../../utils/logger.js";
// NOTE: Keep the Upload, Edit, and Revert modals in lockstep when updating NIP-71 form features.
const REPEATER_KEYS = ["imeta", "text-track", "segment", "t", "p", "r"];
@@ -36,7 +37,7 @@ export class Nip71FormManager {
try {
store.root.removeEventListener("click", store.handlers.click);
} catch (error) {
console.warn("[Nip71FormManager] Failed to detach previous handler", error);
userLogger.warn("[Nip71FormManager] Failed to detach previous handler", error);
}
}
@@ -779,4 +780,3 @@ export class Nip71FormManager {
return this.sections.get(key) || null;
}
}
+8 -7
View File
@@ -1,5 +1,6 @@
import { normalizeDesignSystemContext } from "../designSystem.js";
import positionFloatingPanel from "./utils/positionFloatingPanel.js";
import { userLogger } from "../utils/logger.js";
import { createFloatingPanelStyles } from "./utils/floatingPanelStyles.js";
import {
getPopupOffsetPx,
@@ -460,7 +461,7 @@ export default class MoreMenuController {
await this.clipboard.writeText(valueToCopy);
this.callbacks.showSuccess("Channel npub copied to clipboard!");
} catch (error) {
console.error("Failed to copy npub:", error);
userLogger.error("Failed to copy npub:", error);
this.callbacks.showError("Failed to copy the npub.");
}
break;
@@ -477,7 +478,7 @@ export default class MoreMenuController {
try {
await this.accessControl?.ensureReady?.();
} catch (error) {
console.warn(
userLogger.warn(
"Failed to refresh moderation state before blacklisting:",
error,
);
@@ -521,7 +522,7 @@ export default class MoreMenuController {
});
} catch (error) {
if (this.isDevMode) {
console.warn(
userLogger.warn(
"[Subscriptions] Failed to refresh after blacklist update:",
error,
);
@@ -552,7 +553,7 @@ export default class MoreMenuController {
}
}
} catch (error) {
console.error("Failed to add creator to blacklist:", error);
userLogger.error("Failed to add creator to blacklist:", error);
this.callbacks.showError(
"Failed to update the blacklist. Please try again.",
);
@@ -608,7 +609,7 @@ export default class MoreMenuController {
try {
this.callbacks.onUserBlocksUpdated();
} catch (error) {
console.warn(
userLogger.warn(
"[MoreMenu] Failed to refresh blocked list after update:",
error,
);
@@ -621,14 +622,14 @@ export default class MoreMenuController {
});
} catch (error) {
if (this.isDevMode) {
console.warn(
userLogger.warn(
"[Subscriptions] Failed to refresh after user block update:",
error,
);
}
}
} catch (error) {
console.error("Failed to update personal block list:", error);
userLogger.error("Failed to update personal block list:", error);
const message =
error?.code === "nip04-missing"
? "Your Nostr extension must support NIP-04 to manage private lists."
+32 -31
View File
@@ -1,3 +1,4 @@
import { devLogger, userLogger } from "../utils/logger.js";
import {
isDevMode,
ADMIN_SUPER_NPUB as CONFIG_ADMIN_SUPER_NPUB,
@@ -940,7 +941,7 @@ export class ProfileModalController {
try {
this.profileHistoryRenderer = this.createWatchHistoryRenderer(config);
} catch (error) {
console.error(
userLogger.error(
"[profileModal] Failed to create watch history renderer:",
error,
);
@@ -1372,7 +1373,7 @@ export class ProfileModalController {
try {
await this.switchProfile(entry.pubkey, { entry });
} catch (error) {
console.error("Failed to switch profile:", error);
userLogger.error("Failed to switch profile:", error);
} finally {
button.dataset.loading = "false";
button.setAttribute("aria-busy", "false");
@@ -1427,7 +1428,7 @@ export class ProfileModalController {
try {
this.profileHistoryRenderer?.pause();
} catch (error) {
console.warn("[profileModal] Failed to pause history renderer:", error);
userLogger.warn("[profileModal] Failed to pause history renderer:", error);
}
}
@@ -1990,7 +1991,7 @@ export class ProfileModalController {
}
this.populateBlockedList();
} catch (error) {
console.error("Failed to add creator to personal block list:", error);
userLogger.error("Failed to add creator to personal block list:", error);
context.error = error;
context.reason = error?.code || "service-error";
const message =
@@ -2026,7 +2027,7 @@ export class ProfileModalController {
}
if (!targetHex) {
console.warn("No valid pubkey to remove from block list:", candidate);
userLogger.warn("No valid pubkey to remove from block list:", candidate);
return;
}
@@ -2055,7 +2056,7 @@ export class ProfileModalController {
this.populateBlockedList();
} catch (error) {
console.error(
userLogger.error(
"Failed to remove creator from personal block list:",
error,
);
@@ -2111,7 +2112,7 @@ export class ProfileModalController {
renderer.resume();
}
} catch (error) {
console.error(
userLogger.error(
"[profileModal] Failed to populate watch history pane:",
error,
);
@@ -2769,11 +2770,11 @@ export class ProfileModalController {
if (loadError) {
if (loadError?.code === "nostr-unavailable") {
console.info("Moderation lists are still syncing with relays.");
devLogger.info("Moderation lists are still syncing with relays.");
return;
}
console.error("Failed to load admin lists:", loadError);
userLogger.error("Failed to load admin lists:", loadError);
this.showStatus(null);
this.showError("Unable to load moderation lists. Please try again.");
this.clearAdminLists();
@@ -2866,7 +2867,7 @@ export class ProfileModalController {
}
} catch (error) {
preloadError = error;
console.error("Failed to load admin lists before adding moderator:", error);
userLogger.error("Failed to load admin lists before adding moderator:", error);
}
if (preloadError) {
@@ -2970,7 +2971,7 @@ export class ProfileModalController {
}
} catch (error) {
preloadError = error;
console.error("Failed to load admin lists before removing moderator:", error);
userLogger.error("Failed to load admin lists before removing moderator:", error);
}
if (preloadError) {
@@ -3077,7 +3078,7 @@ export class ProfileModalController {
}
} catch (error) {
preloadError = error;
console.error("Failed to load admin lists before updating entries:", error);
userLogger.error("Failed to load admin lists before updating entries:", error);
}
if (preloadError) {
@@ -3162,7 +3163,7 @@ export class ProfileModalController {
this.showError(errorMessage);
}
if (isDevMode && notifyResult?.error) {
console.warn(
userLogger.warn(
"[admin] Failed to send list notification DM:",
notifyResult,
);
@@ -3178,9 +3179,9 @@ export class ProfileModalController {
}
} catch (error) {
context.notificationError = error;
console.error("Failed to send list notification DM:", error);
userLogger.error("Failed to send list notification DM:", error);
if (isDevMode) {
console.warn(
userLogger.warn(
"List update succeeded, but DM notification threw an unexpected error.",
error,
);
@@ -3468,7 +3469,7 @@ export class ProfileModalController {
targetHex,
});
} catch (refreshError) {
console.warn(
userLogger.warn(
"[ProfileModalController] Failed to refresh videos after blocklist mutation:",
refreshError,
);
@@ -3776,7 +3777,7 @@ export class ProfileModalController {
try {
await this.refreshAdminPaneState();
} catch (error) {
console.error(
userLogger.error(
"Failed to refresh admin pane while opening profile modal:",
error,
);
@@ -3793,7 +3794,7 @@ export class ProfileModalController {
const activeHex = this.normalizeHexPubkey(this.getActivePubkey());
await this.services.userBlocks.ensureLoaded(activeHex);
} catch (error) {
console.warn(
userLogger.warn(
"Failed to refresh user block list while opening profile modal:",
error,
);
@@ -3886,7 +3887,7 @@ export class ProfileModalController {
this.profileHistoryRenderer.destroy();
}
} catch (error) {
console.warn(
userLogger.warn(
"[profileModal] Failed to reset watch history renderer on close:",
error,
);
@@ -3913,7 +3914,7 @@ export class ProfileModalController {
try {
previous.focus();
} catch (error) {
console.warn(
userLogger.warn(
"[profileModal] Failed to restore focus after closing modal:",
error,
);
@@ -3926,7 +3927,7 @@ export class ProfileModalController {
try {
this.callbacks.onClose(this);
} catch (error) {
console.warn(
userLogger.warn(
"[profileModal] onClose callback threw while hiding modal:",
error,
);
@@ -3950,7 +3951,7 @@ export class ProfileModalController {
persistActive: false,
});
} catch (error) {
console.warn(
userLogger.warn(
"[profileModal] Failed to sync saved profiles during login:",
error,
);
@@ -3970,7 +3971,7 @@ export class ProfileModalController {
try {
await this.refreshAdminPaneState();
} catch (error) {
console.warn("Failed to refresh admin pane after login:", error);
userLogger.warn("Failed to refresh admin pane after login:", error);
}
this.populateBlockedList();
@@ -3984,7 +3985,7 @@ export class ProfileModalController {
this.refreshWalletPaneState();
})
.catch((error) => {
console.warn(
userLogger.warn(
"[profileModal] Failed to hydrate deferred login data:",
error,
);
@@ -4004,7 +4005,7 @@ export class ProfileModalController {
persistActive: false,
});
} catch (error) {
console.warn(
userLogger.warn(
"[profileModal] Failed to sync saved profiles during logout:",
error,
);
@@ -4023,7 +4024,7 @@ export class ProfileModalController {
try {
await this.refreshAdminPaneState();
} catch (error) {
console.warn("Failed to refresh admin pane after logout:", error);
userLogger.warn("Failed to refresh admin pane after logout:", error);
}
this.populateBlockedList();
@@ -4041,7 +4042,7 @@ export class ProfileModalController {
persistActive: false,
});
} catch (error) {
console.warn(
userLogger.warn(
"[profileModal] Failed to sync saved profiles after profile update:",
error,
);
@@ -4066,7 +4067,7 @@ export class ProfileModalController {
try {
result = this.services.removeSavedProfile(pubkey) || { removed: false };
} catch (error) {
console.error("Failed to remove saved profile:", error);
userLogger.error("Failed to remove saved profile:", error);
result = { removed: false, error };
}
@@ -4099,7 +4100,7 @@ export class ProfileModalController {
try {
return await hydrate(normalized);
} catch (error) {
console.warn(
userLogger.warn(
`[ProfileModalController] Failed to hydrate wallet settings for ${normalized}:`,
error,
);
@@ -4155,7 +4156,7 @@ export class ProfileModalController {
try {
return this.services.persistSavedProfiles(...args);
} catch (error) {
console.warn(
userLogger.warn(
"[ProfileModalController] Persist saved profiles service threw:",
error,
);
@@ -4205,4 +4206,4 @@ export class ProfileModalController {
}
}
export default ProfileModalController;
export default ProfileModalController;
+5 -4
View File
@@ -1,4 +1,5 @@
import { VideoCard } from "../components/VideoCard.js";
import { userLogger } from "../../utils/logger.js";
import {
subscribeToVideoViewCount,
unsubscribeFromVideoViewCount,
@@ -540,7 +541,7 @@ export class VideoListView {
})
.catch((error) => {
if (this.window?.console?.warn) {
this.window.console.warn(
this.window.userLogger.warn(
"[VideoListView] Failed to resolve posted timestamp:",
error
);
@@ -766,7 +767,7 @@ export class VideoListView {
try {
unsubscribeFromVideoViewCount(entry.pointer, entry.token);
} catch (error) {
console.warn(
userLogger.warn(
`[viewCount] Failed to unsubscribe from stale pointer ${key}:`,
error
);
@@ -920,7 +921,7 @@ export class VideoListView {
this.viewCountSubscriptions.set(pointerInfo.key, entry);
return entry;
} catch (error) {
console.warn("[viewCount] Failed to subscribe to view counter:", error);
userLogger.warn("[viewCount] Failed to subscribe to view counter:", error);
return null;
}
}
@@ -972,7 +973,7 @@ export class VideoListView {
try {
unsubscribeFromVideoViewCount(entry.pointer, entry.token);
} catch (error) {
console.warn(
userLogger.warn(
`[viewCount] Failed to unsubscribe from pointer ${key}:`,
error
);
+6 -5
View File
@@ -1,4 +1,5 @@
import { isDevMode } from "../config.js";
import { userLogger } from "../utils/logger.js";
import {
normalizePointerInput,
pointerKey as derivePointerKey,
@@ -23,7 +24,7 @@ function safeInvoke(callback, payload) {
callback(payload);
} catch (error) {
if (isDevMode) {
console.warn(
userLogger.warn(
"[watchHistoryController] onStateChange handler failed:",
error,
);
@@ -105,7 +106,7 @@ export default class WatchHistoryController {
return derivePointerKey(normalized) || "";
} catch (error) {
if (isDevMode) {
console.warn(
userLogger.warn(
"[watchHistoryController] Failed to derive pointer key:",
error,
);
@@ -322,7 +323,7 @@ export default class WatchHistoryController {
});
} catch (updateError) {
if (isDevMode) {
console.warn(
userLogger.warn(
"[watchHistoryController] Failed to update local watch history list:",
updateError,
);
@@ -356,13 +357,13 @@ export default class WatchHistoryController {
const result = this.watchHistoryService.snapshot(undefined, { reason });
return Promise.resolve(result).catch((error) => {
if (isDevMode) {
console.warn(`[${context}] Watch history flush failed:`, error);
userLogger.warn(`[${context}] Watch history flush failed:`, error);
}
throw error;
});
} catch (error) {
if (isDevMode) {
console.warn(`[${context}] Failed to queue watch history flush:`, error);
userLogger.warn(`[${context}] Failed to queue watch history flush:`, error);
}
return Promise.reject(error);
}
+11 -10
View File
@@ -1,4 +1,5 @@
import { isDevMode } from "../config.js";
import { userLogger } from "../utils/logger.js";
import {
calculateZapShares,
fetchLightningMetadata,
@@ -119,7 +120,7 @@ export default class ZapController {
this.applyDefaultAmount();
this.preloadLightningMetadata().catch((error) => {
if (isDevMode) {
console.warn("[zap] Preload metadata error:", error);
userLogger.warn("[zap] Preload metadata error:", error);
}
});
}
@@ -238,7 +239,7 @@ export default class ZapController {
Promise.resolve()
.then(() => this.requestWalletPane())
.catch((error) => {
console.error("Failed to open wallet pane:", error);
userLogger.error("Failed to open wallet pane:", error);
});
}
}
@@ -313,7 +314,7 @@ export default class ZapController {
await fetchLightningMetadata(lightningAddress);
} catch (error) {
if (isDevMode) {
console.warn("[zap] Failed to preload creator metadata:", error);
userLogger.warn("[zap] Failed to preload creator metadata:", error);
}
}
}
@@ -334,7 +335,7 @@ export default class ZapController {
setCachedPlatformLightningAddress(platformAddress || "");
} catch (error) {
if (isDevMode) {
console.warn("[zap] Failed to load platform Lightning address:", error);
userLogger.warn("[zap] Failed to load platform Lightning address:", error);
}
}
}
@@ -343,7 +344,7 @@ export default class ZapController {
await fetchLightningMetadata(platformAddress);
} catch (error) {
if (isDevMode) {
console.warn("[zap] Failed to preload platform metadata:", error);
userLogger.warn("[zap] Failed to preload platform metadata:", error);
}
}
}
@@ -428,7 +429,7 @@ export default class ZapController {
? details.retryAttempt
: undefined,
};
console.error("[zap] Modal zap failure", summary, error);
userLogger.error("[zap] Modal zap failure", summary, error);
};
const lightningAddress = this.getCurrentVideo()?.lightningAddress || "";
@@ -675,7 +676,7 @@ export default class ZapController {
overrideFee,
});
} catch (error) {
console.error(
userLogger.error(
"[zap] Modal lightning context failed",
{
amount,
@@ -720,7 +721,7 @@ export default class ZapController {
if (Array.isArray(shareTracker) && shareTracker.length) {
error.__zapShareTracker = shareTracker;
}
console.error(
userLogger.error(
"[zap] splitAndZap failed",
{
amount,
@@ -818,7 +819,7 @@ export default class ZapController {
const tracker = Array.isArray(error?.__zapShareTracker)
? error.__zapShareTracker
: [];
console.error(
userLogger.error(
"[zap] Modal zap retry failed",
{
shareType: share?.type || "unknown",
@@ -908,7 +909,7 @@ export default class ZapController {
const tracker = Array.isArray(error?.__zapShareTracker)
? error.__zapShareTracker
: [];
console.error(
userLogger.error(
"[zap] Modal zap attempt failed",
{
amount,
+2 -1
View File
@@ -1,4 +1,5 @@
import { createCardObserver } from "./dom/cardObserver.js";
import { userLogger } from "./utils/logger.js";
import { safeDecodeURIComponent } from "./utils/safeDecode.js";
const ROOT_MARGIN = "0px";
@@ -49,7 +50,7 @@ const urlCardObserver = createCardObserver({
try {
state.onCheck({ card, badgeEl, url, eventId });
} catch (err) {
console.warn("[urlHealthObserver] onCheck handler failed", err);
userLogger.warn("[urlHealthObserver] onCheck handler failed", err);
}
},
});
+13 -12
View File
@@ -1,3 +1,4 @@
import { userLogger } from "./utils/logger.js";
// js/userBlocks.js
import { nostrClient } from "./nostr.js";
import { buildBlockListEvent, BLOCK_LIST_IDENTIFIER } from "./nostrEventSchemas.js";
@@ -74,7 +75,7 @@ class UserBlockListManager {
}
if (!window?.nostr?.nip04?.decrypt) {
console.warn(
userLogger.warn(
"[UserBlockList] nip04.decrypt is unavailable; treating block list as empty."
);
this.reset();
@@ -202,7 +203,7 @@ class UserBlockListManager {
try {
decrypted = await window.nostr.nip04.decrypt(normalized, newest.content);
} catch (err) {
console.error("[UserBlockList] Failed to decrypt block list:", err);
userLogger.error("[UserBlockList] Failed to decrypt block list:", err);
this.blockedPubkeys.clear();
return;
}
@@ -225,7 +226,7 @@ class UserBlockListManager {
});
this.blockedPubkeys = new Set(sanitized);
} catch (err) {
console.error("[UserBlockList] Failed to parse block list:", err);
userLogger.error("[UserBlockList] Failed to parse block list:", err);
this.blockedPubkeys.clear();
}
};
@@ -247,12 +248,12 @@ class UserBlockListManager {
} else {
const reason = outcome.reason;
if (reason?.code === "timeout") {
console.warn(
userLogger.warn(
`[UserBlockList] Relay ${reason.relay} timed out while loading block list (${reason.timeoutMs}ms)`
);
} else {
const relay = reason?.relay || reason?.relayUrl;
console.error(
userLogger.error(
`[UserBlockList] Relay error at ${relay}:`,
reason?.error ?? reason
);
@@ -267,7 +268,7 @@ class UserBlockListManager {
await applyEvents(aggregated, { skipIfEmpty: true });
})
.catch((error) => {
console.error("[UserBlockList] background block list refresh failed:", error);
userLogger.error("[UserBlockList] background block list refresh failed:", error);
});
let fastResult = null;
@@ -278,13 +279,13 @@ class UserBlockListManager {
if (error instanceof AggregateError) {
error.errors?.forEach((err) => {
if (err?.code === "timeout") {
console.warn(
userLogger.warn(
`[UserBlockList] Relay ${err.relay} timed out while loading block list (${err.timeoutMs}ms)`
);
}
});
} else {
console.error("[UserBlockList] Fast block list fetch failed:", error);
userLogger.error("[UserBlockList] Fast block list fetch failed:", error);
}
}
}
@@ -299,7 +300,7 @@ class UserBlockListManager {
this.blockEventId = null;
background.catch(() => {});
} catch (error) {
console.error("[UserBlockList] loadBlocks failed:", error);
userLogger.error("[UserBlockList] loadBlocks failed:", error);
this.blockedPubkeys.clear();
} finally {
this.loaded = true;
@@ -431,7 +432,7 @@ class UserBlockListManager {
if (publishError?.relayFailures?.length) {
publishError.relayFailures.forEach(
({ url, error: relayError, reason }) => {
console.error(
userLogger.error(
`[UserBlockList] Block list rejected by ${url}: ${reason}`,
relayError || reason
);
@@ -449,7 +450,7 @@ class UserBlockListManager {
: relayError
? String(relayError)
: "publish failed";
console.warn(
userLogger.warn(
`[UserBlockList] Block list not accepted by ${url}: ${reason}`,
relayError
);
@@ -465,4 +466,4 @@ export const userBlocks = new UserBlockListManager();
if (typeof window !== "undefined") {
window.userBlocks = userBlocks;
}
}
+99
View File
@@ -0,0 +1,99 @@
// js/utils/logger.js
import { isDevMode } from "../config.js";
const noop = () => {};
const globalConsole = typeof globalThis !== "undefined" ? globalThis.console : undefined;
const safeConsole = {
log: globalConsole?.log?.bind(globalConsole) ?? noop,
info: globalConsole?.info?.bind(globalConsole) ?? noop,
warn: globalConsole?.warn?.bind(globalConsole) ?? noop,
error: globalConsole?.error?.bind(globalConsole) ?? noop,
debug: globalConsole?.debug?.bind(globalConsole) ?? noop,
trace: globalConsole?.trace?.bind(globalConsole) ?? noop,
group: globalConsole?.group?.bind(globalConsole) ?? noop,
groupCollapsed: globalConsole?.groupCollapsed?.bind(globalConsole) ?? noop,
groupEnd: globalConsole?.groupEnd?.bind(globalConsole) ?? noop,
table: globalConsole?.table?.bind(globalConsole) ?? noop,
assert: globalConsole?.assert?.bind(globalConsole) ?? noop,
};
function createChannel({ gateLogs, alwaysWarnError }) {
return {
log: (...args) => {
if (!gateLogs || isDevMode) {
safeConsole.log(...args);
}
},
info: (...args) => {
if (!gateLogs || isDevMode) {
safeConsole.info(...args);
}
},
debug: (...args) => {
if (!gateLogs || isDevMode) {
safeConsole.debug(...args);
}
},
trace: (...args) => {
if (!gateLogs || isDevMode) {
safeConsole.trace(...args);
}
},
group: (...args) => {
if (!gateLogs || isDevMode) {
safeConsole.group(...args);
}
},
groupCollapsed: (...args) => {
if (!gateLogs || isDevMode) {
safeConsole.groupCollapsed(...args);
}
},
groupEnd: (...args) => {
if (!gateLogs || isDevMode) {
safeConsole.groupEnd(...args);
}
},
table: (...args) => {
if (!gateLogs || isDevMode) {
safeConsole.table(...args);
}
},
assert: (...args) => {
if (!gateLogs || isDevMode) {
safeConsole.assert(...args);
}
},
warn: (...args) => {
if (!alwaysWarnError && gateLogs && !isDevMode) {
return;
}
safeConsole.warn(...args);
},
error: (...args) => {
if (!alwaysWarnError && gateLogs && !isDevMode) {
return;
}
safeConsole.error(...args);
},
};
}
const devChannel = createChannel({ gateLogs: true, alwaysWarnError: false });
const userChannel = createChannel({ gateLogs: true, alwaysWarnError: true });
const logger = {
dev: devChannel,
user: userChannel,
};
export const devLogger = devChannel;
export const userLogger = userChannel;
export default logger;
if (typeof window !== "undefined") {
window.bitvidLogger = logger;
}
+5 -4
View File
@@ -1,3 +1,4 @@
import { userLogger } from "logger.js";
// js/utils/storage.js
const URL_HEALTH_STORAGE_PREFIX = "bitvid:urlHealth:";
@@ -21,7 +22,7 @@ export function readUrlHealthFromStorage(eventId) {
return parsed;
}
} catch (err) {
console.warn(`Failed to parse stored URL health for ${eventId}:`, err);
userLogger.warn(`Failed to parse stored URL health for ${eventId}:`, err);
}
removeUrlHealthFromStorage(eventId);
@@ -39,7 +40,7 @@ export function writeUrlHealthToStorage(eventId, entry) {
JSON.stringify(entry)
);
} catch (err) {
console.warn(`Failed to persist URL health for ${eventId}:`, err);
userLogger.warn(`Failed to persist URL health for ${eventId}:`, err);
}
}
@@ -51,6 +52,6 @@ export function removeUrlHealthFromStorage(eventId) {
try {
localStorage.removeItem(getUrlHealthStorageKey(eventId));
} catch (err) {
console.warn(`Failed to remove URL health for ${eventId}:`, err);
userLogger.warn(`Failed to remove URL health for ${eventId}:`, err);
}
}
}
+13 -12
View File
@@ -1,3 +1,4 @@
import { userLogger } from "./utils/logger.js";
/**
* @module viewCounter
* @description Public API for tracking and formatting bitvid video view totals.
@@ -164,7 +165,7 @@ function normalizePointer(pointer) {
}
}
} catch (error) {
console.warn("[viewCounter] Failed to decode NIP-19 pointer:", error);
userLogger.warn("[viewCounter] Failed to decode NIP-19 pointer:", error);
}
}
}
@@ -279,7 +280,7 @@ function restoreCacheSnapshot() {
});
}
} catch (error) {
console.warn("[viewCounter] Failed to restore cached view counts:", error);
userLogger.warn("[viewCounter] Failed to restore cached view counts:", error);
}
}
@@ -307,7 +308,7 @@ function persistCacheSnapshot() {
};
localStorage.setItem(VIEW_COUNTER_STORAGE_KEY, JSON.stringify(payload));
} catch (error) {
console.warn("[viewCounter] Failed to persist view count cache:", error);
userLogger.warn("[viewCounter] Failed to persist view count cache:", error);
}
}
@@ -376,7 +377,7 @@ function notifyHandlers(key) {
try {
handler(snapshot);
} catch (error) {
console.warn("[viewCounter] View handler threw:", error);
userLogger.warn("[viewCounter] View handler threw:", error);
}
}
}
@@ -468,15 +469,15 @@ async function hydratePointer(key, listeners) {
try {
listResult = await listPromise;
} catch (error) {
console.warn("[viewCounter] Failed to hydrate view events via list:", error);
userLogger.warn("[viewCounter] Failed to hydrate view events via list:", error);
}
try {
countResult = await countPromise;
} catch (error) {
if (error?.name === "AbortError") {
console.warn("[viewCounter] View count hydration aborted:", error);
userLogger.warn("[viewCounter] View count hydration aborted:", error);
} else {
console.warn("[viewCounter] Failed to count view events:", error);
userLogger.warn("[viewCounter] Failed to count view events:", error);
}
}
let mutated = false;
@@ -549,7 +550,7 @@ function ensureLiveSubscription(key, listeners) {
try {
unsubscribe();
} catch (error) {
console.warn("[viewCounter] Failed to unsubscribe from view events:", error);
userLogger.warn("[viewCounter] Failed to unsubscribe from view events:", error);
}
listeners.liveUnsub = null;
if (!listeners.hydrationPromise) {
@@ -558,7 +559,7 @@ function ensureLiveSubscription(key, listeners) {
};
setPointerStatus(key, "live");
} catch (error) {
console.warn("[viewCounter] Failed to open live view subscription:", error);
userLogger.warn("[viewCounter] Failed to open live view subscription:", error);
}
}
@@ -583,7 +584,7 @@ export function subscribeToVideoViewCount(pointerInput, handler, options = {}) {
status: state.status,
});
} catch (error) {
console.warn("[viewCounter] Initial handler invocation threw:", error);
userLogger.warn("[viewCounter] Initial handler invocation threw:", error);
}
ensureHydration(key, listeners);
ensureLiveSubscription(key, listeners);
@@ -617,7 +618,7 @@ export function ingestLocalViewEvent({ event, pointer }) {
notifyHandlers(key);
}
} catch (error) {
console.warn("[viewCounter] Failed to ingest local view event:", error);
userLogger.warn("[viewCounter] Failed to ingest local view event:", error);
}
}
@@ -640,4 +641,4 @@ export function formatViewCount(total) {
return compactFormatter.format(value);
}
return String(value);
}
}
+6 -5
View File
@@ -1,3 +1,4 @@
import { devLogger, userLogger } from "./utils/logger.js";
// js/viewManager.js
import { initChannelProfileView } from "./channelProfile.js";
import { subscriptions } from "./subscriptions.js";
@@ -55,7 +56,7 @@ export async function loadView(viewUrl) {
container.appendChild(newScript);
});
} catch (err) {
console.error("View loading error:", err);
userLogger.error("View loading error:", err);
const fallbackMarkup = `
<div class="bv-stack">
<article class="card p-md" data-state="critical">
@@ -92,7 +93,7 @@ export const viewInitRegistry = {
}
},
explore: () => {
console.log("Explore view loaded.");
devLogger.log("Explore view loaded.");
},
history: async () => {
try {
@@ -101,7 +102,7 @@ export const viewInitRegistry = {
await module.initHistoryView();
}
} catch (error) {
console.error("Failed to initialize history view:", error);
userLogger.error("Failed to initialize history view:", error);
}
},
@@ -111,7 +112,7 @@ export const viewInitRegistry = {
* which loads subs if needed and renders the video grid in #subscriptionsVideoList
*/
subscriptions: async () => {
console.log("Subscriptions view loaded.");
devLogger.log("Subscriptions view loaded.");
const app = getApplication();
if (!app?.pubkey) {
@@ -134,4 +135,4 @@ export const viewInitRegistry = {
// Call the initialization function from channelProfile.js
initChannelProfileView();
},
};
};
+47 -46
View File
@@ -1,3 +1,4 @@
import { devLogger, userLogger } from "./utils/logger.js";
// js/watchHistoryService.js
import {
@@ -44,7 +45,7 @@ function resolveFlagEnabled() {
}
} catch (error) {
if (isDevMode) {
console.warn(
userLogger.warn(
"[watchHistoryService] Failed to read FEATURE_WATCH_HISTORY_V2 flag:",
error,
);
@@ -73,7 +74,7 @@ function getLoggedInActorKey() {
}
} catch (error) {
if (isDevMode) {
console.warn(
userLogger.warn(
"[watchHistoryService] Failed to normalize app login pubkey:",
error
);
@@ -169,7 +170,7 @@ function getSessionStorage() {
}
} catch (error) {
if (isDevMode) {
console.warn("[watchHistoryService] sessionStorage unavailable:", error);
userLogger.warn("[watchHistoryService] sessionStorage unavailable:", error);
}
}
return null;
@@ -182,7 +183,7 @@ function getLocalStorage() {
}
} catch (error) {
if (isDevMode) {
console.warn("[watchHistoryService] localStorage unavailable:", error);
userLogger.warn("[watchHistoryService] localStorage unavailable:", error);
}
}
return null;
@@ -206,7 +207,7 @@ function ensureMetadataPreference() {
}
} catch (error) {
if (isDevMode) {
console.warn(
userLogger.warn(
"[watchHistoryService] Failed to read metadata preference:",
error,
);
@@ -229,7 +230,7 @@ function persistMetadataPreference(value) {
}
} catch (error) {
if (isDevMode) {
console.warn(
userLogger.warn(
"[watchHistoryService] Failed to persist metadata preference:",
error,
);
@@ -316,7 +317,7 @@ function restoreMetadataCache() {
raw = storage.getItem(METADATA_STORAGE_KEY);
} catch (error) {
if (isDevMode) {
console.warn(
userLogger.warn(
"[watchHistoryService] Failed to read metadata cache:",
error,
);
@@ -333,7 +334,7 @@ function restoreMetadataCache() {
parsed = JSON.parse(raw);
} catch (error) {
if (isDevMode) {
console.warn(
userLogger.warn(
"[watchHistoryService] Failed to parse metadata cache:",
error,
);
@@ -342,7 +343,7 @@ function restoreMetadataCache() {
storage.removeItem(METADATA_STORAGE_KEY);
} catch (cleanupError) {
if (isDevMode) {
console.warn(
userLogger.warn(
"[watchHistoryService] Failed to clear corrupt metadata cache:",
cleanupError,
);
@@ -356,7 +357,7 @@ function restoreMetadataCache() {
storage.removeItem(METADATA_STORAGE_KEY);
} catch (cleanupError) {
if (isDevMode) {
console.warn(
userLogger.warn(
"[watchHistoryService] Failed to clear outdated metadata cache:",
cleanupError,
);
@@ -429,7 +430,7 @@ function persistMetadataCache() {
storage.removeItem(METADATA_STORAGE_KEY);
} catch (error) {
if (isDevMode) {
console.warn(
userLogger.warn(
"[watchHistoryService] Failed to clear metadata cache:",
error,
);
@@ -450,7 +451,7 @@ function persistMetadataCache() {
storage.setItem(METADATA_STORAGE_KEY, JSON.stringify(payload));
} catch (error) {
if (isDevMode) {
console.warn(
userLogger.warn(
"[watchHistoryService] Failed to persist metadata cache:",
error,
);
@@ -551,7 +552,7 @@ function emit(eventName, payload) {
callback(payload);
} catch (error) {
if (isDevMode) {
console.warn(
userLogger.warn(
`[watchHistoryService] Listener for ${eventName} failed:`,
error
);
@@ -567,7 +568,7 @@ function emit(eventName, payload) {
callback({ event: eventName, payload });
} catch (error) {
if (isDevMode) {
console.warn(
userLogger.warn(
`[watchHistoryService] Wildcard listener error for ${eventName}:`,
error
);
@@ -583,7 +584,7 @@ function emit(eventName, payload) {
window.dispatchEvent(evt);
} catch (error) {
if (isDevMode) {
console.warn(
userLogger.warn(
`[watchHistoryService] Failed to dispatch window event for ${eventName}:`,
error
);
@@ -640,7 +641,7 @@ function restoreQueueState() {
raw = storage.getItem(SESSION_STORAGE_KEY);
} catch (error) {
if (isDevMode) {
console.warn("[watchHistoryService] Failed to read session cache:", error);
userLogger.warn("[watchHistoryService] Failed to read session cache:", error);
}
return;
}
@@ -654,13 +655,13 @@ function restoreQueueState() {
parsed = JSON.parse(raw);
} catch (error) {
if (isDevMode) {
console.warn("[watchHistoryService] Failed to parse session cache:", error);
userLogger.warn("[watchHistoryService] Failed to parse session cache:", error);
}
try {
storage.removeItem(SESSION_STORAGE_KEY);
} catch (cleanupError) {
if (isDevMode) {
console.warn(
userLogger.warn(
"[watchHistoryService] Failed to clear corrupt session cache:",
cleanupError
);
@@ -674,7 +675,7 @@ function restoreQueueState() {
storage.removeItem(SESSION_STORAGE_KEY);
} catch (cleanupError) {
if (isDevMode) {
console.warn(
userLogger.warn(
"[watchHistoryService] Failed to clear outdated session cache:",
cleanupError
);
@@ -771,7 +772,7 @@ function persistQueueState() {
storage.removeItem(SESSION_STORAGE_KEY);
} catch (error) {
if (isDevMode) {
console.warn(
userLogger.warn(
"[watchHistoryService] Failed to clear empty session cache:",
error
);
@@ -784,7 +785,7 @@ function persistQueueState() {
storage.setItem(SESSION_STORAGE_KEY, JSON.stringify(payload));
} catch (error) {
if (isDevMode) {
console.warn("[watchHistoryService] Failed to persist session cache:", error);
userLogger.warn("[watchHistoryService] Failed to persist session cache:", error);
}
}
}
@@ -978,7 +979,7 @@ async function publishView(pointerInput, createdAt, metadata = {}) {
const viewResult = await nostrClient.recordVideoView(pointerInput, recordOptions);
console.info(
devLogger.info(
"[watchHistoryService] Video view recorded. Preparing watch list update.",
{
pointer: pointerInput,
@@ -989,7 +990,7 @@ async function publishView(pointerInput, createdAt, metadata = {}) {
const pointer = normalizePointerInput(pointerInput);
if (!pointer) {
console.warn(
userLogger.warn(
"[watchHistoryService] Skipping watch list update because pointer normalization failed.",
{ pointerInput }
);
@@ -1004,7 +1005,7 @@ async function publishView(pointerInput, createdAt, metadata = {}) {
"";
const actorKey = normalizeActorKey(actorCandidate);
if (!actorKey) {
console.warn(
userLogger.warn(
"[watchHistoryService] Unable to resolve actor for watch list update.",
{ actorCandidate }
);
@@ -1013,7 +1014,7 @@ async function publishView(pointerInput, createdAt, metadata = {}) {
const queue = ensureQueue(actorKey);
if (!queue) {
console.warn(
userLogger.warn(
"[watchHistoryService] Failed to resolve queue for actor.",
{ actorKey }
);
@@ -1024,7 +1025,7 @@ async function publishView(pointerInput, createdAt, metadata = {}) {
const normalizedPointer = normalizePointerInput(pointer);
if (!normalizedPointer) {
console.warn(
userLogger.warn(
"[watchHistoryService] Pointer normalization failed during queue preparation.",
{ pointerInput }
);
@@ -1064,7 +1065,7 @@ async function publishView(pointerInput, createdAt, metadata = {}) {
}
const key = pointerKey(normalizedPointer);
console.info(
devLogger.info(
"[watchHistoryService] Watch list process triggered by video view.",
{
actor: actorKey,
@@ -1084,7 +1085,7 @@ async function publishView(pointerInput, createdAt, metadata = {}) {
}
if (!key) {
console.warn(
userLogger.warn(
"[watchHistoryService] Pointer key generation failed. Skipping queue update.",
{ pointer: normalizedPointer }
);
@@ -1114,7 +1115,7 @@ async function publishView(pointerInput, createdAt, metadata = {}) {
queue.throttle.set(key, now);
persistQueueState();
notifyQueueChange(actorKey);
console.info(
devLogger.info(
"[watchHistoryService] Updated existing watch list entry.",
{
actor: actorKey,
@@ -1128,7 +1129,7 @@ async function publishView(pointerInput, createdAt, metadata = {}) {
if (throttled) {
queue.throttle.set(key, now);
if (isDevMode) {
console.info(
devLogger.info(
`[watchHistoryService] Throttled pointer ${key} for actor ${actorKey}.`
);
}
@@ -1144,7 +1145,7 @@ async function publishView(pointerInput, createdAt, metadata = {}) {
persistQueueState();
notifyQueueChange(actorKey);
console.info(
devLogger.info(
"[watchHistoryService] Added pointer to pending watch list snapshot queue.",
{
actor: actorKey,
@@ -1154,7 +1155,7 @@ async function publishView(pointerInput, createdAt, metadata = {}) {
);
if (!remoteEnabled) {
console.info(
devLogger.info(
"[watchHistoryService] Watch history sync unavailable for this actor; retaining pointer in local session queue only.",
{
actor: actorKey,
@@ -1175,7 +1176,7 @@ async function snapshot(items, options = {}) {
}
if (!isFeatureEnabled(actorKey)) {
console.info(
devLogger.info(
"[watchHistoryService] Snapshot skipped because watch history sync is unavailable for this actor.",
{
actor: actorKey,
@@ -1207,7 +1208,7 @@ async function snapshot(items, options = {}) {
const queue = ensureQueue(actorKey);
console.info(
devLogger.info(
"[watchHistoryService] Initiating watch list snapshot publish.",
{
actor: actorKey,
@@ -1227,7 +1228,7 @@ async function snapshot(items, options = {}) {
}
);
console.info(
devLogger.info(
"[watchHistoryService] Watch list snapshot publish completed.",
{
actor: actorKey,
@@ -1264,7 +1265,7 @@ async function snapshot(items, options = {}) {
await updateFingerprintCache(actorKey, publishResult.items || payloadItems);
emit("snapshot-complete", { actor: actorKey, reason, result: publishResult });
console.info(
devLogger.info(
"[watchHistoryService] Watch list snapshot processed and fingerprint cache updated.",
{
actor: actorKey,
@@ -1276,7 +1277,7 @@ async function snapshot(items, options = {}) {
})()
.catch((error) => {
if (isDevMode) {
console.warn("[watchHistoryService] Snapshot failed:", error);
userLogger.warn("[watchHistoryService] Snapshot failed:", error);
}
throw error;
})
@@ -1306,7 +1307,7 @@ function scheduleWatchHistoryRefresh(actorKey, cacheEntry = {}) {
})
.catch((error) => {
if (isDevMode) {
console.warn("[watchHistoryService] Failed to load watch history:", error);
userLogger.warn("[watchHistoryService] Failed to load watch history:", error);
}
throw error;
})
@@ -1317,7 +1318,7 @@ function scheduleWatchHistoryRefresh(actorKey, cacheEntry = {}) {
}
});
console.info("[watchHistoryService] Triggered nostr watch list refresh.", {
devLogger.info("[watchHistoryService] Triggered nostr watch list refresh.", {
actor: actorKey,
});
@@ -1348,7 +1349,7 @@ async function loadLatest(actorInput, options = {}) {
restoreQueueState();
}
const items = collectQueueItems(actorKey);
console.info(
devLogger.info(
"[watchHistoryService] loadLatest returning local-only watch history queue.",
{
actor: actorKey,
@@ -1360,7 +1361,7 @@ async function loadLatest(actorInput, options = {}) {
const now = Date.now();
const cacheEntry = state.fingerprintCache.get(actorKey);
console.info(
devLogger.info(
"[watchHistoryService] loadLatest invoked.",
{
actor: actorKey,
@@ -1375,7 +1376,7 @@ async function loadLatest(actorInput, options = {}) {
cacheEntry.expiresAt > now;
if (cacheIsFresh) {
console.info(
devLogger.info(
"[watchHistoryService] Returning cached watch list items.",
{
actor: actorKey,
@@ -1386,14 +1387,14 @@ async function loadLatest(actorInput, options = {}) {
}
if (cacheEntry?.promise) {
console.info(
devLogger.info(
"[watchHistoryService] Awaiting in-flight watch list refresh.",
{
actor: actorKey,
}
);
if (allowStale && hasCachedItems) {
console.info(
devLogger.info(
"[watchHistoryService] Returning stale watch list items while refresh completes.",
{
actor: actorKey,
@@ -1412,7 +1413,7 @@ async function loadLatest(actorInput, options = {}) {
const refreshPromise = scheduleWatchHistoryRefresh(actorKey, cacheEntry);
refreshPromise.catch(() => {});
console.info(
devLogger.info(
"[watchHistoryService] Returning stale watch list items while refresh is pending.",
{
actor: actorKey,
@@ -1533,4 +1534,4 @@ if (typeof window !== "undefined") {
}
export { watchHistoryService };
export default watchHistoryService;
export default watchHistoryService;
+6 -5
View File
@@ -1,3 +1,4 @@
import { devLogger, userLogger } from "./utils/logger.js";
//js/webtorrent.js
import WebTorrent from "./webtorrent.min.js";
@@ -288,7 +289,7 @@ export class TorrentClient {
}
log(msg) {
console.log(msg);
devLogger.log(msg);
}
async isBrave() {
@@ -608,20 +609,20 @@ export class TorrentClient {
err.message.includes("CORS") ||
err.message.includes("Access-Control-Allow-Origin")
) {
console.warn(
userLogger.warn(
"CORS warning detected. Attempting to remove the failing webseed/tracker."
);
if (torrent._opts?.urlList?.length) {
torrent._opts.urlList = torrent._opts.urlList.filter((url) => {
return !url.includes("distribution.bbb3d.renderfarming.net");
});
console.warn("Cleaned up webseeds =>", torrent._opts.urlList);
userLogger.warn("Cleaned up webseeds =>", torrent._opts.urlList);
}
if (torrent._opts?.announce?.length) {
torrent._opts.announce = torrent._opts.announce.filter((url) => {
return !url.includes("fastcast.nz");
});
console.warn("Cleaned up trackers =>", torrent._opts.announce);
userLogger.warn("Cleaned up trackers =>", torrent._opts.announce);
}
}
}
@@ -874,4 +875,4 @@ export class TorrentClient {
TorrentClient.PROBE_TRACKERS = DEFAULT_PROBE_TRACKERS;
export const torrentClient = new TorrentClient();
export const torrentClient = new TorrentClient();
+12 -11
View File
@@ -1,5 +1,6 @@
import { createBeaconToast } from "./ui/toastService.js";
import { createTorrentTable } from "./ui/torrentTable.js";
import { devLogger, userLogger } from "../js/utils/logger.js";
const VERSION = "2.0";
@@ -93,7 +94,7 @@ function prepareTorrentFiles(torrent) {
torrent.fileName = `${name}.torrent`;
}
} catch (error) {
console.warn("[beacon] Failed to create torrent blob URL", error);
userLogger.warn("[beacon] Failed to create torrent blob URL", error);
}
}
}
@@ -402,7 +403,7 @@ export function createBeaconApp({
file.getBlob((err, blob) => {
if (err || !blob) {
console.error("[beacon] Failed to get blob for file", file?.name, err);
userLogger.error("[beacon] Failed to get blob for file", file?.name, err);
toast.error("Failed to prepare file for download.");
return;
}
@@ -436,7 +437,7 @@ export function createBeaconApp({
toast.success("Magnet URI copied to clipboard!");
})
.catch((error) => {
console.error("[beacon] Clipboard error", error);
userLogger.error("[beacon] Clipboard error", error);
toast.error("Failed to copy magnet URI");
});
return;
@@ -453,7 +454,7 @@ export function createBeaconApp({
documentRef.body.removeChild(textarea);
toast.success("Magnet URI copied (fallback)!");
} catch (error) {
console.error("[beacon] Clipboard fallback error", error);
userLogger.error("[beacon] Clipboard fallback error", error);
toast.error("Failed to copy magnet URI");
}
}
@@ -465,7 +466,7 @@ export function createBeaconApp({
torrent.destroy((error) => {
if (error) {
console.error("[beacon] Failed to destroy torrent", error);
userLogger.error("[beacon] Failed to destroy torrent", error);
toast.error("Failed to remove torrent");
}
@@ -477,10 +478,10 @@ export function createBeaconApp({
}
function mount() {
console.log(`[beacon] Starting beacon runtime v${VERSION}`);
devLogger.log(`[beacon] Starting beacon runtime v${VERSION}`);
if (!toast) {
console.warn("[beacon] Toast service unavailable");
userLogger.warn("[beacon] Toast service unavailable");
}
if (!WebTorrentClass.WEBRTC_SUPPORT) {
@@ -557,7 +558,7 @@ export function createBeaconApp({
}
const errorHandler = (error) => {
console.error("[beacon] Torrent client error", error);
userLogger.error("[beacon] Torrent client error", error);
toast?.error(error?.message || String(error));
setProcessing(false);
};
@@ -604,7 +605,7 @@ export function createBeaconApp({
try {
task();
} catch (error) {
console.warn("[beacon] Cleanup task failed", error);
userLogger.warn("[beacon] Cleanup task failed", error);
}
});
cleanupTasks.length = 0;
@@ -614,11 +615,11 @@ export function createBeaconApp({
try {
client.destroy();
} catch (error) {
console.warn("[beacon] Failed to destroy client", error);
userLogger.warn("[beacon] Failed to destroy client", error);
}
}
return { mount, destroy };
}
export default createBeaconApp;
export default createBeaconApp;
+1 -1
View File
@@ -1 +1 @@
var O={info:"torrent-toast torrent-toast--info",success:"torrent-toast torrent-toast--success",error:"torrent-toast torrent-toast--error",warn:"torrent-toast torrent-toast--warn"},V="transition duration-200 ease-out",Y="beacon-toast-motion",q="data-beacon-motion";function J(e,t){let a=e?.defaultView;if(a&&typeof a.requestAnimationFrame=="function"){a.requestAnimationFrame(t);return}setTimeout(t,16)}function Q(e){let t=e||(typeof document<"u"?document:null);if(!t)return null;let a=t.getElementById("beacon-toast-container");if(!a){a=t.createElement("div"),a.id="beacon-toast-container",a.setAttribute("role","region"),a.setAttribute("aria-live","polite"),a.className=["pointer-events-none","fixed","inset-x-0","top-4","z-[70]","flex","flex-col","items-center","gap-3","px-4"].join(" ");let i=t.body||t.getElementsByTagName?.("body")?.[0];i&&i.appendChild(a)}return a}function X(e,t,a){let i=e.createElement("div");i.className=[V,a].join(" "),i.setAttribute("role","status"),i.setAttribute("tabindex","0"),i.textContent=t;let o=e.createElement("button");o.type="button",o.className=["absolute","right-3","top-3","rounded","p-1","text-current/70","hover:text-current","focus-visible:outline","focus-visible:outline-2","focus-visible:outline-offset-2","focus-visible:outline-info"].join(" "),o.setAttribute("aria-label","Dismiss notification"),o.innerHTML='<svg class="h-4 w-4" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M3.75 3.75l8.5 8.5"></path><path d="M12.25 3.75l-8.5 8.5"></path></svg>';let d=e.createElement("div");return d.className=["relative","w-full",V,Y].join(" "),d.setAttribute(q,"exit"),d.appendChild(i),i.appendChild(o),{wrapper:d,toast:i,closeButton:o}}function Z(e,t=setTimeout,a=clearTimeout){return{show(i,o={}){if(!i)return;let d=o.type&&O[o.type]?o.type:"info",n=Q(e);if(!n)return;let{wrapper:m,toast:c,closeButton:T}=X(e,i,O[d]);n.appendChild(m),J(e,()=>{m.setAttribute(q,"enter")});let w=typeof o.duration=="number"?o.duration:3500,p=()=>{m.setAttribute(q,"exit");let S=t(()=>{m.parentNode&&m.parentNode.removeChild(m)},200);return T.removeEventListener("click",E),c.removeEventListener("keydown",h),T.removeEventListener("keydown",h),S},E=()=>p(),h=S=>{S.key==="Escape"&&(S.stopPropagation(),p())};T.addEventListener("click",E),c.addEventListener("keydown",h),T.addEventListener("keydown",h);let N=null;return o.sticky||(N=t(()=>{p()},w)),{dismiss(){N&&a(N),p()}}},set(i,o){return typeof o=="string"?this.show(i,{type:o}):this.show(i,o)},info(i,o={}){return this.show(i,{...o,type:"info"})},success(i,o={}){return this.show(i,{...o,type:"success"})},error(i,o={}){return this.show(i,{...o,type:"error"})},warn(i,o={}){return this.show(i,{...o,type:"warn"})}}}function R(e,t=setTimeout,a=clearTimeout){return Z(e,t,a)}var $=[{key:"name",label:"Name",headerClass:"w-full sm:w-1/3 text-left",cellClass:"font-medium text-text truncate"},{key:"progress",label:"Progress",headerClass:"w-24 text-right",cellClass:"tabular-nums text-right",formatter:"progress"},{key:"downloadSpeed",label:"\u2193 Speed",headerClass:"w-24 text-right",cellClass:"tabular-nums text-right",formatter:"bytesPerSecond"},{key:"uploadSpeed",label:"\u2191 Speed",headerClass:"w-24 text-right",cellClass:"tabular-nums text-right",formatter:"bytesPerSecond"},{key:"numPeers",label:"Peers",headerClass:"w-20 text-right",cellClass:"tabular-nums text-right",formatter:"integer"},{key:"ratio",label:"Ratio",headerClass:"w-20 text-right",cellClass:"tabular-nums text-right",formatter:"ratio"}];function ee(e){return e?e.infoHash||e.magnetURI||e.name||String(Math.random()):""}function te(e,t){return!e||!t?!1:e===t||e.magnetURI&&e.magnetURI===t.magnetURI||e.infoHash&&e.infoHash===t.infoHash}function ne(e){return typeof e!="number"||Number.isNaN(e)?"":`${(e*100).toFixed(1)}%`}function re(e){return typeof e!="number"||!Number.isFinite(e)?"0.00":e.toFixed(2)}function oe(e){return typeof e!="number"||!Number.isFinite(e)?"0":Math.max(0,Math.floor(e)).toString()}function ae(e,t){if(typeof t=="function")return t(e,!0)||"";if(typeof e!="number"||Number.isNaN(e)||e<1)return"";let a=["B","kB","MB","GB","TB"],i=Math.min(Math.floor(Math.log(e)/Math.log(1e3)),a.length-1);return`${(e/Math.pow(1e3,i)).toFixed(1)} ${a[i]}/s`}function se(e,t){let a=e.formatter;if(typeof a=="function")return a;let i=t?.[a];if(typeof i=="function")return i;switch(a){case"progress":return ne;case"ratio":return re;case"integer":return oe;case"bytesPerSecond":return o=>ae(o,t?.bytes);default:return o=>o}}function W({documentRef:e=typeof document<"u"?document:null,root:t,onSelect:a,formatters:i={}}={}){if(!e)throw new Error("createTorrentTable requires a document reference");if(!(t instanceof e.defaultView.HTMLElement))throw new Error("createTorrentTable requires a valid root element");let o=e;t.innerHTML="";let d=o.createElement("div");d.className="overflow-hidden rounded-xl border border-border-translucent bg-surface shadLine truncated
var q={info:"torrent-toast torrent-toast--info",success:"torrent-toast torrent-toast--success",error:"torrent-toast torrent-toast--error",warn:"torrent-toast torrent-toast--warn"},$="transition duration-200 ease-out",oe="beacon-toast-motion",P="data-beacon-motion";function ae(e,r){let t=e?.defaultView;if(t&&typeof t.requestAnimationFrame=="function"){t.requestAnimationFrame(r);return}setTimeout(r,16)}function se(e){let r=e||(typeof document<"u"?document:null);if(!r)return null;let t=r.getElementById("beacon-toast-container");if(!t){t=r.createElement("div"),t.id="beacon-toast-container",t.setAttribute("role","region"),t.setAttribute("aria-live","polite"),t.className=["pointer-events-none","fixed","inset-x-0","top-0","z-overlay-toast","flex","w-full","flex-col","items-center","gap-3","px-4","pt-6","sm:items-end","sm:px-6","sm:pt-8"].join(" ");let i=r.body||r.getElementsByTagName?.("body")?.[0];i&&i.appendChild(t)}return t}function ie(e,r,t){let i=e.createElement("div");i.className=[$,t].join(" "),i.setAttribute("role","status"),i.setAttribute("tabindex","0"),i.textContent=r;let a=e.createElement("button");a.type="button",a.className=["notification-dismiss","focus-ring","absolute","right-3","top-3"].join(" "),a.setAttribute("aria-label","Dismiss notification"),a.innerHTML='<svg class="h-4 w-4" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M3.75 3.75l8.5 8.5"></path><path d="M12.25 3.75l-8.5 8.5"></path></svg>';let d=e.createElement("div");return d.className=["relative","w-full",$,oe].join(" "),d.setAttribute(P,"exit"),d.appendChild(i),i.appendChild(a),{wrapper:d,toast:i,closeButton:a}}function le(e,r=setTimeout,t=clearTimeout){return{show(i,a={}){if(!i)return;let d=a.type&&q[a.type]?a.type:"info",n=se(e);if(!n)return;let{wrapper:b,toast:c,closeButton:I}=ie(e,i,q[d]);n.appendChild(b),ae(e,()=>{b.setAttribute(P,"enter")});let A=typeof a.duration=="number"?a.duration:3500,m=()=>{b.setAttribute(P,"exit");let M=r(()=>{b.parentNode&&b.parentNode.removeChild(b)},200);return I.removeEventListener("click",S),c.removeEventListener("keydown",h),I.removeEventListener("keydown",h),M},S=()=>m(),h=M=>{M.key==="Escape"&&(M.stopPropagation(),m())};I.addEventListener("click",S),c.addEventListener("keydown",h),I.addEventListener("keydown",h);let B=null;return a.sticky||(B=r(()=>{m()},A)),{dismiss(){B&&t(B),m()}}},set(i,a){return typeof a=="string"?this.show(i,{type:a}):this.show(i,a)},info(i,a={}){return this.show(i,{...a,type:"info"})},success(i,a={}){return this.show(i,{...a,type:"success"})},error(i,a={}){return this.show(i,{...a,type:"error"})},warn(i,a={}){return this.show(i,{...a,type:"warn"})}}}function j(e,r=setTimeout,t=clearTimeout){return le(e,r,t)}var Y=[{key:"name",label:"Name",headerClass:"w-full sm:w-1/3 text-left",cellClass:"font-medium text-text truncate"},{key:"progress",label:"Progress",headerClass:"w-24 text-right",cellClass:"tabular-nums text-right",formatter:"progress"},{key:"downloadSpeed",label:"\u2193 Speed",headerClass:"w-24 text-right",cellClass:"tabular-nums text-right",formatter:"bytesPerSecond"},{key:"uploadSpeed",label:"\u2191 Speed",headerClass:"w-24 text-right",cellClass:"tabular-nums text-right",formatter:"bytesPerSecond"},{key:"numPeers",label:"Peers",headerClass:"w-20 text-right",cellClass:"tabular-nums text-right",formatter:"integer"},{key:"ratio",label:"Ratio",headerClass:"w-20 text-right",cellClass:"tabular-nums text-right",formatter:"ratio"}];function ce(e){return e?e.infoHash||e.magnetURI||e.name||String(Math.random()):""}function de(e,r){return!e||!r?!1:e===r||e.magnetURI&&e.magnetURI===r.magnetURI||e.infoHash&&e.infoHash===r.infoHash}function ue(e){return typeof e!="number"||Number.isNaN(e)?"":`${(e*100).toFixed(1)}%`}function pe(e){return typeof e!="number"||!Number.isFinite(e)?"0.00":e.toFixed(2)}function fe(e){return typeof e!="number"||!Number.isFinite(e)?"0":Math.max(0,Math.floor(e)).toString()}function me(e,r){if(typeof r=="function")return r(e,!0)||"";if(typeof e!="number"||Number.isNaN(e)||e<1)return"";let t=["B","kB","MB","GB","TB"],i=Math.min(Math.floor(Math.log(e)/Math.log(1e3)),t.length-1);return`${(e/Math.pow(1e3,i)).toFixed(1)} ${t[i]}/s`}function be(e,r){let t=e.formatter;if(typeof t=="function")return t;let i=r?.[t];if(typeof i=="function")return i;switch(t){case"progress":return ue;case"ratio":return pe;case"integer":return fe;case"bytesPerSecond":return a=>me(a,r?.bytes);default:return a=>a}}function G({documentRef:e=typeof document<"u"?document:null,root:r,onSelect:t,formatters:i={}}={}){if(!e)throw new Error("createTorrentTable requires a document reference");if(!(r instanceof e.defaultView.HTMLElement))throw new Error("createTorrentTable requires a valid root element");let a=e;r.innerHTML="";let d=a.createElement("div");d.className="overflow-hidden rounded-xl border border-border-translucent bg-surface shadow-sm";let n=a.createElement("div");n.className="overflow-x-aLine truncated
+3 -2
View File
@@ -1,4 +1,5 @@
import { createBeaconApp } from "../app.js";
import { userLogger } from "../../js/utils/logger.js";
function resolveWebTorrent() {
const globalScope =
@@ -36,14 +37,14 @@ if (typeof document !== "undefined") {
try {
mountBeaconApp();
} catch (error) {
console.error("[beacon] Failed to mount app", error);
userLogger.error("[beacon] Failed to mount app", error);
}
});
} else {
try {
mountBeaconApp();
} catch (error) {
console.error("[beacon] Failed to mount app", error);
userLogger.error("[beacon] Failed to mount app", error);
}
}
}
+10 -1
View File
@@ -14,6 +14,15 @@
<script>
(async () => {
const fallbackChannel = {
error: () => {},
warn: () => {},
info: () => {},
log: () => {},
};
const fallbackLogger = { dev: fallbackChannel, user: fallbackChannel };
const bitvidLogger =
(typeof window !== "undefined" && window.bitvidLogger) || fallbackLogger;
try {
const response = await fetch("content/about.md");
if (!response.ok) {
@@ -35,7 +44,7 @@
hljs.highlightBlock(block);
});
} catch (err) {
console.error("Error loading About content:", err);
bitvidLogger.user.error("Error loading About content:", err);
const container = document.getElementById("markdown-container");
if (container) {
container.innerHTML = `
+10 -1
View File
@@ -17,6 +17,15 @@
<script>
(async () => {
const fallbackChannel = {
error: () => {},
warn: () => {},
info: () => {},
log: () => {},
};
const fallbackLogger = { dev: fallbackChannel, user: fallbackChannel };
const bitvidLogger =
(typeof window !== "undefined" && window.bitvidLogger) || fallbackLogger;
try {
// Fetch the markdown file (change path if needed)
const response = await fetch("content/community-guidelines.md");
@@ -39,7 +48,7 @@
hljs.highlightBlock(block);
});
} catch (err) {
console.error("Error loading community guidelines:", err);
bitvidLogger.user.error("Error loading community guidelines:", err);
const container = document.getElementById("markdown-container");
if (container) {
container.innerHTML = `
+10 -1
View File
@@ -17,6 +17,15 @@
<script>
(async () => {
const fallbackChannel = {
error: () => {},
warn: () => {},
info: () => {},
log: () => {},
};
const fallbackLogger = { dev: fallbackChannel, user: fallbackChannel };
const bitvidLogger =
(typeof window !== "undefined" && window.bitvidLogger) || fallbackLogger;
try {
// Fetch the Markdown file
const response = await fetch("content/getting-started.md");
@@ -40,7 +49,7 @@
hljs.highlightBlock(block);
});
} catch (err) {
console.error("Error loading 'Getting Started' content:", err);
bitvidLogger.user.error("Error loading 'Getting Started' content:", err);
const container = document.getElementById("markdown-container");
if (container) {
container.innerHTML = `
+10 -1
View File
@@ -14,6 +14,15 @@
<script>
(async () => {
const fallbackChannel = {
error: () => {},
warn: () => {},
info: () => {},
log: () => {},
};
const fallbackLogger = { dev: fallbackChannel, user: fallbackChannel };
const bitvidLogger =
(typeof window !== "undefined" && window.bitvidLogger) || fallbackLogger;
try {
const response = await fetch("content/ipns.md");
if (!response.ok) {
@@ -35,7 +44,7 @@
hljs.highlightBlock(block);
});
} catch (err) {
console.error("Error loading IPNS content:", err);
bitvidLogger.user.error("Error loading IPNS content:", err);
const container = document.getElementById("markdown-container");
if (container) {
container.innerHTML = `
+10 -1
View File
@@ -14,6 +14,15 @@
<script>
(async () => {
const fallbackChannel = {
error: () => {},
warn: () => {},
info: () => {},
log: () => {},
};
const fallbackLogger = { dev: fallbackChannel, user: fallbackChannel };
const bitvidLogger =
(typeof window !== "undefined" && window.bitvidLogger) || fallbackLogger;
try {
const response = await fetch("content/links.md");
if (!response.ok) {
@@ -35,7 +44,7 @@
hljs.highlightBlock(block);
});
} catch (err) {
console.error("Error loading Links content:", err);
bitvidLogger.user.error("Error loading Links content:", err);
const container = document.getElementById("markdown-container");
if (container) {
container.innerHTML = `
+10 -1
View File
@@ -14,6 +14,15 @@
<script>
(async () => {
const fallbackChannel = {
error: () => {},
warn: () => {},
info: () => {},
log: () => {},
};
const fallbackLogger = { dev: fallbackChannel, user: fallbackChannel };
const bitvidLogger =
(typeof window !== "undefined" && window.bitvidLogger) || fallbackLogger;
try {
// Fetch your roadmap markdown
const response = await fetch("content/roadmap.md");
@@ -36,7 +45,7 @@
hljs.highlightBlock(block);
});
} catch (err) {
console.error("Error loading roadmap:", err);
bitvidLogger.user.error("Error loading roadmap:", err);
const container = document.getElementById("markdown-container");
if (container) {
container.innerHTML = `