diff --git a/public/index.html b/public/index.html index 4418f82..ce64ae3 100644 --- a/public/index.html +++ b/public/index.html @@ -1,5 +1,5 @@ - + diff --git a/src/App.css b/src/App.css index dbc852e..734433b 100644 --- a/src/App.css +++ b/src/App.css @@ -1,3 +1,6 @@ .App { font-family: inter; + + -webkit-tap-highlight-color: rgba(255, 255, 255, 0); + -webkit-tap-highlight-color: transparent; } \ No newline at end of file diff --git a/src/App.tsx b/src/App.tsx index f3b7bd8..076ef89 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,11 +1,41 @@ -import React from 'react'; +import React, { useEffect, useState } from 'react'; import './App.css'; +import { ContextWindowHeight } from './components/contextWindowHeight'; import { MainScreen } from './components/mainScreen/mainScreen'; function App() { + const [windowHeight, setWindowHeight] = useState(window.screen.availHeight); + + window.addEventListener('resize', e => { + //@ts-ignore + setWindowHeight(e.currentTarget.screen.availHeight) + }) + + window.onload = function () { + hideAddressBar(); + window.addEventListener("orientationchange", function () { + hideAddressBar(); + }, false); + } + + function hideAddressBar() { + setTimeout(function () { + document.body.style.height = window.outerHeight + 'px'; + setTimeout(function () { + window.scrollTo(0, 1); + }, 1100); + }, 1000); + return false; + } + + + + return (
- + + +
); } diff --git a/src/components/contextWindowHeight.ts b/src/components/contextWindowHeight.ts new file mode 100644 index 0000000..8f4b0a0 --- /dev/null +++ b/src/components/contextWindowHeight.ts @@ -0,0 +1,3 @@ +import React from "react"; + +export const ContextWindowHeight = React.createContext(window.screen.availHeight); \ No newline at end of file diff --git a/src/components/mainScreen/mainScreen.css b/src/components/mainScreen/mainScreen.css index 46b8c7a..8b782d7 100644 --- a/src/components/mainScreen/mainScreen.css +++ b/src/components/mainScreen/mainScreen.css @@ -2,6 +2,7 @@ width: 100%; height: 100vh; position: relative; + display: flex; } .main-screen-model { diff --git a/src/components/mainScreen/mainScreen.tsx b/src/components/mainScreen/mainScreen.tsx index 92144eb..7eb9647 100644 --- a/src/components/mainScreen/mainScreen.tsx +++ b/src/components/mainScreen/mainScreen.tsx @@ -1,15 +1,27 @@ -import React, { useState } from "react"; +import React, { useContext, useState } from "react"; import { CSSTransition } from "react-transition-group"; +import { ContextWindowHeight } from "../contextWindowHeight"; import './mainScreen.css'; +import { MobileUsersPart } from "./mobileUsersPart/mobileUsersPart"; import { Toolbar } from "./toolbar/toolbar"; export const MainScreen:React.FC = React.memo(() => { const [showToolbar, setShowToolbar] = useState(false); + const [showMobileUsersPart, setShowMobileUsersPart] = useState(false); + const windowHeight = useContext(ContextWindowHeight); function onClickToolbar() { setShowToolbar(!showToolbar); } + function openMobileUsers() { + setShowMobileUsersPart(true); + } + + function closeMobileUsers() { + setShowMobileUsersPart(false); + } + return
{ + { + windowHeight < 700 ? + + + + : null + }
}) \ No newline at end of file diff --git a/src/components/mainScreen/mobileUsersPart/borderLine.tsx b/src/components/mainScreen/mobileUsersPart/borderLine.tsx new file mode 100644 index 0000000..a10009e --- /dev/null +++ b/src/components/mainScreen/mobileUsersPart/borderLine.tsx @@ -0,0 +1,5 @@ +import React from "react"; + +export const BorderLine:React.FC = React.memo(() => { + return
+}) \ No newline at end of file diff --git a/src/components/mainScreen/mobileUsersPart/closeIcon.svg b/src/components/mainScreen/mobileUsersPart/closeIcon.svg new file mode 100644 index 0000000..c6696a6 --- /dev/null +++ b/src/components/mainScreen/mobileUsersPart/closeIcon.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/components/mainScreen/mobileUsersPart/mobileUsersPart.css b/src/components/mainScreen/mobileUsersPart/mobileUsersPart.css new file mode 100644 index 0000000..9bbb8ba --- /dev/null +++ b/src/components/mainScreen/mobileUsersPart/mobileUsersPart.css @@ -0,0 +1,90 @@ +.mobile-users-part { + position: relative; + width: 100%; + height: 100%; + display: flex; + padding: 32px; + display: flex; + flex-direction: column; + color: #FFFFFF; + box-sizing: border-box; + background-color: #333333; +} + +.border-line { + width: 100%; + height: 1px; + background-color: #4F4F4F; +} + +.mobile-users-part-header { + display: flex; + justify-content: space-between; + align-items: center; + padding-bottom: 24px; +} + +.mobile-users-part-header-title { + font-weight: 600; + font-size: 22px; + line-height: 130%; +} + +.mobile-users-part-header-close-button { + width: 30px; + height: 30px; + border: none; + background-color: transparent; + background: url('closeIcon.svg') 50% 50% no-repeat; + background-size: 100% 100%; +} + +.mobile-users-part-users-container { + display: flex; + flex-direction: column; + gap: 12px; + overflow-y: auto; + padding-top: 12px; +} + +.user-item { + display: flex; + flex-direction: row; + gap: 8px; +} + +.user-item-user-info-container { + display: flex; + flex-direction: column; + width: 100%; + gap: 12px; +} + +.user-item-user-info { + display: flex; + justify-content: space-between; + align-items: center; +} + +.user-item-user-info-buttons { + display: flex; + gap: 8px; +} + +.show-mobile-users-enter { + opacity: 0; +} + +.show-mobile-users-enter-active { + opacity: 1; + transition: .3s; +} + +.show-mobile-users-exit { + opacity: 1; +} + +.show-mobile-users-exit-active { + opacity: 0; + transition: .3s; +} \ No newline at end of file diff --git a/src/components/mainScreen/mobileUsersPart/mobileUsersPart.tsx b/src/components/mainScreen/mobileUsersPart/mobileUsersPart.tsx new file mode 100644 index 0000000..aaff83d --- /dev/null +++ b/src/components/mainScreen/mobileUsersPart/mobileUsersPart.tsx @@ -0,0 +1,32 @@ +import React from "react"; +import { BorderLine } from "./borderLine"; +import './mobileUsersPart.css' +import { UserItem } from "./userItem"; + +type TProps = { + onClickClose: () => void +} + +export const MobileUsersPart:React.FC = React.memo((props) => { + return
+
+ + Участники демонастрации + + +
+ +
+ + + + + + + +
+
+}) \ No newline at end of file diff --git a/src/components/mainScreen/mobileUsersPart/userItem.tsx b/src/components/mainScreen/mobileUsersPart/userItem.tsx new file mode 100644 index 0000000..bd84c2f --- /dev/null +++ b/src/components/mainScreen/mobileUsersPart/userItem.tsx @@ -0,0 +1,42 @@ +import React from "react"; +import { ToolbarButton } from "../toolbar/toolbarButton"; +import { TypeToolbarButtons } from "../toolbar/typeButtons"; +import { BorderLine } from "./borderLine"; +import { CaptionToolbarButtons } from "../toolbar/typeCaptionButtons"; + +type TProps = { + typeUser: TypeToolbarButtons +} + +export const UserItem:React.FC = React.memo((props) => { + return
+ null} + /> +
+
+ {CaptionToolbarButtons[props.typeUser]} +
+ null} + /> + null} + /> +
+
+ +
+
+}) \ No newline at end of file diff --git a/src/components/mainScreen/toolbar/buttonContainer.tsx b/src/components/mainScreen/toolbar/buttonContainer.tsx index cb3bd6c..a127e9d 100644 --- a/src/components/mainScreen/toolbar/buttonContainer.tsx +++ b/src/components/mainScreen/toolbar/buttonContainer.tsx @@ -7,8 +7,10 @@ import { CaptionToolbarButtons } from "./typeCaptionButtons"; type TProps = { buttons: Array<{ type: TypeToolbarButtons, + onClick: () => void, + isCaption: boolean isNotification?: boolean, - onClick: () => void + active?: boolean }> } @@ -22,6 +24,8 @@ export const ButtonContainer:React.FC = React.memo((props) => { type={button.type} isNotification={button?.isNotification} caption={CaptionToolbarButtons[button.type]} + active={button?.active} + isCaption={button.isCaption} />)} diff --git a/src/components/mainScreen/toolbar/icons/newCaptTriangleIcon.svg b/src/components/mainScreen/toolbar/icons/newCaptTriangleIcon.svg new file mode 100644 index 0000000..ace65c4 --- /dev/null +++ b/src/components/mainScreen/toolbar/icons/newCaptTriangleIcon.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/src/components/mainScreen/toolbar/openToolbarBackIcon.svg b/src/components/mainScreen/toolbar/openToolbarBackIcon.svg new file mode 100644 index 0000000..ee6d202 --- /dev/null +++ b/src/components/mainScreen/toolbar/openToolbarBackIcon.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/src/components/mainScreen/toolbar/toolbar.css b/src/components/mainScreen/toolbar/toolbar.css index ca6beaa..2961b37 100644 --- a/src/components/mainScreen/toolbar/toolbar.css +++ b/src/components/mainScreen/toolbar/toolbar.css @@ -2,32 +2,27 @@ display: flex; position: relative; height: 100%; - width: 74px; + /* width: 74px; */ + width: 64px; padding: 0; margin: 0; - transform: translateX(-70px); + transform: translateX(-60px); border-right: 1px solid #4F4F4F; background: #333333; + box-sizing: border-box; } -/* .toolbar-container.closed { - transform: translateX(-70px); -} */ - -/* .toolbar-container.opened { - transform: translateX(0px); -} */ - .toolbar-field { - width: 70px; + width: 60px; background: #333333; padding: 14px 15px; box-sizing: border-box; height: 100%; display: flex; flex-direction: column; - justify-content: space-between; + justify-content: space-between; + align-items: center; } .toolbar-field-part { @@ -64,6 +59,7 @@ height: 128px; border: none; background: url('openToolbarIcon.svg') 50% 50% no-repeat; + background: url('openToolbarBackIcon.svg') 50% 50% no-repeat; background-size: 100% 100%; cursor: pointer; @@ -141,6 +137,7 @@ border-top-right-radius: 50px; border-bottom-right-radius: 50px; border: 1px solid #4F4F4F; + border-left: none; color: white; display: flex; align-items: center; @@ -156,7 +153,7 @@ width: 18px; height: 26px; background-color: #EB5757; - background: url('icons/descriptTiriangleIcon.svg'); + background: url('icons/newCaptTriangleIcon.svg'); } .toolbar-button.notification::after { @@ -170,12 +167,12 @@ background-color: #F2994A; } -.toolbar-button.fullscreenOn { +.toolbar-button.fullscreen.on { background: url('./icons/openFullscreenIcon.svg') 50% 50% no-repeat; background-color: #4F4F4F; } -.toolbar-button.fullscreenOff { +.toolbar-button.fullscreen { background: url('./icons/closeFullscreenIcon.svg') 50% 50% no-repeat; background-color: #4F4F4F; } @@ -197,7 +194,8 @@ } .toolbar-button.users { - background: url('./icons/disableFullscreenIcon.svg'); + background: url('./icons/usersIcon.svg') 50% 50% no-repeat; + background-color: #4F4F4F; } .toolbar-button.micro { @@ -225,12 +223,12 @@ background-color: #4F4F4F; } -.toolbar-button.soundOff { +.toolbar-button.sound { background: url('./icons/soundOffIcon.svg') 50% 50% no-repeat; background-color: #4F4F4F; } -.toolbar-button.soundOn { +.toolbar-button.sound.on { background: url('./icons/soundOnIcon.svg') 50% 50% no-repeat; background-color: #4F4F4F; } @@ -256,7 +254,7 @@ .show-toolbar-enter { - transform: translateX(-70px); + transform: translateX(-60px); } .show-toolbar-enter-done { @@ -273,6 +271,25 @@ } .show-toolbar-exit-active { - transform: translateX(-70px); + transform: translateX(-60px); transition: .3s; +} + +@media screen and (max-height: 700px) { + .toolbar-field { + padding: 20px 14px; + } + + .toolbar-button { + width: 44px; + height: 44px; + } + + .toolbar-button:hover { + opacity: 1; + } + + .toolbar-button:active { + opacity: .7; + } } \ No newline at end of file diff --git a/src/components/mainScreen/toolbar/toolbar.tsx b/src/components/mainScreen/toolbar/toolbar.tsx index dc7e7e4..eda10ba 100644 --- a/src/components/mainScreen/toolbar/toolbar.tsx +++ b/src/components/mainScreen/toolbar/toolbar.tsx @@ -1,4 +1,5 @@ -import React from "react"; +import React, { useContext } from "react"; +import { ContextWindowHeight } from "../../contextWindowHeight"; import { ButtonContainer } from "./buttonContainer"; import './toolbar.css'; import { ToolbarButton } from "./toolbarButton"; @@ -7,36 +8,109 @@ import { CaptionToolbarButtons } from "./typeCaptionButtons"; type TProps = { onClickOpenButton: () => void + onClickMobileUsers?: () => void isOpen: boolean } export const Toolbar:React.FC = React.memo((props) => { + const windowHeight = useContext(ContextWindowHeight); + + if(windowHeight < 700) { + return
+
+
+ { + if(!document.fullscreenElement) { + document.documentElement.requestFullscreen(); + } else { + document.exitFullscreen(); + } + }} + caption={CaptionToolbarButtons['fullscreen on']} + active={true} + isCaption={false} + /> + +
+
+ console.log('click'), + active: true, + isCaption: false + }, + { + type: "micro", + onClick: () => console.log('click'), + active: false, + isCaption: false + } + ]} + /> + {/* */} + null} + caption={CaptionToolbarButtons["other"]} + isCaption={false} + /> +
+
+ +
+ } return
null} - caption={CaptionToolbarButtons["fullscreenOn"]} + type="fullscreen" + onClick={() => { + if(!document.fullscreenElement) { + document.documentElement.requestFullscreen(); + } else { + document.exitFullscreen(); + } + }} + caption={CaptionToolbarButtons['fullscreen on']} + active={true} + isCaption={true} /> console.log('click'), + isCaption: true }, { type: "user self", - onClick: () => console.log('click') - }, - { - type: "user guest", - onClick: () => console.log('click') + onClick: () => console.log('click'), + isCaption: true }, { type: "user guest", onClick: () => console.log('click'), - isNotification: true + isCaption: true + }, + { + type: "user guest", + onClick: () => console.log('click'), + isNotification: true, + isCaption: true } ]} /> @@ -45,12 +119,16 @@ export const Toolbar:React.FC = React.memo((props) => { console.log('click') + type: "control", + onClick: () => console.log('click'), + active: true, + isCaption: true }, { type: "micro", - onClick: () => console.log('click') + onClick: () => console.log('click'), + active: false, + isCaption: true } ]} /> @@ -58,12 +136,14 @@ export const Toolbar:React.FC = React.memo((props) => { type="share" onClick={() => console.log('click')} caption={CaptionToolbarButtons["share"]} + isCaption={true} /> - null} caption={CaptionToolbarButtons["exit"]} + isCaption={true} />
diff --git a/src/components/mainScreen/toolbar/toolbarButton.tsx b/src/components/mainScreen/toolbar/toolbarButton.tsx index 1d836b4..2ca5256 100644 --- a/src/components/mainScreen/toolbar/toolbarButton.tsx +++ b/src/components/mainScreen/toolbar/toolbarButton.tsx @@ -1,17 +1,21 @@ import React, { useState } from "react"; import { TypeToolbarButtons } from "./typeButtons"; +import { CaptionToolbarButtons } from "./typeCaptionButtons"; type TProps = { onClick: () => void type: TypeToolbarButtons - isNotification?: boolean + isCaption: boolean caption: string + active?: boolean + isNotification?: boolean } export const ToolbarButton:React.FC = React.memo((props) => { - const [isActive, setIsActive] = useState(false); + const [isActive, setIsActive] = useState(props?.active || false); const [isActive2, setIsActive2] = useState(false); const [showAddButtons, setShowAddBUttons] = useState(false) + function onClick() { setIsActive(!isActive) } @@ -26,11 +30,17 @@ export const ToolbarButton:React.FC = React.memo((props) => { return
- { + {/* { showAddButtons && props.type.includes('user') &&
@@ -45,10 +55,15 @@ export const ToolbarButton:React.FC = React.memo((props) => { >
- } - {/*
- - {props.caption} -
*/} + } */} + { + props.isCaption &&
+ + { + //@ts-ignore + {CaptionToolbarButtons[isActive ? `${props.type} on` : props.type]} + } +
+ }
}) \ No newline at end of file diff --git a/src/components/mainScreen/toolbar/typeButtons.ts b/src/components/mainScreen/toolbar/typeButtons.ts index fb66bbf..0ab9f4b 100644 --- a/src/components/mainScreen/toolbar/typeButtons.ts +++ b/src/components/mainScreen/toolbar/typeButtons.ts @@ -1,17 +1,17 @@ export type TypeToolbarButtons = - 'fullscreenOn' - | 'fullscreenOff' + // 'fullscreenOn' + 'fullscreen' | 'user admin' | 'user guest' | 'user self' | 'users' | 'micro' - | 'micro on' + // | 'micro on' | 'control' - | 'control on' + // | 'control on' | 'other' - | 'soundOn' - | 'soundOff' + // | 'sound on' + | 'sound' | 'exit' | 'copy' | 'share' \ No newline at end of file diff --git a/src/components/mainScreen/toolbar/typeCaptionButtons.ts b/src/components/mainScreen/toolbar/typeCaptionButtons.ts index 6e5131a..ab1428f 100644 --- a/src/components/mainScreen/toolbar/typeCaptionButtons.ts +++ b/src/components/mainScreen/toolbar/typeCaptionButtons.ts @@ -1,18 +1,18 @@ export const CaptionToolbarButtons = { - fullscreenOn: 'Развернуть', - fullscreenOff: 'Свернуть', + 'fullscreen on': 'Развернуть', + 'fullscreen': 'Свернуть', 'user admin': 'Администратор', 'user guest': 'Гость', 'user self': 'Вы', 'users': 'Пользователи', 'micro': 'Включить микрофон', 'micro on': 'Выключить микрофон', - 'control on': '', + 'control on': 'Запрет управления', 'control': 'Запрос управления', - 'other': '', - 'soundOn': '', - 'soundOff': '', + 'other': 'Дополнительно', + 'sound on': 'Выключить звук', + 'sound': 'Включить звук', 'exit': 'Завершить презентацию', - 'copy': '', + 'copy': 'Скопировать', 'share': 'Поделиться' } \ No newline at end of file diff --git a/src/components/startPage/startPage.css b/src/components/startPage/startPage.css new file mode 100644 index 0000000..71741ac --- /dev/null +++ b/src/components/startPage/startPage.css @@ -0,0 +1,6 @@ +.start-page-container { + width: 100%; + height: 100vh; + background: rgba(17, 13, 28, 0.8); + backdrop-filter: blur(24px); +} \ No newline at end of file diff --git a/src/components/startPage/startPage.tsx b/src/components/startPage/startPage.tsx new file mode 100644 index 0000000..10537b4 --- /dev/null +++ b/src/components/startPage/startPage.tsx @@ -0,0 +1,8 @@ +import React from "react"; +import './startPage.css'; + +export const StartPage:React.FC = React.memo(() => { + return
+ +
+}) \ No newline at end of file