mirror of
https://github.com/PR0M3TH3AN/bitvid.git
synced 2026-10-27 07:52:24 +00:00
Add ensureLoaded helper for subscriptions and align error UX
This commit is contained in:
1 parent
0fb1c36fe1
commit
078c8788b3
3 files changed
+70
-10
No files matched your search
@@ -3448,7 +3448,7 @@ export async function initChannelProfileView() {
|
||||
// 3) Load subscription state when logged in, but always render the toggle UI
|
||||
if (app?.pubkey) {
|
||||
subscriptionsTask = subscriptions
|
||||
.loadSubscriptions(app.pubkey)
|
||||
.ensureLoaded(app.pubkey)
|
||||
.catch((error) => {
|
||||
userLogger.error("Failed to load subscriptions for channel view:", error);
|
||||
})
|
||||
@@ -3833,6 +3833,14 @@ function renderSubscribeButton(channelHex) {
|
||||
renderSubscribeButton(channelHex);
|
||||
} catch (err) {
|
||||
userLogger.error("Failed to update subscription:", err);
|
||||
const permissionErrorCodes = new Set([
|
||||
"extension-permission-denied",
|
||||
"nip04-missing",
|
||||
]);
|
||||
const message = permissionErrorCodes.has(err?.code)
|
||||
? "Your Nostr extension must support NIP-04 to manage private lists."
|
||||
: "Failed to update your subscriptions. Please try again.";
|
||||
currentApp?.showError?.(message);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
+39
-9
@@ -132,6 +132,7 @@ class SubscriptionsManager {
|
||||
this.subscribedPubkeys = new Set();
|
||||
this.subsEventId = null;
|
||||
this.loaded = false;
|
||||
this.loadingPromise = null;
|
||||
this.subscriptionListView = null;
|
||||
this.lastRunOptions = null;
|
||||
this.lastResult = null;
|
||||
@@ -297,6 +298,35 @@ class SubscriptionsManager {
|
||||
}
|
||||
}
|
||||
|
||||
async ensureLoaded(actorHex) {
|
||||
if (this.loaded) {
|
||||
return;
|
||||
}
|
||||
|
||||
const normalizedActor = normalizeHexPubkey(actorHex) || actorHex;
|
||||
if (!normalizedActor) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.loadingPromise) {
|
||||
try {
|
||||
await this.loadingPromise;
|
||||
} catch (error) {
|
||||
throw error;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
const loader = this.loadSubscriptions(normalizedActor);
|
||||
this.loadingPromise = loader;
|
||||
|
||||
try {
|
||||
await loader;
|
||||
} finally {
|
||||
this.loadingPromise = null;
|
||||
}
|
||||
}
|
||||
|
||||
isSubscribed(channelHex) {
|
||||
const normalized = normalizeHexPubkey(channelHex);
|
||||
if (!normalized) {
|
||||
@@ -409,6 +439,7 @@ class SubscriptionsManager {
|
||||
if (!userPubkey) {
|
||||
throw new Error("No user pubkey => cannot addChannel.");
|
||||
}
|
||||
await this.ensureLoaded(userPubkey);
|
||||
if (!normalizedChannel) {
|
||||
devLogger.warn("Attempted to subscribe to invalid pubkey", channelHex);
|
||||
return;
|
||||
@@ -432,6 +463,7 @@ class SubscriptionsManager {
|
||||
if (!userPubkey) {
|
||||
throw new Error("No user pubkey => cannot removeChannel.");
|
||||
}
|
||||
await this.ensureLoaded(userPubkey);
|
||||
if (!normalizedChannel) {
|
||||
devLogger.warn("Attempted to remove invalid pubkey from subscriptions", channelHex);
|
||||
return;
|
||||
@@ -627,15 +659,13 @@ class SubscriptionsManager {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!this.loaded) {
|
||||
try {
|
||||
await this.loadSubscriptions(userPubkey);
|
||||
} catch (error) {
|
||||
userLogger.error(
|
||||
"[SubscriptionsManager] Failed to load subscriptions while rendering feed:",
|
||||
error,
|
||||
);
|
||||
}
|
||||
try {
|
||||
await this.ensureLoaded(userPubkey);
|
||||
} catch (error) {
|
||||
userLogger.error(
|
||||
"[SubscriptionsManager] Failed to load subscriptions while rendering feed:",
|
||||
error,
|
||||
);
|
||||
}
|
||||
|
||||
const channelHexes = this.getSubscribedAuthors();
|
||||
|
||||
@@ -540,6 +540,28 @@ test(
|
||||
},
|
||||
);
|
||||
|
||||
test("ensureLoaded memoizes concurrent loads", async () => {
|
||||
const SubscriptionsManager = subscriptions.constructor;
|
||||
const manager = new SubscriptionsManager();
|
||||
|
||||
let loadCount = 0;
|
||||
manager.loadSubscriptions = async () => {
|
||||
loadCount += 1;
|
||||
await new Promise((resolve) => setTimeout(resolve, 0));
|
||||
manager.loaded = true;
|
||||
};
|
||||
|
||||
const actorHex = "f".repeat(64);
|
||||
|
||||
await Promise.all([
|
||||
manager.ensureLoaded(actorHex),
|
||||
manager.ensureLoaded(actorHex),
|
||||
]);
|
||||
|
||||
assert.equal(loadCount, 1, "loadSubscriptions should only run once");
|
||||
assert.equal(manager.loaded, true, "manager should be marked as loaded");
|
||||
});
|
||||
|
||||
test(
|
||||
"publishSubscriptionList succeeds with direct signer without requesting extension permissions",
|
||||
async () => {
|
||||
|
||||
Reference in new issue
Block a user