diff --git a/frontend/src/resources/css/_chat.scss b/frontend/src/resources/css/_chat.scss
index af0e905..e687c1e 100644
--- a/frontend/src/resources/css/_chat.scss
+++ b/frontend/src/resources/css/_chat.scss
@@ -321,25 +321,6 @@
}
}
-// Reply preview styles
-.reply-preview {
- background-color: $color-dark-surface;
- border-radius: 8px;
- padding: 0.75rem;
- margin-bottom: 1rem;
- border-left: 3px solid $color-dark-primary;
-
- .reply-preview-content {
- color: $color-dark-on-surface-variant;
- font-size: 0.9rem;
- line-height: 1.4;
-
- strong {
- color: $color-dark-primary;
- }
- }
-}
-
.message-profile-pic {
img {
width: 40px;
@@ -362,55 +343,6 @@
}
}
-.dialog-content {
- padding: 1.5rem;
-
- h3 {
- margin: 0 0 1rem 0;
- color: $color-dark-on-surface;
- font-size: 1.2rem;
- font-weight: 600;
- }
-
- mdui-text-field {
- width: 100%;
- margin-bottom: 1.5rem;
- }
-
- .reply-preview {
- margin-bottom: 1rem;
- padding: 0.75rem;
- background-color: $color-dark-surface-container;
- border-radius: 8px;
- border: 1px solid $color-dark-outline;
-
- .reply-content {
- display: flex;
- flex-direction: column;
- gap: 0.25rem;
-
- .reply-username {
- font-weight: 600;
- color: $color-dark-on-surface;
- font-size: 0.85rem;
- }
-
- .reply-text {
- color: $color-dark-on-surface-variant;
- font-size: 0.9rem;
- line-height: 1.4;
- }
- }
- }
-
- .dialog-actions {
- display: flex;
- gap: 0.75rem;
- justify-content: flex-end;
- margin-top: 1rem;
- }
-}
-
.context-menu {
position: fixed;
background: $color-dark-surface;
diff --git a/frontend/src/resources/css/common/_components.scss b/frontend/src/resources/css/common/_components.scss
index cf4e87e..8fd5ee7 100644
--- a/frontend/src/resources/css/common/_components.scss
+++ b/frontend/src/resources/css/common/_components.scss
@@ -101,12 +101,17 @@ button, input {
margin: 0 0 1rem 0;
color: $color-dark-on-surface;
font-size: 1.2rem;
+ font-weight: 600;
}
-
+
+ mdui-text-field {
+ width: 100%;
+ }
+
.dialog-actions {
display: flex;
gap: 0.75rem;
justify-content: flex-end;
- margin-top: 1.5rem;
+ margin-top: 1rem;
}
}
\ No newline at end of file
diff --git a/frontend/src/resources/css/dialogs/_reply.scss b/frontend/src/resources/css/dialogs/_reply.scss
new file mode 100644
index 0000000..420d389
--- /dev/null
+++ b/frontend/src/resources/css/dialogs/_reply.scss
@@ -0,0 +1,31 @@
+@use "../common/material" as *;
+
+.reply-dialog .dialog-content {
+ width: 300px;
+ overflow-x:hidden;
+
+ .reply-preview-dialog {
+ margin-bottom: 1rem;
+ padding: 16px;
+ background-color: $color-dark-surface-container;
+ border-radius: 16px;
+
+ .reply-content {
+ display: flex;
+ flex-direction: column;
+ gap: 0.25rem;
+
+ .reply-username {
+ font-weight: 600;
+ color: $color-dark-on-surface;
+ font-size: 0.85rem;
+ }
+
+ .reply-text {
+ color: $color-dark-on-surface-variant;
+ font-size: 0.9rem;
+ line-height: 1.4;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/frontend/src/resources/css/style.scss b/frontend/src/resources/css/style.scss
index e052db4..c380a7b 100644
--- a/frontend/src/resources/css/style.scss
+++ b/frontend/src/resources/css/style.scss
@@ -8,6 +8,7 @@
@use "common/colors" as *;
@use "common/material" as *;
@use "electron";
+@use "dialogs/reply";
@use "lib/fonts/montserrat";
@use "lib/fonts/material-symbols";
diff --git a/frontend/src/ui/components/chat/ChatMessages.tsx b/frontend/src/ui/components/chat/ChatMessages.tsx
index de1703e..603aa9b 100644
--- a/frontend/src/ui/components/chat/ChatMessages.tsx
+++ b/frontend/src/ui/components/chat/ChatMessages.tsx
@@ -6,7 +6,7 @@ import type { UserProfile } from "../../../core/types";
import { UserProfileDialog } from "./UserProfileDialog";
import { MessageContextMenu, type ContextMenuState } from "./MessageContextMenu";
import { fetchUserProfile } from "../../api/profileApi";
-import { useState, useEffect } from "react";
+import { useState } from "react";
import { delay } from "../../../utils/utils";
import { request } from "../../../websocket";
@@ -23,45 +23,6 @@ export function ChatMessages() {
message: null,
position: { x: 0, y: 0 }
});
- const [isContextMenuClosing, setIsContextMenuClosing] = useState(false);
-
- // Effect to handle clicks outside the context menu
- useEffect(() => {
- const handleClickOutside = (event: MouseEvent) => {
- if (contextMenu.isOpen && !isContextMenuClosing) {
- // Check if the click is on a context menu element
- const target = event.target as Element;
- if (!target.closest('.context-menu')) {
- handleContextMenuClose();
- }
- }
- };
-
- const handleKeyDown = (event: KeyboardEvent) => {
- if (event.key === 'Escape' && contextMenu.isOpen && !isContextMenuClosing) {
- handleContextMenuClose();
- }
- };
-
- const handleWindowBlur = () => {
- // Close context menu when browser window loses focus
- if (contextMenu.isOpen && !isContextMenuClosing) {
- handleContextMenuClose();
- }
- };
-
- // Add event listeners
- document.addEventListener('mousedown', handleClickOutside);
- document.addEventListener('keydown', handleKeyDown);
- window.addEventListener('blur', handleWindowBlur);
-
- // Cleanup
- return () => {
- document.removeEventListener('mousedown', handleClickOutside);
- document.removeEventListener('keydown', handleKeyDown);
- window.removeEventListener('blur', handleWindowBlur);
- };
- }, [contextMenu.isOpen, isContextMenuClosing]);
const handleProfileClick = async (username: string) => {
if (!user.authToken) return;
@@ -83,7 +44,6 @@ export function ChatMessages() {
const handleContextMenu = (e: React.MouseEvent, message: MessageType) => {
e.preventDefault();
console.log("Context menu triggered for message:", message.id, "at position:", e.clientX, e.clientY);
- setIsContextMenuClosing(false);
setContextMenu({
isOpen: true,
message,
@@ -91,17 +51,11 @@ export function ChatMessages() {
});
};
- const handleContextMenuClose = () => {
- setIsContextMenuClosing(true);
- // Wait for animation to complete before removing from DOM
- setTimeout(() => {
- setContextMenu({
- isOpen: false,
- message: null,
- position: { x: 0, y: 0 }
- });
- setIsContextMenuClosing(false);
- }, 200); // Match the animation duration from _animations.scss
+ const handleContextMenuOpenChange = (isOpen: boolean) => {
+ setContextMenu(prev => ({
+ ...prev,
+ isOpen
+ }));
};
const handleEdit = async (message: MessageType) => {
@@ -191,16 +145,16 @@ export function ChatMessages() {
/>
{/* Context Menu */}
- {contextMenu.isOpen && contextMenu.message && (
+ {contextMenu.message && (