dialog.tsx 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. import { DialogItem } from "@/modules/list/objects/item";
  2. import { css } from "@linaria/core";
  3. import {
  4. computed,
  5. defineComponent,
  6. nextTick,
  7. onMounted,
  8. onUnmounted,
  9. reactive,
  10. ref,
  11. } from "vue";
  12. import { object } from "vue-types";
  13. import Item from "./item";
  14. import { useList } from "@/modules/list";
  15. export default defineComponent({
  16. props: {
  17. data: object<DialogItem>().isRequired,
  18. },
  19. emits: ["move"],
  20. setup(props) {
  21. const { store, actions } = useList();
  22. const dialogRef = ref<HTMLElement>();
  23. const closeRef = ref();
  24. const state = reactive({
  25. width: props.data.width,
  26. height: props.data.height,
  27. x: props.data.x,
  28. y: props.data.y,
  29. scale: 0,
  30. itemData: {} as any,
  31. touchClient: null as any,
  32. dialogId: "",
  33. });
  34. const pos = computed(() => {
  35. return {
  36. x: props.data.x,
  37. y: props.data.y,
  38. };
  39. });
  40. onMounted(() => {
  41. state.itemData = store.list.find((e: any) => {
  42. return e._id == props.data.dataId;
  43. });
  44. setTimeout(() => {
  45. nextTick(() => {
  46. state.scale = 1.0;
  47. closeTimeStart();
  48. });
  49. }, 10);
  50. //@ts-ignore
  51. dialogRef.value.dialogId = props.data.id;
  52. dialogRef.value?.addEventListener("touchstart", (e) => {
  53. closeTimeEnd();
  54. });
  55. dialogRef.value?.addEventListener("touchmove", (e) => {
  56. if (state.touchClient) {
  57. const targetTouch = e.targetTouches[0];
  58. const x = targetTouch.clientX - state.touchClient.x;
  59. const y = targetTouch.clientY - state.touchClient.y;
  60. actions.moveDialog(props.data.id, x, y);
  61. state.touchClient.x = targetTouch.clientX;
  62. state.touchClient.y = targetTouch.clientY;
  63. }
  64. });
  65. dialogRef.value?.addEventListener("touchend", (e) => {
  66. state.touchClient = null;
  67. closeTimeStart();
  68. });
  69. dialogRef.value?.addEventListener("mousedown", (e) => {
  70. closeTimeEnd();
  71. });
  72. dialogRef.value?.addEventListener("mousemove", (e) => {
  73. if (state.dialogId) {
  74. actions.moveDialog(state.dialogId, e.movementX, e.movementY);
  75. }
  76. });
  77. dialogRef.value?.addEventListener("mouseup", (e) => {
  78. state.dialogId = "";
  79. closeTimeStart();
  80. });
  81. initEvent();
  82. });
  83. const initEvent = () => {
  84. window.addEventListener("message", (e) => {
  85. const data = JSON.parse(e.data);
  86. if (data.type == "start") {
  87. messageCloseEnd(data.dialogId);
  88. } else {
  89. messageCloseStart(data.dialogId);
  90. }
  91. });
  92. };
  93. onUnmounted(() => {
  94. closeTimeEnd();
  95. });
  96. const closeTimeStart = () => {
  97. closeTimeEnd();
  98. // closeRef.value = setTimeout(close, 30000);
  99. };
  100. const messageCloseStart = (dialogId?: string) => {
  101. if (dialogId == props.data.id) {
  102. closeTimeStart();
  103. }
  104. };
  105. const messageCloseEnd = (dialogId?: string) => {
  106. if (dialogId == props.data.id) {
  107. closeTimeEnd();
  108. }
  109. };
  110. const closeTimeEnd = () => {
  111. if (closeRef.value) {
  112. clearTimeout(closeRef.value);
  113. }
  114. };
  115. function close() {
  116. state.scale = 0;
  117. actions.closingDialog(props.data);
  118. setTimeout(() => {
  119. actions.deleteDialog(props.data);
  120. }, 400);
  121. }
  122. const dialogMove = (flag: boolean) => {
  123. if (flag) {
  124. state.dialogId = props.data.id;
  125. }
  126. };
  127. const dialogTouch = (client: any) => {
  128. state.touchClient = client;
  129. };
  130. return () => (
  131. <div
  132. ref={dialogRef}
  133. class={dialogStyle}
  134. style={{
  135. transform: `translate(-50%, -50%) scale(${state.scale})`,
  136. left: `${pos.value.x}px`,
  137. top: `${pos.value.y}px`,
  138. width: Math.floor(state.width / 100) + "rem",
  139. height: Math.floor(state.height / 100) + "rem",
  140. }}
  141. >
  142. <div class={"dialog_view"}>
  143. {state.itemData._id && (
  144. <Item
  145. data={state.itemData}
  146. dialogId={props.data.id}
  147. onClose={close}
  148. onMove={dialogMove}
  149. onTouch={dialogTouch}
  150. />
  151. )}
  152. </div>
  153. </div>
  154. );
  155. },
  156. });
  157. const dialogStyle = css`
  158. transform: scale(0);
  159. transition: transform 0.4s;
  160. transform-origin: center;
  161. transition-timing-function: cubic-bezier(0.22, 0.61, 0.36, 1);
  162. position: absolute;
  163. background: url("~@/assets/dialog_bg.png") no-repeat center/cover;
  164. .dialog_view {
  165. position: absolute;
  166. top: 50%;
  167. left: 50%;
  168. width: 7rem;
  169. height: 7rem;
  170. transform: translate(-50%, -50%);
  171. }
  172. `;