BlockChildren.jsx 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295
  1. import React from 'react'
  2. import cls from 'classnames'
  3. import newEventStores from 'stores/newEvent'
  4. import { getEventBlockByBid } from 'stores/funcs/newEvent'
  5. import { shallowEqualImmutable } from 'utils/utils'
  6. import { EVENT_BLOCK_TYPE, BLOCK_OP_TYPE } from 'const/const'
  7. export default class BlockChildren extends React.Component {
  8. constructor(props) {
  9. super(props)
  10. this.state = {
  11. subBlockIds: this.getBlockChildren(props.parentBid)
  12. }
  13. // 加载相关组件
  14. this.blockAction = require('../BlockAction').default
  15. this.blockCon = require('../BlockCon').default
  16. this.blockLoop = require('../BlockLoop').default
  17. this.blockComment = require('../BlockComment').default
  18. this.blockGroup = require('../BlockGroup').default
  19. // this.blockError = require('./BlockError').default
  20. this.onEventChange = this.onEventChange.bind(this)
  21. this.getBlockChildren = this.getBlockChildren.bind(this)
  22. this.getChild = this.getChild.bind(this)
  23. this.isBlockGroupChildren = this.isBlockGroupChildren.bind(this)
  24. this.getBlockGroupBg = this.getBlockGroupBg.bind(this)
  25. }
  26. shouldComponentUpdate(nextProps, nextState) {
  27. return (
  28. !shallowEqualImmutable(this.props, nextProps) ||
  29. !shallowEqualImmutable(this.state, nextState)
  30. )
  31. }
  32. componentDidUpdate(preProps) {
  33. // parentBid改变时需要更新
  34. if (preProps.parentBid !== this.props.parentBid) {
  35. let obj = {}
  36. let subBlockIds = this.getBlockChildren()
  37. if (!shallowEqualImmutable(this.state.subBlockIds, subBlockIds)) {
  38. obj.subBlockIds = subBlockIds
  39. }
  40. if (Object.keys(obj).length > 0) {
  41. this.setState(obj)
  42. }
  43. }
  44. }
  45. componentDidMount() {
  46. this.unsubscribe = newEventStores.listen(this.onEventChange)
  47. }
  48. componentWillUnmount() {
  49. this.unsubscribe()
  50. }
  51. onEventChange(status) {
  52. let obj = {}
  53. if (status && status.types) {
  54. if (
  55. (status.types.includes('changeBlockChildren') &&
  56. status.data &&
  57. status.data.parentBid === this.props.parentBid) ||
  58. (status.types.includes('reloadBlock') &&
  59. this.props.parentBid === status.data.affectBlockId)
  60. ) {
  61. obj.subBlockIds = this.getBlockChildren()
  62. }
  63. }
  64. if (Object.keys(obj).length > 0) {
  65. this.setState(obj)
  66. }
  67. }
  68. getBlockChildren() {
  69. let childBids = []
  70. let nodeId = this.props.eventNodeId
  71. let parentBlock = getEventBlockByBid(this.props.parentBid, nodeId)
  72. if (parentBlock) {
  73. if (parentBlock.eventId) {
  74. if (
  75. parentBlock.ast &&
  76. parentBlock.ast.args &&
  77. parentBlock.ast.args.length > 0
  78. ) {
  79. parentBlock.ast.args.forEach(child => {
  80. if (child.ln) {
  81. childBids.push(child.ln)
  82. }
  83. })
  84. }
  85. } else {
  86. switch (parentBlock.op) {
  87. case BLOCK_OP_TYPE.IF:
  88. case BLOCK_OP_TYPE.ELSE:
  89. case BLOCK_OP_TYPE.FOR:
  90. case BLOCK_OP_TYPE.WHILE:
  91. if (
  92. parentBlock.args &&
  93. parentBlock.args.length > 0 &&
  94. parentBlock.args[1]
  95. ) {
  96. if (
  97. parentBlock.args[1].op === 'block' &&
  98. parentBlock.args[1].args &&
  99. parentBlock.args[1].args.length > 0
  100. ) {
  101. parentBlock.args[1].args.forEach(child => {
  102. if (child.ln) {
  103. childBids.push(child.ln)
  104. }
  105. })
  106. }
  107. }
  108. break
  109. case BLOCK_OP_TYPE.BLOCK:
  110. if (parentBlock.args && parentBlock.args.length > 0) {
  111. parentBlock.args.forEach(child => {
  112. if (child.ln) {
  113. childBids.push(child.ln)
  114. }
  115. })
  116. }
  117. break
  118. }
  119. }
  120. }
  121. return childBids
  122. }
  123. getChild(bid, index) {
  124. let nodeId = this.props.eventNodeId
  125. let block = getEventBlockByBid(bid, nodeId)
  126. if (block) {
  127. switch (block.op) {
  128. case BLOCK_OP_TYPE.SET:
  129. case BLOCK_OP_TYPE.CALL:
  130. case BLOCK_OP_TYPE.LET:
  131. case undefined:
  132. let BlockAction = this.blockAction
  133. return (
  134. <BlockAction
  135. key={index}
  136. layer={this.props.layer}
  137. groupLayer={this.props.groupLayer}
  138. nestGroupLayer={this.props.nestGroupLayer}
  139. offspringInNestGroupLayer={this.props.offspringInNestGroupLayer}
  140. extraGapGroupLayer={this.props.extraGapGroupLayer}
  141. loops={this.props.loops}
  142. bid={bid}
  143. eventNodeId={this.props.eventNodeId}
  144. visibleBlockIds={this.props.visibleBlockIds}
  145. isLast={index === this.state.subBlockIds.length - 1}
  146. virtualLayer={this.props.virtualLayer}
  147. />
  148. )
  149. case BLOCK_OP_TYPE.IF:
  150. case BLOCK_OP_TYPE.ELSE:
  151. let BlockCon = this.blockCon
  152. return (
  153. <BlockCon
  154. key={index}
  155. layer={this.props.layer}
  156. groupLayer={this.props.groupLayer}
  157. nestGroupLayer={this.props.nestGroupLayer}
  158. offspringInNestGroupLayer={this.props.offspringInNestGroupLayer}
  159. extraGapGroupLayer={this.props.extraGapGroupLayer}
  160. loops={this.props.loops}
  161. bid={bid}
  162. eventNodeId={this.props.eventNodeId}
  163. visibleBlockIds={this.props.visibleBlockIds}
  164. isLast={index === this.state.subBlockIds.length - 1}
  165. virtualLayer={this.props.virtualLayer}
  166. />
  167. )
  168. case BLOCK_OP_TYPE.FOR:
  169. case BLOCK_OP_TYPE.WHILE:
  170. let BlockLoop = this.blockLoop
  171. return (
  172. <BlockLoop
  173. key={index}
  174. layer={this.props.layer}
  175. groupLayer={this.props.groupLayer}
  176. nestGroupLayer={this.props.nestGroupLayer}
  177. offspringInNestGroupLayer={this.props.offspringInNestGroupLayer}
  178. extraGapGroupLayer={this.props.extraGapGroupLayer}
  179. loops={this.props.loops}
  180. bid={bid}
  181. eventNodeId={this.props.eventNodeId}
  182. visibleBlockIds={this.props.visibleBlockIds}
  183. isLast={index === this.state.subBlockIds.length - 1}
  184. virtualLayer={this.props.virtualLayer}
  185. />
  186. )
  187. case BLOCK_OP_TYPE.NOP:
  188. let BlockComment = this.blockComment
  189. return (
  190. <BlockComment
  191. key={index}
  192. layer={this.props.layer}
  193. groupLayer={this.props.groupLayer}
  194. nestGroupLayer={this.props.nestGroupLayer}
  195. offspringInNestGroupLayer={this.props.offspringInNestGroupLayer}
  196. extraGapGroupLayer={this.props.extraGapGroupLayer}
  197. loops={this.props.loops}
  198. bid={bid}
  199. eventNodeId={this.props.eventNodeId}
  200. visibleBlockIds={this.props.visibleBlockIds}
  201. isLast={index === this.state.subBlockIds.length - 1}
  202. virtualLayer={this.props.virtualLayer}
  203. />
  204. )
  205. case BLOCK_OP_TYPE.BLOCK:
  206. let BlockGroup = this.blockGroup
  207. //Group的嵌套处理
  208. return (
  209. <BlockGroup
  210. key={index}
  211. layer={this.props.layer}
  212. groupLayer={this.props.groupLayer}
  213. nestGroupLayer={this.props.nestGroupLayer}
  214. offspringInNestGroupLayer={this.props.offspringInNestGroupLayer}
  215. extraGapGroupLayer={this.props.extraGapGroupLayer}
  216. loops={this.props.loops}
  217. bid={bid}
  218. eventNodeId={this.props.eventNodeId}
  219. visibleBlockIds={this.props.visibleBlockIds}
  220. isLast={index === this.state.subBlockIds.length - 1}
  221. virtualLayer={this.props.virtualLayer}
  222. />
  223. )
  224. }
  225. } else {
  226. // let BlockError = this.blockError
  227. // return (
  228. // <BlockError
  229. // key={index}
  230. // layer={this.props.layer}
  231. // groupLayer={this.props.groupLayer}
  232. // nestGroupLayer={this.props.nestGroupLayer}
  233. // offspringInNestGroupLayer={this.props.offspringInNestGroupLayer}
  234. // extraGapGroupLayer={this.props.extraGapGroupLayer}
  235. // loops={this.props.loops}
  236. // bid={bid}
  237. // eventNodeId={this.props.eventNodeId}
  238. // visibleBlockIds={this.props.visibleBlockIds}
  239. // isLast={index === this.state.subBlockIds.length - 1}
  240. // virtualLayer={this.props.virtualLayer}
  241. // />
  242. // )
  243. }
  244. return null
  245. }
  246. isBlockGroupChildren = () => {
  247. let nodeId = this.props.eventNodeId
  248. let parentBlock = getEventBlockByBid(this.props.parentBid, nodeId)
  249. return parentBlock?.op === BLOCK_OP_TYPE.BLOCK
  250. }
  251. getBlockGroupBg = () => {
  252. const leftGap = 18 + (this.props.nestGroupLayer - 1) * 2
  253. const gapping = `${leftGap + (this.props.groupLayer - 1) * 2}px`
  254. const left = `${leftGap}px`
  255. const style = {
  256. width: `calc(100% - ${gapping})`,
  257. left: left
  258. }
  259. return this.isBlockGroupChildren() ? (
  260. <div className={'block-group-bg'} style={style} />
  261. ) : null
  262. }
  263. render() {
  264. let subBlockIds = this.state.subBlockIds
  265. if (this.props.visibleBlockIds) {
  266. subBlockIds = subBlockIds.filter(id => {
  267. return this.props.visibleBlockIds.indexOf(id) >= 0
  268. })
  269. }
  270. return subBlockIds && subBlockIds.length > 0 ? (
  271. <div
  272. className={cls('block-children', {
  273. 'block-group-children': this.isBlockGroupChildren()
  274. })}
  275. >
  276. {this.getBlockGroupBg()}
  277. {subBlockIds.map((subBlockId, index) => {
  278. return this.getChild(subBlockId, index)
  279. })}
  280. </div>
  281. ) : null
  282. }
  283. }