import React from 'react' import i18n from 'i18next' import newEventActions from 'actions/newEvent' import newEventStores from 'stores/newEvent' import treeStores from 'stores/tree' import { getEventBlockByBid, emptyCon, genConObj, consAstToArray } from 'stores/funcs/newEvent' import { cpJson, shallowEqualImmutable } from 'utils/utils' import { consFormulaShow } from 'utils/commons/ctrlHide' import { BLOCK_OP_TYPE } from 'const/const' import BlockLoopConItem from './BlockLoopConItem' import FormulaEditor from 'src/components/common/formulaEditor/EventFormulaEditor' export default class BlockLoopCustom extends React.Component { constructor(props) { super(props) this.state = { option: this.getLoopOption(props.bid), custom: this.getLoopCustom(this.getLoopOption(props.bid), props.bid) } this.onEventChange = this.onEventChange.bind(this) this.onChangeTimes = this.onChangeTimes.bind(this) this.getLoopOption = this.getLoopOption.bind(this) this.getLoopCustom = this.getLoopCustom.bind(this) this.getCustomCom = this.getCustomCom.bind(this) this.changeConsAst = this.changeConsAst.bind(this) this.addBlockCon = this.addBlockCon.bind(this) this.delBlockCon = this.delBlockCon.bind(this) } shouldComponentUpdate(nextProps, nextState) { return ( !shallowEqualImmutable(this.props, nextProps) || !shallowEqualImmutable(this.state, nextState) ) } componentDidMount() { this.unsubscribe = newEventStores.listen(this.onEventChange) } componentWillUnmount() { this.unsubscribe() } componentDidUpdate(preProps) { if (preProps.bid !== this.props.bid) { this.setState({ option: this.getLoopOption(), custom: this.getLoopCustom(this.getLoopOption()) }) } } onEventChange(status) { let obj = {} if (status && status.types) { if ( status.types.includes('updateBlockProp') && this.props.bid === status.data.affectBlockId && status.data.prop === 'op' ) { let option = this.getLoopOption() if (this.state.option !== option) { obj.option = option obj.custom = this.getLoopCustom(option) } } if ( status.types.includes('updateBlockProp') && this.props.bid === status.data.affectBlockId && status.data.prop === 'cons' ) { this.forceUpdate() } } if (Object.keys(obj).length > 0) { this.setState(obj) } } genForCons(blockId, value) { return { op: 'let', val: [blockId, 'int'], args: [{ op: 'step', args: [{ op: 'var', expVal: value, args: [] }] }] } } onChangeTimes(value) { this.setState( { custom: value }, () => { let forCons = this.genForCons(this.props.bid, value) newEventActions.updateBlockProp({ blockId: this.props.bid, prop: 'cons', value: forCons }) } ) } getLoopOption(bid) { let _bid = bid || this.props.bid let nodeId = this.props.eventNodeId || newEventStores.curEventNodeId let block = getEventBlockByBid(_bid, nodeId) if (block) { return block.op || BLOCK_OP_TYPE.FOR } return BLOCK_OP_TYPE.FOR } getLoopCustom(option, bid) { let _bid = bid || this.props.bid let nodeId = this.props.eventNodeId || newEventStores.curEventNodeId let block = getEventBlockByBid(_bid, nodeId) if (block) { switch (option) { case BLOCK_OP_TYPE.FOR: return ( block.args && block.args[0] && block.args[0].args && block.args[0].args[0] === 'step' && block.args[0].args[0].args && block.args[0].args[0].args[0].expVar ) case BLOCK_OP_TYPE.WHILE: return consAstToArray(block.args[0]) } } return null } changeConsAst() { // 将cons数组转为ast格式 let cons = cpJson(this.state.custom) let ors = [] let ands = [] cons.forEach((con, index) => { if (con.flag !== 'or') { ands.push(con) } else { ors.push(ands) ands = [] ands.push(con) } if (index === cons.length - 1) { ors.push(ands) } }) let consAst = {} if (ors.length > 1) { // 有or consAst.op = 'or' consAst.args = [] ors.forEach(orItem => { if (orItem.length > 1) { // 多个条件 let andObj = { op: 'and', args: [] } orItem.forEach(conItem => { let conObj = genConObj(conItem) andObj.args.push(conObj) }) consAst.args.push(andObj) } else { // 单个条件 let conObj = genConObj(orItem[0]) consAst.args.push(conObj) } }) } else { // 没有or consAst.op = 'and' consAst.args = [] let andArray = ors[0] if (andArray.length > 1) { // 多个条件 andArray.forEach(conItem => { let conObj = genConObj(conItem) consAst.args.push(conObj) }) } else { // 单个条件 consAst = genConObj(andArray[0]) } } let nodeId = this.props.eventNodeId || treeStores.curEventNodeId newEventActions.updateBlockProp({ nodeId, blockId: this.props.bid, prop: 'cons', value: consAst, trigger: true, addRecord: true }) } addBlockCon() { let cons = this.state.custom let newEmptyCon = emptyCon() cons.push(newEmptyCon) } delBlockCon({ index, resetLast }) { let cons = this.state.custom if (resetLast && cons.length === 1) { cons[0] = emptyCon() } else { cons.splice(index, 1) } if (cons.length === 1) { cons[0].flag = 'and' } } getCustomCom() { let forCom = () => { return (
{i18n.t('EventView.jenga_loop_block.forTag')}
) } let whileCom = () => { let cons = (
{this.state.custom.map((con, index) => { return ( ) })}
) return (
{!this.state.custom || this.state.custom.length === 0 ? null : cons}
) } switch (this.state.option) { case BLOCK_OP_TYPE.FOR: return forCom() case BLOCK_OP_TYPE.WHILE: return whileCom() } } render() { return
{this.getCustomCom()}
} }