init project

This commit is contained in:
Jasder
2020-03-09 00:40:16 +08:00
commit 2937b2a94d
6549 changed files with 7215173 additions and 0 deletions

View File

@@ -0,0 +1,35 @@
/**
<!-- 微信sdk https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421141115 -->
<script src="https://res.wx.qq.com/open/js/jweixin-1.4.0.js"></script>
*/
if(window.wx) {
wx.ready(function () { //需在用户可能点击分享按钮前就先调用
alert('got wx1')
wx.updateAppMessageShareData({
title: ' title', // 分享标题
desc: 'hello world', // 分享描述
link: 'https://www.educoder.net', // 分享链接该链接域名或路径必须与当前页面对应的公众号JS安全域名一致
imgUrl: 'https://test-newweb.educoder.net/images/educoder/headNavLogo.png', // 分享图标
success: function () {
// 设置成功
}
})
});
// wx.onMenuShareAppMessage({
//             title:' title', // 分享标题
//             desc:'hello world', // 分享描述
//             link: 'https://www.educoder.net', //location.href, // 分享链接
//             imgUrl: 'https://pre-newweb.educoder.net/images/educoder/headNavLogo.png', // 分享图标
//             type: '', // 分享类型,music、video或link不填默认为link
//             dataUrl: '', // 如果type是music或video则要提供数据链接默认为空
//             success: function () { 
//                 // 用户确认分享后执行的回调函数
//             },
//             cancel: function () { 
//                 // 用户取消分享后执行的回调函数
//             }
//         });
}

View File

@@ -0,0 +1,25 @@
import React, { Component } from 'react';
import Cropper from '../../common/components/Cropper'
import ChangeHeaderPicModal from '../user/account/ChangeHeaderPicModal'
class TestCrop extends Component {
state = {
};
handleChange = (info) => {
}
render() {
const props = this.props;
return (
<div>
<button onClick={() => { this.refs['changeHeaderPicModal'].setVisible(true)}}>open</button>
<ChangeHeaderPicModal ref="changeHeaderPicModal"></ChangeHeaderPicModal>
<Cropper></Cropper>
</div>
);
}
}
export default (TestCrop);

View File

@@ -0,0 +1,144 @@
import React, { Component } from 'react';
import moment from 'moment'
import Select, {Option, OptGroup} from 'rc-select';
import 'rc-select/assets/index.css';
import { Upload, Icon, message } from 'antd';
import 'antd/lib/upload/style/index.css'
import Radio, { RadioGroup } from 'material-ui/Radio';
import Checkbox from 'material-ui/Checkbox';
import { withStyles } from 'material-ui/styles';
const Dragger = Upload.Dragger;
const props = {
name: 'file',
multiple: true,
action: '//jsonplaceholder.typicode.com/posts/',
onChange(info) {
const status = info.file.status;
if (status !== 'uploading') {
console.log(info.file, info.fileList);
}
if (status === 'done') {
message.success(`${info.file.name} file uploaded successfully.`);
} else if (status === 'error') {
message.error(`${info.file.name} file upload failed.`);
}
},
};
// -------------------------------------------
function getBase64(img, callback) {
const reader = new FileReader();
reader.addEventListener('load', () => callback(reader.result));
reader.readAsDataURL(img);
}
function beforeUpload(file) {
const isJPG = file.type === 'image/jpeg';
// if (!isJPG) {
// message.error('You can only upload JPG file!');
// }
const isLt2M = file.size / 1024 / 1024 < 2;
if (!isLt2M) {
message.error('Image must smaller than 2MB!');
}
// return isJPG && isLt2M;
return isLt2M;
}
// -------------------------------------------
const children = [];
for (let i = 10; i < 36; i++) {
// value={i}
children.push(
<Option key={i.toString(36) + i} disabled={i === 10} title={`中文${i}`} >
中文{i}
</Option>
);
}
// DOC https://v1-0-0.material-ui.com/customization/themes/
const myStyles = theme => ({
// root: {
// color: 'inherit',
// textDecoration: 'inherit',
// '&:hover': {
// textDecoration: 'underline',
// },
// },
// 使用主题的主色
primary: {
color: theme.palette.primary.main,
},
radio: {
'&$checked': {
color: '#4B8DF8'
},
color: 'red'
},
checked: {}
});
class TestRC extends Component {
state = {
loading: false,
};
handleChange = (info) => {
if (info.file.status === 'uploading') {
this.setState({ loading: true });
return;
}
if (info.file.status === 'done') {
// Get this url from response in real world.
getBase64(info.file.originFileObj, imageUrl => this.setState({
imageUrl,
loading: false,
}));
}
}
render() {
const uploadButton = (
<div>
<Icon type={this.state.loading ? 'loading' : 'plus'} />
<div className="ant-upload-text">Upload</div>
</div>
);
const imageUrl = this.state.imageUrl;
/*
labelStyle={{color: 'yellow'}}
iconStyle={{ fill: 'red', color: 'blue' }}
*/
const props = this.props;
return (
<div>
<Radio
label='My checkbox'
classes={{root: props.classes.radio, checked: props.classes.checked}}
>111</Radio>
<Checkbox label='My checkbox'
classes={{root: props.classes.radio, checked: props.classes.checked}}
/>
<Upload
name="avatar"
listType="picture-card"
className="avatar-uploader"
showUploadList={false}
action="//jsonplaceholder.typicode.com/posts/"
beforeUpload={beforeUpload}
onChange={this.handleChange}
>
{imageUrl ? <img src={imageUrl} alt="avatar" /> : uploadButton}
</Upload>
</div>
);
}
}
export default withStyles(myStyles)(TestRC);

