mirror of
https://github.com/PR0M3TH3AN/bitvid.git
synced 2026-10-31 09:52:24 +00:00
Merge pull request #1555 from PR0M3TH3AN/dm-ui-redesign-11990077537705520279
Redesign DM profile pane UI
This commit is contained in:
8 files changed
+4202
-321
No files matched your search
@@ -1270,7 +1270,7 @@
|
||||
</section>
|
||||
<section
|
||||
id="profilePaneMessages"
|
||||
class="profile-pane hidden space-y-4"
|
||||
class="profile-pane hidden"
|
||||
role="tabpanel"
|
||||
aria-labelledby="profileNavMessages"
|
||||
>
|
||||
|
||||
+97
-8
@@ -3063,6 +3063,20 @@
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
/* Specific override for messages pane to prevent parent scrolling on desktop */
|
||||
@media (min-width: theme("screens.md")) {
|
||||
#profilePaneMessages {
|
||||
height: 100%;
|
||||
min-height: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
#dmAppShellMount {
|
||||
height: 100%;
|
||||
min-height: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.profile-pane.hidden {
|
||||
display: none !important;
|
||||
}
|
||||
@@ -5060,7 +5074,8 @@
|
||||
.profile-modal .dm-app-shell {
|
||||
min-height: 0;
|
||||
height: auto;
|
||||
padding: var(--space-md);
|
||||
padding: 0;
|
||||
gap: var(--space-md);
|
||||
}
|
||||
|
||||
.dm-app-shell__sidebar,
|
||||
@@ -5075,6 +5090,10 @@
|
||||
.profile-modal .dm-app-shell__main {
|
||||
height: auto;
|
||||
min-height: 0;
|
||||
border: none;
|
||||
box-shadow: none;
|
||||
background: transparent;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.dm-app-shell__sidebar {
|
||||
@@ -5312,8 +5331,33 @@
|
||||
border-radius: var(--radius-md);
|
||||
}
|
||||
|
||||
.dm-message-row {
|
||||
display: flex;
|
||||
align-items: flex-end;
|
||||
gap: var(--space-xs);
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.dm-message-row--incoming {
|
||||
justify-content: flex-start;
|
||||
}
|
||||
|
||||
.dm-message-row--outgoing {
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.dm-message-avatar {
|
||||
width: var(--space-xl);
|
||||
height: var(--space-xl);
|
||||
flex-shrink: 0;
|
||||
border-radius: var(--radius-full);
|
||||
object-fit: cover;
|
||||
background-color: var(--surface-sunken);
|
||||
border: var(--border-width-hairline) solid var(--border-subtle);
|
||||
}
|
||||
|
||||
.dm-message-bubble {
|
||||
max-width: 85%;
|
||||
max-width: 75%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--space-2xs);
|
||||
@@ -5325,14 +5369,14 @@
|
||||
}
|
||||
|
||||
.dm-message-bubble--incoming {
|
||||
align-self: flex-start;
|
||||
border-bottom-left-radius: var(--radius-sm);
|
||||
}
|
||||
|
||||
.dm-message-bubble--outgoing {
|
||||
align-self: flex-end;
|
||||
background: var(--color-accent);
|
||||
color: var(--color-white);
|
||||
border-color: var(--color-accent-strong);
|
||||
border-bottom-right-radius: var(--radius-sm);
|
||||
}
|
||||
|
||||
.dm-message-bubble--outgoing .dm-message-bubble__meta,
|
||||
@@ -5827,21 +5871,65 @@
|
||||
}
|
||||
}
|
||||
|
||||
/* Ensure the profile pane for messages takes full height */
|
||||
#profilePaneMessages {
|
||||
height: 100%;
|
||||
min-height: 0;
|
||||
}
|
||||
|
||||
@media (min-width: theme("screens.md")) {
|
||||
.profile-modal .dm-app-shell {
|
||||
flex-direction: row;
|
||||
align-items: stretch;
|
||||
height: 100%;
|
||||
min-height: 0;
|
||||
}
|
||||
|
||||
.profile-modal .dm-app-shell__sidebar {
|
||||
flex: 0 0 var(--size-18rem);
|
||||
max-width: var(--size-20rem);
|
||||
height: auto;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.profile-modal .dm-app-shell__main {
|
||||
flex: 1 1 auto;
|
||||
height: auto;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.profile-modal .dm-conversation-list {
|
||||
flex: 1;
|
||||
min-height: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.profile-modal .dm-conversation-list__items {
|
||||
flex: 1;
|
||||
overflow-y: auto;
|
||||
min-height: 0;
|
||||
overscroll-behavior-y: contain;
|
||||
@apply no-scrollbar;
|
||||
}
|
||||
|
||||
.profile-modal .dm-message-thread {
|
||||
flex: 1;
|
||||
min-height: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.profile-modal .dm-message-thread__timeline {
|
||||
flex: 1;
|
||||
overflow-y: auto;
|
||||
min-height: 0;
|
||||
overscroll-behavior-y: contain;
|
||||
@apply no-scrollbar;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5986,9 +6074,10 @@
|
||||
}
|
||||
|
||||
.no-scrollbar {
|
||||
scrollbar-width: none;
|
||||
scrollbar-width: none !important;
|
||||
-ms-overflow-style: none !important;
|
||||
}
|
||||
|
||||
.no-scrollbar::-webkit-scrollbar {
|
||||
display: none;
|
||||
display: none !important;
|
||||
}
|
||||
+3
-15
@@ -1,7 +1,6 @@
|
||||
import { Composer } from "./Composer.js";
|
||||
import { ConversationList } from "./ConversationList.js";
|
||||
import { MessageThread } from "./MessageThread.js";
|
||||
import { NotificationCenter } from "./NotificationCenter.js";
|
||||
import { DMPrivacySettings } from "./DMPrivacySettings.js";
|
||||
import { aggregateZapTotals } from "./zapHelpers.js";
|
||||
import { createZapInterface } from "./ZapInterface.js";
|
||||
@@ -114,6 +113,7 @@ const DEFAULT_ZAP_RECEIPTS = [
|
||||
export class AppShell {
|
||||
constructor({
|
||||
document: doc,
|
||||
currentUserAvatarUrl = "",
|
||||
conversations = DEFAULT_CONVERSATIONS,
|
||||
activeConversationId = DEFAULT_CONVERSATIONS[0]?.id || "",
|
||||
conversationState = "idle",
|
||||
@@ -124,7 +124,6 @@ export class AppShell {
|
||||
composerState = "idle",
|
||||
privacyMode = "nip04",
|
||||
dmPrivacySettings = { readReceiptsEnabled: false, typingIndicatorsEnabled: false },
|
||||
notifications = [],
|
||||
signingAdapter = null,
|
||||
zapConfig = null,
|
||||
mobileView = "list",
|
||||
@@ -168,7 +167,7 @@ export class AppShell {
|
||||
doc,
|
||||
"h1",
|
||||
"dm-app-shell__title text-lg font-bold",
|
||||
"Direct Messages",
|
||||
"Conversations",
|
||||
);
|
||||
sidebarHeader.appendChild(sidebarTitle);
|
||||
|
||||
@@ -219,6 +218,7 @@ export class AppShell {
|
||||
main.appendChild(
|
||||
MessageThread({
|
||||
document: doc,
|
||||
currentUserAvatarUrl,
|
||||
contact: activeConversation,
|
||||
messages,
|
||||
state: threadState,
|
||||
@@ -248,12 +248,6 @@ export class AppShell {
|
||||
zapConfig
|
||||
});
|
||||
|
||||
// Position it relative to the composer or just absolute in main
|
||||
// The extracted createZapInterface uses 'absolute bottom-16 right-4' which positions it nicely
|
||||
// relative to the container if the container is relative.
|
||||
// main usually has relative positioning or we can append to root.
|
||||
// AppShell root has absolute positioning context maybe?
|
||||
// If main is the container, we append there.
|
||||
main.appendChild(zapInterface);
|
||||
};
|
||||
|
||||
@@ -276,12 +270,6 @@ export class AppShell {
|
||||
}
|
||||
}),
|
||||
);
|
||||
main.appendChild(
|
||||
NotificationCenter({
|
||||
document: doc,
|
||||
notices: notifications,
|
||||
}),
|
||||
);
|
||||
|
||||
this.root.appendChild(sidebar);
|
||||
this.root.appendChild(main);
|
||||
|
||||
@@ -29,12 +29,14 @@ export function ConversationList({
|
||||
|
||||
const root = createElement(doc, "section", "dm-conversation-list");
|
||||
const header = createElement(doc, "div", "dm-conversation-list__header");
|
||||
header.appendChild(createElement(doc, "h2", "dm-conversation-list__title", "Messages"));
|
||||
// We removed the redundant "Messages" title here.
|
||||
// If we need spacing/alignment for the button, justify-end in CSS handles it.
|
||||
|
||||
if (typeof onMarkAllRead === "function") {
|
||||
const markAllButton = createElement(
|
||||
doc,
|
||||
"button",
|
||||
"btn-ghost",
|
||||
"btn-ghost ml-auto",
|
||||
"Mark all as read",
|
||||
);
|
||||
markAllButton.type = "button";
|
||||
@@ -45,7 +47,10 @@ export function ConversationList({
|
||||
});
|
||||
header.appendChild(markAllButton);
|
||||
}
|
||||
root.appendChild(header);
|
||||
|
||||
if (header.hasChildNodes()) {
|
||||
root.appendChild(header);
|
||||
}
|
||||
|
||||
const list = createElement(doc, "div", "dm-conversation-list__items no-scrollbar");
|
||||
list.setAttribute("role", "listbox");
|
||||
@@ -88,9 +93,9 @@ export function ConversationList({
|
||||
list.scrollTo({ top: 40, behavior: "smooth" });
|
||||
setTimeout(() => {
|
||||
list.scrollTo({ top: 0, behavior: "smooth" });
|
||||
}, 600);
|
||||
}, 800);
|
||||
}
|
||||
}, 300);
|
||||
}, 600);
|
||||
}
|
||||
}, { threshold: 0.1 });
|
||||
observer.observe(list);
|
||||
@@ -101,7 +106,7 @@ export function ConversationList({
|
||||
list.scrollTo({ top: 40, behavior: "smooth" });
|
||||
setTimeout(() => {
|
||||
list.scrollTo({ top: 0, behavior: "smooth" });
|
||||
}, 600);
|
||||
}, 800);
|
||||
}
|
||||
}, 600);
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ export function MessageBubble({
|
||||
document: doc,
|
||||
message = {},
|
||||
variant = "incoming",
|
||||
avatarSrc = "",
|
||||
} = {}) {
|
||||
if (!doc) {
|
||||
throw new Error("MessageBubble requires a document reference.");
|
||||
@@ -24,12 +25,19 @@ export function MessageBubble({
|
||||
status = "sent",
|
||||
} = message;
|
||||
|
||||
const wrapper = createElement(doc, "div", "dm-message-bubble");
|
||||
wrapper.classList.add(`dm-message-bubble--${variant}`);
|
||||
wrapper.dataset.status = status;
|
||||
const row = createElement(doc, "div", "dm-message-row");
|
||||
row.classList.add(`dm-message-row--${variant}`);
|
||||
|
||||
const avatar = createElement(doc, "img", "dm-message-avatar");
|
||||
avatar.src = avatarSrc || "assets/svg/default-profile.svg";
|
||||
avatar.alt = variant === "outgoing" ? "Me" : "Sender";
|
||||
|
||||
const bubble = createElement(doc, "div", "dm-message-bubble");
|
||||
bubble.classList.add(`dm-message-bubble--${variant}`);
|
||||
bubble.dataset.status = status;
|
||||
|
||||
const content = createElement(doc, "div", "dm-message-bubble__content", body);
|
||||
wrapper.appendChild(content);
|
||||
bubble.appendChild(content);
|
||||
|
||||
const meta = createElement(doc, "div", "dm-message-bubble__meta");
|
||||
if (timestamp) {
|
||||
@@ -55,6 +63,15 @@ export function MessageBubble({
|
||||
meta.appendChild(statusLabel);
|
||||
}
|
||||
|
||||
wrapper.appendChild(meta);
|
||||
return wrapper;
|
||||
bubble.appendChild(meta);
|
||||
|
||||
if (variant === "outgoing") {
|
||||
row.appendChild(bubble);
|
||||
row.appendChild(avatar);
|
||||
} else {
|
||||
row.appendChild(avatar);
|
||||
row.appendChild(bubble);
|
||||
}
|
||||
|
||||
return row;
|
||||
}
|
||||
@@ -16,6 +16,7 @@ export function MessageThread({
|
||||
document: doc,
|
||||
contact = {},
|
||||
messages = [],
|
||||
currentUserAvatarUrl = "",
|
||||
state = "idle",
|
||||
errorType = "",
|
||||
privacyMode = "nip04",
|
||||
@@ -128,10 +129,12 @@ export function MessageThread({
|
||||
timeline.appendChild(DayDivider({ document: doc, label: message.label }));
|
||||
return;
|
||||
}
|
||||
const isOutgoing = message.direction === "outgoing";
|
||||
const bubble = MessageBubble({
|
||||
document: doc,
|
||||
message,
|
||||
variant: message.direction === "outgoing" ? "outgoing" : "incoming",
|
||||
variant: isOutgoing ? "outgoing" : "incoming",
|
||||
avatarSrc: isOutgoing ? currentUserAvatarUrl : (contact.avatarSrc || ""),
|
||||
});
|
||||
timeline.appendChild(bubble);
|
||||
});
|
||||
@@ -152,7 +155,7 @@ export function MessageThread({
|
||||
top: timeline.scrollHeight,
|
||||
behavior: "smooth",
|
||||
});
|
||||
}, 600);
|
||||
}, 800);
|
||||
}, 600);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -4413,6 +4413,11 @@ export class ProfileModalController {
|
||||
activeThread?.latestMessage,
|
||||
);
|
||||
|
||||
const currentUserSummary = this.resolveProfileSummaryForPubkey(
|
||||
this.resolveActiveDmActor(),
|
||||
);
|
||||
const currentUserAvatarUrl = currentUserSummary?.avatarSrc || "";
|
||||
|
||||
container.innerHTML = "";
|
||||
|
||||
try {
|
||||
@@ -4420,6 +4425,7 @@ export class ProfileModalController {
|
||||
|
||||
this.dmAppShell = new AppShell({
|
||||
document,
|
||||
currentUserAvatarUrl,
|
||||
conversations,
|
||||
activeConversationId,
|
||||
conversationState,
|
||||
|
||||
+4056
-283
File diff suppressed because it is too large.
Load diff
Reference in new issue
Block a user