This commit is contained in:
2025-10-20 22:08:12 +03:00
Unverified
parent 97f19ce52b
commit 27e1cf7a68
5 changed files with 26 additions and 53 deletions
+7 -8
View File
@@ -2,10 +2,10 @@ import { BrowserRouter, Routes, Route, useNavigate, matchRoutes, type RouteObjec
import { ElectronTitleBar } from "./Electron";
import { useAppState } from "./pages/chat/state";
import { lazy, useEffect, useState } from "react";
import { parseProfileLink } from "./core/profileLinks.ts";
import NotFoundPage from "./pages/not-found/NotFoundPage.tsx";
import ProtectedRoute from "./pages/ProtectedRoute.tsx";
import DownloadAppPage from "./pages/download-app/DownloadAppPage.tsx";
import { parseProfileLink } from "./core/profileLinks";
import NotFoundPage from "./pages/not-found/NotFoundPage";
import ProtectedRoute from "./pages/ProtectedRoute";
import DownloadAppPage from "./pages/download-app/DownloadAppPage";
// Lazy load route components
const HomePage = lazy(() => import("./pages/home/HomePage"));
@@ -19,12 +19,12 @@ const routeConfig: RouteObject[] = [
{ path: "/register", element: <RegisterPage /> },
{ path: "/download-app", element: <DownloadAppPage /> },
{
path: "/chat",
path: "/chat",
element: (
<ProtectedRoute>
<ChatPage />
</ProtectedRoute>
)
)
},
{ path: "*", element: <SmartCatchAll /> }
];
@@ -46,8 +46,7 @@ function SmartCatchAll() {
return;
}
// Check if it's a profile link
const profileInfo = parseProfileLink(); // no url specified intentionally to let it use the current url
const profileInfo = parseProfileLink(); // No URL specified intentionally to let it use the current URL
if (profileInfo) {
setShowNotFound(false);
+2 -2
View File
@@ -27,8 +27,8 @@ export default function ChatPage() {
const profileInfo = location.state.profileInfo;
// Create a unique key for this profile
const profileKey = profileInfo.userId
? `user_${profileInfo.userId}`
const profileKey = profileInfo.userId
? `user_${profileInfo.userId}`
: `username_${profileInfo.username}`;
// Skip if we've already processed this exact profile
+14 -38
View File
@@ -74,8 +74,7 @@ export function ProfileDialog() {
const [isSaving, setIsSaving] = useState(false);
const [errors, setErrors] = useState<{[key: string]: string}>({});
const fileInputRef = useRef<HTMLInputElement>(null);
const backdropRef = useRef<HTMLDivElement>(null);
const dialogRef = useRef<HTMLDivElement>(null);
const [openClass, setOpenClass] = useState(false);
// Handle dialog open/close based on state
useEffect(() => {
@@ -84,17 +83,12 @@ export function ProfileDialog() {
fetchFreshProfileData(chat.profileDialog);
} else if (!chat.profileDialog && isOpen) {
// Start close animation
if (backdropRef.current && dialogRef.current) {
backdropRef.current.classList.remove('open');
dialogRef.current.classList.remove('open');
setOpenClass(false);
// Wait for animation to complete before closing
setTimeout(() => {
setIsOpen(false);
}, 300); // Match CSS transition duration
} else {
setIsOpen(false);
}
}, 300);
}
}, [chat.profileDialog, isOpen]);
@@ -132,13 +126,10 @@ export function ProfileDialog() {
useEffect(() => {
if (isOpen) {
// Small delay to ensure DOM is ready for transition
const timer = setTimeout(() => {
if (backdropRef.current && dialogRef.current) {
backdropRef.current.classList.add('open');
dialogRef.current.classList.add('open');
}
}, 10);
return () => clearTimeout(timer);
const timer = requestAnimationFrame(() => {
setOpenClass(true);
});
return () => cancelAnimationFrame(timer);
}
}, [isOpen]);
@@ -214,17 +205,12 @@ export function ProfileDialog() {
};
function triggerCloseAnimation() {
if (backdropRef.current && dialogRef.current) {
backdropRef.current.classList.remove('open');
dialogRef.current.classList.remove('open');
setOpenClass(false);
// Wait for animation to complete before closing
setTimeout(() => {
closeProfileDialog();
}, 300); // Match CSS transition duration
} else {
// Wait for animation to complete before closing
setTimeout(() => {
closeProfileDialog();
}
}, 300); // Match CSS transition duration
};
function handleBackdropClick(e: React.MouseEvent) {
@@ -402,13 +388,10 @@ export function ProfileDialog() {
return createPortal(
<div
ref={backdropRef}
className="profile-dialog-backdrop"
onClick={handleBackdropClick}
>
<div ref={dialogRef} className="profile-dialog">
className={`profile-dialog-backdrop ${openClass ? "open" : ""}`}
onClick={handleBackdropClick}>
<div className={`profile-dialog ${openClass ? "open" : ""}`}>
<div className="profile-dialog-content">
{/* Profile Picture */}
<div className="profile-picture-section">
<img
className="profile-picture"
@@ -429,7 +412,6 @@ export function ProfileDialog() {
)}
</div>
{/* Display Name */}
<div className={`username-section ${errors.display_name ? 'error' : ''}`}>
<input
className="username-input"
@@ -444,7 +426,6 @@ export function ProfileDialog() {
)}
</div>
{/* Online Status */}
{(currentData?.userId || currentData?.isOwnProfile) && (
<div className="online-status-section">
<OnlineStatus userId={currentData.userId || user.currentUser!.id} />
@@ -462,8 +443,6 @@ export function ProfileDialog() {
readOnly={!currentData.isOwnProfile}
placeholder="username" />
{/* Bio */}
{currentData.bio !== undefined && (
<Section
type="bio"
@@ -477,7 +456,6 @@ export function ProfileDialog() {
/>
)}
{/* Member Since */}
{currentData.memberSince && (
<Section
type="member-since"
@@ -491,7 +469,6 @@ export function ProfileDialog() {
</div>
</div>
{/* Save FAB */}
{currentData.isOwnProfile && (
<mdui-fab
icon="check"
@@ -501,7 +478,6 @@ export function ProfileDialog() {
/>
)}
{/* Hidden file input */}
<input
ref={fileInputRef}
type="file"
@@ -143,7 +143,6 @@ export function ChatMessages({ messages = [], children, isDm = false, onReplySel
{children}
</div>
<MaterialDialog
headline="Удалить сообщение?"
open={deleteDialogOpen}
+3 -4
View File
@@ -512,11 +512,10 @@ export function Message({ message, isAuthor, onContextMenu, onReactionClick, isD
</Quote>
)}
<div
className={`message-content ${isEmojiMessage ? "emoji-content" : ""} ${isSingleEmojiMessage ? "single-emoji-content" : ""}`}
<div
className={`message-content ${isEmojiMessage ? "emoji-content" : ""} ${isSingleEmojiMessage ? "single-emoji-content" : ""}`}
dangerouslySetInnerHTML={formattedMessage}
onClick={handleLinkClick}
/>
onClick={handleLinkClick} />
{message.files && message.files.length > 0 && (
<mdui-list className="message-attachments">