Skip to content

Commit 53ad359

Browse files
author
Ives van Hoorne
committed
Sign in procedure
1 parent 32b856f commit 53ad359

File tree

8 files changed

+165
-27
lines changed

8 files changed

+165
-27
lines changed

packages/app/src/app/components/SubTitle/index.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@ import styled from 'styled-components';
22
import delayEffect from 'common/utils/animation/delay-effect';
33

44
export default styled.h2`
5-
${props =>
6-
props.delay != null && delayEffect(props.delay || 0)} text-align: center;
5+
${props => props.delay != null && delayEffect(props.delay || 0)};
6+
text-align: center;
77
width: 100%;
88
font-size: 1.75rem;
9-
color: ${props => props.theme.background2.lighten(2)};
9+
color: rgba(255, 255, 255, 0.7);
1010
font-weight: 300;
1111
margin-top: 0;
1212
margin-bottom: 1.5rem;
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import React from 'react';
2+
import styled from 'styled-components';
3+
import RecordIcon from 'react-icons/lib/md/fiber-manual-record';
4+
5+
const DotContainer = styled.div`
6+
font-size: 4rem;
7+
display: block;
8+
color: rgb(253, 36, 57);
9+
10+
svg {
11+
transition: 0.3s ease opacity;
12+
}
13+
`;
14+
15+
export default class BlinkingDot extends React.PureComponent {
16+
state = {
17+
showing: true,
18+
};
19+
20+
componentDidMount() {
21+
this.timer = setInterval(() => {
22+
this.setState({ showing: !this.state.showing });
23+
}, 1000);
24+
}
25+
26+
componentWillUnmount() {
27+
clearInterval(this.timer);
28+
}
29+
30+
render() {
31+
return (
32+
<DotContainer>
33+
<RecordIcon style={{ opacity: this.state.showing ? 1 : 0 }} />
34+
</DotContainer>
35+
);
36+
}
37+
}

packages/app/src/app/pages/Live/index.js

Lines changed: 114 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -3,63 +3,156 @@ import { inject, observer } from 'mobx-react';
33
import { Link } from 'react-router-dom';
44
import { DragDropContext } from 'react-dnd';
55
import HTML5Backend from 'react-dnd-html5-backend';
6-
import QuickActions from 'app/pages/Sandbox/QuickActions';
76

7+
import Navigation from 'app/pages/common/Navigation';
8+
import Fullscreen from 'common/components/flex/Fullscreen';
9+
10+
import QuickActions from 'app/pages/Sandbox/QuickActions';
811
import Title from 'app/components/Title';
912
import SubTitle from 'app/components/SubTitle';
1013
import Centered from 'common/components/flex/Centered';
1114
import Skeleton from 'app/components/Skeleton';
15+
import Padding from 'common/components/spacing/Padding';
16+
import SignInButton from 'app/pages/common/SignInButton';
1217

1318
import Editor from '../Sandbox/Editor';
19+
import BlinkingDot from './BlinkingDot';
1420

1521
class LivePage extends React.Component {
22+
loggedIn = this.props.store.hasLogIn;
23+
1624
componentWillMount() {
1725
this.initializeLive();
1826
}
1927

2028
initializeLive = () => {
21-
this.props.signals.live.roomJoined({
22-
roomId: this.props.match.params.id,
23-
});
29+
if (this.props.store.hasLogIn) {
30+
this.loggedIn = true;
31+
this.props.signals.live.roomJoined({
32+
roomId: this.props.match.params.id,
33+
});
34+
}
2435
};
2536

2637
componentDidUpdate(prevProps) {
27-
if (prevProps.match.params.id !== this.props.match.params.id) {
38+
if (
39+
prevProps.match.params.id !== this.props.match.params.id ||
40+
(this.props.store.hasLogIn && !this.loggedIn)
41+
) {
2842
this.initializeLive();
2943
}
3044
}
3145

32-
render() {
33-
const { match, store } = this.props;
46+
getContent = () => {
47+
const { store } = this.props;
48+
49+
if (!store.hasLogIn) {
50+
return (
51+
<React.Fragment>
52+
<div
53+
style={{
54+
fontWeight: 300,
55+
color: 'rgba(255, 255, 255, 0.5)',
56+
marginBottom: '1rem',
57+
fontSize: '1.5rem',
58+
}}
59+
>
60+
Sign in required
61+
</div>
62+
<Title style={{ fontSize: '1.25rem' }}>
63+
You need to sign in to join this session
64+
</Title>
65+
<br />
66+
<div>
67+
<SignInButton />
68+
</div>
69+
</React.Fragment>
70+
);
71+
}
72+
73+
if (store.live.error) {
74+
if (store.live.error === 'room not found') {
75+
return (
76+
<React.Fragment>
77+
<div
78+
style={{
79+
fontWeight: 300,
80+
color: 'rgba(255, 255, 255, 0.5)',
81+
marginBottom: '1rem',
82+
fontSize: '1.5rem',
83+
}}
84+
>
85+
Something went wrong
86+
</div>
87+
<Title style={{ fontSize: '1.25rem' }}>
88+
It seems like this session doesn{"'"}t exist or has been closed
89+
</Title>
90+
<br />
91+
<Link to="/s">Create Sandbox</Link>
92+
</React.Fragment>
93+
);
94+
}
3495

35-
if (store.live.isLoading) {
3696
return (
37-
<Centered horizontal vertical>
97+
<React.Fragment>
98+
<Title>An error occured while connecting to the live session:</Title>
99+
<SubTitle>{store.live.error}</SubTitle>
100+
<br />
101+
<br />
102+
<Link to="/s">Create Sandbox</Link>
103+
</React.Fragment>
104+
);
105+
}
106+
107+
if (store.live.isLoading || !store.editor.currentSandbox) {
108+
return (
109+
<React.Fragment>
38110
<Skeleton
39111
titles={[
40112
{
41-
content: 'Loading sandbox...',
113+
content: <BlinkingDot />,
42114
delay: 0,
43115
},
44116
{
45-
content: 'Fetching git repository...',
46-
delay: 2,
117+
content: 'Joining Live Session...',
118+
delay: 0.5,
47119
},
48120
]}
49121
/>
50-
</Centered>
122+
</React.Fragment>
51123
);
52124
}
53125

54-
if (store.live.error) {
126+
return null;
127+
};
128+
129+
render() {
130+
const { match, store } = this.props;
131+
132+
const content = this.getContent();
133+
134+
if (content) {
55135
return (
56-
<Centered style={{ height: '100vh' }} horizontal vertical>
57-
<Title>An error occured when connecting to the live session:</Title>
58-
<SubTitle>{store.editor.error}</SubTitle>
59-
<br />
60-
<br />
61-
<Link to="/s">Create Sandbox</Link>
62-
</Centered>
136+
<Fullscreen>
137+
<Padding
138+
style={{
139+
display: 'flex',
140+
flexDirection: 'column',
141+
width: '100vw',
142+
height: '100vh',
143+
}}
144+
margin={1}
145+
>
146+
<Navigation title="Live Session" />
147+
<Centered
148+
style={{ flex: 1, width: '100%', height: '100%' }}
149+
horizontal
150+
vertical
151+
>
152+
{content}
153+
</Centered>
154+
</Padding>
155+
</Fullscreen>
63156
);
64157
}
65158

packages/app/src/app/pages/index.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ class Routes extends React.Component<Props> {
104104
<Route exact path="/s/cli" component={CliInstructions} />
105105
<Route exact path="/s" component={NewSandbox} />
106106
<Route path="/s/:id*" component={Sandbox} />
107-
<Route path="/l/:id" component={Live} />
107+
<Route path="/live/:id" component={Live} />
108108
<Route path="/signin/:jwt?" component={SignIn} />
109109
<Route path="/u/:username" component={Profile} />
110110
<Route path="/search" component={Search} />

packages/app/src/app/store/getters.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import store from 'store/dist/store.modern';
2+
13
export function isPatron() {
24
return Boolean(
35
this.user && this.user.subscription && this.user.subscription.since
@@ -7,3 +9,7 @@ export function isPatron() {
79
export function isLoggedIn() {
810
return Boolean(this.jwt) && Boolean(this.user);
911
}
12+
13+
export function hasLogIn() {
14+
return !!store.get('jwt');
15+
}

packages/app/src/app/store/index.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import KeybindingManagerProvider from './providers/KeybindingManager';
1717

1818
import * as sequences from './sequences';
1919
import * as errors from './errors';
20-
import { isPatron, isLoggedIn } from './getters';
20+
import { isPatron, isLoggedIn, hasLogIn } from './getters';
2121

2222
import patron from './modules/patron';
2323
import editor from './modules/editor';
@@ -55,6 +55,7 @@ export default Module({
5555
getters: {
5656
isPatron,
5757
isLoggedIn,
58+
hasLogIn,
5859
},
5960
signals: {
6061
appUnmounted: sequences.unloadApp,

packages/app/src/app/store/modules/live/actions.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -401,7 +401,7 @@ export function computePendingOperation({ props, state }) {
401401
export function getUserJoinedNotification({ props }) {
402402
const user = props.data.users.find(u => u.id === props.data.joined_user_id);
403403

404-
return { message: `${user.username} joined the live session!` };
404+
return { message: `${user.username} joined the live session.` };
405405
}
406406

407407
export function getUserLeftNotification({ props, state }) {

packages/app/src/app/store/sequences.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,7 @@ export const signOut = [
164164
set(state`user.jwt`, null),
165165
set(state`user.badges`, []),
166166
set(state`user.integrations`, {}),
167+
unset(state`user`),
167168
];
168169

169170
export const getZeitUserDetails = [

0 commit comments

Comments
 (0)