feat(保存和导入) 新增保存到本地和从本地导入功能

This commit is contained in:
guanpengchn
2019-06-16 15:57:49 +08:00
parent 1a2bdd3df0
commit f16b217b6e
8 changed files with 213 additions and 38 deletions

View File

@@ -1,17 +0,0 @@
language: node_js
node_js:
- '10'
branchs:
only:
- master
install:
- yarn install
script:
- yarn build
addons:
ssh_known_hosts: 39.96.191.154
before_install:
- openssl aes-256-cbc -K $encrypted_e6c41ade86ae_key -iv $encrypted_e6c41ade86ae_iv -in id_rsa.enc -out ~/.ssh/id_rsa -d
after_success:
- chmod 600 ~/.ssh/id_rsa
- ssh travis@39.96.191.154 -o StrictHostKeyChecking=no 'cd ~/markdown-resume && git pull && yarn install && yarn build'

Binary file not shown.

View File

@@ -34,6 +34,14 @@ class App extends Component {
this.props.navbar.setBtnDisable(true); this.props.navbar.setBtnDisable(true);
} }
}; };
window.onbeforeunload = e => {
e = e || window.event;
if (e) {
e.returnValue = "数据目前存储在浏览器中,记得保存到本地备份!";
}
return "数据目前存储在浏览器中,记得保存到本地备份!";
};
} }
componentDidUpdate() { componentDidUpdate() {

View File

@@ -0,0 +1,165 @@
import React, { Component } from "react";
import PropTypes from "prop-types";
import { withStyles } from "@material-ui/core/styles";
import Menu from "@material-ui/core/Menu";
import Button from "@material-ui/core/Button";
import MenuItem from "@material-ui/core/MenuItem";
import Tooltip from "@material-ui/core/Tooltip";
import corner from "../../icons/corner.svg";
import { ENTER_DELAY, LEAVE_DELAY, STORAGE_LAYOUT } from "../../utils/constant";
import { downloadFile } from "../../utils/helper";
import { observer, inject } from "mobx-react";
@inject("navbar")
@inject("dialog")
@observer
class Export extends Component {
state = {
exportAnchorEl: null
};
openModeMenu = event => {
event.stopPropagation();
this.setState({ exportAnchorEl: event.currentTarget });
};
closeModeMenu = event => {
event.stopPropagation();
this.setState({ exportAnchorEl: null });
};
handleExport = event => {
event.stopPropagation();
this.props.navbar.setExported(true);
this.setState({ exportAnchorEl: null });
};
saveToLocal = event => {
event.stopPropagation();
const layout = window.localStorage.getItem(STORAGE_LAYOUT);
const filename = `markdown-resume-${new Date().getTime()}.json`;
downloadFile(filename, layout);
this.setState({ exportAnchorEl: null });
};
importFromLocal = event => {
event.stopPropagation();
const file = event.target.files[0];
this.fileReader = new FileReader();
this.fileReader.onloadend = this.handleFileRead;
this.fileReader.readAsText(file);
this.setState({ exportAnchorEl: null });
};
handleFileRead = e => {
const content = this.fileReader.result;
window.localStorage.setItem(STORAGE_LAYOUT, content);
window.location.href = "/";
};
openHelpDialog = event => {
event.stopPropagation();
this.props.dialog.setHelpOpened(true);
this.setState({ exportAnchorEl: null });
};
render() {
const { classes } = this.props;
const { exportAnchorEl } = this.state;
const exportOpen = Boolean(exportAnchorEl);
return (
<div>
<Tooltip
title="导入导出"
placement="bottom"
enterDelay={ENTER_DELAY}
leaveDelay={LEAVE_DELAY}
disableFocusListener
>
<Button
className={classes.btn}
color="primary"
variant="outlined"
onClick={this.openModeMenu}
>
导入导出
<img src={corner} alt="logo" className={classes.corner} />
</Button>
</Tooltip>
{/* 模板选择器菜单 */}
<Menu
id="template-menu"
anchorEl={exportAnchorEl}
open={exportOpen}
onClose={this.closeModeMenu}
classes={{
paper: classes.menu
}}
>
<MenuItem className={classes.menuItem} style={{ display: "none" }} />
<MenuItem className={classes.menuItem} onClick={this.handleExport}>
导出PDF
</MenuItem>
<MenuItem className={classes.menuItem} onClick={this.saveToLocal}>
保存到本地
</MenuItem>
<label htmlFor="outlined-button-file">
<MenuItem className={classes.menuItem}>
<input
accept="application/json"
className={classes.input}
id="outlined-button-file"
type="file"
onChange={this.importFromLocal}
/>
从本地导入
</MenuItem>
</label>
<MenuItem className={classes.menuItem} onClick={this.openHelpDialog}>
帮助
</MenuItem>
</Menu>
</div>
);
}
}
const styles = theme => ({
btn: {
padding: "0px 10px",
height: "100%",
width: "100px"
},
menu: {
top: "40px !important"
},
menuItem: {
fontSize: "0.95em"
},
corner: {
position: "absolute",
bottom: 2,
right: 2
},
input: {
display: "none"
},
label: {
width: "100%",
height: "100%"
}
});
Export.propTypes = {
classes: PropTypes.object.isRequired
};
export default withStyles(styles)(Export);

View File

@@ -61,9 +61,9 @@ class DialogHelp extends Component {
indicatorColor="primary" indicatorColor="primary"
textColor="primary" textColor="primary"
> >
<Tab label="注意" />
<Tab label="使用规则" /> <Tab label="使用规则" />
<Tab label="Markdown语法" /> <Tab label="Markdown语法" />
<Tab label="细节" />
</Tabs> </Tabs>
{value === 0 && ( {value === 0 && (
<DialogContentText <DialogContentText
@@ -75,7 +75,11 @@ class DialogHelp extends Component {
dangerouslySetInnerHTML={{ __html: this.md.render(HELP_INFO[1]) }} dangerouslySetInnerHTML={{ __html: this.md.render(HELP_INFO[1]) }}
/> />
)} )}
{value === 2 && <p>Item Three</p>} {value === 2 && (
<DialogContentText
dangerouslySetInnerHTML={{ __html: this.md.render(HELP_INFO[2]) }}
/>
)}
</DialogContent> </DialogContent>
<DialogActions> <DialogActions>
<Button onClick={this.handleClose} color="primary"> <Button onClick={this.handleClose} color="primary">

View File

@@ -2,14 +2,15 @@ import React, { Component } from "react";
import PropTypes from "prop-types"; import PropTypes from "prop-types";
import { withStyles } from "@material-ui/core/styles"; import { withStyles } from "@material-ui/core/styles";
import Button from "@material-ui/core/Button"; // import Button from "@material-ui/core/Button";
import List from "@material-ui/core/List"; import List from "@material-ui/core/List";
import ListItem from "@material-ui/core/ListItem"; // import ListItem from "@material-ui/core/ListItem";
import Tooltip from "@material-ui/core/Tooltip"; // import Tooltip from "@material-ui/core/Tooltip";
import github from "../../icons/github.svg"; // import github from "../../icons/github.svg";
import Export from "../Button/Export"
import { ENTER_DELAY, LEAVE_DELAY } from "../../utils/constant"; // import { ENTER_DELAY, LEAVE_DELAY } from "../../utils/constant";
import { observer, inject } from "mobx-react"; import { observer, inject } from "mobx-react";
@@ -17,29 +18,25 @@ import { observer, inject } from "mobx-react";
@inject("navbar") @inject("navbar")
@observer @observer
class ListStorage extends Component { class ListStorage extends Component {
handleSave = () => {}; // handleSave = () => {};
handleExport = () => {
this.props.navbar.setExported(true);
this.setState({ anchorEl: null });
};
render() { render() {
const { classes } = this.props; const { classes } = this.props;
return ( return (
<List className={classes.list}> <List className={classes.list}>
<ListItem {/* <ListItem
className={classes.listExport} className={classes.listExport}
button button
onClick={this.handleExport} onClick={this.handleExport}
> > */}
<Button variant="outlined" color="primary" className={classes.btn}> <Export/>
{/* <Button variant="outlined" color="primary" className={classes.btn}>
导出PDF 导出PDF
</Button> </Button> */}
</ListItem> {/* </ListItem> */}
<Tooltip {/* <Tooltip
title="登录" title="登录"
placement="bottom" placement="bottom"
enterDelay={ENTER_DELAY} enterDelay={ENTER_DELAY}
@@ -53,7 +50,7 @@ class ListStorage extends Component {
> >
<img src={github} alt="logo" /> <img src={github} alt="logo" />
</ListItem> </ListItem>
</Tooltip> </Tooltip> */}
</List> </List>
); );
} }

View File

@@ -77,6 +77,10 @@ export const HELP_MARKDOWN = `
\`\`\` \`\`\`
`; `;
export const HELP_INFO = [HELP_USE, HELP_MARKDOWN]; export const HELP_NOTICE = `
### 简历数据目前自动保存在浏览器中,如果清理浏览器将会丢失!
### 记得编辑后保存到本地备份!
`
export const HELP_INFO = [HELP_NOTICE, HELP_USE, HELP_MARKDOWN];
export const THEMES = [THEME0, THEME1, THEME2, THEME3, THEME4]; export const THEMES = [THEME0, THEME1, THEME2, THEME3, THEME4];

View File

@@ -224,3 +224,17 @@ const solveLine = value => {
} }
return html; return html;
}; };
/**
* 创建并下载文件
* @param {String} fileName 文件名
* @param {String} content 文件内容
*/
export const downloadFile = (fileName, content) => {
var aTag = document.createElement('a');
var blob = new Blob([content]);
aTag.download = fileName;
aTag.href = URL.createObjectURL(blob);
aTag.click();
URL.revokeObjectURL(blob);
}