отправка сообщений, пул доступных чатов. починил textarea

This commit is contained in:
UNIKNOW 2024-04-30 14:31:18 +04:00
parent 5327139049
commit 23c6e396f4
14 changed files with 737 additions and 659 deletions

23
package-lock.json generated
View file

@ -14,6 +14,7 @@
"socket.io": "^4.7.4",
"socket.io-client": "^4.7.4",
"svelte-routing": "^2.12.0",
"svelte-select": "^5.8.3",
"websocket": "^1.0.34",
"ws": "^8.16.0"
},
@ -648,7 +649,6 @@
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.6.0.tgz",
"integrity": "sha512-PcF++MykgmTj3CIyOQbKA/hDzOAiqI3mhuoN44WRCopIs1sgoDoU4oty4Jtqaj/y3oDU6fnVSm4QG0a3t5i0+g==",
"dev": true,
"dependencies": {
"@floating-ui/utils": "^0.2.1"
}
@ -657,7 +657,6 @@
"version": "1.6.1",
"resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.6.1.tgz",
"integrity": "sha512-iA8qE43/H5iGozC3W0YSnVSW42Vh522yyM1gj+BqRwVsTNOyr231PsXDaV04yT39PsO0QL2QpbI/M0ZaLUQgRQ==",
"dev": true,
"dependencies": {
"@floating-ui/core": "^1.6.0",
"@floating-ui/utils": "^0.2.1"
@ -666,8 +665,7 @@
"node_modules/@floating-ui/utils": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.1.tgz",
"integrity": "sha512-9TANp6GPoMtYzQdt54kfAyMmz1+osLlXdg2ENroU7zzrtflTLrrC/lgrIfaSe+Wu0b89GKccT7vxXA0MoAIO+Q==",
"dev": true
"integrity": "sha512-9TANp6GPoMtYzQdt54kfAyMmz1+osLlXdg2ENroU7zzrtflTLrrC/lgrIfaSe+Wu0b89GKccT7vxXA0MoAIO+Q=="
},
"node_modules/@isaacs/cliui": {
"version": "8.0.2",
@ -3428,6 +3426,15 @@
"node": ">=16"
}
},
"node_modules/svelte-floating-ui": {
"version": "1.5.8",
"resolved": "https://registry.npmjs.org/svelte-floating-ui/-/svelte-floating-ui-1.5.8.tgz",
"integrity": "sha512-dVvJhZ2bT+kQDHlE4Lep8t+sgEc0XD96fXLzAi2DDI2bsaegBbClxXVNMma0C2WsG+n9GJSYx292dTvA8CYRtw==",
"dependencies": {
"@floating-ui/core": "^1.5.0",
"@floating-ui/dom": "^1.5.3"
}
},
"node_modules/svelte-hmr": {
"version": "0.15.3",
"resolved": "https://registry.npmjs.org/svelte-hmr/-/svelte-hmr-0.15.3.tgz",
@ -3508,6 +3515,14 @@
"resolved": "https://registry.npmjs.org/svelte-routing/-/svelte-routing-2.12.0.tgz",
"integrity": "sha512-6i4Mncy4P2b7gD7+BOT9JzQvrfGfGXqFra8VXYU5//bpn6AzJ0PLEhH1E/KwY2AxleOiS/8Nm37MGuic2kn15A=="
},
"node_modules/svelte-select": {
"version": "5.8.3",
"resolved": "https://registry.npmjs.org/svelte-select/-/svelte-select-5.8.3.tgz",
"integrity": "sha512-nQsvflWmTCOZjssdrNptzfD1Ok45hHVMTL5IHay5DINk7dfu5Er+8KsVJnZMJdSircqtR0YlT4YkCFlxOUhVPA==",
"dependencies": {
"svelte-floating-ui": "1.5.8"
}
},
"node_modules/svelte-time": {
"version": "0.8.2",
"resolved": "https://registry.npmjs.org/svelte-time/-/svelte-time-0.8.2.tgz",

View file

@ -39,6 +39,7 @@
"socket.io": "^4.7.4",
"socket.io-client": "^4.7.4",
"svelte-routing": "^2.12.0",
"svelte-select": "^5.8.3",
"websocket": "^1.0.34",
"ws": "^8.16.0"
}

View file

@ -1,7 +1,3 @@
@tailwind base;
@tailwind components;
@tailwind utilities;
@font-face {
font-family: 'Comfortaa';
src: url('./fonts/Comfortaa-VariableFont_wght.ttf') format('truetype');
@ -9,6 +5,5 @@
font-style: normal;
font-stretch: normal;
}
:root{
--fontColor: #FFFFFF;
}

View file

