Files
desktop/app/views/Main/Main.tsx

207 lines
9.0 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { Alert, Box, Button, Divider, Flex, Overlay } from "@mantine/core";
import { useEffect, useState } from "react";
import { Route, Routes, useLocation, useNavigate } from "react-router-dom";
import { Profile } from "@/app/views/Profile/Profile";
import { useRosettaColors } from "@/app/hooks/useRosettaColors";
import { DialogPreview } from "@/app/views/DialogPreview/DialogPreview";
import { Theme } from "../Theme/Theme";
import { Safety } from "../Safety/Safety";
import { Backup } from "../Backup/Backup";
import { Chat } from "../Chat/Chat";
import { PrivateView } from "@/app/components/PrivateView/PrivateView";
import { useDialogFiber } from "@/app/providers/DialogProvider/useDialogFiber";
import { Update } from "../Update/Update";
import { useRosettaBreakpoints } from "@/app/hooks/useRosettaBreakpoints";
import { Dialogs } from "../Dialogs/Dialogs";
import { DialogsPanel } from "@/app/components/DialogsPanel/DialogsPanel";
import { useViewPanelsState, ViewPanelsState } from "@/app/hooks/useViewPanelsState";
import { TransportProvider } from "@/app/providers/TransportProvider/TransportProvider";
import { useDebouncedCallback } from "@mantine/hooks";
import { SystemAccountProvider } from "@/app/providers/SystemAccountsProvider/SystemAccountsProvider";
import { CreateGroup } from "../CreateGroup/CreateGroup";
import { GroupInfo } from "../GroupInfo/GroupInfo";
import { GroupEncryption } from "../GroupEncryption/GroupEncryption";
import useWindow from "@/app/hooks/useWindow";
import { usePublicKey } from "@/app/providers/AccountProvider/usePublicKey";
import { useDatabase } from "@/app/providers/DatabaseProvider/useDatabase";
import { useMemoryClean } from "@/app/providers/MemoryProvider/useMemoryClean";
import { useAccountProvider } from "@/app/providers/AccountProvider/useAccountProvider";
import { useLogout } from "@/app/providers/AccountProvider/useLogout";
import { useUpdateMessage } from "@/app/hooks/useUpdateMessage";
import { useDeviceMessage } from "@/app/hooks/useDeviceMessage";
import { UpdateProvider } from "@/app/providers/UpdateProvider/UpdateProvider";
import { useSynchronize } from "@/app/providers/DialogProvider/useSynchronize";
export function Main() {
const { mainColor, borderColor } = useRosettaColors();
const { lg } = useRosettaBreakpoints();
const location = useLocation();
const [viewState, setViewState] = useViewPanelsState();
/**
* Слушаем диалоги в пассивном режиме
*/
useDialogFiber();
/**
* Отправляем сообщение об обновлении,
* если версия приложения изменилась
*/
useUpdateMessage();
/**
* Слушаем все сообщения на присоединение новых устройств
* к нашему аккаунту
*/
useDeviceMessage();
/**
* Синхронизируем сообщения при подключении
*/
useSynchronize();
const { setSize, setResizeble } = useWindow();
/**
* Operation: OLD PUBLIC KEY MIGRATION
*/
const publicKey = usePublicKey();
const [oldPublicKey, setOldPublicKey] = useState(false);
const { runQuery } = useDatabase();
const navigate = useNavigate();
const memClean = useMemoryClean();
const { setAccounts } = useAccountProvider();
const logout = useLogout();
useEffect(() => {
if (publicKey.length > 80) {
/**
* Old public keys
*/
setOldPublicKey(true);
}
}, [publicKey]);
const dropAccountsAndMessages = async () => {
localStorage.clear();
await runQuery("DELETE FROM accounts");
await runQuery("DELETE FROM messages");
await runQuery("DELETE FROM dialogs");
memClean();
setAccounts([]);
logout();
setTimeout(() => {
navigate("/");
}, 500);
}
useEffect(() => {
let { width, height } = getWindowSavedSize();
setSize(width, height);
setResizeble(true);
const sizeListener = () => {
saveSize(window.innerWidth, window.innerHeight);
};
window.addEventListener("resize", sizeListener);
return () => {
window.removeEventListener("resize", sizeListener);
}
}, []);
useEffect(() => {
if (lg && viewState == ViewPanelsState.DIALOGS_PANEL_ONLY) {
setViewState(ViewPanelsState.DIALOGS_PANEL_SHOW);
return;
}
if (!lg && location.pathname != '/main') {
setViewState(ViewPanelsState.DIALOGS_PANEL_HIDE);
return;
}
if (!lg && location.pathname == '/main' && window.innerWidth < 770) {
setViewState(ViewPanelsState.DIALOGS_PANEL_ONLY);
return;
}
if (!lg) {
setViewState(ViewPanelsState.DIALOGS_PANEL_HIDE);
return;
}
if (lg) {
setViewState(ViewPanelsState.DIALOGS_PANEL_SHOW);
return;
}
}, [lg, location]);
const saveSize = useDebouncedCallback((w: number, h: number) => {
localStorage.setItem("windowWidth", w.toString());
localStorage.setItem("windowHeight", h.toString());
}, 1000);
const getWindowSavedSize = () => {
const savedWidth = localStorage.getItem("windowWidth");
const savedHeight = localStorage.getItem("windowHeight");
return {
width: savedWidth ? parseInt(savedWidth) : window.innerWidth,
height: savedHeight ? parseInt(savedHeight) : window.innerHeight
}
}
return (
<PrivateView>
<SystemAccountProvider>
<TransportProvider>
<UpdateProvider>
<Flex direction={'row'} style={{
height: '100%',
width: '100vw',
}}>
<div style={{
display: viewState != ViewPanelsState.DIALOGS_PANEL_HIDE ? 'block' : 'none',
width: viewState == ViewPanelsState.DIALOGS_PANEL_ONLY ? '100%' : '300px',
}}>
<DialogsPanel></DialogsPanel>
</div>
<Divider color={borderColor} orientation={'vertical'}></Divider>
{viewState != ViewPanelsState.DIALOGS_PANEL_ONLY && <Box
bg={mainColor}
style={{
flexGrow: 1,
height: 'calc(100vh - 27px)',
width: `calc(100% - 300px)`,
minWidth: 0
}}
>
<Routes>
<Route path={'/chat/:id'} element={<Chat />}></Route>
<Route path={'/profile/:id'} element={<Profile />}></Route>
<Route path={'/'} element={<DialogPreview />}></Route>
<Route path={'/theme'} element={<Theme />}></Route>
<Route path={'/safety'} element={<Safety />}></Route>
<Route path={'/update'} element={<Update />}></Route>
<Route path={'/backup'} element={<Backup />}></Route>
<Route path={'/dialogs'} element={<Dialogs />}></Route>
<Route path={'/newgroup'} element={<CreateGroup />}></Route>
<Route path={'/group/:id'} element={<GroupInfo />}></Route>
<Route path={'/groupencrypt/:key'} element={<GroupEncryption />}></Route>
</Routes>
</Box>}
</Flex>
{oldPublicKey && (
<Overlay blur={8} color="#333">
<Flex direction={'column'} align={'center'} justify={'center'} h={'100%'}>
<Alert w={400} variant="filled" color="red" title="Old account">
Your account uses an old format public key which is no longer supported. Please create a new account to continue using the application.
<br></br>After press "OK" button, the application will close and remove all data.
</Alert>
<Button w={400} mt={'md'} color="red" onClick={dropAccountsAndMessages}>OK</Button>
</Flex>
</Overlay>
)}
</UpdateProvider>
</TransportProvider>
</SystemAccountProvider>
</PrivateView>);
}