MainView.jsx 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. import React from "react";
  2. import styled from "styled-components";
  3. import { useTranslation } from "react-i18next";
  4. import { Board } from "./board";
  5. import SelectedItemsPane from "./SelectedItemsPane";
  6. import { useUsers } from "./users";
  7. import Touch from "./ui/Touch";
  8. import { MediaLibraryProvider } from "./mediaLibrary";
  9. import ImageDropNPaste from "./ImageDropNPaste";
  10. import AddItemButton from "./AddItemButton";
  11. import { MessageButton } from "./message";
  12. import { insideClass } from "./utils";
  13. import EditInfoButton from "./EditInfoButton";
  14. const StyledBoardView = styled.div`
  15. width: 100vw;
  16. height: 100vh;
  17. overflow: hidden;
  18. `;
  19. const BoardContainer = styled.div`
  20. position: relative;
  21. width: 100%;
  22. height: 100%;
  23. overflow: hidden;
  24. box-sizing: border-box;
  25. background-color: var(--color-darkGrey);
  26. `;
  27. const ActionBar = styled.div`
  28. position: fixed;
  29. bottom: 1em;
  30. right: 0em;
  31. display: flex;
  32. width: 100%;
  33. text-shadow: 1px 1px 2px #222;
  34. font-size: 0.8em;
  35. pointer-events: none;
  36. & > *:not(.spacer) {
  37. padding: 0 1.5em;
  38. pointer-events: all;
  39. }
  40. & .spacer {
  41. flex: 1;
  42. }
  43. @media screen and (max-width: 640px) {
  44. & > *:not(.spacer) {
  45. padding: 0 0.5em;
  46. }
  47. & .spacer {
  48. padding: 0;
  49. }
  50. }
  51. @media screen and (max-width: 420px) {
  52. & > *:not(.spacer) {
  53. padding: 0 0.2em;
  54. }
  55. }
  56. `;
  57. export const MainView = ({
  58. edit: editMode = false,
  59. mediaLibraries,
  60. mediaHandlers,
  61. itemMap,
  62. actionMap,
  63. ItemFormComponent,
  64. BoardFormComponent,
  65. }) => {
  66. const { t } = useTranslation();
  67. const { currentUser, localUsers: users } = useUsers();
  68. const [moveFirst, setMoveFirst] = React.useState(false);
  69. const [hideMenu, setHideMenu] = React.useState(false);
  70. React.useEffect(() => {
  71. // Chrome-related issue.
  72. // Making the wheel event non-passive, which allows to use preventDefault() to prevent
  73. // the browser original zoom and therefore allowing our custom one.
  74. // More detail at https://github.com/facebook/react/issues/14856
  75. const cancelWheel = (event) => {
  76. if (insideClass(event.target, "board")) event.preventDefault();
  77. };
  78. document.body.addEventListener("wheel", cancelWheel, { passive: false });
  79. return () => {
  80. document.body.removeEventListener("wheel", cancelWheel);
  81. };
  82. }, []);
  83. return (
  84. <StyledBoardView>
  85. <MediaLibraryProvider libraries={mediaLibraries} {...mediaHandlers}>
  86. <BoardContainer>
  87. <ImageDropNPaste>
  88. <Board
  89. user={currentUser}
  90. users={users}
  91. itemMap={itemMap}
  92. moveFirst={moveFirst}
  93. hideMenu={hideMenu}
  94. />
  95. </ImageDropNPaste>
  96. <SelectedItemsPane
  97. hideMenu={hideMenu}
  98. itemMap={itemMap}
  99. actionMap={actionMap}
  100. ItemFormComponent={ItemFormComponent}
  101. />
  102. </BoardContainer>
  103. <ActionBar>
  104. {!editMode && <MessageButton />}
  105. {editMode && (
  106. <EditInfoButton BoardFormComponent={BoardFormComponent} />
  107. )}
  108. <div className="spacer" />
  109. <Touch
  110. onClick={() => setMoveFirst(false)}
  111. alt={t("Select mode")}
  112. label={t("Select")}
  113. title={t("Switch to select mode")}
  114. icon={"mouse-pointer"}
  115. active={!moveFirst}
  116. />
  117. <Touch
  118. onClick={() => setMoveFirst(true)}
  119. alt={t("Move mode")}
  120. label={t("Move")}
  121. title={t("Switch to move mode")}
  122. icon={"hand"}
  123. active={moveFirst}
  124. />
  125. <Touch
  126. onClick={() => setHideMenu((prev) => !prev)}
  127. alt={hideMenu ? t("Show menu") : t("Hide menu")}
  128. label={hideMenu ? t("Show menu") : t("Hide menu")}
  129. title={hideMenu ? t("Show action menu") : t("Hide action menu")}
  130. icon={hideMenu ? "eye-with-line" : "eye"}
  131. />
  132. <div className="spacer" />
  133. <AddItemButton itemMap={itemMap} />
  134. </ActionBar>
  135. </MediaLibraryProvider>
  136. </StyledBoardView>
  137. );
  138. };
  139. export default MainView;