mirror of
https://github.com/fromchat-messenger/web.git
synced 2026-09-22 19:15:08 +03:00
Modularize and fix code
This commit is contained in:
+11
-5
@@ -1,17 +1,20 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="ru" class="mdui-theme-dark">
|
<html lang="ru" class="mdui-theme-dark">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<title>Loading...</title>
|
<title>Loading...</title>
|
||||||
<link rel="icon" href="./src/images/logotip.png" viewBox='0 0 100% 100%'>
|
<link rel="icon" href="./src/images/logo.png" />
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<!-- Login Form -->
|
<!-- Login Form -->
|
||||||
<div id="login-form" class="auth-container">
|
<div id="login-form" class="auth-container">
|
||||||
<div class="auth-card fade-in">
|
<div class="auth-card fade-in">
|
||||||
<div class="auth-header">
|
<div class="auth-header">
|
||||||
<h2><span class="material-symbols filled large">login</span> Добро пожаловать!</h2>
|
<h2>
|
||||||
|
<span class="material-symbols filled large">login</span>
|
||||||
|
Добро пожаловать!
|
||||||
|
</h2>
|
||||||
<p>Войдите в свой аккаунт</p>
|
<p>Войдите в свой аккаунт</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="auth-body">
|
<div class="auth-body">
|
||||||
@@ -40,7 +43,10 @@
|
|||||||
<div id="register-form" class="auth-container" style="display: none;">
|
<div id="register-form" class="auth-container" style="display: none;">
|
||||||
<div class="auth-card fade-in">
|
<div class="auth-card fade-in">
|
||||||
<div class="auth-header">
|
<div class="auth-header">
|
||||||
<h2><span class="material-symbols filled large">person_add</span> Регистрация</h2>
|
<h2>
|
||||||
|
<span class="material-symbols filled large">person_add</span>
|
||||||
|
Регистрация
|
||||||
|
</h2>
|
||||||
<p>Создайте новый аккаунт</p>
|
<p>Создайте новый аккаунт</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="auth-body">
|
<div class="auth-body">
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { loadMessages } from "./main";
|
import { loadMessages } from "./chat";
|
||||||
import type { Headers, ErrorResponse, User, LoginResponse, LoginRequest, RegisterRequest } from "./types";
|
import type { Headers, ErrorResponse, User, LoginResponse, LoginRequest, RegisterRequest } from "./types";
|
||||||
import { API_BASE_URL } from "./config";
|
import { API_BASE_URL } from "./config";
|
||||||
|
|
||||||
|
|||||||
@@ -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();
|
||||||
|
});
|
||||||
|
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 22 KiB |
@@ -0,0 +1,7 @@
|
|||||||
|
import { showLogin } from "./auth";
|
||||||
|
import { PRODUCT_NAME } from "./config";
|
||||||
|
|
||||||
|
showLogin();
|
||||||
|
|
||||||
|
document.getElementById("productname")!.textContent = PRODUCT_NAME;
|
||||||
|
document.title = PRODUCT_NAME;
|
||||||
@@ -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;
|
||||||
|
});
|
||||||
+4
-183
@@ -1,187 +1,8 @@
|
|||||||
import './css/style.scss';
|
import './css/style.scss';
|
||||||
import "mdui/mdui.css";
|
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 "./links";
|
||||||
import "./material";
|
import "./material";
|
||||||
import type { Dialog } from 'mdui/components/dialog.js';
|
import "./chat";
|
||||||
|
import "./leftpanel";
|
||||||
const websocket = new WebSocket(`ws://${API_FULL_BASE_URL}/chat/ws`);
|
import "./init";
|
||||||
|
|
||||||
|
|
||||||
// Функция для форматирования времени
|
|
||||||
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;
|
|
||||||
});
|
|
||||||
+10
-10
@@ -1,13 +1,13 @@
|
|||||||
import 'mdui/components/tabs.js';
|
import 'mdui/components/tabs';
|
||||||
import 'mdui/components/tab.js';
|
import 'mdui/components/tab';
|
||||||
import 'mdui/components/tab-panel.js';
|
import 'mdui/components/tab-panel';
|
||||||
import 'mdui/components/list.js';
|
import 'mdui/components/list';
|
||||||
import 'mdui/components/list-item.js';
|
import 'mdui/components/list-item';
|
||||||
import 'mdui/components/bottom-app-bar.js';
|
import 'mdui/components/bottom-app-bar';
|
||||||
import 'mdui/components/button-icon.js';
|
import 'mdui/components/button-icon';
|
||||||
import 'mdui/components/fab.js';
|
import 'mdui/components/fab';
|
||||||
import 'mdui/components/dialog.js';
|
import 'mdui/components/dialog';
|
||||||
import 'mdui/components/button.js';
|
import 'mdui/components/button';
|
||||||
|
|
||||||
import { setColorScheme } from 'mdui/functions/setColorScheme.js';
|
import { setColorScheme } from 'mdui/functions/setColorScheme.js';
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user