Image.js 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. import React, { memo } from "react";
  2. import { useUsers } from "../../../../components/users";
  3. // See https://stackoverflow.com/questions/3680429/click-through-div-to-underlying-elements
  4. // https://developer.mozilla.org/fr/docs/Web/CSS/pointer-events
  5. const Image = ({
  6. width,
  7. height,
  8. content = "/default.png",
  9. backContent,
  10. flipped = false,
  11. setState,
  12. unflippedFor,
  13. text,
  14. backText,
  15. overlay,
  16. }) => {
  17. const { currentUser } = useUsers();
  18. const size = {};
  19. if (width) {
  20. size.width = width;
  21. }
  22. if (height) {
  23. size.height = height;
  24. }
  25. const onDblClick = React.useCallback(
  26. (e) => {
  27. if (e.ctrlKey) {
  28. setState((prevItem) => {
  29. if (prevItem.unflippedFor !== null) {
  30. return { ...prevItem, unflippedFor: null };
  31. } else {
  32. return {
  33. ...prevItem,
  34. unflippedFor: currentUser.id,
  35. flipped: false,
  36. };
  37. }
  38. });
  39. } else {
  40. setState((prevItem) => ({
  41. ...prevItem,
  42. flipped: !prevItem.flipped,
  43. unflippedFor: null,
  44. }));
  45. }
  46. },
  47. [setState, currentUser.id]
  48. );
  49. let image;
  50. if (
  51. backContent &&
  52. (flipped || (unflippedFor && unflippedFor !== currentUser.id))
  53. ) {
  54. image = (
  55. <>
  56. {text && (
  57. <div
  58. className="image-text"
  59. style={{
  60. position: "absolute",
  61. right: 0,
  62. padding: "0 3px",
  63. backgroundColor: "black",
  64. color: "white",
  65. borderRadius: "50%",
  66. userSelect: "none",
  67. }}
  68. >
  69. {backText}
  70. </div>
  71. )}
  72. <img
  73. src={backContent}
  74. alt=""
  75. draggable={false}
  76. {...size}
  77. style={{ userSelect: "none", pointerEvents: "none" }}
  78. />
  79. </>
  80. );
  81. } else {
  82. image = (
  83. <div className="image-wrapper" style={{ position: "relative" }}>
  84. {unflippedFor && (
  85. <div
  86. style={{
  87. position: "absolute",
  88. top: "-18px",
  89. left: "4px",
  90. color: "#555",
  91. backgroundColor: "#CCCCCCA0",
  92. userSelect: "none",
  93. pointerEvents: "none",
  94. }}
  95. >
  96. Only you
  97. </div>
  98. )}
  99. {overlay && (
  100. <img
  101. src={overlay.content}
  102. alt=""
  103. style={{
  104. position: "absolute",
  105. userSelect: "none",
  106. pointerEvents: "none",
  107. }}
  108. />
  109. )}
  110. {text && (
  111. <div
  112. className="image-text"
  113. style={{
  114. position: "absolute",
  115. right: 0,
  116. padding: "0 3px",
  117. backgroundColor: "black",
  118. color: "white",
  119. borderRadius: "50%",
  120. userSelect: "none",
  121. }}
  122. >
  123. {text}
  124. </div>
  125. )}
  126. <img
  127. src={content}
  128. alt=""
  129. draggable={false}
  130. {...size}
  131. style={{ userSelect: "none", pointerEvents: "none" }}
  132. />
  133. </div>
  134. );
  135. }
  136. return <div onDoubleClick={onDblClick}>{image}</div>;
  137. };
  138. export default memo(Image);