From 35fb6158deb00fea09b5cfeb689ed4922f35e0ea Mon Sep 17 00:00:00 2001 From: Christian Alfoni Date: Fri, 13 Dec 2019 19:23:22 +0100 Subject: [PATCH 1/4] refactor LivePageand make changedShortsids a derived --- packages/app/package.json | 4 +- packages/app/src/app/index.js | 2 +- .../app/src/app/overmind/effects/api/index.ts | 12 +- packages/app/src/app/overmind/factories.ts | 21 +++ .../app/src/app/overmind/internalActions.ts | 1 + packages/app/src/app/overmind/modals.ts | 2 + .../app/overmind/namespaces/editor/actions.ts | 51 +++--- .../namespaces/editor/internalActions.ts | 17 -- .../app/overmind/namespaces/editor/state.ts | 16 +- .../app/overmind/namespaces/live/actions.ts | 55 +++--- .../namespaces/live/liveMessageOperators.ts | 5 - .../Live/{BlinkingDot.js => BlinkingDot.tsx} | 5 +- .../app/pages/Live/{index.js => index.tsx} | 161 ++++++++---------- .../pages/Sandbox/Editor/Header/Header.tsx | 23 ++- packages/app/src/app/pages/index.tsx | 4 +- yarn.lock | 38 ++--- 16 files changed, 216 insertions(+), 201 deletions(-) rename packages/app/src/app/pages/Live/{BlinkingDot.js => BlinkingDot.tsx} (86%) rename packages/app/src/app/pages/Live/{index.js => index.tsx} (51%) diff --git a/packages/app/package.json b/packages/app/package.json index bac5c84e82c..5886694173d 100644 --- a/packages/app/package.json +++ b/packages/app/package.json @@ -158,9 +158,9 @@ "normalizr": "^3.2.3", "onigasm": "^2.2.1", "ot": "^0.0.15", - "overmind": "^21.0.0-1575912749783", + "overmind": "^21.0.0-1576231149763", "overmind-devtools": "^19.0.0", - "overmind-react": "^22.0.0-1575912749783", + "overmind-react": "^22.0.0-1576231149763", "phoenix": "^1.4.11", "postcss": "^6.0.9", "postcss-selector-parser": "^2.2.3", diff --git a/packages/app/src/app/index.js b/packages/app/src/app/index.js index d017937b1e3..85c2b1fcf49 100644 --- a/packages/app/src/app/index.js +++ b/packages/app/src/app/index.js @@ -25,10 +25,10 @@ import { createOvermind } from 'overmind'; import { Provider as ActualOvermindProvider } from 'overmind-react'; import React from 'react'; import { ApolloProvider } from 'react-apollo'; +import { DndProvider } from 'react-dnd'; import { render } from 'react-dom'; import { Router } from 'react-router-dom'; import { ThemeProvider } from 'styled-components'; -import { DndProvider } from 'react-dnd'; import { config } from './overmind'; import { Provider as OvermindProvider } from './overmind/Provider'; diff --git a/packages/app/src/app/overmind/effects/api/index.ts b/packages/app/src/app/overmind/effects/api/index.ts index 1ddb2ea8943..e8bf8befccf 100755 --- a/packages/app/src/app/overmind/effects/api/index.ts +++ b/packages/app/src/app/overmind/effects/api/index.ts @@ -19,8 +19,8 @@ import { UploadedFilesInfo, UserSandbox, } from '@codesandbox/common/lib/types'; -import { client } from 'app/graphql/client'; import { LIST_PERSONAL_TEMPLATES } from 'app/components/CreateNewSandbox/queries'; +import { client } from 'app/graphql/client'; import { transformDirectory, @@ -116,10 +116,12 @@ export default { ) .then(transformModule); }, - saveModules(sandboxId: string, modules: Module[]) { - return api.put(`/sandboxes/${sandboxId}/modules/mupdate`, { - modules, - }); + saveModules(sandboxId: string, modules: Module[]): Promise { + return api + .put(`/sandboxes/${sandboxId}/modules/mupdate`, { + modules, + }) + .then(modulesResult => modulesResult.map(transformModule)); }, getGitChanges(sandboxId: string): Promise { return api.get(`/sandboxes/${sandboxId}/git/diff`); diff --git a/packages/app/src/app/overmind/factories.ts b/packages/app/src/app/overmind/factories.ts index 450d8a648c3..5faf7e9e721 100755 --- a/packages/app/src/app/overmind/factories.ts +++ b/packages/app/src/app/overmind/factories.ts @@ -3,6 +3,26 @@ import { IDerive, IState, json } from 'overmind'; import { AsyncAction } from '.'; +/* + Ensures that we have a user when firing the action +*/ +export const withUser = ( + continueAction: AsyncAction +): AsyncAction => async (context, value) => { + const { state, when } = context; + + if (state.isLoggedIn) { + await continueAction(context, value); + } else { + await when(() => state.isLoggedIn); + await continueAction(context, value); + } +}; + +/* + Ensures that we have loaded the app with the initial user + and settings +*/ export const withLoadApp = ( continueAction?: AsyncAction ): AsyncAction => async (context, value) => { @@ -18,6 +38,7 @@ export const withLoadApp = ( state.isAuthenticating = true; state.jwt = effects.jwt.get() || null; + effects.connection.addListener(actions.connectionChanged); actions.internal.setStoredSettings(); effects.keybindingManager.set( diff --git a/packages/app/src/app/overmind/internalActions.ts b/packages/app/src/app/overmind/internalActions.ts index 3d167335811..4881096106b 100755 --- a/packages/app/src/app/overmind/internalActions.ts +++ b/packages/app/src/app/overmind/internalActions.ts @@ -36,6 +36,7 @@ export const signIn: AsyncAction<{ useExtraScopes?: boolean }> = async ( effects.live.connect(); actions.userNotifications.internal.initialize(); // Seemed a bit different originally? actions.refetchSandboxInfo(); + state.isAuthenticating = false; } catch (error) { actions.internal.handleError({ message: 'Could not authenticate with Github', diff --git a/packages/app/src/app/overmind/modals.ts b/packages/app/src/app/overmind/modals.ts index c527942506c..aa8ea85a54c 100644 --- a/packages/app/src/app/overmind/modals.ts +++ b/packages/app/src/app/overmind/modals.ts @@ -1,3 +1,5 @@ export const forkFrozenModal = { result: 'fork' as 'fork' | 'cancel' | 'unfreeze', }; + +export const authenticateUserModal = {}; diff --git a/packages/app/src/app/overmind/namespaces/editor/actions.ts b/packages/app/src/app/overmind/namespaces/editor/actions.ts index f49b3ebb0b0..7d62e2f4022 100755 --- a/packages/app/src/app/overmind/namespaces/editor/actions.ts +++ b/packages/app/src/app/overmind/namespaces/editor/actions.ts @@ -70,7 +70,7 @@ export const sandboxChanged: AsyncAction<{ id: string }> = withLoadApp<{ return; } - await effects.vscode.closeAllTabs(); + // await effects.vscode.closeAllTabs(); state.editor.error = null; @@ -87,10 +87,6 @@ export const sandboxChanged: AsyncAction<{ id: string }> = withLoadApp<{ state.editor.isLoading = !hasExistingSandbox; state.editor.notFound = false; - // Only reset changed modules if sandbox wasn't in memory, otherwise a fork - // can mark real changed modules as unchanged - state.editor.changedModuleShortids = []; - try { const sandbox = await effects.api.getSandbox(newId); @@ -232,17 +228,42 @@ export const codeChanged: Action<{ export const saveClicked: AsyncAction = withOwnedSandbox( async ({ state, effects, actions }) => { const sandbox = state.editor.currentSandbox; - const currentlyChangedModuleShortids = state.editor.changedModuleShortids.slice(); try { const changedModules = sandbox.modules.filter(module => state.editor.changedModuleShortids.includes(module.shortid) ); - state.editor.changedModuleShortids = []; + const updatedModules = await effects.api.saveModules( + sandbox.id, + changedModules + ); + + updatedModules.forEach(updatedModule => { + const module = sandbox.modules.find( + moduleItem => moduleItem.shortid === updatedModule.shortid + ); - await effects.api.saveModules(sandbox.id, changedModules); - effects.moduleRecover.clearSandbox(sandbox.id); + if (module) { + module.insertedAt = updatedModule.insertedAt; + module.updatedAt = updatedModule.updatedAt; + + module.savedCode = + updatedModule.code === module.code ? null : updatedModule.code; + + effects.vscode.sandboxFsSync.writeFile( + state.editor.modulesByPath, + module + ); + effects.moduleRecover.remove(sandbox.id, module); + } else { + // We might not have the module, as it was created by the server. In + // this case we put it in. There is an edge case here where the user + // might delete the module while it is being updated, but it will very + // likely not happen + sandbox.modules.push(updatedModule); + } + }); if ( state.editor.currentSandbox.originalGit && @@ -253,13 +274,6 @@ export const saveClicked: AsyncAction = withOwnedSandbox( effects.preview.executeCodeImmediately(); } catch (error) { - // Put back any unsaved modules taking into account that you - // might have changed some modules waiting for saving - currentlyChangedModuleShortids.forEach(moduleShortid => { - if (!state.editor.changedModuleShortids.includes(moduleShortid)) { - state.editor.changedModuleShortids.push(moduleShortid); - } - }); actions.internal.handleError({ message: 'There was a problem with saving the files, please try again', error, @@ -510,11 +524,6 @@ export const discardModuleChanges: Action<{ module.updatedAt = new Date().toString(); effects.vscode.revertModule(module); - - state.editor.changedModuleShortids.splice( - state.editor.changedModuleShortids.indexOf(moduleShortid), - 1 - ); }; export const fetchEnvironmentVariables: AsyncAction = async ({ diff --git a/packages/app/src/app/overmind/namespaces/editor/internalActions.ts b/packages/app/src/app/overmind/namespaces/editor/internalActions.ts index 5b9bea00581..07ffcb4f182 100755 --- a/packages/app/src/app/overmind/namespaces/editor/internalActions.ts +++ b/packages/app/src/app/overmind/namespaces/editor/internalActions.ts @@ -120,11 +120,6 @@ export const saveCode: AsyncAction<{ effects.vscode.sandboxFsSync.writeFile(state.editor.modulesByPath, module); effects.moduleRecover.remove(sandbox.id, module); - state.editor.changedModuleShortids.splice( - state.editor.changedModuleShortids.indexOf(module.shortid), - 1 - ); - if (cbID) { effects.vscode.callCallback(cbID); } @@ -269,23 +264,11 @@ export const setModuleCode: Action<{ code: string; }> = ({ state, effects }, { module, code }) => { const { currentSandbox } = state.editor; - const hasChangedModuleId = state.editor.changedModuleShortids.includes( - module.shortid - ); if (module.savedCode === null) { module.savedCode = module.code; } - if (hasChangedModuleId && module.savedCode === code) { - state.editor.changedModuleShortids.splice( - state.editor.changedModuleShortids.indexOf(module.shortid), - 1 - ); - } else if (!hasChangedModuleId && module.savedCode !== code) { - state.editor.changedModuleShortids.push(module.shortid); - } - effects.vscode.runCommand('workbench.action.keepEditor'); const tabs = state.editor.tabs as ModuleTab[]; diff --git a/packages/app/src/app/overmind/namespaces/editor/state.ts b/packages/app/src/app/overmind/namespaces/editor/state.ts index e1c5c689344..315cee2a833 100755 --- a/packages/app/src/app/overmind/namespaces/editor/state.ts +++ b/packages/app/src/app/overmind/namespaces/editor/state.ts @@ -39,7 +39,7 @@ type State = { notFound: boolean; error: string | null; isResizing: boolean; - changedModuleShortids: string[]; + changedModuleShortids: Derive; currentTabId: string; tabs: Tabs; errors: ModuleError[]; @@ -79,7 +79,19 @@ export const state: State = { error: null, isResizing: false, modulesByPath: {}, - changedModuleShortids: [], + changedModuleShortids: ({ currentSandbox }) => { + if (!currentSandbox) { + return []; + } + + return currentSandbox.modules.reduce((aggr, module) => { + if (module.savedCode !== null && module.savedCode !== module.code) { + return aggr.concat(module.shortid); + } + + return aggr; + }, []); + }, currentTabId: null, tabs: [], errors: [], diff --git a/packages/app/src/app/overmind/namespaces/live/actions.ts b/packages/app/src/app/overmind/namespaces/live/actions.ts index c83410f2913..abb3e851b52 100755 --- a/packages/app/src/app/overmind/namespaces/live/actions.ts +++ b/packages/app/src/app/overmind/namespaces/live/actions.ts @@ -1,6 +1,6 @@ import { LiveMessage, LiveMessageEvent } from '@codesandbox/common/lib/types'; import { Action, AsyncAction, Operator } from 'app/overmind'; -import { withLoadApp } from 'app/overmind/factories'; +import { withLoadApp, withUser } from 'app/overmind/factories'; import getItems from 'app/overmind/utils/items'; import { filter, fork, pipe } from 'overmind'; @@ -11,33 +11,44 @@ export const internal = internalActions; export const roomJoined: AsyncAction<{ roomId: string; -}> = withLoadApp(async ({ state, effects, actions }, { roomId }) => { - await effects.vscode.initialize; - await effects.vscode.closeAllTabs(); - const sandbox = await actions.live.internal.initialize(roomId); +}> = withUser( + withLoadApp(async ({ state, effects, actions }, { roomId }) => { + await effects.vscode.initialize; + await effects.vscode.closeAllTabs(); - if (state.updateStatus === 'available') { - const modal = 'liveVersionMismatch'; - effects.analytics.track('Open Modal', { modal }); - state.currentModal = modal; - } + if (state.live.isLive) { + actions.live.internal.disconnect(); + } - await actions.internal.setCurrentSandbox(sandbox); + const sandbox = await actions.live.internal.initialize(roomId); - const items = getItems(state); - const defaultItem = items.find(i => i.defaultOpen) || items[0]; + if (!sandbox) { + return; + } - state.workspace.openedWorkspaceItem = defaultItem.id; + if (state.updateStatus === 'available') { + const modal = 'liveVersionMismatch'; + effects.analytics.track('Open Modal', { modal }); + state.currentModal = modal; + } - await effects.vscode.changeSandbox(state.editor.currentSandbox, fs => { - state.editor.modulesByPath = fs; - }); + await actions.internal.setCurrentSandbox(sandbox); - effects.live.sendModuleStateSyncRequest(); - effects.vscode.openModule(state.editor.currentModule); - effects.preview.executeCodeImmediately({ initialRender: true }); - state.live.isLoading = false; -}); + const items = getItems(state); + const defaultItem = items.find(i => i.defaultOpen) || items[0]; + + state.workspace.openedWorkspaceItem = defaultItem.id; + + await effects.vscode.changeSandbox(state.editor.currentSandbox, fs => { + state.editor.modulesByPath = fs; + }); + + effects.live.sendModuleStateSyncRequest(); + effects.vscode.openModule(state.editor.currentModule); + effects.preview.executeCodeImmediately({ initialRender: true }); + state.editor.isLoading = false; + }) +); export const createLiveClicked: AsyncAction = async ( { actions, effects, state }, diff --git a/packages/app/src/app/overmind/namespaces/live/liveMessageOperators.ts b/packages/app/src/app/overmind/namespaces/live/liveMessageOperators.ts index 8812e2d9b1c..90fca84f5d7 100644 --- a/packages/app/src/app/overmind/namespaces/live/liveMessageOperators.ts +++ b/packages/app/src/app/overmind/namespaces/live/liveMessageOperators.ts @@ -111,11 +111,6 @@ export const onModuleSaved: Operator { + timer: NodeJS.Timer; state = { showing: true, }; diff --git a/packages/app/src/app/pages/Live/index.js b/packages/app/src/app/pages/Live/index.tsx similarity index 51% rename from packages/app/src/app/pages/Live/index.js rename to packages/app/src/app/pages/Live/index.tsx index 7a8e46d55c1..a1e5c6d96fc 100644 --- a/packages/app/src/app/pages/Live/index.js +++ b/packages/app/src/app/pages/Live/index.tsx @@ -2,62 +2,44 @@ import Centered from '@codesandbox/common/lib/components/flex/Centered'; import Fullscreen from '@codesandbox/common/lib/components/flex/Fullscreen'; import Padding from '@codesandbox/common/lib/components/spacing/Padding'; import { getSandboxName } from '@codesandbox/common/lib/utils/get-sandbox-name'; -import { inject, observer } from 'app/componentConnectors'; import { Skeleton } from 'app/components/Skeleton'; import { SubTitle } from 'app/components/SubTitle'; import { Title } from 'app/components/Title'; +import { useOvermind } from 'app/overmind'; import { Navigation } from 'app/pages/common/Navigation'; import { SignInButton } from 'app/pages/common/SignInButton'; import { QuickActions } from 'app/pages/Sandbox/QuickActions'; -import { hasAuthToken } from 'app/utils/user'; -import * as React from 'react'; -import Helmet from 'react-helmet'; +import React, { useEffect } from 'react'; +import { Helmet } from 'react-helmet'; import { Link } from 'react-router-dom'; import Editor from '../Sandbox/Editor'; import { BlinkingDot } from './BlinkingDot'; -class LivePage extends React.Component { - loggedIn = this.props.store.hasLogIn; - - UNSAFE_componentWillMount() { - this.initializeLive(); - } - - disconnectLive() { - if (this.props.store.live.isLive) { - this.props.signals.live.onNavigateAway({}); - } - } - - componentWillUnmount() { - this.disconnectLive(); - this.props.signals.editor.onNavigateAway({}); - } - - initializeLive = () => { - if (hasAuthToken()) { - this.loggedIn = true; - this.props.signals.live.roomJoined({ - roomId: this.props.match.params.id, - }); - } +interface Props { + match: { + params: { + id: string; + }; }; +} - componentDidUpdate(prevProps) { - if ( - prevProps.match.params.id !== this.props.match.params.id || - (hasAuthToken() && !this.loggedIn) - ) { - this.disconnectLive(); - this.initializeLive(); - } - } +export const LivePage: React.FC = ({ match }) => { + const { state, actions } = useOvermind(); - getContent = () => { - const { store } = this.props; + useEffect(() => { + actions.live.roomJoined({ roomId: match.params.id }); + }, [actions.live, match.params.id]); - if (!hasAuthToken()) { + useEffect( + () => () => { + actions.live.onNavigateAway(); + }, + [actions.live] + ); + + function getContent() { + if (!state.user) { return ( <>
An error occured while connecting to the live session: - {store.live.error} + {state.live.error}

Create Sandbox @@ -116,7 +98,12 @@ class LivePage extends React.Component { ); } - if (!store.editor.currentSandbox) { + if ( + state.isAuthenticating || + state.editor.isLoading || + state.live.isLoading || + !state.editor.currentSandbox + ) { return ( <> - - - - {content} - - - - ); - } + } - const sandbox = store.editor.currentSandbox; + const content = getContent(); + if (content) { return ( - <> - {sandbox && ( - - {getSandboxName(sandbox)} - CodeSandbox - - )} - - - + + + + + {content} + + + ); } -} -// eslint-disable-next-line import/no-default-export -export default inject('signals', 'store')(observer(LivePage)); + const sandbox = state.editor.currentSandbox; + + return ( + <> + {sandbox && ( + + {getSandboxName(sandbox)} - CodeSandbox + + )} + + + + ); +}; diff --git a/packages/app/src/app/pages/Sandbox/Editor/Header/Header.tsx b/packages/app/src/app/pages/Sandbox/Editor/Header/Header.tsx index 4407e14489f..6b92c890d20 100644 --- a/packages/app/src/app/pages/Sandbox/Editor/Header/Header.tsx +++ b/packages/app/src/app/pages/Sandbox/Editor/Header/Header.tsx @@ -1,29 +1,28 @@ import { dashboardUrl } from '@codesandbox/common/lib/utils/url-generator'; import { useOvermind } from 'app/overmind'; -import React from 'react'; - import { UserMenu } from 'app/pages/common/UserMenu'; +import React from 'react'; import { - SaveAllButton, - RefreshButton, - PreferencesButton, - NewSandboxButton, + ForkButton, LikeButton, + NewSandboxButton, PickButton, + PreferencesButton, + RefreshButton, + SaveAllButton, ShareButton, - ForkButton, } from './Buttons'; import { - Container, - Right, - Left, + AccountContainer, Centered, + Container, DashboardIcon, DashboardLink, - AccountContainer, - UserMenuContainer, + Left, + Right, SignInButton, + UserMenuContainer, } from './elements'; import { Logo } from './Logo'; import { MenuBar } from './MenuBar'; diff --git a/packages/app/src/app/pages/index.tsx b/packages/app/src/app/pages/index.tsx index 2e16468fef5..3fb14795818 100644 --- a/packages/app/src/app/pages/index.tsx +++ b/packages/app/src/app/pages/index.tsx @@ -26,7 +26,9 @@ const SignIn = Loadable(() => import(/* webpackChunkName: 'page-sign-in' */ './SignIn') ); const Live = Loadable(() => - import(/* webpackChunkName: 'page-sign-in' */ './Live') + import(/* webpackChunkName: 'page-sign-in' */ './Live').then(module => ({ + default: module.LivePage, + })) ); const ZeitSignIn = Loadable(() => import(/* webpackChunkName: 'page-zeit' */ './ZeitAuth') diff --git a/yarn.lock b/yarn.lock index 2b697fe9e94..b2e32e52c2e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6989,10 +6989,10 @@ betsy@1.0.2: "@types/node" "^10.5.1" tslib "^1.9.3" -betsy@1.0.2-1575912749783: - version "1.0.2-1575912749783" - resolved "https://registry.yarnpkg.com/betsy/-/betsy-1.0.2-1575912749783.tgz#490d13a88200edea620bce29d3606ec9389fcd3c" - integrity sha512-wD9Ev7hmZIi88/y0ti+wqMkQZJgxt4VeYi8Vf4gIB5wV3BRnnInsP6kOHn9SpJA0YGxRtMsyYviVVJnrNymhEg== +betsy@1.0.2-1576231149763: + version "1.0.2-1576231149763" + resolved "https://registry.yarnpkg.com/betsy/-/betsy-1.0.2-1576231149763.tgz#d1a37190dd0a9c10734f5f6e9c391b5ec9924017" + integrity sha512-We3SZQQYJzhnDE/Uke44yxhjt8hAUB9ojgG+bRAyk2e4JnuxTkT2mX28BMy+5US5zeyYgShRCvKCmUo/UQJJIA== better-assert@~1.0.0: version "1.0.2" @@ -20460,12 +20460,12 @@ overmind-react@19.0.1: overmind "18.0.1" tslib "^1.9.3" -overmind-react@^22.0.0-1575912749783: - version "22.0.0-1575912749783" - resolved "https://registry.yarnpkg.com/overmind-react/-/overmind-react-22.0.0-1575912749783.tgz#07c3bb982a4ace5533a9b2f1a260ac4f4af0dac2" - integrity sha512-BHU3GvfOQcuI8Mf/NaLh0a+k65w2lDdo6otqDvwoE2kagwvi7esnNL6y1fA9/eeTReTkTyRCkqo3L8o43MTEdQ== +overmind-react@^22.0.0-1576231149763: + version "22.0.0-1576231149763" + resolved "https://registry.yarnpkg.com/overmind-react/-/overmind-react-22.0.0-1576231149763.tgz#97c40ca34c2385ab5f866f5d6b93f79be5f2f3e4" + integrity sha512-3ZrWIAGp6sbzZ7FtVGcinXdFMlGdHe2mQW0hCZDWPPJduqme9WEFpz1sILK4vtv60UT287osAYfqx4hrCD8LJQ== dependencies: - overmind "21.0.0-1575912749783" + overmind "21.0.0-1576231149763" overmind-themes@next: version "1.0.2-1562145138120" @@ -20485,14 +20485,14 @@ overmind@18.0.1: proxy-state-tree "4.4.0" tslib "^1.9.3" -overmind@21.0.0-1575912749783, overmind@^21.0.0-1575912749783: - version "21.0.0-1575912749783" - resolved "https://registry.yarnpkg.com/overmind/-/overmind-21.0.0-1575912749783.tgz#911490b517bcbedf9c1dbc50cb1d69597e793ce8" - integrity sha512-/LQKLJ8kagrQuNEw8LEaZ++gZ13k8SgJrkdXpFBJ3/4t7QFY4nokiIP/fwLnHpcxFykf9o9fFPGw7cSxTJBq3w== +overmind@21.0.0-1576231149763, overmind@^21.0.0-1576231149763: + version "21.0.0-1576231149763" + resolved "https://registry.yarnpkg.com/overmind/-/overmind-21.0.0-1576231149763.tgz#0e3be6c3826507f3777682927667fe6da27fef66" + integrity sha512-agqq6dwojfGVrOJ3N26wjoW2BjCI/35pU3CqTj0yxaCcoAulzhBXX8FJL7T51ocWDCqDl0auqW0QF47eJe/txw== dependencies: - betsy "1.0.2-1575912749783" + betsy "1.0.2-1576231149763" is-plain-obj "^1.1.0" - proxy-state-tree "4.6.0-1575912749783" + proxy-state-tree "4.6.0-1576231149763" tslib "^1.10.0" p-cancelable@^0.3.0: @@ -22730,10 +22730,10 @@ proxy-state-tree@4.4.0: dependencies: is-plain-obj "^1.1.0" -proxy-state-tree@4.6.0-1575912749783: - version "4.6.0-1575912749783" - resolved "https://registry.yarnpkg.com/proxy-state-tree/-/proxy-state-tree-4.6.0-1575912749783.tgz#f1ba65f02d7538cd9f4a051912dfcc3acd5e15eb" - integrity sha512-0KfTL1GsS5I0W5OS+VmfkYordHpreahRuJPVQ6uVQS/pdS16QHIuX1b6MaJgaqhrYrovaiHQubbHAJFVWBURDw== +proxy-state-tree@4.6.0-1576231149763: + version "4.6.0-1576231149763" + resolved "https://registry.yarnpkg.com/proxy-state-tree/-/proxy-state-tree-4.6.0-1576231149763.tgz#6bac5b56b44fc15cb751fa35035ef6a9ff560a27" + integrity sha512-/xz73SFgBdmlXXbkHE6kr+/++ejfer0Pi7MJTAEMvf1eAwRexRQy3oM7DpDeE790T/TGsgtWiZQYQVcvyBC+8Q== dependencies: is-plain-obj "^1.1.0" From 6b66111f60209a8cde2bb82a83bbb1366affa995 Mon Sep 17 00:00:00 2001 From: Christian Alfoni Date: Sat, 14 Dec 2019 14:13:39 +0100 Subject: [PATCH 2/4] change how we handle signing into live --- packages/app/src/app/overmind/factories.ts | 16 ---- .../app/overmind/namespaces/editor/actions.ts | 2 +- .../app/overmind/namespaces/live/actions.ts | 74 +++++++++++-------- packages/app/src/app/pages/Live/index.tsx | 16 +++- 4 files changed, 59 insertions(+), 49 deletions(-) diff --git a/packages/app/src/app/overmind/factories.ts b/packages/app/src/app/overmind/factories.ts index 5faf7e9e721..00831b4bb59 100755 --- a/packages/app/src/app/overmind/factories.ts +++ b/packages/app/src/app/overmind/factories.ts @@ -3,22 +3,6 @@ import { IDerive, IState, json } from 'overmind'; import { AsyncAction } from '.'; -/* - Ensures that we have a user when firing the action -*/ -export const withUser = ( - continueAction: AsyncAction -): AsyncAction => async (context, value) => { - const { state, when } = context; - - if (state.isLoggedIn) { - await continueAction(context, value); - } else { - await when(() => state.isLoggedIn); - await continueAction(context, value); - } -}; - /* Ensures that we have loaded the app with the initial user and settings diff --git a/packages/app/src/app/overmind/namespaces/editor/actions.ts b/packages/app/src/app/overmind/namespaces/editor/actions.ts index 7d62e2f4022..3dd53a53e5d 100755 --- a/packages/app/src/app/overmind/namespaces/editor/actions.ts +++ b/packages/app/src/app/overmind/namespaces/editor/actions.ts @@ -70,7 +70,7 @@ export const sandboxChanged: AsyncAction<{ id: string }> = withLoadApp<{ return; } - // await effects.vscode.closeAllTabs(); + await effects.vscode.closeAllTabs(); state.editor.error = null; diff --git a/packages/app/src/app/overmind/namespaces/live/actions.ts b/packages/app/src/app/overmind/namespaces/live/actions.ts index abb3e851b52..8feeaa98507 100755 --- a/packages/app/src/app/overmind/namespaces/live/actions.ts +++ b/packages/app/src/app/overmind/namespaces/live/actions.ts @@ -1,6 +1,6 @@ import { LiveMessage, LiveMessageEvent } from '@codesandbox/common/lib/types'; import { Action, AsyncAction, Operator } from 'app/overmind'; -import { withLoadApp, withUser } from 'app/overmind/factories'; +import { withLoadApp } from 'app/overmind/factories'; import getItems from 'app/overmind/utils/items'; import { filter, fork, pipe } from 'overmind'; @@ -9,46 +9,60 @@ import * as liveMessage from './liveMessageOperators'; export const internal = internalActions; +export const signInToRoom: AsyncAction<{ + roomId: string; +}> = withLoadApp(async ({ state, effects, actions }, { roomId }) => { + await actions.internal.signIn({}); + + if (state.isLoggedIn) { + await actions.live.roomJoined({ + roomId, + }); + } +}); + export const roomJoined: AsyncAction<{ roomId: string; -}> = withUser( - withLoadApp(async ({ state, effects, actions }, { roomId }) => { - await effects.vscode.initialize; - await effects.vscode.closeAllTabs(); +}> = withLoadApp(async ({ state, effects, actions }, { roomId }) => { + if (!state.isLoggedIn) { + return; + } - if (state.live.isLive) { - actions.live.internal.disconnect(); - } + await effects.vscode.initialize; + await effects.vscode.closeAllTabs(); - const sandbox = await actions.live.internal.initialize(roomId); + if (state.live.isLive) { + actions.live.internal.disconnect(); + } - if (!sandbox) { - return; - } + const sandbox = await actions.live.internal.initialize(roomId); - if (state.updateStatus === 'available') { - const modal = 'liveVersionMismatch'; - effects.analytics.track('Open Modal', { modal }); - state.currentModal = modal; - } + if (!sandbox) { + return; + } - await actions.internal.setCurrentSandbox(sandbox); + if (state.updateStatus === 'available') { + const modal = 'liveVersionMismatch'; + effects.analytics.track('Open Modal', { modal }); + state.currentModal = modal; + } - const items = getItems(state); - const defaultItem = items.find(i => i.defaultOpen) || items[0]; + await actions.internal.setCurrentSandbox(sandbox); - state.workspace.openedWorkspaceItem = defaultItem.id; + const items = getItems(state); + const defaultItem = items.find(i => i.defaultOpen) || items[0]; - await effects.vscode.changeSandbox(state.editor.currentSandbox, fs => { - state.editor.modulesByPath = fs; - }); + state.workspace.openedWorkspaceItem = defaultItem.id; - effects.live.sendModuleStateSyncRequest(); - effects.vscode.openModule(state.editor.currentModule); - effects.preview.executeCodeImmediately({ initialRender: true }); - state.editor.isLoading = false; - }) -); + await effects.vscode.changeSandbox(state.editor.currentSandbox, fs => { + state.editor.modulesByPath = fs; + }); + + effects.live.sendModuleStateSyncRequest(); + effects.vscode.openModule(state.editor.currentModule); + effects.preview.executeCodeImmediately({ initialRender: true }); + state.editor.isLoading = false; +}); export const createLiveClicked: AsyncAction = async ( { actions, effects, state }, diff --git a/packages/app/src/app/pages/Live/index.tsx b/packages/app/src/app/pages/Live/index.tsx index a1e5c6d96fc..f2ba5bbb9c9 100644 --- a/packages/app/src/app/pages/Live/index.tsx +++ b/packages/app/src/app/pages/Live/index.tsx @@ -1,5 +1,7 @@ +import { Button } from '@codesandbox/common/lib/components/Button'; import Centered from '@codesandbox/common/lib/components/flex/Centered'; import Fullscreen from '@codesandbox/common/lib/components/flex/Fullscreen'; +import Row from '@codesandbox/common/lib/components/flex/Row'; import Padding from '@codesandbox/common/lib/components/spacing/Padding'; import { getSandboxName } from '@codesandbox/common/lib/utils/get-sandbox-name'; import { Skeleton } from 'app/components/Skeleton'; @@ -7,10 +9,10 @@ import { SubTitle } from 'app/components/SubTitle'; import { Title } from 'app/components/Title'; import { useOvermind } from 'app/overmind'; import { Navigation } from 'app/pages/common/Navigation'; -import { SignInButton } from 'app/pages/common/SignInButton'; import { QuickActions } from 'app/pages/Sandbox/QuickActions'; import React, { useEffect } from 'react'; import { Helmet } from 'react-helmet'; +import GithubIcon from 'react-icons/lib/go/mark-github'; import { Link } from 'react-router-dom'; import Editor from '../Sandbox/Editor'; @@ -57,7 +59,17 @@ export const LivePage: React.FC = ({ match }) => {
- +
); From a899710cf6458e2b09bff0e09387d88a46ecfa07 Mon Sep 17 00:00:00 2001 From: Christian Alfoni Date: Wed, 18 Dec 2019 10:06:31 +0100 Subject: [PATCH 3/4] improve auth indication when joining live sandbox --- packages/app/src/app/pages/Live/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/app/src/app/pages/Live/index.tsx b/packages/app/src/app/pages/Live/index.tsx index f2ba5bbb9c9..01ed6f19815 100644 --- a/packages/app/src/app/pages/Live/index.tsx +++ b/packages/app/src/app/pages/Live/index.tsx @@ -41,7 +41,7 @@ export const LivePage: React.FC = ({ match }) => { ); function getContent() { - if (!state.user) { + if (!state.isAuthenticating && !state.user) { return ( <>
Date: Wed, 18 Dec 2019 10:08:55 +0100 Subject: [PATCH 4/4] fix type on setInterval --- packages/app/src/app/pages/Live/BlinkingDot.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/app/src/app/pages/Live/BlinkingDot.tsx b/packages/app/src/app/pages/Live/BlinkingDot.tsx index 730b2afdd4f..f48d9efe096 100644 --- a/packages/app/src/app/pages/Live/BlinkingDot.tsx +++ b/packages/app/src/app/pages/Live/BlinkingDot.tsx @@ -13,13 +13,13 @@ const DotContainer = styled.div` `; export class BlinkingDot extends React.PureComponent<{}, { showing: boolean }> { - timer: NodeJS.Timer; + timer: number; state = { showing: true, }; componentDidMount() { - this.timer = setInterval(() => { + this.timer = window.setInterval(() => { this.setState(state => ({ showing: !state.showing })); }, 1000); }