This commit is contained in:
2025-11-02 20:48:00 +03:00
Unverified
parent 2b316de17e
commit 852ab15bd8
9 changed files with 17 additions and 377 deletions
@@ -1,184 +0,0 @@
@use "../../../css/colors" as *;
@use "../../../css/material" as *;
@use "sass:color";
// Animation for reactions appearing/disappearing
@keyframes messageReactionsFadeIn {
from {
opacity: 0;
transform: translateY(-10px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
@keyframes reactionFadeIn {
from {
opacity: 0;
transform: scale(0.8);
}
to {
opacity: 1;
transform: scale(1);
}
}
@keyframes reactionFadeOut {
from {
opacity: 1;
transform: scale(1);
}
to {
opacity: 0;
transform: scale(0.8);
}
}
// Context menu wrapper animations
@keyframes contextMenuEnter {
to {
opacity: 1;
transform: scale(1);
}
}
@keyframes contextMenuEnterLeft {
to {
opacity: 1;
transform: translateX(0) scale(1);
}
}
@keyframes contextMenuEnterUp {
to {
opacity: 1;
transform: translateY(0) scale(1);
}
}
@keyframes contextMenuEnterUpLeft {
to {
opacity: 1;
transform: translateX(0) translateY(0) scale(1);
}
}
@keyframes contextMenuClose {
to {
opacity: 0;
transform: scale(0.8);
}
}
@keyframes contextMenuCloseLeft {
to {
opacity: 0;
transform: translateX(-20px) scale(0.8);
}
}
@keyframes contextMenuCloseUp {
to {
opacity: 0;
transform: translateY(20px) scale(0.8);
}
}
@keyframes contextMenuCloseUpLeft {
to {
opacity: 0;
transform: translateX(-20px) translateY(20px) scale(0.8);
}
}
@keyframes emojiMenuEnter {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
@keyframes emojiMenuEnterDown {
from {
opacity: 0;
transform: scaleY(0);
transform-origin: top;
}
to {
opacity: 1;
transform: scaleY(1);
}
}
@keyframes emojiMenuEnterUp {
from {
opacity: 0;
transform: scaleY(0);
transform-origin: bottom;
}
to {
opacity: 1;
transform: scaleY(1);
}
}
// Reaction bar animations
@keyframes reactionBarEnter {
to {
opacity: 1;
transform: translateY(0) scale(1);
}
}
@keyframes reactionBarEnterLeft {
to {
opacity: 1;
transform: translateX(0) translateY(0) scale(1);
}
}
@keyframes reactionBarEnterUp {
to {
opacity: 1;
transform: translateY(0) scale(1);
}
}
@keyframes reactionBarEnterRight {
to {
opacity: 1;
transform: translateX(0) scale(1);
}
}
@keyframes reactionBarClose {
to {
opacity: 0;
transform: translateY(-20px) scale(0.9);
}
}
@keyframes reactionBarCloseLeft {
to {
opacity: 0;
transform: translateX(-20px) translateY(-20px) scale(0.9);
}
}
@keyframes reactionBarCloseUp {
to {
opacity: 0;
transform: translateY(20px) scale(0.9);
}
}
@@ -73,6 +73,13 @@
&.dragging {
cursor: grabbing;
box-shadow: 0 20px 60px rgba(0, 0, 0, 0.7);
transition: width 0.4s cubic-bezier(0.4, 0, 0.2, 1),
height 0.4s cubic-bezier(0.4, 0, 0.2, 1),
background-color 0.4s cubic-bezier(0.4, 0, 0.2, 1),
backdrop-filter 0.4s cubic-bezier(0.4, 0, 0.2, 1),
border 0.4s cubic-bezier(0.4, 0, 0.2, 1),
border-radius 0.4s cubic-bezier(0.4, 0, 0.2, 1),
box-shadow 0.4s cubic-bezier(0.4, 0, 0.2, 1);
}
.callHeader {
@@ -1,13 +1,13 @@
import { useState, useEffect, useRef } from "react";
import { motion, AnimatePresence } from "motion/react";
import { MaterialDialog } from "@/core/components/Dialog";
import { RichTextArea } from "@/core/components/RichTextArea";
import type { Message } from "@/core/types";
import Quote from "@/core/components/Quote";
import { useImmer } from "use-immer";
import { EmojiMenu } from "./EmojiMenu";
import { MaterialButton, MaterialIcon, MaterialIconButton } from "@/utils/material";
import { MaterialIcon, MaterialIconButton } from "@/utils/material";
import styles from "@/pages/chat/css/ChatInput.module.scss";
import { alert } from "mdui/functions/alert";
interface ChatInputWrapperProps {
onSendMessage: (message: string, files: File[]) => void;
@@ -47,7 +47,6 @@ export function ChatInputWrapper(
const [message, setMessage] = useState("");
const [selectedFiles, setSelectedFiles] = useImmer<File[]>([]);
const [attachmentsVisible, setAttachmentsVisible] = useState(false);
const [errorOpen, setErrorOpen] = useState(false);
const [emojiMenuOpen, setEmojiMenuOpen] = useState(false);
const [emojiMenuPosition, setEmojiMenuPosition] = useState({ x: 0, y: 0 });
const chatInputWrapperRef = useRef<HTMLDivElement>(null);
@@ -116,9 +115,13 @@ export function ChatInputWrapper(
const totalSize = selectedFiles.reduce((acc, f) => acc + f.size, 0);
const limit = 4 * 1024 * 1024 * 1024; // 4GB
if (totalSize > limit) {
setErrorOpen(true);
alert({
headline: "Ошибка",
description: "Общий размер вложений превышает 4 ГБ."
});
return;
}
if (editingMessage && onSaveEdit) {
onSaveEdit(message);
setMessage("");
@@ -249,11 +252,6 @@ export function ChatInputWrapper(
</div>
</div>
</form>
<MaterialDialog open={errorOpen} onOpenChange={setErrorOpen} close-on-overlay-click close-on-esc>
<div slot="headline">Ошибка</div>
<div>Общий размер вложений превышает 4 ГБ.</div>
<MaterialButton slot="action" onClick={() => setErrorOpen(false)}>Закрыть</MaterialButton>
</MaterialDialog>
<EmojiMenu
isOpen={emojiMenuOpen}
@@ -132,13 +132,13 @@ export function CallWindow() {
style={isMinimized ? {
left: pipPosition.x,
top: pipPosition.y
} : undefined}
} : {}}
initial={false}
exit={isMinimized ?
{ opacity: 0, scale: 0.7 } :
{ opacity: 0, y: -100 }
}
transition={{
transition={isDragging ? { duration: 0 } : {
opacity: { duration: 0.4 },
scale: { duration: 0.4 },
y: { duration: 0.4 }