);
}
}
@@ -100,7 +80,6 @@ Settings.propTypes =
{
me : appPropTypes.Me.isRequired,
room : appPropTypes.Room.isRequired,
- onToggleSettings : PropTypes.func.isRequired,
handleChangeWebcam : PropTypes.func.isRequired,
handleChangeAudioDevice : PropTypes.func.isRequired,
onToggleAdvancedMode : PropTypes.func.isRequired
diff --git a/app/lib/components/ToolArea/ToolArea.jsx b/app/lib/components/ToolArea/ToolArea.jsx
new file mode 100644
index 0000000..3ec7cf7
--- /dev/null
+++ b/app/lib/components/ToolArea/ToolArea.jsx
@@ -0,0 +1,125 @@
+import React from 'react';
+import { connect } from 'react-redux';
+import PropTypes from 'prop-types';
+import * as stateActions from '../../redux/stateActions';
+import ParticipantList from '../ParticipantList/ParticipantList';
+import Chat from '../Chat/Chat';
+import Settings from '../Settings';
+
+class ToolArea extends React.Component
+{
+ constructor(props)
+ {
+ super(props);
+ }
+
+ render()
+ {
+ const {
+ toolarea,
+ setToolTab
+ } = this.props;
+
+ return (
+
+ );
+ }
+}
+
+ToolArea.propTypes =
+{
+ advancedMode : PropTypes.bool,
+ toolarea : PropTypes.object.isRequired,
+ setToolTab : PropTypes.func.isRequired
+};
+
+const mapStateToProps = (state) =>
+{
+ return {
+ toolarea : state.toolarea
+ };
+};
+
+const mapDispatchToProps = (dispatch) =>
+{
+ return {
+ setToolTab : (toolTab) =>
+ {
+ dispatch(stateActions.setToolTab(toolTab));
+ }
+ };
+};
+
+const ToolAreaContainer = connect(
+ mapStateToProps,
+ mapDispatchToProps
+)(ToolArea);
+
+export default ToolAreaContainer;
diff --git a/app/lib/components/ToolArea/ToolAreaButton.jsx b/app/lib/components/ToolArea/ToolAreaButton.jsx
new file mode 100644
index 0000000..b158ba4
--- /dev/null
+++ b/app/lib/components/ToolArea/ToolAreaButton.jsx
@@ -0,0 +1,60 @@
+import React from 'react';
+import { connect } from 'react-redux';
+import PropTypes from 'prop-types';
+import classnames from 'classnames';
+import * as stateActions from '../../redux/stateActions';
+
+class ToolAreaButton extends React.Component
+{
+ render()
+ {
+ const {
+ toolAreaOpen,
+ toggleToolArea
+ } = this.props;
+
+ return (
+
+
toggleToolArea()}
+ />
+
+ );
+ }
+}
+
+ToolAreaButton.propTypes =
+{
+ toolAreaOpen : PropTypes.bool.isRequired,
+ toggleToolArea : PropTypes.func.isRequired
+};
+
+const mapStateToProps = (state) =>
+{
+ return {
+ toolAreaOpen : state.toolarea.toolAreaOpen
+ };
+};
+
+const mapDispatchToProps = (dispatch) =>
+{
+ return {
+ toggleToolArea : () =>
+ {
+ dispatch(stateActions.toggleToolArea());
+ }
+ };
+};
+
+const ToolAreaButtonContainer = connect(
+ mapStateToProps,
+ mapDispatchToProps
+)(ToolAreaButton);
+
+export default ToolAreaButtonContainer;
diff --git a/app/lib/redux/reducers/index.js b/app/lib/redux/reducers/index.js
index 779f775..e5c89a3 100644
--- a/app/lib/redux/reducers/index.js
+++ b/app/lib/redux/reducers/index.js
@@ -7,6 +7,7 @@ import consumers from './consumers';
import notifications from './notifications';
import chatmessages from './chatmessages';
import chatbehavior from './chatbehavior';
+import toolarea from './toolarea';
const reducers = combineReducers(
{
@@ -17,7 +18,8 @@ const reducers = combineReducers(
consumers,
notifications,
chatmessages,
- chatbehavior
+ chatbehavior,
+ toolarea
});
export default reducers;
diff --git a/app/lib/redux/reducers/peers.js b/app/lib/redux/reducers/peers.js
index b7001b9..d7174d5 100644
--- a/app/lib/redux/reducers/peers.js
+++ b/app/lib/redux/reducers/peers.js
@@ -60,6 +60,19 @@ const peers = (state = initialState, action) =>
return { ...state, [newPeer.name]: newPeer };
}
+ case 'SET_PEER_SCREEN_IN_PROGRESS':
+ {
+ const { peerName, flag } = action.payload;
+ const peer = state[peerName];
+
+ if (!peer)
+ throw new Error('no Peer found');
+
+ const newPeer = { ...peer, peerScreenInProgress: flag };
+
+ return { ...state, [newPeer.name]: newPeer };
+ }
+
case 'SET_PEER_RAISE_HAND_STATE':
{
const { peerName, raiseHandState } = action.payload;
diff --git a/app/lib/redux/reducers/toolarea.js b/app/lib/redux/reducers/toolarea.js
new file mode 100644
index 0000000..00ad64a
--- /dev/null
+++ b/app/lib/redux/reducers/toolarea.js
@@ -0,0 +1,30 @@
+const initialState =
+{
+ toolAreaOpen : false,
+ currentToolTab : 'chat' // chat, settings, layout, users
+};
+
+const toolarea = (state = initialState, action) =>
+{
+ switch (action.type)
+ {
+ case 'TOGGLE_TOOL_AREA':
+ {
+ const toolAreaOpen = !state.toolAreaOpen;
+
+ return { ...state, toolAreaOpen };
+ }
+
+ case 'SET_TOOL_TAB':
+ {
+ const { toolTab } = action.payload;
+
+ return { ...state, currentToolTab: toolTab };
+ }
+
+ default:
+ return state;
+ }
+};
+
+export default toolarea;
diff --git a/app/lib/redux/requestActions.js b/app/lib/redux/requestActions.js
index ff865fa..5d9a240 100644
--- a/app/lib/redux/requestActions.js
+++ b/app/lib/redux/requestActions.js
@@ -119,6 +119,22 @@ export const resumePeerVideo = (peerName) =>
};
};
+export const pausePeerScreen = (peerName) =>
+{
+ return {
+ type : 'PAUSE_PEER_SCREEN',
+ payload : { peerName }
+ };
+};
+
+export const resumePeerScreen = (peerName) =>
+{
+ return {
+ type : 'RESUME_PEER_SCREEN',
+ payload : { peerName }
+ };
+};
+
export const userLogin = () =>
{
return {
diff --git a/app/lib/redux/roomClientMiddleware.js b/app/lib/redux/roomClientMiddleware.js
index 64a1059..61aa34b 100644
--- a/app/lib/redux/roomClientMiddleware.js
+++ b/app/lib/redux/roomClientMiddleware.js
@@ -149,6 +149,24 @@ export default ({ dispatch, getState }) => (next) =>
break;
}
+ case 'PAUSE_PEER_SCREEN':
+ {
+ const { peerName } = action.payload;
+
+ client.pausePeerScreen(peerName);
+
+ break;
+ }
+
+ case 'RESUME_PEER_SCREEN':
+ {
+ const { peerName } = action.payload;
+
+ client.resumePeerScreen(peerName);
+
+ break;
+ }
+
case 'RAISE_HAND':
{
client.sendRaiseHandState(true);
diff --git a/app/lib/redux/stateActions.js b/app/lib/redux/stateActions.js
index dfc3e28..4db655b 100644
--- a/app/lib/redux/stateActions.js
+++ b/app/lib/redux/stateActions.js
@@ -125,6 +125,14 @@ export const setPeerAudioInProgress = (peerName, flag) =>
};
};
+export const setPeerScreenInProgress = (peerName, flag) =>
+{
+ return {
+ type : 'SET_PEER_SCREEN_IN_PROGRESS',
+ payload : { peerName, flag }
+ };
+};
+
export const setMyRaiseHandState = (flag) =>
{
return {
@@ -148,6 +156,21 @@ export const toggleSettings = () =>
};
};
+export const toggleToolArea = () =>
+{
+ return {
+ type : 'TOGGLE_TOOL_AREA'
+ };
+};
+
+export const setToolTab = (toolTab) =>
+{
+ return {
+ type : 'SET_TOOL_TAB',
+ payload : { toolTab }
+ };
+};
+
export const setMyRaiseHandStateInProgress = (flag) =>
{
return {
diff --git a/app/resources/images/icon_tool_area_black.svg b/app/resources/images/icon_tool_area_black.svg
new file mode 100644
index 0000000..1acc639
--- /dev/null
+++ b/app/resources/images/icon_tool_area_black.svg
@@ -0,0 +1,4 @@
+
diff --git a/app/resources/images/icon_tool_area_white.svg b/app/resources/images/icon_tool_area_white.svg
new file mode 100644
index 0000000..c860ab2
--- /dev/null
+++ b/app/resources/images/icon_tool_area_white.svg
@@ -0,0 +1,4 @@
+
diff --git a/app/stylus/components/Chat.styl b/app/stylus/components/Chat.styl
index 4ae0c0b..6399832 100644
--- a/app/stylus/components/Chat.styl
+++ b/app/stylus/components/Chat.styl
@@ -1,10 +1,10 @@
[data-component='ChatWidget'] {
+ position: absolute;
bottom: 0;
display: flex;
flex-direction: column;
margin: 0 10px 10px 0;
max-width: 300px;
- position: fixed;
right: 0;
width: 90vw;
z-index: 9999;
@@ -56,10 +56,13 @@
box-shadow: 0px 2px 10px 1px #000;
}
+[data-component='Chat'] {
+ height: 100%;
+}
+
[data-component='MessageList'] {
background-color: rgba(#fff, 0.9);
- height: 50vh;
- max-height: 350px;
+ height: 91vmin;
overflow-y: scroll;
padding-top: 5px;
border-radius: 5px 5px 0px 0px;
@@ -114,8 +117,8 @@
align-items: center;
display: flex;
background-color: rgba(#fff, 0.9);
- height: 35px;
- padding: 5px;
+ height: 6vmin;
+ padding: 0.5vmin;
border-radius: 0 0 5px 5px;
> .new-message {
diff --git a/app/stylus/components/Notifications.styl b/app/stylus/components/Notifications.styl
index 35d86bf..329fa64 100644
--- a/app/stylus/components/Notifications.styl
+++ b/app/stylus/components/Notifications.styl
@@ -1,9 +1,9 @@
[data-component='Notifications'] {
- position: fixed;
+ position: absolute;
z-index: 9999;
pointer-events: none;
top: 0;
- right: 0;
+ right: 65px;
bottom: 0;
padding: 20px;
display: flex;
diff --git a/app/stylus/components/ParticipantList.styl b/app/stylus/components/ParticipantList.styl
new file mode 100644
index 0000000..1f0bd98
--- /dev/null
+++ b/app/stylus/components/ParticipantList.styl
@@ -0,0 +1,132 @@
+[data-component='ParticipantList'] {
+ width: 100%;
+
+ > .list {
+ box-shadow: 0 4px 10px 0 rgba(0,0,0,0.2), \
+ 0 4px 20px 0 rgba(0,0,0,0.19);
+
+ > .list-item {
+ padding: 0.5vmin;
+ border-bottom: 1px solid #ddd;
+ width: 100%;
+ overflow: hidden;
+ }
+ }
+}
+
+[data-component='ListPeer'] {
+ > .controls {
+ float: right;
+ display: flex;
+ flex-direction: row;
+ justify-content: flex-start;
+ align-items: center;
+
+ > .button {
+ flex: 0 0 auto;
+ margin: 0.2vmin;
+ border-radius: 2px;
+ background-position: center;
+ background-size: 75%;
+ background-repeat: no-repeat;
+ background-color: rgba(#000, 0.5);
+ cursor: pointer;
+ transition-property: opacity, background-color;
+ transition-duration: 0.15s;
+
+ +desktop() {
+ width: 24px;
+ height: 24px;
+ opacity: 0.85;
+
+ &:hover {
+ opacity: 1;
+ }
+ }
+
+ +mobile() {
+ width: 22px;
+ height: 22px;
+ }
+
+ &.unsupported {
+ pointer-events: none;
+ }
+
+ &.disabled {
+ pointer-events: none;
+ opacity: 0.5;
+ }
+
+ &.on {
+ background-color: rgba(#fff, 0.7);
+ }
+
+ &.mic {
+ &.on {
+ background-image: url('/resources/images/icon_mic_black_on.svg');
+ }
+
+ &.off {
+ background-image: url('/resources/images/icon_remote_mic_white_off.svg');
+ background-color: rgba(#d42241, 0.7);
+ }
+
+ &.unsupported {
+ background-image: url('/resources/images/icon_mic_white_unsupported.svg');
+ }
+ }
+
+ &.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 {
+ &.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');
+ }
+ }
+ }
+ }
+
+ > .avatar {
+ padding: 8px 16px;
+ float: left;
+ width: auto;
+ border: none;
+ display: block;
+ outline: 0;
+ border-radius: 50%;
+ vertical-align: middle;
+ }
+
+ > .peer-info {
+ font-size: 1.4vmin;
+ float: left;
+ width: auto;
+ border: none;
+ display: block;
+ outline: 0;
+ padding: 0.6vmin;
+ }
+}
diff --git a/app/stylus/components/Room.styl b/app/stylus/components/Room.styl
index ec3e43c..aa62aa0 100644
--- a/app/stylus/components/Room.styl
+++ b/app/stylus/components/Room.styl
@@ -1,268 +1,283 @@
[data-component='Room'] {
- position: relative;
- height: 100%;
- width: 100%;
-
AppearFadeIn(300ms);
- > .state {
- position: fixed;
- z-index: 100;
- display: flex;
- flex-direction: row;
- justify-content: center;
- align-items: center;
- border-radius: 25px;
- background-color: rgba(#fff, 0.2);
-
- +desktop() {
- top: 20px;
- left: 20px;
- width: 124px;
- }
-
- +mobile() {
- top: 10px;
- left: 10px;
- width: 110px;
- }
-
- > .icon {
- flex: 0 0 auto;
- border-radius: 100%;
-
- +desktop() {
- margin: 5px;
- margin-right: 0;
- height: 20px;
- width: 20px;
- }
-
- +mobile() {
- margin: 4px;
- margin-right: 0;
- height: 16px;
- width: 16px;
- }
-
- &.new, &.closed {
- background-color: rgba(#aaa, 0.5);
- }
-
- &.connecting {
- animation: Room-info-state-connecting .75s infinite linear;
- }
-
- &.connected {
- background-color: rgba(#30bd18, 0.75);
-
- +mobile() {
- display: none;
- }
- }
- }
-
- > .text {
- flex: 100 0 auto;
- user-select: none;
- pointer-events: none;
- text-align: center;
- text-transform: uppercase;
- font-family: 'Roboto';
- font-weight: 400;
- color: rgba(#fff, 0.75);
-
- +desktop() {
- font-size: 12px;
- }
-
- +mobile() {
- font-size: 10px;
- }
-
- &.connected {
- +mobile() {
- display: none;
- }
- }
- }
- }
-
- > .room-link-wrapper {
- pointer-events: none;
+ > .room-wrapper {
position: absolute;
- z-index: 1;
top: 0;
left: 0;
- right: 0;
- display: flex;
- flex-direction: row;
- justify-content: center;
+ height: 100%;
+ width: 100%;
+ transition: width 0.3s;
- > .room-link {
- width: auto;
- background-color: rgba(#fff, 0.75);
- border-bottom-right-radius: 4px;
- border-bottom-left-radius: 4px;
- box-shadow: 0px 3px 12px 2px rgba(#111, 0.4);
+ > .state {
+ position: fixed;
+ z-index: 100;
+ display: flex;
+ flex-direction: row;
+ justify-content: center;
+ align-items: center;
+ border-radius: 25px;
+ background-color: rgba(#fff, 0.2);
- > a.link {
- display: block;;
- user-select: none;
- pointer-events: auto;
- color: #104758;
- font-weight: 400;
- cursor: pointer;
- text-decoration: none;
- transition-property: opacity;
- transition-duration: 0.25s;
- opacity: 0.8;
+ +desktop() {
+ top: 20px;
+ left: 20px;
+ width: 124px;
+ }
+
+ +mobile() {
+ top: 10px;
+ left: 10px;
+ width: 110px;
+ }
+
+ > .icon {
+ flex: 0 0 auto;
+ border-radius: 100%;
+desktop() {
- padding: 10px 20px;
- font-size: 16px;
+ margin: 5px;
+ margin-right: 0;
+ height: 20px;
+ width: 20px;
}
+mobile() {
- padding: 6px 10px;
- font-size: 14px;
+ margin: 4px;
+ margin-right: 0;
+ height: 16px;
+ width: 16px;
}
- &:hover {
- opacity: 1;
- text-decoration: underline;
+ &.new, &.closed {
+ background-color: rgba(#aaa, 0.5);
+ }
+
+ &.connecting {
+ animation: Room-info-state-connecting .75s infinite linear;
+ }
+
+ &.connected {
+ background-color: rgba(#30bd18, 0.75);
+
+ +mobile() {
+ display: none;
+ }
+ }
+ }
+
+ > .text {
+ flex: 100 0 auto;
+ user-select: none;
+ pointer-events: none;
+ text-align: center;
+ text-transform: uppercase;
+ font-family: 'Roboto';
+ font-weight: 400;
+ color: rgba(#fff, 0.75);
+
+ +desktop() {
+ font-size: 12px;
+ }
+
+ +mobile() {
+ font-size: 10px;
+ }
+
+ &.connected {
+ +mobile() {
+ display: none;
+ }
}
}
}
- }
- > .me-container {
- position: fixed;
- z-index: 100;
- overflow: hidden;
- box-shadow: 0px 5px 12px 2px rgba(#111, 0.5);
- transition-property: border-color;
- transition-duration: 0.15s;
+ > .room-link-wrapper {
+ pointer-events: none;
+ position: absolute;
+ z-index: 1;
+ top: 0;
+ left: 0;
+ right: 0;
+ display: flex;
+ flex-direction: row;
+ justify-content: center;
- &.active-speaker {
- border-color: #fff;
+ > .room-link {
+ width: auto;
+ background-color: rgba(#fff, 0.75);
+ border-bottom-right-radius: 4px;
+ border-bottom-left-radius: 4px;
+ box-shadow: 0px 3px 12px 2px rgba(#111, 0.4);
+
+ > a.link {
+ display: block;;
+ user-select: none;
+ pointer-events: auto;
+ color: #104758;
+ font-weight: 400;
+ cursor: pointer;
+ text-decoration: none;
+ transition-property: opacity;
+ transition-duration: 0.25s;
+ opacity: 0.8;
+
+ +desktop() {
+ padding: 10px 20px;
+ font-size: 16px;
+ }
+
+ +mobile() {
+ padding: 6px 10px;
+ font-size: 14px;
+ }
+
+ &:hover {
+ opacity: 1;
+ text-decoration: underline;
+ }
+ }
+ }
}
- +desktop() {
- height: 200px;
- width: 235px;
- bottom: 20px;
- left: 20px;
- border: 1px solid rgba(#fff, 0.15);
- }
-
- +mobile() {
- height: 175px;
- width: 150px;
- bottom: 10px;
- left: 10px;
- border: 1px solid rgba(#fff, 0.25);
- }
- }
-
- > .sidebar {
- position: fixed;
- z-index: 101;
- top: calc(50% - 60px);
- height: 120px;
- display: flex;
- flex-direction: column;
- justify-content: center;
- align-items: center;
-
- +desktop() {
- left: 20px;
- width: 36px;
- }
-
- +mobile() {
- left: 10px;
- width: 32px;
- }
-
- > .button {
- flex: 0 0 auto;
- margin: 4px 0;
- background-position: center;
- background-size: 75%;
- background-repeat: no-repeat;
- background-color: rgba(#fff, 0.3);
- cursor: pointer;
- transition-property: opacity, background-color;
+ > .me-container {
+ position: fixed;
+ z-index: 100;
+ overflow: hidden;
+ box-shadow: 0px 5px 12px 2px rgba(#111, 0.5);
+ transition-property: border-color;
transition-duration: 0.15s;
- border-radius: 100%;
+
+ &.active-speaker {
+ border-color: #fff;
+ }
+desktop() {
- height: 36px;
+ height: 200px;
+ width: 235px;
+ bottom: 20px;
+ left: 20px;
+ border: 1px solid rgba(#fff, 0.15);
+ }
+
+ +mobile() {
+ height: 175px;
+ width: 150px;
+ bottom: 10px;
+ left: 10px;
+ border: 1px solid rgba(#fff, 0.25);
+ }
+ }
+
+ > .sidebar {
+ position: fixed;
+ z-index: 101;
+ top: calc(50% - 60px);
+ height: 120px;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+
+ +desktop() {
+ left: 20px;
width: 36px;
}
+mobile() {
- height: 32px;
+ left: 10px;
width: 32px;
}
- &.on {
- background-color: rgba(#fff, 0.7);
- }
+ > .button {
+ flex: 0 0 auto;
+ margin: 4px 0;
+ background-position: center;
+ background-size: 75%;
+ background-repeat: no-repeat;
+ background-color: rgba(#fff, 0.3);
+ cursor: pointer;
+ transition-property: opacity, background-color;
+ transition-duration: 0.15s;
+ border-radius: 100%;
- &.disabled {
- pointer-events: none;
- opacity: 0.5;
- }
-
- &.login {
- &.off {
- background-image: url('/resources/images/icon_login_white.svg');
+ +desktop() {
+ height: 36px;
+ width: 36px;
}
- }
- &.settings {
- &.off {
- background-image: url('/resources/images/icon_settings_white.svg');
+ +mobile() {
+ height: 32px;
+ width: 32px;
}
&.on {
- background-image: url('/resources/images/icon_settings_black.svg');
- }
- }
-
- &.screen {
- &.on {
- background-image: url('/resources/images/no-share-screen-black.svg');
+ background-color: rgba(#fff, 0.7);
}
- &.off {
- background-image: url('/resources/images/share-screen-white.svg');
+ &.disabled {
+ pointer-events: none;
+ opacity: 0.5;
}
- &.unsupported {
- background-image: url('/resources/images/no-share-screen-white.svg');
- background-color: rgba(#d42241, 0.7);
+ &.login {
+ &.off {
+ background-image: url('/resources/images/icon_login_white.svg');
+ }
}
- &.need-extension {
- background-image: url('/resources/images/share-screen-extension.svg');
- }
- }
- &.raise-hand {
- background-image: url('/resources/images/icon-hand-white.svg');
+ &.settings {
+ &.off {
+ background-image: url('/resources/images/icon_settings_white.svg');
+ }
- &.on {
- background-image: url('/resources/images/icon-hand-black.svg');
+ &.on {
+ background-image: url('/resources/images/icon_settings_black.svg');
+ }
}
- }
- &.leave-meeting {
- background-image: url('/resources/images/leave-meeting.svg');
+ &.screen {
+ &.on {
+ background-image: url('/resources/images/no-share-screen-black.svg');
+ }
+
+ &.off {
+ background-image: url('/resources/images/share-screen-white.svg');
+ }
+
+ &.unsupported {
+ background-image: url('/resources/images/no-share-screen-white.svg');
+ background-color: rgba(#d42241, 0.7);
+ }
+
+ &.need-extension {
+ background-image: url('/resources/images/share-screen-extension.svg');
+ }
+ }
+ &.raise-hand {
+ background-image: url('/resources/images/icon-hand-white.svg');
+
+ &.on {
+ background-image: url('/resources/images/icon-hand-black.svg');
+ }
+ }
+
+ &.leave-meeting {
+ background-image: url('/resources/images/leave-meeting.svg');
+ }
}
}
}
+
+ > .toolarea-wrapper {
+ position: fixed;
+ top: 0;
+ right: 0;
+ width: 20%;
+ height: 100%;
+ background-color: #FFF;
+ transition: width 0.3s;
+ }
}
.Dropdown-root {
@@ -360,6 +375,60 @@
padding: 8px 10px;
}
+.react-tabs__tab-list {
+ border-bottom: 1px solid #aaa;
+ margin: 0 0 10px;
+ padding: 0;
+}
+
+.react-tabs__tab {
+ display: inline-block;
+ border: 1px solid transparent;
+ border-bottom: none;
+ bottom: -1px;
+ position: relative;
+ list-style: none;
+ padding: 6px 12px;
+ cursor: pointer;
+ -webkit-tap-highlight-color: transparent;
+}
+
+.react-tabs__tab--selected {
+ background: #fff;
+ border-color: #aaa;
+ color: black;
+ border-radius: 5px 5px 0 0;
+}
+
+.react-tabs__tab--disabled {
+ color: GrayText;
+ cursor: default;
+}
+
+.react-tabs__tab:focus {
+ box-shadow: 0 0 5px hsl(208, 99%, 50%);
+ border-color: hsl(208, 99%, 50%);
+ outline: none;
+}
+
+.react-tabs__tab:focus:after {
+ content: "";
+ position: absolute;
+ height: 5px;
+ left: -4px;
+ right: -4px;
+ bottom: -5px;
+ background: #fff;
+}
+
+.react-tabs__tab-panel {
+ display: none;
+}
+
+.react-tabs__tab-panel--selected {
+ display: block;
+}
+
@keyframes Room-info-state-connecting {
50% { background-color: rgba(orange, 0.75); }
}
diff --git a/app/stylus/components/Settings.styl b/app/stylus/components/Settings.styl
index a58d04a..b5f818d 100644
--- a/app/stylus/components/Settings.styl
+++ b/app/stylus/components/Settings.styl
@@ -1,53 +1,3 @@
[data-component='Settings'] {
- position: fixed;
- top: 0;
- bottom: 0;
- left: 0;
- right: 0;
- z-index: 19999;
- background-color: rgba(000, 000, 000, 0.5);
- AppearFadeIn(500ms);
-
- > .dialog {
- position: absolute;
- width: 40vmin;
- left: 50%;
- top: 50%;
- transform: translate(-50%, -50%);
- background-color: #fff;
- border-radius: 4px;
- box-shadow: 0px 3px 12px 2px rgba(#111, 0.4);
- padding: 1vmin;
-
- > .header {
- > span {
- font-size: 2vmin;
- font-weight: 400;
- }
- }
-
- > .settings {
- }
-
- > .footer {
- bottom: 0;
- right: 0;
- left: 0;
- display: flex;
- flex-direction: column;
- justify-content: flex-end;
- align-items: flex-end;
-
- > .button {
- flex: 0 0 auto;
- margin: 1vmin;
- background-color: rgba(#000, 0.8);
- color: #fff;
- cursor: pointer;
- border-radius: 4px;
- padding: 0.5vmin;
- }
- }
- }
}
diff --git a/app/stylus/components/ToolArea.styl b/app/stylus/components/ToolArea.styl
new file mode 100644
index 0000000..cd177f2
--- /dev/null
+++ b/app/stylus/components/ToolArea.styl
@@ -0,0 +1,99 @@
+[data-component='ToolAreaButton'] {
+ position: absolute;
+ z-index: 101;
+ top: 20px;
+ right: 20px;
+ height: 36px;
+ width: 36px;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+
+ > .button {
+ flex: 0 0 auto;
+ margin: 4px 0;
+ background-position: center;
+ background-size: 75%;
+ background-repeat: no-repeat;
+ background-color: rgba(#fff, 0.3);
+ cursor: pointer;
+ transition-property: opacity, background-color;
+ transition-duration: 0.15s;
+ border-radius: 100%;
+
+ +desktop() {
+ height: 36px;
+ width: 36px;
+ }
+
+ +mobile() {
+ height: 32px;
+ width: 32px;
+ }
+
+ &.on {
+ background-color: rgba(#fff, 0.7);
+ }
+
+ &.disabled {
+ pointer-events: none;
+ opacity: 0.5;
+ }
+
+ &.toolarea-button {
+ background-image: url('/resources/images/icon_tool_area_white.svg');
+
+ &.on {
+ background-image: url('/resources/images/icon_tool_area_black.svg');
+ }
+ }
+ }
+}
+
+[data-component='ToolArea'] {
+ width: 100%;
+ height: 100%;
+
+ > .tabs {
+ display: flex;
+ flex-wrap: wrap;
+ height: 100%;
+
+ > label {
+ order: 1;
+ display: block;
+ padding: 1vmin 0 1vmin 0;
+ cursor: pointer;
+ background: rgba(#000, 0.3);
+ font-weight: bold;
+ transition: background ease 0.2s;
+ text-align: center;
+ width: 25%;
+ font-size: 1.3vmin;
+ height: 3vmin;
+ }
+
+ > .tab {
+ order: 99;
+ flex-grow: 1;
+ width: 100%;
+ height: 100%;
+ display: none;
+ padding: 1vmin;
+ background: #fff;
+ }
+
+ > input[type="radio"] {
+ display: none;
+ }
+
+ > input[type="radio"]:checked + label {
+ background: #fff;
+ }
+
+ > input[type="radio"]:checked + label + .tab {
+ display: block;
+ }
+ }
+}
diff --git a/app/stylus/index.styl b/app/stylus/index.styl
index 9f9fec5..4d9561c 100644
--- a/app/stylus/index.styl
+++ b/app/stylus/index.styl
@@ -43,6 +43,8 @@ body {
@import './components/Notifications';
@import './components/Chat';
@import './components/Settings';
+ @import './components/ToolArea';
+ @import './components/ParticipantList';
}
// Hack to detect in JS the current media query