Advertisement
Guest User

Untitled

a guest
Dec 18th, 2017
93
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.91 KB | None | 0 0
  1. /* @flow */
  2.  
  3. import { areBBoxesIntersectedByY } from '../../../../../utils/bbox';
  4.  
  5. import makeEpic from '../../../../epics/makeEpic';
  6. import { receiveOnly } from '../../../../epics/makeResolveWhenFulfilledSaga';
  7. import { SelectionFrameBorderWidth, SelectionFrameMargin } from '../../../../constants/app';
  8.  
  9. import templateOffsetValueActionType from '../../../oneweb/Template/epics/templateOffset/valueActionType';
  10. import propertiesPanelValueActionType from '../../../PropertiesPanel/epic/valueActionType';
  11.  
  12. import scrollValueActionType from '../scroll/valueActionType';
  13. import workspaceBBoxValueActionType from '../workspaceBBox/valueActionType';
  14. import { IDLE } from '../componentsEval/userInteractionMutations/interactionModes';
  15. import selectedComponentValueActionType from '../selectedComponent/valueActionType';
  16. import editModeComponentIdValueActionType from '../editModeComponentId/valueActionType';
  17. import componentsDependenciesValueActionType from '../componentsDependencies/valueActionType';
  18. import { UserInteractionModeSelectedComponentIdSelector, ReceiveOnlyComponentsMap } from '../componentsEval/selectorActionTypes'; // eslint-disable-line max-len
  19.  
  20. import { MCTA_WIDTH } from './actionTypes';
  21. import valueActionType from './valueActionType';
  22.  
  23. import styles from '../../../../view/Workspace/Decorations/ComponentMainActions/ComponentMainActions.css';
  24.  
  25. import type { ComponentMainActionsEpicState } from './flowTypes';
  26.  
  27. import { SelectedComponentActionSelector } from '../componentsEval/selectorActionTypes';
  28.  
  29. const
  30. defaultState: ComponentMainActionsEpicState = {
  31. show: false,
  32. selectedComponentId: null,
  33. selectedComponent: null,
  34. dependencies: null
  35. },
  36. SECONDARY_MCTA_HEIGHT = parseInt(styles.SECONDARY_MCTA_HEIGHT, 10),
  37. MCTA_BOTTOM_GAP = 8,
  38. SelectionFrameWidth = SelectionFrameBorderWidth + SelectionFrameMargin,
  39. MIN_TOP_DISTANCE = 47,
  40. getMctaTop = (selectedComponent, bottomOnly = false) => {
  41. const
  42. { top, height } = selectedComponent,
  43. isLessTopDistance = top < MIN_TOP_DISTANCE,
  44. mctaGapFromTop = MCTA_BOTTOM_GAP + SelectionFrameWidth;
  45. return isLessTopDistance || bottomOnly ?
  46. top + height + mctaGapFromTop : top - mctaGapFromTop - SECONDARY_MCTA_HEIGHT;
  47. },
  48. getMCTALeftTop = (selectedComponent, scroll) => {
  49. const
  50. { left, top } = selectedComponent;
  51. let mctaTop = getMctaTop(selectedComponent);
  52. if (top >= MIN_TOP_DISTANCE && scroll.y > mctaTop) {
  53. mctaTop = getMctaTop(selectedComponent, true);
  54. }
  55. return {
  56. top: mctaTop,
  57. left
  58. };
  59. },
  60. positionReducer = ({
  61. values: [
  62. editModeComponentId,
  63. workspaceBBox,
  64. templateOffset,
  65. { state: { position, dimensions } },
  66. selectedComponent,
  67. mctaWidth,
  68. scroll
  69. ],
  70. state: prevState
  71. }) => {
  72. if (!prevState.selectedComponent) {
  73. return { state: prevState };
  74. }
  75.  
  76. const
  77. component = (selectedComponent || prevState.selectedComponent),
  78. { left, width } = component,
  79. mctaLeftTop = getMCTALeftTop(component, scroll);
  80.  
  81. let mctaBBox;
  82.  
  83. if (editModeComponentId) {
  84. mctaBBox = {
  85. ...mctaLeftTop,
  86. bottom: mctaLeftTop.top + SECONDARY_MCTA_HEIGHT,
  87. right: mctaLeftTop.left + mctaWidth
  88. };
  89.  
  90. const propertiesPanelBBox = {
  91. top: position.y - templateOffset.y,
  92. left: position.x - templateOffset.x,
  93. right: position.x - templateOffset.x + dimensions.width,
  94. bottom: position.y - templateOffset.y + dimensions.height
  95. },
  96. // right overlapping with properties panel
  97. isRightOverlap = propertiesPanelBBox.left <= mctaBBox.right
  98. && areBBoxesIntersectedByY(propertiesPanelBBox, mctaBBox)
  99. && propertiesPanelBBox.right > left,
  100.  
  101. isBeyondWorkspaceRight = mctaBBox.right > workspaceBBox.right,
  102. mctaRightAlignedLeft = left - mctaWidth + width;
  103.  
  104. if (isRightOverlap || isBeyondWorkspaceRight) {
  105. mctaBBox.left = mctaRightAlignedLeft;
  106. }
  107. }
  108.  
  109. return {
  110. state: {
  111. ...prevState,
  112. selectedComponent: component,
  113. mctaLeft: (mctaBBox || mctaLeftTop).left,
  114. mctaTop: (mctaBBox || mctaLeftTop).top
  115. }
  116. };
  117. },
  118. epic = makeEpic({
  119. defaultState,
  120. valueActionType,
  121. updaters: [
  122. {
  123. conditions: [
  124. receiveOnly(componentsDependenciesValueActionType),
  125. SelectedComponentActionSelector
  126. ],
  127. reducer: ({
  128. values: [componentDependencies, selectedComponent],
  129. state: prevState
  130. }) => {
  131. return {
  132. state: {
  133. ...prevState,
  134. dependencies: selectedComponent ? componentDependencies[selectedComponent.kind] : null
  135. }
  136. };
  137. }
  138. },
  139. {
  140. conditions: [
  141. receiveOnly(scrollValueActionType),
  142. ReceiveOnlyComponentsMap,
  143. UserInteractionModeSelectedComponentIdSelector
  144. ],
  145. reducer: ({
  146. values: [scroll, componentsMap, { selectedComponentId, mode }],
  147. state: prevState
  148. }) => {
  149. if (!selectedComponentId) {
  150. return { state: defaultState };
  151. }
  152.  
  153. if (mode !== IDLE) {
  154. if (prevState.show) {
  155. return { state: { ...prevState, show: false } };
  156. }
  157. return { state: prevState };
  158. }
  159.  
  160. const
  161. component = componentsMap[selectedComponentId],
  162. mctaLeftTop = getMCTALeftTop(component, scroll);
  163.  
  164. return {
  165. state: {
  166. ...prevState,
  167. show: true,
  168. selectedComponentId,
  169. selectedComponent: component,
  170. mctaLeft: mctaLeftTop.left,
  171. mctaTop: mctaLeftTop.top
  172. }
  173. };
  174. }
  175. },
  176. {
  177. conditions: [
  178. receiveOnly(editModeComponentIdValueActionType),
  179. receiveOnly(workspaceBBoxValueActionType),
  180. receiveOnly(templateOffsetValueActionType),
  181. receiveOnly(propertiesPanelValueActionType),
  182. selectedComponentValueActionType,
  183. MCTA_WIDTH,
  184. receiveOnly(scrollValueActionType)
  185. ],
  186. reducer: positionReducer
  187. },
  188. {
  189. conditions: [
  190. receiveOnly(editModeComponentIdValueActionType),
  191. receiveOnly(workspaceBBoxValueActionType),
  192. receiveOnly(templateOffsetValueActionType),
  193. receiveOnly(propertiesPanelValueActionType),
  194. selectedComponentValueActionType,
  195. receiveOnly(MCTA_WIDTH),
  196. scrollValueActionType
  197. ],
  198. reducer: positionReducer
  199. }
  200. ]
  201. });
  202.  
  203. export {
  204. epic as default
  205. };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement