diff --git a/packages/app/src/app/overmind/namespaces/live/actions.ts b/packages/app/src/app/overmind/namespaces/live/actions.ts index 5c0cb26b695..f281d99e8d7 100755 --- a/packages/app/src/app/overmind/namespaces/live/actions.ts +++ b/packages/app/src/app/overmind/namespaces/live/actions.ts @@ -18,17 +18,15 @@ import * as liveMessage from './liveMessageOperators'; export const internal = internalActions; -export const signInToRoom: AsyncAction<{ - roomId: string; -}> = withLoadApp(async ({ state, actions }, { roomId }) => { - state.signInModalOpen = true; - - if (state.isLoggedIn) { - await actions.live.roomJoined({ - roomId, - }); +export const signInToRoom: AsyncAction = withLoadApp( + async ({ actions, state }, roomId) => { + state.signInModalOpen = true; + + if (state.isLoggedIn) { + await actions.live.roomJoined(roomId); + } } -}); +); export const onOperationError: Action<{ moduleShortid: string; @@ -40,57 +38,57 @@ export const onOperationError: Action<{ }); }; -export const roomJoined: AsyncAction<{ - roomId: string; -}> = withLoadApp(async ({ state, effects, actions }, { roomId }) => { - if (!state.isLoggedIn) { - return; - } +export const roomJoined: AsyncAction = withLoadApp( + async ({ actions, effects, state }, roomId) => { + if (!state.isLoggedIn) { + return; + } - await effects.vscode.initialized; - await effects.vscode.closeAllTabs(); + await effects.vscode.initialized; + await effects.vscode.closeAllTabs(); - state.live.joinSource = 'live'; + state.live.joinSource = 'live'; - if (state.live.isLive) { - actions.live.internal.disconnect(); - } + if (state.live.isLive) { + actions.live.internal.disconnect(); + } - const sandbox = await actions.live.internal.initialize(roomId); + const sandbox = await actions.live.internal.initialize(roomId); - if (!sandbox) { - return; - } + if (!sandbox) { + return; + } - if (state.updateStatus === 'available') { - const modal = 'liveVersionMismatch'; - effects.analytics.track('Open Modal', { modal }); - state.currentModal = modal; - } + if (state.updateStatus === 'available') { + const modal = 'liveVersionMismatch'; + effects.analytics.track('Open Modal', { modal }); + state.currentModal = modal; + } - await actions.internal.setCurrentSandbox(sandbox); + await actions.internal.setCurrentSandbox(sandbox); - actions.editor.listenToSandboxChanges({ sandboxId: sandbox.id }); - const items = getItems(state); - const defaultItem = items.find(i => i.defaultOpen) || items[0]; + actions.editor.listenToSandboxChanges({ sandboxId: sandbox.id }); + const items = getItems(state); + const defaultItem = items.find(i => i.defaultOpen) || items[0]; - state.workspace.openedWorkspaceItem = defaultItem.id; + state.workspace.openedWorkspaceItem = defaultItem.id; - await effects.vscode.changeSandbox(sandbox, fs => { - state.editor.modulesByPath = fs; - }); + await effects.vscode.changeSandbox(sandbox, fs => { + state.editor.modulesByPath = fs; + }); - effects.vscode.openModule(state.editor.currentModule); + effects.vscode.openModule(state.editor.currentModule); - if ( - sandbox.featureFlags.comments && - hasPermission(sandbox.authorization, 'comment') - ) { - actions.comments.getSandboxComments(sandbox.id); - } + if ( + sandbox.featureFlags.comments && + hasPermission(sandbox.authorization, 'comment') + ) { + actions.comments.getSandboxComments(sandbox.id); + } - state.editor.isLoading = false; -}); + state.editor.isLoading = false; + } +); export const createLiveClicked: AsyncAction = async ( { actions, effects, state }, diff --git a/packages/app/src/app/pages/Live/BlinkingDot.tsx b/packages/app/src/app/pages/Live/BlinkingDot.tsx deleted file mode 100644 index f48d9efe096..00000000000 --- a/packages/app/src/app/pages/Live/BlinkingDot.tsx +++ /dev/null @@ -1,38 +0,0 @@ -import React from 'react'; -import RecordIcon from 'react-icons/lib/md/fiber-manual-record'; -import styled from 'styled-components'; - -const DotContainer = styled.div` - font-size: 4rem; - display: block; - color: rgb(253, 36, 57); - - svg { - transition: 0.3s ease opacity; - } -`; - -export class BlinkingDot extends React.PureComponent<{}, { showing: boolean }> { - timer: number; - state = { - showing: true, - }; - - componentDidMount() { - this.timer = window.setInterval(() => { - this.setState(state => ({ showing: !state.showing })); - }, 1000); - } - - componentWillUnmount() { - clearInterval(this.timer); - } - - render() { - return ( - - - - ); - } -} diff --git a/packages/app/src/app/pages/Live/Error/RoomNotFoundError.tsx b/packages/app/src/app/pages/Live/Error/RoomNotFoundError.tsx new file mode 100644 index 00000000000..4f4ea896946 --- /dev/null +++ b/packages/app/src/app/pages/Live/Error/RoomNotFoundError.tsx @@ -0,0 +1,20 @@ +import { Button, Text } from '@codesandbox/components'; +import css from '@styled-system/css'; +import React, { FunctionComponent } from 'react'; +import { Link } from 'react-router-dom'; + +export const RoomNotFoundError: FunctionComponent = () => ( + <> + + Something went wrong + + + + {`It seems like this session doesn't exist or has been closed`} + + + + + + +); diff --git a/packages/app/src/app/pages/Live/Error/index.tsx b/packages/app/src/app/pages/Live/Error/index.tsx new file mode 100644 index 00000000000..ec620dfd677 --- /dev/null +++ b/packages/app/src/app/pages/Live/Error/index.tsx @@ -0,0 +1,36 @@ +import { Button, Text } from '@codesandbox/components'; +import css from '@styled-system/css'; +import React, { FunctionComponent } from 'react'; +import { Link } from 'react-router-dom'; + +import { useOvermind } from 'app/overmind'; + +import { RoomNotFoundError } from './RoomNotFoundError'; + +export const Error: FunctionComponent = () => { + const { + state: { + live: { error }, + }, + } = useOvermind(); + + if (error === 'room not found') { + return ; + } + + return ( + <> + + An error occurred while connecting to the live session: + + + + {error} + + + + + + + ); +}; diff --git a/packages/app/src/app/pages/Live/NotAuthenticated.tsx b/packages/app/src/app/pages/Live/NotAuthenticated.tsx new file mode 100644 index 00000000000..349ce4f3b11 --- /dev/null +++ b/packages/app/src/app/pages/Live/NotAuthenticated.tsx @@ -0,0 +1,34 @@ +import { Button, Element, Stack, Text } from '@codesandbox/components'; +import React, { FunctionComponent } from 'react'; +import { useParams } from 'react-router-dom'; + +import { useOvermind } from 'app/overmind'; + +export const NotAuthenticated: FunctionComponent = () => { + const { + actions: { + live: { signInToRoom }, + }, + } = useOvermind(); + const { roomId } = useParams(); + + return ( + <> + + Sign in required + + + + You need to sign in to join this session + + + + + + + ); +}; diff --git a/packages/app/src/app/pages/Live/index.tsx b/packages/app/src/app/pages/Live/index.tsx index ec4a176e4fd..6f91553d96a 100644 --- a/packages/app/src/app/pages/Live/index.tsx +++ b/packages/app/src/app/pages/Live/index.tsx @@ -1,110 +1,55 @@ -import css from '@styled-system/css'; -import { - ThemeProvider, - Button, - Text, - Element, - Stack, -} from '@codesandbox/components'; -import codesandboxBlack from '@codesandbox/components/lib/themes/codesandbox-black'; +import CodeSandboxBlack from '@codesandbox/components/lib/themes/codesandbox-black'; import { getSandboxName } from '@codesandbox/common/lib/utils/get-sandbox-name'; +import { Element, Stack, ThemeProvider } from '@codesandbox/components'; +import css from '@styled-system/css'; +import React, { FunctionComponent, useEffect } from 'react'; +import { Helmet } from 'react-helmet'; +import { useParams } from 'react-router-dom'; + import { useOvermind } from 'app/overmind'; import { Navigation } from 'app/pages/common/Navigation'; -import React, { useEffect } from 'react'; -import { Helmet } from 'react-helmet'; -import { Link } from 'react-router-dom'; import Editor from '../Sandbox/Editor'; -interface Props { - match: { - params: { - id: string; - }; - }; -} +import { Error } from './Error'; +import { NotAuthenticated } from './NotAuthenticated'; -export const LivePage: React.FC = ({ match }) => { - const { state, actions } = useOvermind(); +export const Live: FunctionComponent = () => { + const { + actions: { + live: { onNavigateAway, roomJoined }, + }, + state: { + editor: { currentSandbox }, + isAuthenticating, + live: { error }, + user, + }, + } = useOvermind(); + const { roomId } = useParams(); useEffect(() => { - actions.live.roomJoined({ roomId: match.params.id }); - }, [actions.live, match.params.id]); + roomJoined(roomId); + }, [roomJoined, roomId]); - useEffect( - () => () => { - actions.live.onNavigateAway(); - }, - [actions.live] - ); + useEffect(() => () => onNavigateAway(), [onNavigateAway]); - function getContent() { - if (!state.isAuthenticating && !state.user) { - return ( - <> - - Sign in required - - - You need to sign in to join this session - - - - - - ); + const getContent = () => { + if (!isAuthenticating && !user) { + return ; } - if (state.live.error) { - if (state.live.error === 'room not found') { - return ( - <> - - Something went wrong - - - It seems like this session doesn - {"'"}t exist or has been closed - - - - - - ); - } - - return ( - <> - - An error occurred while connecting to the live session: - - - {state.live.error} - - - - - - ); + if (error) { + return ; } return null; - } + }; const content = getContent(); - if (content) { return ( - + = ({ match }) => { css={css({ width: '100%', height: '100vh', overflow: 'hidden' })} > + {content} @@ -133,15 +79,14 @@ export const LivePage: React.FC = ({ match }) => { ); } - const sandbox = state.editor.currentSandbox; - return ( <> - {sandbox && ( + {currentSandbox ? ( - {getSandboxName(sandbox)} - CodeSandbox + {getSandboxName(currentSandbox)} - CodeSandbox - )} + ) : null} + ); diff --git a/packages/app/src/app/pages/index.tsx b/packages/app/src/app/pages/index.tsx index 9f109b55ab6..acf38f83b05 100644 --- a/packages/app/src/app/pages/index.tsx +++ b/packages/app/src/app/pages/index.tsx @@ -42,7 +42,7 @@ const SignIn = Loadable(() => ); const Live = Loadable(() => import(/* webpackChunkName: 'page-sign-in' */ './Live').then(module => ({ - default: module.LivePage, + default: module.Live, })) ); const VercelSignIn = Loadable(() => @@ -164,7 +164,7 @@ const RoutesComponent: React.FC = () => { - +