Major cleanup. Moved a lot of CSS variables out too root of CSS for easier styling.

master
Håvar Aambø Fosstveit 2018-12-18 12:13:47 +01:00
parent db9d423feb
commit 651cd6f737
44 changed files with 296 additions and 517 deletions

View File

@ -365,9 +365,7 @@ export default class RoomClient
{ {
if (err) if (err)
{ {
return this.props.notify({ return this.notify('An error occurred while saving a file');
text : 'An error occurred while saving a file'
});
} }
saveAs(blob, file.name); saveAs(blob, file.name);
@ -396,23 +394,27 @@ export default class RoomClient
// same file was sent multiple times. // same file was sent multiple times.
if (torrent.progress === 1) if (torrent.progress === 1)
{ {
return store.dispatch(
store.dispatch(
stateActions.setFileDone( stateActions.setFileDone(
torrent.magnetURI, torrent.magnetURI,
torrent.files torrent.files
)); ));
return;
} }
let lastMove = 0;
torrent.on('download', () => torrent.on('download', () =>
{
if (Date.now() - lastMove > 1000)
{ {
store.dispatch( store.dispatch(
stateActions.setFileProgress( stateActions.setFileProgress(
torrent.magnetURI, torrent.magnetURI,
torrent.progress torrent.progress
)); ));
lastMove = Date.now();
}
}); });
torrent.on('done', () => torrent.on('done', () =>

View File

@ -2,7 +2,7 @@ import React, { Component } from 'react';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import classnames from 'classnames'; import classnames from 'classnames';
import * as stateActions from '../redux/stateActions'; import * as stateActions from '../../redux/stateActions';
class HiddenPeers extends Component class HiddenPeers extends Component
{ {
@ -29,7 +29,7 @@ class HiddenPeers extends Component
this.timeout = setTimeout(() => this.timeout = setTimeout(() =>
{ {
this.setState({ className: '' }); this.setState({ className: '' });
}, 2000); }, 500);
}); });
} }
} }
@ -42,20 +42,13 @@ class HiddenPeers extends Component
} = this.props; } = this.props;
return ( return (
<div <div data-component='HiddenPeers'>
data-component='HiddenPeers'
className={this.state.className}
onMouseOver={this.handleMouseOver}
onMouseOut={this.handleMouseOut}
>
<div data-component='HiddenPeersView'>
<div className={classnames('view-container', this.state.className)} onClick={() => openUsersTab()}> <div className={classnames('view-container', this.state.className)} onClick={() => openUsersTab()}>
<p>+{hiddenPeersCount} <br /> participant <p>+{hiddenPeersCount} <br /> participant
{(hiddenPeersCount === 1) ? null : 's'} {(hiddenPeersCount === 1) ? null : 's'}
</p> </p>
</div> </div>
</div> </div>
</div>
); );
} }
} }

View File