@ -9,7 +9,11 @@
<body data-sveltekit-preload-data="hover">
<div style="display: contents">%sveltekit.body%</div>
<style>
</body>
<style lang="scss">
:root{
--bg: #101010;
--gradient: linear-gradient(to bottom, #3C53FF, #7734AA);
@ -30,6 +34,93 @@
background-color: var(--bg);
}
* {
font-family: Comfortaa;
margin: 0;
}
h1,h2,h3,h4,h5,p{
color:var(--fontColor);
cursor: default;
}
select {
min-width: 50px;
width: 8rem;
display: flex;
justify-content: center;
text-align: center;
font-size: 24px;
font-weight: 300;
overflow: auto;
}
option {
background-color: var(--bg);
border: 0;
}
button{
text-shadow: 0 0 20px white;
font-size: 36px;
background: transparent;
border: 0;
height: 10%;
}
button,
select,
option {
cursor: pointer;
}
h1,
h3,
input,
select,
button,
textarea {
color: var(--fontColor);
}
h1 {
display: flex;
justify-content: center;
align-items: center;
text-shadow: 0 0 20px white;
font-size: 48px;
height: 10%;
}
h3 {
font-weight: 100;
font-size: 24px;
}
p {
font-size: 20px;
font-weight: 100;
}
.noise {
position: relative;
width: 100%;
height: 100%;
display: flex;
box-shadow: 4px 4px 11px rgba(#000000, 0.4);
border-radius: 15px;
}
.noise::before {
content: '';
background-image: url(../noise.gif);
opacity: 0.011;
width: 100%;
height: 100%;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
pointer-events: none;
border-radius: 15px;
}
</style>
</body>
</html>

85
src/lib/chat.js Normal file
View file

@ -0,0 +1,85 @@
import { FlyControls } from "three/examples/jsm/Addons.js";
export async function getLastMessages(){
const response = await fetch('http://localhost:8000/api/chat/get_some_messages/2?messages_loaded=0&messages_to_get=14',
{
method:'GET',
credentials:'include'
})
if(!response.ok)
{
console.log(response.status)
}
if(response.ok)
{
let msgMassive = await response.json();
let localTime
for(let i = 0; i< msgMassive.length;i++){
localTime = new Date(msgMassive[i].created_at)
msgMassive[i].created_at = localTime
}
msgMassive.reverse();
console.log(msgMassive)
return msgMassive
}
}
export async function MessagePicToUrl(messagePic){
console.log(messagePic)
const DataForm = new FormData();
DataForm.append('file', messagePic)
const respone = await fetch('http://localhost:8000/api/images/upload_image',
{
method:"POST",
body:DataForm
})
if(!respone.ok)
console.log("ошибка", respone.status)
if(respone.ok){
const data = await respone.json();
console.log("картинка принята")
return data.image_url;
}
}
export async function getAllChats(){
const response = await fetch(`http://localhost:8000/api/chat`,
{
method:"GET",
credentials:'include'
})
if(response.ok){
return await response.json();
}
else{
console.log(response.status)
}
}
export async function getPinnedMsg(ID){
const response = await fetch(`http://localhost:8000/api/chat/pinned_messages/${ID}`,{
method:"GET",
credentials:'include'
})
if(response.ok){
return await response.json();
}
else{
console.log(response.status)
}
}

29
src/lib/login.js Normal file
View file

@ -0,0 +1,29 @@
export async function handleLogin(username, password) {
const response = await fetch('http://localhost:8000/api/users/login', {
method: 'POST',
credentials:'include',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify
({
email_or_username: username,
password: password
})
})
if(response.status === 200)
{
window.location.href = '/chatPage'
return ""
}
else if(response.status === 401)
{
return "Неправильный логин или пароль"
}
else{
console.log(response.status)
}
}

100
src/lib/register.js Normal file
View file

@ -0,0 +1,100 @@
export async function checkName(username) {
const response = await fetch('http://localhost:8000/api/users/check_existing_username', {
method:'POST',
credentials:"include",
headers:{
'Content-Type': 'application/json'
},
body: JSON.stringify({
"username": username
})
})
if(response.status === 200){
return ""
}
else if(response.status === 409){
let data = "ник занят"
return data
}
else if(response.status === 422){
let data = await response.json();
return data
}
else{
console.log(response.status)
}
}
export async function checkMail(mail) {
const response = await fetch('http://localhost:8000/api/users/check_existing_email', {
method:'POST',
credentials:"include",
headers:{
'Content-Type': 'application/json'
},
body: JSON.stringify({
"email": mail
})
})
if(response.status === 200){
return ""
}
else if(response.status === 409){
return "почта занята"
}
else if(response.status === 422){
return "не похоже на почту"
}
}
export async function VerificationEmail(Code){
const response = await fetch('http://localhost:8000/api/users/email_verification',{
method:'POST',
credentials:'include',
headers:{
'Content-Type' : 'application/json'
},
body: JSON.stringify({
"user_code": Code
})
})
if(response.status === 200){
window.location.href = '/'
return ""
}
else if(response.status === 422){
return "Неправильный код"
}
}
export async function handleRegister(username,password,email,date_of_birth){
const response = await fetch('http://localhost:8000/api/users/register',{
method:'POST',
credentials:"include",
headers:{
'Content-Type': 'application/json'
},
body: JSON.stringify({
"email": email,
"username": username,
"password": password,
"date_of_birth": date_of_birth
})
})
if(response.status === 201){
const data = await response.json();
console.log(data)
return data;
}
else if(response.status === 422){
console.log(response.status)
let data = "Validation Error"
return data
}
}

View file

@ -13,133 +13,8 @@ export async function UserCheck(){
else{
const data = await response.json();
return
}
}
export async function checkName(username) {
const response = await fetch('http://localhost:8000/api/users/check_existing_username', {
method:'POST',
credentials:"include",
headers:{
'Content-Type': 'application/json'
},
body: JSON.stringify({
"username": username
})
})
if(response.status === 200){
}
else if(response.status === 409){
let data = "ник занят"
return data
}
else if(response.status === 422){
let data = await response.json();
return data
}
}
export async function checkMail(mail) {
const response = await fetch('http://localhost:8000/api/users/check_existing_email', {
method:'POST',
credentials:"include",
headers:{
'Content-Type': 'application/json'
},
body: JSON.stringify({
"email": mail
})
})
if(response.status === 200){
}
else if(response.status === 409){
let data = "почта занята"
return data
}
else if(response.status === 422){
let data = "не похоже на почту"
return data
}
}
export async function VerificationEmail(Code){
const response = await fetch('http://localhost:8000/api/users/email_verification',{
method:'POST',
credentials:'include',
headers:{
'Content-Type' : 'application/json'
},
body: JSON.stringify({
"user_code": Code
})
})
if(response.status === 200){
window.location.href = '/'
return ""
}
else if(response.status === 422){
return "Неправильный код"
}
}
export async function handleRegister(username,password,email,date_of_birth){
const response = await fetch('http://localhost:8000/api/users/register',{
method:'POST',
credentials:"include",
headers:{
'Content-Type': 'application/json'
},
body: JSON.stringify({
"email": email,
"username": username,
"password": password,
"date_of_birth": date_of_birth
})
})
if(response.status === 201){
const data = await response.json();
console.log(data)
return data;
}
else if(response.status === 422){
console.log(response.status)
let data = "Validation Error"
return data
}
}
export async function handleLogin(username, password) {
const response = await fetch('http://localhost:8000/api/users/login', {
method: 'POST',
credentials:'include',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify
({
email_or_username: username,
password: password
})
})
if(response.status === 200)
{
window.location.href = '/chatPage'
}
else if(response.status === 401)
{
return "Неправильный логин или пароль"
}
else{
console.log(response.status)
}
}
export async function handleLogout() {
@ -164,56 +39,3 @@ export async function VerificationEmail(Code){
}
}
export async function getLastMessages(){
const response = await fetch('http://localhost:8000/api/chat/get_some_messages/2?messages_loaded=0&messages_to_get=14',
{
method:'GET',
credentials:'include'
})
if(!response.ok)
{
console.log(response.status)
}
if(response.ok)
{
let msgMassive = await response.json();
let localTime
for(let i = 0; i< msgMassive.length;i++){
localTime = new Date(msgMassive[i].created_at)
msgMassive[i].created_at = localTime
}
msgMassive.reverse();
console.log(msgMassive)
return msgMassive
}
}
export async function MessagePicToUrl(messagePic){
console.log(messagePic)
const DataForm = new FormData();
DataForm.append('file', messagePic)
const respone = await fetch('http://localhost:8000/api/images/upload_image',
{
method:"POST",
body:DataForm
})
if(!respone.ok)
console.log("ошибка", respone.status)
if(respone.ok){
const data = await respone.json();
console.log("картинка принята")
return data.image_url;
}
}

View file

@ -1,135 +1,137 @@
<script>
import { onMount } from 'svelte';
import { UserCheck, handleLogout} from '$lib/userFunction';
import Select from 'svelte-select';
import { UserCheck, handleLogout } from '$lib/userFunction';
let Nickname;
let userImage;
let jopa = 0;
onMount(async () => {
const UserData = await UserCheck();
Nickname = UserData.username;
userImage = UserData.avatar_image;
});
let isOpen = false;
function dropDown() {
isOpen = !isOpen;
}
</script>
<header class="headerClass">
<div class="divsiteAvatar">
<header>
<div class="avatarDiv">
<img class="siteAvatar" src="./BP-NEON.png" alt="лого" />
<p class="siteAvatarBP">Black Phoenix</p>
<h2>BP Chat</h2>
</div>
<div class="divUser">
<button class="buttonUser" on:click={() => (isOpen = !isOpen)}>
<h3 class="name">{Nickname}</h3>
<div class="AvatarDiv"><img class="userAvatar" src={userImage} alt="аватарка" /></div>
<div class="userUser">
<button class="buttonUser"
style:border-bottom-right-radius={isOpen ? '0px' : '15px'}
style:border-bottom-left-radius= {isOpen ? '0px' : '15px'}
on:click={dropDown}>
<h3>{Nickname}</h3>
<div><img class="userAvatar" src={userImage} alt="аватарка"/></div>
</button>
</div>
{#if isOpen}
<div class="dropdown">
<div class="listItem">Профиль</div>
<div class="listItem">Настройки</div>
<div class="ListLine"></div>
<div on:click={handleLogout} class="Button">Выйти</div>
<button class="listItem" >Профиль</button>
<button class="listItem">Настройки</button>
<button on:click={handleLogout} class="listItem">Выйти</button>
</div>
{/if}
</div>
</header>
<style>
<style lang="scss">
.buttonUser,
.dropdown{
border: 1px solid transparent;
background:
linear-gradient(#101010, #101010) padding-box,
var(--gradient) border-box;
//background-repeat: no-repeat;
//background-attachment: fixed;
border-bottom-left-radius: 15px;
border-bottom-right-radius: 15px;
border-bottom: 0;
border-top-right-radius: 0;
border-top-left-radius: 0;
}
header {
position: relative;
display: flex;
justify-content: space-between;
height: 100%;
width: 100%;
margin-left: 9%;
margin-right: 9%;
}
.avatarDiv {
border: 1px solid transparent;
background:
linear-gradient(#101010, #101010) padding-box,
var(--gradient) border-box;
border-radius: 15px;
border-bottom: 0;
border-top-right-radius: 0;
border-top-left-radius: 0;
margin-top: -1px;
}
.buttonUser {
width: 100%;
width: 230px;
height: 100%;
border-bottom-left-radius: 10px;
border-bottom-right-radius: 10px;
display: flex;
justify-content: space-around;
align-items: center;
background-color: rgba(255, 255, 255, 0.3);
border: 0;
}
.ListLine {
border: 1px solid lightgray;
margin-top: 3px;
margin-top: -1px;
}
.dropdown {
z-index: 3;
cursor: pointer;
position: absolute;
right: 5vw;
top: 10vh;
width: 200px;
background-color: rgba(255, 255, 255, 0.3);
border: 0;
border-radius: 10px;
width: 230px;
display: flex;
flex-direction: column;
align-items: flex-start;
border-top: 0;
}
.userAvatar {
display: flex;
align-items: center;
width: 75px;
height: 75px;
border-radius: 50%;
}
.dropdown > *{
cursor: pointer;
}
.listItem{
font-size: 16px;
}
.headerClass > * {
margin-bottom: 0;
}
.headerClass {
list-style: none;
display: grid;
grid-template-columns: 5vw 200px repeat(5, auto) 200px 5vw;
grid-template-rows: 9vh;
gap: 0;
}
.siteAvatar {
margin: 0;
padding: 0;
.avatarDiv {
width: 230px;
height: 100%;
object-fit: cover;
}
.siteAvatarBP {
display: flex;
align-items: center;
font-size: 20px;
}
.divsiteAvatar {
grid-column: 2;
display: flex;
justify-content: space-evenly;
align-items: center;
}
.divUser {
grid-column: 8;
display: flex;
align-items: center;
justify-content: space-around;
width: 100%;
height: 100%;
}
.userAvatar {
justify-content: right;
width: 75px;
height: 75px;
border-radius: 50%;
max-width: 100%;
max-height: 100%;
min-height: 50px;
min-width: 50px;
display: flex;
align-items: center;
background-color: white;
}
.AvatarDiv{
.siteAvatar {
height: 90%;
}
</style>

View file

@ -1,11 +1,12 @@
<script>
import { getLastMessages, MessagePicToUrl, getAllChats, getPinnedMsg } from '$lib/chat';
import { UserCheck } from '$lib/userFunction'
import Header from '../Header.svelte';
import createWebSocket from '$lib/websocket';
import { onMount } from 'svelte';
import Time from 'svelte-time';
import { dayjs } from 'svelte-time';
import 'dayjs/locale/ru';
import { UserCheck, getLastMessages, MessagePicToUrl} from '$lib/userFunction.js';
import createWebSocket from '$lib/websocket';
dayjs.locale('ru');
console.clear();
@ -13,15 +14,17 @@
let userId; //пользователь, который залогинен
let socket; //вебсокет
let messages = []; //массив сообщений, которые отображаются на сайте
let messageText = ''; //сообщения для отправки
let messagePic; //картинка для отправки
let messages = [] //массив сообщений, которые отображаются на сайте
let messageText = '' //сообщения для отправки
let image_url = null
let messagePic //картинка для отправки
let flag = "send"
let answer = null
let chats = [] //массив чатов, доступных юзеру
let pinnedMsg = []
onMount(async () => {
const userData = await UserCheck();
let userId = userData.id;
let chatId = 2;
if(userId === undefined)
@ -29,6 +32,9 @@
const websocketUrl = `ws://localhost:8000/api/chat/ws/${chatId}?user_id=${userId}`;
pinnedMsg = await getPinnedMsg(chatId)
console.log(pinnedMsg)
chats = await getAllChats()
messages = await getLastMessages();
socket = createWebSocket(websocketUrl, (message) => {
@ -38,6 +44,10 @@
async function uploadImages() {
const fileInput = document.getElementById('file');
if(fileInput === null){
return null;
}
else{
const file = fileInput.files[0];
let urlpic;
if (file) {
@ -48,271 +58,299 @@
fileInput.value = null;
return urlpic;
}
}
async function sendMessage() {
let messageUrl = await uploadImages();
if (messageText.trim() !== '' || messageUrl != null) {
socket.send(JSON.stringify({ message: messageText, image_url: messageUrl }));
socket.send(JSON.stringify({flag: flag,
message: messageText,
image_url: image_url,
answer: answer }));
messageText = ""
}
}
function handleKeyPress(event) {
if (event.key === 'Enter' && !event.shiftKey) {
// Если нажат Enter и не нажат Shift, отправляем сообщение
sendMessage(event);
messageText = ""
function onEnterPress(event) {
if (event.key === "Enter" && !event.shiftKey) {
event.preventDefault();
console.log("нажата ", messageText)
sendMessage()
}
}
let rows = 1
const maxRows = 10
function adjustTextareaHeight() {
const textarea = document.getElementById("msg"); // Target specific textarea
if (textarea) {
textarea.style.height = '1em'; //??
textarea.style.height = (textarea.scrollHeight > maxRows * 18) ? `${maxRows * 18}px` : `${textarea.scrollHeight}px`; // Limit height based on maxRows and font size
//console.log(textarea.scrollHeight)
}
}
function onInput(event) {
const lines = event.target.value.split("\n").length;
if (lines > maxRows) {
event.target.value = event.target.value.slice(0, event.target.value.lastIndexOf("\n")); // Prevent exceeding max lines
}
adjustTextareaHeight();
}
</script>
<body class="backgroundPic">
<div class="DivHeader"><Header /></div>
<div>жопа2</div>
<div class="divChat">
<div class="chatBox">
<body>
<div class="grid">
<div class="headerDiv"><Header/></div>
<div>
<div class="gradient">
<div class="chatsDiv">
{#each chats as chat}
<div class="chatDivLeft">
<img class="chatImage" src="{chat.avatar_image}" alt="">
<h2>{chat.chat_name}</h2>
</div>
{/each}
</div>
</div>
</div>
<div>
<div class="gradient">
<div class="chatDiv">
{#if messages.length == 0}
<div class="NoMsgDiv">
<h1 class="NoMsg1">В этом чате еще нет сообщений.</h1>
<h3 class="NoMsg2">Крыски, начните обсуждать киску <br> прям за ее спиной</h3>
<div class="noMsgDiv">
<h2 class="noMsg1">В этом чате еще нет сообщений.</h2>
<h3 class="noMsg2">Крыски, начните обсуждать <br> прям за ее спиной</h3>
</div>
{/if}
<div class="msgDiv">
{#each messages as message}
<div class="MsgAll">
<img class="MsgAva" src={message.avatar_image} alt="ава" />
<div class="divMessage">
<div class="userFiled">
<h3 class="MsgName">{message.username}</h3>
<div class="MsgTime"><Time relative timestamp={message.created_at}></Time></div>
<div class="messageMain">
<img class="messageAvatar" src="{message.avatar_image}" alt="ава">
<div class="messageDiv">
<h3>{message.username}</h3>
<div class="messageMessage">
<p>{message.message}</p>
{#if message.image_url != null}
<img src="{message.image_url}" alt="пикча">
{/if}
</div>
<p class="MsgMsg">{message.message}</p>
{#if message.image_url != null}
<img class="MsgPic" src={message.image_url} alt="" />
{/if}
</div>
</div>
{/each}
</div>
<form class="chatSend" on:submit={sendMessage}>
<textarea
class="chatInput"
placeholder="Введите сообщение"
maxlength="2000"
rows="1"
type="text"
bind:value={messageText}
on:keypress={handleKeyPress}
></textarea>
<div class="fileInputDiv">
<input name="file" id="file" type="file" accept="image/*" bind:value={messagePic} />
<label class="attachingImages" for="file"><img src="./attachment.svg" alt=""></label>
<div class="inputDiv">
<textarea on:keydown={onEnterPress}
autofocus placeholder="Введите сообщение" rows="{rows}" bind:value={messageText}
on:input={onInput} name="msg" id="msg"></textarea>
<img class="logoForImage" src="logoForImage.svg" alt="">
</div>
</form>
</div>
<div>жопа4</div>
<div>жопа5</div>
<div>жопа6</div>
<div>жопа7</div>
</div>
</div>
<div><div class="gradient">
{#if pinnedMsg.length === 0}
<div class="noMsgDiv">
<h2 class="noMsg1">Тут ничего нет</h2>
<h3 class="noMsg2">Но если ты закрепишь сообщение, <br> тут что то изменится</h3>
</div>
{/if}
{#each pinnedMsg as msg}
<div class="mainPinned">
<h3 class="msgPinned">{msg.message}</h3>
<img class="imgPinned" src="{msg.avatar_image}" alt="">
</div>
{/each}
</div></div>
<div><h1>7</h1></div>
<div><h1>8</h1></div>
<div><h1>9</h1></div>
</div>
</body>
<style>
.NoMsgDiv {
<style lang="scss">
.mainPinned{
}
.imgPinned{
height: 60px;
width: 60px;
border-radius: 15px;
}
.chatsDiv{
display: flex;
align-items: center;
flex-direction: column;
text-align: center;
}
.NoMsgDiv > * {
align-self: center; /* Центрирование по вертикали внутри .NoMsgDiv */
}
.NoMsg1{
}
.NoMsg2{
}
.fileInputDiv{
background-color: rgba(255, 255, 255, 0.1);
border-bottom-right-radius: 15px;
}
.attachingImages{
display: flex;
justify-content: center;
width: 4vh;
height: 4vh;
min-width: 30px;
min-height: 30px;
padding: 10px;
}
#file{
display: none;
}
.userFiled {
}
.userFiled > * {
display: inline;
margin: 0.5vw;
}
.MsgMsg{
word-wrap: break-word;
display: inline;
}
.MsgName{
display: inline;
}
.MsgTime{
display: inline;
}
.MsgPic {
margin-left: 1vw;
margin-bottom: 1vh;
width: 80%;
border: 1px solid rgba(255, 255, 255, 0.5);
border-radius: 15px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.9);
}
.MsgAva {
height: 50px;
width: 50px;
border: 2px solid rgba(255, 255, 255, 0.6);
border-radius: 10px;
}
.MsgAll {
display: block;
gap: 1vw;
}
.divMessage {
background-color: rgba(255, 255, 255, 0.3);
border: 1px solid rgba(255, 255, 255, 0.5);
border-radius: 15px;
box-shadow: 0 0px 30px rgba(0, 0, 0, 0.2);
margin: 3px;
}
.chatBox {
overflow-y: auto;
width: 100%;
height: 100%;
width: 100%;
/* From https://css.glass */
background-color: rgba(255, 255, 255, 0.2);
overflow: hidden;
}
.chatDivLeft{
display: flex;
flex-direction: row;
align-items: center;
width: 95%;
height: 75px;
margin-top: 10px;
border-radius: 15px;
border-bottom-left-radius: 0;
border-bottom-right-radius: 0;
box-shadow:
8.6px 0px 10.7px -13px rgba(0, 0, 0, 0.07),
14.3px 0px 17.9px -13px rgba(0, 0, 0, 0.042),
18.4px 0px 22.2px -13px rgba(0, 0, 0, 0.038),
21.8px 0px 24.6px -13px rgba(0, 0, 0, 0.037),
25.8px 0px 26.4px -13px rgba(0, 0, 0, 0.037),
31.9px 0px 30.2px -13px rgba(0, 0, 0, 0.037),
44px 0px 43px -13px rgba(0, 0, 0, 0.036),
100px 0px 142px -13px rgba(0, 0, 0, 0.031);
backdrop-filter: blur(7px);
border: 1px solid rgba(255, 255, 255, 0.43);
border: 1px solid transparent;
background:
linear-gradient(#101010, #101010) padding-box,
var(--gradient) border-box;
}
.chatImage{
height: 60px;
width: 60px;
border-radius: 15px;
margin: 0 10px;
}
.chatSend {
box-shadow:
8.6px 8.6px 10.7px -13px rgba(0, 0, 0, 0.07),
14.3px 14.3px 17.9px -13px rgba(0, 0, 0, 0.042),
18.4px 18.4px 22.2px -13px rgba(0, 0, 0, 0.038),
21.8px 21.8px 24.6px -13px rgba(0, 0, 0, 0.037),
25.8px 25.8px 26.4px -13px rgba(0, 0, 0, 0.037),
31.9px 31.9px 30.2px -13px rgba(0, 0, 0, 0.037),
44px 44px 43px -13px rgba(0, 0, 0, 0.036),
100px 100px 142px -13px rgba(0, 0, 0, 0.031);
.logoForImage{
display: flex;
width: 100%;
justify-content: space-between;
border: 1px solid rgba(255, 255, 255, 0.43);
border-bottom-left-radius: 15px;
border-bottom-right-radius: 15px;
justify-self: center;
align-self: flex-start;
width: 2rem;
height: 2rem;
padding: 5px;
//background-color: red;
}
.chatInput {
outline: none;
width: 100%;
resize: none;
box-sizing: border-box;
background-color: rgba(255, 255, 255, 0.2);
border: transparent solid;
max-height: 12em;
border-bottom-left-radius: 15px;
.messageMessage{
background-color: #7734AA;
border-radius: 15px;
padding: 5px;
word-break: break-word;
}
.divChat {
.messageDiv{
}
.messageAvatar{
width: 60px;
height: 60px;
border-radius: 15px;
margin-right: 10px;
}
.messageMain{
display: flex;
flex-direction: row;
padding-bottom: 10px;
}
.msgDiv{
display: flex;
flex-direction: column;
display: flex;
height: 100%;
margin-bottom: 10px;
overflow: auto;
//background-color: red;
}
.inputDiv{
display: flex;
flex-direction: row;
border-radius: 15px;
border: 1px solid transparent;
background:
linear-gradient(#101010, #101010) padding-box,
var(--gradient) border-box;
//padding: 5px;
//background-color: red;
}
#msg{
width: 100%;
background-color: transparent;
border: 0;
line-height: 1em;
outline: none;
resize: none;
padding: 13px 0 0 5px;
//background-color: red;
}
.chatDiv{
//background-color: red;
width: 98%;
height: 98%;
display: flex;
flex-direction: column;
align-self: center;
align-content: center;
}
.headerDiv{
grid-column: span 3;
}
.gradient{
border: 1px solid transparent;
background:
linear-gradient(#101010, #101010) padding-box,
var(--gradient) border-box;
border-radius: 15px;
width: 95%;
height: 95%;
display: flex; /* Добавляем для центрирования по вертикали и горизонтали */
align-self: center; /* Центрируем по вертикали */
justify-content: center; /* Центрируем по горизонтали */
margin: auto;
}
body{
width: 100%;
height: 100%;
}
.grid{
display: grid;
grid-template-columns: 30vw 40vw 30vw; /* 2 колонки с равным распределением ширины */
grid-template-rows: 10vh 80vh 10vh;
grid-template-columns: 30% 40% 30%;
grid-template-rows: 10% 90% 10%;
width: 100%;
height: 100%;
}
.grid > *{
outline: 1px solid white;
display: flex;
align-items: center;
justify-content: center;
}
body > * {
/* border: 1px solid black; */
.noMsgDiv{
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
text-align: center;
height: 100%;
//background-color: red;
}
.noMsgDiv > h2{
padding-bottom: 10px;
}
* {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
}
.backgroundPic {
grid-column: span 3;
grid-row: span 3;
background-color: #7a5abd;
background-image: url(./BPytka.png);
background-repeat: no-repeat;
background-size: 50vh;
background-position-x: 50%;
background-position-y: 50%;
}
.DivHeader {
grid-column: 3 span;
border: 0 !important;
margin: 0;
padding: 0;
z-index: 2;
min-height: 500px !important;
}
</style>

View file

@ -1,11 +1,9 @@
<script>
import { dictionary } from './../../../.svelte-kit/generated/client/app.js';
import Header from '../Header.svelte';
import { handleLogin } from '$lib/userFunction';
import { handleLogin } from '$lib/login';
import { onMount } from 'svelte';
import { fly, blur } from 'svelte/transition';
import { cubicOut } from 'svelte/easing';
import { backInOut } from 'svelte/easing';
import { cubicOut, backInOut } from 'svelte/easing';
async function listener(event){
@ -75,8 +73,9 @@
<div class="loginField">
<div class="loginMainDiv">
<div class="loginDiv" transition:fly={{ y: -1920, duration: 1000, backInOut }}>
<div class="jopa1">
<div class="noise">
<div class="marginDiv">
<div class="greetingsDiv">
<h1 id="hi" transition:blur={{
y: -30, duration: 1900, easing: cubicOut }}>{hi}</h1>
@ -84,6 +83,7 @@
y: -30, duration: 2000, easing: cubicOut }}>
{greeting}</h2>
</div>
<div class="bigGroup">
<div class="group">
<h3>никнейм или почта</h3>
@ -92,8 +92,7 @@
<div class="group">
<h3>пароль</h3>
<input placeholder=" " type="password" id="password" on:input={listener} bind:value={password} />
<input placeholder=" " type="password" id="password" on:input={listener} bind:value={password} />z
</div>
</div>
@ -109,7 +108,7 @@
</div>
</div>
<div class="regDiv" transition:fly={{ y: -1920, duration: 800, backInOut }}>
<div class="jopa1">
<div class="noise">
<div class="regregDiv">
<h2 class="reg1">Нет аккаунта? Лох!</h2>
<button class="reg2" on:click={() => (window.location.href = '/register')}
@ -135,7 +134,7 @@
// border: 1px solid white;
// bottom: 29.5%;
// }
// не рабоая хуйня. переделать как нибудь <h3 class="passwordError">{passwordError}</h3>
// не рабочая . переделать как нибудь <h3 class="passwordError">{passwordError}</h3>
.greetingsDiv{
height: 30%;
@ -143,14 +142,12 @@
flex-direction: column;
gap: 35px;
justify-content: center;
}
.enterDiv{
display: flex;
flex-direction: column;
height: 20%;
}
.enterButt{
height: 60%;
@ -186,7 +183,6 @@
.group > * {
margin-top: 1%;
margin-bottom: 1%;
}
.group {
@ -271,29 +267,6 @@
//border: 1px solid white;
}
.jopa1 {
position: relative;
overflow: hidden;
width: 100%;
height: 100%;
box-shadow: 4px 4px 11px rgba($color: #000000, $alpha: 0.4);
border-radius: 15px;
}
.jopa1::after {
content: '';
background-image: url(../noise.gif);
opacity: 0.011;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
pointer-events: none;
border-radius: 15px;
}
input {
border: 1px solid transparent;
background:
@ -369,8 +342,4 @@
flex-direction: row;
}
* {
font-family: Comfortaa;
margin: 0;
}
</style>

View file

@ -1,5 +1,5 @@
<script>
import { handleRegister, checkName, checkMail, VerificationEmail } from '$lib/userFunction.js';
import { handleRegister, checkName, checkMail, VerificationEmail } from '$lib/register';
import { fly } from 'svelte/transition';
import { cubicOut } from 'svelte/easing';
@ -55,7 +55,7 @@
else if (name.length < 2){
nameError = "ник от двух символов";
}
else if (name != '') {
else if (name.length != 0) {
let error = await checkName(name);
console.log(error);
nameError = error;
@ -110,7 +110,7 @@
<div class="mainDivInner">
<div class="mainDivFront">
<div class="jopa1">
<div class="noise">
<div class="marginDiv">
<form on:submit|preventDefault={SendData}>
<h1>Регистрация</h1>
@ -142,7 +142,7 @@
<div class="group">
<div class="groupname">
<h3>пароль</h3>
{#if passwordError && passwordError !== ''}
{#if passwordError !== ''}
<h3 id="password" transition:fly={{ y: -30, duration: 300, easing: cubicOut }}>
{passwordError}
</h3>
@ -211,7 +211,7 @@
<div class="mainDivBack">
<div class="jopa1">
<div class="noise">
<div class="marginDivBack">
<h1>Подтверди</h1>
@ -275,10 +275,10 @@
linear-gradient(#101010, #101010) padding-box,
var(--gradient) border-box;
border-radius: 15px;
width: 100%;
height: 100%;
backface-visibility: hidden;
}
.rotated
@ -287,11 +287,6 @@
transform: rotateX(180deg);
}
* {
font-family: Comfortaa;
margin: 0;
}
form {
display: flex;
flex-direction: column;
@ -343,28 +338,6 @@
justify-content: space-between;
}
.jopa1 {
width: 100%;
height: 100%;
display: flex;
box-shadow: 4px 4px 11px rgba($color: #000000, $alpha: 0.4);
border-radius: 15px;
}
.jopa1::before {
content: '';
background-image: url(../noise.gif);
opacity: 0.011;
width: 100%;
height: 100%;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
pointer-events: none;
border-radius: 15px;
}
input,
select {
border: 1px solid transparent;
@ -406,52 +379,5 @@
width: 4em;
}
select {
min-width: 50px;
width: 8rem;
display: flex;
justify-content: center;
text-align: center;
font-size: 24px;
font-weight: 300;
overflow: auto;
}
option {
background-color: var(--bg);
border: 0;
}
button[type='submit'] {
text-shadow: 0 0 20px white;
font-size: 36px;
background: transparent;
border: 0;
height: 10%;
}
button[type='submit'],
select,
option {
cursor: pointer;
}
h1,
h3,
input,
select,
button[type='submit'] {
color: var(--fontColor);
}
h1 {
display: flex;
justify-content: center;
align-items: center;
text-shadow: 0 0 20px white;
font-size: 48px;
height: 10%;
}
h3 {
font-weight: 100;
font-size: 24px;
}
</style>

5
static/logoForImage.svg Normal file
View file

@ -0,0 +1,5 @@
<svg width="45" height="45" viewBox="0 0 45 45" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M32.2897 14.1223C33.0829 14.1223 33.7259 13.4793 33.7259 12.6862C33.7259 11.893 33.0829 11.25 32.2897 11.25C31.4965 11.25 30.8535 11.893 30.8535 12.6862C30.8535 13.4793 31.4965 14.1223 32.2897 14.1223Z" fill="white" stroke="white" stroke-width="4" stroke-miterlimit="10"/>
<path d="M32.7373 7.03125C35.6201 7.03125 37.9686 9.37969 37.9686 12.2625V32.9625C37.9686 35.8453 35.6201 38.1938 32.7373 38.1938H12.6561C9.77324 38.1938 7.4248 35.8453 7.4248 32.9625V12.2625C7.4248 9.37969 9.77324 7.03125 12.6561 7.03125H32.7373ZM32.7373 2.8125H12.6561C7.43184 2.8125 3.20605 7.04531 3.20605 12.2625V32.9625C3.20605 38.1867 7.43887 42.4125 12.6561 42.4125H32.7373C37.9615 42.4125 42.1873 38.1797 42.1873 32.9625V12.2625C42.1873 7.04531 37.9545 2.8125 32.7373 2.8125Z" fill="white"/>
<path d="M8 22.2875C9.2032 22.142 10.9935 21.9797 13.1535 22.0021C18.2054 22.0636 21.1627 23.0935 24.8303 23.7035C27.6788 24.1793 31.7596 24.5375 37 23.9274C37 27.9516 37 31.9758 37 36H8.60885C8.4059 31.4273 8.20295 26.8602 8 22.2875Z" fill="white" stroke="white" stroke-width="6" stroke-miterlimit="10"/>
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

BIN
static/noise.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 703 KiB