mirror of
https://github.com/PR0M3TH3AN/bitvid.git
synced 2026-10-27 07:52:24 +00:00
Merge pull request #1403 from PR0M3TH3AN/codex/replace-legacy-markup-in-profile-modal
Mount DM AppShell into Profile Messages pane
This commit is contained in:
2 files changed
+52
-289
No files matched your search
@@ -1067,295 +1067,7 @@
|
||||
role="tabpanel"
|
||||
aria-labelledby="profileNavMessages"
|
||||
>
|
||||
<p class="text-sm text-muted">
|
||||
View encrypted conversations sent with NIP-04 or NIP-44. bitvid keeps message data on this device only.
|
||||
</p>
|
||||
<div class="card space-y-4 p-4">
|
||||
<div class="flex flex-wrap items-start justify-between gap-3">
|
||||
<div class="space-y-1">
|
||||
<h3 class="text-sm font-semibold text-text">Direct message actions</h3>
|
||||
<p class="text-xs text-muted">
|
||||
Start a new DM or jump to relay preferences before you send.
|
||||
</p>
|
||||
</div>
|
||||
<button
|
||||
id="profileMessagesSendDm"
|
||||
type="button"
|
||||
class="btn focus-ring inline-flex items-center gap-2"
|
||||
data-size="sm"
|
||||
>
|
||||
Send DM
|
||||
</button>
|
||||
</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">Recipient DM relays</h4>
|
||||
<p class="text-xs text-muted">
|
||||
Use the relays advertised in kind 10050 to prioritize encrypted delivery.
|
||||
</p>
|
||||
</div>
|
||||
<button
|
||||
id="profileMessagesOpenRelays"
|
||||
type="button"
|
||||
class="btn-ghost focus-ring inline-flex items-center gap-2"
|
||||
data-size="sm"
|
||||
>
|
||||
Use DM relays
|
||||
</button>
|
||||
</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">NIP-17 privacy delivery</h4>
|
||||
<p class="text-xs text-muted">
|
||||
Send gift-wrapped DMs to the relays your recipient advertises in kind 10050.
|
||||
</p>
|
||||
</div>
|
||||
<label
|
||||
for="profileMessagesPrivacyToggle"
|
||||
class="inline-flex items-center gap-2 text-xs font-medium text-muted-strong"
|
||||
title="NIP-17 gift-wraps your DM so relays only see the wrapper and relay hints, not the plaintext. It requires the recipient to publish kind 10050 relay hints."
|
||||
>
|
||||
<input
|
||||
id="profileMessagesPrivacyToggle"
|
||||
type="checkbox"
|
||||
class="checkbox"
|
||||
/>
|
||||
Use NIP-17
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card space-y-4 p-4">
|
||||
<div class="flex flex-wrap items-start justify-between gap-3">
|
||||
<div class="space-y-1">
|
||||
<h3 class="text-sm font-semibold text-text">Your DM relay hints</h3>
|
||||
<p class="text-xs text-muted">
|
||||
Publish kind 10050 so contacts can deliver NIP-17 gift-wrapped DMs to you.
|
||||
</p>
|
||||
</div>
|
||||
<button
|
||||
id="profileMessagesRelayPublish"
|
||||
type="button"
|
||||
class="btn focus-ring inline-flex items-center gap-2"
|
||||
data-size="sm"
|
||||
title="Publishing kind 10050 makes your DM relay list public so others can deliver NIP-17 messages."
|
||||
>
|
||||
Publish relays
|
||||
</button>
|
||||
</div>
|
||||
<label class="flex-1 text-sm text-muted-strong" for="profileMessagesRelayInput">
|
||||
<span class="mb-2 block font-medium">Add a DM relay</span>
|
||||
<div class="flex flex-wrap items-center gap-2">
|
||||
<input
|
||||
id="profileMessagesRelayInput"
|
||||
type="url"
|
||||
inputmode="url"
|
||||
autocomplete="off"
|
||||
class="input flex-1"
|
||||
placeholder="wss://relay.example.com"
|
||||
/>
|
||||
<button
|
||||
id="profileMessagesRelayAdd"
|
||||
type="button"
|
||||
class="btn-ghost focus-ring inline-flex items-center gap-2"
|
||||
data-size="sm"
|
||||
>
|
||||
Add
|
||||
</button>
|
||||
</div>
|
||||
</label>
|
||||
<ul
|
||||
id="profileMessagesRelayList"
|
||||
class="grid-stack"
|
||||
data-orientation="vertical"
|
||||
aria-live="polite"
|
||||
aria-label="Your DM relay hints"
|
||||
></ul>
|
||||
<p
|
||||
id="profileMessagesRelayStatus"
|
||||
class="text-xs text-muted"
|
||||
role="status"
|
||||
aria-live="polite"
|
||||
></p>
|
||||
</div>
|
||||
<div class="card space-y-4 p-4">
|
||||
<div class="space-y-1">
|
||||
<h3 class="text-sm font-semibold text-text">Message activity privacy</h3>
|
||||
<p class="text-xs text-muted">
|
||||
Read receipts and typing indicators are optional signals published to relays.
|
||||
</p>
|
||||
</div>
|
||||
<div class="rounded-lg border border-border/60 bg-bg-muted px-3 py-2 text-xs text-muted">
|
||||
Privacy warning: enabling these signals shares message activity metadata with anyone
|
||||
who can access your relay events.
|
||||
</div>
|
||||
<div class="space-y-2">
|
||||
<label
|
||||
for="profileMessagesReadReceiptsToggle"
|
||||
class="inline-flex items-center gap-2 text-xs font-medium text-muted-strong"
|
||||
>
|
||||
<input
|
||||
id="profileMessagesReadReceiptsToggle"
|
||||
type="checkbox"
|
||||
class="checkbox"
|
||||
/>
|
||||
Send read receipts
|
||||
</label>
|
||||
<label
|
||||
for="profileMessagesTypingToggle"
|
||||
class="inline-flex items-center gap-2 text-xs font-medium text-muted-strong"
|
||||
>
|
||||
<input
|
||||
id="profileMessagesTypingToggle"
|
||||
type="checkbox"
|
||||
class="checkbox"
|
||||
/>
|
||||
Share typing indicators
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
id="profileMessagesStatus"
|
||||
class="sr-only"
|
||||
role="status"
|
||||
aria-live="polite"
|
||||
></div>
|
||||
<div
|
||||
id="profileMessagesLoading"
|
||||
class="hidden py-6"
|
||||
role="status"
|
||||
aria-live="polite"
|
||||
>
|
||||
<div class="sidebar-loading-wrapper">
|
||||
<div class="sidebar-loading-indicator">
|
||||
<span
|
||||
class="status-spinner status-spinner--inline"
|
||||
aria-hidden="true"
|
||||
></span>
|
||||
<span class="sidebar-loading-text"
|
||||
>Fetching direct messages from relays…</span
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
id="profileMessagesError"
|
||||
class="card hidden border border-critical/40 bg-critical/10 px-4 py-3 text-sm text-critical"
|
||||
role="alert"
|
||||
aria-live="assertive"
|
||||
></div>
|
||||
<div
|
||||
id="profileMessagesEmpty"
|
||||
class="card hidden border border-dashed border-border/60 p-6 text-center text-sm text-muted"
|
||||
role="status"
|
||||
aria-live="polite"
|
||||
>
|
||||
No direct messages yet.
|
||||
</div>
|
||||
<div class="flex items-center justify-end gap-2">
|
||||
<button
|
||||
id="profileMessagesReload"
|
||||
type="button"
|
||||
class="btn-ghost focus-ring inline-flex items-center gap-2"
|
||||
data-size="sm"
|
||||
>
|
||||
Refresh
|
||||
</button>
|
||||
</div>
|
||||
<ul
|
||||
id="profileMessagesList"
|
||||
class="grid-stack hidden"
|
||||
data-orientation="vertical"
|
||||
aria-live="polite"
|
||||
aria-label="Direct message threads"
|
||||
></ul>
|
||||
<div
|
||||
id="profileMessagesConversation"
|
||||
class="hidden flex flex-col gap-3"
|
||||
role="log"
|
||||
aria-live="polite"
|
||||
aria-label="Direct message conversation"
|
||||
></div>
|
||||
<p
|
||||
id="profileMessagesConversationEmpty"
|
||||
class="hidden text-sm text-muted"
|
||||
role="status"
|
||||
aria-live="polite"
|
||||
>
|
||||
Select a thread to view messages and attachments.
|
||||
</p>
|
||||
<div class="flex flex-col gap-3 border-t border-border/60 pt-4">
|
||||
<label class="sr-only" for="profileMessageInput">Message</label>
|
||||
<textarea
|
||||
id="profileMessageInput"
|
||||
class="input min-h-[var(--size-96px)]"
|
||||
rows="3"
|
||||
placeholder="Write a message…"
|
||||
></textarea>
|
||||
<div class="flex flex-col gap-2">
|
||||
<input
|
||||
id="profileMessageAttachmentInput"
|
||||
type="file"
|
||||
class="sr-only"
|
||||
multiple
|
||||
/>
|
||||
<div class="flex flex-wrap items-center gap-2">
|
||||
<button
|
||||
id="profileMessageAttachmentButton"
|
||||
type="button"
|
||||
class="btn-ghost focus-ring inline-flex items-center gap-2"
|
||||
data-size="sm"
|
||||
>
|
||||
Attach file
|
||||
</button>
|
||||
<label class="inline-flex items-center gap-2 text-xs text-muted">
|
||||
<input
|
||||
id="profileMessageAttachmentEncrypt"
|
||||
type="checkbox"
|
||||
class="checkbox"
|
||||
/>
|
||||
Encrypt attachments
|
||||
</label>
|
||||
<button
|
||||
id="profileMessageAttachmentClearCache"
|
||||
type="button"
|
||||
class="btn-ghost focus-ring inline-flex items-center gap-2"
|
||||
data-size="sm"
|
||||
>
|
||||
Clear attachment cache
|
||||
</button>
|
||||
</div>
|
||||
<div
|
||||
id="profileMessageAttachmentList"
|
||||
class="grid-stack"
|
||||
data-orientation="vertical"
|
||||
></div>
|
||||
</div>
|
||||
<div class="flex flex-wrap items-center justify-between gap-2">
|
||||
<p
|
||||
id="profileMessagesComposerHelper"
|
||||
class="text-xs text-muted hidden"
|
||||
role="status"
|
||||
aria-live="polite"
|
||||
>
|
||||
Sign in to send messages.
|
||||
</p>
|
||||
<p
|
||||
id="profileMessagesPrivacyMode"
|
||||
class="text-xs text-muted"
|
||||
title="NIP-04 sends a direct encrypted DM; NIP-17 gift-wraps messages to reduce metadata exposure but relies on relay hints."
|
||||
>
|
||||
Privacy: NIP-04
|
||||
</p>
|
||||
<button
|
||||
id="profileMessageSendBtn"
|
||||
type="button"
|
||||
class="btn focus-ring inline-flex items-center gap-2"
|
||||
data-size="sm"
|
||||
>
|
||||
Send
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div id="dmAppShellMount"></div>
|
||||
</section>
|
||||
<section
|
||||
id="profilePaneHistory"
|
||||
|
||||
@@ -15,6 +15,7 @@ import {
|
||||
} from "../constants.js";
|
||||
import { getBreakpointLg } from "../designSystem/metrics.js";
|
||||
import { getProviderMetadata } from "../services/authProviders/index.js";
|
||||
import { AppShell } from "./dm/index.js";
|
||||
import { devLogger, userLogger } from "../utils/logger.js";
|
||||
import {
|
||||
normalizeHashtag,
|
||||
@@ -1295,6 +1296,8 @@ export class ProfileModalController {
|
||||
this.profileMessagesRelayStatus = null;
|
||||
this.profileMessagesReadReceiptsToggle = null;
|
||||
this.profileMessagesTypingToggle = null;
|
||||
this.dmAppShellContainer = null;
|
||||
this.dmAppShell = null;
|
||||
this.profileLinkPreviewAutoToggle = null;
|
||||
this.walletUriInput = null;
|
||||
this.walletDefaultZapInput = null;
|
||||
@@ -1608,6 +1611,8 @@ export class ProfileModalController {
|
||||
document.getElementById("profileMessagesReadReceiptsToggle") || null;
|
||||
this.profileMessagesTypingToggle =
|
||||
document.getElementById("profileMessagesTypingToggle") || null;
|
||||
this.dmAppShellContainer =
|
||||
document.getElementById("dmAppShellMount") || null;
|
||||
this.profileLinkPreviewAutoToggle =
|
||||
document.getElementById("profileLinkPreviewAutoToggle") || null;
|
||||
|
||||
@@ -4038,13 +4043,59 @@ export class ProfileModalController {
|
||||
void this.ensureDirectMessageSubscription(actor);
|
||||
}
|
||||
|
||||
mountDmAppShell() {
|
||||
const container =
|
||||
this.dmAppShellContainer instanceof HTMLElement
|
||||
? this.dmAppShellContainer
|
||||
: null;
|
||||
if (!container) {
|
||||
return;
|
||||
}
|
||||
|
||||
container.innerHTML = "";
|
||||
|
||||
try {
|
||||
this.dmAppShell = new AppShell({ document });
|
||||
} catch (error) {
|
||||
this.dmAppShell = null;
|
||||
devLogger.warn("[profileModal] Failed to mount DM app shell:", error);
|
||||
return;
|
||||
}
|
||||
|
||||
const root =
|
||||
this.dmAppShell &&
|
||||
typeof this.dmAppShell.getRoot === "function"
|
||||
? this.dmAppShell.getRoot()
|
||||
: null;
|
||||
if (!(root instanceof HTMLElement)) {
|
||||
devLogger.warn("[profileModal] DM app shell root missing.");
|
||||
return;
|
||||
}
|
||||
|
||||
container.appendChild(root);
|
||||
}
|
||||
|
||||
unmountDmAppShell() {
|
||||
const container =
|
||||
this.dmAppShellContainer instanceof HTMLElement
|
||||
? this.dmAppShellContainer
|
||||
: null;
|
||||
if (container) {
|
||||
container.innerHTML = "";
|
||||
}
|
||||
|
||||
this.dmAppShell = null;
|
||||
}
|
||||
|
||||
resumeProfileMessages() {
|
||||
this.messagesViewActive = true;
|
||||
this.mountDmAppShell();
|
||||
this.updateMessagesReloadState();
|
||||
}
|
||||
|
||||
pauseProfileMessages() {
|
||||
this.messagesViewActive = false;
|
||||
this.unmountDmAppShell();
|
||||
this.updateMessagesReloadState();
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user