Skip to content

Commit c809fd8

Browse files
committed
ui: load snippet
1 parent d6b3b32 commit c809fd8

File tree

6 files changed

+57
-21
lines changed

6 files changed

+57
-21
lines changed

web/src/App.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,10 @@ function App() {
2020
<Fabric className="App">
2121
<Router>
2222
<Switch>
23-
<Route path="/" component={Playground} />
23+
<Route
24+
path="/(snippet)?/:snippetID?"
25+
component={Playground}
26+
/>
2427
</Switch>
2528
</Router>
2629
</Fabric>

web/src/Playground.tsx

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,20 @@ import { Header } from './Header';
33
import CodeEditor from './editor/CodeEditor';
44
import './Playground.css';
55
import Preview from './Preview';
6+
import { useParams } from "react-router-dom";
7+
import {newSnippetLoadDispatcher} from "./store";
8+
import { connect } from 'react-redux';
69

7-
export default class Playground extends React.Component{
8-
render() {
9-
return <div className="playground">
10-
<Header />
11-
<CodeEditor />
12-
<Preview />
13-
</div>;
10+
const Playground = connect()(function (props) {
11+
const {snippetID} = useParams();
12+
if (snippetID) {
13+
props.dispatch(newSnippetLoadDispatcher(snippetID));
1414
}
15-
}
15+
return <div className="playground">
16+
<Header />
17+
<CodeEditor />
18+
<Preview />
19+
</div>;
20+
});
21+
22+
export default Playground;

web/src/Preview.tsx

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -26,20 +26,15 @@ export default class Preview extends React.Component<PreviewProps> {
2626
}
2727
}
2828

29-
get progressStyles() {
29+
get progressClass() {
3030
return this.props.loading ? 'app-preview__progress' : 'app-preview__progress--hidden';
31-
// return {
32-
// display: this.props.loading ? 'block' : 'none',
33-
// position: 'relative',
34-
// bottom: '8px',
35-
// }
3631
}
3732

3833
render() {
3934
let content;
4035
if (this.props.lastError) {
4136
content = <MessageBar messageBarType={MessageBarType.error} isMultiline={true}>
42-
<b className='app-preview__label'>Build failed</b>
37+
<b className='app-preview__label'>Error</b>
4338
<pre className='app-preview__errors'>
4439
{this.props.lastError}
4540
</pre>
@@ -58,7 +53,7 @@ export default class Preview extends React.Component<PreviewProps> {
5853
}
5954

6055
return <div className="app-preview" style={this.styles}>
61-
<ProgressIndicator className={this.progressStyles}/>
56+
<ProgressIndicator className={this.progressClass}/>
6257
<div className='app-preview__content'>
6358
{content}
6459
</div>

web/src/services/api.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,11 @@ const apiAddress = process.env['REACT_APP_LANG_SERVER'] ?? window.location.origi
66

77
let axiosClient = axios.default.create({baseURL: `${apiAddress}/api`});
88

9+
export interface Snippet {
10+
fileName: string
11+
code: string
12+
}
13+
914
export interface EvalEvent {
1015
Message: string
1116
Kind: string
@@ -22,6 +27,7 @@ export interface IAPIClient {
2227
getSuggestions(query: {packageName?: string, value?:string}): Promise<monaco.languages.CompletionList>
2328
evaluateCode(code: string): Promise<CompilerResponse>
2429
formatCode(code: string): Promise<CompilerResponse>
30+
getSnippet(id: string): Promise<Snippet>
2531
}
2632

2733
class Client implements IAPIClient {
@@ -44,6 +50,10 @@ class Client implements IAPIClient {
4450
return this.post<CompilerResponse>('/format', code);
4551
}
4652

53+
async getSnippet(id: string): Promise<Snippet> {
54+
return this.get<Snippet>(`/snippet/${id}`);
55+
}
56+
4757
private async get<T>(uri: string): Promise<T> {
4858
try {
4959
const resp = await this.client.get<T>(uri);

web/src/store/dispatch.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import {
99
import {State} from "./state";
1010
import client from '../services/api';
1111
import config from '../services/config';
12+
import {DEMO_CODE} from '../editor/props';
1213

1314
type StateProvider = () => State
1415
type DispatchFn = (Action) => any
@@ -35,6 +36,24 @@ export function newImportFileDispatcher(f: File): Dispatcher {
3536
};
3637
}
3738

39+
export function newSnippetLoadDispatcher(snippetID: string): Dispatcher {
40+
return async(dispatch: DispatchFn, getState: StateProvider) => {
41+
console.log('load snippet %s', snippetID);
42+
if (!snippetID) {
43+
dispatch(newImportFileAction('prog.go', DEMO_CODE));
44+
return;
45+
}
46+
47+
try {
48+
const resp = await client.getSnippet(snippetID);
49+
const { fileName, code } = resp;
50+
dispatch(newImportFileAction(fileName, code));
51+
} catch(err) {
52+
dispatch(newBuildErrorAction(err.message));
53+
}
54+
}
55+
}
56+
3857
export const saveFileDispatcher: Dispatcher =
3958
(_: DispatchFn, getState: StateProvider) => {
4059
try {

web/src/store/reducers.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ import { connectRouter } from 'connected-react-router';
22
import { combineReducers } from 'redux';
33

44
import {Action, ActionType, FileImportArgs} from './actions';
5-
import {DEMO_CODE} from '../editor/props';
65
import {EditorState, SettingsState, State, StatusState} from './state';
76
import { CompilerResponse } from '../services/api';
87
import localConfig from '../services/config'
@@ -29,7 +28,7 @@ const reducers = {
2928

3029
return s;
3130
},
32-
}, {fileName: 'main.go', code: DEMO_CODE}),
31+
}, {fileName: 'main.go', code: ''}),
3332
status: mapByAction<StatusState>({
3433
[ActionType.COMPILE_RESULT]: (s: StatusState, a: Action<CompilerResponse>) => {
3534
return {
@@ -38,6 +37,9 @@ const reducers = {
3837
events: a.payload.events,
3938
}
4039
},
40+
[ActionType.IMPORT_FILE]: (s: StatusState, a: Action<string>) => {
41+
return {...s, loading: false}
42+
},
4143
[ActionType.COMPILE_FAIL]: (s: StatusState, a: Action<string>) => {
4244
return {...s, loading: false, lastError: a.payload}
4345
},
@@ -56,11 +58,11 @@ const reducers = {
5658

5759
export const getInitialState = (): State => ({
5860
status: {
59-
loading: false
61+
loading: true
6062
},
6163
editor: {
6264
fileName: 'prog.go',
63-
code: DEMO_CODE
65+
code: ''
6466
},
6567
settings: {
6668
darkMode: localConfig.darkThemeEnabled

0 commit comments

Comments
 (0)