Skip to content

Commit eaf83f8

Browse files
author
Ives van Hoorne
committed
Reconnecting
1 parent 7a6e590 commit eaf83f8

File tree

15 files changed

+266
-68
lines changed

15 files changed

+266
-68
lines changed

packages/app/src/app/components/CodeEditor/Monaco/index.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1381,7 +1381,7 @@ class MonacoEditor extends React.Component<Props, State> implements Editor {
13811381
requestAnimationFrame(() => {
13821382
if (modelInfo.cursorPos) {
13831383
this.editor.setPosition(modelInfo.cursorPos);
1384-
this.editor.revealPositionInCenter(modelInfo.cursorPos);
1384+
this.editor.revealPosition(modelInfo.cursorPos);
13851385
}
13861386

13871387
this.syntaxHighlight(

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,9 @@ export default class CodeEditor extends React.PureComponent<Props, State> {
125125
}
126126

127127
const Editor =
128-
settings.vimMode || settings.codeMirror ? CodeMirror : Monaco;
128+
(settings.vimMode || settings.codeMirror) && !props.isLive
129+
? CodeMirror
130+
: Monaco;
129131

130132
return (
131133
<div

packages/app/src/app/pages/Sandbox/Editor/Content/index.js

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -385,10 +385,7 @@ class EditorPreview extends React.Component<Props, State> {
385385
height={editorHeight}
386386
settings={settings(store)}
387387
sendTransforms={this.sendTransforms}
388-
readOnly={
389-
false
390-
// (store.live.isLive && !store.live.isCurrentEditor)
391-
}
388+
readOnly={!store.live.isCurrentEditor}
392389
isLive={store.live.isLive}
393390
onCodeReceived={signals.live.onCodeReceived}
394391
onSelectionChanged={signals.live.onSelectionChanged}

packages/app/src/app/pages/Sandbox/Editor/Navigation/index.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import React from 'react';
22
import { inject, observer } from 'mobx-react';
33

44
import GitHubIcon from 'react-icons/lib/go/mark-github';
5-
import LiveIcon from 'react-icons/lib/md/cast-connected';
5+
import LiveIcon from 'react-icons/lib/md/wifi-tethering';
66

77
import getWorkspaceItems from 'app/store/modules/workspace/items';
88
import Tooltip from 'common/components/Tooltip';
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import React from 'react';
2+
3+
const pad = t => {
4+
if (`${t}`.length === 1) {
5+
return `0${t}`;
6+
}
7+
8+
return `${t}`;
9+
};
10+
11+
export default class Countdown extends React.PureComponent {
12+
componentDidMount() {
13+
this.timer = setTimeout(this.tick, 1000);
14+
}
15+
16+
tick = () => {
17+
this.forceUpdate();
18+
19+
this.timer = setTimeout(this.tick, 1000);
20+
};
21+
22+
componentWillUnmount() {
23+
clearTimeout(this.timer);
24+
}
25+
26+
getTimes = () => {
27+
const delta = Date.now() - this.props.time;
28+
29+
const hours = Math.floor(delta / 1000 / 60 / 60);
30+
const minutes = Math.floor((delta - hours * 1000 * 60 * 60) / 1000 / 60);
31+
const seconds = Math.floor((delta - minutes * 1000 * 60) / 1000);
32+
33+
return { hours: pad(hours), minutes: pad(minutes), seconds: pad(seconds) };
34+
};
35+
36+
render() {
37+
const { hours, minutes, seconds } = this.getTimes();
38+
39+
return (
40+
<div>
41+
{hours > 0 && `${hours}:`}
42+
{minutes}:{seconds}
43+
</div>
44+
);
45+
}
46+
}

packages/app/src/app/pages/Sandbox/Editor/Workspace/items/Live/LiveButton.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,10 @@ export default class LiveButton extends React.PureComponent {
6565
}
6666
}
6767

68+
componentWillUnmount() {
69+
clearInterval(this.timer);
70+
}
71+
6872
startHovering = () => {
6973
this.setState({ hovering: true });
7074
};

packages/app/src/app/pages/Sandbox/Editor/Workspace/items/Live/LiveInfo.js

Lines changed: 93 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,17 @@
11
import React from 'react';
22
import styled from 'styled-components';
33
import { observer } from 'mobx-react';
4+
import { sortBy } from 'lodash';
45

56
import RecordIcon from 'react-icons/lib/md/fiber-manual-record';
67
import Input from 'common/components/Input';
78
import Margin from 'common/components/spacing/Margin';
89
import delay from 'common/utils/animation/delay-effect';
910

1011
import User from './User';
12+
import Countdown from './Countdown';
1113

12-
import {
13-
Description,
14-
WorkspaceInputContainer,
15-
WorkspaceSubtitle,
16-
} from '../../elements';
14+
import { Description } from '../../elements';
1715

1816
const Container = styled.div`
1917
${delay()};
@@ -26,25 +24,16 @@ const Title = styled.div`
2624
font-weight: 800;
2725
display: flex;
2826
align-items: center;
29-
justify-content: center;
3027
vertical-align: middle;
3128
32-
padding-bottom: 1rem;
29+
padding: 0.5rem 1rem;
30+
padding-top: 0;
3331
3432
svg {
3533
margin-right: 0.25rem;
3634
}
3735
`;
3836

39-
const Separator = styled.hr`
40-
height: 1px;
41-
width: 100%;
42-
43-
background-color: rgba(255, 255, 255, 0.1);
44-
border: none;
45-
outline: none;
46-
`;
47-
4837
const StyledInput = styled(Input)`
4938
width: calc(100% - 1.5rem);
5039
margin: 0 0.75rem;
@@ -62,6 +51,7 @@ const SubTitle = styled.div`
6251

6352
const Users = styled.div`
6453
padding: 0.25rem 1rem;
54+
padding-top: 0;
6555
color: rgba(255, 255, 255, 0.8);
6656
`;
6757

@@ -83,16 +73,19 @@ const Mode = styled.button`
8373
border: none;
8474
outline: none;
8575
background-color: transparent;
86-
cursor: pointer;
76+
cursor: ${props => (props.onClick ? 'pointer' : 'inherit')};
8777
color: white;
8878
opacity: ${props => (props.selected ? 1 : 0.6)};
8979
margin: 0.25rem 0;
9080
9181
z-index: 3;
9282
83+
${props =>
84+
props.onClick &&
85+
`
9386
&:hover {
9487
opacity: 1;
95-
}
88+
}`};
9689
`;
9790

9891
const ModeDetails = styled.div`
@@ -123,15 +116,42 @@ class LiveInfo extends React.Component {
123116
};
124117

125118
render() {
126-
const { roomInfo, isOwner, ownerId, setMode } = this.props;
119+
const {
120+
roomInfo,
121+
isOwner,
122+
ownerId,
123+
setMode,
124+
addEditor,
125+
removeEditor,
126+
currentUserId,
127+
} = this.props;
127128

128129
const owner = roomInfo.users.find(u => u.id === ownerId);
129-
const otherUsers = roomInfo.users.filter(x => x.id !== ownerId);
130+
131+
const editors = sortBy(
132+
roomInfo.users.filter(
133+
u => roomInfo.editorIds.indexOf(u.id) > -1 && u.id !== ownerId
134+
),
135+
'username'
136+
);
137+
const otherUsers = sortBy(
138+
roomInfo.users.filter(
139+
u => u.id !== ownerId && roomInfo.editorIds.indexOf(u.id) === -1
140+
),
141+
'username'
142+
);
130143

131144
return (
132145
<Container>
133146
<Title>
134-
<RecordIcon /> {isOwner ? "You've gone live!" : 'You are live!'}
147+
<div style={{ flex: 1, display: 'flex', alignItems: 'center' }}>
148+
<RecordIcon /> {isOwner ? "You've gone live!" : 'You are live!'}
149+
</div>
150+
<div>
151+
{roomInfo.startTime != null && (
152+
<Countdown time={roomInfo.startTime} />
153+
)}
154+
</div>
135155
</Title>
136156
<Description>
137157
Share this link with others to invite them to the session:
@@ -141,51 +161,78 @@ class LiveInfo extends React.Component {
141161
value={`https://codesandbox.io/live/${roomInfo.roomId}`}
142162
/>
143163

144-
{isOwner && (
145-
<Margin top={1}>
146-
<SubTitle>Live Mode</SubTitle>
147-
<ModeSelect>
148-
<ModeSelector i={roomInfo.mode === 'open' ? 0 : 1} />
149-
<Mode
150-
onClick={() => setMode({ mode: 'open' })}
151-
selected={roomInfo.mode === 'open'}
152-
>
153-
<div>Open</div>
154-
<ModeDetails>Everyone can edit</ModeDetails>
155-
</Mode>
156-
<Mode
157-
onClick={() => setMode({ mode: 'classroom' })}
158-
selected={roomInfo.mode === 'classroom'}
159-
>
160-
<div>Classroom</div>
161-
<ModeDetails>Fine grained control over editors</ModeDetails>
162-
</Mode>
163-
</ModeSelect>
164-
</Margin>
165-
)}
164+
<Margin top={1}>
165+
<SubTitle>Live Mode</SubTitle>
166+
<ModeSelect>
167+
<ModeSelector i={roomInfo.mode === 'open' ? 0 : 1} />
168+
<Mode
169+
onClick={isOwner ? () => setMode({ mode: 'open' }) : undefined}
170+
selected={roomInfo.mode === 'open'}
171+
>
172+
<div>Open</div>
173+
<ModeDetails>Everyone can edit</ModeDetails>
174+
</Mode>
175+
<Mode
176+
onClick={
177+
isOwner ? () => setMode({ mode: 'classroom' }) : undefined
178+
}
179+
selected={roomInfo.mode === 'classroom'}
180+
>
181+
<div>Classroom</div>
182+
<ModeDetails>Take control over who can edit</ModeDetails>
183+
</Mode>
184+
</ModeSelect>
185+
</Margin>
166186

167187
{owner && (
168188
<Margin top={1}>
169189
<SubTitle>Owner</SubTitle>
170190
<Users>
171-
<User user={owner} roomInfo={roomInfo} type="Sandbox Owner" />
191+
<User
192+
currentUserId={currentUserId}
193+
user={owner}
194+
roomInfo={roomInfo}
195+
type="Owner"
196+
/>
172197
</Users>
173198
</Margin>
174199
)}
175200

201+
{editors.length > 0 &&
202+
roomInfo.mode === 'classroom' && (
203+
<Margin top={1}>
204+
<SubTitle>Editors</SubTitle>
205+
<Users>
206+
{editors.map(user => (
207+
<User
208+
currentUserId={currentUserId}
209+
key={user.id}
210+
showSwitch={isOwner && roomInfo.mode === 'classroom'}
211+
user={user}
212+
roomInfo={roomInfo}
213+
onClick={() => removeEditor({ userId: user.id })}
214+
type="Editor"
215+
/>
216+
))}
217+
</Users>
218+
</Margin>
219+
)}
220+
176221
<Margin top={1}>
177222
<SubTitle>Users</SubTitle>
178223

179224
<Users>
180225
{otherUsers.length ? (
181226
otherUsers.map(user => (
182227
<User
228+
currentUserId={currentUserId}
183229
key={user.id}
184-
showSwitch={roomInfo.mode === 'classroom'}
185-
switchOn={false}
230+
showSwitch={isOwner && roomInfo.mode === 'classroom'}
186231
user={user}
187232
roomInfo={roomInfo}
233+
onClick={() => addEditor({ userId: user.id })}
188234
type="Spectator"
235+
showPlusIcon
189236
/>
190237
))
191238
) : (

0 commit comments

Comments
 (0)