mirror of
https://github.com/PR0M3TH3AN/bitvid.git
synced 2026-10-29 08:52:25 +00:00
Fix watch history pointer classification
This commit is contained in:
1 parent
e127c6f58e
commit
5e81bc9aef
2 files changed
+108
-6
No files matched your search
+33
-6
@@ -2579,19 +2579,46 @@ class NostrClient {
|
||||
? Math.max(1, normalizedBatchSize)
|
||||
: 1;
|
||||
|
||||
const classifyWatchHistoryPointer = (pointer) => {
|
||||
const classifyWatchHistoryPointer = (pointer, ownerPubkey) => {
|
||||
if (!pointer || pointer.type !== "a") {
|
||||
return "none";
|
||||
}
|
||||
const [kindStr, pubkey, identifier] = pointer.value.split(":");
|
||||
const value =
|
||||
typeof pointer.value === "string" ? pointer.value.trim() : "";
|
||||
if (!value) {
|
||||
return "none";
|
||||
}
|
||||
const parts = value.split(":");
|
||||
if (parts.length < 3) {
|
||||
return "none";
|
||||
}
|
||||
const [kindStr, pubkeyRaw, ...identifierParts] = parts;
|
||||
const kind = Number.parseInt(kindStr, 10);
|
||||
if (!Number.isFinite(kind) || kind !== WATCH_HISTORY_KIND) {
|
||||
return "none";
|
||||
}
|
||||
if (identifier === WATCH_HISTORY_LIST_IDENTIFIER) {
|
||||
const identifier = identifierParts.join(":");
|
||||
const normalizedIdentifier =
|
||||
typeof identifier === "string" ? identifier.trim() : "";
|
||||
if (!normalizedIdentifier) {
|
||||
return "none";
|
||||
}
|
||||
const normalizedIdentifierLower = normalizedIdentifier.toLowerCase();
|
||||
if (normalizedIdentifierLower === WATCH_HISTORY_LIST_IDENTIFIER) {
|
||||
return "head";
|
||||
}
|
||||
if (typeof identifier === "string" && identifier) {
|
||||
if (!normalizedIdentifierLower.startsWith("watch-history:")) {
|
||||
return "none";
|
||||
}
|
||||
const normalizedOwner =
|
||||
typeof ownerPubkey === "string" && ownerPubkey.trim()
|
||||
? ownerPubkey.trim().toLowerCase()
|
||||
: "";
|
||||
const normalizedPubkey =
|
||||
typeof pubkeyRaw === "string" && pubkeyRaw.trim()
|
||||
? pubkeyRaw.trim().toLowerCase()
|
||||
: "";
|
||||
if (!normalizedOwner || !normalizedPubkey || normalizedOwner === normalizedPubkey) {
|
||||
return "chunk";
|
||||
}
|
||||
return "none";
|
||||
@@ -2628,7 +2655,7 @@ class NostrClient {
|
||||
if (!pointer) {
|
||||
continue;
|
||||
}
|
||||
const pointerType = classifyWatchHistoryPointer(pointer);
|
||||
const pointerType = classifyWatchHistoryPointer(pointer, actor);
|
||||
if (pointerType === "head") {
|
||||
addPointerToMap(pointer, headPointerMap);
|
||||
continue;
|
||||
@@ -2776,7 +2803,7 @@ class NostrClient {
|
||||
if (!key) {
|
||||
continue;
|
||||
}
|
||||
const pointerType = classifyWatchHistoryPointer(pointer);
|
||||
const pointerType = classifyWatchHistoryPointer(pointer, actor);
|
||||
const event = pointerMatches.get(key);
|
||||
if (pointerType === "chunk" || pointerType === "head") {
|
||||
if (event) {
|
||||
|
||||
@@ -398,6 +398,81 @@ try {
|
||||
|
||||
localStorage.clear();
|
||||
|
||||
const VIDEO_POINTER_AUTHOR = `${ACTOR}-video-author`;
|
||||
const VIDEO_POINTER_IDENTIFIER = "pointer-video-identifier";
|
||||
const videoPointer = {
|
||||
type: "a",
|
||||
value: `${WATCH_HISTORY_KIND}:${VIDEO_POINTER_AUTHOR}:${VIDEO_POINTER_IDENTIFIER}`,
|
||||
relay: null,
|
||||
};
|
||||
|
||||
const pointerClient = createDecryptClient(ACTOR);
|
||||
const pointerEntry = pointerClient.createWatchHistoryEntry(
|
||||
null,
|
||||
[videoPointer],
|
||||
Date.now()
|
||||
);
|
||||
pointerClient.watchHistoryCache.set(ACTOR, pointerEntry);
|
||||
pointerClient.fetchWatchHistory = async () => {};
|
||||
|
||||
const observedResolveFilters = [];
|
||||
const videoEvent = {
|
||||
id: "video-pointer-event",
|
||||
kind: WATCH_HISTORY_KIND,
|
||||
pubkey: VIDEO_POINTER_AUTHOR,
|
||||
created_at: 1_700_555_000,
|
||||
tags: [["d", VIDEO_POINTER_IDENTIFIER]],
|
||||
content: JSON.stringify({
|
||||
version: 3,
|
||||
title: "Pointer Video",
|
||||
url: "https://cdn.example.com/video.mp4",
|
||||
}),
|
||||
};
|
||||
|
||||
pointerClient.pool = {
|
||||
list: async (_relays, filters) => {
|
||||
observedResolveFilters.push(filters);
|
||||
return [videoEvent];
|
||||
},
|
||||
};
|
||||
|
||||
const resolvedFromPointer = await pointerClient.resolveWatchHistory(1);
|
||||
|
||||
assert.equal(
|
||||
resolvedFromPointer.length,
|
||||
1,
|
||||
"resolveWatchHistory should return results for 'a' style video pointers"
|
||||
);
|
||||
assert.equal(
|
||||
resolvedFromPointer[0].id,
|
||||
videoEvent.id,
|
||||
"resolved video should match the pointer event id"
|
||||
);
|
||||
assert.equal(
|
||||
resolvedFromPointer[0].title,
|
||||
"Pointer Video",
|
||||
"resolved video should parse title from the event payload"
|
||||
);
|
||||
|
||||
const pointerKey = `a:${videoPointer.value.trim().toLowerCase()}`;
|
||||
const cachedEntry = pointerClient.watchHistoryCache.get(ACTOR);
|
||||
assert(cachedEntry.resolved.has(pointerKey), "resolved cache should retain the video");
|
||||
assert.equal(
|
||||
cachedEntry.resolved.get(pointerKey)?.id,
|
||||
videoEvent.id,
|
||||
"resolved cache should store the converted video result"
|
||||
);
|
||||
|
||||
assert(
|
||||
observedResolveFilters.some((filters) =>
|
||||
filters.some((filter) =>
|
||||
Array.isArray(filter?.["#d"]) &&
|
||||
filter["#d"].includes(VIDEO_POINTER_IDENTIFIER)
|
||||
)
|
||||
),
|
||||
"resolveWatchHistory should request the video identifier instead of treating it as a chunk"
|
||||
);
|
||||
|
||||
const originalDateNow = Date.now;
|
||||
try {
|
||||
const baseTime = 1_700_000_000_000;
|
||||
|
||||
Reference in new issue
Block a user