View File

@@ -0,0 +1,63 @@
import React, { Component } from 'react';
import CodeMirror from 'react-codeMirror'
require('codemirror/lib/codemirror.css');
require('codemirror/mode/javascript/javascript');
require('codemirror/mode/xml/xml');
require('codemirror/mode/markdown/markdown');
/*
*/
class TestCodeMirror extends Component {
constructor(props) {
super(props)
this.updateCode = this.updateCode.bind(this)
this.state = {
code: '// Code\n //2 \n //3 \n //4 \n //5 \n\n\n\n\n\n\n'
}
}
updateCode(newCode) {
this.setState({
code: newCode,
});
}
componentDidMount() {
var readOnlyLines = [0,1,2,3,8];
this.refs.editor.getCodeMirror().on('beforeChange',function(cm,change) {
console.log('change.from.line', change.from.line)
if ( readOnlyLines.indexOf(change.from.line) !== -1
// 有问题:如果用回车将有内容的行挤到不可编辑的行,那么无法删除掉不可编辑行里的内容了
// 解决办法:将所需的行数固定写好,禁用掉回车键。
// || change.from.line > ( readOnlyLines[readOnlyLines.length -1] + 1 )
) {
change.cancel();
}
});
}
setCode() {
this.setState({
code: 'test'
})
}
render() {
var options = {
lineNumbers: true,
mode: 'javascript',
};
return (
<div>
<button onClick={this.setCode.bind(this)}>set</button>
<CodeMirror ref="editor" value={this.state.code} onChange={this.updateCode} options={options} />
</div>
)
}
}
export default TestCodeMirror;

View File

@@ -0,0 +1,110 @@
import React, { Component } from "react";
import ReactDOM from "react-dom";
import { DragDropContext, Droppable, Draggable } from "react-beautiful-dnd";
import styled from "styled-components";
// fake data generator
const getItems = count =>
Array.from({ length: count }, (v, k) => k).map(k => ({
id: `item-${k}`,
content: `item ${k}`
}));
// a little function to help us with reordering the result
const reorder = (list, startIndex, endIndex) => {
const result = Array.from(list);
const [removed] = result.splice(startIndex, 1);
result.splice(endIndex, 0, removed);
return result;
};
const List = styled.div`
background: lightgrey;
padding: 10px;
`;
const Item = styled.div`
display: flex;
align-items: center;
padding: 10px;
margin-bottom: 10px;
border: 1px solid grey;
background: white;
&:hover {
background: lightgrey;
}
`;
const DragHandle = styled.div`
width: 15px;
height: 15px;
margin-right: 8px;
background: grey;
visibility: hidden;
&:hover {
background: black;
}
${Item}:hover & {
visibility: visible;
}
`;
class App extends Component {
constructor(props) {
super(props);
this.state = {
items: getItems(10)
};
this.onDragEnd = this.onDragEnd.bind(this);
}
onDragEnd(result) {
// dropped outside the list
if (!result.destination) {
return;
}
const items = reorder(
this.state.items,
result.source.index,
result.destination.index
);
this.setState({
items
});
}
// Normally you would want to split things out into separate components.
// But in this example everything is just done in one place for simplicity
render() {
return (
<DragDropContext onDragEnd={this.onDragEnd}>
<Droppable droppableId="droppable">
{(provided, snapshot) => (
<List ref={provided.innerRef}>
{this.state.items.map((item, index) => (
<Draggable key={item.id} draggableId={item.id} index={index}>
{(provided, snapshot) => (
<Item ref={provided.innerRef} {...provided.draggableProps}>
<DragHandle {...provided.dragHandleProps} />
{item.content}
</Item>
)}
</Draggable>
))}
{provided.placeholder}
</List>
)}
</Droppable>
</DragDropContext>
);
}
}
export default App;
// Put the thing into the DOM!
// ReactDOM.render(<App />, document.getElementById("root"));

