import { useNavigate } from "react-router-dom";
import { useState, type ReactNode } from "react";
import styles from "@/pages/home/home.module.scss";
import useDownloadAppScreen from "@/core/hooks/useDownloadAppScreen";
import { MaterialButton, MaterialIcon, MaterialIconButton, MaterialList, MaterialListItem } from "@/utils/material";
import generalChatScreenshot from "@/images/screenshots/general-chat.png";
import dmScreenshot from "@/images/screenshots/dm.png";
import windowsIcon from "@/images/windows.svg";
import linuxIcon from "@/images/linux.svg";
import macIcon from "@/images/mac.svg";
import { HomeHeader } from "@/pages/home/HomeHeader";
import { HomeFooter } from "@/pages/home/HomeFooter";
import { SplitButton } from "@/core/components/SplitButton";
import { DownloadDialog } from "@/pages/home/DownloadDialog";
import { OS_CONFIG, ALL_OS, detectOs, type DownloadOs } from "@/pages/home/os";
interface FeatureSectionProps {
title: ReactNode;
children: ReactNode;
screenshot: string;
right?: boolean;
}
function FeatureSection({
title,
children,
screenshot,
right = false,
}: FeatureSectionProps) {
const featureText = (
);
const featureScreenshot = (
)
return (
{right ? <>{featureText}{featureScreenshot}> : <>{featureScreenshot}{featureText}>}
)
}
export default function HomePage() {
const navigate = useNavigate();
const { isMobile } = useDownloadAppScreen();
const [dialogOpen, setDialogOpen] = useState(false);
const [dialogOs, setDialogOs] = useState(() => detectOs());
const [menuOpen, setMenuOpen] = useState(false);
const triggerDownload = (os: DownloadOs): boolean => {
if (typeof document === "undefined") {
return false;
}
setDialogOs(os);
setDialogOpen(true);
const link = document.createElement("a");
link.href = `/api/download/${os}`;
link.download = "";
link.style.display = "none";
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
return true;
};
const getButtonVariant = (os: DownloadOs): "filled" | "tonal" | "outlined" => {
const detectedOs = detectOs();
if (os === detectedOs) return "filled";
if (!isMobile && ["windows", "linux", "macos"].includes(os)) return "tonal";
if (isMobile && (os === "android" || os === "ios") && os !== detectedOs) return "tonal";
return "outlined";
};
return (
FromChat
100% бесплатный и открытый мессенджер. Поддерживает self-hosted установку на своём сервере.
{isMobile ? null : (
navigate("/auth?mode=login")}
icon="devices"
>
Открыть веб-версию
)}
triggerDownload(detectOs())}
menuOpen={menuOpen}
onMenuOpen={setMenuOpen}
menu={(
{ALL_OS.map((os) => (
{
if (triggerDownload(os)) setMenuOpen(false);
}}
>
{["windows", "linux", "macos"].includes(os) && (
)}
))}
)}
/>
Общий чат>}
screenshot={generalChatScreenshot}
right
>
Открытый форум для всех пользователей сервера. Пишите сообщения, делитесь файлами и общайтесь в реальном времени.
Личные сообщения>}
screenshot={dmScreenshot}>
Общайтесь с одним человеком в личной переписке.
Скачайте приложение
Настольное приложение с уведомлениями и автономной работой
или мобильное приложение для Android и iOS.
| Платформа |
Описание |
|
{ALL_OS.map((os) => (
|
{["windows", "linux", "macos"].includes(os) ? (
) : (
)}
{OS_CONFIG[os].label}
|
{OS_CONFIG[os].description}
|
triggerDownload(os)}
>
Скачать
triggerDownload(os)}
title={`Скачать ${OS_CONFIG[os].label}`}
/>
|
))}
Готовы начать общение?
Создайте аккаунт за минуту. Общайтесь в общем чате, ведите личную переписку
или звоните — всё бесплатно и с открытым кодом.
{isMobile ? (
navigate("/download-app")}>
Скачать приложение
) : (
<>
navigate("/register")}>
Создать аккаунт
navigate("/login")}>
Войти
>
)}
);
}