Implement fromchat.ru/@username and fromchat.ru/?u=userId links, mentions

This commit is contained in:
2025-10-20 21:12:40 +03:00
Unverified
parent 818b7c1b46
commit 97f19ce52b
6 changed files with 252 additions and 30 deletions
+62 -18
View File
@@ -1,10 +1,11 @@
import { BrowserRouter, Routes, Route } from "react-router-dom";
import { BrowserRouter, Routes, Route, useNavigate, matchRoutes, type RouteObject } from "react-router-dom";
import { ElectronTitleBar } from "./Electron";
import { useAppState } from "./pages/chat/state";
import { useEffect, useState, lazy } from "react";
import ProtectedRoute from "./pages/ProtectedRoute";
import NotFoundPage from "./pages/not-found/NotFoundPage";
import DownloadAppPage from "./pages/download-app/DownloadAppPage";
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";
// Lazy load route components
const HomePage = lazy(() => import("./pages/home/HomePage"));
@@ -12,11 +13,63 @@ const LoginPage = lazy(() => import("./pages/auth/LoginPage"));
const RegisterPage = lazy(() => import("./pages/auth/RegisterPage"));
const ChatPage = lazy(() => import("./pages/chat/ui/ChatPage"));
const routeConfig: RouteObject[] = [
{ path: "/", element: <HomePage /> },
{ path: "/login", element: <LoginPage /> },
{ path: "/register", element: <RegisterPage /> },
{ path: "/download-app", element: <DownloadAppPage /> },
{
path: "/chat",
element: (
<ProtectedRoute>
<ChatPage />
</ProtectedRoute>
)
},
{ path: "*", element: <SmartCatchAll /> }
];
function SmartCatchAll() {
const navigate = useNavigate();
const [showNotFound, setShowNotFound] = useState(false);
function isValidRoute(path: string): boolean {
const validRoutes = routeConfig.filter(route => route.path !== "*");
const matches = matchRoutes(validRoutes, path);
return Boolean(matches && matches.length > 0);
}
useEffect(() => {
if (isValidRoute(location.pathname)) {
setShowNotFound(false);
return;
}
// Check if it's a profile link
const profileInfo = parseProfileLink(); // no url specified intentionally to let it use the current url
if (profileInfo) {
setShowNotFound(false);
navigate("/chat", {
replace: true,
state: { profileInfo }
});
} else {
setShowNotFound(true);
}
}, [navigate]);
// Show 404 page
if (showNotFound) {
return <NotFoundPage />;
}
}
export default function App() {
const { restoreUserFromStorage } = useAppState();
const [authReady, setAuthReady] = useState(false);
// Restore user from localStorage on app initialization
useEffect(() => {
restoreUserFromStorage().finally(() => {
setAuthReady(true);
@@ -28,18 +81,9 @@ export default function App() {
<ElectronTitleBar />
<div id="main-wrapper">
<Routes>
<Route path="/" element={<HomePage />} />
<Route path="/login" element={<LoginPage />} />
<Route path="/register" element={<RegisterPage />} />
<Route path="/download-app" element={<DownloadAppPage />} />
<Route path="/">
<Route path="chat" element={
<ProtectedRoute>
<ChatPage />
</ProtectedRoute>
} />
</Route>
<Route path="*" element={<NotFoundPage />} />
{routeConfig.map((route, index) => (
<Route key={index} path={route.path} element={route.element} />
))}
</Routes>
</div>
</BrowserRouter>