Add randdom room name generation

This commit is contained in:
Saúl Ibarra Corretgé 2020-05-19 11:43:55 +02:00
parent a1a52c4b42
commit d2f49288f1
6 changed files with 155 additions and 26 deletions

View file

@ -6,6 +6,7 @@ import { SpotlightTarget } from '@atlaskit/onboarding';
import Page from '@atlaskit/page'; import Page from '@atlaskit/page';
import { AtlasKitThemeProvider } from '@atlaskit/theme'; import { AtlasKitThemeProvider } from '@atlaskit/theme';
import { generateRoomWithoutSeparator } from 'js-utils/random';
import React, { Component } from 'react'; import React, { Component } from 'react';
import type { Dispatch } from 'redux'; import type { Dispatch } from 'redux';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
@ -16,7 +17,7 @@ import { Onboarding, startOnboarding } from '../../onboarding';
import { RecentList } from '../../recent-list'; import { RecentList } from '../../recent-list';
import { normalizeServerURL } from '../../utils'; import { normalizeServerURL } from '../../utils';
import { Body, Form, Header, Wrapper } from '../styled'; import { Body, FieldWrapper, Form, Header, Label, Wrapper } from '../styled';
type Props = { type Props = {
@ -34,6 +35,26 @@ type Props = {
type State = { type State = {
/**
* Timer for animating the room name geneeration.
*/
animateTimeoutId: ?TimeoutID,
/**
* Generated room name.
*/
generatedRoomname: string,
/**
* Current room name placeholder.
*/
roomPlaceholder: string,
/**
* Timer for re-generating a new room name.
*/
updateTimeoutId: ?TimeoutID,
/** /**
* URL of the room to join. * URL of the room to join.
* If this is not a url it will be treated as room name for default domain. * If this is not a url it will be treated as room name for default domain.
@ -65,16 +86,25 @@ class Welcome extends Component<Props, State> {
} }
} }
this.state = { url }; this.state = {
animateTimeoutId: undefined,
generatedRoomname: '',
roomPlaceholder: '',
updateTimeoutId: undefined,
url
};
// Bind event handlers. // Bind event handlers.
this._animateRoomnameChanging = this._animateRoomnameChanging.bind(this);
this._onURLChange = this._onURLChange.bind(this); this._onURLChange = this._onURLChange.bind(this);
this._onFormSubmit = this._onFormSubmit.bind(this); this._onFormSubmit = this._onFormSubmit.bind(this);
this._onJoin = this._onJoin.bind(this); this._onJoin = this._onJoin.bind(this);
this._updateRoomname = this._updateRoomname.bind(this);
} }
/** /**
* Start Onboarding once component is mounted. * Start Onboarding once component is mounted.
* Start generating randdom room names.
* *
* NOTE: It autonatically checks if the onboarding is shown or not. * NOTE: It autonatically checks if the onboarding is shown or not.
* *
@ -82,6 +112,17 @@ class Welcome extends Component<Props, State> {
*/ */
componentDidMount() { componentDidMount() {
this.props.dispatch(startOnboarding('welcome-page')); this.props.dispatch(startOnboarding('welcome-page'));
this._updateRoomname();
}
/**
* Stop all timers when unmounting.
*
* @returns {voidd}
*/
componentWillUnmount() {
this._clearTimeouts();
} }
/** /**
@ -103,6 +144,46 @@ class Welcome extends Component<Props, State> {
); );
} }
_animateRoomnameChanging: (string) => void;
/**
* Animates the changing of the room name.
*
* @param {string} word - The part of room name that should be added to
* placeholder.
* @private
* @returns {void}
*/
_animateRoomnameChanging(word: string) {
let animateTimeoutId;
const roomPlaceholder = this.state.roomPlaceholder + word.substr(0, 1);
if (word.length > 1) {
animateTimeoutId
= setTimeout(
() => {
this._animateRoomnameChanging(
word.substring(1, word.length));
},
70);
}
this.setState({
animateTimeoutId,
roomPlaceholder
});
}
/**
* Method that clears timeouts for animations and updates of room name.
*
* @private
* @returns {void}
*/
_clearTimeouts() {
clearTimeout(this.state.animateTimeoutId);
clearTimeout(this.state.updateTimeoutId);
}
_onFormSubmit: (*) => void; _onFormSubmit: (*) => void;
/** /**
@ -124,7 +205,7 @@ class Welcome extends Component<Props, State> {
* @returns {void} * @returns {void}
*/ */
_onJoin() { _onJoin() {
const inputURL = this.state.url; const inputURL = this.state.url || this.state.generatedRoomname;
const lastIndexOfSlash = inputURL.lastIndexOf('/'); const lastIndexOfSlash = inputURL.lastIndexOf('/');
let room; let room;
let serverURL; let serverURL;
@ -195,26 +276,53 @@ class Welcome extends Component<Props, State> {
<Header> <Header>
<SpotlightTarget name = 'conference-url'> <SpotlightTarget name = 'conference-url'>
<Form onSubmit = { this._onFormSubmit }> <Form onSubmit = { this._onFormSubmit }>
<FieldTextStateless <Label>{ 'Enter a name for your conference or a Jitsi URL' } </Label>
autoFocus = { true } <FieldWrapper>
isInvalid = { locationError } <FieldTextStateless
isLabelHidden = { true } autoFocus = { true }
onChange = { this._onURLChange } isInvalid = { locationError }
placeholder = 'Enter a name for your conference or a Jitsi URL' isLabelHidden = { true }
shouldFitContainer = { true } onChange = { this._onURLChange }
type = 'text' placeholder = { this.state.roomPlaceholder }
value = { this.state.url } /> shouldFitContainer = { true }
type = 'text'
value = { this.state.url } />
<Button
appearance = 'primary'
onClick = { this._onJoin }
type = 'button'>
GO
</Button>
</FieldWrapper>
</Form> </Form>
</SpotlightTarget> </SpotlightTarget>
<Button
appearance = 'primary'
onClick = { this._onJoin }
type = 'button'>
GO
</Button>
</Header> </Header>
); );
} }
_updateRoomname: () => void;
/**
* Triggers the generation of a new room name and initiates an animation of
* its changing.
*
* @protected
* @returns {void}
*/
_updateRoomname() {
const generatedRoomname = generateRoomWithoutSeparator();
const roomPlaceholder = '';
const updateTimeoutId = setTimeout(this._updateRoomname, 10000);
this._clearTimeouts();
this.setState(
{
generatedRoomname,
roomPlaceholder,
updateTimeoutId
},
() => this._animateRoomnameChanging(generatedRoomname));
}
} }
export default connect()(Welcome); export default connect()(Welcome);

View file

@ -0,0 +1,10 @@
// @flow
import styled from 'styled-components';
export default styled.div`
align-items: center;
display: flex;
justify-content: space-between;
magin: auto;
`;

View file

@ -0,0 +1,8 @@
// @flow
import styled from 'styled-components';
export default styled.span`
color: white;
font-weight: bold;
`;

View file

@ -1,4 +1,6 @@
export { default as Body } from './Body'; export { default as Body } from './Body';
export { default as FieldWrapper } from './FieldWrapper';
export { default as Form } from './Form'; export { default as Form } from './Form';
export { default as Header } from './Header'; export { default as Header } from './Header';
export { default as Label } from './Label';
export { default as Wrapper } from './Wrapper'; export { default as Wrapper } from './Wrapper';

15
package-lock.json generated
View file

@ -4289,9 +4289,9 @@
"optional": true "optional": true
}, },
"bowser": { "bowser": {
"version": "1.9.1", "version": "2.7.0",
"resolved": "https://registry.npmjs.org/bowser/-/bowser-1.9.1.tgz", "resolved": "https://registry.npmjs.org/bowser/-/bowser-2.7.0.tgz",
"integrity": "sha512-UXti1JB6oK8hO983AImunnV6j/fqAEeDlPXh99zhsP5g32oLbxJJ6qcOaUesR+tqqhnUVQHlRJyD0dfiV0Hxaw==" "integrity": "sha512-aIlMvstvu8x+34KEiOHD3AsBgdrzg6sxALYiukOWhFvGMbQI6TRP/iY0LMhUrHs56aD6P1G0Z7h45PUJaa5m9w=="
}, },
"boxen": { "boxen": {
"version": "4.2.0", "version": "4.2.0",
@ -8415,11 +8415,12 @@
"integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="
}, },
"js-utils": { "js-utils": {
"version": "github:jitsi/js-utils#0c53500a5120be2aa3fc590f0f932a0d4771920f", "version": "github:jitsi/js-utils#cf11996bd866fdb47326c59a5d3bc24be17282d4",
"from": "github:jitsi/js-utils#0c53500a5120be2aa3fc590f0f932a0d4771920f", "from": "github:jitsi/js-utils#cf11996bd866fdb47326c59a5d3bc24be17282d4",
"requires": { "requires": {
"bowser": "1.9.1", "bowser": "2.7.0",
"js-md5": "0.7.3" "js-md5": "0.7.3",
"postis": "2.2.0"
} }
}, },
"js-yaml": { "js-yaml": {

View file

@ -103,7 +103,7 @@
"electron-window-state": "5.0.3", "electron-window-state": "5.0.3",
"history": "4.10.1", "history": "4.10.1",
"jitsi-meet-electron-utils": "github:jitsi/jitsi-meet-electron-utils#v2.0.6", "jitsi-meet-electron-utils": "github:jitsi/jitsi-meet-electron-utils#v2.0.6",
"js-utils": "github:jitsi/js-utils#0c53500a5120be2aa3fc590f0f932a0d4771920f", "js-utils": "github:jitsi/js-utils#cf11996bd866fdb47326c59a5d3bc24be17282d4",
"moment": "2.23.0", "moment": "2.23.0",
"mousetrap": "1.6.2", "mousetrap": "1.6.2",
"react": "16.6.3", "react": "16.6.3",