From 79376b3a506b614c5d3eeba4b75e0690de4416a7 Mon Sep 17 00:00:00 2001 From: Torjus Date: Mon, 16 Jul 2018 12:39:09 +0200 Subject: [PATCH] Hide toolbars after 10 seconds --- app/.eslintrc.js | 5 +- app/lib/components/Room.jsx | 90 ++++++-- .../components/ToolArea/ToolAreaButton.jsx | 9 +- app/lib/redux/reducers/room.js | 9 +- app/lib/redux/stateActions.js | 5 + app/package-lock.json | 195 ++++++++++++++++++ app/package.json | 2 + app/stylus/components/Room.styl | 36 ++++ 8 files changed, 326 insertions(+), 25 deletions(-) diff --git a/app/.eslintrc.js b/app/.eslintrc.js index 70a5569..6d49fa4 100644 --- a/app/.eslintrc.js +++ b/app/.eslintrc.js @@ -24,14 +24,14 @@ module.exports = version: '15' } }, + parser: 'babel-eslint', parserOptions: { - ecmaVersion: 6, + ecmaVersion: 9, sourceType: 'module', ecmaFeatures: { impliedStrict: true, - experimentalObjectRestSpread: true, jsx: true } }, @@ -121,7 +121,6 @@ module.exports = 'no-implicit-globals': 2, 'no-inner-declarations': 2, 'no-invalid-regexp': 2, - 'no-invalid-this': 2, 'no-irregular-whitespace': 2, 'no-lonely-if': 2, 'no-mixed-operators': 2, diff --git a/app/lib/components/Room.jsx b/app/lib/components/Room.jsx index 6128149..089cf5d 100644 --- a/app/lib/components/Room.jsx +++ b/app/lib/components/Room.jsx @@ -6,6 +6,7 @@ import classnames from 'classnames'; import ClipboardButton from 'react-clipboard.js'; import * as appPropTypes from './appPropTypes'; import * as requestActions from '../redux/requestActions'; +import * as stateActions from '../redux/stateActions'; import { Appear } from './transitions'; import Me from './Me'; import Peers from './Peers'; @@ -15,20 +16,61 @@ import ToolArea from './ToolArea/ToolArea'; import FullScreenView from './FullScreenView'; import Draggable from 'react-draggable'; +// Hide toolbars after 10 seconds of inactivity. +const TIMEOUT = 10 * 1000; + +/** + * Create a function which will call the callback function + * after the given amount of milliseconds has passed since + * the last time the callback function was called. + */ +const idle = (callback, delay) => +{ + let handle; + + return () => + { + if (handle) + { + clearTimeout(handle); + } + + handle = setTimeout(callback, delay); + }; +}; + class Room extends React.Component { - handleMouseMove = () => { - + /** + * Hides the different toolbars on the page after a + * given amount of time has passed since the + * last time the cursor was moved. + */ + waitForHide = idle(() => + { + this.props.setToolbarsVisible(false); + }, TIMEOUT); + + handleMouseMove = () => + { + // If the toolbars were hidden, show them again when + // the user moves their cursor. + if (!this.props.room.toolbarsVisible) + { + this.props.setToolbarsVisible(true); + } + + this.waitForHide(); } componentDidMount() { - + window.addEventListener('mousemove', this.handleMouseMove); } componentWillUnmount() { - + window.removeEventListener('mousemove', this.handleMouseMove); } render() @@ -91,8 +133,12 @@ class Room extends React.Component :null } - -
+ +
-
+
@@ -275,6 +325,10 @@ const mapDispatchToProps = (dispatch) => onLogin : () => { dispatch(requestActions.userLogin()); + }, + setToolbarsVisible : (visible) => + { + dispatch(stateActions.setToolbarsVisible(visible)); } }; }; diff --git a/app/lib/components/ToolArea/ToolAreaButton.jsx b/app/lib/components/ToolArea/ToolAreaButton.jsx index 3133f9c..14e7d92 100644 --- a/app/lib/components/ToolArea/ToolAreaButton.jsx +++ b/app/lib/components/ToolArea/ToolAreaButton.jsx @@ -17,8 +17,9 @@ class ToolAreaButton extends React.Component return (
{ return { toolAreaOpen : state.toolarea.toolAreaOpen, + visible : state.room.toolbarsVisible, unread : state.toolarea.unread }; }; diff --git a/app/lib/redux/reducers/room.js b/app/lib/redux/reducers/room.js index c2552bd..e92196b 100644 --- a/app/lib/redux/reducers/room.js +++ b/app/lib/redux/reducers/room.js @@ -5,7 +5,8 @@ const initialState = activeSpeakerName : null, showSettings : false, advancedMode : false, - fullScreenConsumer : null // ConsumerID + fullScreenConsumer : null, // ConsumerID + toolbarsVisible : true }; const room = (state = initialState, action) => @@ -58,6 +59,12 @@ const room = (state = initialState, action) => return { ...state, fullScreenConsumer: currentConsumer ? null : consumerId }; } + case 'SET_TOOLBARS_VISIBLE': + { + const { toolbarsVisible } = action.payload; + + return { ...state, toolbarsVisible }; + } default: return state; } diff --git a/app/lib/redux/stateActions.js b/app/lib/redux/stateActions.js index 8748bf3..f9a88d4 100644 --- a/app/lib/redux/stateActions.js +++ b/app/lib/redux/stateActions.js @@ -369,6 +369,11 @@ export const toggleConsumerFullscreen = (consumerId) => }; }; +export const setToolbarsVisible = (toolbarsVisible) => ({ + type : 'SET_TOOLBARS_VISIBLE', + payload : { toolbarsVisible } +}); + export const increaseBadge = () => { return { diff --git a/app/package-lock.json b/app/package-lock.json index 12a46b1..d6b27e2 100644 --- a/app/package-lock.json +++ b/app/package-lock.json @@ -4,6 +4,169 @@ "lockfileVersion": 1, "requires": true, "dependencies": { + "@babel/code-frame": { + "version": "7.0.0-beta.44", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.0.0-beta.44.tgz", + "integrity": "sha512-cuAuTTIQ9RqcFRJ/Y8PvTh+paepNcaGxwQwjIDRWPXmzzyAeCO4KqS9ikMvq0MCbRk6GlYKwfzStrcP3/jSL8g==", + "dev": true, + "requires": { + "@babel/highlight": "7.0.0-beta.44" + } + }, + "@babel/generator": { + "version": "7.0.0-beta.44", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.0.0-beta.44.tgz", + "integrity": "sha512-5xVb7hlhjGcdkKpMXgicAVgx8syK5VJz193k0i/0sLP6DzE6lRrU1K3B/rFefgdo9LPGMAOOOAWW4jycj07ShQ==", + "dev": true, + "requires": { + "@babel/types": "7.0.0-beta.44", + "jsesc": "^2.5.1", + "lodash": "^4.2.0", + "source-map": "^0.5.0", + "trim-right": "^1.0.1" + }, + "dependencies": { + "jsesc": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.1.tgz", + "integrity": "sha1-5CGiqOINawgZ3yiQj3glJrlt0f4=", + "dev": true + } + } + }, + "@babel/helper-function-name": { + "version": "7.0.0-beta.44", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.0.0-beta.44.tgz", + "integrity": "sha512-MHRG2qZMKMFaBavX0LWpfZ2e+hLloT++N7rfM3DYOMUOGCD8cVjqZpwiL8a0bOX3IYcQev1ruciT0gdFFRTxzg==", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "7.0.0-beta.44", + "@babel/template": "7.0.0-beta.44", + "@babel/types": "7.0.0-beta.44" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.0.0-beta.44", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0-beta.44.tgz", + "integrity": "sha512-w0YjWVwrM2HwP6/H3sEgrSQdkCaxppqFeJtAnB23pRiJB5E/O9Yp7JAAeWBl+gGEgmBFinnTyOv2RN7rcSmMiw==", + "dev": true, + "requires": { + "@babel/types": "7.0.0-beta.44" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.0.0-beta.44", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.0.0-beta.44.tgz", + "integrity": "sha512-aQ7QowtkgKKzPGf0j6u77kBMdUFVBKNHw2p/3HX/POt5/oz8ec5cs0GwlgM8Hz7ui5EwJnzyfRmkNF1Nx1N7aA==", + "dev": true, + "requires": { + "@babel/types": "7.0.0-beta.44" + } + }, + "@babel/highlight": { + "version": "7.0.0-beta.44", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.0.0-beta.44.tgz", + "integrity": "sha512-Il19yJvy7vMFm8AVAh6OZzaFoAd0hbkeMZiX3P5HGD+z7dyI7RzndHB0dg6Urh/VAFfHtpOIzDUSxmY6coyZWQ==", + "dev": true, + "requires": { + "chalk": "^2.0.0", + "esutils": "^2.0.2", + "js-tokens": "^3.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", + "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + } + } + }, + "@babel/template": { + "version": "7.0.0-beta.44", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.0.0-beta.44.tgz", + "integrity": "sha512-w750Sloq0UNifLx1rUqwfbnC6uSUk0mfwwgGRfdLiaUzfAOiH0tHJE6ILQIUi3KYkjiCDTskoIsnfqZvWLBDng==", + "dev": true, + "requires": { + "@babel/code-frame": "7.0.0-beta.44", + "@babel/types": "7.0.0-beta.44", + "babylon": "7.0.0-beta.44", + "lodash": "^4.2.0" + }, + "dependencies": { + "babylon": { + "version": "7.0.0-beta.44", + "resolved": "https://registry.npmjs.org/babylon/-/babylon-7.0.0-beta.44.tgz", + "integrity": "sha512-5Hlm13BJVAioCHpImtFqNOF2H3ieTOHd0fmFGMxOJ9jgeFqeAwsv3u5P5cR7CSeFrkgHsT19DgFJkHV0/Mcd8g==", + "dev": true + } + } + }, + "@babel/traverse": { + "version": "7.0.0-beta.44", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.0.0-beta.44.tgz", + "integrity": "sha512-UHuDz8ukQkJCDASKHf+oDt3FVUzFd+QYfuBIsiNu/4+/ix6pP/C+uQZJ6K1oEfbCMv/IKWbgDEh7fcsnIE5AtA==", + "dev": true, + "requires": { + "@babel/code-frame": "7.0.0-beta.44", + "@babel/generator": "7.0.0-beta.44", + "@babel/helper-function-name": "7.0.0-beta.44", + "@babel/helper-split-export-declaration": "7.0.0-beta.44", + "@babel/types": "7.0.0-beta.44", + "babylon": "7.0.0-beta.44", + "debug": "^3.1.0", + "globals": "^11.1.0", + "invariant": "^2.2.0", + "lodash": "^4.2.0" + }, + "dependencies": { + "babylon": { + "version": "7.0.0-beta.44", + "resolved": "https://registry.npmjs.org/babylon/-/babylon-7.0.0-beta.44.tgz", + "integrity": "sha512-5Hlm13BJVAioCHpImtFqNOF2H3ieTOHd0fmFGMxOJ9jgeFqeAwsv3u5P5cR7CSeFrkgHsT19DgFJkHV0/Mcd8g==", + "dev": true + }, + "globals": { + "version": "11.7.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.7.0.tgz", + "integrity": "sha512-K8BNSPySfeShBQXsahYB/AbbWruVOTyVpgoIDnl8odPpeSfP2J5QO2oLFFdl2j7GfDCtZj2bMKar2T49itTPCg==", + "dev": true + } + } + }, + "@babel/types": { + "version": "7.0.0-beta.44", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.0.0-beta.44.tgz", + "integrity": "sha512-5eTV4WRmqbaFM3v9gHAIljEQJU4Ssc6fxL61JN+Oe2ga/BwyjzjamwkCVVAQjHGuAX8i0BWo42dshL8eO5KfLQ==", + "dev": true, + "requires": { + "esutils": "^2.0.2", + "lodash": "^4.2.0", + "to-fast-properties": "^2.0.0" + }, + "dependencies": { + "to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", + "dev": true + } + } + }, "JSONStream": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.3.tgz", @@ -636,6 +799,38 @@ } } }, + "babel-eslint": { + "version": "8.2.6", + "resolved": "https://registry.npmjs.org/babel-eslint/-/babel-eslint-8.2.6.tgz", + "integrity": "sha512-aCdHjhzcILdP8c9lej7hvXKvQieyRt20SF102SIGyY4cUIiw6UaAtK4j2o3dXX74jEmy0TJ0CEhv4fTIM3SzcA==", + "dev": true, + "requires": { + "@babel/code-frame": "7.0.0-beta.44", + "@babel/traverse": "7.0.0-beta.44", + "@babel/types": "7.0.0-beta.44", + "babylon": "7.0.0-beta.44", + "eslint-scope": "3.7.1", + "eslint-visitor-keys": "^1.0.0" + }, + "dependencies": { + "babylon": { + "version": "7.0.0-beta.44", + "resolved": "https://registry.npmjs.org/babylon/-/babylon-7.0.0-beta.44.tgz", + "integrity": "sha512-5Hlm13BJVAioCHpImtFqNOF2H3ieTOHd0fmFGMxOJ9jgeFqeAwsv3u5P5cR7CSeFrkgHsT19DgFJkHV0/Mcd8g==", + "dev": true + }, + "eslint-scope": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-3.7.1.tgz", + "integrity": "sha1-PWPD7f2gLgbgGkUq2IyqzHzctug=", + "dev": true, + "requires": { + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" + } + } + } + }, "babel-generator": { "version": "6.26.1", "resolved": "https://registry.npmjs.org/babel-generator/-/babel-generator-6.26.1.tgz", diff --git a/app/package.json b/app/package.json index 26e493e..3bcce90 100644 --- a/app/package.json +++ b/app/package.json @@ -35,6 +35,7 @@ }, "devDependencies": { "babel-core": "^6.26.3", + "babel-eslint": "^8.2.6", "babel-preset-env": "^1.7.0", "babel-preset-es2015": "^6.24.1", "babel-preset-react-app": "^3.1.2", @@ -59,6 +60,7 @@ "gulp-touch-cmd": "0.0.1", "gulp-uglify": "^3.0.0", "gulp-util": "^3.0.8", + "lodash": "^4.17.10", "mkdirp": "^0.5.1", "ncp": "^2.0.0", "nib": "^1.1.2", diff --git a/app/stylus/components/Room.styl b/app/stylus/components/Room.styl index f2d9743..9938a6d 100644 --- a/app/stylus/components/Room.styl +++ b/app/stylus/components/Room.styl @@ -276,6 +276,18 @@ } } +.room-controls { + visibility: hidden; + animation: fade-out 0.5s; + opacity: 0; + + &.visible { + visibility: visible; + opacity: 1; + animation: fade-in 0.5s; + } +} + .Dropdown-root { position: relative; padding: 0.3vmin; @@ -428,3 +440,27 @@ @keyframes Room-info-state-connecting { 50% { background-color: rgba(orange, 0.75); } } + +@keyframes fade-in { + from { + opacity: 0; + visibility: hidden; + } + + to { + opacity: 1; + visibility: visible; + } +} + +@keyframes fade-out { + from { + opacity: 1; + visibility: visible; + } + + to { + opacity: 0; + visibility: hidden; + } +} \ No newline at end of file