!1 Merge back to master

Merge pull request !1 from dev branch
This commit is contained in:
hekk 2018-05-27 21:32:55 +08:00
parent 30c963a5f0
commit 61a1c93f0f
89 changed files with 15859 additions and 2 deletions

View file

@ -0,0 +1,214 @@
import React from "react";
import { getIcon, getIconColor } from "../display/icon";
const statusNull = "null";
const statusInfo = "info";
const statusWarn = "warn";
const statusError = "error";
const statusOk = "ok";
const statusStart = "start";
const statusEnd = "end";
const IconInfo = getIcon("infoCir");
const IconWarn = getIcon("exTri");
const IconError = getIcon("timesCir");
const IconOk = getIcon("checkCir");
const IconStart = getIcon("refresh");
const colorInfo = getIconColor("infoCir");
const colorWarn = getIconColor("exTri");
const colorError = getIconColor("timesCir");
const colorOk = getIconColor("checkCir");
const colorStart = getIconColor("refresh");
const classFadeIn = "log-fade-in";
const classHidden = "log-hidden";
const styleStr = `
.log .${classFadeIn} {
opacity: 1;
margin-left: 0.5rem;
padding: 0.25rem 0.5rem;
transition: opacity 0.3s, margin-left 0.3s, padding 0.3s;
}
.log .${classHidden} {
opacity: 0;
margin-left: 0rem;
padding: 0;
transition: opacity 0.3s, margin-left 0.3s, padding 0.3s;
}
.log a {
color: #2980b9;
transition: color 0.3s;
text-decoration: none;
}
.log a:hover {
color: #3498db;
transition: color 0.3s;
text-decoration: none;
}
`;
const wait = 5000;
const logSlotLen = 2;
const getEmptyLog = () => ({
className: classHidden,
msg: "",
status: statusNull
});
const getLogIcon = status => {
switch (status) {
case statusInfo:
return (
<IconInfo
size={16}
style={{ marginRight: "0.25rem", color: colorInfo }}
/>
);
case statusWarn:
return (
<IconWarn
size={16}
style={{ marginRight: "0.25rem", color: colorWarn }}
/>
);
case statusError:
return (
<IconError
size={16}
style={{ marginRight: "0.25rem", color: colorError }}
/>
);
case statusOk:
return (
<IconOk size={16} style={{ marginRight: "0.25rem", color: colorOk }} />
);
case statusStart:
return (
<IconStart
size={16}
className={"anm-rotate"}
style={{ marginRight: "0.25rem", color: colorStart }}
/>
);
case statusEnd:
return (
<IconOk size={16} style={{ marginRight: "0.25rem", color: colorOk }} />
);
default:
return <span />;
}
};
export class Log extends React.PureComponent {
constructor(props) {
super(props);
this.state = {
logs: Array(logSlotLen).fill(getEmptyLog())
};
this.id = 0;
}
genId = () => {
return this.id++ % logSlotLen;
};
addLog = (status, msg) => {
const id = this.genId();
const nextLogs = [
...this.state.logs.slice(0, id),
{
className: classFadeIn,
msg,
status
},
...this.state.logs.slice(id + 1)
];
this.setState({ logs: nextLogs });
this.delayClearLog(id);
return id;
};
delayClearLog = idToDel => {
setTimeout(this.clearLog, wait, idToDel);
};
clearLog = idToDel => {
// TODO: there may be race condition here
const nextLogs = [
...this.state.logs.slice(0, idToDel),
getEmptyLog(),
...this.state.logs.slice(idToDel + 1)
];
this.setState({ logs: nextLogs });
};
info = msg => {
this.addLog(statusInfo, msg);
};
warn = msg => {
this.addLog(statusWarn, msg);
};
error = msg => {
this.addLog(statusError, msg);
};
ok = msg => {
this.addLog(statusOk, msg);
};
start = msg => {
const id = this.genId();
const nextLogs = [
...this.state.logs.slice(0, id),
{
className: classFadeIn,
msg,
status: statusStart
},
...this.state.logs.slice(id + 1)
];
this.setState({ logs: nextLogs });
return id;
};
end = (startId, msg) => {
// remove start log
this.clearLog(startId);
this.addLog(statusEnd, msg);
};
render() {
const logList = Object.keys(this.state.logs).map(logId => {
return (
<span
key={logId}
style={this.props.styleLog}
className={this.state.logs[logId].className}
>
{getLogIcon(this.state.logs[logId].status)}
{this.state.logs[logId].msg}
</span>
);
});
return (
<span className={"log"} style={this.props.style}>
{logList}
<style>{styleStr}</style>
</span>
);
}
}
Log.defaultProps = {
style: {},
styleLog: {}
};