View File

@@ -0,0 +1,30 @@
import React, { Component } from 'react';
import { BrowserRouter as Router, Route, Link, Switch } from "react-router-dom";
import MonacoTest from './monaco'
import TestCrop from './TestCrop'
import TestDragBeautiful from './dnd/TestDragBeautiful'
class TestIndex extends Component {
state = {
loading: false,
};
render() {
return (
<div style={{height: '100%'}}>
test page
<Switch {...this.props}>
<Route exact path="/test/monacoTest" component={MonacoTest}></Route>
<Route exact path="/test/testCrop" component={TestCrop}></Route>
<Route exact path="/test/dragBeautifulTest" component={TestDragBeautiful}></Route>
</Switch>
</div>
);
}
}
export default TestIndex;

View File

@@ -0,0 +1,195 @@
import React, { Component } from 'react';
// import Divider from 'material-ui/Divider';
// import Dialog, {
// DialogActions,
// DialogContent,
// DialogContentText,
// DialogTitle,
// } from 'material-ui/Dialog';
// import AppBar from 'material-ui/AppBar';
// import getMuiTheme from 'material-ui/styles/getMuiTheme'
// import MobileTearSheet from '../../../MobileTearSheet';
// import ActionGrade from 'material-ui/svg-icons/action/grade';
// import Divider from 'material-ui/Divider';
// import Avatar from 'material-ui/Avatar';
// import PropTypes from 'prop-types';
// import Tabs, { Tab } from 'material-ui/Tabs';
// import Input, { InputLabel } from 'material-ui/Input';
// import { FormControl, FormHelperText } from 'material-ui/Form';
import { IIHOC as DebuggerHOC, stringify } from './ii_debug'
const style = {
paper: {
display: 'inline-block',
float: 'left',
margin: '16px 32px 16px 0',
},
rightIcon: {
textAlign: 'center',
lineHeight: '24px',
},
};
/*
<AppBar
title="Title"
iconClassNameRight="muidocs-icon-navigation-expand-more"
/>
*/
// https://material-ui-next.com/discover-more/showcase/
// class TestMaterialDesign extends Component {
// // ------------------------------------------------
// // static childContextTypes = {
// // muiTheme: PropTypes.object
// // }
// // getChildContext() {
// // return {
// // muiTheme: getMuiTheme()
// // }
// // }
// // ------------------------------------------------
// state = {
// open: false,
// value: 0,
// };
// handleOpen = () => {
// this.setState({open: true});
// };
// handleClose = () => {
// this.setState({open: false});
// };
// handleChange = (event, value) => {
// this.setState({ value });
// };
// onGoldRewardInputChange(event) {
// this.setState({ goldRewardInput: event.target.value });
// }
// render() {
// const {value} = this.state
// return (
// <Dialog
// open={true}
// onClose={this.handleGoldRewardDialogClose}
// >
// <DialogTitle id="alert-dialog-title">{"奖励设置"}</DialogTitle>
// <DialogContent>
// <FormControl aria-describedby="name-error-text">
// <InputLabel htmlFor="goldReward">1请输入奖励的金币数量</InputLabel>
// <Input id="goldReward" type="number" value={this.state.goldRewardInput} onChange={(e) => this.onGoldRewardInputChange(e)} />
// </FormControl>
// </DialogContent>
// <DialogActions>
// </DialogActions>
// </Dialog>
// );
// }
// }
// const TestMaterialDesign = () => (
// <FlatButton label="Primary" primary={true} />
// );
// export default TestMaterialDesign;
// --------------------------------------------------------
// Props Proxy and state abstraction demonstration
function PPHOC(WrappedComponent) {
return class PP extends React.Component {
componentDidMount() {
// console.log('componentDidMount1 componentDidMount1 ')
}
constructor(props) {
super(props)
this.state = { fields: {} }
}
getField(fieldName) {
if (!this.state.fields[fieldName]) {
// TODO 从服务端取state对应的数据
// 共享state
this.state.fields[fieldName] = {
value: '',
onChange: event => {
this.state.fields[fieldName].value = event.target.value
this.forceUpdate()
}
}
}
return {
value: this.state.fields[fieldName].value,
onChange: this.state.fields[fieldName].onChange
}
}
render() {
const props = Object.assign({}, this.props, {
fields: this.getField.bind(this),
})
return (
<div>
<h2>
PP HOC
</h2>
<p>Im a Props Proxy HOC that abstracts controlled inputs</p>
<WrappedComponent {...props}/>
</div>
)
}
}
}
class Example extends React.Component {
componentDidMount() {
console.log('componentDidMount componentDidMount ')
}
render() {
return (
<div>
<h2>
Wrapped Component
</h2>
<p>
Props
</p>
<pre>{stringify(this.props)}</pre>
<form>
<label>Automatically controlled input!</label>
<input type="email" {...this.props.fields('email')}/>
</form>
</div>
)
}
}
const EnhancedExample = DebuggerHOC(PPHOC(Example))
// module.exports = EnhancedExample;
export default EnhancedExample

