Update environment variables, refactor App component, and enhance user experience with new speed indicators. Added speed test modal and improved styling for icons and components.

This commit is contained in:
2025-05-23 18:25:18 +05:00
parent 91343bd2f6
commit 23e5f0034b
50 changed files with 1343 additions and 500 deletions
+2 -2
View File
@@ -4,5 +4,5 @@ VITE_COORD_URL=https://coord.graff.tech
VITE_CRM_API_URL=https://crm.stream.graff.tech/api
# VITE_API_URL=http://localhost:5002
VITE_API_URL=https://stream.graff.tech/api
VITE_SOCKET_URL=http://localhost:5003
# VITE_SOCKET_URL=https://stream.graff.tech
# VITE_SOCKET_URL=http://localhost:5003
VITE_SOCKET_URL=https://stream.graff.tech
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+279
View File
@@ -0,0 +1,279 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="robots" content="noindex, noarchive">
<meta name="format-detection" content="telephone=no">
<title>Transfonter demo</title>
<link href="stylesheet.css" rel="stylesheet">
<style>
/*
http://meyerweb.com/eric/tools/css/reset/
v2.0 | 20110126
License: none (public domain)
*/
html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, embed,
figure, figcaption, footer, header, hgroup,
menu, nav, output, ruby, section, summary,
time, mark, audio, video {
margin: 0;
padding: 0;
border: 0;
font-size: 100%;
font: inherit;
vertical-align: baseline;
}
/* HTML5 display-role reset for older browsers */
article, aside, details, figcaption, figure,
footer, header, hgroup, menu, nav, section {
display: block;
}
body {
line-height: 1;
}
ol, ul {
list-style: none;
}
blockquote, q {
quotes: none;
}
blockquote:before, blockquote:after,
q:before, q:after {
content: '';
content: none;
}
table {
border-collapse: collapse;
border-spacing: 0;
}
/* demo styles */
body {
background: #f0f0f0;
color: #000;
}
.page {
background: #fff;
width: 920px;
margin: 0 auto;
padding: 20px 20px 0 20px;
overflow: hidden;
}
.font-container {
overflow-x: auto;
overflow-y: hidden;
margin-bottom: 40px;
line-height: 1.3;
white-space: nowrap;
padding-bottom: 5px;
}
h1 {
position: relative;
background: #444;
font-size: 32px;
color: #fff;
padding: 10px 20px;
margin: 0 -20px 12px -20px;
}
.letters {
font-size: 25px;
margin-bottom: 20px;
}
.s10:before {
content: '10px';
}
.s11:before {
content: '11px';
}
.s12:before {
content: '12px';
}
.s14:before {
content: '14px';
}
.s18:before {
content: '18px';
}
.s24:before {
content: '24px';
}
.s30:before {
content: '30px';
}
.s36:before {
content: '36px';
}
.s48:before {
content: '48px';
}
.s60:before {
content: '60px';
}
.s72:before {
content: '72px';
}
.s10:before, .s11:before, .s12:before, .s14:before,
.s18:before, .s24:before, .s30:before, .s36:before,
.s48:before, .s60:before, .s72:before {
font-family: Arial, sans-serif;
font-size: 10px;
font-weight: normal;
font-style: normal;
color: #999;
padding-right: 6px;
}
pre {
display: block;
padding: 9px;
margin: 0 0 12px;
font-family: Monaco, Menlo, Consolas, "Courier New", monospace;
font-size: 13px;
line-height: 1.428571429;
color: #333;
font-weight: normal;
font-style: normal;
background-color: #f5f5f5;
border: 1px solid #ccc;
overflow-x: auto;
border-radius: 4px;
}
/* responsive */
@media (max-width: 959px) {
.page {
width: auto;
margin: 0;
}
}
</style>
</head>
<body>
<div class="page">
<div class="demo">
<h1 style="font-family: 'Gilroy'; font-weight: 600; font-style: normal;">Gilroy-SemiBold</h1>
<pre title="Usage">.your-style {
font-family: 'Gilroy';
font-weight: 600;
font-style: normal;
}</pre>
<pre title="Preload (optional)">
&lt;link rel=&quot;preload&quot; href=&quot;Gilroy-SemiBold.woff2&quot; as=&quot;font&quot; type=&quot;font/woff2&quot; crossorigin&gt;</pre>
<div class="font-container" style="font-family: 'Gilroy'; font-weight: 600; font-style: normal;">
<p class="letters">
abcdefghijklmnopqrstuvwxyz<br>
ABCDEFGHIJKLMNOPQRSTUVWXYZ<br>
0123456789.:,;()*!?'@#&lt;&gt;$%&^+-=~
</p>
<p class="s10" style="font-size: 10px;">The quick brown fox jumps over the lazy dog.</p>
<p class="s11" style="font-size: 11px;">The quick brown fox jumps over the lazy dog.</p>
<p class="s12" style="font-size: 12px;">The quick brown fox jumps over the lazy dog.</p>
<p class="s14" style="font-size: 14px;">The quick brown fox jumps over the lazy dog.</p>
<p class="s18" style="font-size: 18px;">The quick brown fox jumps over the lazy dog.</p>
<p class="s24" style="font-size: 24px;">The quick brown fox jumps over the lazy dog.</p>
<p class="s30" style="font-size: 30px;">The quick brown fox jumps over the lazy dog.</p>
<p class="s36" style="font-size: 36px;">The quick brown fox jumps over the lazy dog.</p>
<p class="s48" style="font-size: 48px;">The quick brown fox jumps over the lazy dog.</p>
<p class="s60" style="font-size: 60px;">The quick brown fox jumps over the lazy dog.</p>
<p class="s72" style="font-size: 72px;">The quick brown fox jumps over the lazy dog.</p>
</div>
</div>
<div class="demo">
<h1 style="font-family: 'Gilroy'; font-weight: bold; font-style: normal;">Gilroy-Bold</h1>
<pre title="Usage">.your-style {
font-family: 'Gilroy';
font-weight: bold;
font-style: normal;
}</pre>
<pre title="Preload (optional)">
&lt;link rel=&quot;preload&quot; href=&quot;Gilroy-Bold.woff2&quot; as=&quot;font&quot; type=&quot;font/woff2&quot; crossorigin&gt;</pre>
<div class="font-container" style="font-family: 'Gilroy'; font-weight: bold; font-style: normal;">
<p class="letters">
abcdefghijklmnopqrstuvwxyz<br>
ABCDEFGHIJKLMNOPQRSTUVWXYZ<br>
0123456789.:,;()*!?'@#&lt;&gt;$%&^+-=~
</p>
<p class="s10" style="font-size: 10px;">The quick brown fox jumps over the lazy dog.</p>
<p class="s11" style="font-size: 11px;">The quick brown fox jumps over the lazy dog.</p>
<p class="s12" style="font-size: 12px;">The quick brown fox jumps over the lazy dog.</p>
<p class="s14" style="font-size: 14px;">The quick brown fox jumps over the lazy dog.</p>
<p class="s18" style="font-size: 18px;">The quick brown fox jumps over the lazy dog.</p>
<p class="s24" style="font-size: 24px;">The quick brown fox jumps over the lazy dog.</p>
<p class="s30" style="font-size: 30px;">The quick brown fox jumps over the lazy dog.</p>
<p class="s36" style="font-size: 36px;">The quick brown fox jumps over the lazy dog.</p>
<p class="s48" style="font-size: 48px;">The quick brown fox jumps over the lazy dog.</p>
<p class="s60" style="font-size: 60px;">The quick brown fox jumps over the lazy dog.</p>
<p class="s72" style="font-size: 72px;">The quick brown fox jumps over the lazy dog.</p>
</div>
</div>
<div class="demo">
<h1 style="font-family: 'Gilroy'; font-weight: normal; font-style: normal;">Gilroy-Regular</h1>
<pre title="Usage">.your-style {
font-family: 'Gilroy';
font-weight: normal;
font-style: normal;
}</pre>
<pre title="Preload (optional)">
&lt;link rel=&quot;preload&quot; href=&quot;Gilroy-Regular.woff2&quot; as=&quot;font&quot; type=&quot;font/woff2&quot; crossorigin&gt;</pre>
<div class="font-container" style="font-family: 'Gilroy'; font-weight: normal; font-style: normal;">
<p class="letters">
abcdefghijklmnopqrstuvwxyz<br>
ABCDEFGHIJKLMNOPQRSTUVWXYZ<br>
0123456789.:,;()*!?'@#&lt;&gt;$%&^+-=~
</p>
<p class="s10" style="font-size: 10px;">The quick brown fox jumps over the lazy dog.</p>
<p class="s11" style="font-size: 11px;">The quick brown fox jumps over the lazy dog.</p>
<p class="s12" style="font-size: 12px;">The quick brown fox jumps over the lazy dog.</p>
<p class="s14" style="font-size: 14px;">The quick brown fox jumps over the lazy dog.</p>
<p class="s18" style="font-size: 18px;">The quick brown fox jumps over the lazy dog.</p>
<p class="s24" style="font-size: 24px;">The quick brown fox jumps over the lazy dog.</p>
<p class="s30" style="font-size: 30px;">The quick brown fox jumps over the lazy dog.</p>
<p class="s36" style="font-size: 36px;">The quick brown fox jumps over the lazy dog.</p>
<p class="s48" style="font-size: 48px;">The quick brown fox jumps over the lazy dog.</p>
<p class="s60" style="font-size: 60px;">The quick brown fox jumps over the lazy dog.</p>
<p class="s72" style="font-size: 72px;">The quick brown fox jumps over the lazy dog.</p>
</div>
</div>
<div class="demo">
<h1 style="font-family: 'Gilroy'; font-weight: 500; font-style: normal;">Gilroy-Medium</h1>
<pre title="Usage">.your-style {
font-family: 'Gilroy';
font-weight: 500;
font-style: normal;
}</pre>
<pre title="Preload (optional)">
&lt;link rel=&quot;preload&quot; href=&quot;Gilroy-Medium.woff2&quot; as=&quot;font&quot; type=&quot;font/woff2&quot; crossorigin&gt;</pre>
<div class="font-container" style="font-family: 'Gilroy'; font-weight: 500; font-style: normal;">
<p class="letters">
abcdefghijklmnopqrstuvwxyz<br>
ABCDEFGHIJKLMNOPQRSTUVWXYZ<br>
0123456789.:,;()*!?'@#&lt;&gt;$%&^+-=~
</p>
<p class="s10" style="font-size: 10px;">The quick brown fox jumps over the lazy dog.</p>
<p class="s11" style="font-size: 11px;">The quick brown fox jumps over the lazy dog.</p>
<p class="s12" style="font-size: 12px;">The quick brown fox jumps over the lazy dog.</p>
<p class="s14" style="font-size: 14px;">The quick brown fox jumps over the lazy dog.</p>
<p class="s18" style="font-size: 18px;">The quick brown fox jumps over the lazy dog.</p>
<p class="s24" style="font-size: 24px;">The quick brown fox jumps over the lazy dog.</p>
<p class="s30" style="font-size: 30px;">The quick brown fox jumps over the lazy dog.</p>
<p class="s36" style="font-size: 36px;">The quick brown fox jumps over the lazy dog.</p>
<p class="s48" style="font-size: 48px;">The quick brown fox jumps over the lazy dog.</p>
<p class="s60" style="font-size: 60px;">The quick brown fox jumps over the lazy dog.</p>
<p class="s72" style="font-size: 72px;">The quick brown fox jumps over the lazy dog.</p>
</div>
</div>
</div>
</body>
</html>
+48
View File
@@ -0,0 +1,48 @@
@font-face {
font-family: 'Gilroy';
src: url('Gilroy-SemiBold.eot');
src: url('Gilroy-SemiBold.eot?#iefix') format('embedded-opentype'),
url('Gilroy-SemiBold.woff2') format('woff2'),
url('Gilroy-SemiBold.woff') format('woff'),
url('Gilroy-SemiBold.ttf') format('truetype');
font-weight: 600;
font-style: normal;
font-display: swap;
}
@font-face {
font-family: 'Gilroy';
src: url('Gilroy-Bold.eot');
src: url('Gilroy-Bold.eot?#iefix') format('embedded-opentype'),
url('Gilroy-Bold.woff2') format('woff2'),
url('Gilroy-Bold.woff') format('woff'),
url('Gilroy-Bold.ttf') format('truetype');
font-weight: bold;
font-style: normal;
font-display: swap;
}
@font-face {
font-family: 'Gilroy';
src: url('Gilroy-Regular.eot');
src: url('Gilroy-Regular.eot?#iefix') format('embedded-opentype'),
url('Gilroy-Regular.woff2') format('woff2'),
url('Gilroy-Regular.woff') format('woff'),
url('Gilroy-Regular.ttf') format('truetype');
font-weight: normal;
font-style: normal;
font-display: swap;
}
@font-face {
font-family: 'Gilroy';
src: url('Gilroy-Medium.eot');
src: url('Gilroy-Medium.eot?#iefix') format('embedded-opentype'),
url('Gilroy-Medium.woff2') format('woff2'),
url('Gilroy-Medium.woff') format('woff'),
url('Gilroy-Medium.ttf') format('truetype');
font-weight: 500;
font-style: normal;
font-display: swap;
}
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+279
View File
@@ -0,0 +1,279 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="robots" content="noindex, noarchive">
<meta name="format-detection" content="telephone=no">
<title>Transfonter demo</title>
<link href="stylesheet.css" rel="stylesheet">
<style>
/*
http://meyerweb.com/eric/tools/css/reset/
v2.0 | 20110126
License: none (public domain)
*/
html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, embed,
figure, figcaption, footer, header, hgroup,
menu, nav, output, ruby, section, summary,
time, mark, audio, video {
margin: 0;
padding: 0;
border: 0;
font-size: 100%;
font: inherit;
vertical-align: baseline;
}
/* HTML5 display-role reset for older browsers */
article, aside, details, figcaption, figure,
footer, header, hgroup, menu, nav, section {
display: block;
}
body {
line-height: 1;
}
ol, ul {
list-style: none;
}
blockquote, q {
quotes: none;
}
blockquote:before, blockquote:after,
q:before, q:after {
content: '';
content: none;
}
table {
border-collapse: collapse;
border-spacing: 0;
}
/* demo styles */
body {
background: #f0f0f0;
color: #000;
}
.page {
background: #fff;
width: 920px;
margin: 0 auto;
padding: 20px 20px 0 20px;
overflow: hidden;
}
.font-container {
overflow-x: auto;
overflow-y: hidden;
margin-bottom: 40px;
line-height: 1.3;
white-space: nowrap;
padding-bottom: 5px;
}
h1 {
position: relative;
background: #444;
font-size: 32px;
color: #fff;
padding: 10px 20px;
margin: 0 -20px 12px -20px;
}
.letters {
font-size: 25px;
margin-bottom: 20px;
}
.s10:before {
content: '10px';
}
.s11:before {
content: '11px';
}
.s12:before {
content: '12px';
}
.s14:before {
content: '14px';
}
.s18:before {
content: '18px';
}
.s24:before {
content: '24px';
}
.s30:before {
content: '30px';
}
.s36:before {
content: '36px';
}
.s48:before {
content: '48px';
}
.s60:before {
content: '60px';
}
.s72:before {
content: '72px';
}
.s10:before, .s11:before, .s12:before, .s14:before,
.s18:before, .s24:before, .s30:before, .s36:before,
.s48:before, .s60:before, .s72:before {
font-family: Arial, sans-serif;
font-size: 10px;
font-weight: normal;
font-style: normal;
color: #999;
padding-right: 6px;
}
pre {
display: block;
padding: 9px;
margin: 0 0 12px;
font-family: Monaco, Menlo, Consolas, "Courier New", monospace;
font-size: 13px;
line-height: 1.428571429;
color: #333;
font-weight: normal;
font-style: normal;
background-color: #f5f5f5;
border: 1px solid #ccc;
overflow-x: auto;
border-radius: 4px;
}
/* responsive */
@media (max-width: 959px) {
.page {
width: auto;
margin: 0;
}
}
</style>
</head>
<body>
<div class="page">
<div class="demo">
<h1 style="font-family: 'Inter'; font-weight: 600; font-style: normal;">Inter Semi Bold</h1>
<pre title="Usage">.your-style {
font-family: 'Inter';
font-weight: 600;
font-style: normal;
}</pre>
<pre title="Preload (optional)">
&lt;link rel=&quot;preload&quot; href=&quot;Inter-SemiBold.woff2&quot; as=&quot;font&quot; type=&quot;font/woff2&quot; crossorigin&gt;</pre>
<div class="font-container" style="font-family: 'Inter'; font-weight: 600; font-style: normal;">
<p class="letters">
abcdefghijklmnopqrstuvwxyz<br>
ABCDEFGHIJKLMNOPQRSTUVWXYZ<br>
0123456789.:,;()*!?'@#&lt;&gt;$%&^+-=~
</p>
<p class="s10" style="font-size: 10px;">The quick brown fox jumps over the lazy dog.</p>
<p class="s11" style="font-size: 11px;">The quick brown fox jumps over the lazy dog.</p>
<p class="s12" style="font-size: 12px;">The quick brown fox jumps over the lazy dog.</p>
<p class="s14" style="font-size: 14px;">The quick brown fox jumps over the lazy dog.</p>
<p class="s18" style="font-size: 18px;">The quick brown fox jumps over the lazy dog.</p>
<p class="s24" style="font-size: 24px;">The quick brown fox jumps over the lazy dog.</p>
<p class="s30" style="font-size: 30px;">The quick brown fox jumps over the lazy dog.</p>
<p class="s36" style="font-size: 36px;">The quick brown fox jumps over the lazy dog.</p>
<p class="s48" style="font-size: 48px;">The quick brown fox jumps over the lazy dog.</p>
<p class="s60" style="font-size: 60px;">The quick brown fox jumps over the lazy dog.</p>
<p class="s72" style="font-size: 72px;">The quick brown fox jumps over the lazy dog.</p>
</div>
</div>
<div class="demo">
<h1 style="font-family: 'Inter'; font-weight: normal; font-style: normal;">Inter Regular</h1>
<pre title="Usage">.your-style {
font-family: 'Inter';
font-weight: normal;
font-style: normal;
}</pre>
<pre title="Preload (optional)">
&lt;link rel=&quot;preload&quot; href=&quot;Inter-Regular.woff2&quot; as=&quot;font&quot; type=&quot;font/woff2&quot; crossorigin&gt;</pre>
<div class="font-container" style="font-family: 'Inter'; font-weight: normal; font-style: normal;">
<p class="letters">
abcdefghijklmnopqrstuvwxyz<br>
ABCDEFGHIJKLMNOPQRSTUVWXYZ<br>
0123456789.:,;()*!?'@#&lt;&gt;$%&^+-=~
</p>
<p class="s10" style="font-size: 10px;">The quick brown fox jumps over the lazy dog.</p>
<p class="s11" style="font-size: 11px;">The quick brown fox jumps over the lazy dog.</p>
<p class="s12" style="font-size: 12px;">The quick brown fox jumps over the lazy dog.</p>
<p class="s14" style="font-size: 14px;">The quick brown fox jumps over the lazy dog.</p>
<p class="s18" style="font-size: 18px;">The quick brown fox jumps over the lazy dog.</p>
<p class="s24" style="font-size: 24px;">The quick brown fox jumps over the lazy dog.</p>
<p class="s30" style="font-size: 30px;">The quick brown fox jumps over the lazy dog.</p>
<p class="s36" style="font-size: 36px;">The quick brown fox jumps over the lazy dog.</p>
<p class="s48" style="font-size: 48px;">The quick brown fox jumps over the lazy dog.</p>
<p class="s60" style="font-size: 60px;">The quick brown fox jumps over the lazy dog.</p>
<p class="s72" style="font-size: 72px;">The quick brown fox jumps over the lazy dog.</p>
</div>
</div>
<div class="demo">
<h1 style="font-family: 'Inter'; font-weight: 500; font-style: normal;">Inter Medium</h1>
<pre title="Usage">.your-style {
font-family: 'Inter';
font-weight: 500;
font-style: normal;
}</pre>
<pre title="Preload (optional)">
&lt;link rel=&quot;preload&quot; href=&quot;Inter-Medium.woff2&quot; as=&quot;font&quot; type=&quot;font/woff2&quot; crossorigin&gt;</pre>
<div class="font-container" style="font-family: 'Inter'; font-weight: 500; font-style: normal;">
<p class="letters">
abcdefghijklmnopqrstuvwxyz<br>
ABCDEFGHIJKLMNOPQRSTUVWXYZ<br>
0123456789.:,;()*!?'@#&lt;&gt;$%&^+-=~
</p>
<p class="s10" style="font-size: 10px;">The quick brown fox jumps over the lazy dog.</p>
<p class="s11" style="font-size: 11px;">The quick brown fox jumps over the lazy dog.</p>
<p class="s12" style="font-size: 12px;">The quick brown fox jumps over the lazy dog.</p>
<p class="s14" style="font-size: 14px;">The quick brown fox jumps over the lazy dog.</p>
<p class="s18" style="font-size: 18px;">The quick brown fox jumps over the lazy dog.</p>
<p class="s24" style="font-size: 24px;">The quick brown fox jumps over the lazy dog.</p>
<p class="s30" style="font-size: 30px;">The quick brown fox jumps over the lazy dog.</p>
<p class="s36" style="font-size: 36px;">The quick brown fox jumps over the lazy dog.</p>
<p class="s48" style="font-size: 48px;">The quick brown fox jumps over the lazy dog.</p>
<p class="s60" style="font-size: 60px;">The quick brown fox jumps over the lazy dog.</p>
<p class="s72" style="font-size: 72px;">The quick brown fox jumps over the lazy dog.</p>
</div>
</div>
<div class="demo">
<h1 style="font-family: 'Inter'; font-weight: bold; font-style: normal;">Inter Bold</h1>
<pre title="Usage">.your-style {
font-family: 'Inter';
font-weight: bold;
font-style: normal;
}</pre>
<pre title="Preload (optional)">
&lt;link rel=&quot;preload&quot; href=&quot;Inter-Bold.woff2&quot; as=&quot;font&quot; type=&quot;font/woff2&quot; crossorigin&gt;</pre>
<div class="font-container" style="font-family: 'Inter'; font-weight: bold; font-style: normal;">
<p class="letters">
abcdefghijklmnopqrstuvwxyz<br>
ABCDEFGHIJKLMNOPQRSTUVWXYZ<br>
0123456789.:,;()*!?'@#&lt;&gt;$%&^+-=~
</p>
<p class="s10" style="font-size: 10px;">The quick brown fox jumps over the lazy dog.</p>
<p class="s11" style="font-size: 11px;">The quick brown fox jumps over the lazy dog.</p>
<p class="s12" style="font-size: 12px;">The quick brown fox jumps over the lazy dog.</p>
<p class="s14" style="font-size: 14px;">The quick brown fox jumps over the lazy dog.</p>
<p class="s18" style="font-size: 18px;">The quick brown fox jumps over the lazy dog.</p>
<p class="s24" style="font-size: 24px;">The quick brown fox jumps over the lazy dog.</p>
<p class="s30" style="font-size: 30px;">The quick brown fox jumps over the lazy dog.</p>
<p class="s36" style="font-size: 36px;">The quick brown fox jumps over the lazy dog.</p>
<p class="s48" style="font-size: 48px;">The quick brown fox jumps over the lazy dog.</p>
<p class="s60" style="font-size: 60px;">The quick brown fox jumps over the lazy dog.</p>
<p class="s72" style="font-size: 72px;">The quick brown fox jumps over the lazy dog.</p>
</div>
</div>
</div>
</body>
</html>
+48
View File
@@ -0,0 +1,48 @@
@font-face {
font-family: 'Inter';
src: url('Inter-SemiBold.eot');
src: url('Inter-SemiBold.eot?#iefix') format('embedded-opentype'),
url('Inter-SemiBold.woff2') format('woff2'),
url('Inter-SemiBold.woff') format('woff'),
url('Inter-SemiBold.ttf') format('truetype');
font-weight: 600;
font-style: normal;
font-display: swap;
}
@font-face {
font-family: 'Inter';
src: url('Inter-Regular.eot');
src: url('Inter-Regular.eot?#iefix') format('embedded-opentype'),
url('Inter-Regular.woff2') format('woff2'),
url('Inter-Regular.woff') format('woff'),
url('Inter-Regular.ttf') format('truetype');
font-weight: normal;
font-style: normal;
font-display: swap;
}
@font-face {
font-family: 'Inter';
src: url('Inter-Medium.eot');
src: url('Inter-Medium.eot?#iefix') format('embedded-opentype'),
url('Inter-Medium.woff2') format('woff2'),
url('Inter-Medium.woff') format('woff'),
url('Inter-Medium.ttf') format('truetype');
font-weight: 500;
font-style: normal;
font-display: swap;
}
@font-face {
font-family: 'Inter';
src: url('Inter-Bold.eot');
src: url('Inter-Bold.eot?#iefix') format('embedded-opentype'),
url('Inter-Bold.woff2') format('woff2'),
url('Inter-Bold.woff') format('woff'),
url('Inter-Bold.ttf') format('truetype');
font-weight: bold;
font-style: normal;
font-display: swap;
}
+23 -44
View File
@@ -30,8 +30,8 @@ function App() {
state.isOpen,
state.setIsOpen,
]);
const [loading, setLoading] = useState<boolean>(false);
const [countdownTimer, setCountdownTimer] = useState(15);
// const [loading, setLoading] = useState<boolean>(false);
// const [countdownTimer, setCountdownTimer] = useState(15);
const { t, i18n } = useTranslation();
const build = searchParams.get("build") || null;
const type = searchParams.get("type") || "demo";
@@ -86,7 +86,7 @@ function App() {
console.log("location", location);
setLoading(true);
// setLoading(true);
try {
const response: any = await ky
@@ -100,29 +100,34 @@ function App() {
if (response.stream) {
setStreamUrl(`/stream/${response.stream}`);
setInterval(() => {
setCountdownTimer((prev) => prev - 1);
}, 1000);
// setInterval(() => {
// setCountdownTimer((prev) => prev - 1);
// }, 1000);
} else if (response.error) {
toastError(response.error);
setLoading(false);
// setLoading(false);
} else {
toastError("Неизвестная ошибка");
setLoading(false);
// setLoading(false);
}
} catch (error) {
if (error instanceof Error) {
toastError(`Неизвестная ошибка 2: ${error.message}`);
}
setLoading(false);
// setLoading(false);
}
}
// useEffect(() => {
// if (countdownTimer > 0 || !streamUrl) return;
// navigate(streamUrl);
// }, [countdownTimer]);
useEffect(() => {
if (countdownTimer > 0 || !streamUrl) return;
if (!streamUrl) return;
navigate(streamUrl);
}, [countdownTimer]);
}, [streamUrl]);
useEffect(() => {
getLang();
@@ -137,8 +142,6 @@ function App() {
}, [i18n.language]);
return (
<>
{!loading ? (
<>
<div className="min-h-screen bg-[#14161F] text-white overflow-hidden">
<div className="container mx-auto 2xl:px-10 lg:px-8 sm:px-6 px-4 max-w-[1600px]">
@@ -161,10 +164,9 @@ function App() {
</p>
<p className="lg:w-[368px] lg:text-base text-sm">
<Trans i18nKey={"main.desc"}>
Клиент из любой точки мира может посмотреть жилой
комплекс, даже на нулевом этапе строительства. Он выберет
лучшую планировку и оценит вид из окон своей будущей
квартиры.
Клиент из любой точки мира может посмотреть жилой комплекс,
даже на нулевом этапе строительства. Он выберет лучшую
планировку и оценит вид из окон своей будущей квартиры.
</Trans>
</p>
</div>
@@ -337,9 +339,7 @@ function App() {
className="flex gap-0 p-2 transition-all duration-300 rounded-full bg-gradient group-hover:gap-1 group-hover:pr-4 group-hover:pl-6"
>
<span className="font-medium w-0 opacity-0 group-hover:w-[82px] group-hover:opacity-100 overflow-hidden transition-all duration-300">
<Trans i18nKey={"main.cards.button"}>
Запустить
</Trans>
<Trans i18nKey={"main.cards.button"}>Запустить</Trans>
</span>
<ArrowRightIcon />
</button>
@@ -510,10 +510,7 @@ function App() {
</div>
<div className="flex flex-col gap-4 sm:gap-1">
<p className="flex flex-col gap-1 sm:flex-row sm:gap-4">
<a
href="https://graff.tech/privacypolicy"
target="_blank"
>
<a href="https://graff.tech/privacypolicy" target="_blank">
<Trans i18nKey={"footer.link"}>
Политика конфиденциальности
</Trans>
@@ -524,9 +521,7 @@ function App() {
</p>
<p className="text-xs text-[#C5C7CE]">
© 2023 GRAFF interactive.{" "}
<Trans i18nKey={"footer.text"}>
Все права защищены.
</Trans>
<Trans i18nKey={"footer.text"}>Все права защищены.</Trans>
</p>
</div>
</div>
@@ -565,22 +560,6 @@ function App() {
<ToastContainer />
</>
) : (
<div className="bg-[#14161F] h-screen flex justify-center items-center">
<p className="flex items-center self-center gap-4 text-white w-fit font-gilroy">
<img
src="/icons/Loader.png"
alt=""
className="w-6 h-6 animate-spin"
/>
<span>
<Trans i18nKey="loading">Загрузка</Trans>
... {countdownTimer} <Trans i18nKey="loadingSub">сек</Trans>
</span>
</p>
</div>
)}
</>
);
}
+1 -1
View File
@@ -5,7 +5,7 @@ function ModalContainer2() {
return (
<div
className={`fixed top-0 left-0 w-full h-full ${
className={`fixed top-0 left-0 w-full h-full flex items-center justify-center ${
!modal ? "hidden" : ""
}`}
>
+19 -7
View File
@@ -10,6 +10,9 @@ import CloseIcon from "./icons/CloseIcon";
import { useState } from "react";
import { useClickAway } from "@uidotdev/usehooks";
import SpinnerIcon from "./icons/SpinnerIcon";
import InternetSpeedHighIcon from "./icons/InternetSpeedHighIcon";
import InternetSpeedMediumIcon from "./icons/InternetSpeedMediumIcon";
import InternetSpeedLowIcon from "./icons/InternetSpeedLowIcon";
interface Props {
me: IUser;
@@ -28,21 +31,30 @@ function User({ me, user, handleTransferControl, handleKick }: Props) {
return (
<div key={user.id} className="flex items-center justify-between gap-2">
<div
className={`flex items-center gap-2 ${
className={`transition-all flex items-center gap-2 ${
!user.isVideoInitialized ? "opacity-50" : ""
}`}
>
<div className="relative w-6 h-6 bg-[#E6ECF2] rounded-full flex items-center justify-center">
<p className="text-xs font-semibold">{user.name[0]?.toUpperCase()}</p>
{user?.isControlAllowed && (
<div className="absolute bottom-0 right-0 bg-[#49A1F5] w-2 h-2 rounded-full border border-white"></div>
)}
{!user.isVideoInitialized ? (
<div className="-mt-0.5 flex items-center justify-center w-5 h-5">
<SpinnerIcon />
</div>
) : (
<div className="-mt-0.5">
{(user.downloadSpeed < 10 && <InternetSpeedLowIcon />) ||
(user.downloadSpeed < 20 && <InternetSpeedMediumIcon />) ||
(user.downloadSpeed >= 20 && <InternetSpeedHighIcon />)}
</div>
)}
<p className="text-xs">{user.name}</p>
<div className="text-[#CCCCCC]">
{isMobile ? <MobileIcon /> : <DesktopIcon />}
</div>
{!user.isVideoInitialized && <SpinnerIcon />}
{user?.isControlAllowed && (
<HandOnIcon className="w-5 h-5 text-[#77828C]" />
)}
</div>
{me.isAdmin && (
@@ -0,0 +1,20 @@
function InternetSpeedHighIcon() {
return (
<svg
width={21}
height={20}
viewBox="0 0 21 20"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
fillRule="evenodd"
clipRule="evenodd"
d="M3.94148 8.78912C7.72935 5.07029 13.8709 5.07029 17.6581 8.78912C17.7032 8.83334 17.739 8.88585 17.7633 8.94365C17.7877 9.00144 17.8003 9.06339 17.8003 9.12595C17.8003 9.18852 17.7877 9.25046 17.7633 9.30826C17.739 9.36606 17.7032 9.41857 17.6581 9.46279L17.3154 9.79931C17.2245 9.88848 17.1012 9.93857 16.9727 9.93857C16.8442 9.93857 16.721 9.88848 16.63 9.79931C13.4099 6.63795 8.18974 6.63795 4.97024 9.79931C4.87931 9.88848 4.75605 9.93857 4.62753 9.93857C4.49902 9.93857 4.37576 9.88848 4.28483 9.79931L3.94212 9.46279C3.8513 9.3735 3.80029 9.25247 3.80029 9.12627C3.80029 9.00008 3.8513 8.87904 3.94212 8.78976L3.94148 8.78912ZM5.99901 10.8095C8.65013 8.20625 12.9495 8.20625 15.6013 10.8095C15.6463 10.8537 15.6821 10.9062 15.7065 10.964C15.7309 11.0218 15.7434 11.0838 15.7434 11.1463C15.7434 11.2089 15.7309 11.2708 15.7065 11.3286C15.6821 11.3864 15.6463 11.4389 15.6013 11.4832L15.2585 11.8197C15.2135 11.864 15.16 11.8992 15.1011 11.9232C15.0421 11.9472 14.979 11.9596 14.9152 11.9596C14.8514 11.9596 14.7882 11.9472 14.7293 11.9232C14.6704 11.8992 14.6169 11.864 14.5718 11.8197C13.5714 10.8374 12.2146 10.2855 10.7998 10.2855C9.38503 10.2855 8.02819 10.8374 7.02777 11.8197C6.93684 11.9089 6.81358 11.9589 6.68507 11.9589C6.55655 11.9589 6.43329 11.9089 6.34236 11.8197L5.99965 11.4832C5.90884 11.3939 5.85783 11.2728 5.85783 11.1466C5.85783 11.0204 5.90884 10.8994 5.99965 10.8101L5.99901 10.8095ZM8.07077 12.8299C8.43104 12.476 8.85876 12.1954 9.32951 12.0039C9.80026 11.8124 10.3048 11.7138 10.8144 11.7138C11.3239 11.7138 11.8285 11.8124 12.2992 12.0039C12.77 12.1954 13.1977 12.476 13.5579 12.8299C13.603 12.8741 13.6388 12.9266 13.6632 12.9844C13.6875 13.0422 13.7001 13.1041 13.7001 13.1667C13.7001 13.2293 13.6875 13.2912 13.6632 13.349C13.6388 13.4068 13.603 13.4593 13.5579 13.5035L13.2152 13.84C13.1702 13.8843 13.1167 13.9194 13.0579 13.9434C12.999 13.9673 12.9359 13.9796 12.8722 13.9796C12.8085 13.9796 12.7454 13.9673 12.6866 13.9434C12.6277 13.9194 12.5742 13.8843 12.5292 13.84C12.304 13.6189 12.0367 13.4434 11.7424 13.3237C11.4482 13.204 11.1328 13.1424 10.8144 13.1424C10.4959 13.1424 10.1805 13.204 9.88627 13.3237C9.59204 13.4434 9.3247 13.6189 9.09953 13.84C9.0086 13.9292 8.88534 13.9793 8.75682 13.9793C8.62831 13.9793 8.50505 13.9292 8.41412 13.84L8.07141 13.5035C7.98059 13.4142 7.92958 13.2932 7.92958 13.167C7.92958 13.0408 7.98059 12.9198 8.07141 12.8305L8.07077 12.8299ZM10.1283 14.8502C10.2184 14.7617 10.3253 14.6915 10.443 14.6436C10.5608 14.5957 10.6869 14.5711 10.8144 14.5711C10.9418 14.5711 11.068 14.5957 11.1857 14.6436C11.3034 14.6915 11.4103 14.7617 11.5004 14.8502C11.5455 14.8945 11.5812 14.947 11.6056 15.0048C11.63 15.0626 11.6426 15.1245 11.6426 15.1871C11.6426 15.2496 11.63 15.3116 11.6056 15.3694C11.5812 15.4272 11.5455 15.4797 11.5004 15.5239L11.1577 15.8604C11.1127 15.9047 11.0592 15.9398 11.0003 15.9637C10.9415 15.9877 10.8784 16 10.8147 16C10.751 16 10.6879 15.9877 10.629 15.9637C10.5702 15.9398 10.5167 15.9047 10.4717 15.8604L10.1289 15.5239C10.0381 15.4346 9.98712 15.3136 9.98712 15.1874C9.98712 15.0612 10.0381 14.9402 10.1289 14.8509L10.1283 14.8502Z"
fill="#27AE60"
/>
</svg>
);
}
export default InternetSpeedHighIcon;
@@ -0,0 +1,28 @@
function InternetSpeedLowIcon() {
return (
<svg
width={21}
height={20}
viewBox="0 0 21 20"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
fillRule="evenodd"
clipRule="evenodd"
d="M8.07052 12.8299C8.43079 12.476 8.85852 12.1954 9.32927 12.0039C9.80001 11.8124 10.3046 11.7138 10.8141 11.7138C11.3237 11.7138 11.8282 11.8124 12.299 12.0039C12.7697 12.1954 13.1974 12.476 13.5577 12.8299C13.6028 12.8741 13.6385 12.9266 13.6629 12.9844C13.6873 13.0422 13.6999 13.1041 13.6999 13.1667C13.6999 13.2293 13.6873 13.2912 13.6629 13.349C13.6385 13.4068 13.6028 13.4593 13.5577 13.5035L13.215 13.84C13.17 13.8843 13.1165 13.9194 13.0576 13.9434C12.9988 13.9673 12.9357 13.9796 12.872 13.9796C12.8083 13.9796 12.7452 13.9673 12.6863 13.9434C12.6275 13.9194 12.574 13.8843 12.5289 13.84C12.3038 13.6189 12.0364 13.4434 11.7422 13.3237C11.448 13.204 11.1326 13.1424 10.8141 13.1424C10.4956 13.1424 10.1803 13.204 9.88603 13.3237C9.5918 13.4434 9.32446 13.6189 9.09929 13.84C9.00836 13.9292 8.8851 13.9793 8.75658 13.9793C8.62807 13.9793 8.5048 13.9292 8.41387 13.84L8.07117 13.5035C7.98035 13.4142 7.92934 13.2932 7.92934 13.167C7.92934 13.0408 7.9797 12.9191 8.07052 12.8299ZM10.1281 14.8502C10.2181 14.7617 10.3251 14.6915 10.4428 14.6436C10.5605 14.5957 10.6867 14.5711 10.8141 14.5711C10.9415 14.5711 11.0677 14.5957 11.1854 14.6436C11.3031 14.6915 11.4101 14.7617 11.5002 14.8502C11.5452 14.8945 11.581 14.947 11.6054 15.0048C11.6298 15.0626 11.6423 15.1245 11.6423 15.1871C11.6423 15.2496 11.6298 15.3116 11.6054 15.3694C11.581 15.4272 11.5452 15.4797 11.5002 15.5239L11.1575 15.8604C11.1124 15.9047 11.059 15.9398 11.0001 15.9637C10.9412 15.9877 10.8781 16 10.8144 16C10.7507 16 10.6876 15.9877 10.6288 15.9637C10.5699 15.9398 10.5164 15.9047 10.4714 15.8604L10.1287 15.5239C10.0379 15.4346 9.98687 15.3136 9.98687 15.1874C9.98687 15.0612 10.0372 14.9395 10.1281 14.8502Z"
fill="#EB5757"
/>
<path
d="M5.99876 10.8095C8.64989 8.20625 12.9492 8.20625 15.601 10.8095C15.6461 10.8537 15.6818 10.9062 15.7062 10.964C15.7306 11.0218 15.7432 11.0838 15.7432 11.1463C15.7432 11.2089 15.7306 11.2708 15.7062 11.3286C15.6818 11.3864 15.6461 11.4389 15.601 11.4832L15.2583 11.8197C15.2133 11.864 15.1597 11.8992 15.1008 11.9232C15.0419 11.9472 14.9787 11.9596 14.915 11.9596C14.8512 11.9596 14.788 11.9472 14.7291 11.9232C14.6702 11.8992 14.6166 11.864 14.5716 11.8197C13.5712 10.8374 12.2143 10.2855 10.7996 10.2855C9.38479 10.2855 8.02795 10.8374 7.02753 11.8197C6.9366 11.9089 6.81334 11.9589 6.68482 11.9589C6.55631 11.9589 6.43305 11.9089 6.34212 11.8197L5.99941 11.4832C5.90859 11.3939 5.85758 11.2728 5.85758 11.1466C5.85758 11.0204 5.90795 10.8988 5.99876 10.8095Z"
fill="#CDCDCD"
/>
<path
d="M3.94123 8.78912C7.72911 5.07029 13.8707 5.07029 17.6579 8.78912C17.703 8.83334 17.7387 8.88585 17.7631 8.94365C17.7875 9.00144 17.8 9.06339 17.8 9.12595C17.8 9.18852 17.7875 9.25046 17.7631 9.30826C17.7387 9.36606 17.703 9.41857 17.6579 9.46279L17.3152 9.79931C17.2243 9.88848 17.101 9.93857 16.9725 9.93857C16.844 9.93857 16.7207 9.88848 16.6298 9.79931C13.4096 6.63795 8.1895 6.63795 4.97 9.79931C4.87907 9.88848 4.75581 9.93857 4.62729 9.93857C4.49878 9.93857 4.37551 9.88848 4.28458 9.79931L3.94188 9.46279C3.85106 9.3735 3.80005 9.25247 3.80005 9.12627C3.80005 9.00008 3.85041 8.87841 3.94123 8.78912Z"
fill="#CDCDCD"
/>
</svg>
);
}
export default InternetSpeedLowIcon;
@@ -0,0 +1,24 @@
function InternetSpeedMediumIcon() {
return (
<svg
width={21}
height={20}
viewBox="0 0 21 20"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
fillRule="evenodd"
clipRule="evenodd"
d="M15.6008 10.8095C12.949 8.20625 8.64964 8.20625 5.99852 10.8095C5.9077 10.8988 5.85734 11.0204 5.85734 11.1466C5.85734 11.2728 5.90835 11.3939 5.99917 11.4832L6.34187 11.8197C6.4328 11.9089 6.55606 11.9589 6.68458 11.9589C6.81309 11.9589 6.93635 11.9089 7.02729 11.8197C8.02771 10.8374 9.38454 10.2855 10.7993 10.2855C12.2141 10.2855 13.5709 10.8374 14.5714 11.8197C14.6164 11.864 14.6699 11.8992 14.7288 11.9232C14.7878 11.9472 14.8509 11.9596 14.9147 11.9596C14.9785 11.9596 15.0417 11.9472 15.1006 11.9232C15.1595 11.8992 15.213 11.864 15.2581 11.8197L15.6008 11.4832C15.6458 11.4389 15.6816 11.3864 15.706 11.3286C15.7304 11.2708 15.7429 11.2089 15.7429 11.1463C15.7429 11.0838 15.7304 11.0218 15.706 10.964C15.6816 10.9062 15.6458 10.8537 15.6008 10.8095ZM9.32902 12.0039C8.85827 12.1954 8.43055 12.476 8.07028 12.8299C7.97946 12.9191 7.92909 13.0408 7.92909 13.167C7.92909 13.2932 7.98011 13.4142 8.07092 13.5035L8.41363 13.84C8.50456 13.9292 8.62782 13.9793 8.75634 13.9793C8.88485 13.9793 9.00811 13.9292 9.09904 13.84C9.32421 13.6189 9.59155 13.4434 9.88579 13.3237C10.18 13.204 10.4954 13.1424 10.8139 13.1424C11.1324 13.1424 11.4477 13.204 11.742 13.3237C12.0362 13.4434 12.3035 13.6189 12.5287 13.84C12.5737 13.8843 12.6272 13.9194 12.6861 13.9434C12.7449 13.9673 12.808 13.9796 12.8717 13.9796C12.9354 13.9796 12.9985 13.9673 13.0574 13.9434C13.1162 13.9194 13.1697 13.8843 13.2148 13.84L13.5575 13.5035C13.6025 13.4593 13.6383 13.4068 13.6627 13.349C13.6871 13.2912 13.6996 13.2293 13.6996 13.1667C13.6996 13.1041 13.6871 13.0422 13.6627 12.9844C13.6383 12.9266 13.6025 12.8741 13.5575 12.8299C13.1972 12.476 12.7695 12.1954 12.2987 12.0039C11.828 11.8124 11.3234 11.7138 10.8139 11.7138C10.3043 11.7138 9.79977 11.8124 9.32902 12.0039ZM10.4426 14.6436C10.3248 14.6915 10.2179 14.7617 10.1278 14.8502C10.037 14.9395 9.98663 15.0612 9.98663 15.1874C9.98663 15.3136 10.0376 15.4346 10.1285 15.5239L10.4712 15.8604C10.5162 15.9047 10.5697 15.9398 10.6285 15.9637C10.6874 15.9877 10.7505 16 10.8142 16C10.8779 16 10.941 15.9877 10.9998 15.9637C11.0587 15.9398 11.1122 15.9047 11.1572 15.8604L11.4999 15.5239C11.545 15.4797 11.5807 15.4272 11.6051 15.3694C11.6295 15.3116 11.6421 15.2496 11.6421 15.1871C11.6421 15.1245 11.6295 15.0626 11.6051 15.0048C11.5807 14.947 11.545 14.8945 11.4999 14.8502C11.4099 14.7617 11.3029 14.6915 11.1852 14.6436C11.0675 14.5957 10.9413 14.5711 10.8139 14.5711C10.6864 14.5711 10.5603 14.5957 10.4426 14.6436Z"
fill="#F2994A"
/>
<path
d="M3.94099 8.78912C7.72886 5.07029 13.8704 5.07029 17.6577 8.78912C17.7027 8.83334 17.7385 8.88585 17.7629 8.94365C17.7872 9.00144 17.7998 9.06339 17.7998 9.12595C17.7998 9.18852 17.7872 9.25046 17.7629 9.30826C17.7385 9.36606 17.7027 9.41857 17.6577 9.46279L17.3149 9.79931C17.224 9.88848 17.1008 9.93857 16.9722 9.93857C16.8437 9.93857 16.7205 9.88848 16.6295 9.79931C13.4094 6.63795 8.18925 6.63795 4.96975 9.79931C4.87882 9.88848 4.75556 9.93857 4.62705 9.93857C4.49853 9.93857 4.37527 9.88848 4.28434 9.79931L3.94163 9.46279C3.85082 9.3735 3.7998 9.25247 3.7998 9.12627C3.7998 9.00008 3.85017 8.87841 3.94099 8.78912Z"
fill="#CDCDCD"
/>
</svg>
);
}
export default InternetSpeedMediumIcon;
+10 -54
View File
@@ -1,63 +1,19 @@
function SpinnerIcon() {
return (
<svg
width={24}
height={24}
width={16}
height={16}
stroke="#000"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
className="w-4 h-4"
>
<g>
<rect x={11} y={1} width={2} height={5} opacity={0.14} />
<rect
x={11}
y={1}
width={2}
height={5}
transform="rotate(30 12 12)"
opacity={0.29}
/>
<rect
x={11}
y={1}
width={2}
height={5}
transform="rotate(60 12 12)"
opacity={0.43}
/>
<rect
x={11}
y={1}
width={2}
height={5}
transform="rotate(90 12 12)"
opacity={0.57}
/>
<rect
x={11}
y={1}
width={2}
height={5}
transform="rotate(120 12 12)"
opacity={0.71}
/>
<rect
x={11}
y={1}
width={2}
height={5}
transform="rotate(150 12 12)"
opacity={0.86}
/>
<rect x={11} y={1} width={2} height={5} transform="rotate(180 12 12)" />
<animateTransform
attributeName="transform"
type="rotate"
calcMode="discrete"
dur="0.75s"
values="0 12 12;30 12 12;60 12 12;90 12 12;120 12 12;150 12 12;180 12 12;210 12 12;240 12 12;270 12 12;300 12 12;330 12 12;360 12 12"
repeatCount="indefinite"
/>
<style>
{
".spinner_V8m1{transform-origin:center;animation:spinner_zKoa 2s linear infinite}.spinner_V8m1 circle{stroke-linecap:round;animation:spinner_YpZS 1.5s ease-in-out infinite}@keyframes spinner_zKoa{100%{transform:rotate(360deg)}}@keyframes spinner_YpZS{0%{stroke-dasharray:0 150;stroke-dashoffset:0}47.5%{stroke-dasharray:42 150;stroke-dashoffset:-16}95%,100%{stroke-dasharray:42 150;stroke-dashoffset:-59}}"
}
</style>
<g className="spinner_V8m1">
<circle cx={12} cy={12} r={9.5} fill="none" strokeWidth={3} />
</g>
</svg>
);
@@ -0,0 +1,58 @@
/* eslint-disable @typescript-eslint/no-non-null-assertion */
/* eslint-disable react-hooks/exhaustive-deps */
import { useEffect, useRef } from "react";
import { useSpeedtest } from "../../../hooks/useSpeedtest";
import { useCountdown } from "usehooks-ts";
interface Props {
onSuccess: (downloadSpeed: number) => void;
}
function SpeedtestModal({ onSuccess }: Props) {
const [downloadSpeed] = useSpeedtest();
const downloadSpeedRef = useRef<number>();
downloadSpeedRef.current = downloadSpeed;
const [counter, { startCountdown }] = useCountdown({ countStart: 15 });
useEffect(() => {
console.log("SpeedtestModal - downloadSpeed", downloadSpeed);
}, [downloadSpeed]);
useEffect(() => {
startCountdown();
setTimeout(() => {
onSuccess(downloadSpeedRef.current!);
}, 15000);
}, []);
return (
<div className="p-12 bg-white rounded-lg w-[494px] shadow">
<div className="space-y-4 pb-6 border-b border-[#DAE0E5]">
<p className="text-2xl font-semibold leading-[24px]">
Пожалуйста, подождите
</p>
<p className="text-sm text-[#77828C]">
Проверяем качество вашего
<br />
интернет-соединения
</p>
</div>
<div className="pt-6 space-y-3">
<div className="flex items-center justify-between">
<p>Проверка</p>
<p className="text-[#49A1F5]">Осталось {counter} секунд</p>
</div>
<div className="h-1.5 bg-[#F0F1F2] rounded-lg">
<div className="h-full bg-[#49A1F5] rounded-lg animate-progress"></div>
</div>
{/* <div className="grid w-1/4 grid-cols-2 gap-2">
<p className="text-[#77828C]">{downloadSpeed.toFixed(1)}</p>
<p className="text-[#77828C]">MBit/s</p>
</div> */}
</div>
</div>
);
}
export default SpeedtestModal;
+32
View File
@@ -0,0 +1,32 @@
import { useEffect, useState } from "react";
import { v4 as uuidv4 } from "uuid";
export function useSpeedtest() {
const [downloadSpeed, setDownloadSpeed] = useState<number>(0);
const [loadedEnd, setLoadedEnd] = useState(false);
function speedtest() {
const startTime = performance.now();
const xhr = new XMLHttpRequest();
let elapsedTime = 0; // seconds
let loaded = 0; // seconds
xhr.open("get", `https://files.graff.tech/static/download?uuid=${uuidv4()}`);
xhr.timeout = 15000;
xhr.onprogress = (e) => {
loaded = e.loaded / 1024000;
elapsedTime = (performance.now() - startTime) / 1000;
setDownloadSpeed((loaded / elapsedTime) * 8);
};
xhr.onloadend = () => setLoadedEnd(true);
xhr.send();
}
useEffect(() => {
speedtest();
}, []);
return [downloadSpeed, loadedEnd] as const;
}
+17 -2
View File
@@ -1,5 +1,5 @@
@import url("https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap");
@import url("https://gistcdn.githack.com/mfd/09b70eb47474836f25a21660282ce0fd/raw/e06a670afcb2b861ed2ac4a1ef752d062ef6b46b/Gilroy.css");
@import url("/fonts/Inter/stylesheet.css");
@import url("/fonts/Gilroy/stylesheet.css");
@tailwind base;
@tailwind components;
@@ -63,3 +63,18 @@ input {
*::-webkit-scrollbar-thumb:hover {
border-width: 2px;
}
/* Animation */
.animate-progress {
animation: progress 15s ease-in-out;
}
@keyframes progress {
from {
width: 0;
}
to {
width: 100%;
}
}
+52 -13
View File
@@ -45,6 +45,10 @@ import ChatIcon from "../components/icons/ChatIcon";
import useChatStore from "../stores/useChatStore";
import UsersIcon from "../components/icons/UsersIcon";
import Users from "../components/Users";
import SpeedtestModal from "../components/modals/stream/SpeedtestModal";
import InternetSpeedHighIcon from "../components/icons/InternetSpeedHighIcon";
import InternetSpeedLowIcon from "../components/icons/InternetSpeedLowIcon";
import InternetSpeedMediumIcon from "../components/icons/InternetSpeedMediumIcon";
// import ChatIcon from "../components/icons/ChatIcon";
// import MoreIcon from "../components/icons/MoreIcon";
@@ -87,6 +91,9 @@ function StreamPage() {
const [isShowUsers, setIsShowUsers] = useState<boolean>(false);
const { isPortrait } = useMobileOrientation();
const { setMessages } = useChatStore();
const [activeSession, setActiveSession, activeSessionRef] =
useStateRef<any>();
const [downloadSpeed, setDownloadSpeed] = useState(0);
async function startCall(remotePeerId: string) {
if (!peerInstance) return;
@@ -138,12 +145,14 @@ function StreamPage() {
}
function initPeer() {
console.log("initPeer");
const peer = new Peer({
host: "stream.graff.tech",
config: {
iceServers: [
{
urls: "turn:194.26.138.94:3478", // Replace with your TURN server URL
urls: "turn:185.173.176.83:3478", // Replace with your TURN server URL
username: "username1", // Replace with your TURN username
credential: "password1", // Replace with your TURN credential
},
@@ -187,6 +196,7 @@ function StreamPage() {
peerId,
superAdmin,
isVideoInitialized,
downloadSpeed,
},
},
});
@@ -284,16 +294,10 @@ function StreamPage() {
}
async function getWSUrl() {
const activeSession = await getActiveSession();
console.log("activeSession", activeSession);
if (!activeSession || activeSession.status === "error") {
setIsEnded(true);
return;
}
setIsEnded(false);
setWSUrl(
`wss://${activeSession.location}.sess.stream.graff.tech/server/${activeSession.localIP}:${activeSession.cirrusPort}`
`wss://${activeSessionRef.current.location}.sess.stream.graff.tech/server/${activeSessionRef.current.localIP}:${activeSessionRef.current.cirrusPort}`
);
setModal(<SetNameModal onAction={handleSetName} />);
@@ -341,12 +345,38 @@ function StreamPage() {
}, 1000);
}
useEffect(() => {
async function init() {
const activeSession = await getActiveSession();
console.log("activeSession init", activeSession);
if (!activeSession || activeSession.status === "error") {
setIsEnded(true);
return;
}
setActiveSession(activeSession);
setIsEnded(false);
setModal(
<SpeedtestModal
onSuccess={(downloadSpeed) => {
setDownloadSpeed(Math.round(downloadSpeed));
getWSUrl();
}}
/>
);
}
useEffect(() => {
init();
// getWSUrl();
// initSocket();
}, []);
useEffect(() => {
console.log("permission", permission);
if (permission === undefined) return;
initPeer();
@@ -410,14 +440,23 @@ function StreamPage() {
</div>
<div className="flex items-center gap-4 max-lg:flex-col">
<div className="items-center hidden gap-2 lg:flex">
<div className="relative w-6 h-6 bg-[#E6ECF2] rounded-full flex items-center justify-center">
{/* <div className="relative w-6 h-6 bg-[#E6ECF2] rounded-full flex items-center justify-center">
<p className="text-xs font-semibold">
{name[0]?.toUpperCase()}
</p>
{me?.isControlAllowed && (
<div className="absolute bottom-0 right-0 bg-[#49A1F5] w-2 h-2 rounded-full border border-white"></div>
)}
</div> */}
{me && (
<div className="-mt-0.5">
{(me.downloadSpeed < 10 && <InternetSpeedLowIcon />) ||
(me.downloadSpeed < 20 && (
<InternetSpeedMediumIcon />
)) ||
(me.downloadSpeed >= 20 && <InternetSpeedHighIcon />)}
</div>
)}
<p className="text-xs">{name}</p>
<div className="text-[#CCCCCC]">
{isMobile ? <MobileIcon /> : <DesktopIcon />}
@@ -506,7 +545,7 @@ function StreamPage() {
/>
<Tooltip
text={
isShowChat
isShowUsers
? "Скрыть участников"
: "Показать участников"
}
@@ -669,8 +708,8 @@ function StreamPage() {
</div>
)}
<ModalContainer2 />
<ToastContainer />
<ModalContainer2 />
</>
)}
+1
View File
@@ -8,6 +8,7 @@ interface IUser {
peerId: string;
micEnabled: boolean;
isVideoInitialized: boolean;
downloadSpeed: number;
}
export default IUser;
+25
View File
@@ -0,0 +1,25 @@
import { v4 as uuidv4 } from "uuid";
export function speedtest() {
return new Promise<number>((resolve) => {
const startTime = performance.now();
const xhr = new XMLHttpRequest();
let elapsedTime = 0; // seconds
let loaded = 0; // seconds
xhr.open("get", `https://files.graff.tech/static/download?uuid=${uuidv4()}`);
xhr.timeout = 15000;
xhr.onprogress = (e) => {
loaded = e.loaded / 1024000;
elapsedTime = (performance.now() - startTime) / 1000;
};
xhr.onloadend = loadedend;
xhr.send();
function loadedend() {
const result = Math.round((loaded / elapsedTime) * 8);
resolve(result);
}
});
}