Полный рефакторинг сервера и клиента, голосовые сообщения, аудио/видео, Docker
Сервер: - Вынесена конфигурация в server/config.js (порт, размер файла из env) - Вынесена аутентификация в server/auth.js (загрузка users.json, authenticate()) - Вынесено управление соединениями в server/clients.js (createJsonSender, broadcast, validateFile) - server/server.js стал точкой входа — минимальный код Клиент: - Вынесены хуки: hooks/useWebSocket.js (WebSocket + auth), hooks/useChatMessages.js (сообщения + уведомления) - Вынесены утилиты: utils/blob.js (base64 → Blob URL), utils/linkify.jsx (URL → ссылки), utils/notify.js (звук + favicon) Новые функции: - VoiceRecorder — запись голоса через MediaRecorder, отправка как файл - Аудио/видео плеер в Message (audio/*, video/* с controls) - URL linkification — http/https ссылки автоматически кликабельны - Звуковое уведомление (Web Audio API) при сообщении на неактивной вкладке - Красная точка на favicon при непрочитанных сообщениях Инфраструктура: - docker-entrypoint.sh: авто-перезапуск Node.js сервера при падении - Обновлён README.md: новая структура проекта, список функций, примеры - Кастомный тонкий скроллбар в Message.css
This commit is contained in:
@@ -0,0 +1,23 @@
|
||||
const URL_REGEX = /(https?:\/\/[^\s<]+[^\s<.,!?)}\]"'\\])/gi;
|
||||
|
||||
export function linkifyText(text) {
|
||||
const parts = [];
|
||||
let lastIndex = 0;
|
||||
let match;
|
||||
URL_REGEX.lastIndex = 0;
|
||||
while ((match = URL_REGEX.exec(text)) !== null) {
|
||||
if (match.index > lastIndex) {
|
||||
parts.push(text.slice(lastIndex, match.index));
|
||||
}
|
||||
parts.push(
|
||||
<a key={match.index} href={match[0]} target="_blank" rel="noopener noreferrer">
|
||||
{match[0]}
|
||||
</a>
|
||||
);
|
||||
lastIndex = match.index + match[0].length;
|
||||
}
|
||||
if (lastIndex < text.length) {
|
||||
parts.push(text.slice(lastIndex));
|
||||
}
|
||||
return parts.length ? parts : text;
|
||||
}
|
||||
Reference in New Issue
Block a user