Skip to content

Commit 66e6a71

Browse files
faceyspaceyCompuIves
authored andcommitted
feat($urlParams): add params for isInProjectView + initialPath (codesandbox#49)
* feat($urlParams): add params for isInProjectView + initialPath * fix($flow): addd isInprojectView + initialPath to Sandbox flow type * Add @faceyspacey as a contributor * Add @faceyspacey as a contributor * feat($fileEavl): removed toggle isInProjectView switch from address bar, re-incarnated it as isFileEval in the Files WorkspaceItem * fix($deleteLogging): remove console.logs * fix($checked): switch checkbox value to checked attribute * fix($logging): remove logging * fix($frameUrl): insure iframe doesnt re-render when its URL changes * bring navigator project/module view switch back * start($currentDirectoryShortid) * Rename path variables * Remove file eval switch * Remove directoryShortId from Files component * Select index.js defaultModule by default in ShareView * Change current module view wording * Make embed work with URL parameters * Auto open directory of current module * fix($logging): remove logging * Update @faceyspacey as a contributor * chore($tests): update test snapshots
1 parent 2fec82c commit 66e6a71

File tree

20 files changed

+250
-51
lines changed

20 files changed

+250
-51
lines changed

.all-contributorsrc

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,16 @@
5252
"contributions": [
5353
"code"
5454
]
55+
},
56+
{
57+
"login": "faceyspacey",
58+
"name": "James Gillmore",
59+
"avatar_url": "https://avatars3.githubusercontent.com/u/154732?v=3",
60+
"profile": "http://twitter.com/faceyspacey",
61+
"contributions": [
62+
"code",
63+
"bug"
64+
]
5565
}
5666
]
5767
}

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# [CodeSandbox](https://codesandbox.io) [![Chat](https://img.shields.io/badge/chat-on%20discord-7289da.svg)](https://discord.gg/KE3TbEZ) [![All Contributors](https://img.shields.io/badge/all_contributors-4-orange.svg?style=flat-square)](#contributors) [![Build Status](https://travis-ci.org/CompuIves/codesandbox-client.svg?branch=master)](https://travis-ci.org/CompuIves/codesandbox-client)
1+
# [CodeSandbox](https://codesandbox.io) [![Chat](https://img.shields.io/badge/chat-on%20discord-7289da.svg)](https://discord.gg/KE3TbEZ) [![All Contributors](https://img.shields.io/badge/all_contributors-5-orange.svg?style=flat-square)](#contributors) [![Build Status](https://travis-ci.org/CompuIves/codesandbox-client.svg?branch=master)](https://travis-ci.org/CompuIves/codesandbox-client)
22

33
An online code editor with a focus on React.
44

