Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

MobileMenu.tsx 5.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. import React from "react";
  2. import { AppState } from "../types";
  3. import { ActionManager } from "../actions/manager";
  4. import { t, setLanguage } from "../i18n";
  5. import Stack from "./Stack";
  6. import { LanguageList } from "./LanguageList";
  7. import { showSelectedShapeActions } from "../element";
  8. import { NonDeletedExcalidrawElement } from "../element/types";
  9. import { FixedSideContainer } from "./FixedSideContainer";
  10. import { Island } from "./Island";
  11. import { HintViewer } from "./HintViewer";
  12. import { calculateScrollCenter } from "../scene";
  13. import { SelectedShapeActions, ShapesSwitcher } from "./Actions";
  14. import { Section } from "./Section";
  15. import { RoomDialog } from "./RoomDialog";
  16. import { SCROLLBAR_WIDTH, SCROLLBAR_MARGIN } from "../scene/scrollbars";
  17. import { LockIcon } from "./LockIcon";
  18. import { LoadingMessage } from "./LoadingMessage";
  19. type MobileMenuProps = {
  20. appState: AppState;
  21. actionManager: ActionManager;
  22. exportButton: React.ReactNode;
  23. setAppState: any;
  24. elements: readonly NonDeletedExcalidrawElement[];
  25. onRoomCreate: () => void;
  26. onUsernameChange: (username: string) => void;
  27. onRoomDestroy: () => void;
  28. onLockToggle: () => void;
  29. canvas: HTMLCanvasElement | null;
  30. };
  31. export const MobileMenu = ({
  32. appState,
  33. elements,
  34. actionManager,
  35. exportButton,
  36. setAppState,
  37. onRoomCreate,
  38. onUsernameChange,
  39. onRoomDestroy,
  40. onLockToggle,
  41. canvas,
  42. }: MobileMenuProps) => (
  43. <>
  44. {appState.isLoading && <LoadingMessage />}
  45. <FixedSideContainer side="top">
  46. <Section heading="shapes">
  47. {(heading) => (
  48. <Stack.Col gap={4} align="center">
  49. <Stack.Row gap={1}>
  50. <Island padding={1}>
  51. {heading}
  52. <Stack.Row gap={1}>
  53. <ShapesSwitcher
  54. elementType={appState.elementType}
  55. setAppState={setAppState}
  56. />
  57. </Stack.Row>
  58. </Island>
  59. <LockIcon
  60. checked={appState.elementLocked}
  61. onChange={onLockToggle}
  62. title={t("toolBar.lock")}
  63. />
  64. </Stack.Row>
  65. </Stack.Col>
  66. )}
  67. </Section>
  68. <HintViewer appState={appState} elements={elements} />
  69. </FixedSideContainer>
  70. <div
  71. className="App-bottom-bar"
  72. style={{
  73. marginBottom: SCROLLBAR_WIDTH + SCROLLBAR_MARGIN * 2,
  74. marginLeft: SCROLLBAR_WIDTH + SCROLLBAR_MARGIN * 2,
  75. marginRight: SCROLLBAR_WIDTH + SCROLLBAR_MARGIN * 2,
  76. }}
  77. >
  78. <Island padding={3}>
  79. {appState.openMenu === "canvas" ? (
  80. <Section className="App-mobile-menu" heading="canvasActions">
  81. <div className="panelColumn">
  82. <Stack.Col gap={4}>
  83. {actionManager.renderAction("loadScene")}
  84. {actionManager.renderAction("saveScene")}
  85. {actionManager.renderAction("saveAsScene")}
  86. {exportButton}
  87. {actionManager.renderAction("clearCanvas")}
  88. <RoomDialog
  89. isCollaborating={appState.isCollaborating}
  90. collaboratorCount={appState.collaborators.size}
  91. username={appState.username}
  92. onUsernameChange={onUsernameChange}
  93. onRoomCreate={onRoomCreate}
  94. onRoomDestroy={onRoomDestroy}
  95. />
  96. {actionManager.renderAction("changeViewBackgroundColor")}
  97. <fieldset>
  98. <legend>{t("labels.language")}</legend>
  99. <LanguageList
  100. onChange={(lng) => {
  101. setLanguage(lng);
  102. setAppState({});
  103. }}
  104. />
  105. </fieldset>
  106. </Stack.Col>
  107. </div>
  108. </Section>
  109. ) : appState.openMenu === "shape" &&
  110. showSelectedShapeActions(appState, elements) ? (
  111. <Section className="App-mobile-menu" heading="selectedShapeActions">
  112. <SelectedShapeActions
  113. appState={appState}
  114. elements={elements}
  115. renderAction={actionManager.renderAction}
  116. elementType={appState.elementType}
  117. />
  118. </Section>
  119. ) : null}
  120. <footer className="App-toolbar">
  121. <div className="App-toolbar-content">
  122. {actionManager.renderAction("toggleCanvasMenu")}
  123. {actionManager.renderAction("toggleEditMenu")}
  124. {actionManager.renderAction("undo")}
  125. {actionManager.renderAction("redo")}
  126. {actionManager.renderAction(
  127. appState.multiElement ? "finalize" : "duplicateSelection",
  128. )}
  129. {actionManager.renderAction("deleteSelectedElements")}
  130. </div>
  131. {appState.scrolledOutside && (
  132. <button
  133. className="scroll-back-to-content"
  134. onClick={() => {
  135. setAppState({
  136. ...calculateScrollCenter(elements, appState, canvas),
  137. });
  138. }}
  139. >
  140. {t("buttons.scrollBackToContent")}
  141. </button>
  142. )}
  143. </footer>
  144. </Island>
  145. </div>
  146. </>
  147. );