@ -4,10 +4,10 @@ import ReactTooltip from 'react-tooltip';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import classnames from 'classnames'; import classnames from 'classnames';
import { getDeviceInfo } from 'mediasoup-client'; import { getDeviceInfo } from 'mediasoup-client';
import * as appPropTypes from './appPropTypes'; import * as appPropTypes from '../appPropTypes';
import { withRoomContext } from '../RoomContext'; import { withRoomContext } from '../../RoomContext';
import PeerView from './PeerView'; import PeerView from '../VideoContainers/PeerView';
import ScreenView from './ScreenView'; import ScreenView from '../VideoContainers/ScreenView';
class Me extends React.Component class Me extends React.Component
{ {

View File

@ -2,11 +2,11 @@ import React, { Component } from 'react';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import classnames from 'classnames'; import classnames from 'classnames';
import * as appPropTypes from './appPropTypes'; import * as appPropTypes from '../appPropTypes';
import { withRoomContext } from '../RoomContext'; import { withRoomContext } from '../../RoomContext';
import * as stateActions from '../redux/stateActions'; import * as stateActions from '../../redux/stateActions';
import PeerView from './PeerView'; import PeerView from '../VideoContainers/PeerView';
import ScreenView from './ScreenView'; import ScreenView from '../VideoContainers/ScreenView';
class Peer extends Component class Peer extends Component
{ {
@ -139,7 +139,9 @@ class Peer extends Component
/> />
<div <div
className={classnames('button', 'fullscreen')} className={classnames('button', 'fullscreen', {
disabled : !videoVisible
})}
onClick={(e) => onClick={(e) =>
{ {
e.stopPropagation(); e.stopPropagation();
@ -168,7 +170,10 @@ class Peer extends Component
})} })}
> >
<div <div
className={classnames('button', 'newwindow')} className={classnames('button', 'newwindow', {
disabled : !screenVisible ||
(windowConsumer === screenConsumer.id)
})}
onClick={(e) => onClick={(e) =>
{ {
e.stopPropagation(); e.stopPropagation();
@ -177,7 +182,9 @@ class Peer extends Component
/> />
<div <div
className={classnames('button', 'fullscreen')} className={classnames('button', 'fullscreen', {
disabled : !screenVisible
})}
onClick={(e) => onClick={(e) =>
{ {
e.stopPropagation(); e.stopPropagation();

View File

@ -2,9 +2,9 @@ import React, { Component } from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import classnames from 'classnames'; import classnames from 'classnames';
import * as appPropTypes from './appPropTypes'; import * as appPropTypes from '../appPropTypes';
import { withRoomContext } from '../RoomContext'; import { withRoomContext } from '../../RoomContext';
import FullScreen from './FullScreen'; import FullScreen from '../FullScreen';
class Sidebar extends Component class Sidebar extends Component
{ {

View File

@ -4,9 +4,9 @@ import ResizeObserver from 'resize-observer-polyfill';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import debounce from 'lodash/debounce'; import debounce from 'lodash/debounce';
import classnames from 'classnames'; import classnames from 'classnames';
import { withRoomContext } from '../RoomContext'; import { withRoomContext } from '../../RoomContext';
import Peer from './Peer'; import Peer from '../Containers/Peer';
import HiddenPeers from './HiddenPeers'; import HiddenPeers from '../Containers/HiddenPeers';
class Filmstrip extends Component class Filmstrip extends Component
{ {

View File

@ -3,9 +3,9 @@ import { connect } from 'react-redux';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import classnames from 'classnames'; import classnames from 'classnames';
import debounce from 'lodash/debounce'; import debounce from 'lodash/debounce';
import { Appear } from './transitions'; import { Appear } from '../transitions';
import Peer from './Peer'; import Peer from '../Containers/Peer';
import HiddenPeers from './HiddenPeers'; import HiddenPeers from '../Containers/HiddenPeers';
import ResizeObserver from 'resize-observer-polyfill'; import ResizeObserver from 'resize-observer-polyfill';
const RATIO = 1.334; const RATIO = 1.334;
@ -129,9 +129,9 @@ class Peers extends React.Component
} }
})} })}
<div className='hidden-peer-container'> <div className='hidden-peer-container'>
<If condition={spotlightsLength < peers.length}> <If condition={spotlightsLength < Object.keys(peers).length}>
<HiddenPeers <HiddenPeers
hiddenPeersCount={peers.length-spotlightsLength} hiddenPeersCount={Object.keys(peers).length - spotlightsLength}
/> />
</If> </If>
</div> </div>

View File

@ -9,17 +9,17 @@ import * as appPropTypes from './appPropTypes';
import * as requestActions from '../redux/requestActions'; import * as requestActions from '../redux/requestActions';
import * as stateActions from '../redux/stateActions'; import * as stateActions from '../redux/stateActions';
import { Appear } from './transitions'; import { Appear } from './transitions';
import Me from './Me'; import Me from './Containers/Me';
import Peers from './Peers'; import Peers from './Layouts/Peers';
import AudioPeers from './PeerAudio/AudioPeers'; import AudioPeers from './PeerAudio/AudioPeers';
import Notifications from './Notifications'; import Notifications from './Notifications';
import ToolArea from './ToolArea/ToolArea'; import ToolArea from './ToolArea/ToolArea';
import FullScreenView from './FullScreenView'; import FullScreenView from './VideoContainers/FullScreenView';
import VideoWindow from './VideoWindow/VideoWindow'; import VideoWindow from './VideoWindow/VideoWindow';
import Draggable from 'react-draggable'; import Draggable from 'react-draggable';
import { idle } from '../utils'; import { idle } from '../utils';
import Sidebar from './Sidebar'; import Sidebar from './Controls/Sidebar';
import Filmstrip from './Filmstrip'; import Filmstrip from './Layouts/Filmstrip';
// Hide toolbars after 10 seconds of inactivity. // Hide toolbars after 10 seconds of inactivity.
const TIMEOUT = 10 * 1000; const TIMEOUT = 10 * 1000;

View File

@ -1,7 +1,7 @@
import React, { Component } from 'react'; import React, { Component } from 'react';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { withRoomContext } from '../../RoomContext'; import { withRoomContext } from '../../../RoomContext';
import MessageList from './MessageList'; import MessageList from './MessageList';
class Chat extends Component class Chat extends Component

View File

@ -3,7 +3,7 @@ import { compose } from 'redux';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import marked from 'marked'; import marked from 'marked';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import scrollToBottom from './scrollToBottom'; import scrollToBottom from '../scrollToBottom';
const linkRenderer = new marked.Renderer(); const linkRenderer = new marked.Renderer();

View File

@ -1,7 +1,7 @@
import React, { Component, Fragment } from 'react'; import React, { Component, Fragment } from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { withRoomContext } from '../../RoomContext'; import { withRoomContext } from '../../../RoomContext';
import magnet from 'magnet-uri'; import magnet from 'magnet-uri';
const DEFAULT_PICTURE = 'resources/images/avatar-empty.jpeg'; const DEFAULT_PICTURE = 'resources/images/avatar-empty.jpeg';

View File

@ -2,7 +2,7 @@ import React, { Component } from 'react';
import { compose } from 'redux'; import { compose } from 'redux';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import scrollToBottom from '../Chat/scrollToBottom'; import scrollToBottom from '../scrollToBottom';
import File from './File'; import File from './File';
class FileList extends Component class FileList extends Component

View File

@ -2,7 +2,7 @@ import React, { Component } from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import classNames from 'classnames'; import classNames from 'classnames';
import { withRoomContext } from '../../RoomContext'; import { withRoomContext } from '../../../RoomContext';
import FileList from './FileList'; import FileList from './FileList';
class FileSharing extends Component class FileSharing extends Component

View File

@ -1,6 +1,6 @@
import React from 'react'; import React from 'react';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { Me } from '../appPropTypes'; import { Me } from '../../appPropTypes';
const ListMe = ({ me }) => const ListMe = ({ me }) =>
{ {

View File

@ -2,8 +2,8 @@ import React from 'react';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import classnames from 'classnames'; import classnames from 'classnames';
import * as appPropTypes from '../appPropTypes'; import * as appPropTypes from '../../appPropTypes';
import { withRoomContext } from '../../RoomContext'; import { withRoomContext } from '../../../RoomContext';
const ListPeer = (props) => const ListPeer = (props) =>
{ {

View File

@ -1,8 +1,8 @@
import React from 'react'; import React from 'react';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import classNames from 'classnames'; import classNames from 'classnames';
import * as appPropTypes from '../appPropTypes'; import * as appPropTypes from '../../appPropTypes';
import { withRoomContext } from '../../RoomContext'; import { withRoomContext } from '../../../RoomContext';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import ListPeer from './ListPeer'; import ListPeer from './ListPeer';
import ListMe from './ListMe'; import ListMe from './ListMe';

View File

@ -1,8 +1,8 @@
import React from 'react'; import React from 'react';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import * as appPropTypes from './appPropTypes'; import * as appPropTypes from '../../appPropTypes';
import { withRoomContext } from '../RoomContext'; import { withRoomContext } from '../../../RoomContext';
import * as stateActions from '../redux/stateActions'; import * as stateActions from '../../../redux/stateActions';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import Dropdown from 'react-dropdown'; import Dropdown from 'react-dropdown';
import ReactTooltip from 'react-tooltip'; import ReactTooltip from 'react-tooltip';
@ -46,7 +46,6 @@ const Settings = ({
audioDevices = []; audioDevices = [];
return ( return (
<div data-component='Settings'>
<div className='settings'> <div className='settings'>
<Dropdown <Dropdown
options={webcams} options={webcams}
@ -91,7 +90,6 @@ const Settings = ({
/> />
</div> </div>
</div> </div>
</div>
); );
}; };

View File

@ -3,10 +3,10 @@ import { connect } from 'react-redux';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import classNames from 'classnames'; import classNames from 'classnames';
import * as stateActions from '../../redux/stateActions'; import * as stateActions from '../../redux/stateActions';
import ParticipantList from '../ParticipantList/ParticipantList'; import ParticipantList from './ParticipantList/ParticipantList';
import Chat from '../Chat/Chat'; import Chat from './Chat/Chat';
import Settings from '../Settings'; import Settings from './Settings/Settings';
import FileSharing from '../FileSharing/FileSharing'; import FileSharing from './FileSharing/FileSharing';
import TabHeader from './TabHeader'; import TabHeader from './TabHeader';
class ToolArea extends React.Component class ToolArea extends React.Component

View File

@ -2,8 +2,8 @@ import React from 'react';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import classnames from 'classnames'; import classnames from 'classnames';
import * as appPropTypes from './appPropTypes'; import * as appPropTypes from '../appPropTypes';
import * as stateActions from '../redux/stateActions'; import * as stateActions from '../../redux/stateActions';
import FullView from './FullView'; import FullView from './FullView';
const FullScreenView = (props) => const FullScreenView = (props) =>

View File

@ -1,7 +1,6 @@
import React from 'react'; import React from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import classnames from 'classnames'; import classnames from 'classnames';
import Spinner from 'react-spinner';
export default class FullView extends React.Component export default class FullView extends React.Component
{ {
@ -34,12 +33,6 @@ export default class FullView extends React.Component
autoPlay autoPlay
muted={Boolean(true)} muted={Boolean(true)}
/> />
<If condition={videoProfile === 'none'}>
<div className='spinner-container'>
<Spinner />
</div>
</If>
</div> </div>
); );
} }

View File

@ -1,9 +1,8 @@
import React from 'react'; import React from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import classnames from 'classnames'; import classnames from 'classnames';
import Spinner from 'react-spinner'; import * as appPropTypes from '../appPropTypes';
import * as appPropTypes from './appPropTypes'; import EditableInput from '../Controls/EditableInput';
import EditableInput from './EditableInput';
export default class PeerView extends React.Component export default class PeerView extends React.Component
{ {
@ -122,12 +121,6 @@ export default class PeerView extends React.Component
<div className='volume-container'> <div className='volume-container'>
<div className={classnames('bar', `level${volume}`)} /> <div className={classnames('bar', `level${volume}`)} />
</div> </div>
<If condition={videoProfile === 'none'}>
<div className='spinner-container'>
<Spinner />
</div>
</If>
</div> </div>
); );
} }

View File

@ -1,7 +1,6 @@
import React from 'react'; import React from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import classnames from 'classnames'; import classnames from 'classnames';
import Spinner from 'react-spinner';
export default class ScreenView extends React.Component export default class ScreenView extends React.Component
{ {
@ -68,12 +67,6 @@ export default class ScreenView extends React.Component
autoPlay autoPlay
muted={Boolean(true)} muted={Boolean(true)}
/> />
<If condition={screenProfile === 'none'}>
<div className='spinner-container'>
<Spinner />
</div>
</If>
</div> </div>
); );
} }

View File

@ -4,7 +4,7 @@ import NewWindow from './NewWindow';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import * as appPropTypes from '../appPropTypes'; import * as appPropTypes from '../appPropTypes';
import * as stateActions from '../../redux/stateActions'; import * as stateActions from '../../redux/stateActions';
import FullView from '../FullView'; import FullView from '../VideoContainers/FullView';
const VideoWindow = (props) => const VideoWindow = (props) =>
{ {

View File

@ -23,7 +23,7 @@
} }
> .client, > .response { > .client, > .response {
background-color: rgba(#000, 0.1); background-color: var(--chat-message-color);
border-radius: 5px; border-radius: 5px;
max-width: 85%; max-width: 85%;
display: flex; display: flex;
@ -70,8 +70,8 @@
[data-component='Sender'] { [data-component='Sender'] {
display: flex; display: flex;
background-color: #fff; background-color: var(--chat-input-bg-color);
color: #000; color: var(--chat-input-text-color);
flex-shrink: 0; flex-shrink: 0;
margin-top: 0.5rem; margin-top: 0.5rem;
height: 3rem; height: 3rem;
@ -84,7 +84,6 @@
margin-right: 1vmin; margin-right: 1vmin;
border-radius: 0.5vmin; border-radius: 0.5vmin;
padding-left: 1vmin; padding-left: 1vmin;
color: #000;
&.focus { &.focus {
outline: none; outline: none;
@ -95,8 +94,7 @@
width: 20%; width: 20%;
box-shadow: 0vmin 0vmin 1vmin 0vmin rgba(17,17,17,0.5); box-shadow: 0vmin 0vmin 1vmin 0vmin rgba(17,17,17,0.5);
border: 0; border: 0;
background-color: #aef; background-color: var(--chat-send-bg-color);
color: #000;
font-size: 1rem; font-size: 1rem;
border-radius: 0.5vmin; border-radius: 0.5vmin;
} }

View File

@ -7,11 +7,15 @@
> .share-file { > .share-file {
cursor: pointer; cursor: pointer;
width: 100%; width: 100%;
background: #aef; background: var(--filesharing-bg-color);
padding: 1rem; padding: 1rem;
border-radius: 1vmin; border-radius: 1vmin;
box-shadow: 0vmin 0vmin 1vmin 0vmin rgba(17,17,17,0.5); box-shadow: 0vmin 0vmin 1vmin 0vmin rgba(17,17,17,0.5);
&:hover {
opacity: 0.85;
}
&.disabled { &.disabled {
cursor: not-allowed; cursor: not-allowed;
} }

View File

@ -63,13 +63,13 @@
&.active { &.active {
> .film-content { > .film-content {
border-color: #FFF; border-color: var(--active-speaker-border-color);
} }
} }
&.selected { &.selected {
> .film-content { > .film-content {
border-color: #377EFF; border-color: var(--selected-peer-border-color);
} }
} }
} }

View File

@ -69,37 +69,4 @@
filter: blur(5px); filter: blur(5px);
} }
} }
> .spinner-container {
position: absolute;
top: 0
bottom: 0;
left: 0;
right: 0;
background-color: rgba(#000, 0.75);
.react-spinner {
position: relative;
width: 48px;
height: 48px;
top: 50%;
left: 50%;
.react-spinner_bar {
position: absolute;
width: 20%;
height: 7.8%;
top: -3.9%;
left: -10%;
animation: PeerView-spinner 1.2s linear infinite;
border-radius: 5px;
background-color: rgba(#fff, 0.5);
}
}
}
}
@keyframes FullView-spinner {
0% { opacity: 1; }
100% { opacity: 0.15; }
} }

View File

@ -1,4 +1,4 @@
[data-component='HiddenPeersView'] { [data-component='HiddenPeers'] {
height: 100%; height: 100%;
width: 100%; width: 100%;
display: flex; display: flex;
@ -31,6 +31,8 @@
background-position: bottom; background-position: bottom;
background-size: auto 85%; background-size: auto 85%;
background-repeat: no-repeat; background-repeat: no-repeat;
border: var(--peer-border);
box-shadow: var(--peer-shadow);
text-align: center; text-align: center;
vertical-align: middle; vertical-align: middle;
line-height: 1.8vmin; line-height: 1.8vmin;
@ -39,55 +41,28 @@
animation: none; animation: none;
&.pulse { &.pulse {
animation: pulse 2s; animation: pulse 0.5s;
} }
} }
.view-container>p{ .view-container>p{
transform: translate(0%,50%); transform: translate(0%,50%);
} }
.view-container,
.view-container::before,
.view-container::after {
/* Add shadow to distinguish sheets from one another */
box-shadow: 2px 1px 1px rgba(0,0,0,0.15);
}
.view-container::before,
.view-container::after {
content: "";
position: absolute;
width: 100%;
height: 100%;
background-color: #2a4b58;
}
/* Second sheet of paper */
.view-container::before {
left: .7vmin;
top: .7vmin;
z-index: -1;
}
/* Third sheet of paper */
.view-container::after {
left: 1.4vmin;
top: 1.4vmin;
z-index: -2;
}
} }
@keyframes pulse { @keyframes pulse {
0% { 0%
box-shadow: 0 0 0 0 rgba(255, 255, 255, 1.0); {
transform: scale3d(1, 1, 1);
} }
70% { 50%
box-shadow: 0 0 0 10px rgba(255, 255, 255, 0); {
transform: scale3d(1.2, 1.2, 1.2);
} }
100% { 100%
box-shadow: 0 0 0 0 rgba(255, 255, 255, 0); {
transform: scale3d(1, 1, 1);
} }
} }

View File

@ -1,19 +1,18 @@
[data-component='Logo'] { [data-component='Logo'] {
position: absolute; position: absolute;
height: 4%; width: var(--logo-width);
width: 8%; height: var(--logo-height);
top: 1%; top: 1%;
left: 1%; left: 1%;
z-index: 20; z-index: 20;
background-position: left; background-position: left;
background-size: 100%; background-size: 100%;
background-repeat: no-repeat; background-repeat: no-repeat;
+desktop() { +desktop() {
opacity: 1; opacity: 1;
} }
+mobile() { background-image: var(--logo);
}
background-image: url('/resources/images/logo.svg');
background-size: contain; background-size: contain;
} }

View File

@ -6,8 +6,8 @@
> .view-container { > .view-container {
position: relative; position: relative;
width: 20vmin; width: var(--me-width);
height: 15vmin; height: var(--me-height);
&.webcam { &.webcam {
order: 2; order: 2;
@ -23,9 +23,7 @@
right: 0; right: 0;
top: 0; top: 0;
display: flex; display: flex;
flex-direction:; row; flex-direction: row;
justify-content: flex-start;
align-items: center;
padding: 0.4vmin; padding: 0.4vmin;
opacity: 0; opacity: 0;
transition: opacity 0.3s; transition: opacity 0.3s;
@ -41,28 +39,20 @@
background-position: center; background-position: center;
background-size: 75%; background-size: 75%;
background-repeat: no-repeat; background-repeat: no-repeat;
background-color: rgba(#000, 0.5); background-color: var(--media-control-button-color);
cursor: pointer; cursor: pointer;
opacity: 0; opacity: 0;
transition-property: opacity, background-color; transition-property: opacity, background-color;
transition-duration: 0.15s; transition-duration: 0.15s;
width: var(--media-control-button-size);
&.visible { height: var(--media-control-button-size);
opacity: 0.85;
}
+desktop() {
width: 24px;
height: 24px;
&:hover { &:hover {
opacity: 1; opacity: 1;
} }
}
+mobile() { &.visible {
width: 22px; opacity: 0.85;
height: 22px;
} }
&.unsupported { &.unsupported {
@ -71,11 +61,15 @@
&.disabled { &.disabled {
pointer-events: none; pointer-events: none;
opacity: 0.5; background-color: var(--media-control-botton-disabled);
} }
&.on { &.on {
background-color: rgba(#fff, 0.7); background-color: var(--media-control-botton-on);
}
&.off {
background-color: var(--media-control-botton-off);
} }
&.mic { &.mic {
@ -85,7 +79,6 @@
&.off { &.off {
background-image: url('/resources/images/icon_remote_mic_white_off.svg'); background-image: url('/resources/images/icon_remote_mic_white_off.svg');
background-color: rgba(#d42241, 0.7);
} }
&.unsupported { &.unsupported {
@ -100,33 +93,12 @@
&.off { &.off {
background-image: url('/resources/images/icon_remote_webcam_white_off.svg'); background-image: url('/resources/images/icon_remote_webcam_white_off.svg');
background-color: rgba(#d42241, 0.7);
} }
&.unsupported { &.unsupported {
background-image: url('/resources/images/icon_webcam_white_unsupported.svg'); background-image: url('/resources/images/icon_webcam_white_unsupported.svg');
} }
} }
&.screen {
&.on {
background-image: url('/resources/images/share-screen-black.svg');
}
&.off {
background-image: url('/resources/images/no-share-screen-white.svg');
background-color: rgba(#d42241, 0.7);
}
&.unsupported {
background-image: url('/resources/images/no-share-screen-white.svg');
}
}
&.fullscreen {
background-image: url('/resources/images/icon_fullscreen_black.svg');
background-color: rgba(#fff, 0.7);
}
} }
} }
} }

View File

@ -84,8 +84,8 @@
} }
&.info { &.info {
background-color: rgba(#0a1d26, 0.75); background-color: var(--notification-info-bg-color);
color: rgba(#fff, 0.65); color: var(--notification-info-text-color);
>.icon { >.icon {
opacity: 0.65; opacity: 0.65;
@ -94,8 +94,8 @@
} }
&.error { &.error {
background-color: rgba(#ff1914, 0.65); background-color: var(--notification-error-bg-color);
color: rgba(#fff, 0.85); color: var(--notification-error-text-color);
>.icon { >.icon {
opacity: 0.85; opacity: 0.85;

View File

@ -51,21 +51,13 @@
background-color: rgba(#000, 0.5); background-color: rgba(#000, 0.5);
transition-property: opacity, background-color; transition-property: opacity, background-color;
transition-duration: 0.15s; transition-duration: 0.15s;
width: var(--media-control-button-size);
+desktop() { height: var(--media-control-button-size);
width: 24px;
height: 24px;
opacity: 0.85; opacity: 0.85;
&:hover { &:hover {
opacity: 1; opacity: 1;
} }
}
+mobile() {
width: 22px;
height: 22px;
}
&.on { &.on {
opacity: 1; opacity: 1;
@ -102,19 +94,20 @@
position: absolute; position: absolute;
bottom: 0px; bottom: 0px;
&.level0 { height: 0; background-color: rgba(#000, 0.8); } &.level0 { height: 0; }
&.level1 { height: 0.2vh; background-color: rgba(#000, 0.8); } &.level1 { height: 0.2vh; }
&.level2 { height: 0.4vh; background-color: rgba(#000, 0.8); } &.level2 { height: 0.4vh; }
&.level3 { height: 0.6vh; background-color: rgba(#000, 0.8); } &.level3 { height: 0.6vh; }
&.level4 { height: 0.8vh; background-color: rgba(#000, 0.8); } &.level4 { height: 0.8vh; }
&.level5 { height: 1.0vh; background-color: rgba(#000, 0.8); } &.level5 { height: 1.0vh; }
&.level6 { height: 1.2vh; background-color: rgba(#000, 0.8); } &.level6 { height: 1.2vh; }
&.level7 { height: 1.4vh; background-color: rgba(#000, 0.8); } &.level7 { height: 1.4vh; }
&.level8 { height: 1.6vh; background-color: rgba(#000, 0.8); } &.level8 { height: 1.6vh; }
&.level9 { height: 1.8vh; background-color: rgba(#000, 0.8); } &.level9 { height: 1.8vh; }
&.level10 { height: 2.0vh; background-color: rgba(#000, 0.8); } &.level10 { height: 2.0vh; }
} }
} }
> .controls { > .controls {
float: right; float: right;
display: flex; display: flex;
@ -133,21 +126,13 @@
cursor: pointer; cursor: pointer;
transition-property: opacity, background-color; transition-property: opacity, background-color;
transition-duration: 0.15s; transition-duration: 0.15s;
width: var(--media-control-button-size);
+desktop() { height: var(--media-control-button-size);
width: 24px;
height: 24px;
opacity: 0.85; opacity: 0.85;
&:hover { &:hover {
opacity: 1; opacity: 1;
} }
}
+mobile() {
width: 22px;
height: 22px;
}
&.unsupported { &.unsupported {
pointer-events: none; pointer-events: none;
@ -155,11 +140,15 @@
&.disabled { &.disabled {
pointer-events: none; pointer-events: none;
opacity: 0.5; background-color: var(--media-control-botton-disabled);
} }
&.on { &.on {
background-color: rgba(#fff, 0.7); background-color: var(--media-control-botton-on);
}
&.off {
background-color: var(--media-control-botton-off);
} }
&.mic { &.mic {
@ -169,7 +158,6 @@
&.off { &.off {
background-image: url('/resources/images/icon_remote_mic_white_off.svg'); background-image: url('/resources/images/icon_remote_mic_white_off.svg');
background-color: rgba(#d42241, 0.7);
} }
&.unsupported { &.unsupported {
@ -184,7 +172,6 @@
&.off { &.off {
background-image: url('/resources/images/icon_remote_webcam_white_off.svg'); background-image: url('/resources/images/icon_remote_webcam_white_off.svg');
background-color: rgba(#d42241, 0.7);
} }
&.unsupported { &.unsupported {
@ -199,7 +186,6 @@
&.off { &.off {
background-image: url('/resources/images/no-share-screen-white.svg'); background-image: url('/resources/images/no-share-screen-white.svg');
background-color: rgba(#d42241, 0.7);
} }
&.unsupported { &.unsupported {

View File

@ -54,21 +54,13 @@
background-color: rgba(#000, 0.5); background-color: rgba(#000, 0.5);
transition-property: opacity, background-color; transition-property: opacity, background-color;
transition-duration: 0.15s; transition-duration: 0.15s;
width: var(--media-control-button-size);
+desktop() { height: var(--media-control-button-size);
width: 24px;
height: 24px;
opacity: 0.85; opacity: 0.85;
&:hover { &:hover {
opacity: 1; opacity: 1;
} }
}
+mobile() {
width: 22px;
height: 22px;
}
&.on { &.on {
opacity: 1; opacity: 1;
@ -107,25 +99,17 @@
background-position: center; background-position: center;
background-size: 75%; background-size: 75%;
background-repeat: no-repeat; background-repeat: no-repeat;
background-color: rgba(#000, 0.5); background-color: var(--media-control-button-color);
cursor: pointer; cursor: pointer;
transition-property: opacity, background-color; transition-property: opacity, background-color;
transition-duration: 0.15s; transition-duration: 0.15s;
width: var(--media-control-button-size);
+desktop() { height: var(--media-control-button-size);
width: 24px;
height: 24px;
opacity: 0.85; opacity: 0.85;
&:hover { &:hover {
opacity: 1; opacity: 1;
} }
}
+mobile() {
width: 22px;
height: 22px;
}
&.unsupported { &.unsupported {
pointer-events: none; pointer-events: none;
@ -133,11 +117,15 @@
&.disabled { &.disabled {
pointer-events: none; pointer-events: none;
opacity: 0.5; background-color: var(--media-control-botton-disabled);
} }
&.on { &.on {
background-color: rgba(#fff, 0.7); background-color: var(--media-control-botton-on);
}
&.off {
background-color: var(--media-control-botton-off);
} }
&.mic { &.mic {
@ -147,7 +135,6 @@
&.off { &.off {
background-image: url('/resources/images/icon_remote_mic_white_off.svg'); background-image: url('/resources/images/icon_remote_mic_white_off.svg');
background-color: rgba(#d42241, 0.7);
} }
&.unsupported { &.unsupported {
@ -155,21 +142,6 @@
} }
} }
&.webcam {
&.on {
background-image: url('/resources/images/icon_webcam_black_on.svg');
}
&.off {
background-image: url('/resources/images/icon_remote_webcam_white_off.svg');
background-color: rgba(#d42241, 0.7);
}
&.unsupported {
background-image: url('/resources/images/icon_webcam_white_unsupported.svg');
}
}
&.screen { &.screen {
&.on { &.on {
background-image: url('/resources/images/share-screen-black.svg'); background-image: url('/resources/images/share-screen-black.svg');
@ -177,7 +149,6 @@
&.off { &.off {
background-image: url('/resources/images/no-share-screen-white.svg'); background-image: url('/resources/images/no-share-screen-white.svg');
background-color: rgba(#d42241, 0.7);
} }
&.unsupported { &.unsupported {
@ -187,12 +158,10 @@
&.fullscreen { &.fullscreen {
background-image: url('/resources/images/icon_fullscreen_black.svg'); background-image: url('/resources/images/icon_fullscreen_black.svg');
background-color: rgba(#fff, 0.7);
} }
&.newwindow { &.newwindow {
background-image: url('/resources/images/icon_new_window_black.svg'); background-image: url('/resources/images/icon_new_window_black.svg');
background-color: rgba(#fff, 0.7);
} }
} }
} }

View File

@ -6,15 +6,13 @@
display: flex; display: flex;
flex-direction: column; flex-direction: column;
overflow: hidden; overflow: hidden;
background-color: rgba(#2a4b58, 0.9); background-color: var(--peer-bg-color);
background-image: url('/resources/images/buddy.svg'); background-image: var(--peer-empty-avatar);
background-position: bottom; background-position: bottom;
background-size: auto 85%; background-size: auto 85%;
background-repeat: no-repeat; background-repeat: no-repeat;
> .info { > .info {
$backgroundTint = #000;
position: absolute; position: absolute;
z-index: 10; z-index: 10;
top: 0.6vmin; top: 0.6vmin;
@ -178,7 +176,7 @@
user-select: none; user-select: none;
transition-property: opacity; transition-property: opacity;
transition-duration: .15s; transition-duration: .15s;
background-color: rgba(#000, 0.75); background-color: var(--peer-video-bg-color);
&.is-me { &.is-me {
transform: scaleX(-1); transform: scaleX(-1);
@ -225,37 +223,4 @@
&.level10 { height: 100%; background-color: rgba(#000, 0.65); } &.level10 { height: 100%; background-color: rgba(#000, 0.65); }
} }
} }
> .spinner-container {
position: absolute;
top: 0
bottom: 0;
left: 0;
right: 0;
background-color: rgba(#000, 0.75);
.react-spinner {
position: relative;
width: 48px;
height: 48px;
top: 50%;
left: 50%;
.react-spinner_bar {
position: absolute;
width: 20%;
height: 7.8%;
top: -3.9%;
left: -10%;
animation: PeerView-spinner 1.2s linear infinite;
border-radius: 5px;
background-color: rgba(#fff, 0.5);
}
}
}
}
@keyframes PeerView-spinner {
0% { opacity: 1; }
100% { opacity: 0.15; }
} }

View File

@ -31,18 +31,18 @@
+desktop() { +desktop() {
flex: 0 0 auto; flex: 0 0 auto;
margin: 6px; margin: 6px;
border: 1px solid rgba(#fff, 0.15); border: var(--peer-border);
box-shadow: 0px 5px 12px 2px rgba(#111, 0.5); box-shadow: var(--peer-shadow);
transition-property: border-color; transition-property: border-color;
transition-duration: 0.15s; transition-duration: 0.15s;
&.active-speaker { &.active-speaker {
border-color: #fff; border-color: var(--active-speaker-border-color);
} }
&.selected { &.selected {
> .peer-content { > .peer-content {
border: 1px solid #377eff; border-color: var(--selected-peer-border-color);
} }
} }
} }

View File

@ -143,24 +143,15 @@
position: fixed; position: fixed;
z-index: 110; z-index: 110;
overflow: hidden; overflow: hidden;
box-shadow: 0px 5px 12px 2px rgba(#111, 0.5); box-shadow: var(--me-shadow);
transition-property: border-color; transition-property: border-color;
transition-duration: 0.15s; transition-duration: 0.15s;
&.active-speaker {
border-color: #fff;
}
+desktop() {
top: 6%; top: 6%;
left:1%; left:1%;
border: 1px solid rgba(#fff, 0.15); border: var(--me-border);
}
+mobile() { &.active-speaker {
top: 6%; border-color: var(--active-speaker-border-color);
left: 1%;
border: 1px solid rgba(#fff, 0.25);
} }
} }
} }

View File

@ -6,15 +6,13 @@
display: flex; display: flex;
flex-direction: column; flex-direction: column;
overflow: hidden; overflow: hidden;
background-color: rgba(#2a4b58, 0.9); background-color: var(--peer-bg-color);
background-image: url('/resources/images/buddy.svg'); background-image: var(--peer-empty-avatar);
background-position: bottom; background-position: bottom;
background-size: auto 85%; background-size: auto 85%;
background-repeat: no-repeat; background-repeat: no-repeat;
> .info { > .info {
$backgroundTint = #000;
position: absolute; position: absolute;
z-index: 10; z-index: 10;
top: 0.6vmin; top: 0.6vmin;
@ -58,7 +56,7 @@
user-select: none; user-select: none;
transition-property: opacity; transition-property: opacity;
transition-duration: .15s; transition-duration: .15s;
background-color: rgba(#000, 0.75); background-color: var(--peer-video-bg-color);
&.is-me { &.is-me {
transform: scaleX(-1); transform: scaleX(-1);
@ -73,37 +71,4 @@
filter: blur(5px); filter: blur(5px);
} }
} }
> .spinner-container {
position: absolute;
top: 0
bottom: 0;
left: 0;
right: 0;
background-color: rgba(#000, 0.75);
.react-spinner {
position: relative;
width: 48px;
height: 48px;
top: 50%;
left: 50%;
.react-spinner_bar {
position: absolute;
width: 20%;
height: 7.8%;
top: -3.9%;
left: -10%;
animation: PeerView-spinner 1.2s linear infinite;
border-radius: 5px;
background-color: rgba(#fff, 0.5);
}
}
}
}
@keyframes ScreenView-spinner {
0% { opacity: 1; }
100% { opacity: 0.15; }
} }

View File

@ -1,3 +0,0 @@
[data-component='Settings'] {
}

View File

@ -1,8 +1,8 @@
[data-component='Sidebar'] { [data-component='Sidebar'] {
position: fixed; position: fixed;
z-index: 500; z-index: 500;
top: calc(50% - 60px); top: 50%;
height: 120px; transform: translate(0%, -50%);
display: flex; display: flex;
flex-direction: column; flex-direction: column;
justify-content: center; justify-content: center;
@ -24,7 +24,7 @@
background-position: center; background-position: center;
background-size: 75%; background-size: 75%;
background-repeat: no-repeat; background-repeat: no-repeat;
background-color: rgba(#fff, 0.3); background-color: var(--circle-button-color);
cursor: pointer; cursor: pointer;
transition-property: opacity, background-color; transition-property: opacity, background-color;
transition-duration: 0.15s; transition-duration: 0.15s;
@ -32,24 +32,20 @@
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
height: var(--circle-button-size);
+desktop() { width: var(--circle-button-size);
height: 2.5em;
width: 2.5em;
}
+mobile() {
height: 2.5em;
width: 2.5em;
}
&.on { &.on {
background-color: rgba(#fff, 0.7); background-color: var(--circle-button-toggled-color);
}
&.unsupported {
background-color: var(--circle-button-unsupported-color);
} }
&.disabled { &.disabled {
pointer-events: none; pointer-events: none;
opacity: 0.5; background-color: var(--circle-button-diabled-color);
} }
&.login { &.login {
@ -93,7 +89,6 @@
&.unsupported { &.unsupported {
background-image: url('/resources/images/no-share-screen-white.svg'); background-image: url('/resources/images/no-share-screen-white.svg');
background-color: rgba(#d42241, 0.7);
} }
&.need-extension { &.need-extension {

View File

@ -27,35 +27,6 @@
.toolarea-shade.open { .toolarea-shade.open {
display: block; display: block;
} }
> .button {
background-position: center;
background-size: 100%;
background-repeat: no-repeat;
background-color: rgba(#aef);
cursor: pointer;
border-radius: 15%;
padding: 1px;
+desktop() {
height: 36px;
width: 18px;
}
+mobile() {
height: 32px;
width: 16px;
}
&.toolarea-close-button {
background-image: url('/resources/images/arrow_right.svg');
position: absolute;
top: 50%;
left: -22px;
display: none;
&.on {
display: block;
}
}
}
> .toolarea-button { > .toolarea-button {
text-align: center; text-align: center;

View File

@ -7,6 +7,53 @@ global-reset();
@import './reset'; @import './reset';
@import './keyframes'; @import './keyframes';
:root {
--logo: url('/resources/images/logo.svg');
--logo-width: 8%;
--logo-height: 4%;
--background: url('/resources/images/background.svg');
--background-color: rgba(51, 51, 51, 1.0);
--circle-button-color: rgba(255, 255, 255, 0.3);
--circle-button-toggled-color: rgba(255, 255, 255, 0.7);
--circle-button-unsupported-color: rgba(212, 34, 65, 0.7);
--circle-button-diabled-color: rgba(255, 255, 255, 0.5);
--circle-button-size: 2.5em;
--media-control-button-color: rgba(255, 255, 255, 0.85);
--media-control-botton-on: rgba(255, 255, 255, 0.7);
--media-control-botton-off: rgba(212, 34, 65, 0.7);
--media-control-botton-disabled: rgba(255, 255, 255, 0.5)
--media-control-button-size: 1.5em;
--me-shadow: 0px 5px 12px 2px rgba(17, 17, 17, 0.5);
--me-border: 1px solid rgba(255, 255, 255, 0.15);
--me-width: 20vmin;
--me-height: 15vmin;
--peer-shadow: 0px 5px 12px 2px rgba(17, 17, 17, 0.5);
--peer-border: 1px solid rgba(255, 255, 255, 0.15);
--peer-empty-avatar: url('/resources/images/buddy.svg');
--peer-bg-color: rgba(42, 75, 88, 0.9);
--peer-video-bg-color: rgba(0, 0, 0, 0.75);
--chat-message-color: rgba(0, 0, 0, 0.1);
--chat-input-bg-color: rgba(255, 255, 255, 1.0);
--chat-input-text-color: rgba(0, 0, 0, 1.0);
--chat-send-bg-color: rgba(170, 238, 255, 1.0);
--filesharing-bg-color: rgba(170, 238, 255, 1.0);
--notification-info-bg-color: rgba(10, 29, 38, 0.75);
--notification-info-text-color: rgba(255, 255, 255, 0.65);
--notification-error-bg-color: rgba(255, 25, 20, 0.65);
--notification-error-text-color: rgba(255, 255, 255, 0.85);
--active-speaker-border-color: rgba(255, 255, 255, 1.0);
--selected-peer-border-color: rgba(55, 126, 255, 1.0);
}
html { html {
height: 100%; height: 100%;
font-family: 'Roboto'; font-family: 'Roboto';
@ -23,11 +70,11 @@ body {
height: 100%; height: 100%;
overflow-x: hidden; overflow-x: hidden;
overflow-y: hidden; overflow-y: hidden;
background-color: #333; background-color: var(--background-color);
+desktop() { +desktop() {
font-size: 16px; font-size: 16px;
background-image: url('/resources/images/background.svg'); background-image: var(--background);
background-attachment: fixed; background-attachment: fixed;
background-position: center; background-position: center;
background-size: cover; background-size: cover;
@ -48,11 +95,10 @@ body {
@import './components/Peers'; @import './components/Peers';
@import './components/Peer'; @import './components/Peer';
@import './components/PeerView'; @import './components/PeerView';
@import './components/HiddenPeersView'; @import './components/HiddenPeers';
@import './components/ScreenView'; @import './components/ScreenView';
@import './components/Notifications'; @import './components/Notifications';
@import './components/Chat'; @import './components/Chat';
@import './components/Settings';
@import './components/ToolArea'; @import './components/ToolArea';
@import './components/ParticipantList'; @import './components/ParticipantList';
@import './components/FullScreenView'; @import './components/FullScreenView';