mirror of
https://github.com/PR0M3TH3AN/bitvid.git
synced 2026-10-27 07:52:24 +00:00
Enable local watch history fallback when sync disabled
This commit is contained in:
1 parent
84b70475d9
commit
b1a493f113
3 files changed
+118
-51
No files matched your search
+25
-6
@@ -739,6 +739,12 @@ export function createWatchHistoryRenderer(config = {}) {
|
||||
},
|
||||
} = config;
|
||||
|
||||
const syncEnabled = watchHistoryService.isEnabled?.() === true;
|
||||
const localSupported =
|
||||
typeof watchHistoryService.supportsLocalHistory === "function"
|
||||
? watchHistoryService.supportsLocalHistory() !== false
|
||||
: true;
|
||||
|
||||
const state = {
|
||||
initialized: false,
|
||||
actor: null,
|
||||
@@ -763,7 +769,9 @@ export function createWatchHistoryRenderer(config = {}) {
|
||||
? watchHistoryService.shouldStoreMetadata() !== false
|
||||
: true,
|
||||
sessionFallbackActive: false,
|
||||
featureEnabled: watchHistoryService.isEnabled?.() === true,
|
||||
syncEnabled,
|
||||
localSupported,
|
||||
featureEnabled: syncEnabled || localSupported,
|
||||
};
|
||||
|
||||
let elements = {
|
||||
@@ -895,18 +903,29 @@ export function createWatchHistoryRenderer(config = {}) {
|
||||
}
|
||||
|
||||
function updateFeatureBanner() {
|
||||
const enabled = watchHistoryService.isEnabled?.() === true;
|
||||
state.featureEnabled = enabled;
|
||||
const syncEnabled = watchHistoryService.isEnabled?.() === true;
|
||||
const localSupported =
|
||||
typeof watchHistoryService.supportsLocalHistory === "function"
|
||||
? watchHistoryService.supportsLocalHistory() !== false
|
||||
: true;
|
||||
state.syncEnabled = syncEnabled;
|
||||
state.localSupported = localSupported;
|
||||
state.featureEnabled = syncEnabled || localSupported;
|
||||
if (!(elements.featureBanner instanceof HTMLElement)) {
|
||||
return;
|
||||
}
|
||||
if (enabled) {
|
||||
if (syncEnabled) {
|
||||
elements.featureBanner.textContent = "";
|
||||
setHidden(elements.featureBanner, true);
|
||||
return;
|
||||
}
|
||||
elements.featureBanner.textContent =
|
||||
"Watch history sync is disabled on this server. Local history only.";
|
||||
if (localSupported) {
|
||||
elements.featureBanner.textContent =
|
||||
"Watch history sync is disabled on this server. Local history only.";
|
||||
} else {
|
||||
elements.featureBanner.textContent =
|
||||
"Watch history is disabled on this server.";
|
||||
}
|
||||
setHidden(elements.featureBanner, false);
|
||||
}
|
||||
|
||||
|
||||
+27
-45
@@ -454,9 +454,6 @@ function getOrCreateQueue(actorKey) {
|
||||
}
|
||||
|
||||
function restoreQueueState() {
|
||||
if (!isFeatureEnabled()) {
|
||||
return;
|
||||
}
|
||||
if (state.restored) {
|
||||
return;
|
||||
}
|
||||
@@ -567,9 +564,6 @@ function restoreQueueState() {
|
||||
}
|
||||
|
||||
function ensureQueue(actorKey) {
|
||||
if (!isFeatureEnabled()) {
|
||||
return null;
|
||||
}
|
||||
if (!actorKey) {
|
||||
return null;
|
||||
}
|
||||
@@ -580,9 +574,6 @@ function ensureQueue(actorKey) {
|
||||
}
|
||||
|
||||
function persistQueueState() {
|
||||
if (!isFeatureEnabled()) {
|
||||
return;
|
||||
}
|
||||
const storage = getSessionStorage();
|
||||
if (!storage) {
|
||||
return;
|
||||
@@ -647,9 +638,6 @@ function resolveActorKey(actorInput) {
|
||||
}
|
||||
|
||||
function collectQueueItems(actorKey) {
|
||||
if (!isFeatureEnabled()) {
|
||||
return [];
|
||||
}
|
||||
const queue = state.queues.get(actorKey);
|
||||
if (!queue) {
|
||||
return [];
|
||||
@@ -675,9 +663,6 @@ function collectQueueItems(actorKey) {
|
||||
}
|
||||
|
||||
function notifyQueueChange(actorKey) {
|
||||
if (!isFeatureEnabled()) {
|
||||
return;
|
||||
}
|
||||
emit("queue-changed", {
|
||||
actor: actorKey,
|
||||
items: collectQueueItems(actorKey),
|
||||
@@ -685,9 +670,6 @@ function notifyQueueChange(actorKey) {
|
||||
}
|
||||
|
||||
function clearQueue(actorKey) {
|
||||
if (!isFeatureEnabled()) {
|
||||
return;
|
||||
}
|
||||
const queue = state.queues.get(actorKey);
|
||||
if (!queue) {
|
||||
return;
|
||||
@@ -834,17 +816,6 @@ async function publishView(pointerInput, createdAt, metadata = {}) {
|
||||
}
|
||||
);
|
||||
|
||||
if (!isFeatureEnabled()) {
|
||||
console.info(
|
||||
"[watchHistoryService] Watch history feature disabled; skipping queue update.",
|
||||
{
|
||||
pointer: pointerInput,
|
||||
createdAt,
|
||||
}
|
||||
);
|
||||
return viewResult;
|
||||
}
|
||||
|
||||
const pointer = normalizePointerInput(pointerInput);
|
||||
if (!pointer) {
|
||||
console.warn(
|
||||
@@ -981,6 +952,17 @@ async function publishView(pointerInput, createdAt, metadata = {}) {
|
||||
}
|
||||
);
|
||||
|
||||
if (!isFeatureEnabled()) {
|
||||
console.info(
|
||||
"[watchHistoryService] Watch history sync disabled; retaining pointer in local session queue only.",
|
||||
{
|
||||
actor: actorKey,
|
||||
pointerKey: key,
|
||||
watchedAt: normalizedPointer.watchedAt,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
return viewResult;
|
||||
}
|
||||
|
||||
@@ -1104,18 +1086,26 @@ async function snapshot(items, options = {}) {
|
||||
}
|
||||
|
||||
async function loadLatest(actorInput) {
|
||||
if (!isFeatureEnabled()) {
|
||||
console.info(
|
||||
"[watchHistoryService] loadLatest skipped because watch history feature is disabled.",
|
||||
{ actor: resolveActorKey(actorInput) || null }
|
||||
);
|
||||
return [];
|
||||
}
|
||||
const actorKey = resolveActorKey(actorInput);
|
||||
if (!actorKey) {
|
||||
return [];
|
||||
}
|
||||
|
||||
if (!isFeatureEnabled()) {
|
||||
if (!state.restored) {
|
||||
restoreQueueState();
|
||||
}
|
||||
const items = collectQueueItems(actorKey);
|
||||
console.info(
|
||||
"[watchHistoryService] loadLatest returning session watch history queue.",
|
||||
{
|
||||
actor: actorKey,
|
||||
itemCount: items.length,
|
||||
}
|
||||
);
|
||||
return items;
|
||||
}
|
||||
|
||||
const now = Date.now();
|
||||
const cacheEntry = state.fingerprintCache.get(actorKey);
|
||||
console.info(
|
||||
@@ -1217,9 +1207,6 @@ async function getFingerprint(actorInput) {
|
||||
}
|
||||
|
||||
function resetProgress(actorInput) {
|
||||
if (!isFeatureEnabled()) {
|
||||
return;
|
||||
}
|
||||
const actorKey = normalizeActorKey(actorInput);
|
||||
if (actorKey) {
|
||||
state.queues.delete(actorKey);
|
||||
@@ -1237,9 +1224,6 @@ function resetProgress(actorInput) {
|
||||
}
|
||||
|
||||
function getQueuedPointers(actorInput) {
|
||||
if (!isFeatureEnabled()) {
|
||||
return [];
|
||||
}
|
||||
const actorKey = normalizeActorKey(actorInput);
|
||||
if (!actorKey) {
|
||||
return [];
|
||||
@@ -1251,9 +1235,6 @@ function getQueuedPointers(actorInput) {
|
||||
}
|
||||
|
||||
function getAllQueues() {
|
||||
if (!isFeatureEnabled()) {
|
||||
return {};
|
||||
}
|
||||
if (!state.restored) {
|
||||
restoreQueueState();
|
||||
}
|
||||
@@ -1280,6 +1261,7 @@ function getSettings() {
|
||||
|
||||
const watchHistoryService = {
|
||||
isEnabled: isFeatureEnabled,
|
||||
supportsLocalHistory: () => true,
|
||||
publishView,
|
||||
snapshot,
|
||||
loadLatest,
|
||||
|
||||
@@ -980,12 +980,78 @@ async function testWatchHistoryServiceIntegration() {
|
||||
}
|
||||
}
|
||||
|
||||
async function testWatchHistoryLocalFallbackWhenDisabled() {
|
||||
console.log("Running watch history local fallback test...");
|
||||
|
||||
const actor = "local-fallback-actor";
|
||||
const originalRecordView = nostrClient.recordVideoView;
|
||||
const originalPub = nostrClient.pubkey;
|
||||
|
||||
try {
|
||||
setWatchHistoryV2Enabled(false);
|
||||
localStorage.clear();
|
||||
watchHistoryService.resetProgress();
|
||||
nostrClient.pubkey = "";
|
||||
nostrClient.recordVideoView = async (_pointer, options = {}) => ({
|
||||
ok: true,
|
||||
event: {
|
||||
id: "local-view",
|
||||
pubkey: actor,
|
||||
created_at: options.created_at || 1_700_500_000,
|
||||
},
|
||||
});
|
||||
|
||||
const supported =
|
||||
typeof watchHistoryService.supportsLocalHistory === "function"
|
||||
? watchHistoryService.supportsLocalHistory()
|
||||
: true;
|
||||
assert.equal(
|
||||
supported,
|
||||
true,
|
||||
"service should report local history support while sync disabled",
|
||||
);
|
||||
|
||||
const createdAt = 1_700_500_000;
|
||||
await watchHistoryService.publishView(
|
||||
{ type: "e", value: "local-pointer" },
|
||||
createdAt,
|
||||
{ actor },
|
||||
);
|
||||
|
||||
const queued = watchHistoryService.getQueuedPointers(actor);
|
||||
assert.equal(
|
||||
queued.length,
|
||||
1,
|
||||
"local queue should retain pointer when sync is disabled",
|
||||
);
|
||||
|
||||
const latest = await watchHistoryService.loadLatest(actor);
|
||||
assert.equal(
|
||||
latest.length,
|
||||
1,
|
||||
"loadLatest should surface session queue entries when sync disabled",
|
||||
);
|
||||
assert.equal(latest[0]?.value, "local-pointer");
|
||||
assert.equal(latest[0]?.type, "e");
|
||||
assert(
|
||||
Number.isFinite(latest[0]?.watchedAt) && latest[0].watchedAt > 0,
|
||||
"local fallback entries should carry watchedAt timestamps",
|
||||
);
|
||||
} finally {
|
||||
setWatchHistoryV2Enabled(true);
|
||||
watchHistoryService.resetProgress();
|
||||
nostrClient.recordVideoView = originalRecordView;
|
||||
nostrClient.pubkey = originalPub;
|
||||
}
|
||||
}
|
||||
|
||||
await testPublishSnapshotCanonicalizationAndChunking();
|
||||
await testPublishSnapshotUsesExtensionCrypto();
|
||||
await testPublishSnapshotFailureRetry();
|
||||
await testWatchHistoryPartialRelayRetry();
|
||||
await testResolveWatchHistoryBatchingWindow();
|
||||
await testWatchHistoryServiceIntegration();
|
||||
await testWatchHistoryLocalFallbackWhenDisabled();
|
||||
|
||||
console.log("watch-history.test.mjs completed successfully");
|
||||
|
||||
|
||||
Reference in new issue
Block a user