提交 6e810e6b 编写于 作者: J Jason Park

Add meta tags and refactor code

上级 950f5d3a
# Algorithm Visualizer # Algorithm Visualizer
[![Join the chat at https://gitter.im/parkjs814/AlgorithmVisualizer](https://badges.gitter.im/parkjs814/AlgorithmVisualizer.svg)](https://gitter.im/parkjs814/AlgorithmVisualizer?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) Write down your algorithm to be visualized.
[![OpenCollective](https://opencollective.com/algorithmvisualizer/backers/badge.svg)](#backers) \ No newline at end of file
[![OpenCollective](https://opencollective.com/algorithmvisualizer/sponsors/badge.svg)](#sponsors)
http://parkjs814.github.io/AlgorithmVisualizer
![Algorithm Visualizer](http://i.giphy.com/3o6EhJFgsyShX6MHeM.gif)
### Contributing
We encourage you to check out [**Wiki**](https://github.com/parkjs814/AlgorithmVisualizer/wiki) before you get started.
If in need of any help, join our [Gitter](https://gitter.im/parkjs814/AlgorithmVisualizer?utm_source=share-link&utm_medium=link&utm_campaign=share-link) chatroom!
Special thanks to our [Top Contributors](CONTRIBUTORS.md)!
### Backers
Support us with a monthly donation and help us continue our activities. [[Become a backer](https://opencollective.com/algorithmvisualizer#backer)]
<a href="https://opencollective.com/algorithmvisualizer/backer/0/website" target="_blank"><img src="https://opencollective.com/algorithmvisualizer/backer/0/avatar.svg"></a>
<a href="https://opencollective.com/algorithmvisualizer/backer/1/website" target="_blank"><img src="https://opencollective.com/algorithmvisualizer/backer/1/avatar.svg"></a>
<a href="https://opencollective.com/algorithmvisualizer/backer/2/website" target="_blank"><img src="https://opencollective.com/algorithmvisualizer/backer/2/avatar.svg"></a>
<a href="https://opencollective.com/algorithmvisualizer/backer/3/website" target="_blank"><img src="https://opencollective.com/algorithmvisualizer/backer/3/avatar.svg"></a>
<a href="https://opencollective.com/algorithmvisualizer/backer/4/website" target="_blank"><img src="https://opencollective.com/algorithmvisualizer/backer/4/avatar.svg"></a>
<a href="https://opencollective.com/algorithmvisualizer/backer/5/website" target="_blank"><img src="https://opencollective.com/algorithmvisualizer/backer/5/avatar.svg"></a>
<a href="https://opencollective.com/algorithmvisualizer/backer/6/website" target="_blank"><img src="https://opencollective.com/algorithmvisualizer/backer/6/avatar.svg"></a>
<a href="https://opencollective.com/algorithmvisualizer/backer/7/website" target="_blank"><img src="https://opencollective.com/algorithmvisualizer/backer/7/avatar.svg"></a>
<a href="https://opencollective.com/algorithmvisualizer/backer/8/website" target="_blank"><img src="https://opencollective.com/algorithmvisualizer/backer/8/avatar.svg"></a>
<a href="https://opencollective.com/algorithmvisualizer/backer/9/website" target="_blank"><img src="https://opencollective.com/algorithmvisualizer/backer/9/avatar.svg"></a>
<a href="https://opencollective.com/algorithmvisualizer/backer/10/website" target="_blank"><img src="https://opencollective.com/algorithmvisualizer/backer/10/avatar.svg"></a>
<a href="https://opencollective.com/algorithmvisualizer/backer/11/website" target="_blank"><img src="https://opencollective.com/algorithmvisualizer/backer/11/avatar.svg"></a>
<a href="https://opencollective.com/algorithmvisualizer/backer/12/website" target="_blank"><img src="https://opencollective.com/algorithmvisualizer/backer/12/avatar.svg"></a>
<a href="https://opencollective.com/algorithmvisualizer/backer/13/website" target="_blank"><img src="https://opencollective.com/algorithmvisualizer/backer/13/avatar.svg"></a>
<a href="https://opencollective.com/algorithmvisualizer/backer/14/website" target="_blank"><img src="https://opencollective.com/algorithmvisualizer/backer/14/avatar.svg"></a>
<a href="https://opencollective.com/algorithmvisualizer/backer/15/website" target="_blank"><img src="https://opencollective.com/algorithmvisualizer/backer/15/avatar.svg"></a>
<a href="https://opencollective.com/algorithmvisualizer/backer/16/website" target="_blank"><img src="https://opencollective.com/algorithmvisualizer/backer/16/avatar.svg"></a>
<a href="https://opencollective.com/algorithmvisualizer/backer/17/website" target="_blank"><img src="https://opencollective.com/algorithmvisualizer/backer/17/avatar.svg"></a>
<a href="https://opencollective.com/algorithmvisualizer/backer/18/website" target="_blank"><img src="https://opencollective.com/algorithmvisualizer/backer/18/avatar.svg"></a>
<a href="https://opencollective.com/algorithmvisualizer/backer/19/website" target="_blank"><img src="https://opencollective.com/algorithmvisualizer/backer/19/avatar.svg"></a>
<a href="https://opencollective.com/algorithmvisualizer/backer/20/website" target="_blank"><img src="https://opencollective.com/algorithmvisualizer/backer/20/avatar.svg"></a>
<a href="https://opencollective.com/algorithmvisualizer/backer/21/website" target="_blank"><img src="https://opencollective.com/algorithmvisualizer/backer/21/avatar.svg"></a>
<a href="https://opencollective.com/algorithmvisualizer/backer/22/website" target="_blank"><img src="https://opencollective.com/algorithmvisualizer/backer/22/avatar.svg"></a>
<a href="https://opencollective.com/algorithmvisualizer/backer/23/website" target="_blank"><img src="https://opencollective.com/algorithmvisualizer/backer/23/avatar.svg"></a>
<a href="https://opencollective.com/algorithmvisualizer/backer/24/website" target="_blank"><img src="https://opencollective.com/algorithmvisualizer/backer/24/avatar.svg"></a>
<a href="https://opencollective.com/algorithmvisualizer/backer/25/website" target="_blank"><img src="https://opencollective.com/algorithmvisualizer/backer/25/avatar.svg"></a>
<a href="https://opencollective.com/algorithmvisualizer/backer/26/website" target="_blank"><img src="https://opencollective.com/algorithmvisualizer/backer/26/avatar.svg"></a>
<a href="https://opencollective.com/algorithmvisualizer/backer/27/website" target="_blank"><img src="https://opencollective.com/algorithmvisualizer/backer/27/avatar.svg"></a>
<a href="https://opencollective.com/algorithmvisualizer/backer/28/website" target="_blank"><img src="https://opencollective.com/algorithmvisualizer/backer/28/avatar.svg"></a>
<a href="https://opencollective.com/algorithmvisualizer/backer/29/website" target="_blank"><img src="https://opencollective.com/algorithmvisualizer/backer/29/avatar.svg"></a>
### Sponsors
Become a sponsor and get your logo on our README on Github with a link to your site. [[Become a sponsor](https://opencollective.com/algorithmvisualizer#sponsor)]
<a href="https://opencollective.com/algorithmvisualizer/sponsor/0/website" target="_blank"><img src="https://opencollective.com/algorithmvisualizer/sponsor/0/avatar.svg"></a>
<a href="https://opencollective.com/algorithmvisualizer/sponsor/1/website" target="_blank"><img src="https://opencollective.com/algorithmvisualizer/sponsor/1/avatar.svg"></a>
<a href="https://opencollective.com/algorithmvisualizer/sponsor/2/website" target="_blank"><img src="https://opencollective.com/algorithmvisualizer/sponsor/2/avatar.svg"></a>
<a href="https://opencollective.com/algorithmvisualizer/sponsor/3/website" target="_blank"><img src="https://opencollective.com/algorithmvisualizer/sponsor/3/avatar.svg"></a>
<a href="https://opencollective.com/algorithmvisualizer/sponsor/4/website" target="_blank"><img src="https://opencollective.com/algorithmvisualizer/sponsor/4/avatar.svg"></a>
<a href="https://opencollective.com/algorithmvisualizer/sponsor/5/website" target="_blank"><img src="https://opencollective.com/algorithmvisualizer/sponsor/5/avatar.svg"></a>
<a href="https://opencollective.com/algorithmvisualizer/sponsor/6/website" target="_blank"><img src="https://opencollective.com/algorithmvisualizer/sponsor/6/avatar.svg"></a>
<a href="https://opencollective.com/algorithmvisualizer/sponsor/7/website" target="_blank"><img src="https://opencollective.com/algorithmvisualizer/sponsor/7/avatar.svg"></a>
<a href="https://opencollective.com/algorithmvisualizer/sponsor/8/website" target="_blank"><img src="https://opencollective.com/algorithmvisualizer/sponsor/8/avatar.svg"></a>
<a href="https://opencollective.com/algorithmvisualizer/sponsor/9/website" target="_blank"><img src="https://opencollective.com/algorithmvisualizer/sponsor/9/avatar.svg"></a>
<a href="https://opencollective.com/algorithmvisualizer/sponsor/10/website" target="_blank"><img src="https://opencollective.com/algorithmvisualizer/sponsor/10/avatar.svg"></a>
<a href="https://opencollective.com/algorithmvisualizer/sponsor/11/website" target="_blank"><img src="https://opencollective.com/algorithmvisualizer/sponsor/11/avatar.svg"></a>
<a href="https://opencollective.com/algorithmvisualizer/sponsor/12/website" target="_blank"><img src="https://opencollective.com/algorithmvisualizer/sponsor/12/avatar.svg"></a>
<a href="https://opencollective.com/algorithmvisualizer/sponsor/13/website" target="_blank"><img src="https://opencollective.com/algorithmvisualizer/sponsor/13/avatar.svg"></a>
<a href="https://opencollective.com/algorithmvisualizer/sponsor/14/website" target="_blank"><img src="https://opencollective.com/algorithmvisualizer/sponsor/14/avatar.svg"></a>
<a href="https://opencollective.com/algorithmvisualizer/sponsor/15/website" target="_blank"><img src="https://opencollective.com/algorithmvisualizer/sponsor/15/avatar.svg"></a>
<a href="https://opencollective.com/algorithmvisualizer/sponsor/16/website" target="_blank"><img src="https://opencollective.com/algorithmvisualizer/sponsor/16/avatar.svg"></a>
<a href="https://opencollective.com/algorithmvisualizer/sponsor/17/website" target="_blank"><img src="https://opencollective.com/algorithmvisualizer/sponsor/17/avatar.svg"></a>
<a href="https://opencollective.com/algorithmvisualizer/sponsor/18/website" target="_blank"><img src="https://opencollective.com/algorithmvisualizer/sponsor/18/avatar.svg"></a>
<a href="https://opencollective.com/algorithmvisualizer/sponsor/19/website" target="_blank"><img src="https://opencollective.com/algorithmvisualizer/sponsor/19/avatar.svg"></a>
<a href="https://opencollective.com/algorithmvisualizer/sponsor/20/website" target="_blank"><img src="https://opencollective.com/algorithmvisualizer/sponsor/20/avatar.svg"></a>
<a href="https://opencollective.com/algorithmvisualizer/sponsor/21/website" target="_blank"><img src="https://opencollective.com/algorithmvisualizer/sponsor/21/avatar.svg"></a>
<a href="https://opencollective.com/algorithmvisualizer/sponsor/22/website" target="_blank"><img src="https://opencollective.com/algorithmvisualizer/sponsor/22/avatar.svg"></a>
<a href="https://opencollective.com/algorithmvisualizer/sponsor/23/website" target="_blank"><img src="https://opencollective.com/algorithmvisualizer/sponsor/23/avatar.svg"></a>
<a href="https://opencollective.com/algorithmvisualizer/sponsor/24/website" target="_blank"><img src="https://opencollective.com/algorithmvisualizer/sponsor/24/avatar.svg"></a>
<a href="https://opencollective.com/algorithmvisualizer/sponsor/25/website" target="_blank"><img src="https://opencollective.com/algorithmvisualizer/sponsor/25/avatar.svg"></a>
<a href="https://opencollective.com/algorithmvisualizer/sponsor/26/website" target="_blank"><img src="https://opencollective.com/algorithmvisualizer/sponsor/26/avatar.svg"></a>
<a href="https://opencollective.com/algorithmvisualizer/sponsor/27/website" target="_blank"><img src="https://opencollective.com/algorithmvisualizer/sponsor/27/avatar.svg"></a>
<a href="https://opencollective.com/algorithmvisualizer/sponsor/28/website" target="_blank"><img src="https://opencollective.com/algorithmvisualizer/sponsor/28/avatar.svg"></a>
<a href="https://opencollective.com/algorithmvisualizer/sponsor/29/website" target="_blank"><img src="https://opencollective.com/algorithmvisualizer/sponsor/29/avatar.svg"></a>
文件已添加
文件已添加
...@@ -15,9 +15,16 @@ const languages = [{ ...@@ -15,9 +15,16 @@ const languages = [{
ext: 'py', ext: 'py',
mode: 'python', mode: 'python',
}]; }];
const exts = languages.map(language => language.ext); const exts = languages.map(language => language.ext);
const us = {
login: 'algorithm-visualizer',
avatar_url: 'https://github.com/algorithm-visualizer.png',
};
export { export {
languages, languages,
exts, exts,
us,
}; };
...@@ -2,6 +2,7 @@ import React from 'react'; ...@@ -2,6 +2,7 @@ import React from 'react';
import Cookies from 'js-cookie'; import Cookies from 'js-cookie';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import Promise from 'bluebird'; import Promise from 'bluebird';
import { Helmet } from 'react-helmet';
import AutosizeInput from 'react-input-autosize'; import AutosizeInput from 'react-input-autosize';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import faPlus from '@fortawesome/fontawesome-free-solid/faPlus'; import faPlus from '@fortawesome/fontawesome-free-solid/faPlus';
...@@ -21,7 +22,7 @@ import { CategoryApi, GitHubApi } from '/apis'; ...@@ -21,7 +22,7 @@ import { CategoryApi, GitHubApi } from '/apis';
import { tracerManager } from '/core'; import { tracerManager } from '/core';
import { actions } from '/reducers'; import { actions } from '/reducers';
import { extension, refineGist } from '/common/util'; import { extension, refineGist } from '/common/util';
import { exts } from '/common/config'; import { exts, us } from '/common/config';
import README from '/static/README.md'; import README from '/static/README.md';
import styles from './stylesheet.scss'; import styles from './stylesheet.scss';
...@@ -127,7 +128,7 @@ class App extends React.Component { ...@@ -127,7 +128,7 @@ class App extends React.Component {
loadAlgorithm({ categoryKey, algorithmKey, gistId }) { loadAlgorithm({ categoryKey, algorithmKey, gistId }) {
const { ext } = this.props.env; const { ext } = this.props.env;
let fetchPromise = Promise.reject(); let fetchPromise = null;
if (categoryKey && algorithmKey) { if (categoryKey && algorithmKey) {
fetchPromise = CategoryApi.getAlgorithm(categoryKey, algorithmKey) fetchPromise = CategoryApi.getAlgorithm(categoryKey, algorithmKey)
.then(({ algorithm }) => algorithm); .then(({ algorithm }) => algorithm);
...@@ -136,7 +137,7 @@ class App extends React.Component { ...@@ -136,7 +137,7 @@ class App extends React.Component {
titles: ['Scratch Paper', 'Untitled'], titles: ['Scratch Paper', 'Untitled'],
files: [{ files: [{
name: 'README.md', name: 'README.md',
content: '# README', content: `# Scratch Paper\nVisualize your own algorithm here!\n\n[Tracer API](https://github.com/algorithm-visualizer/tracers/wiki)`,
contributors: [], contributors: [],
}, { }, {
name: `code.${ext}`, name: `code.${ext}`,
...@@ -146,16 +147,15 @@ class App extends React.Component { ...@@ -146,16 +147,15 @@ class App extends React.Component {
}); });
} else if (gistId) { } else if (gistId) {
fetchPromise = GitHubApi.getGist(gistId, { timestamp: Date.now() }).then(refineGist); fetchPromise = GitHubApi.getGist(gistId, { timestamp: Date.now() }).then(refineGist);
} else {
fetchPromise = Promise.reject(new Error());
} }
fetchPromise fetchPromise
.then(algorithm => this.props.setCurrent(categoryKey, algorithmKey, gistId, algorithm.titles, algorithm.files)) .then(algorithm => this.props.setCurrent(categoryKey, algorithmKey, gistId, algorithm.titles, algorithm.files))
.catch(() => this.props.setCurrent(undefined, undefined, undefined, ['Algorithm Visualizer'], [{ .catch(() => this.props.setCurrent(undefined, undefined, undefined, ['Algorithm Visualizer'], [{
name: 'README.md', name: 'README.md',
content: README, content: README,
contributors: [{ contributors: [us],
login: 'algorithm-visualizer',
avatar_url: 'https://github.com/algorithm-visualizer.png',
}],
}])) }]))
.finally(() => { .finally(() => {
const { files } = this.props.current; const { files } = this.props.current;
...@@ -214,7 +214,13 @@ class App extends React.Component { ...@@ -214,7 +214,13 @@ class App extends React.Component {
const { navigatorOpened, workspaceWeights, viewerTabIndex, editorTabIndex } = this.state; const { navigatorOpened, workspaceWeights, viewerTabIndex, editorTabIndex } = this.state;
const { titles, files } = this.props.current; const { titles, files } = this.props.current;
const readmeFile = files.find(file => file.name === 'README.md'); const readmeFile = files.find(file => file.name === 'README.md') || {
name: 'README.md',
content: `# ${titles[1]}\nREADME.md not found`,
contributors: [us],
};
const groups = /^\s*# .*\n+([^\n]+)/.exec(readmeFile.content);
const description = groups && groups[1] || '';
const editorTitles = files.map(file => file.name); const editorTitles = files.map(file => file.name);
if (files[editorTabIndex]) { if (files[editorTabIndex]) {
...@@ -229,6 +235,10 @@ class App extends React.Component { ...@@ -229,6 +235,10 @@ class App extends React.Component {
return ( return (
<div className={styles.app}> <div className={styles.app}>
<Helmet>
<title>{titles.join(' - ')}</title>
<meta name="description" content={description} />
</Helmet>
<Header className={styles.header} onClickTitleBar={() => this.toggleNavigatorOpened()} <Header className={styles.header} onClickTitleBar={() => this.toggleNavigatorOpened()}
navigatorOpened={navigatorOpened} loadScratchPapers={() => this.loadScratchPapers()} navigatorOpened={navigatorOpened} loadScratchPapers={() => this.loadScratchPapers()}
loadAlgorithm={params => this.loadAlgorithm(params)} loadAlgorithm={params => this.loadAlgorithm(params)}
...@@ -239,7 +249,7 @@ class App extends React.Component { ...@@ -239,7 +249,7 @@ class App extends React.Component {
<Navigator loadAlgorithm={params => this.loadAlgorithm(params)} /> <Navigator loadAlgorithm={params => this.loadAlgorithm(params)} />
<TabContainer titles={['Description', 'Visualization']} tabIndex={viewerTabIndex} <TabContainer titles={['Description', 'Visualization']} tabIndex={viewerTabIndex}
onChangeTabIndex={tabIndex => this.handleChangeViewerTabIndex(tabIndex)}> onChangeTabIndex={tabIndex => this.handleChangeViewerTabIndex(tabIndex)}>
<MarkdownViewer source={readmeFile ? readmeFile.content : 'README.md not found'} /> <MarkdownViewer source={readmeFile.content} />
<VisualizationViewer /> <VisualizationViewer />
</TabContainer> </TabContainer>
<TabContainer className={styles.editor_tab_container} titles={editorTitles} tabIndex={editorTabIndex} <TabContainer className={styles.editor_tab_container} titles={editorTitles} tabIndex={editorTabIndex}
......
...@@ -13,6 +13,12 @@ class Button extends React.Component { ...@@ -13,6 +13,12 @@ class Button extends React.Component {
this.state = { this.state = {
confirming: false, confirming: false,
}; };
this.timeout = null;
}
componentWillUnmount() {
if (this.timeout) window.clearTimeout(this.timeout);
} }
render() { render() {
...@@ -29,7 +35,8 @@ class Button extends React.Component { ...@@ -29,7 +35,8 @@ class Button extends React.Component {
href = null; href = null;
onClick = () => { onClick = () => {
this.setState({ confirming: true }); this.setState({ confirming: true });
window.setTimeout(() => { this.timeout = window.setTimeout(() => {
this.timeout = null;
this.setState({ confirming: false }); this.setState({ confirming: false });
}, 2000); }, 2000);
}; };
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
display: flex; display: flex;
flex-direction: column-reverse; flex-direction: column-reverse;
padding: 16px; padding: 16px;
pointer-events: none;
} }
.toast { .toast {
...@@ -14,6 +15,7 @@ ...@@ -14,6 +15,7 @@
margin: 8px; margin: 8px;
font-size: $font-size-large; font-size: $font-size-large;
white-space: pre-line; white-space: pre-line;
pointer-events: auto;
&.success { &.success {
border-color: rgb(0, 150, 0); border-color: rgb(0, 150, 0);
......
...@@ -169,6 +169,8 @@ class TracerManager { ...@@ -169,6 +169,8 @@ class TracerManager {
.then(traces => { .then(traces => {
this.reset(traces); this.reset(traces);
this.applyTraceChunk(); this.applyTraceChunk();
})
.catch(error => {
}); });
} }
......
...@@ -5,12 +5,17 @@ ...@@ -5,12 +5,17 @@
"display": "standalone", "display": "standalone",
"theme_color": "#393939", "theme_color": "#393939",
"background_color": "#393939", "background_color": "#393939",
"description": "Algorithm Visualizer", "description": "Write down your algorithm to be visualized.",
"icons": [ "icons": [
{ {
"src": "img/favicon.png", "src": "/img/favicon.png",
"sizes": "256x256", "sizes": "256x256",
"type": "image/png" "type": "image/png"
},
{
"src": "/img/icon.png",
"sizes": "1024x1024",
"type": "image/png"
} }
], ],
"related_applications": [ "related_applications": [
......
...@@ -13,15 +13,10 @@ ...@@ -13,15 +13,10 @@
gtag('config', 'UA-78128848-1'); gtag('config', 'UA-78128848-1');
</script> </script>
<meta charset="utf-8"> <meta charset="utf-8">
<meta name="description" content="Tool for visualizing algorithms.">
<meta property="og:title" content="Algorithm Visualizer" />
<meta property="og:description" content="Tool for visualizing algorithms." />
<meta property="og:image" content="/img/image.png" />
<meta http-equiv="x-ua-compatible" content="ie=edge"> <meta http-equiv="x-ua-compatible" content="ie=edge">
<meta name="viewport" content="width=device-width"> <meta name="viewport" content="width=device-width">
<meta name="theme-color" content="#393939"> <meta name="theme-color" content="#393939">
<title>Algorithm Visualizer</title> <link rel="shortcut icon" href="/favicon.png" type="image/png">
<link rel="shortcut icon" href="/img/favicon.png" type="image/x-icon">
<link rel="manifest" href="/manifest.json"> <link rel="manifest" href="/manifest.json">
<link href="https://fonts.googleapis.com/css?family=Roboto+Mono:400,700|Roboto:400,700" rel="stylesheet"> <link href="https://fonts.googleapis.com/css?family=Roboto+Mono:400,700|Roboto:400,700" rel="stylesheet">
</head> </head>
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册