Fix reply preview

This commit is contained in:
2025-11-26 16:28:18 +03:00
Unverified
parent 6d0edd19c3
commit abbd3e2db9
5 changed files with 74 additions and 87 deletions
@@ -2,24 +2,6 @@
@use "../../../css/material" as *;
@use "sass:color";
// Reply preview styles (shared with Message component)
.quote.contextualContent > .quoteInner {
display: flex;
flex-direction: column;
gap: 4px;
.replyUsername {
font-weight: 600;
color: $color-dark-on-surface;
font-size: 0.85rem;
}
.replyText {
overflow: hidden;
text-overflow: ellipsis;
}
}
.chatInputWrapper {
position: relative;
margin: 0 10px 10px 10px;
+43 -59
View File
@@ -2,27 +2,11 @@
@use "../../../css/material" as *;
@use "sass:color";
.quote.contextualContent > .quoteInner {
display: flex;
flex-direction: column;
gap: 4px;
.replyUsername {
font-weight: 600;
color: $color-dark-on-surface;
font-size: 0.85rem;
}
.replyText {
overflow: hidden;
text-overflow: ellipsis;
}
}
.message {
$status-indicator-size: 16px;
margin-bottom: 1rem;
margin-bottom: 10px;
max-width: 70%;
position: relative;
width: fit-content;
@@ -30,30 +14,8 @@
align-items: flex-start;
gap: 8px;
&.received {
.messageProfilePic {
width: 40px;
height: 40px;
flex-shrink: 0;
cursor: pointer;
transition: transform 0.2s ease;
&:hover {
transform: scale(1.05);
}
img {
width: 100%;
height: 100%;
border-radius: 50%;
object-fit: cover;
border: 2px solid $color-dark-outline;
}
}
}
.messageInner {
border-radius: 12px;
border-radius: 20px 20px 8px 8px; // Top corners rounded, bottom corners sharper
position: relative;
word-wrap: break-word;
overflow-wrap: anywhere;
@@ -72,6 +34,7 @@
display: flex;
align-items: center;
gap: 4px;
width: fit-content;
&:hover {
transform: scale(1.05);
@@ -92,9 +55,10 @@
}
}
.quote.replyPreview {
:global(.quote).replyPreview {
user-select: none;
margin: 10px;
margin: 5px;
border-radius: 16px;
}
.messageAttachments {
@@ -194,10 +158,31 @@
}
&.received {
.messageProfilePic {
width: 40px;
height: 40px;
flex-shrink: 0;
cursor: pointer;
transition: transform 0.2s ease;
align-self: flex-end;
&:hover {
transform: scale(1.05);
}
img {
width: 100%;
height: 100%;
border-radius: 50%;
object-fit: cover;
border: 2px solid $color-dark-outline;
}
}
.messageInner {
background: $color-dark-surface-container;
color: $color-dark-on-surface;
border-top-left-radius: 5px;
border-radius: 20px 20px 20px 8px; // Top-left: 5px, top-right: 20px, bottom: 8px
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
border: 1px solid rgba($color-dark-outline-variant, 0.4);
position: relative;
@@ -231,27 +216,27 @@
margin-left: auto;
flex-direction: row-reverse;
:global(.quote).replyPreview {
background: linear-gradient(135deg, rgba(255, 255, 255, 0.15), rgba(255, 255, 255, 0.08));
border: 1px solid rgba(255, 255, 255, 0.2);
position: relative;
overflow: hidden;
box-shadow: 0 2px 8px rgba(147, 51, 234, 0.5);
:global(.quote-inner) {
position: relative;
z-index: 1;
}
}
.messageInner {
background: linear-gradient(135deg, #9333EA, #6366F1, #3B82F6);
color: $color-dark-on-primary;
border-top-right-radius: 5px;
background: linear-gradient(135deg, #9333EA, #6366F1, #2f68c5);
border-radius: 20px 20px 8px 20px; // Top-left: 20px, top-right: 5px, bottom: 8px
box-shadow: 0 0 20px rgba($color-dark-primary, 0.4);
border: 1px solid rgba($color-dark-primary, 0.5);
position: relative;
overflow: hidden;
&::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: linear-gradient(135deg, rgba(255, 255, 255, 0.15), rgba(255, 255, 255, 0.08));
pointer-events: none;
z-index: 0;
}
> * {
position: relative;
z-index: 1;
@@ -273,7 +258,6 @@
}
.messageTime {
color: $color-dark-on-primary;
font-weight: 500;
}
}
@@ -0,0 +1,19 @@
@use "../../../css/colors" as *;
@use "../../../css/material" as *;
:global(.quote).contextualContent > :global(.quote-inner) {
display: flex;
flex-direction: column;
gap: 4px;
.replyUsername {
font-weight: 600;
color: $color-dark-on-surface;
font-size: 0.85rem;
}
.replyText {
overflow: hidden;
text-overflow: ellipsis;
}
}
@@ -7,6 +7,7 @@ import { useImmer } from "use-immer";
import { EmojiMenu } from "./EmojiMenu";
import { MaterialIcon, MaterialIconButton } from "@/utils/material";
import styles from "@/pages/chat/css/ChatInput.module.scss";
import replyPreviewStyles from "@/pages/chat/css/reply-preview.module.scss";
import { alert } from "mdui/functions/alert";
interface ChatInputWrapperProps {
@@ -161,9 +162,9 @@ export function ChatInputWrapper(
>
<div className={styles.contextualPreview}>
<MaterialIcon name="edit" />
<Quote className={`${styles.quote} ${styles.contextualContent}`} background="surfaceContainer">
<span className={styles.replyUsername}>{editingMessage!.username}</span>
<span className={styles.replyText}>{editingMessage!.content}</span>
<Quote className={`${replyPreviewStyles.contextualContent}`} background="surfaceContainer">
<span className={replyPreviewStyles.replyUsername}>{editingMessage!.username}</span>
<span className={replyPreviewStyles.replyText}>{editingMessage!.content}</span>
</Quote>
<MaterialIconButton icon="close" className={styles.replyCancel} onClick={onClearEdit}></MaterialIconButton>
</div>
@@ -181,9 +182,9 @@ export function ChatInputWrapper(
>
<div className={styles.contextualPreview}>
<MaterialIcon name="reply" />
<Quote className={`${styles.quote} ${styles.contextualContent}`} background="surfaceContainer">
<span className={styles.replyUsername}>{replyTo!.username}</span>
<span className={styles.replyText}>{replyTo!.content}</span>
<Quote className={`${replyPreviewStyles.contextualContent}`} background="surfaceContainer">
<span className={replyPreviewStyles.replyUsername}>{replyTo!.username}</span>
<span className={replyPreviewStyles.replyText}>{replyTo!.content}</span>
</Quote>
<MaterialIconButton icon="close" className={styles.replyCancel} onClick={onClearReply}></MaterialIconButton>
</div>
+5 -4
View File
@@ -17,6 +17,7 @@ import { createPortal } from "react-dom";
import { parseProfileLink } from "@/core/profileLinks";
import { MaterialCircularProgress, MaterialIconButton, MaterialList, MaterialListItem } from "@/utils/material";
import styles from "@/pages/chat/css/Message.module.scss";
import replyPreviewStyles from "@/pages/chat/css/reply-preview.module.scss";
interface MessageReactionsProps {
reactions?: Reaction[];
@@ -483,7 +484,7 @@ export function Message({ message, isAuthor, onContextMenu, onReactionClick, isD
{!isAuthor && !isDm && (
<div className={styles.messageProfilePic} onClick={handleProfileClick}>
<img
src={message.username?.startsWith("Deleted User #") ? defaultAvatar : (message.profile_picture || defaultAvatar)}
src={message.profile_picture || defaultAvatar}
alt={message.username}
onError={(e) => {
e.target.src = defaultAvatar;
@@ -507,9 +508,9 @@ export function Message({ message, isAuthor, onContextMenu, onReactionClick, isD
)}
{message.reply_to && (
<Quote className={`${styles.replyPreview} ${styles.contextualContent}`} background={isAuthor ? "primaryContainer" : "surfaceContainer"}>
<span className={styles.replyUsername}>{message.reply_to.username}</span>
<span className={styles.replyText}>{message.reply_to.content}</span>
<Quote className={`${styles.replyPreview} ${replyPreviewStyles.contextualContent}`} background={isAuthor ? "primaryContainer" : "surfaceContainer"}>
<span className={replyPreviewStyles.replyUsername}>{message.reply_to.username}</span>
<span className={replyPreviewStyles.replyText}>{message.reply_to.content}</span>
</Quote>
)}