Skip to content

Commit

Permalink
fix: refresh state in playground by debounce (#201)
Browse files Browse the repository at this point in the history
  • Loading branch information
magicmatatjahu authored Dec 8, 2020
1 parent de3a411 commit ba4df03
Show file tree
Hide file tree
Showing 5 changed files with 85 additions and 47 deletions.
68 changes: 39 additions & 29 deletions playground/src/Playground.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,40 +14,48 @@ import {
AsyncApiWrapper,
} from './components';

import { defaultConfig, parse } from './common';
import { defaultConfig, parse, debounce } from './common';
import * as specs from './specs';

const defaultSchema = specs.streetlights;

interface State {
schema: string;
config: string;
schemaFromEditor: string;
schemaFromExternalResource: string;
configFromEditor: string;
refreshing: boolean;
}

class Playground extends Component<{}, State> {
updateSchemaFn: (value: string) => void;
updateConfigFn: (value: string) => void;

state = {
schema: defaultSchema,
config: defaultConfig,
schemaFromEditor: defaultSchema,
schemaFromExternalResource: '',
configFromEditor: defaultConfig,
refreshing: false,
};

constructor(props: any) {
super(props);
this.updateSchemaFn = debounce(
this.updateSchema,
750,
this.startRefreshing,
this.stopRefreshing,
);
this.updateConfigFn = debounce(
this.updateConfig,
750,
this.startRefreshing,
this.stopRefreshing,
);
}

render() {
const {
schema,
config = defaultConfig,
schemaFromEditor,
schemaFromExternalResource,
configFromEditor,
} = this.state;

const parsedConfig = config
? parse<ConfigInterface>(config)
: parse<ConfigInterface>(defaultConfig);
const { schema, config, schemaFromExternalResource } = this.state;
const parsedConfig = parse<ConfigInterface>(config || defaultConfig);

return (
<PlaygroundWrapper>
Expand All @@ -64,18 +72,18 @@ class Playground extends Component<{}, State> {
/>
<CodeEditorComponent
key="Schema"
code={schemaFromEditor}
code={schema}
externalResource={schemaFromExternalResource}
parentCallback={this.updateSchema}
parentCallback={this.updateSchemaFn}
mode="text/yaml"
/>
</>
</Tab>
<Tab title="Configuration" key="Configuration">
<CodeEditorComponent
key="Configuration"
code={configFromEditor}
parentCallback={this.updateConfig}
code={config}
parentCallback={this.updateConfigFn}
/>
</Tab>
</Tabs>
Expand All @@ -89,27 +97,29 @@ class Playground extends Component<{}, State> {
}

private updateSchema = (schema: string) => {
this.setState({ schemaFromEditor: schema });
this.setState({ schema: schema });
};

private updateSchemaFromExternalResource = (schema: string) => {
this.setState({ schemaFromExternalResource: schema });
};

private updateConfig = (config: string) => {
this.setState({ configFromEditor: config });
this.setState({ config: config });
};

private startRefreshing = (): void => {
setTimeout(() => {
this.setState({ refreshing: true });
}, 500);
};

private refreshState = () => {
const { schemaFromEditor, configFromEditor } = this.state;
this.setState({
schema: schemaFromEditor,
config: configFromEditor,
});
private stopRefreshing = (): void => {
this.setState({ refreshing: false });
};

private renderAdditionalHeaderContent = () => (
<RefreshIcon onClick={this.refreshState}>{'\uE00A'}</RefreshIcon>
<RefreshIcon show={this.state.refreshing}>{'\uE00A'}</RefreshIcon>
);
}

Expand Down
2 changes: 1 addition & 1 deletion playground/src/common/defaultConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ export const defaultConfig: string = `{
"security": false,
"messages": true,
"schemas": true,
"channels": true,
"channels": true
},
"showErrors": true,
"disableDefaultTheme": false
Expand Down
18 changes: 18 additions & 0 deletions playground/src/common/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,21 @@ export const fetchSchema = async (link: string): Promise<any> => {
function handleResponse(response: any) {
return response.text().then((data: string) => data);
}

export function debounce<T>(
func: Function,
wait: number,
onStart: () => void,
onCancel: () => void,
): () => any {
let timeout: number | undefined;
return function(...args: any[]) {
if (timeout) clearTimeout(timeout);
onStart();
timeout = setTimeout(() => {
timeout = undefined;
func(...args);
onCancel();
}, wait || 1000);
};
}
2 changes: 1 addition & 1 deletion playground/src/components/CodeEditorComponent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ class CodeEditorComponent extends Component<Props, State> {
code: this.props.code,
};

componentDidUpdate(nextProps: Props, nextState: State) {
componentDidUpdate(nextProps: Props) {
const { externalResource } = this.props;
if (nextProps.externalResource !== externalResource) {
this.setState({ code: externalResource! });
Expand Down
42 changes: 26 additions & 16 deletions playground/src/components/styled.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,9 +84,6 @@ export const ContentWrapper = styled.div`

export const CodeEditorsWrapper = styled.div`
width: 40%;
height: calc(100vh - 50px);
min-height: calc(100vh - 50px);
overflow: auto;
background: rgb(38, 50, 56);
`;

Expand Down Expand Up @@ -123,7 +120,7 @@ export const CodeEditorWrapper = styled.div`
export const TabsHeader = styled.ul`
list-style: none;
padding: 0;
margin: 0 5px;
margin: 0 5px 15px;
display: flex;
justify-items: flex-start;
flex-flow: row nowrap;
Expand All @@ -136,27 +133,40 @@ export const TabsAdditionalHeaderContent = styled.li`
padding: 19px 15px;
`;

export const RefreshIcon = styled.div`
interface RefreshIconProps {
show?: boolean;
}

export const RefreshIcon = styled.div<RefreshIconProps>`
font-family: 'SAP-Icons';
font-weight: 700;
color: #f77669;
transition: 0.2s color linear;
cursor: pointer;
&:hover {
color: #c3e88d;
transition: 0.2s all linear;
opacity: ${props => (props.show ? '1' : '0')};
animation-name: spin;
animation-duration: 1.5s;
animation-iteration-count: infinite;
animation-timing-function: linear;
@keyframes spin {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
`;

interface TabsContentProps {
margin?: string;
}

export const TabsContent = styled.div<TabsContentProps>`
margin: ${props => (props.margin ? props.margin : '20px')};
export const TabsContent = styled.div`
margin: 0;
padding: 0 20px;
font-size: 14px;
color: #515559;
line-height: 1.57;
overflow: auto;
height: calc(100vh - 117px);
min-height: calc(100vh - 117px);
`;

export const TabWrapper = styled.li``;
Expand Down

0 comments on commit ba4df03

Please sign in to comment.