mirror of
https://github.com/PR0M3TH3AN/bitvid.git
synced 2026-10-31 18:02:27 +00:00
Add profile switching support for NIP-07 accounts
This commit is contained in:
1 parent
c617fcbfda
commit
ee09b723af
2 files changed
+164
-1
No files matched your search
@@ -3897,6 +3897,16 @@ class bitvidApp {
|
||||
});
|
||||
}
|
||||
|
||||
if (
|
||||
this.profileAddAccountBtn &&
|
||||
this.profileAddAccountBtn.dataset.bound !== "true"
|
||||
) {
|
||||
this.profileAddAccountBtn.dataset.bound = "true";
|
||||
this.profileAddAccountBtn.addEventListener("click", () => {
|
||||
this.handleAddProfile();
|
||||
});
|
||||
}
|
||||
|
||||
Object.entries(this.profileNavButtons).forEach(([name, button]) => {
|
||||
if (!button || button.dataset.navBound === "true") {
|
||||
return;
|
||||
@@ -4440,6 +4450,119 @@ class bitvidApp {
|
||||
});
|
||||
}
|
||||
|
||||
async handleAddProfile() {
|
||||
if (!this.profileAddAccountBtn) {
|
||||
return;
|
||||
}
|
||||
|
||||
const button = this.profileAddAccountBtn;
|
||||
if (button.dataset.loading === "true") {
|
||||
return;
|
||||
}
|
||||
|
||||
const titleEl = button.querySelector(".profile-switcher__addTitle");
|
||||
const hintEl = button.querySelector(".profile-switcher__addHint");
|
||||
const originalTitle = titleEl ? titleEl.textContent : "";
|
||||
const originalHint = hintEl ? hintEl.textContent : "";
|
||||
const originalAriaLabel = button.getAttribute("aria-label");
|
||||
const originalDisabled = button.disabled;
|
||||
|
||||
const setLoadingState = (isLoading) => {
|
||||
button.disabled = isLoading ? true : originalDisabled;
|
||||
button.dataset.loading = isLoading ? "true" : "false";
|
||||
button.setAttribute("aria-busy", isLoading ? "true" : "false");
|
||||
if (isLoading) {
|
||||
button.setAttribute("aria-disabled", "true");
|
||||
} else if (originalDisabled) {
|
||||
button.setAttribute("aria-disabled", "true");
|
||||
} else {
|
||||
button.removeAttribute("aria-disabled");
|
||||
}
|
||||
if (isLoading) {
|
||||
if (titleEl) {
|
||||
titleEl.textContent = "Connecting...";
|
||||
}
|
||||
if (hintEl) {
|
||||
hintEl.textContent = "Check your extension";
|
||||
}
|
||||
button.setAttribute(
|
||||
"aria-label",
|
||||
"Connecting to your Nostr extension"
|
||||
);
|
||||
} else {
|
||||
if (titleEl) {
|
||||
titleEl.textContent = originalTitle;
|
||||
}
|
||||
if (hintEl) {
|
||||
hintEl.textContent = originalHint;
|
||||
}
|
||||
if (originalAriaLabel === null) {
|
||||
button.removeAttribute("aria-label");
|
||||
} else {
|
||||
button.setAttribute("aria-label", originalAriaLabel);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
setLoadingState(true);
|
||||
|
||||
try {
|
||||
const pubkey = await nostrClient.login({
|
||||
allowAccountSelection: true,
|
||||
});
|
||||
|
||||
const normalizedPubkey = this.normalizeHexPubkey(pubkey);
|
||||
if (!normalizedPubkey) {
|
||||
throw new Error(
|
||||
"Received an invalid public key from the Nostr extension."
|
||||
);
|
||||
}
|
||||
|
||||
const alreadySaved = this.savedProfiles.some(
|
||||
(entry) =>
|
||||
this.normalizeHexPubkey(entry.pubkey) === normalizedPubkey
|
||||
);
|
||||
if (alreadySaved) {
|
||||
this.showSuccess("That profile is already saved on this device.");
|
||||
return;
|
||||
}
|
||||
|
||||
const npub = this.safeEncodeNpub(normalizedPubkey) || "";
|
||||
let profileMeta = this.getProfileCacheEntry(normalizedPubkey)?.profile;
|
||||
|
||||
if (!profileMeta) {
|
||||
await this.loadOwnProfile(normalizedPubkey);
|
||||
profileMeta = this.getProfileCacheEntry(normalizedPubkey)?.profile;
|
||||
}
|
||||
|
||||
const name = profileMeta?.name || "";
|
||||
const picture =
|
||||
profileMeta?.picture || "assets/svg/default-profile.svg";
|
||||
|
||||
this.savedProfiles.push({
|
||||
pubkey: normalizedPubkey,
|
||||
npub,
|
||||
name,
|
||||
picture,
|
||||
authType: "nip07",
|
||||
});
|
||||
|
||||
this.persistSavedProfiles({ persistActive: false });
|
||||
this.renderSavedProfiles();
|
||||
|
||||
this.showSuccess("Profile added. Select it when you're ready to switch.");
|
||||
} catch (error) {
|
||||
console.error("Failed to add profile via NIP-07:", error);
|
||||
const message =
|
||||
error && typeof error.message === "string" && error.message.trim()
|
||||
? error.message.trim()
|
||||
: "Couldn't add that profile. Please try again.";
|
||||
this.showError(message);
|
||||
} finally {
|
||||
setLoadingState(false);
|
||||
}
|
||||
}
|
||||
|
||||
async handleAddBlockedCreator() {
|
||||
if (!this.profileBlockedInput) {
|
||||
return;
|
||||
|
||||
+41
-1
@@ -593,7 +593,7 @@ class NostrClient {
|
||||
/**
|
||||
* Attempt login with a Nostr extension
|
||||
*/
|
||||
async login() {
|
||||
async login(options = {}) {
|
||||
try {
|
||||
const extension = window.nostr;
|
||||
if (!extension) {
|
||||
@@ -603,6 +603,13 @@ class NostrClient {
|
||||
);
|
||||
}
|
||||
|
||||
const { allowAccountSelection = false, expectPubkey } =
|
||||
typeof options === "object" && options !== null ? options : {};
|
||||
const normalizedExpectedPubkey =
|
||||
typeof expectPubkey === "string" && expectPubkey.trim()
|
||||
? expectPubkey.trim().toLowerCase()
|
||||
: null;
|
||||
|
||||
if (typeof extension.getPublicKey !== "function") {
|
||||
throw new Error(
|
||||
"This NIP-07 extension is missing getPublicKey support. Please update the extension."
|
||||
@@ -624,6 +631,30 @@ class NostrClient {
|
||||
}
|
||||
}
|
||||
|
||||
if (allowAccountSelection && typeof extension.selectAccounts === "function") {
|
||||
try {
|
||||
const selection = await extension.selectAccounts(
|
||||
expectPubkey ? [expectPubkey] : undefined
|
||||
);
|
||||
|
||||
const didCancelSelection =
|
||||
selection === undefined ||
|
||||
selection === null ||
|
||||
selection === false ||
|
||||
(Array.isArray(selection) && selection.length === 0);
|
||||
|
||||
if (didCancelSelection) {
|
||||
throw new Error("Account selection was cancelled.");
|
||||
}
|
||||
} catch (selectionErr) {
|
||||
const message =
|
||||
selectionErr && typeof selectionErr.message === "string"
|
||||
? selectionErr.message
|
||||
: "Account selection was cancelled.";
|
||||
throw new Error(message);
|
||||
}
|
||||
}
|
||||
|
||||
let timeoutId;
|
||||
const pubkey = await Promise.race([
|
||||
extension.getPublicKey(),
|
||||
@@ -646,6 +677,15 @@ class NostrClient {
|
||||
"The NIP-07 extension did not return a public key. Please try again."
|
||||
);
|
||||
}
|
||||
|
||||
if (
|
||||
normalizedExpectedPubkey &&
|
||||
pubkey.toLowerCase() !== normalizedExpectedPubkey
|
||||
) {
|
||||
throw new Error(
|
||||
"The selected account doesn't match the expected profile. Please try again."
|
||||
);
|
||||
}
|
||||
const npub = window.NostrTools.nip19.npubEncode(pubkey);
|
||||
|
||||
if (isDevMode) {
|
||||
|
||||
Reference in new issue
Block a user