ui update: test version

This commit is contained in:
VyacheslavShtyrlin
2023-02-20 23:16:07 +05:00
parent f3b411a4de
commit c34d3ae1fe
129 changed files with 1192 additions and 2274 deletions
+4 -4
View File
@@ -8,8 +8,8 @@
"popup-connect-title": "Connection code",
"popup-connect-btn-mode": "Select demonstration mode",
"popup-connect-btn-continue": "Continue",
"fullscreen-control-btn": "Expand",
"fullscreen-control-btn-active": "Collapse",
"fullscreen-control-btn": "Windowed mode",
"fullscreen-control-btn-active": "Fullscreen mode",
"request-control-btn": "Request control",
"request-control-btn-disable": "Stop control",
"mute-control-btn": "Turn On Mic",
@@ -19,9 +19,9 @@
"popup-control-code": "Connection code",
"popup-control-link": "Link for connection",
"popup-control-btn": "Copy",
"popup-control-btn-active": "Copied!",
"popup-control-btn-active": "Link Copied",
"language-control-btn": "Language",
"exit-control-btn": "Exit presintation",
"exit-control-btn": "Exit",
"popup-control-exit-title": "Are you sure you want to end the demo?",
"popup-control-yes": "Finish",
"popup-control-no": "Stay"
+4 -4
View File
@@ -8,8 +8,8 @@
"popup-connect-title": "Код подключения к демонстрации",
"popup-connect-btn-mode": "Выбор способа демонстрации",
"popup-connect-btn-continue": "Продолжить",
"fullscreen-control-btn": "Развернуть",
"fullscreen-control-btn-active": "Свернуть",
"fullscreen-control-btn": "Полноэкранный режим",
"fullscreen-control-btn-active": "Оконный режим",
"request-control-btn": "Запрос управления",
"request-control-btn-disable": "Запрет управления",
"mute-control-btn": "Включить микрофон",
@@ -19,9 +19,9 @@
"popup-control-code": "Код подключения",
"popup-control-link": "Ссылка для подключения",
"popup-control-btn": "Скопировать",
"popup-control-btn-active": "Скопировано",
"popup-control-btn-active": "Ссылка скопирована",
"language-control-btn": "Язык",
"exit-control-btn": "Завершить презентацию",
"exit-control-btn": "Выйти",
"popup-control-exit-title": "Вы уверены, что хотите закончить демонстрацию??",
"popup-control-yes": "Закончить",
"popup-control-no": "Остаться"
+10 -16
View File
@@ -4,8 +4,6 @@
width: 100%;
}
.content__container {
height: 100vh;
width: 400px;
@@ -17,13 +15,18 @@
left: 50%;
border-width: 0px 2px;
border-style: solid;
border-color: #23242A;
border-color: #23242a;
transform: translate(-50%, -50%);
/* This is a shorthand of */
}
.popup {
width: 100%;
background: transparent;
padding: 56px;
box-sizing: border-box;
}
.card-container {
display: flex;
flex-direction: row;
@@ -38,8 +41,7 @@
line-height: 100%;
/* identical to box height, or 38px */
color: #FFFFFF;
color: #ffffff;
}
.demos_container {
@@ -47,12 +49,9 @@
border-radius: 16px;
}
@media screen and (max-width: 1440px) {
.card-title {
margin: 22px 0 40px 0;
}
.card-container {
@@ -67,15 +66,12 @@
.card-title {
margin: 42px 0 40px 0;
}
}
@media screen and (max-width: 920px) {
.card-title {
margin: 36px 0 32px 0;
}
.card-title {
@@ -91,6 +87,4 @@
width: 100%;
border: none;
}
}
+20 -20
View File
@@ -1,22 +1,25 @@
import "./App.css";
import 'styles/styles.css'
import { useEffect } from "react";
import { Redirect, Route, Switch, useHistory } from "react-router-dom";
import { Header } from "./components/header/header";
import { Card } from "./components/demos/Card";
import { Main } from "./components/Main/Main";
import { PlayerComponent } from "./components/playerComponent/playerComponent";
import { useAppDispatch, useAppSelector } from "./hooks/redux";
import { fetchCards } from "./store/reducers/ActionCreator";
import { cardSlice } from "./store/reducers/cardSlice";
import { languageSlice } from "./store/reducers/languageSlice";
import { ICards } from "./models/ICards";
import { useTranslation } from "react-i18next";
import cookies from "js-cookie";
const App: React.FC = () => {
import { Header } from "components/shared/Header/Header";
import { Card } from "components/pages/Main/Card/Card";
import { PopupComponent } from "components/pages/ConnectPage/PopupComponent/PopupComponent";
import { PlayerComponent } from "components/pages/Stream/PlayerComponent/PlayerComponent";
import { useAppDispatch, useAppSelector } from "hooks/redux";
import { fetchCards } from "store/reducers/ActionCreator";
import { cardSlice } from "store/reducers/cardSlice";
import { languageSlice } from "store/reducers/languageSlice";
import { ICards } from "models/ICards";
const App: React.FC = () => {
const dispatch = useAppDispatch();
const history = useHistory();
@@ -29,6 +32,9 @@ const App: React.FC = () => {
dispatch(handleChangeLanguage(cookies.get("i18next")));
}, []);
useEffect(() => {
window.screen.orientation.lock("landscape");
}, []);
const handleCards = (card: ICards) => {
dispatch(handleCurrentCard(card));
history.push("/connect-page");
@@ -48,11 +54,7 @@ const App: React.FC = () => {
<h3 className="card-title">{t("demo-title")}</h3>
<div className="card-container">
{cards.map((i: ICards) => (
<Card
onClick={() => handleCards(i)}
key={i._id}
item={i}
></Card>
<Card onClick={() => handleCards(i)} key={i._id} item={i}></Card>
))}
</div>
</div>
@@ -62,7 +64,7 @@ const App: React.FC = () => {
<div className="background">
<Header></Header>
<div className="content__container">
<Main></Main>
<PopupComponent></PopupComponent>
</div>
</div>
) : (
@@ -70,9 +72,7 @@ const App: React.FC = () => {
)}
</Route>
<Route exact path="/stream/:id">
<PlayerComponent
closeStream={closeStream}
></PlayerComponent>
<PlayerComponent closeStream={closeStream}></PlayerComponent>
</Route>
</Switch>
);
-60
View File
@@ -1,60 +0,0 @@
.exit-popup-container {
position: absolute;
display: flex;
flex-direction: column;
width: 494px;
height: 330px;
box-sizing: border-box;
border: 1px solid #4F4F4F;
border-radius: 32px;
top: calc(50% - 469px / 2);
left: calc(50% - 494px / 2);
background-color: #333333;
color: #FFFFFF;
padding: 48px;
/* gap: 24px; */
justify-content: space-between;
}
.exit-popup-button-container {
display: flex;
flex-direction: column;
gap: 24px;
}
.exit-popup-button {
border-radius: 12px;
border: none;
color: white;
height: 60px;
font-style: normal;
font-weight: 600;
font-size: 16px;
line-height: 20px;
cursor: pointer;
}
.exit-popup-button_confirm {
background: #567ECE;
opacity: 1;
}
.exit-popup-button_finish {
background: #404040;
}
.exit-popup-button-title {
width: 366px;
}
.exit-popup-button_confirm:hover {
opacity: 0.7;
transition: .3s;
}
.exit-popup-header {
align-items: normal;
}
-36
View File
@@ -1,36 +0,0 @@
import "../PopupShare/sharePopup.css";
import "./ExitPopup.css";
import { TSidebarPopup } from "../../utils/types";
import { useTranslation } from "react-i18next";
export const ExitPopup: React.FC<TSidebarPopup> = ({ setClose, onExit }) => {
const { t } = useTranslation();
return (
<div className="exit-popup-container">
<div className="mobile-users-part-header exit-popup-header">
<span className="mobile-users-part-header-title exit-popup-button-title">
{t("popup-control-exit-title")}
</span>
<button
onClick={() => setClose()}
className="mobile-users-part-header-close-button"
></button>
</div>
<div className="exit-popup-button-container">
<button
onClick={() => setClose()}
className="exit-popup-button exit-popup-button_confirm"
>
{t("popup-control-no")}
</button>
<button
onClick={() => onExit?.()}
className="exit-popup-button exit-popup-button_finish"
>
{t("popup-control-yes")}
</button>
</div>
</div>
);
};
@@ -1,38 +0,0 @@
import "../sidebar/toolbar.css";
import { languageSlice } from "../../store/reducers/languageSlice";
import { useAppDispatch, useAppSelector } from "../../hooks/redux";
export const LanguagePopup: React.FC<any> = ({ setOpen }) => {
const { handleChangeLanguage } = languageSlice.actions;
const buttons = [{ value: "ru" }, { value: "en" }];
const dispatch = useAppDispatch();
const onChange = (value: string) => {
dispatch(handleChangeLanguage(value));
setOpen(false);
};
const { currentLang } = useAppSelector((state) => state.languageReducer);
return (
<div className="toolbar-language-popup">
{buttons.map((i) => (
<div className="toolbar-button-area">
<button
key={i.value}
value={i.value}
onClick={(e: any) => onChange(e.target.value)}
className={
currentLang === i.value
? "toolbar-button toolbar-button-active"
: "toolbar-button"
}
>
{i.value.toUpperCase()}
</button>
</div>
))}
</div>
);
};
Binary file not shown.

Before

Width:  |  Height:  |  Size: 189 B

-3
View File
@@ -1,3 +0,0 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M12 12L16.9996 17M12 12L17 7M12 12L7 17M12 12L7.00002 7" stroke="white" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

Before

Width:  |  Height:  |  Size: 233 B

-112
View File
@@ -1,112 +0,0 @@
.navigation {
display: flex;
flex-direction: column;
color: #E3DDE5;
padding: 8px 10px;
box-sizing: border-box;
position: fixed;
top: 66px;
right: 0;
bottom: 0;
background: #0E0E0E;
width: 100%;
z-index: 3;
overflow-y: scroll;
}
.nav__close {
cursor: pointer;
object-fit: cover;
width: 24px;
}
.button__container {
}
.nav__header {
display: flex;
flex-direction: column;
gap: 42px;
}
.logo {
width: 31px;
height: 50px;
}
.button__nav_container {
margin-top: 28px;
padding: 1px;
display: flex;
gap: 20px;
align-items: center;
}
.nav__button {
appearance: none;
background-color: transparent;
color: #ebebeb;
margin: 0;
text-align: left;
border: none;
height: 13px;
-webkit-appearance: none;
padding: 0;
cursor: pointer;
}
.language__container {
border-bottom: 1px solid transparent;
}
.language__container_active {
box-sizing: border-box;
height: 20px;
border-bottom: 1px solid #EBEBEB;
}
.nav__button_active {
border-bottom: 1px solid #EBEBEB;
}
.nav__title {
font-style: normal;
font-weight: 500;
font-size: 24px;
line-height: 100%;
/* identical to box height, or 24px */
color: #FFFFFF;
margin: 0;
text-decoration: none;
}
.nav__line {
background-color: #454545;
width: 100%;
height: 1px;
margin-bottom: 40px;
}
.nav__title_container {
display: flex;
gap: 24px;
}
.icon_chevron {
width: 20px;
}
.nav__buttons {
display: flex;
flex-direction: column;
gap: 10px;
margin-bottom: 50px;
}
-185
View File
@@ -1,185 +0,0 @@
import './navigation.css'
import '../header/header.css'
import "../../styles/styles.css"
import write from '../footer/send.svg'
import phone from '../footer/phone.svg'
import iconButton from "../../styles/iconButton.svg"
import { AnimatePresence, motion } from "framer-motion";
import chevron from '../header/chevronIcon.svg'
type THeader = {
menuOpen?: boolean,
language: string,
setOpen?: (value: boolean) => void
changeLanguage: (language: string) => void;
setOpacity?: (value: boolean) => void;
text?: any;
}
const container = {
hidden: {
translateX: '100%',
transition: { duration: 0.2, ease: 'easeOut' }
},
show: {
translateX: '0%',
transition: { duration: 0.2, ease: 'easeIn' },
},
exit: {
translateX: '0%',
transition: { duration: 0.2, ease: 'easeOut' }
}
}
const staggeredVariants = {
hidden: {
transition: {
}
},
show: {
transition: {
staggerChildren: 0.35,
staggerDirection: -1,
}
},
exit: {
transition: {
}
}
}
const items = {
hidden: {
opacity: 0,
},
show: {
opacity: 1,
transition: { ease: 'easeIn' },
},
exit: {
opacity: 1,
}
}
export const Nav: React.FC<THeader> = ({ menuOpen, language, changeLanguage, text }) => {
const userLanguage = language === 'RU';
const { cardLarge, cardLarge1, cardSmall, cardSmall1 } = text
const langArray = [{
value: 'ru-RU',
name: 'RU'
},
{
value: 'en-EN',
name: 'EN'
}]
function langActive(lang: string, language: string) {
if (lang === language) {
return 'language__container_active'
}
else {
return 'language__container'
}
}
return (
<AnimatePresence>
{menuOpen && (
<motion.nav
variants={container}
initial={'hidden'}
animate={'show'}
exit={'hidden'}
className={`navigation`}>
<motion.div
variants={staggeredVariants}
initial={'hidden'}
animate={'show'}
exit={'exit'}
className='nav__buttons'>
<motion.div
variants={items}
className='nav__header'>
<div className='button__nav_container'>
{langArray.map((lang, i) => (
<div className={langActive(lang.name, language)}>
<button value={lang.value} key={i} onClick={() => changeLanguage(lang.name)} className='nav__button'>{lang.name}</button>
</div>
))}
</div>
<div className='nav__title_container'>
<a target='_blank' rel="noreferrer" href={userLanguage ? 'https://graff.tech/' : 'http://en.graff.tech/'} className='nav__title'>{text.captionCompain}</a>
<img alt='icon' className='icon_chevron' src={chevron}></img>
</div>
<span className='nav__line'></span>
</motion.div>
<motion.a
href={userLanguage ? 'mailto:info@graff.tech' : 'mailto:waseem@graff.tech'}
variants={items}
className='footer__card_2'>
<div className='ellipse__container'>
<div className="main-block__icon_container">
<img alt='icon' src={iconButton} className="main-block__icon"></img>
</div>
</div>
<div className={'card__write'}>
<img alt='icon' src={write} className='card__icon'></img>
<p className='card__caption'>{cardSmall.caption}</p>
</div>
</motion.a>
<motion.a
href={userLanguage ? 'tel:+7-800-770-00-76' : 'tel:+971-50-938-8902'}
variants={items}
className='footer__card_2'>
<div className='ellipse__container'>
<div className="main-block__icon_container">
<img alt='icon' src={iconButton} className="main-block__icon"></img>
</div>
</div>
<div className='card__write'>
<img alt='icon' src={phone} className='card__icon'></img>
<p className='card__caption'>{cardSmall1.caption}</p>
</div>
</motion.a>
<motion.div
variants={items}
className={'footer__card_l'}>
<div className='card__contacts'>
<p className='card__email'>info@graff.tech</p>
<p className='card__tel'>+7 800 770 00 76</p>
</div>
<div className='card__adress'>
<p className='card__street'>{cardLarge.address}</p>
<p className='card_city'>{cardLarge.city}</p>
</div>
<p className='card_country'>{cardLarge.country}</p>
</motion.div>
<motion.div
variants={items}
className='footer__card_l'>
<div className='card__contacts'>
<p className='card__email'>waseem@graff.tech</p>
<p className='card__tel'>+971 50 938 8902</p>
</div>
<div className='card__adress card__adress_uae'>
<p className='card_city'>{cardLarge1.address}</p>
</div>
<p className='card_country'>{cardLarge1.country}</p>
</motion.div>
</motion.div>
</motion.nav>
)}
</AnimatePresence>
)
}
-141
View File
@@ -1,141 +0,0 @@
.share-popup-container {
position: absolute;
display: flex;
flex-direction: column;
width: 494px;
height: 469px;
box-sizing: border-box;
border: 1px solid #4F4F4F;
border-radius: 32px;
top: calc(50% - 469px / 2);
left: calc(50% - 494px / 2);
background-color: #333333;
color: #FFFFFF;
padding: 48px;
gap: 24px;
}
.share-header-popup {
padding-bottom: 0px;
}
.border-line {
width: 80%;
height: 1px;
background-color: #404040;
}
.share-popup-data-container {
display: flex;
flex-direction: column;
gap: 16px;
}
.share-popup-data-title {
font-weight: 600;
font-size: 18px;
line-height: 22px;
user-select: none;
}
.share-popup-data-input {
background-color: #4F4F4F;
outline: none;
width: 100%;
border: none;
border-radius: 12px;
color: #FFFFFF;
box-sizing: border-box;
}
.mobile-users-part-header-title {
display: flex;
gap: 12px;
align-items: center;
font-weight: 400;
font-size: 22px;
line-height: 130%;
-webkit-user-select: none;
user-select: none;
}
.mobile-users-part-header-close-button {
width: 15px;
height: 15px;
border: none;
background-color: transparent;
background: url(../../images/icons/close.svg) 50% 50% no-repeat;
background-size: 100% 100%;
cursor: pointer;
}
.share-popup-data-input.code {
height: 76px;
font-weight: 300;
font-size: 38px;
line-height: 46px;
letter-spacing: 0.3em;
text-align: center;
padding: 15px 0;
}
.share-popup-data-input.href {
height: 48px;
padding: 14.5px 16px;
font-weight: 400;
font-size: 16px;
line-height: 19px;
}
.share-popup-copy-button {
display: flex;
box-sizing: border-box;
width: 176px;
height: 48px;
align-items: center;
justify-content: center;
border-radius: 12px;
background-color: #567ECE;
border: none;
color: #FFFFFF;
font-weight: 500;
font-size: 16px;
line-height: 20px;
gap: 4px;
cursor: pointer;
transition: .3s;
}
.share-popup-copy-button:hover {
opacity: .7;
}
.share-popup-copy-button.copied {
background-color: #219653;
transition: .3s;
}
.share-popup-copy-button-icon {
width: 24px;
height: 24px;
background: url('copyIcon.svg') 50% 50% no-repeat;
background-size: 100% 100%;
}
.show-share-popup-enter {
opacity: 0;
}
.show-share-popup-enter-active {
opacity: 1;
transition: .3s;
}
.show-share-popup-exit {
opacity: 1;
}
.show-share-popup-exit-active {
opacity: 0;
transition: .3s;
}
@@ -1,10 +0,0 @@
import { Route, Redirect } from "react-router-dom";
export const ProtectedComponent: React.FC<any> = ({ children, ...props }) => {
console.log(props)
return (
<Route>
{() => (props.currentCard ? children : <Redirect to="/" />)}
</Route>
)
}
-4
View File
@@ -1,4 +0,0 @@
export const UserList: React.FC<any> = ({ selected, setSelected }) => {
return <></>;
};
Binary file not shown.

Before

Width:  |  Height:  |  Size: 213 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 182 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 166 KiB

@@ -1,33 +0,0 @@
import "../../styles/styles.css"
import './demonstration.css'
import building from './building.png'
import iconButton from "./iconButton.svg"
export const Demostration: React.FC<any> = ({text}) => {
const { card } = text;
return (
<div className="block">
<a href='https://stream.graff.tech/' target='_blank' rel="noreferrer" className='demos_container demos__route'>
<div className="main-block__icon_container demo__icon">
<img alt="icon" src={iconButton} className="main-block__icon"></img>
</div>
<div className='demo'>
<img alt='buildingImg' src={building} className='demo_image'></img>
<div className='demo_info'>
<div className='title__block'>
<h4 className='title__demo'>{card.title}</h4>
<p className='caption'>{card.subTitle}</p>
</div>
<div className='body__block'>
<p className='caption1'>{card.caption}</p>
<p className='caption2'>{card.caption1}</p>
</div>
</div>
</div>
</a>
</div>
)
}
@@ -1,152 +0,0 @@
.demonstration__title {
margin: 0 0 44px 0;
font-style: normal;
font-weight: 400;
font-size: 40px;
line-height: 100%;
/* or 40px */
color: #FFFFFF;
}
.demos-card__container {
display: flex;
flex-direction: row;
gap: 24px;
}
.demo__icon {
right: 36px;
top: 36px;
}
.demo-card__header {
position: relative;
}
.demos-card {
background: #1E1E1E;
border-radius: 24px;
width: 384px;
}
.block {
margin-top: 80px;
display: flex;
flex-direction: column;
gap: 20px;
}
.demo-card__image {
width: 100%;
height: 300px;
border-radius: 24px;
}
.demo-card__info {
padding: 32px;
display: flex;
flex-direction: column;
gap: 20px;
}
.demo-card__icon {
position: absolute;
top: 0;
right: 0;
width: 16px;
}
.demo-card__title {
font-weight: 400;
font-size: 22px;
line-height: 130%;
color: #EBEBEB;
margin: 0 0 5px 0;
}
.demo-card__subtitle {
font-weight: 400;
font-size: 14px;
line-height: 130%;
/* or 18px */
/* Landing/White */
color: #EBEBEB;
opacity: 0.5;
}
.demo-card__text {
font-style: normal;
font-weight: 400;
font-size: 16px;
line-height: 130%;
/* or 21px */
/* Landing/White */
margin: 0 0 10px 0;
color: #EBEBEB;
}
.demo-card__subtext {
font-weight: 400;
font-size: 14px;
line-height: 130%;
/* or 18px */
/* Landing/White */
color: #EBEBEB;
opacity: 0.5;
}
.demos-card {
cursor: pointer;
}
.demos-card:hover>div>div>div>img {
transition: opacity ease-out 0.2s;
opacity: 1;
}
.demos__route {
width: 100%;
}
@media screen and (max-width: 1024px) {
.block {
padding: 0 20px 80px;
}
.demos-card__container {
flex-direction: column;
}
.demos-card {
display: flex;
flex-direction: row;
width: 100%;
}
.demo-card__image {
width: 200px;
height: auto;
}
}
@media screen and (max-width: 639px) {
.demo__icon {
right: 19px;
top: 186px;
}
}
@@ -1,3 +0,0 @@
<svg width="10" height="10" viewBox="0 0 10 10" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M5.35356 9.35355C5.1583 9.54881 4.84171 9.54882 4.64645 9.35356C4.45119 9.1583 4.45118 8.84171 4.64644 8.64645L5.35356 9.35355ZM9 4.99993L9.35355 4.64637C9.44732 4.74014 9.5 4.86731 9.5 4.99992C9.5 5.13253 9.44732 5.25971 9.35356 5.35348L9 4.99993ZM4.64645 1.35356C4.45119 1.1583 4.45118 0.841714 4.64644 0.64645C4.8417 0.451186 5.15829 0.451183 5.35355 0.646443L4.64645 1.35356ZM1 5.49993C0.723858 5.49993 0.5 5.27607 0.5 4.99993C0.5 4.72378 0.723858 4.49993 1 4.49993V5.49993ZM4.64644 8.64645L8.64644 4.64638L9.35356 5.35348L5.35356 9.35355L4.64644 8.64645ZM8.64645 5.35348L4.64645 1.35356L5.35355 0.646443L9.35355 4.64637L8.64645 5.35348ZM9 5.49993H1V4.49993H9V5.49993Z" fill="white"/>
</svg>

Before

Width:  |  Height:  |  Size: 801 B

-3
View File
@@ -1,3 +0,0 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M12 12L16.9996 17M12 12L17 7M12 12L7 17M12 12L7.00002 7" stroke="white" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

Before

Width:  |  Height:  |  Size: 233 B

@@ -1,8 +1,4 @@
.loader-container {
width: 100%;
background: transparent;
padding: 56px;
box-sizing: border-box;
.popup-type-loader {
display: flex;
flex-direction: column;
gap: 58px;
@@ -14,6 +10,22 @@
flex-direction: column;
}
.popup-img-container {
height: 94px;
width: 100%;
padding: 0 21px 16px 0;
margin-bottom: 32px;
box-sizing: border-box;
}
.popup-logo {
height: 78px;
width: 267px;
object-fit: contain;
}
.loading-caption {
font-style: normal;
font-weight: 400;
@@ -1,7 +1,6 @@
import "../../styles/styles.css";
import "./LoadingPopup.css";
import loader from "./loader.svg";
import { useHistory } from "react-router-dom";
import { useTranslation } from "react-i18next";
export const LoadingPopup: React.FC<any> = ({ logo }) => {
@@ -9,9 +8,11 @@ export const LoadingPopup: React.FC<any> = ({ logo }) => {
const { t } = useTranslation();
return (
<div className="loader-container">
<div className="popup popup-type-loader">
<div className="loading-logo-container">
<div className="popup-img-container">
<img className="popup-logo" src={logo} alt="лого" />
</div>
<span className="loading-caption">Пожалуйста подождите</span>
</div>
<span className="loader"></span>

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

@@ -1,15 +1,16 @@
import "./main.css";
import { useEffect, useState } from "react";
import { motion, AnimatePresence } from "framer-motion";
import { PopupConnect } from "../popupConnect/popupConnect";
import { LoadingPopup } from "../LoadingPopup/LoadingPopup";
import { popupAnimation } from "../../utils/animationProps";
import { useAppDispatch, useAppSelector } from "../../hooks/redux";
import { createSession } from "../../store/reducers/ActionCreator";
import { sessionSlice } from "../../store/reducers/sessionSlice";
import { popupAnimation } from "utils/animationProps";
export const Main: React.FC = () => {
import { PopupConnect } from "components/pages/ConnectPage/PopupConnect/PopupConnect";
import { LoadingPopup } from "components/pages/ConnectPage/LoadingPopup/LoadingPopup";
import { useAppDispatch, useAppSelector } from "hooks/redux";
import { createSession } from "store/reducers/ActionCreator";
import { sessionSlice } from "store/reducers/sessionSlice";
export const PopupComponent: React.FC = () => {
const dispatch = useAppDispatch();
const { currentCard } = useAppSelector((state) => state.cardReducer);
const [visible, setVisible] = useState({
@@ -64,8 +65,7 @@ export const Main: React.FC = () => {
animate={"show"}
exit={"hidden"}
>
<LoadingPopup logo={currentCard.image.logo}
></LoadingPopup>
<LoadingPopup logo={currentCard.image.logo}></LoadingPopup>
</motion.div>
)}
</AnimatePresence>
@@ -0,0 +1,44 @@
.popup-img-container {
height: 94px;
width: 100%;
padding: 0 21px 16px 0;
margin-bottom: 32px;
box-sizing: border-box;
}
.popup-logo {
height: 78px;
width: 267px;
object-fit: contain;
}
.popup-button-container {
display: flex;
flex-direction: column;
gap: 16px;
}
.line {
height: 1px;
background-color: #23242A;
width: 100%;
}
@media screen and (max-width: 1000px) {
.popup-img-container {
margin-bottom: 16px;
}
}
@media screen and (max-width: 640px) {
.popup-connect {
padding: 16px;
}
}
@@ -1,5 +1,7 @@
import "./PopupConnect.css";
import { useHistory } from "react-router-dom";
import "./popupConnect.css";
import { useTranslation } from "react-i18next";
export const PopupConnect: React.FC<any> = ({ onConnect, logo, isLoading }) => {
@@ -12,24 +14,25 @@ export const PopupConnect: React.FC<any> = ({ onConnect, logo, isLoading }) => {
history.push(`/stream/${res.payload.session_id}`);
} else {
alert(res.payload);
history.push('/')
history.push("/");
}
});
};
return (
<div className="popup-connect">
<div className="popup">
<div className="popup-img-container">
<img className="popup-logo" src={logo} alt="лого" />
</div>
<div className="popup-button-container">
<button
onClick={handleConnect}
className="button-connect">{t("popup-main-btn-start")}
<button onClick={handleConnect} className="button-primary">
{t("popup-main-btn-start")}
</button>
<div className="popup-line"></div>
<button onClick={() => history.goBack()} className="button-back">{t("popup-main-select")}
<button onClick={() => history.goBack()} className="button-secondary">
{t("popup-main-select")}
</button>
</div>
</div>
);
};
@@ -1,7 +1,7 @@
import "./Card.css";
import "../../styles/styles.css";
import iconButton from "./iconButton.svg";
import { useAppSelector } from "../../hooks/redux";
import { useAppSelector } from "hooks/redux";
export const Card: React.FC<any> = ({ item, onClick }) => {
const { currentLang } = useAppSelector((state) => state.languageReducer);

Before

Width:  |  Height:  |  Size: 602 KiB

After

Width:  |  Height:  |  Size: 602 KiB

Before

Width:  |  Height:  |  Size: 792 KiB

After

Width:  |  Height:  |  Size: 792 KiB

Before

Width:  |  Height:  |  Size: 666 KiB

After

Width:  |  Height:  |  Size: 666 KiB

Before

Width:  |  Height:  |  Size: 864 B

After

Width:  |  Height:  |  Size: 864 B

@@ -0,0 +1,42 @@
import control from "images/icons/control.svg";
import controlOff from "images/icons/HandOff.svg";
import { useEffect, useState } from "react";
import { useTranslation } from "react-i18next";
import { Button } from "components/shared/Button/Button";
export const ControlButton: React.FC<any> = ({ onClick, isSidebarWide }) => {
const { t } = useTranslation();
const [active, setActive] = useState(false);
const [button, setButton] = useState({
icon: control,
active: "request-control-btn",
inactive: "request-control-btn-disable",
type: "control",
});
useEffect(() => {
setButton({ ...button, icon: active ? control : controlOff });
}, [active]);
function handleClick() {
onClick();
setActive((prev) => !prev);
}
return (
<div
onClick={handleClick}
className="toolbar-button-area"
>
<Button
isSidebarWide={isSidebarWide}
button={button}
active={active}
></Button>
</div>
);
};
@@ -1,9 +1,8 @@
import { ControlButton } from "../ui/ControlButton/ControlButton";
import { MicroButton } from "../ui/MicroButton/MicroButton";
import { ShareButton } from "../ui/ShareButton/ShareButton";
import { LanguageButton } from "../ui/LanguageButton/LanguageButton";
import { ExitButton } from "../ui/ExitButton/ExitButton";
import React, { useState, useEffect } from "react";
import { ControlButton } from "components/pages/Stream/ControlButton/ControlButton";
import { MicroButton } from "components/pages/Stream/MicroButton/MicroButton";
import { ShareButton } from "components/pages/Stream/ShareButton/ShareButton";
import { LanguageButton } from "components/pages/Stream/LanguageButton/LanguageButton";
import { ExitButton } from "components/pages/Stream/ExitButton/ExitButton";
export const ControlPanel: React.FC<any> = ({
handleOpenSharePopup,
@@ -1,7 +1,8 @@
import exit from "images/icons/exit.svg";
import { useState } from "react";
import { Button } from "../button/button";
import exit from "../../../images/icons/exit.svg";
import { THOC } from "../../../utils/types";
import { Button } from "components/shared/Button/Button";
export const ExitButton: React.FC<any> = ({ onClick, isSidebarWide }) => {
const [active, setActive] = useState(false);
@@ -13,14 +14,17 @@ export const ExitButton: React.FC<any> = ({ onClick, isSidebarWide }) => {
};
function handleClick() {
console.log("click");
setActive((prev) => !prev);
onClick()
onClick();
}
return (
<div className="toolbar-button-area">
<Button isSidebarWide={isSidebarWide} button={button} onClick={handleClick}></Button>
</div>
<button
tabIndex={-1}
onClick={handleClick}
className="toolbar-button-area"
>
<Button isSidebarWide={isSidebarWide} button={button}></Button>
</button>
);
};
@@ -0,0 +1,57 @@
import fullscreen from "images/icons/fullscreen.svg";
import fullscreenOff from "images/icons/fullscreenOff.svg";
import { useState, useEffect } from "react";
import { useTranslation } from "react-i18next";
import { Button } from "components/shared/Button/Button";
export const FullscreenButton: React.FC<any> = ({ isSidebarWide }) => {
const [active, setActive] = useState(Boolean(document.fullscreenElement));
const [button, setButton] = useState({
icon: fullscreen,
inactive: "fullscreen-control-btn",
active: "fullscreen-control-btn-active",
type: "fullscreen",
});
const { t } = useTranslation();
const handleClick = () => {
setActive(Boolean(document.fullscreenElement));
if (!document.fullscreenElement) {
document.body.requestFullscreen();
} else {
document.exitFullscreen();
}
};
useEffect(() => {
setButton({
icon: !active ? fullscreen : fullscreenOff,
inactive: "fullscreen-control-btn",
active: "fullscreen-control-btn-active",
type: "fullscreen",
});
}, [active]);
useEffect(() => {
const onFullscreenChange = () => {
setActive(Boolean(document.fullscreenElement));
};
document.addEventListener("fullscreenchange", onFullscreenChange);
return () =>
document.removeEventListener("fullscreenchange", onFullscreenChange);
}, []);
return (
<div tabIndex={-1} onClick={handleClick} className="toolbar-button-area">
<Button
isSidebarWide={isSidebarWide}
button={button}
active={active}
></Button>
</div>
);
};
@@ -1,8 +1,10 @@
import microOn from "images/icons/MicroOn.svg";
import { useState } from "react";
import { LanguagePopup } from "../../LanguagePopup/LanguagePopup";
import { Button } from "../button/button";
import microOn from "../../../images/icons/MicroOn.svg";
import { AnimatePresence, motion } from "framer-motion";
import { Button } from "components/shared/Button/Button";
const container = {
hidden: {
opacity: 0,
@@ -45,7 +47,6 @@ export const LanguageButton: React.FC<any> = ({ hover, setHover, isSidebarWide }
animate={"show"}
exit={"hidden"}
>
<LanguagePopup setOpen={setOpen}></LanguagePopup>
</motion.div>
)}
</AnimatePresence>
@@ -0,0 +1,46 @@
import microOn from "images/icons/MicroOn.svg";
import microOff from "images/icons/MicroOff.svg";
import { useState, useEffect } from "react";
import { useTranslation } from "react-i18next";
import { Button } from "components/shared/Button/Button";
export const MicroButton: React.FC<any> = ({
onClick,
isMuted,
isSidebarWide,
}) => {
const { t } = useTranslation();
const [button, setButton] = useState({
icon: microOn,
active: "mute-control-btn",
inactive: "mute-control-btn-disable",
type: "microphone",
});
const [active, setActive] = useState(false);
useEffect(() => {
setButton({ ...button, icon: active ? microOn : microOff });
}, [active]);
function handleClick() {
onClick();
setActive((prev) => !prev);
}
return (
<div
tabIndex={-1}
onClick={handleClick}
className="toolbar-button-area"
>
<Button
isSidebarWide={isSidebarWide}
button={button}
active={isMuted}
></Button>
</div>
);
};
@@ -1,10 +1,12 @@
import "./playerStyles.css";
import { useHistory, useParams } from "react-router-dom";
import "./PlayerStyles.css";
import React, { useEffect } from "react";
import { Sidebar } from "../sidebar/sidebar";
import { connectSession } from "../../store/reducers/ActionCreator";
import { useAppDispatch, useAppSelector } from "../../hooks/redux";
import { sessionSlice } from "../../store/reducers/sessionSlice";
import { useHistory, useParams } from "react-router-dom";
import { Sidebar } from "components/pages/Stream/Sidebar/Sidebar";
import { connectSession } from "store/reducers/ActionCreator";
import { useAppDispatch, useAppSelector } from "hooks/redux";
import { sessionSlice } from "store/reducers/sessionSlice";
type link = {
id: string;
@@ -14,13 +16,12 @@ export const PlayerComponent: React.FC<any> = ({ closeStream }) => {
const { id } = useParams<link>();
const dispatch = useAppDispatch();
const { cleanErrors } = sessionSlice.actions;
const history = useHistory()
const history = useHistory();
useEffect(() => {
dispatch(connectSession(id)).then((res: any) => {
if (res.error) {
alert(res.payload);
history.push('/')
}
});
return () => {
@@ -33,11 +34,13 @@ export const PlayerComponent: React.FC<any> = ({ closeStream }) => {
return (
<>
<iframe
id='player'
id="player"
onFocus={() => console.log('focus')}
onBlur={(e) => e.target.focus()} /// element loosing focus and keyboard input doesn't work
src={url}
className={"player playerOn"}
security={""}
allowFullScreen={true}
></iframe>
<Sidebar closeStream={closeStream}></Sidebar>
</>
@@ -0,0 +1,50 @@
.exit-popup-container {
position: absolute;
display: flex;
flex-direction: column;
box-sizing: border-box;
background-color: #333333;
color: #ffffff;
padding: 40px;
top: 50%;
width: 400px;
left: 50%;
background: #151619;
transform: translate(-50%, -50%);
/* gap: 24px; */
justify-content: space-between;
}
.exit-popup-button-container {
display: flex;
flex-direction: column;
gap: 24px;
}
.exit-popup-button {
border-radius: 12px;
border: none;
color: white;
height: 60px;
font-style: normal;
font-weight: 600;
font-size: 16px;
line-height: 20px;
cursor: pointer;
}
.exit-popup-button_confirm {
background: #567ece;
opacity: 1;
}
.exit-popup-button_finish {
background: #404040;
}
.exit-popup-button_confirm:hover {
opacity: 0.7;
transition: 0.3s;
}
@@ -0,0 +1,38 @@
import "../PopupShare/sharePopup.css";
import "./PopupExit.css";
import { useTranslation } from "react-i18next";
import { TSidebarPopup } from "utils/types";
export const PopupExit: React.FC<TSidebarPopup> = ({ setClose, onExit }) => {
const { t } = useTranslation();
return (
<div className="popup exit-popup-container popup">
<div className="popup-position-container">
<div className="mobile-users-part-header">
<span className="mobile-users-part-header-title exit-popup-button-title">
{t("popup-control-exit-title")}
</span>
<button
onClick={() => setClose()}
className="mobile-users-part-header-close-button"
></button>
</div>
<div className="exit-popup-button-container">
<button onClick={() => setClose()} className="button button-primary">
{t("popup-control-no")}
</button>
<button
style={{ height: "48px" }}
onClick={() => onExit?.()}
className=" button button-secondary"
>
{t("popup-control-yes")}
</button>
</div>
</div>
</div>
);
};
@@ -1,5 +1,7 @@
import "./sharePopup.css";
import { useState, useEffect } from "react";
import { useTranslation } from "react-i18next";
export const PopupShare: React.FC<any> = ({ setClose }) => {
@@ -20,7 +22,7 @@ export const PopupShare: React.FC<any> = ({ setClose }) => {
const { t } = useTranslation();
return (
<div className="share-popup-container">
<div className="share-popup-container popup">
<div className="mobile-users-part-header share-header-popup">
<span className="mobile-users-part-header-title">
{t("popup-control-invite-title")}
@@ -41,12 +43,19 @@ export const PopupShare: React.FC<any> = ({ setClose }) => {
></input>
</div>
<div className="share-popup-data-container">
<button className="share-popup-copy-button ">
{!copy ? (
<button onClick={copyLink} className="button button-primary ">
<span className="share-popup-copy-button-icon"></span>
<span onClick={copyLink} className="share-popup-copy-button-title">
<span className="">
{copy ? t("popup-control-btn-active") : t("popup-control-btn")}
</span>
</button>
) : (
<button onClick={copyLink} className="button button-teritary">
<span className="share-popup-copied-button-icon"></span>
<span className="">{t("popup-control-btn-active")}</span>
</button>
)}
</div>
</div>
);
@@ -0,0 +1,3 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M5 12L10 17L19 8" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

After

Width:  |  Height:  |  Size: 211 B

@@ -0,0 +1,4 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M18 7H10C9.44772 7 9 7.44772 9 8V20C9 20.5523 9.44772 21 10 21H18C18.5523 21 19 20.5523 19 20V8C19 7.44772 18.5523 7 18 7Z" fill="white"/>
<path d="M5 5V17C5 17.5523 5.44772 18 6 18C6.55228 18 7 17.5523 7 17V6C7 5.44772 7.44772 5 8 5H15C15.5523 5 16 4.55228 16 4C16 3.44772 15.5523 3 15 3H7C5.89543 3 5 3.89543 5 5Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 444 B

@@ -0,0 +1,162 @@
.share-popup-container {
position: absolute;
display: flex;
flex-direction: column;
top: 50%;
left: 50%;
background: #151619;
transform: translate(-50%, -50%);
border-radius: 4px;
width: 400px;
color: #ffffff;
padding: 40px;
gap: 32px;
}
.share-header-popup {
padding-bottom: 0px;
}
.border-line {
width: 80%;
height: 1px;
background-color: #404040;
}
.share-popup-data-container {
display: flex;
flex-direction: column;
gap: 16px;
}
.share-popup-data-title {
font-weight: 600;
font-size: 18px;
line-height: 22px;
user-select: none;
}
.share-popup-data-input {
background: #23242a;
border: 1px solid #23242a;
border-radius: 4px;
outline: none;
width: 100%;
border: none;
color: #ffffff;
box-sizing: border-box;
}
.share-popup-copied-button-icon {
width: 24px;
height: 24px;
background: url("copiedIcon.svg") 50% 50% no-repeat;
background-size: 100% 100%;
}
.button-copy {
width: fit-content;
display: flex;
padding: 12px 24px 12px 16px;
}
.mobile-users-part-header-title {
display: flex;
gap: 12px;
align-items: flex-start;
font-weight: 400;
font-style: normal;
font-weight: 400;
font-size: 24px;
line-height: 125%;
-webkit-user-select: none;
user-select: none;
}
.popup-position-container {
position: relative;
}
.mobile-users-part-header-close-button {
top: 0;
right: 0;
position: absolute;
width: 15px;
height: 15px;
border: none;
background-color: transparent;
background: url(images/icons/close.svg) 50% 50% no-repeat;
background-size: 100% 100%;
cursor: pointer;
}
.share-popup-data-input.code {
height: 76px;
font-weight: 300;
font-size: 38px;
line-height: 46px;
letter-spacing: 0.3em;
text-align: center;
padding: 15px 0;
}
.share-popup-data-input.href {
height: 48px;
padding: 14.5px 16px;
font-weight: 400;
font-size: 16px;
line-height: 19px;
}
.share-popup-copy-button {
display: flex;
box-sizing: border-box;
width: 176px;
height: 48px;
align-items: center;
justify-content: center;
border-radius: 12px;
background-color: #567ece;
border: none;
color: #ffffff;
font-weight: 500;
font-size: 16px;
line-height: 20px;
gap: 4px;
cursor: pointer;
transition: 0.3s;
}
.share-popup-copy-button:hover {
opacity: 0.7;
}
.share-popup-copy-button.copied {
background-color: #219653;
transition: 0.3s;
}
.share-popup-copy-button-icon {
width: 24px;
height: 24px;
background: url("copyIcon.svg") 50% 50% no-repeat;
background-size: 100% 100%;
}
.show-share-popup-enter {
opacity: 0;
}
.show-share-popup-enter-active {
opacity: 1;
transition: 0.3s;
}
.show-share-popup-exit {
opacity: 1;
}
.show-share-popup-exit-active {
opacity: 0;
transition: 0.3s;
}
@@ -0,0 +1,30 @@
import share from "images/icons/Share.svg";
import { useTranslation } from "react-i18next";
import { Button } from "components/shared/Button/Button";
export const ShareButton: React.FC<any> = ({ onClick, isSidebarWide }) => {
const button = {
icon: share,
active: "share-contro-btn",
inactive: "share-contro-btn",
type: "share",
};
const { t } = useTranslation();
function handleClick() {
onClick();
}
return (
<button
tabIndex={-1}
onClick={handleClick}
className="toolbar-button-area"
>
<Button isSidebarWide={isSidebarWide} button={button}></Button>
</button>
);
};
@@ -1,15 +1,12 @@
.toolbar-container {
user-select: none;
display: flex;
position: relative;
height: 100vh;
/* width: 74px; */
width: 64px;
padding: 0;
margin: 0;
/* transform: translateX(-60px); */
border-right: 1px solid #4f4f4f;
background: #333333;
padding: 10px;
background: #1c1d21;
box-sizing: border-box;
}
@@ -18,7 +15,6 @@
left: 50%;
transform: translate(-50%, -50%);
position: absolute;
}
.toolbar-confirm-block {
@@ -29,14 +25,13 @@
.mobile-users-part-header {
display: flex;
justify-content: space-between;
align-items: center;
padding-bottom: 24px;
align-items: flex-start;
padding-bottom: 32px;
}
.toolbar-field {
background: #333333;
overflow: hidden;
padding: 14px 15px;
width: 100%;
background: transparent;
box-sizing: border-box;
height: 100%;
display: flex;
@@ -46,11 +41,23 @@
}
.toolbar-field-part {
width: 100%;
display: flex;
flex-direction: column;
position: relative;
gap: 10px;
}
.toolbar-button-caption {
color: #c5c7ce;
font-style: normal;
font-weight: 400;
font-size: 14px;
line-height: 140%;
white-space: nowrap;
position: relative;
}
.toolbar-button-container {
display: flex;
flex-direction: column;
@@ -98,12 +105,13 @@
}
.toolbar-button-area {
cursor: pointer;
align-items: center;
position: relative;
display: flex;
gap: 8px;
/* background-color: #333333; */
/* border-top-left-radius: 50px solid #4f4f4f; */
padding: 8px;
background-color: transparent;
}
.toolbar-button-area.hidden {
@@ -142,17 +150,12 @@
}
.toolbar-button {
background-color: #4f4f4f;
background: transparent;
position: relative;
width: 40px;
height: 40px;
width: 24px;
height: 24px;
border: none;
border-radius: 50px;
background-size: 100% 100%;
cursor: pointer;
flex-shrink: 0;
display: flex;
align-items: center;
color: #ffffff;
font-weight: 400;
font-size: 14px;
@@ -165,28 +168,9 @@
background: #567ece;
}
.user-icon {
position: relative;
width: 40px;
height: 40px;
border: none;
border-radius: 50px;
background-size: 100% 100%;
background-color: #4f4f4f;
cursor: pointer;
flex-shrink: 0;
display: flex;
align-items: center;
color: #ffffff;
font-weight: 400;
font-size: 14px;
justify-content: center;
line-height: 17px;
padding: 0px;
}
.toolbar-button_exit {
background: #eb5757;
background: transparent;
}
.language-caption {
@@ -196,8 +180,8 @@
}
.toolbar-icon {
object-fit: cover;
width: 45%;
width: 24px;
height: 100%;
}
.empty__block {
@@ -244,7 +228,7 @@
margin-left: 2px;
opacity: 0;
position: absolute;
left: 100%;
left: 126%;
height: 24px;
top: calc(50% - 12px);
/* background-color: #27AE60; */
@@ -256,15 +240,15 @@
box-sizing: content-box;
}
.toolbar-button-description-rectangle {
/* display: inline-block; */
white-space: nowrap;
/* flex-shrink: 0; */
background-color: #333333;
background: #23242a;
height: 24px;
border-top-right-radius: 50px;
border-bottom-right-radius: 50px;
border: 1px solid #4f4f4f;
border-left: none;
color: white;
display: flex;
@@ -311,9 +295,7 @@
background-color: #4f4f4f;
}
.toolbar-button.user {
background: url("icons/userIcon.svg") 50% 50% no-repeat;
}
.toolbar-button.admin {
background-color: #2f80ed;
@@ -594,13 +576,8 @@
@media screen and (max-height: 700px) {
.toolbar-field {
padding: 20px 14px;
}
.toolbar-button {
width: 44px;
height: 44px;
}
.toolbar-button:hover {
opacity: 1;
@@ -1,14 +1,20 @@
import "./toolbar.css";
import "./Sidebar.css";
import React, { useState, useEffect } from "react";
import { UserList } from "../UserList/UserList";
import { FullscreenButton } from "../ui/FullscreenButton/FullscreenButton";
import { PopupShare } from "../PopupShare/PopupShare";
import { ExitPopup } from "../ExitPopup/ExitPopup";
import { ControlPanel } from "../ControlPanel/ControlPanel";
import { AnimatePresence, motion } from "framer-motion";
import { sidebarVariants, popupAnimation, wideSidebarVariants } from "../../utils/animationProps";
import { WideSidebarButton } from "../ui/WideSidebarButton/WideSidebarButton";
import { UserList } from "components/pages/Stream/UserList/UserList";
import { FullscreenButton } from "components/pages/Stream/FullscreenButton/FullscreenButton";
import { PopupShare } from "components/pages/Stream/PopupShare/PopupShare";
import { PopupExit } from "components/pages/Stream/PopupExit/PopupExit";
import { ControlPanel } from "../ControlPanel/ControlPanel";
import { WideSidebarButton } from "components/pages/Stream/WideSidebarButton/WideSidebarButton";
import {
sidebarVariants,
popupAnimation,
wideSidebarVariants,
wideSidebarAdminVariants,
} from "utils/animationProps";
export const Sidebar: React.FC<any> = ({ closeStream }) => {
const [open, setOpen] = useState(false);
@@ -17,8 +23,10 @@ export const Sidebar: React.FC<any> = ({ closeStream }) => {
popup2: false,
});
const isAdmin = true;
const [selected, setSelected] = useState(false);
const [wideSidebar, setWideSidebar] = useState(false)
const [wideSidebar, setWideSidebar] = useState(false);
const [isMuted, setMuted] = useState(true);
@@ -50,11 +58,9 @@ export const Sidebar: React.FC<any> = ({ closeStream }) => {
function closeSideBar() {
setSelected(false);
setOpen(false);
setWideSidebar(false)
setWideSidebar(false);
}
useEffect(() => () => unmountComponent(), []);
function unmountComponent() {
@@ -65,24 +71,42 @@ export const Sidebar: React.FC<any> = ({ closeStream }) => {
});
}
console.log(wideSidebar, 'wide', open, 'open')
const setAnimation = () => {
if (isAdmin) return wideSidebarAdminVariants;
else {
return wideSidebarVariants;
}
};
return (
<div>
<>
<motion.div
initial={false}
animate={open ? "open" : "closed"}
variants={wideSidebar ? wideSidebarVariants : sidebarVariants}
variants={wideSidebar ? setAnimation() : sidebarVariants}
className="toolbar-container"
>
<div style={wideSidebar ? {width: "220px"} : {width: "60px"}} className="toolbar-field">
<div
style={wideSidebar ? { overflow: "hidden" } : { overflow: "visible" }}
className="toolbar-field"
>
<div className="toolbar-field-part">
<FullscreenButton isSidebarWide={wideSidebar}
> </FullscreenButton>
<UserList isSidebarWide={wideSidebar} /// this is for disable showhing button's caption
selected={selected} setSelected={setSelected}></UserList>
<FullscreenButton isSidebarWide={wideSidebar}> </FullscreenButton>
<div className="toolbar-button-container-border-line"></div>
<UserList
closeSidebar={closeSideBar}
isSidebarWide={wideSidebar} /// this is for disable showhing button's caption
isAdmin={isAdmin}
></UserList>
</div>
<motion.div onHoverStart={() => setWideSidebar(true)} className="toolbar-field-part">
<WideSidebarButton isSidebarWide={wideSidebar} close={closeSideBar}></WideSidebarButton>
<motion.div
onHoverStart={() => setWideSidebar(true)}
className="toolbar-field-part"
>
<WideSidebarButton
isSidebarWide={wideSidebar}
close={closeSideBar}
></WideSidebarButton>
</motion.div>
<ControlPanel
isSidebarWide={wideSidebar}
@@ -92,9 +116,20 @@ export const Sidebar: React.FC<any> = ({ closeStream }) => {
handleOpenExitPopup={handleOpenExitPopup}
></ControlPanel>
</div>
{!open && <motion.div onClick={() => setOpen(true)} className="toolbar-open-button">
<AnimatePresence>
{!open && (
<motion.div
variants={popupAnimation}
initial={"hidden"}
animate={"show"}
exit={"hidden"}
onClick={() => setOpen(true)}
className="toolbar-open-button"
>
<span className="toolbar-open-button-icon"></span>
</motion.div>}
</motion.div>
)}
</AnimatePresence>
</motion.div>
<AnimatePresence>
{popup.popup1 && (
@@ -117,13 +152,13 @@ export const Sidebar: React.FC<any> = ({ closeStream }) => {
animate={"show"}
exit={"hidden"}
>
<ExitPopup
<PopupExit
onExit={closeStream}
setClose={handleClosePopups}
></ExitPopup>
></PopupExit>
</motion.div>
)}
</AnimatePresence>
</div>
</>
);
};

Before

Width:  |  Height:  |  Size: 284 B

After

Width:  |  Height:  |  Size: 284 B

Before

Width:  |  Height:  |  Size: 3.6 KiB

After

Width:  |  Height:  |  Size: 3.6 KiB

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

Before

Width:  |  Height:  |  Size: 233 B

After

Width:  |  Height:  |  Size: 233 B

Before

Width:  |  Height:  |  Size: 921 B

After

Width:  |  Height:  |  Size: 921 B

Before

Width:  |  Height:  |  Size: 793 B

After

Width:  |  Height:  |  Size: 793 B

Before

Width:  |  Height:  |  Size: 1018 B

After

Width:  |  Height:  |  Size: 1018 B

Before

Width:  |  Height:  |  Size: 430 B

After

Width:  |  Height:  |  Size: 430 B

Before

Width:  |  Height:  |  Size: 495 B

After

Width:  |  Height:  |  Size: 495 B

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Before

Width:  |  Height:  |  Size: 3.6 KiB

After

Width:  |  Height:  |  Size: 3.6 KiB

Before

Width:  |  Height:  |  Size: 581 B

After

Width:  |  Height:  |  Size: 581 B

Before

Width:  |  Height:  |  Size: 554 B

After

Width:  |  Height:  |  Size: 554 B

Before

Width:  |  Height:  |  Size: 485 B

After

Width:  |  Height:  |  Size: 485 B

Before

Width:  |  Height:  |  Size: 432 B

After

Width:  |  Height:  |  Size: 432 B

@@ -3,6 +3,6 @@
<path d="M17.5 -2C17.5 -2.18939 17.393 -2.36252 17.2236 -2.44721C17.0542 -2.53191 16.8515 -2.51363 16.7 -2.4L-1.16667 11C-2.5 12 -2.5 14 -1.16667 15L16.7 28.4C16.8515 28.5136 17.0542 28.5319 17.2236 28.4472C17.393 28.3625 17.5 28.1894 17.5 28V-2Z" fill="#333333" stroke="#4F4F4F" stroke-linecap="round" stroke-linejoin="round"/>
</mask>
<g mask="url(#mask0_688_6251)">
<path d="M18.5 1C18.5 0.815602 18.3985 0.646172 18.2359 0.559163C18.0734 0.472153 17.8761 0.481689 17.7227 0.583975L2.2188 10.9199C0.734468 11.9094 0.734468 14.0906 2.2188 15.0801L17.7227 25.416C17.8761 25.5183 18.0734 25.5278 18.2359 25.4408C18.3985 25.3538 18.5 25.1844 18.5 25V1Z" fill="#333333" stroke="#4F4F4F" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M18.5 1C18.5 0.815602 18.3985 0.646172 18.2359 0.559163C18.0734 0.472153 17.8761 0.481689 17.7227 0.583975L2.2188 10.9199C0.734468 11.9094 0.734468 14.0906 2.2188 15.0801L17.7227 25.416C17.8761 25.5183 18.0734 25.5278 18.2359 25.4408C18.3985 25.3538 18.5 25.1844 18.5 25V1Z" fill="#23242A" stroke="#23242A" stroke-linecap="round" stroke-linejoin="round"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 957 B

After

Width:  |  Height:  |  Size: 957 B

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

Before

Width:  |  Height:  |  Size: 529 B

After

Width:  |  Height:  |  Size: 529 B

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 2.0 KiB

Before

Width:  |  Height:  |  Size: 3.6 KiB

After

Width:  |  Height:  |  Size: 3.6 KiB

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 2.0 KiB

Before

Width:  |  Height:  |  Size: 671 B

After

Width:  |  Height:  |  Size: 671 B

Before

Width:  |  Height:  |  Size: 3.5 KiB

After

Width:  |  Height:  |  Size: 3.5 KiB

Before

Width:  |  Height:  |  Size: 5.7 KiB

After

Width:  |  Height:  |  Size: 5.7 KiB

@@ -1,7 +1,7 @@
<svg width="26" height="130" viewBox="0 0 26 130" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M1 0.5H0.5V1V129V129.5H1H4.69231H4.96719L5.11447 129.268L23.8655 99.7209C24.9331 98.0386 25.5 96.0872 25.5 94.0947V35.9053C25.5 33.9128 24.9331 31.9614 23.8655 30.2791L5.11447 0.732088L4.96719 0.5H4.69231H1Z" stroke="#4F4F4F"/>
<path d="M0 0H3.69231L22.4805 30.0683C23.4735 31.6574 24 33.4935 24 35.3674V94.6326C24 96.5064 23.4735 98.3426 22.4805 99.9317L3.69231 130H0V0Z" fill="#333333"/>
<path d="M1 1H4.69231L23.4433 30.547C24.4601 32.1492 25 34.0076 25 35.9053V94.0947C25 95.9924 24.4601 97.8508 23.4433 99.453L4.69231 129H1V1Z" fill="#333333"/>
<rect x="1" width="4" height="2" fill="#333333"/>
<rect x="1" y="128" width="4" height="2" fill="#333333"/>
<path d="M1 0.5H0.5V1V129V129.5H1H4.69231H4.96719L5.11447 129.268L23.8655 99.7209C24.9331 98.0386 25.5 96.0872 25.5 94.0947V35.9053C25.5 33.9128 24.9331 31.9614 23.8655 30.2791L5.11447 0.732088L4.96719 0.5H4.69231H1Z" stroke="#1C1D21"/>
<path d="M0 0H3.69231L22.4805 30.0683C23.4735 31.6574 24 33.4935 24 35.3674V94.6326C24 96.5064 23.4735 98.3426 22.4805 99.9317L3.69231 130H0V0Z" fill="#1C1D21"/>
<path d="M1 1H4.69231L23.4433 30.547C24.4601 32.1492 25 34.0076 25 35.9053V94.0947C25 95.9924 24.4601 97.8508 23.4433 99.453L4.69231 129H1V1Z" fill="#1C1D21"/>
<rect x="1" width="4" height="2" fill="#1C1D21"/>
<rect x="1" y="128" width="4" height="2" fill="#1C1D21"/>
</svg>

Before

Width:  |  Height:  |  Size: 772 B

After

Width:  |  Height:  |  Size: 772 B

Before

Width:  |  Height:  |  Size: 610 B

After

Width:  |  Height:  |  Size: 610 B

Before

Width:  |  Height:  |  Size: 610 B

After

Width:  |  Height:  |  Size: 610 B

Before

Width:  |  Height:  |  Size: 265 B

After

Width:  |  Height:  |  Size: 265 B

Before

Width:  |  Height:  |  Size: 284 B

After

Width:  |  Height:  |  Size: 284 B

+78
View File
@@ -0,0 +1,78 @@
.user-container {
user-select: none;
cursor: pointer;
width: 100%;
display: flex;
flex-direction: row;
justify-content: space-between;
}
.user {
display: flex;
align-items: center;
gap: 8px;
}
.user-name {
font-style: normal;
font-weight: 400;
font-size: 14px;
line-height: 140%;
color: #c5c7ce;
white-space: nowrap;
}
.icon-container {
align-items: center;
display: flex;
gap: 3px;
flex-direction: column;
}
.you-caption {
font-weight: 400;
font-size: 12px;
line-height: 130%;
/* identical to box height, or 16px */
/* Button_3 */
color: #73788c;
}
.user-wrapper {
position: relative;
}
.user-wrapper:nth-child(1) {
margin-top: 10px;
}
.user-button-container {
display: flex;
gap: 8px;
padding: 8px;
}
.icon-container {
cursor: pointer;
padding: 8px;
}
.control-circle {
width: 8px;
height: 8px;
background-color: #798fff;
border-radius: 50%;
margin-bottom: 5px;
}
.user-control-caption {
display: flex;
gap: 4px;
font-weight: 400;
font-size: 10px;
line-height: 130%;
align-items: center;
color: #798fff;
}
+155
View File
@@ -0,0 +1,155 @@
import "./User.css";
import { AnimatePresence, motion } from "framer-motion";
import { useState, useEffect } from "react";
import userPic from "images/icons/Person.svg";
import chevronDown from "images/icons/ChevronDown.svg";
import control from "images/icons/control.svg";
import controlOff from "images/icons/HandOff.svg";
import microOn from "images/icons/MicroOn.svg";
import microOff from "images/icons/MicroOff.svg";
import {
popupAnimation,
userMenuAnimation,
animationButton,
transition,
iconAnimation,
} from "utils/animationProps";
export const User: React.FC<any> = ({
isAdmin,
isSidebarWide,
closeSidebar,
}) => {
const [hover, setHover] = useState(false);
const [expand, setExpand] = useState(false);
const [mute, setMute] = useState(true);
const [isControl, setControl] = useState(false);
useEffect(() => {
setExpand(false);
}, [closeSidebar]);
const expandMenu = () => {
if (isSidebarWide) {
if (isAdmin) setExpand((prev) => !prev);
}
};
return (
<>
<motion.div
variants={userMenuAnimation}
animate={expand ? "open" : "closed"}
className="user-wrapper"
>
<div onClick={expandMenu} className="user-container">
<div className="user">
<motion.div
onHoverStart={() => setHover(true)}
onHoverEnd={() => setHover(false)}
className="icon-container"
>
<img
alt="иконка пользователя"
className="user-icon"
src={userPic}
></img>
</motion.div>
<motion.span
initial={false}
variants={animationButton}
animate={isSidebarWide ? "show" : "hidden"}
className="user-name"
>
Пользователь
</motion.span>
</div>
{isSidebarWide && (
<AnimatePresence>
{!isControl && (
<motion.div
variants={popupAnimation}
initial={"hidden"}
animate={"show"}
exit={"hidden"}
className="user-control-caption"
>
<div className="control-circle"></div>
<span className="user-control-caption">Управление</span>
</motion.div>
)}
</AnimatePresence>
)}
{isAdmin && (
<motion.div
initial={false}
variants={animationButton}
animate={isSidebarWide ? "show" : "hidden"}
className="icon-container"
>
<motion.img
initial={false}
transition={transition}
variants={iconAnimation}
animate={expand ? "open" : "closed"}
src={chevronDown}
className="arrow-caption"
></motion.img>
</motion.div>
)}
</div>
{expand && (
<AnimatePresence>
<motion.div
variants={popupAnimation}
initial={"hidden"}
animate={"show"}
exit={"hidden"}
className="user-button-container"
>
<div
onClick={() => setControl((prev) => !prev)}
className="button button-secondary"
>
<img src={isControl ? control : controlOff}></img>
<span>
{isControl ? "Передать управление" : "Вернуть управление"}
</span>
</div>
<div
style={{width: "40px", padding: "16px"}}
onClick={() => setMute((prev) => !prev)}
className="button button-teritary"
>
<img
alt="иконка звук выкл"
src={mute ? microOn : microOff}
className="mic"
></img>
</div>
</motion.div>
</AnimatePresence>
)}
</motion.div>
<AnimatePresence initial={false}>
{!isSidebarWide && hover && (
<motion.div
variants={animationButton}
initial={"hidden"}
animate={"show"}
exit={"hidden"}
className="toolbar-button-description-container toolbar-button-description-user"
>
<span className="toolbar-button-description-triangle"></span>
<span className="toolbar-button-description-rectangle">
Пользователь
</span>
</motion.div>
)}
</AnimatePresence>
</>
);
};
@@ -0,0 +1,10 @@
import { User } from "components/pages/Stream/User/User";
export const UserList: React.FC<any> = ({ isSidebarWide, isAdmin, closeSidebar }) => {
return (
<div className="toolbar-field-part">
<User closeSidebar={closeSidebar} isAdmin={isAdmin} isSidebarWide={isSidebarWide}></User>
<div className="toolbar-button-container-border-line"></div>
</div>
);
};
@@ -0,0 +1,4 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M16 17L11 12L16 7" stroke="#C5C7CE" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M7 22L7 12L7 2" stroke="#C5C7CE" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

After

Width:  |  Height:  |  Size: 322 B

@@ -0,0 +1,38 @@
import wideButton from "./Menu.svg";
import { useState } from "react";
import { useTranslation } from "react-i18next";
import { Button } from "components/shared/Button/Button";
export const WideSidebarButton: React.FC<any> = ({ close, isSidebarWide }) => {
const { t } = useTranslation();
const [active, setActive] = useState(false);
const [button, setButton] = useState({
icon: wideButton,
inactive: "Скрыть меню",
active: "Скрыть меню",
type: "fullscreen",
noHover: true,
});
const handleClick = () => {
close();
setActive((prev) => !prev);
};
return (
<button
tabIndex={-1}
onFocus={(e) => e.target.blur()}
onClick={handleClick}
className="toolbar-button-area"
>
<Button
isSidebarWide={isSidebarWide}
button={button}
active={active}
></Button>
</button>
);
};
@@ -1,63 +0,0 @@
.popup-connect {
width: 100%;
background: transparent;
padding: 56px;
box-sizing: border-box;
}
.popup-logo {
height: 94px;
width: 100%;
margin-bottom: 32px;
object-fit: contain;
}
.popup-button-container {
display: flex;
flex-direction: column;
gap: 16px;
}
.line {
height: 1px;
background-color: #23242A;
width: 100%;
}
.button-connect {
color: #FFFFFF;
font-style: normal;
font-weight: 400;
font-size: 16px;
line-height: 150%;
height: 48px;
background: linear-gradient(180deg, #BC75FF 0%, #798FFF 100%);
border-radius: 4px;
padding: 12px 24px;
}
.button-back {
padding: 8px 16px;
border-radius: 4px;
font-family: 'Inter';
font-style: normal;
font-weight: 400;
font-size: 12px;
line-height: 130%;
color: #C5C7CE;
background: #1C1D21;
border-radius: 4px;
height: 32px;
}
@media screen and (max-width: 640px) {
.popup-connect {
padding: 16px;
}
}
-76
View File
@@ -1,76 +0,0 @@
.popup__user {
position: relative;
width: 494px;
background: #262626;
border-radius: 32px;
padding: 48px;
box-sizing: border-box;
}
.popup__user_back {
position: absolute;
width: 16px;
height: 16px;
cursor: pointer;
}
.popup__user_content {
display: flex;
flex-direction: column;
gap: 24px;
align-items: center;
}
.popup__user_picture {
background: #219653;
width: 198px;
height: 198px;
border-radius: 172px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.popup__user_name {
font-style: normal;
font-weight: 400;
font-size: 38px;
line-height: 130%;
/* or 49px */
text-align: center;
/* App/White */
color: #ffffff;
border-bottom: 1px solid #FFFFFF;
margin: 0 0 42px;
width: 57%;
}
.popup__button {
display: none;
}
@media screen and (max-width: 639px) {
.popup__user {
width: 100%;
border-radius: 0px;
height: 100%;
padding: 32px 10px 67px;
height: 100vh;
}
.popup__button {
display: flex;
flex-direction: column;
gap: 16px;
}
.popup__user_name {
margin: 0 0 54px;
}
.popup__user_back {
display: none;
}
}
-25
View File
@@ -1,25 +0,0 @@
import "../../styles/styles.css";
import "./popupUser.css";
import person from "../../images/Person.png";
import buttonBack from "../../images/backButton.svg";
export const PopupUser: React.FC = ({}) => {
return (
<div className="popup__user">
<img alt="btn-back" className="popup__user_back" src={buttonBack}></img>
<div className="popup__user_content">
<div className="popup__user_picture">
<img alt="avatar" src={person}></img>
</div>
<p className="popup__user_name">Константин Коренецкий </p>
<button className="button">Продолжить</button>
<div className="popup__button">
<span className="line"></span>
<button className="popup__caption">
Выбор способа демонстрации{" "}
</button>
</div>
</div>
</div>
);
};
@@ -1,48 +0,0 @@
import "../sidebar/toolbar.css";
import { useState } from "react";
import { TUserControl } from "../../utils/types";
import { MicroButton } from "../ui/MicroButton/MicroButton";
import iconUser from "../../images/icons/user.svg";
import { PopupUserControlButton } from "../popupUserControlButton/PopupUserControlButton";
export const PopupUserControl: React.FC<TUserControl> = ({
user,
isAdmin,
sendControlRequest,
localUser,
handleControl,
setNotification,
handleReturnControl,
setMuted,
isMuted,
}) => {
const handleMuteUser = () => {
const element = document.getElementById(user.id) as HTMLAudioElement;
if (isMuted) {
console.log(element);
element.volume = 1;
setMuted(false);
} else {
element.volume = 0;
setMuted(true);
}
};
return (
<div className="toolbar-open-add-button-container">
<div className="user-icon">
<img alt="icon" className="toolbar-icon" src={iconUser}></img>
</div>
<MicroButton isMuted={isMuted} onClick={handleMuteUser}></MicroButton>
<PopupUserControlButton
handleControl={handleControl}
localUser={localUser}
sendControlRequest={sendControlRequest}
isAdmin={isAdmin}
setNotification={setNotification}
user={user}
handleReturnControl={handleReturnControl}
></PopupUserControlButton>
</div>
);
};
@@ -1,126 +0,0 @@
import control from "../../images/icons/control.svg";
import "../sidebar/toolbar.css";
import { useState } from "react";
import controlOff from "../../images/icons/control.svg";
export const PopupUserControlButton: React.FC<any> = ({
isAdmin,
user,
sendControlRequest,
localUser,
handleControl,
setNotification,
handleReturnControl,
}) => {
const [show, setShow] = useState(false);
const isUserAdmin = isAdmin(user);
function onChangeControl() {
handleControl(user.id);
setShow(false);
setNotification(false);
}
return (
<div>
{!show ? (
<>
{" "}
{isUserAdmin ? (
<>
{user.control ? (
<button
onClick={() => handleReturnControl()}
className="control-button"
>
<img
alt="icon"
src={control}
className="control-button-icon"
></img>
<span className="constrol-button-title">
Вернуть управление
</span>
</button>
) : (
<button
onClick={() => setShow((prev) => !prev)}
className="control-button"
>
<img
alt="icon"
src={control}
className="control-button-icon"
></img>
<span className="constrol-button-title">
Передать управление
</span>
</button>
)}
</>
) : (
<>
{user.admin ? (
<>
{!user.control ? (
<button
onClick={() => handleReturnControl()}
className="control-button"
>
<img
alt="icon"
src={control}
className="control-button-icon"
></img>
<span className="constrol-button-title">
Вернуть управление
</span>
</button>
) : (
<button
onClick={() => sendControlRequest(localUser)}
className="control-button"
>
<img
alt="icon"
src={control}
className="control-button-icon"
></img>
<span className="constrol-button-title">
Запросить управление
</span>
</button>
)}
</>
) : (
<div className="empty__block"></div>
)}
</>
)}
</>
) : (
<div className="toolbar-confirm-block">
{" "}
<button
onClick={() => setShow((prev) => !prev)}
className="toolbar-button no medium"
>
<div className="toolbar-button-medium-view">
<img className="" src={controlOff}></img>
<span className="toolbar-button-medium-view-title">Нет</span>
</div>
</button>
<button
onClick={onChangeControl}
className="toolbar-button yes medium"
>
<div className="toolbar-button-medium-view">
<img className="" src={control}></img>
<span className="toolbar-button-medium-view-title">Да</span>
</div>
</button>
</div>
)}
</div>
);
};
+64
View File
@@ -0,0 +1,64 @@
import "components/pages/Stream/Sidebar/Sidebar.css";
import { useState } from "react";
import { AnimatePresence, motion } from "framer-motion";
import { useTranslation } from "react-i18next";
import { animationButton } from "utils/animationProps";
import { useAppSelector } from "hooks/redux";
export const Button: React.FC<any> = ({ button, active, isSidebarWide }) => {
const [hover, setHover] = useState(false);
const { currentLang } = useAppSelector((state) => state.languageReducer);
const typeButton = button.type !== "fullscreen" && button.type !== "language";
const { t } = useTranslation();
return (
<>
<motion.div
onHoverStart={() => setHover(true)}
onHoverEnd={() => setHover(false)}
className={
button.type === "exit"
? "toolbar-button_exit toolbar-button"
: "toolbar-button"
}
>
{button.type === "language" ? (
<span className="language-caption">{currentLang.toUpperCase()}</span>
) : (
<img alt="icon" className="toolbar-icon" src={button.icon} />
)}
</motion.div>
<motion.span
initial={false}
variants={animationButton}
animate={isSidebarWide ? "show" : "hidden"}
className="toolbar-button-caption"
>
{active ? t(button.active) : t(button.inactive)}
</motion.span>
{!button.noHover && (
<AnimatePresence initial={false}>
{!isSidebarWide && hover && (
<motion.div
variants={animationButton}
initial={"hidden"}
animate={"show"}
exit={"hidden"}
className="toolbar-button-description-container"
>
<span className="toolbar-button-description-triangle"></span>
<span className="toolbar-button-description-rectangle">
{active ? t(button.active) : t(button.inactive)}
</span>
</motion.div>
)}
</AnimatePresence>
)}
</>
);
};

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Before

Width:  |  Height:  |  Size: 3.0 KiB

After

Width:  |  Height:  |  Size: 3.0 KiB

Some files were not shown because too many files have changed in this diff Show More