View File

@@ -0,0 +1,68 @@
import React from 'react'
import ReactDOM from 'react-dom'
function replacer(key, value) {
if (typeof value === 'function') {
return `function ${value.name}() {...}`
}
return value
}
export function stringify(value) {
return JSON.stringify(value, replacer, 2)
}
// II debug example
// We are using the Inheritance Inversion technique to display
// the current state and props of the WrappedComponent (the component you want to debug).
// This is based on the technique that Mickael Jackson and Ryan Florence recommend
export function IIHOC(WrappedComponent) {
return class II extends WrappedComponent {
render() {
return (
<div>
<h2>
HOC Debugger Component
</h2>
<p>
Props
</p>
<pre>{stringify(this.props)}</pre>
<p>
State
</p>
<pre>{stringify(this.state)}</pre>
{super.render()}
</div>
)
}
}
}
class Example extends React.Component {
constructor(props) {
super(props)
this.state = {
name: 'fran',
email: 'franleplant@gmail.com'
}
}
render() {
return (
<div>
<h2>
Wrapped Component
</h2>
<p>Im a wrapped component</p>
</div>
)
}
}
// const EnhancedExample = IIHOC(Example)
// ReactDOM.render(<EnhancedExample date={(new Date).toISOString()}
// callback={function test() {}}/>, document.getElementById('root'))

View File

@@ -0,0 +1,17 @@
import React, { Component } from 'react';
import TPIMonaco from '../../page/component/monaco/TPIMonaco'
class MonacoTest extends Component {
state = {
loading: false,
};
render() {
console.log('monacoTest render')
return (
<TPIMonaco repositoryCode={'asdfasdf'}></TPIMonaco>
);
}
}
export default MonacoTest;

View File

@@ -0,0 +1,85 @@
import React, { PureComponent } from 'react';
import PropTypes from 'prop-types';
import { addUrlProps, UrlQueryParamTypes } from 'react-url-query';
/**
* Specify how the URL gets decoded here. This is an object that takes the prop
* name as a key, and a query param specifier as the value. The query param
* specifier can have a `type`, indicating how to decode the value from the
* URL, and a `queryParam` field that indicates which key in the query
* parameters should be read (this defaults to the prop name if not provided).
*/
const urlPropsQueryConfig = {
bar: { type: UrlQueryParamTypes.string },
foo: { type: UrlQueryParamTypes.number, queryParam: 'fooInUrl' },
};
class TestUrlQuery extends PureComponent {
static propTypes = {
bar: PropTypes.string,
foo: PropTypes.number,
// change handlers are automatically generated and passed if a config is provided
// and `addChangeHandlers` isn't false. They use `replaceIn` by default, just
// updating that single query parameter and keeping the other existing ones.
onChangeFoo: PropTypes.func,
onChangeBar: PropTypes.func,
onChangeUrlQueryParams: PropTypes.func,
}
static defaultProps = {
foo: 123,
bar: 'bar',
}
render() {
const {
foo, bar, onChangeFoo, onChangeBar, onChangeUrlQueryParams
} = this.props;
return (
<div>
<table>
<tbody>
<tr>
<td>foo</td>
<td>{foo}</td>
<td>(url query param)</td>
<td>
<button onClick={() => onChangeFoo(Math.round(Math.random() * 1000))}>
Change foo
</button>
</td>
</tr>
<tr>
<td>bar</td>
<td>{bar}</td>
<td>(url query param)</td>
<td>
<button onClick={() => onChangeBar(Math.random().toString(32).substring(8))}>
Change bar
</button>
</td>
</tr>
<tr>
<td colSpan={4}>
<button onClick={() => onChangeUrlQueryParams({
foo: Math.round(Math.random() * 1000),
bar: Math.random().toString(32).substring(8),
})}>
Change both with one URL update
</button>
</td>
</tr>
</tbody>
</table>
</div>
);
}
}
/**
* We use the addUrlProps higher-order component to map URL query parameters
* to props for TestUrlQuery. In this case the mapping happens automatically by
* first decoding the URL query parameters based on the urlPropsQueryConfig.
*/
export default addUrlProps({ urlPropsQueryConfig })(TestUrlQuery);