mirror of
https://github.com/PR0M3TH3AN/bitvid.git
synced 2026-10-27 07:52:24 +00:00
Merge pull request #1384 from PR0M3TH3AN/codex/extend-profile-modal-logic-for-actions
Profile modal: add DM recipient context, relay hints & actions
This commit is contained in:
5 files changed
+452
-12
No files matched your search
@@ -1031,9 +1031,9 @@
|
||||
</div>
|
||||
<div class="flex flex-wrap items-center justify-between gap-3 border-t border-border/60 pt-3">
|
||||
<div class="space-y-1">
|
||||
<h4 class="text-xs font-semibold text-text">Preferred DM relay</h4>
|
||||
<h4 class="text-xs font-semibold text-text">Recipient DM relays</h4>
|
||||
<p class="text-xs text-muted">
|
||||
Select a relay to prioritize encrypted message delivery.
|
||||
Use the relays advertised in kind 10050 to prioritize encrypted delivery.
|
||||
</p>
|
||||
</div>
|
||||
<button
|
||||
@@ -1042,7 +1042,7 @@
|
||||
class="btn-ghost focus-ring inline-flex items-center gap-2"
|
||||
data-size="sm"
|
||||
>
|
||||
Manage relays
|
||||
Use DM relays
|
||||
</button>
|
||||
</div>
|
||||
<div class="flex flex-wrap items-center justify-between gap-3 border-t border-border/60 pt-3">
|
||||
|
||||
@@ -68,6 +68,7 @@ import { devLogger, userLogger } from "./utils/logger.js";
|
||||
import createPopover from "./ui/overlay/popoverEngine.js";
|
||||
import { createVideoSettingsMenuPanel } from "./ui/components/videoMenuRenderers.js";
|
||||
import moderationService from "./services/moderationService.js";
|
||||
import { sanitizeRelayList } from "./nostr/nip46Client.js";
|
||||
import {
|
||||
initViewCounter,
|
||||
subscribeToVideoViewCount,
|
||||
@@ -220,6 +221,8 @@ class Application {
|
||||
this.modalManager = modalManager;
|
||||
|
||||
this.modalCreatorProfileRequestToken = null;
|
||||
this.dmRecipientPubkey = null;
|
||||
this.dmRelayHints = new Map();
|
||||
|
||||
this.commentController = null;
|
||||
this.initializeCommentController();
|
||||
@@ -3058,6 +3061,171 @@ class Application {
|
||||
});
|
||||
}
|
||||
|
||||
getDmRecipientPubkey() {
|
||||
return this.dmRecipientPubkey;
|
||||
}
|
||||
|
||||
setDmRecipientPubkey(pubkey) {
|
||||
const normalized = this.normalizeHexPubkey(pubkey);
|
||||
this.dmRecipientPubkey = normalized || null;
|
||||
return this.dmRecipientPubkey;
|
||||
}
|
||||
|
||||
getDmRelayHints(pubkey) {
|
||||
const normalized = this.normalizeHexPubkey(pubkey);
|
||||
if (!normalized || !(this.dmRelayHints instanceof Map)) {
|
||||
return [];
|
||||
}
|
||||
const hints = this.dmRelayHints.get(normalized);
|
||||
return Array.isArray(hints) ? hints.slice() : [];
|
||||
}
|
||||
|
||||
setDmRelayHints(pubkey, hints = []) {
|
||||
const normalized = this.normalizeHexPubkey(pubkey);
|
||||
if (!normalized) {
|
||||
return [];
|
||||
}
|
||||
if (!(this.dmRelayHints instanceof Map)) {
|
||||
this.dmRelayHints = new Map();
|
||||
}
|
||||
const stored = sanitizeRelayList(Array.isArray(hints) ? hints : []);
|
||||
this.dmRelayHints.set(normalized, stored);
|
||||
return stored.slice();
|
||||
}
|
||||
|
||||
async fetchDmRelayHints(pubkey) {
|
||||
const normalized = this.normalizeHexPubkey(pubkey);
|
||||
if (!normalized) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const cached = this.getDmRelayHints(normalized);
|
||||
if (cached.length) {
|
||||
return cached;
|
||||
}
|
||||
|
||||
const relayCandidates =
|
||||
Array.isArray(nostrClient?.readRelays) && nostrClient.readRelays.length
|
||||
? nostrClient.readRelays
|
||||
: Array.isArray(nostrClient?.relays)
|
||||
? nostrClient.relays
|
||||
: [];
|
||||
|
||||
const relayList = sanitizeRelayList(relayCandidates);
|
||||
if (!relayList.length) {
|
||||
return [];
|
||||
}
|
||||
|
||||
if (!nostrClient?.pool || typeof nostrClient.pool.list !== "function") {
|
||||
return [];
|
||||
}
|
||||
|
||||
try {
|
||||
const events = await nostrClient.pool.list(relayList, [
|
||||
{ kinds: [10050], authors: [normalized], limit: 1 },
|
||||
]);
|
||||
const sorted = Array.isArray(events)
|
||||
? events
|
||||
.filter((event) => event && event.pubkey === normalized)
|
||||
.sort((a, b) => (b?.created_at || 0) - (a?.created_at || 0))
|
||||
: [];
|
||||
if (!sorted.length) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const tags = Array.isArray(sorted[0]?.tags) ? sorted[0].tags : [];
|
||||
const relayHints = sanitizeRelayList(
|
||||
tags
|
||||
.filter((tag) => Array.isArray(tag) && tag[0] === "relay")
|
||||
.map((tag) => (typeof tag[1] === "string" ? tag[1].trim() : "")),
|
||||
);
|
||||
|
||||
this.setDmRelayHints(normalized, relayHints);
|
||||
return relayHints;
|
||||
} catch (error) {
|
||||
devLogger.warn(
|
||||
"[Application] Failed to load DM relay hints:",
|
||||
error,
|
||||
);
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
openDirectMessageComposer({ recipientPubkey, source = "" } = {}) {
|
||||
const normalized = this.normalizeHexPubkey(recipientPubkey);
|
||||
if (!normalized) {
|
||||
this.showError("Please select a valid message recipient.");
|
||||
return false;
|
||||
}
|
||||
|
||||
this.setDmRecipientPubkey(normalized);
|
||||
|
||||
if (this.profileController) {
|
||||
try {
|
||||
if (typeof this.profileController.setDirectMessageRecipient === "function") {
|
||||
this.profileController.setDirectMessageRecipient(normalized, {
|
||||
reason: source || "external",
|
||||
});
|
||||
}
|
||||
if (typeof this.profileController.show === "function") {
|
||||
this.profileController.show("messages");
|
||||
}
|
||||
if (typeof this.profileController.focusMessageComposer === "function") {
|
||||
this.profileController.focusMessageComposer();
|
||||
}
|
||||
} catch (error) {
|
||||
devLogger.warn(
|
||||
"[Application] Failed to open DM composer:",
|
||||
error,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
handleProfileSendDmRequest({ recipient } = {}) {
|
||||
const recipientPubkey =
|
||||
typeof recipient?.pubkey === "string"
|
||||
? recipient.pubkey
|
||||
: null;
|
||||
|
||||
return this.openDirectMessageComposer({
|
||||
recipientPubkey,
|
||||
source: "profile-modal",
|
||||
});
|
||||
}
|
||||
|
||||
handleProfileUseDmRelays({ recipient, controller } = {}) {
|
||||
const relayHints = Array.isArray(recipient?.relayHints)
|
||||
? recipient.relayHints
|
||||
: [];
|
||||
if (!relayHints.length) {
|
||||
this.showError("No DM relays found for this recipient.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (recipient?.pubkey) {
|
||||
this.setDmRelayHints(recipient.pubkey, relayHints);
|
||||
}
|
||||
|
||||
this.showSuccess("Recipient DM relays ready for use.");
|
||||
if (controller?.focusMessageComposer) {
|
||||
controller.focusMessageComposer();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
handleProfilePrivacyToggle({ enabled, controller } = {}) {
|
||||
if (enabled) {
|
||||
this.showStatus("Privacy mode is coming in Phase 3.");
|
||||
if (controller?.setPrivacyToggleState) {
|
||||
controller.setPrivacyToggleState(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
updateProfileInDOM(pubkey, profile) {
|
||||
if (this.profileIdentityController) {
|
||||
this.profileIdentityController.updateProfileIdentity({
|
||||
|
||||
@@ -3357,6 +3357,14 @@ function setupChannelMessageControls() {
|
||||
return;
|
||||
}
|
||||
|
||||
if (typeof app?.openDirectMessageComposer === "function") {
|
||||
app.openDirectMessageComposer({
|
||||
recipientPubkey: resolvedHex,
|
||||
source: "channel-profile",
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
const controller = app?.profileController;
|
||||
if (!controller) {
|
||||
app?.showError?.("Messages are unavailable right now.");
|
||||
|
||||
@@ -432,6 +432,7 @@ export default class ApplicationBootstrap {
|
||||
formatShortNpub: (value) => formatShortNpub(value),
|
||||
getProfileCacheEntry: (pubkey) => app.getProfileCacheEntry(pubkey),
|
||||
batchFetchProfiles: (authorSet) => app.batchFetchProfiles(authorSet),
|
||||
fetchDmRelayHints: (pubkey) => app.fetchDmRelayHints(pubkey),
|
||||
switchProfile: (pubkey) => app.authService.switchProfile(pubkey),
|
||||
removeSavedProfile: (pubkey) =>
|
||||
app.authService.removeSavedProfile(pubkey),
|
||||
@@ -499,6 +500,10 @@ export default class ApplicationBootstrap {
|
||||
setStoredActiveProfilePubkey(normalized, options);
|
||||
return getActiveProfilePubkey();
|
||||
},
|
||||
getDmRecipient: () => app.getDmRecipientPubkey(),
|
||||
setDmRecipient: (pubkey) => app.setDmRecipientPubkey(pubkey),
|
||||
getDmRelayHints: (pubkey) => app.getDmRelayHints(pubkey),
|
||||
setDmRelayHints: (pubkey, hints) => app.setDmRelayHints(pubkey, hints),
|
||||
};
|
||||
|
||||
const profileModalCallbacks = {
|
||||
@@ -532,6 +537,10 @@ export default class ApplicationBootstrap {
|
||||
app.handleProfileHistoryEvent(payload),
|
||||
onModerationSettingsChange: (payload) =>
|
||||
app.handleModerationSettingsChange(payload),
|
||||
onSendDm: (payload) => app.handleProfileSendDmRequest(payload),
|
||||
onOpenRelays: (payload) => app.handleProfileUseDmRelays(payload),
|
||||
onTogglePrivacy: (payload) =>
|
||||
app.handleProfilePrivacyToggle(payload),
|
||||
};
|
||||
|
||||
app.profileController = new ProfileModalController({
|
||||
|
||||
@@ -276,6 +276,13 @@ const SERVICE_CONTRACT = [
|
||||
"Fetches and caches profile metadata for a set of pubkeys so the modal can hydrate avatars/names in bulk.",
|
||||
fallback: () => async () => [],
|
||||
},
|
||||
{
|
||||
key: "fetchDmRelayHints",
|
||||
type: "function",
|
||||
description:
|
||||
"Fetches DM relay hints (kind 10050) for a given pubkey.",
|
||||
fallback: () => async () => [],
|
||||
},
|
||||
{
|
||||
key: "switchProfile",
|
||||
type: "function",
|
||||
@@ -695,6 +702,62 @@ const STATE_CONTRACT = [
|
||||
return internal.walletBusy;
|
||||
},
|
||||
},
|
||||
{
|
||||
key: "getDmRecipient",
|
||||
type: "function",
|
||||
description:
|
||||
"Returns the currently selected direct message recipient pubkey.",
|
||||
fallback: (internal) => () => internal.dmRecipient,
|
||||
},
|
||||
{
|
||||
key: "setDmRecipient",
|
||||
type: "function",
|
||||
description:
|
||||
"Updates the selected direct message recipient pubkey and returns the stored value.",
|
||||
fallback: (internal) => (pubkey) => {
|
||||
if (typeof pubkey === "string") {
|
||||
const trimmed = pubkey.trim();
|
||||
internal.dmRecipient = trimmed || null;
|
||||
} else {
|
||||
internal.dmRecipient = null;
|
||||
}
|
||||
return internal.dmRecipient;
|
||||
},
|
||||
},
|
||||
{
|
||||
key: "getDmRelayHints",
|
||||
type: "function",
|
||||
description:
|
||||
"Returns the cached DM relay hints for a given pubkey.",
|
||||
fallback: (internal) => (pubkey) => {
|
||||
const normalized =
|
||||
typeof pubkey === "string" ? pubkey.trim().toLowerCase() : "";
|
||||
if (!normalized || !(internal.dmRelayHints instanceof Map)) {
|
||||
return [];
|
||||
}
|
||||
const hints = internal.dmRelayHints.get(normalized);
|
||||
return Array.isArray(hints) ? hints.slice() : [];
|
||||
},
|
||||
},
|
||||
{
|
||||
key: "setDmRelayHints",
|
||||
type: "function",
|
||||
description:
|
||||
"Stores DM relay hints for a given pubkey and returns the stored list.",
|
||||
fallback: (internal) => (pubkey, hints = []) => {
|
||||
if (!(internal.dmRelayHints instanceof Map)) {
|
||||
internal.dmRelayHints = new Map();
|
||||
}
|
||||
const normalized =
|
||||
typeof pubkey === "string" ? pubkey.trim().toLowerCase() : "";
|
||||
if (!normalized) {
|
||||
return [];
|
||||
}
|
||||
const stored = Array.isArray(hints) ? hints.slice() : [];
|
||||
internal.dmRelayHints.set(normalized, stored);
|
||||
return stored;
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
function buildServicesContract(services = {}, internalState) {
|
||||
@@ -883,6 +946,8 @@ export class ProfileModalController {
|
||||
walletBusy: false,
|
||||
walletSettings: createInternalDefaultNwcSettings(),
|
||||
moderationSettings: createInternalDefaultModerationSettings(),
|
||||
dmRecipient: null,
|
||||
dmRelayHints: new Map(),
|
||||
};
|
||||
|
||||
this.services = buildServicesContract(services, this.internalState);
|
||||
@@ -1769,6 +1834,148 @@ export class ProfileModalController {
|
||||
return null;
|
||||
}
|
||||
|
||||
resolveActiveDmRecipient() {
|
||||
const candidate =
|
||||
typeof this.state.getDmRecipient === "function"
|
||||
? this.state.getDmRecipient()
|
||||
: null;
|
||||
const normalized = this.normalizeHexPubkey(candidate);
|
||||
if (normalized) {
|
||||
return normalized;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
buildDmRecipientContext(pubkey) {
|
||||
const normalized = this.normalizeHexPubkey(pubkey);
|
||||
if (!normalized) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const npub =
|
||||
typeof this.safeEncodeNpub === "function"
|
||||
? this.safeEncodeNpub(normalized)
|
||||
: null;
|
||||
|
||||
const cacheEntry =
|
||||
typeof this.services.getProfileCacheEntry === "function"
|
||||
? this.services.getProfileCacheEntry(normalized)
|
||||
: null;
|
||||
const profile = cacheEntry?.profile || null;
|
||||
|
||||
const displayName =
|
||||
profile?.display_name?.trim?.() ||
|
||||
profile?.name?.trim?.() ||
|
||||
(typeof this.formatShortNpub === "function"
|
||||
? this.formatShortNpub(npub)
|
||||
: npub) ||
|
||||
npub ||
|
||||
"Unknown profile";
|
||||
|
||||
const relayHints =
|
||||
typeof this.state.getDmRelayHints === "function"
|
||||
? this.state.getDmRelayHints(normalized)
|
||||
: [];
|
||||
|
||||
return {
|
||||
pubkey: normalized,
|
||||
npub,
|
||||
profile,
|
||||
displayName,
|
||||
relayHints: Array.isArray(relayHints) ? relayHints.slice() : [],
|
||||
};
|
||||
}
|
||||
|
||||
async ensureDmRecipientData(pubkey) {
|
||||
const normalized = this.normalizeHexPubkey(pubkey);
|
||||
if (!normalized) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (
|
||||
typeof this.services.batchFetchProfiles === "function"
|
||||
) {
|
||||
try {
|
||||
await this.services.batchFetchProfiles([normalized]);
|
||||
} catch (error) {
|
||||
devLogger.warn(
|
||||
"[profileModal] Failed to fetch DM recipient metadata:",
|
||||
error,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (typeof this.services.fetchDmRelayHints === "function") {
|
||||
try {
|
||||
const hints = await this.services.fetchDmRelayHints(normalized);
|
||||
if (typeof this.state.setDmRelayHints === "function") {
|
||||
this.state.setDmRelayHints(normalized, hints);
|
||||
}
|
||||
} catch (error) {
|
||||
devLogger.warn(
|
||||
"[profileModal] Failed to fetch DM relay hints:",
|
||||
error,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return this.buildDmRecipientContext(normalized);
|
||||
}
|
||||
|
||||
setDirectMessageRecipient(pubkey, { reason = "manual" } = {}) {
|
||||
const normalized = this.normalizeHexPubkey(pubkey);
|
||||
const nextRecipient = normalized || null;
|
||||
|
||||
if (typeof this.state.setDmRecipient === "function") {
|
||||
this.state.setDmRecipient(nextRecipient);
|
||||
}
|
||||
|
||||
this.updateMessageThreadSelection(nextRecipient);
|
||||
|
||||
if (nextRecipient) {
|
||||
void this.ensureDmRecipientData(nextRecipient);
|
||||
this.setMessagesAnnouncement("Ready to message this recipient.");
|
||||
} else if (reason === "clear") {
|
||||
this.setMessagesAnnouncement("Message recipient cleared.");
|
||||
}
|
||||
|
||||
return nextRecipient;
|
||||
}
|
||||
|
||||
updateMessageThreadSelection(activeRecipient) {
|
||||
if (!(this.profileMessagesList instanceof HTMLElement)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const normalized = this.normalizeHexPubkey(activeRecipient);
|
||||
const items = Array.from(
|
||||
this.profileMessagesList.querySelectorAll("[data-remote-pubkey]"),
|
||||
);
|
||||
|
||||
items.forEach((item) => {
|
||||
if (!(item instanceof HTMLElement)) {
|
||||
return;
|
||||
}
|
||||
const remote = this.normalizeHexPubkey(item.dataset.remotePubkey);
|
||||
const isActive = normalized && remote === normalized;
|
||||
item.dataset.state = isActive ? "active" : "inactive";
|
||||
});
|
||||
}
|
||||
|
||||
focusMessageComposer() {
|
||||
const input = this.profileMessageInput;
|
||||
if (input instanceof HTMLTextAreaElement) {
|
||||
input.focus();
|
||||
input.select();
|
||||
}
|
||||
}
|
||||
|
||||
setPrivacyToggleState(enabled) {
|
||||
if (this.profileMessagesPrivacyToggle instanceof HTMLInputElement) {
|
||||
this.profileMessagesPrivacyToggle.checked = Boolean(enabled);
|
||||
}
|
||||
}
|
||||
|
||||
ensureDirectMessageSubscription(actorPubkey = null) {
|
||||
if (
|
||||
!this.nostrService ||
|
||||
@@ -1845,6 +2052,8 @@ export class ProfileModalController {
|
||||
? this.normalizeHexPubkey(actorPubkey)
|
||||
: this.resolveActiveDmActor();
|
||||
|
||||
this.setDirectMessageRecipient(null, { reason: "clear" });
|
||||
|
||||
if (
|
||||
this.directMessagesSubscription &&
|
||||
this.directMessagesSubscription.actor &&
|
||||
@@ -2057,27 +2266,49 @@ export class ProfileModalController {
|
||||
}
|
||||
}
|
||||
|
||||
handleSendDmRequest() {
|
||||
async handleSendDmRequest() {
|
||||
const recipient = this.resolveActiveDmRecipient();
|
||||
if (!recipient) {
|
||||
this.showError("Please select a message recipient.");
|
||||
return;
|
||||
}
|
||||
|
||||
const context = await this.ensureDmRecipientData(recipient);
|
||||
this.focusMessageComposer();
|
||||
|
||||
const callback = this.callbacks.onSendDm;
|
||||
if (callback && callback !== noop) {
|
||||
callback({
|
||||
actorPubkey: this.resolveActiveDmActor(),
|
||||
recipient: context,
|
||||
controller: this,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
handleOpenDmRelaysRequest() {
|
||||
async handleOpenDmRelaysRequest() {
|
||||
const recipient = this.resolveActiveDmRecipient();
|
||||
if (!recipient) {
|
||||
this.showError("Please select a message recipient.");
|
||||
return;
|
||||
}
|
||||
|
||||
const context = await this.ensureDmRecipientData(recipient);
|
||||
|
||||
const callback = this.callbacks.onOpenRelays;
|
||||
if (callback && callback !== noop) {
|
||||
callback({ controller: this });
|
||||
callback({ controller: this, recipient: context });
|
||||
}
|
||||
}
|
||||
|
||||
handlePrivacyToggle(enabled) {
|
||||
const callback = this.callbacks.onTogglePrivacy;
|
||||
if (callback && callback !== noop) {
|
||||
callback({ controller: this, enabled: Boolean(enabled) });
|
||||
callback({
|
||||
controller: this,
|
||||
enabled: Boolean(enabled),
|
||||
recipient: this.buildDmRecipientContext(this.resolveActiveDmRecipient()),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2120,10 +2351,11 @@ export class ProfileModalController {
|
||||
return;
|
||||
}
|
||||
|
||||
const targetCandidate =
|
||||
this.resolveActiveDmActor() || this.directMessagesLastActor;
|
||||
const targetHex = this.resolveActiveDmRecipient();
|
||||
const target =
|
||||
typeof targetCandidate === "string" ? targetCandidate.trim() : "";
|
||||
typeof targetHex === "string" && typeof this.safeEncodeNpub === "function"
|
||||
? this.safeEncodeNpub(targetHex)
|
||||
: "";
|
||||
if (!target) {
|
||||
this.showError("Please select a message recipient.");
|
||||
return;
|
||||
@@ -2172,6 +2404,7 @@ export class ProfileModalController {
|
||||
this.directMessagesCache = [];
|
||||
this.directMessagesLastActor = this.resolveActiveDmActor();
|
||||
this.messagesInitialLoadPending = true;
|
||||
this.setDirectMessageRecipient(null, { reason: "clear" });
|
||||
|
||||
if (this.profileMessagesList instanceof HTMLElement) {
|
||||
this.profileMessagesList.innerHTML = "";
|
||||
@@ -2391,6 +2624,7 @@ export class ProfileModalController {
|
||||
const item = document.createElement("li");
|
||||
item.className = "card flex flex-col gap-3 p-4";
|
||||
item.setAttribute("data-remote-pubkey", thread.remoteHex);
|
||||
item.dataset.state = "inactive";
|
||||
|
||||
const header = document.createElement("div");
|
||||
header.className = "flex items-start justify-between gap-3";
|
||||
@@ -2468,6 +2702,13 @@ export class ProfileModalController {
|
||||
|
||||
item.appendChild(meta);
|
||||
|
||||
item.addEventListener("click", () => {
|
||||
this.setDirectMessageRecipient(thread.remoteHex, {
|
||||
reason: "thread-select",
|
||||
});
|
||||
this.focusMessageComposer();
|
||||
});
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
@@ -2524,6 +2765,19 @@ export class ProfileModalController {
|
||||
}
|
||||
}
|
||||
|
||||
const activeRecipient = this.resolveActiveDmRecipient();
|
||||
const hasActiveRecipient =
|
||||
activeRecipient &&
|
||||
threads.some((thread) => thread.remoteHex === activeRecipient);
|
||||
|
||||
if (threads.length && !hasActiveRecipient) {
|
||||
this.setDirectMessageRecipient(threads[0].remoteHex, {
|
||||
reason: "thread-default",
|
||||
});
|
||||
} else if (hasActiveRecipient) {
|
||||
this.updateMessageThreadSelection(activeRecipient);
|
||||
}
|
||||
|
||||
this.profileMessagesList.classList.remove("hidden");
|
||||
this.profileMessagesList.removeAttribute("hidden");
|
||||
}
|
||||
@@ -2697,6 +2951,7 @@ export class ProfileModalController {
|
||||
}
|
||||
|
||||
this.directMessagesCache = [];
|
||||
this.setDirectMessageRecipient(null, { reason: "clear" });
|
||||
if (this.profileMessagesList instanceof HTMLElement) {
|
||||
this.profileMessagesList.innerHTML = "";
|
||||
this.profileMessagesList.classList.add("hidden");
|
||||
@@ -2843,13 +3098,13 @@ export class ProfileModalController {
|
||||
|
||||
if (this.profileMessagesSendDmButton instanceof HTMLElement) {
|
||||
this.profileMessagesSendDmButton.addEventListener("click", () => {
|
||||
this.handleSendDmRequest();
|
||||
void this.handleSendDmRequest();
|
||||
});
|
||||
}
|
||||
|
||||
if (this.profileMessagesOpenRelaysButton instanceof HTMLElement) {
|
||||
this.profileMessagesOpenRelaysButton.addEventListener("click", () => {
|
||||
this.handleOpenDmRelaysRequest();
|
||||
void this.handleOpenDmRelaysRequest();
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user