diff --git a/frontend/src/auth.ts b/frontend/src/auth.ts
index d6c1bd6..d869a72 100644
--- a/frontend/src/auth.ts
+++ b/frontend/src/auth.ts
@@ -1,4 +1,4 @@
-import { loadMessages } from "./main";
+import { loadMessages } from "./chat";
import type { Headers, ErrorResponse, User, LoginResponse, LoginRequest, RegisterRequest } from "./types";
import { API_BASE_URL } from "./config";
diff --git a/frontend/src/chat.ts b/frontend/src/chat.ts
new file mode 100644
index 0000000..1c71fc8
--- /dev/null
+++ b/frontend/src/chat.ts
@@ -0,0 +1,111 @@
+import { getAuthHeaders, currentUser, authToken } from "./auth";
+import { API_BASE_URL } from "./config";
+import { websocket } from "./websocket";
+import type { Message, Messages, WebSocketMessage } from "./types";
+import { formatTime } from "./utils";
+
+
+export function addMessage(message: Message, isAuthor: boolean) {
+ const messagesContainer = document.querySelector('.chat-messages') as HTMLElement;
+ const messageDiv = document.createElement('div');
+ messageDiv.classList.add("message");
+ if (isAuthor) {
+ messageDiv.classList.add("sent");
+ } else {
+ messageDiv.classList.add("received");
+ }
+ messageDiv.dataset.id = `${message.id}`;
+
+ const messageInner = document.createElement('div');
+ messageInner.classList.add('message-inner');
+
+ if (!isAuthor) {
+ const usernameDiv = document.createElement('div');
+ usernameDiv.classList.add('message-username');
+ usernameDiv.textContent = message.username;
+ messageInner.appendChild(usernameDiv);
+ }
+
+ const contentDiv = document.createElement('div');
+ contentDiv.textContent = message.content;
+ messageInner.appendChild(contentDiv);
+
+ const timeDiv = document.createElement('div');
+ timeDiv.classList.add('message-time');
+ timeDiv.textContent = formatTime(message.timestamp);
+
+ if (isAuthor && message.is_read) {
+ const checkIcon = document.createElement('span');
+ checkIcon.classList.add("material-symbols", "outlined");
+ timeDiv.appendChild(checkIcon);
+ }
+
+ messageInner.appendChild(timeDiv);
+ messageDiv.appendChild(messageInner);
+ messagesContainer.appendChild(messageDiv);
+
+ // Прокрутка к новому сообщению
+ messagesContainer.scrollTop = messagesContainer.scrollHeight;
+}
+
+export function loadMessages() {
+ fetch(`${API_BASE_URL}/get_messages`, {
+ headers: getAuthHeaders()
+ })
+ .then(response => response.json())
+ .then((data: Messages) => {
+ if (data.messages && data.messages.length > 0) {
+ const messagesContainer = document.querySelector('.chat-messages') as HTMLElement;
+
+ const lastMessage = messagesContainer.lastElementChild as HTMLElement
+ let lastMessageId: number = 0
+ if (lastMessage) {
+ lastMessageId = Number(lastMessage.dataset.id)
+ }
+
+ // Добавляем только новые сообщения
+ data.messages.forEach(msg => {
+ if (msg.id > lastMessageId) {
+ addMessage(msg, msg.username == currentUser!.username);
+ }
+ });
+ }
+ });
+}
+
+export function sendMessage() {
+ const input = document.querySelector('.message-input') as HTMLInputElement;
+ const message = input.value.trim();
+
+ if (message) {
+ const payload: WebSocketMessage = {
+ data: {
+ content: message
+ },
+ credentials: {
+ scheme: "Bearer",
+ credentials: authToken!
+ },
+ type: "sendMessage"
+ }
+
+ let callback: ((e: MessageEvent) => void) | null = null
+ callback = (e) => {
+ websocket.removeEventListener("message", callback!);
+ const response: WebSocketMessage = JSON.parse(e.data)
+ console.log(response)
+ if (!response.error) {
+ input.value = "";
+ }
+ }
+ websocket.addEventListener("message", callback);
+
+ websocket.send(JSON.stringify(payload));
+ }
+}
+
+
+document.getElementById('message-form')!.addEventListener('submit', (e) => {
+ e.preventDefault();
+ sendMessage();
+});
\ No newline at end of file
diff --git a/frontend/src/images/logotip.png b/frontend/src/images/logo.png
similarity index 100%
rename from frontend/src/images/logotip.png
rename to frontend/src/images/logo.png
diff --git a/frontend/src/init.ts b/frontend/src/init.ts
new file mode 100644
index 0000000..87305c2
--- /dev/null
+++ b/frontend/src/init.ts
@@ -0,0 +1,7 @@
+import { showLogin } from "./auth";
+import { PRODUCT_NAME } from "./config";
+
+showLogin();
+
+document.getElementById("productname")!.textContent = PRODUCT_NAME;
+document.title = PRODUCT_NAME;
\ No newline at end of file
diff --git a/frontend/src/leftpanel.ts b/frontend/src/leftpanel.ts
new file mode 100644
index 0000000..9115422
--- /dev/null
+++ b/frontend/src/leftpanel.ts
@@ -0,0 +1,36 @@
+import type { Dialog } from "mdui/components/dialog";
+
+// сварачивание и разворачивание чата
+const but = document.getElementById('chat-recrol')!;
+const but_list1 = document.getElementById('chat1but')!;
+const but_list2 = document.getElementById('chat1but2')!;
+const cont1 = document.getElementById('conteinerchat')!;
+const namechat = document.getElementById('namechat')!;
+
+but.addEventListener('click', () => {
+ but.style.display = 'none';
+ cont1.style.display = 'none';
+});
+but_list1.addEventListener('click', () => {
+ but.style.display = 'flex';
+ cont1.style.display = 'flex';
+ namechat.textContent = 'общий чат';
+});
+but_list2.addEventListener('click', () => {
+ but.style.display = 'flex';
+ cont1.style.display = 'flex';
+ namechat.textContent = 'общий чат 2';
+});
+
+// открытие профиля
+const butprofile = document.getElementById('profbut')!;
+const dialog = document.getElementById("profile-dialog") as Dialog;
+const dialogClose = document.getElementById("profile-dialog-close")!;
+
+butprofile.addEventListener('click', () => {
+ dialog.open = true;
+});
+
+dialogClose.addEventListener("click", () => {
+ dialog.open = false;
+});
\ No newline at end of file
diff --git a/frontend/src/main.ts b/frontend/src/main.ts
index 06b5181..ce8bbf8 100644
--- a/frontend/src/main.ts
+++ b/frontend/src/main.ts
@@ -1,187 +1,8 @@
import './css/style.scss';
import "mdui/mdui.css";
-import { showLogin, getAuthHeaders, authToken, currentUser } from './auth';
-import { API_BASE_URL, API_FULL_BASE_URL, PRODUCT_NAME } from './config';
-import type { Message, Messages, WebSocketMessage } from './types';
+
import "./links";
import "./material";
-import type { Dialog } from 'mdui/components/dialog.js';
-
-const websocket = new WebSocket(`ws://${API_FULL_BASE_URL}/chat/ws`);
-
-
-// Функция для форматирования времени
-function formatTime(dateString: string) {
- const date = new Date(dateString);
- let hours = date.getHours();
- let minutes = date.getMinutes();
- const hoursString = hours < 10 ? '0' + hours : hours;
- const minutesString = minutes < 10 ? '0' + minutes : minutes;
- return hoursString + ':' + minutesString;
-}
-
-// Добавление нового сообщения в чат
-export function addMessage(message: Message, isAuthor: boolean) {
- const messagesContainer = document.querySelector('.chat-messages') as HTMLElement;
- const messageDiv = document.createElement('div');
- messageDiv.classList.add("message");
- if (isAuthor) {
- messageDiv.classList.add("sent");
- } else {
- messageDiv.classList.add("received");
- }
- messageDiv.dataset.id = `${message.id}`;
-
- const messageInner = document.createElement('div');
- messageInner.classList.add('message-inner');
-
- if (!isAuthor) {
- const usernameDiv = document.createElement('div');
- usernameDiv.classList.add('message-username');
- usernameDiv.textContent = message.username;
- messageInner.appendChild(usernameDiv);
- }
-
- const contentDiv = document.createElement('div');
- contentDiv.textContent = message.content;
- messageInner.appendChild(contentDiv);
-
- const timeDiv = document.createElement('div');
- timeDiv.classList.add('message-time');
- timeDiv.textContent = formatTime(message.timestamp);
-
- if (isAuthor && message.is_read) {
- const checkIcon = document.createElement('span');
- checkIcon.classList.add("material-symbols", "outlined");
- timeDiv.appendChild(checkIcon);
- }
-
- messageInner.appendChild(timeDiv);
- messageDiv.appendChild(messageInner);
- messagesContainer.appendChild(messageDiv);
-
- // Прокрутка к новому сообщению
- messagesContainer.scrollTop = messagesContainer.scrollHeight;
-}
-
-// Загрузка сообщений
-export function loadMessages() {
- fetch(`${API_BASE_URL}/get_messages`, {
- headers: getAuthHeaders()
- })
- .then(response => response.json())
- .then((data: Messages) => {
- if (data.messages && data.messages.length > 0) {
- const messagesContainer = document.querySelector('.chat-messages') as HTMLElement;
-
- const lastMessage = messagesContainer.lastElementChild as HTMLElement
- let lastMessageId: number = 0
- if (lastMessage) {
- lastMessageId = Number(lastMessage.dataset.id)
- }
-
- // Добавляем только новые сообщения
- data.messages.forEach(msg => {
- if (msg.id > lastMessageId) {
- addMessage(msg, msg.username == currentUser!.username);
- }
- });
- }
- });
-}
-
-// Отправка сообщения
-export function sendMessage() {
- const input = document.querySelector('.message-input') as HTMLInputElement;
- const message = input.value.trim();
-
- if (message) {
- const payload: WebSocketMessage = {
- data: {
- content: message
- },
- credentials: {
- scheme: "Bearer",
- credentials: authToken!
- },
- type: "sendMessage"
- }
-
- let callback: ((e: MessageEvent) => void) | null = null
- callback = (e) => {
- websocket.removeEventListener("message", callback!);
- const response: WebSocketMessage = JSON.parse(e.data)
- console.log(response)
- if (!response.error) {
- input.value = "";
- }
- }
- websocket.addEventListener("message", callback);
-
- websocket.send(JSON.stringify(payload));
- }
-}
-
-
-// --------------
-// Initialization
-// --------------
-
-websocket.addEventListener("message", (e) => {
- const message: WebSocketMessage = JSON.parse(e.data);
- switch (message.type) {
- case "newMessage": {
- const newMessage: Message = message.data;
- addMessage(newMessage, newMessage.username == currentUser!.username);
- break;
- }
- }
-});
-
-showLogin();
-
-document.getElementById('message-form')!.addEventListener('submit', (e) => {
- e.preventDefault();
- sendMessage();
-});
-
-document.getElementById("productname")!.textContent = PRODUCT_NAME;
-document.title = PRODUCT_NAME;
-
-
-// сварачивание и разворачивание чата
-const but = document.getElementById('chat-recrol')!;
-const but_list1 = document.getElementById('chat1but')!;
-const but_list2 = document.getElementById('chat1but2')!;
-const cont1 = document.getElementById('conteinerchat')!;
-const logout = document.getElementById('logouts')!;
-const namechat = document.getElementById('namechat')!;
-
-but.addEventListener('click',() => {
- but.style.display = 'none';
- cont1.style.display = 'none';
- logout.style.display = 'flex';
-});
-but_list1.addEventListener('click',() => {
- but.style.display = 'flex';
- cont1.style.display = 'flex';
- namechat.textContent = 'общий чат';
-});
-but_list2.addEventListener('click',() => {
- but.style.display = 'flex';
- cont1.style.display = 'flex';
- namechat.textContent = 'общий чат 2';
-});
-
-// открытие профиля
-const butprofile = document.getElementById('profbut')!;
-const dialog = document.getElementById("profile-dialog") as Dialog;
-const dialogClose = document.getElementById("profile-dialog-close")!;
-
-butprofile.addEventListener('click', () => {
- dialog.open = true;
-});
-
-dialogClose.addEventListener("click", () => {
- dialog.open = false;
-});
\ No newline at end of file
+import "./chat";
+import "./leftpanel";
+import "./init";
\ No newline at end of file
diff --git a/frontend/src/material.ts b/frontend/src/material.ts
index 3d4a75d..e6d3398 100644
--- a/frontend/src/material.ts
+++ b/frontend/src/material.ts
@@ -1,13 +1,13 @@
-import 'mdui/components/tabs.js';
-import 'mdui/components/tab.js';
-import 'mdui/components/tab-panel.js';
-import 'mdui/components/list.js';
-import 'mdui/components/list-item.js';
-import 'mdui/components/bottom-app-bar.js';
-import 'mdui/components/button-icon.js';
-import 'mdui/components/fab.js';
-import 'mdui/components/dialog.js';
-import 'mdui/components/button.js';
+import 'mdui/components/tabs';
+import 'mdui/components/tab';
+import 'mdui/components/tab-panel';
+import 'mdui/components/list';
+import 'mdui/components/list-item';
+import 'mdui/components/bottom-app-bar';
+import 'mdui/components/button-icon';
+import 'mdui/components/fab';
+import 'mdui/components/dialog';
+import 'mdui/components/button';
import { setColorScheme } from 'mdui/functions/setColorScheme.js';
diff --git a/frontend/src/utils.ts b/frontend/src/utils.ts
new file mode 100644
index 0000000..cbc4a7a
--- /dev/null
+++ b/frontend/src/utils.ts
@@ -0,0 +1,8 @@
+export function formatTime(dateString: string) {
+ const date = new Date(dateString);
+ let hours = date.getHours();
+ let minutes = date.getMinutes();
+ const hoursString = hours < 10 ? '0' + hours : hours;
+ const minutesString = minutes < 10 ? '0' + minutes : minutes;
+ return hoursString + ':' + minutesString;
+}
\ No newline at end of file
diff --git a/frontend/src/websocket.ts b/frontend/src/websocket.ts
new file mode 100644
index 0000000..1ce731f
--- /dev/null
+++ b/frontend/src/websocket.ts
@@ -0,0 +1,22 @@
+import { currentUser } from "./auth";
+import { addMessage } from "./chat";
+import { API_FULL_BASE_URL } from "./config";
+import type { WebSocketMessage, Message } from "./types";
+
+
+export const websocket = new WebSocket(`ws://${API_FULL_BASE_URL}/chat/ws`);
+
+// --------------
+// Initialization
+// --------------
+
+websocket.addEventListener("message", (e) => {
+ const message: WebSocketMessage = JSON.parse(e.data);
+ switch (message.type) {
+ case "newMessage": {
+ const newMessage: Message = message.data;
+ addMessage(newMessage, newMessage.username == currentUser!.username);
+ break;
+ }
+ }
+});
\ No newline at end of file