@@ -44,8 +44,8 @@ CodeSandbox consists several separate servers, some of these are open sourced.
4444
Thanks goes to these wonderful people ([emoji key](https://github.com/kentcdodds/all-contributors#emoji-key)):
4545

4646
<!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section -->
47-
| [<img src="https://avatars0.githubusercontent.com/u/587016?v=3" width="100px;"/><br /><sub>Ives van Hoorne</sub>](http://ivesvh.com)<br />[💬](#question-CompuIves "Answering Questions") [📝](#blog-CompuIves "Blogposts") [🐛](https://github.com/CompuIves/CodeSandbox/issues?q=author%3ACompuIves "Bug reports") [💻](https://github.com/CompuIves/CodeSandbox/commits?author=CompuIves "Code") [🎨](#design-CompuIves "Design") [📖](https://github.com/CompuIves/CodeSandbox/commits?author=CompuIves "Documentation") [💡](#example-CompuIves "Examples") [🚇](#infra-CompuIves "Infrastructure (Hosting, Build-Tools, etc)") [👀](#review-CompuIves "Reviewed Pull Requests") [⚠️](https://github.com/CompuIves/CodeSandbox/commits?author=CompuIves "Tests") [🔧](#tool-CompuIves "Tools") | [<img src="https://avatars0.githubusercontent.com/u/887639?v=3" width="100px;"/><br /><sub>Donavon West</sub>](http://donavon.com)<br />[💻](https://github.com/CompuIves/CodeSandbox/commits?author=donavon "Code") | [<img src="https://avatars0.githubusercontent.com/u/5266810?v=3" width="100px;"/><br /><sub>Jeff Allen</sub>](http://www.jeffallen.io/)<br />[💻](https://github.com/CompuIves/CodeSandbox/commits?author=vueu "Code") | [<img src="https://avatars0.githubusercontent.com/u/1089897?v=3" width="100px;"/><br /><sub>Ben Gummer</sub>](https://github.com/bengummer)<br />[💻](https://github.com/CompuIves/CodeSandbox/commits?author=bengummer "Code") |
48-
| :---: | :---: | :---: | :---: |
47+
| [<img src="https://avatars0.githubusercontent.com/u/587016?v=3" width="100px;"/><br /><sub>Ives van Hoorne</sub>](http://ivesvh.com)<br />[💬](#question-CompuIves "Answering Questions") [📝](#blog-CompuIves "Blogposts") [🐛](https://github.com/CompuIves/CodeSandbox/issues?q=author%3ACompuIves "Bug reports") [💻](https://github.com/CompuIves/CodeSandbox/commits?author=CompuIves "Code") [🎨](#design-CompuIves "Design") [📖](https://github.com/CompuIves/CodeSandbox/commits?author=CompuIves "Documentation") [💡](#example-CompuIves "Examples") [🚇](#infra-CompuIves "Infrastructure (Hosting, Build-Tools, etc)") [👀](#review-CompuIves "Reviewed Pull Requests") [⚠️](https://github.com/CompuIves/CodeSandbox/commits?author=CompuIves "Tests") [🔧](#tool-CompuIves "Tools") | [<img src="https://avatars0.githubusercontent.com/u/887639?v=3" width="100px;"/><br /><sub>Donavon West</sub>](http://donavon.com)<br />[💻](https://github.com/CompuIves/CodeSandbox/commits?author=donavon "Code") | [<img src="https://avatars0.githubusercontent.com/u/5266810?v=3" width="100px;"/><br /><sub>Jeff Allen</sub>](http://www.jeffallen.io/)<br />[💻](https://github.com/CompuIves/CodeSandbox/commits?author=vueu "Code") | [<img src="https://avatars0.githubusercontent.com/u/1089897?v=3" width="100px;"/><br /><sub>Ben Gummer</sub>](https://github.com/bengummer)<br />[💻](https://github.com/CompuIves/CodeSandbox/commits?author=bengummer "Code") | [<img src="https://avatars3.githubusercontent.com/u/154732?v=3" width="100px;"/><br /><sub>James Gillmore</sub>](http://twitter.com/faceyspacey)<br />[💻](https://github.com/CompuIves/CodeSandbox/commits?author=faceyspacey "Code") [🐛](https://github.com/CompuIves/CodeSandbox/issues?q=author%3Afaceyspacey "Bug reports") |
48+
| :---: | :---: | :---: | :---: | :---: |
4949
<!-- ALL-CONTRIBUTORS-LIST:END -->
5050

5151
This project follows the [all-contributors](https://github.com/kentcdodds/all-contributors) specification. Contributions of any kind welcome!

src/app/components/sandbox/Preview/Navigator.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,4 +92,4 @@ export default ({
9292
</Tooltip>
9393
</SwitchContainer>}
9494
</Container>
95-
);
95+
);

src/app/components/sandbox/Preview/index.js

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ const StyledFrame = styled.iframe`
2929

3030
type Props = {
3131
sandboxId: string,
32+
initialPath: ?string,
3233
isInProjectView: boolean,
3334
modules: Array<Module>,
3435
directories: Array<Directory>,
@@ -56,20 +57,27 @@ type State = {
5657
};
5758

5859
export default class Preview extends React.PureComponent {
60+
initialPath: string;
61+
5962
constructor(props: Props) {
6063
super(props);
6164

6265
this.state = {
6366
frameInitialized: false,
6467
history: [],
6568
historyPosition: 0,
66-
urlInAddressBar: '',
69+
urlInAddressBar: props.initialPath || '',
6770
url: null,
6871
};
6972

7073
if (!props.noDelay) {
7174
this.executeCode = debounce(this.executeCode, 800);
7275
}
76+
77+
// we need a value that doesn't change when receiving `initialPath`
78+
// from the query params, or the iframe will continue to be re-rendered
79+
// when the user navigates the iframe app, which shows the loading screen
80+
this.initialPath = this.state.urlInAddressBar;
7381
}
7482

7583
static defaultProps = {
@@ -252,6 +260,7 @@ export default class Preview extends React.PureComponent {
252260
const { history, historyPosition } = this.state;
253261

254262
document.getElementById('sandbox').src = frameUrl(history[historyPosition]);
263+
255264
this.setState({
256265
urlInAddressBar: history[historyPosition],
257266
});
@@ -350,7 +359,7 @@ export default class Preview extends React.PureComponent {
350359
/>}
351360
<StyledFrame
352361
sandbox="allow-forms allow-scripts allow-same-origin allow-modals allow-popups allow-presentation"
353-
src={frameUrl()}
362+
src={frameUrl(this.initialPath)}
354363
id="sandbox"
355364
hideNavigation={hideNavigation}
356365
/>

src/app/pages/Sandbox/Editor/Content/Header/ShareView.js

Lines changed: 46 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -144,13 +144,16 @@ const mapStateToProps = createSelector(
144144
);
145145
class ShareView extends React.PureComponent {
146146
props: Props;
147+
147148
state = {
148149
showEditor: true,
149150
showPreview: true,
150151
defaultModule: null,
151152
autoResize: false,
152153
hideNavigation: false,
154+
isCurrentModuleView: false,
153155
fontSize: 14,
156+
initialPath: '',
154157
};
155158

156159
handleChange = e => this.setState({ message: e.target.value });
@@ -169,6 +172,7 @@ class ShareView extends React.PureComponent {
169172
setMixedView = () => this.setState({ showEditor: true, showPreview: true });
170173

171174
setDefaultModule = id => this.setState({ defaultModule: id });
175+
clearDefaultModule = () => this.setState({ defaultModule: null });
172176

173177
getOptionsUrl = () => {
174178
const {
@@ -177,12 +181,15 @@ class ShareView extends React.PureComponent {
177181
showPreview,
178182
autoResize,
179183
hideNavigation,
184+
isCurrentModuleView,
180185
fontSize,
186+
initialPath,
181187
} = this.state;
182188

183189
const options = {};
184190

185-
if (defaultModule) {
191+
const mainModuleShortid = findMainModule(this.props.modules).shortid;
192+
if (defaultModule && defaultModule !== mainModuleShortid) {
186193
options.module = defaultModule;
187194
}
188195

@@ -201,10 +208,18 @@ class ShareView extends React.PureComponent {
201208
options.hidenavigation = 1;
202209
}
203210

211+
if (isCurrentModuleView) {
212+
options.moduleview = 1;
213+
}
214+
204215
if (fontSize !== 14) {
205216
options.fontsize = fontSize;
206217
}
207218

219+
if (initialPath) {
220+
options.initialpath = initialPath;
221+
}
222+
208223
return optionsToParameterizedUrl(options);
209224
};
210225

@@ -220,6 +235,11 @@ class ShareView extends React.PureComponent {
220235
return protocolAndHost() + embedUrl(sandbox) + this.getOptionsUrl();
221236
};
222237

238+
setInitialPath = ({ target }) => {
239+
const initialPath = target.value;
240+
this.setState({ initialPath });
241+
};
242+
223243
getIframeScript = () =>
224244
`<iframe src="${this.getEmbedUrl()}" style="width:100%; height:500px; border:0; border-radius: 4px; overflow:hidden;" sandbox="allow-modals allow-forms allow-popups allow-scripts allow-same-origin"></iframe>`;
225245

@@ -251,20 +271,27 @@ class ShareView extends React.PureComponent {
251271
this.setState({ hideNavigation });
252272
};
253273

274+
setIsCurrentModuleView = (isCurrentModuleView: boolean) => {
275+
this.setState({ isCurrentModuleView });
276+
};
277+
254278
setFontSize = (fontSize: number) => [this.setState({ fontSize })];
255279

256280
render() {
257281
const { sandbox, modules, directories } = this.props;
282+
258283
const {
259284
showEditor,
260285
showPreview,
261286
autoResize,
262287
hideNavigation,
288+
isCurrentModuleView,
263289
fontSize,
290+
initialPath,
264291
} = this.state;
265292

266293
const defaultModule =
267-
this.state.defaultModule || findMainModule(modules).id;
294+
this.state.defaultModule || findMainModule(modules).shortid;
268295

269296
return (
270297
<Container>
@@ -295,12 +322,27 @@ class ShareView extends React.PureComponent {
295322
value={hideNavigation}
296323
setValue={this.setHideNavigation}
297324
/>
325+
<PaddedPreference
326+
title="Show current module view"
327+
tooltip="Only show the module that's currently open"
328+
value={isCurrentModuleView}
329+
setValue={this.setIsCurrentModuleView}
330+
/>
298331
<PaddedPreference
299332
title="Font size"
300333
value={fontSize}
301334
setValue={this.setFontSize}
302335
/>
303336
</div>
337+
<Inputs>
338+
<LinkName>Project Initial Path</LinkName>
339+
<input
340+
onFocus={this.select}
341+
placeholder="e.g: /home"
342+
value={initialPath}
343+
onChange={this.setInitialPath}
344+
/>
345+
</Inputs>
304346
<div>
305347
<h4>Default view</h4>
306348
<div
@@ -321,13 +363,13 @@ class ShareView extends React.PureComponent {
321363
</div>
322364
</div>
323365
<div>
324-
<h4>Default module to show and preview</h4>
366+
<h4>Default module to show</h4>
325367

326368
<FilesContainer>
327369
<Files
328370
modules={modules}
329-
directories={directories}
330371
directoryId={null}
372+
directories={directories}
331373
currentModule={defaultModule}
332374
setCurrentModule={this.setDefaultModule}
333375
/>

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

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import sandboxActionCreators from 'app/store/entities/sandboxes/actions';
1919
import userActionCreators from 'app/store/user/actions';
2020
import {
2121
findMainModule,
22+
findCurrentModule,
2223
getModulePath,
2324
modulesFromSandboxSelector,
2425
} from 'app/store/entities/sandboxes/modules/selectors';
@@ -133,10 +134,10 @@ class EditorPreview extends React.PureComponent {
133134

134135
const mainModule = findMainModule(modules);
135136
if (!mainModule) throw new Error('Cannot find main module');
136-
137+
137138
const { currentModule: currentModuleId } = sandbox;
138-
const currentModule =
139-
modules.find(m => m.id === currentModuleId) || mainModule;
139+
140+
const currentModule = findCurrentModule(modules, currentModuleId, mainModule);
140141
const modulePath = getModulePath(modules, directories, currentModule.id);
141142

142143
if (currentModule == null) return null;
@@ -163,6 +164,7 @@ class EditorPreview extends React.PureComponent {
163164
<FullSize inactive={this.state.resizing}>
164165
<Preview
165166
sandboxId={sandbox.id}
167+
initialPath={sandbox.initialPath}
166168
bundle={sandbox.dependencyBundle}
167169
fetchBundle={sandboxActions.fetchDependenciesBundle}
168170
module={currentModule}

src/app/pages/Sandbox/Editor/Workspace/Files/DirectoryEntry/index.js

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,19 @@ import type { Module, Directory, ModuleError } from 'common/types';
99
import sandboxActionCreators from 'app/store/entities/sandboxes/actions';
1010
import { validateTitle } from 'app/store/entities//sandboxes/modules/validator';
1111
import contextMenuActionCreators from 'app/store/context-menu/actions';
12+
import { getModuleParents } from 'app/store/entities/sandboxes/modules/selectors';
1213

1314
import Entry from './Entry';
1415
import DirectoryChildren from './DirectoryChildren';
1516

16-
const EntryContainer = styled.div`
17-
position: relative;
18-
`;
17+
const EntryContainer = styled.div`position: relative;`;
1918

2019
const Overlay = styled.div`
2120
position: absolute;
22-
top: 0; bottom: 0; left: 0; right: 0;
21+
top: 0;
22+
bottom: 0;
23+
left: 0;
24+
right: 0;
2325
background-color: rgba(0, 0, 0, 0.3);
2426
display: ${props => (props.isOver ? 'block' : 'none')};
2527
`;
@@ -61,9 +63,18 @@ class DirectoryEntry extends React.PureComponent {
6163
constructor(props) {
6264
super(props);
6365

66+
const { id, modules, directories, currentModuleId } = this.props;
67+
const currentModuleParents = getModuleParents(
68+
modules,
69+
directories,
70+
currentModuleId,
71+
);
72+
73+
const isParentOfModule = currentModuleParents.includes(id);
74+
6475
this.state = {
6576
creating: '',
66-
open: props.root,
77+
open: props.root || isParentOfModule,
6778
};
6879
}
6980

src/app/pages/Sandbox/Editor/Workspace/Files/index.js

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import { DragDropContext } from 'react-dnd';
99
import {
1010
modulesFromSandboxSelector,
1111
findMainModule,
12+
findCurrentModule,
1213
} from 'app/store/entities/sandboxes/modules/selectors';
1314
import { directoriesFromSandboxSelector } from 'app/store/entities/sandboxes/directories/selectors';
1415

@@ -47,12 +48,15 @@ class Files extends React.PureComponent {
4748

4849
render() {
4950
const { sandbox, modules, directories } = this.props;
51+
if (sandbox == null) return null;
5052

5153
const mainModule = findMainModule(modules);
52-
53-
const { currentModule } = sandbox;
54-
55-
if (sandbox == null) return null;
54+
const { currentModule: currentModuleId } = sandbox;
55+
const currentModule = findCurrentModule(
56+
modules,
57+
currentModuleId,
58+
mainModule,
59+
);
5660

5761
return (
5862
<DirectoryEntry
@@ -62,8 +66,7 @@ class Files extends React.PureComponent {
6266
modules={sortBy(modules, 'title')}
6367
directories={sortBy(directories, 'title')}
6468
isInProjectView={sandbox.isInProjectView}
65-
// $FlowIssue
66-
currentModuleId={currentModule || mainModule.id}
69+
currentModuleId={currentModule.id}
6770
errors={sandbox.errors}
6871
id={null}
6972
shortid={null}

src/app/pages/Sandbox/Editor/Workspace/WorkspaceItem.js

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,9 @@ const ChildContainer = styled.div`
1111
overflow: ${props => (props.open ? 'inherit' : 'hidden')};
1212
height: ${props => (props.open ? '100%' : 0)};
1313
14-
${({ disabled }) => disabled && `
14+
${({ disabled }) =>
15+
disabled &&
16+
`
1517
pointer-events: none;
1618
1719
&:after {
@@ -29,7 +31,7 @@ const ChildContainer = styled.div`
2931
right: 0;
3032
background-color: rgba(0, 0, 0, 0.4);
3133
}
32-
`}
34+
`};
3335
`;
3436

3537
const ItemHeader = styled.div`
@@ -86,7 +88,9 @@ export default class WorkspaceItem extends React.PureComponent {
8688
return (
8789
<div>
8890
<ItemHeader onClick={this.toggleOpen}>
89-
<Title>{title}</Title>
91+
<Title>
92+
{title}
93+
</Title>
9094
<ExpandIconContainer open={open} />
9195
</ItemHeader>
9296
<ChildContainer disabled={disabled} open={open}>

0 commit comments

Comments
 (0)