index.tsx 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. /* eslint-disable jsx-a11y/iframe-has-title */
  2. import React, { useCallback, useEffect, useMemo, useState } from "react";
  3. import styles from "./index.module.scss";
  4. import { A2FileObjType, A2FileType } from "@/types";
  5. import { baseURL } from "@/utils/http";
  6. import classNames from "classnames";
  7. import ImageLazy from "@/ImageLazy";
  8. import R_leftImg from "@/assets/img/goods/R_left.png";
  9. import R_rightImg from "@/assets/img/goods/R_right.png";
  10. import icon1 from "@/assets/img/goods/icon1.png";
  11. import icon1Ac from "@/assets/img/goods/icon1Ac.png";
  12. type Props = {
  13. listObj: A2FileObjType;
  14. audioInfo: A2FileType;
  15. isOpen: boolean;
  16. };
  17. function RightFile({ listObj, audioInfo, isOpen }: Props) {
  18. useEffect(() => {
  19. // 如果有音频信息
  20. if (audioInfo.id) {
  21. // 显示音频图标
  22. setRight1({ show: true, done: false });
  23. window.setTimeout(() => {
  24. const dom: HTMLAudioElement = document.querySelector("#myAudio")!;
  25. dom.onended = () => {
  26. // console.log("-------音频播放结束");
  27. // 音频播放结束
  28. setRight1({ show: true, done: false });
  29. };
  30. // 音频的状态
  31. if (!isOpen) {
  32. dom.play();
  33. setRight1({ show: true, done: true });
  34. }
  35. }, 100);
  36. }
  37. }, [audioInfo, isOpen]);
  38. // 文件类型 type
  39. const [type, setType] = useState<"model" | "video" | "img">("model");
  40. // 音频的显示和隐藏
  41. const [right1, setRight1] = useState({ show: false, done: false });
  42. // 当前显示的 索引
  43. const [showInd, setShowInd] = useState(0);
  44. const cutIndFu = useCallback(
  45. (num: number) => {
  46. setShowInd(showInd + num);
  47. },
  48. [showInd]
  49. );
  50. // 打开和关闭音频
  51. const audioCutFu = useCallback((val: boolean) => {
  52. const dom: HTMLAudioElement = document.querySelector("#myAudio")!;
  53. if (val) dom.play();
  54. else dom.pause();
  55. setRight1({ show: true, done: val });
  56. }, []);
  57. // 在页面展示的数组
  58. const list = useMemo(() => {
  59. return listObj[type];
  60. }, [listObj, type]);
  61. // 是否只有单独的音频上传
  62. const isOneAudio = useMemo(() => {
  63. if (
  64. audioInfo.id &&
  65. listObj.img.length === 0 &&
  66. listObj.model.length === 0 &&
  67. listObj.video.length === 0
  68. )
  69. return true;
  70. else return false;
  71. }, [audioInfo, listObj]);
  72. // 切换不同文件(模型/视频/图片的数组)
  73. const typeArr = useMemo(() => {
  74. const arr: {
  75. name: "模型" | "视频" | "图片";
  76. type: "model" | "video" | "img";
  77. }[] = [];
  78. if (listObj.model.length) arr.push({ name: "模型", type: "model" });
  79. if (listObj.video.length) arr.push({ name: "视频", type: "video" });
  80. if (listObj.img.length) arr.push({ name: "图片", type: "img" });
  81. return arr;
  82. }, [listObj]);
  83. // 当前默认展示什么模块(优先级按照 模型-视频-图片)
  84. useEffect(() => {
  85. if (listObj.model.length) setType("model");
  86. else if (listObj.video.length) setType("video");
  87. else setType("img");
  88. }, [listObj]);
  89. // 每次变化type的时候把 索引变成0
  90. useEffect(() => {
  91. setShowInd(0);
  92. }, [type]);
  93. return (
  94. <div className={styles.RightFile}>
  95. {/* 音频的控制模块 */}
  96. <div className="R_audioBox" hidden={!isOneAudio}>
  97. {audioInfo.filePath ? (
  98. <audio
  99. src={baseURL + audioInfo.filePath}
  100. controls
  101. id="myAudio"
  102. ></audio>
  103. ) : null}
  104. </div>
  105. {/* 音频按钮 */}
  106. <div className="R_audioIcon" hidden={!right1.show || isOneAudio}>
  107. <img
  108. src={icon1Ac}
  109. alt=""
  110. title="打开文物音频"
  111. hidden={right1.done}
  112. onClick={() => audioCutFu(true)}
  113. />
  114. <img
  115. onClick={() => audioCutFu(false)}
  116. src={icon1}
  117. alt=""
  118. title="关闭文物音频"
  119. hidden={!right1.done}
  120. />
  121. </div>
  122. {/* 模型缓存起来 */}
  123. {listObj.model && listObj.model[0] && listObj.model[0].id ? (
  124. <div className="R1_row R1_rowAc R1_IrBox" hidden={type !== "model"}>
  125. <iframe
  126. src={`model.html?m=${listObj.model[0].filePath}`}
  127. frameBorder="0"
  128. ></iframe>
  129. </div>
  130. ) : null}
  131. {list.map((v, i) => (
  132. <div
  133. className={classNames("R1_row", i === showInd ? "R1_rowAc" : "")}
  134. key={v.id}
  135. >
  136. {v.type === "video" && i === showInd ? (
  137. <video src={baseURL + v.filePath} controls></video>
  138. ) : v.type === "img" ? (
  139. <ImageLazy src={v.filePath} width="100%" height="100%" />
  140. ) : null}
  141. </div>
  142. ))}
  143. {/* 左右按钮 */}
  144. <div
  145. hidden={list.length <= 1}
  146. onClick={() => cutIndFu(-1)}
  147. className={classNames("R_left", showInd === 0 ? "R_arrowNo" : "")}
  148. >
  149. <img src={R_leftImg} alt="" />
  150. </div>
  151. <div
  152. hidden={list.length <= 1}
  153. onClick={() => cutIndFu(1)}
  154. className={classNames(
  155. "R_right",
  156. showInd >= list.length - 1 ? "R_arrowNo" : ""
  157. )}
  158. >
  159. <img src={R_rightImg} alt="" />
  160. </div>
  161. {/* 中间的模块选择 */}
  162. <div className="R_typeCutBox" hidden={typeArr.length <= 1}>
  163. {typeArr.map((v) => (
  164. <div
  165. onClick={() => setType(v.type)}
  166. className={classNames(
  167. "R_typeCutRow",
  168. type === v.type ? "R_typeCutRowAc" : ""
  169. )}
  170. key={v.type}
  171. >
  172. {v.name}
  173. {listObj[v.type].length > 1 ? listObj[v.type].length : null}
  174. </div>
  175. ))}
  176. </div>
  177. {/* 索引 */}
  178. {list.length > 1 ? (
  179. <div className="showIndBox">
  180. {showInd + 1} / {list.length}
  181. </div>
  182. ) : null}
  183. </div>
  184. );
  185. }
  186. const MemoRightFile = React.memo(RightFile);
  187. export default MemoRightFile;