Browse Source

feat: remove name from appState and use in component directly

Aakansha Doshi 1 year ago
parent
commit
b2331ffd98

+ 2 - 0
excalidraw-app/App.tsx

@@ -45,6 +45,7 @@ import {
   ResolvablePromise,
   ResolvablePromise,
   resolvablePromise,
   resolvablePromise,
   isRunningInIframe,
   isRunningInIframe,
+  getDateTime,
 } from "../packages/excalidraw/utils";
 } from "../packages/excalidraw/utils";
 import {
 import {
   FIREBASE_STORAGE_PREFIXES,
   FIREBASE_STORAGE_PREFIXES,
@@ -775,6 +776,7 @@ const ExcalidrawWrapper = () => {
                   excalidrawAPI.getSceneElements(),
                   excalidrawAPI.getSceneElements(),
                   excalidrawAPI.getAppState(),
                   excalidrawAPI.getAppState(),
                   excalidrawAPI.getFiles(),
                   excalidrawAPI.getFiles(),
+                  `${t("labels.untitled")}-${getDateTime()}`,
                 );
                 );
               }}
               }}
             >
             >

+ 9 - 3
excalidraw-app/components/ExportToExcalidrawPlus.tsx

@@ -23,13 +23,14 @@ import { FILE_UPLOAD_MAX_BYTES } from "../app_constants";
 import { encodeFilesForUpload } from "../data/FileManager";
 import { encodeFilesForUpload } from "../data/FileManager";
 import { MIME_TYPES } from "../../packages/excalidraw/constants";
 import { MIME_TYPES } from "../../packages/excalidraw/constants";
 import { trackEvent } from "../../packages/excalidraw/analytics";
 import { trackEvent } from "../../packages/excalidraw/analytics";
-import { getFrame } from "../../packages/excalidraw/utils";
+import { getDateTime, getFrame } from "../../packages/excalidraw/utils";
 import { ExcalidrawLogo } from "../../packages/excalidraw/components/ExcalidrawLogo";
 import { ExcalidrawLogo } from "../../packages/excalidraw/components/ExcalidrawLogo";
 
 
 export const exportToExcalidrawPlus = async (
 export const exportToExcalidrawPlus = async (
   elements: readonly NonDeletedExcalidrawElement[],
   elements: readonly NonDeletedExcalidrawElement[],
   appState: Partial<AppState>,
   appState: Partial<AppState>,
   files: BinaryFiles,
   files: BinaryFiles,
+  name: string,
 ) => {
 ) => {
   const firebase = await loadFirebaseStorage();
   const firebase = await loadFirebaseStorage();
 
 
@@ -53,7 +54,7 @@ export const exportToExcalidrawPlus = async (
     .ref(`/migrations/scenes/${id}`)
     .ref(`/migrations/scenes/${id}`)
     .put(blob, {
     .put(blob, {
       customMetadata: {
       customMetadata: {
-        data: JSON.stringify({ version: 2, name: appState.name }),
+        data: JSON.stringify({ version: 2, name }),
         created: Date.now().toString(),
         created: Date.now().toString(),
       },
       },
     });
     });
@@ -117,7 +118,12 @@ export const ExportToExcalidrawPlus: React.FC<{
         onClick={async () => {
         onClick={async () => {
           try {
           try {
             trackEvent("export", "eplus", `ui (${getFrame()})`);
             trackEvent("export", "eplus", `ui (${getFrame()})`);
-            await exportToExcalidrawPlus(elements, appState, files);
+            await exportToExcalidrawPlus(
+              elements,
+              appState,
+              files,
+              `${t("labels.untitled")}-${getDateTime()}`,
+            );
             onSuccess();
             onSuccess();
           } catch (error: any) {
           } catch (error: any) {
             console.error(error);
             console.error(error);

+ 3 - 0
packages/excalidraw/actions/actionClipboard.tsx

@@ -13,6 +13,7 @@ import { exportCanvas, prepareElementsForExport } from "../data/index";
 import { isTextElement } from "../element";
 import { isTextElement } from "../element";
 import { t } from "../i18n";
 import { t } from "../i18n";
 import { isFirefox } from "../constants";
 import { isFirefox } from "../constants";
+import { getDateTime } from "../utils";
 
 
 export const actionCopy = register({
 export const actionCopy = register({
   name: "copy",
   name: "copy",
@@ -138,6 +139,7 @@ export const actionCopyAsSvg = register({
         {
         {
           ...appState,
           ...appState,
           exportingFrame,
           exportingFrame,
+          name: app.props.name || `${t("labels.untitled")}-${getDateTime()}`,
         },
         },
       );
       );
       return {
       return {
@@ -184,6 +186,7 @@ export const actionCopyAsPng = register({
       await exportCanvas("clipboard", exportedElements, appState, app.files, {
       await exportCanvas("clipboard", exportedElements, appState, app.files, {
         ...appState,
         ...appState,
         exportingFrame,
         exportingFrame,
+        name: app.props.name || `${t("labels.untitled")}-${getDateTime()}`,
       });
       });
       return {
       return {
         appState: {
         appState: {

+ 15 - 3
packages/excalidraw/actions/actionExport.tsx

@@ -19,6 +19,7 @@ import { nativeFileSystemSupported } from "../data/filesystem";
 import { Theme } from "../element/types";
 import { Theme } from "../element/types";
 
 
 import "../components/ToolIcon.scss";
 import "../components/ToolIcon.scss";
+import { getDateTime } from "../utils";
 
 
 export const actionChangeProjectName = register({
 export const actionChangeProjectName = register({
   name: "changeProjectName",
   name: "changeProjectName",
@@ -29,7 +30,7 @@ export const actionChangeProjectName = register({
   PanelComponent: ({ appState, updateData, appProps, data }) => (
   PanelComponent: ({ appState, updateData, appProps, data }) => (
     <ProjectName
     <ProjectName
       label={t("labels.fileTitle")}
       label={t("labels.fileTitle")}
-      value={appState.name || "Unnamed"}
+      value={appProps.name}
       onChange={(name: string) => updateData(name)}
       onChange={(name: string) => updateData(name)}
       isNameEditable={
       isNameEditable={
         typeof appProps.name === "undefined" && !appState.viewModeEnabled
         typeof appProps.name === "undefined" && !appState.viewModeEnabled
@@ -144,8 +145,18 @@ export const actionSaveToActiveFile = register({
 
 
     try {
     try {
       const { fileHandle } = isImageFileHandle(appState.fileHandle)
       const { fileHandle } = isImageFileHandle(appState.fileHandle)
-        ? await resaveAsImageWithScene(elements, appState, app.files)
-        : await saveAsJSON(elements, appState, app.files);
+        ? await resaveAsImageWithScene(
+            elements,
+            appState,
+            app.files,
+            app.props.name || `${t("labels.untitled")}-${getDateTime()}`,
+          )
+        : await saveAsJSON(
+            elements,
+            appState,
+            app.files,
+            app.props.name || `${t("labels.untitled")}-${getDateTime()}`,
+          );
 
 
       return {
       return {
         commitToHistory: false,
         commitToHistory: false,
@@ -190,6 +201,7 @@ export const actionSaveFileToDisk = register({
           fileHandle: null,
           fileHandle: null,
         },
         },
         app.files,
         app.files,
+        app.props.name || `${t("labels.untitled")}-${getDateTime()}`,
       );
       );
       return {
       return {
         commitToHistory: false,
         commitToHistory: false,

+ 0 - 2
packages/excalidraw/appState.ts

@@ -65,7 +65,6 @@ export const getDefaultAppState = (): Omit<
     isRotating: false,
     isRotating: false,
     lastPointerDownWith: "mouse",
     lastPointerDownWith: "mouse",
     multiElement: null,
     multiElement: null,
-    name: `${t("labels.untitled")}-${getDateTime()}`,
     contextMenu: null,
     contextMenu: null,
     openMenu: null,
     openMenu: null,
     openPopup: null,
     openPopup: null,
@@ -175,7 +174,6 @@ const APP_STATE_STORAGE_CONF = (<
   isRotating: { browser: false, export: false, server: false },
   isRotating: { browser: false, export: false, server: false },
   lastPointerDownWith: { browser: true, export: false, server: false },
   lastPointerDownWith: { browser: true, export: false, server: false },
   multiElement: { browser: false, export: false, server: false },
   multiElement: { browser: false, export: false, server: false },
-  name: { browser: true, export: false, server: false },
   offsetLeft: { browser: false, export: false, server: false },
   offsetLeft: { browser: false, export: false, server: false },
   offsetTop: { browser: false, export: false, server: false },
   offsetTop: { browser: false, export: false, server: false },
   contextMenu: { browser: false, export: false, server: false },
   contextMenu: { browser: false, export: false, server: false },

+ 3 - 15
packages/excalidraw/components/App.tsx

@@ -270,6 +270,7 @@ import {
   updateStable,
   updateStable,
   addEventListener,
   addEventListener,
   normalizeEOL,
   normalizeEOL,
+  getDateTime,
 } from "../utils";
 } from "../utils";
 import {
 import {
   createSrcDoc,
   createSrcDoc,
@@ -619,7 +620,6 @@ class App extends React.Component<AppProps, AppState> {
       gridModeEnabled = false,
       gridModeEnabled = false,
       objectsSnapModeEnabled = false,
       objectsSnapModeEnabled = false,
       theme = defaultAppState.theme,
       theme = defaultAppState.theme,
-      name = defaultAppState.name,
     } = props;
     } = props;
     this.state = {
     this.state = {
       ...defaultAppState,
       ...defaultAppState,
@@ -630,7 +630,6 @@ class App extends React.Component<AppProps, AppState> {
       zenModeEnabled,
       zenModeEnabled,
       objectsSnapModeEnabled,
       objectsSnapModeEnabled,
       gridSize: gridModeEnabled ? GRID_SIZE : null,
       gridSize: gridModeEnabled ? GRID_SIZE : null,
-      name,
       width: window.innerWidth,
       width: window.innerWidth,
       height: window.innerHeight,
       height: window.innerHeight,
     };
     };
@@ -1725,7 +1724,7 @@ class App extends React.Component<AppProps, AppState> {
       this.files,
       this.files,
       {
       {
         exportBackground: this.state.exportBackground,
         exportBackground: this.state.exportBackground,
-        name: this.state.name,
+        name: this.props?.name || `${t("labels.untitled")}-${getDateTime()}`,
         viewBackgroundColor: this.state.viewBackgroundColor,
         viewBackgroundColor: this.state.viewBackgroundColor,
         exportingFrame: opts.exportingFrame,
         exportingFrame: opts.exportingFrame,
       },
       },
@@ -2124,7 +2123,7 @@ class App extends React.Component<AppProps, AppState> {
         let gridSize = actionResult?.appState?.gridSize || null;
         let gridSize = actionResult?.appState?.gridSize || null;
         const theme =
         const theme =
           actionResult?.appState?.theme || this.props.theme || THEME.LIGHT;
           actionResult?.appState?.theme || this.props.theme || THEME.LIGHT;
-        let name = actionResult?.appState?.name ?? this.state.name;
+
         const errorMessage =
         const errorMessage =
           actionResult?.appState?.errorMessage ?? this.state.errorMessage;
           actionResult?.appState?.errorMessage ?? this.state.errorMessage;
         if (typeof this.props.viewModeEnabled !== "undefined") {
         if (typeof this.props.viewModeEnabled !== "undefined") {
@@ -2139,10 +2138,6 @@ class App extends React.Component<AppProps, AppState> {
           gridSize = this.props.gridModeEnabled ? GRID_SIZE : null;
           gridSize = this.props.gridModeEnabled ? GRID_SIZE : null;
         }
         }
 
 
-        if (typeof this.props.name !== "undefined") {
-          name = this.props.name;
-        }
-
         editingElement =
         editingElement =
           editingElement || actionResult.appState?.editingElement || null;
           editingElement || actionResult.appState?.editingElement || null;
 
 
@@ -2165,7 +2160,6 @@ class App extends React.Component<AppProps, AppState> {
               zenModeEnabled,
               zenModeEnabled,
               gridSize,
               gridSize,
               theme,
               theme,
-              name,
               errorMessage,
               errorMessage,
             });
             });
           },
           },
@@ -2699,12 +2693,6 @@ class App extends React.Component<AppProps, AppState> {
       });
       });
     }
     }
 
 
-    if (this.props.name && prevProps.name !== this.props.name) {
-      this.setState({
-        name: this.props.name,
-      });
-    }
-
     this.excalidrawContainerRef.current?.classList.toggle(
     this.excalidrawContainerRef.current?.classList.toggle(
       "theme--dark",
       "theme--dark",
       this.state.theme === "dark",
       this.state.theme === "dark",

+ 4 - 3
packages/excalidraw/components/ImageExportDialog.tsx

@@ -34,7 +34,7 @@ import { Tooltip } from "./Tooltip";
 import "./ImageExportDialog.scss";
 import "./ImageExportDialog.scss";
 import { useAppProps } from "./App";
 import { useAppProps } from "./App";
 import { FilledButton } from "./FilledButton";
 import { FilledButton } from "./FilledButton";
-import { cloneJSON } from "../utils";
+import { cloneJSON, getDateTime } from "../utils";
 import { prepareElementsForExport } from "../data";
 import { prepareElementsForExport } from "../data";
 
 
 const supportsContextFilters =
 const supportsContextFilters =
@@ -73,7 +73,9 @@ const ImageExportModal = ({
   );
   );
 
 
   const appProps = useAppProps();
   const appProps = useAppProps();
-  const [projectName, setProjectName] = useState(appStateSnapshot.name);
+  const [projectName, setProjectName] = useState(
+    appProps.name || `${t("labels.untitled")}-${getDateTime()}`,
+  );
   const [exportSelectionOnly, setExportSelectionOnly] = useState(hasSelection);
   const [exportSelectionOnly, setExportSelectionOnly] = useState(hasSelection);
   const [exportWithBackground, setExportWithBackground] = useState(
   const [exportWithBackground, setExportWithBackground] = useState(
     appStateSnapshot.exportBackground,
     appStateSnapshot.exportBackground,
@@ -109,7 +111,6 @@ const ImageExportModal = ({
       elements: exportedElements,
       elements: exportedElements,
       appState: {
       appState: {
         ...appStateSnapshot,
         ...appStateSnapshot,
-        name: projectName,
         exportBackground: exportWithBackground,
         exportBackground: exportWithBackground,
         exportWithDarkMode: exportDarkMode,
         exportWithDarkMode: exportDarkMode,
         exportScale,
         exportScale,

+ 6 - 3
packages/excalidraw/components/ProjectName.tsx

@@ -1,14 +1,15 @@
 import "./TextInput.scss";
 import "./TextInput.scss";
 
 
 import React, { useState } from "react";
 import React, { useState } from "react";
-import { focusNearestParent } from "../utils";
+import { focusNearestParent, getDateTime } from "../utils";
 
 
 import "./ProjectName.scss";
 import "./ProjectName.scss";
 import { useExcalidrawContainer } from "./App";
 import { useExcalidrawContainer } from "./App";
 import { KEYS } from "../keys";
 import { KEYS } from "../keys";
+import { t } from "../i18n";
 
 
 type Props = {
 type Props = {
-  value: string;
+  value?: string;
   onChange: (value: string) => void;
   onChange: (value: string) => void;
   label: string;
   label: string;
   isNameEditable: boolean;
   isNameEditable: boolean;
@@ -17,7 +18,9 @@ type Props = {
 
 
 export const ProjectName = (props: Props) => {
 export const ProjectName = (props: Props) => {
   const { id } = useExcalidrawContainer();
   const { id } = useExcalidrawContainer();
-  const [fileName, setFileName] = useState<string>(props.value);
+  const [fileName, setFileName] = useState<string>(
+    props.value || `${t("labels.untitled")}-${getDateTime()}`,
+  );
 
 
   const handleBlur = (event: any) => {
   const handleBlur = (event: any) => {
     if (!props.ignoreFocus) {
     if (!props.ignoreFocus) {

+ 2 - 1
packages/excalidraw/data/json.ts

@@ -71,6 +71,7 @@ export const saveAsJSON = async (
   elements: readonly ExcalidrawElement[],
   elements: readonly ExcalidrawElement[],
   appState: AppState,
   appState: AppState,
   files: BinaryFiles,
   files: BinaryFiles,
+  name: string,
 ) => {
 ) => {
   const serialized = serializeAsJSON(elements, appState, files, "local");
   const serialized = serializeAsJSON(elements, appState, files, "local");
   const blob = new Blob([serialized], {
   const blob = new Blob([serialized], {
@@ -78,7 +79,7 @@ export const saveAsJSON = async (
   });
   });
 
 
   const fileHandle = await fileSave(blob, {
   const fileHandle = await fileSave(blob, {
-    name: appState.name,
+    name,
     extension: "excalidraw",
     extension: "excalidraw",
     description: "Excalidraw file",
     description: "Excalidraw file",
     fileHandle: isImageFileHandle(appState.fileHandle)
     fileHandle: isImageFileHandle(appState.fileHandle)

+ 2 - 1
packages/excalidraw/data/resave.ts

@@ -7,8 +7,9 @@ export const resaveAsImageWithScene = async (
   elements: readonly ExcalidrawElement[],
   elements: readonly ExcalidrawElement[],
   appState: AppState,
   appState: AppState,
   files: BinaryFiles,
   files: BinaryFiles,
+  name: string,
 ) => {
 ) => {
-  const { exportBackground, viewBackgroundColor, name, fileHandle } = appState;
+  const { exportBackground, viewBackgroundColor, fileHandle } = appState;
 
 
   const fileHandleType = getFileHandleType(fileHandle);
   const fileHandleType = getFileHandleType(fileHandle);
 
 

+ 0 - 1
packages/excalidraw/history.ts

@@ -26,7 +26,6 @@ const clearAppStatePropertiesForHistory = (appState: AppState) => {
     viewBackgroundColor: appState.viewBackgroundColor,
     viewBackgroundColor: appState.viewBackgroundColor,
     editingLinearElement: appState.editingLinearElement,
     editingLinearElement: appState.editingLinearElement,
     editingGroupId: appState.editingGroupId,
     editingGroupId: appState.editingGroupId,
-    name: appState.name,
   };
   };
 };
 };
 
 

+ 0 - 1
packages/excalidraw/types.ts

@@ -247,7 +247,6 @@ export interface AppState {
   scrollY: number;
   scrollY: number;
   cursorButton: "up" | "down";
   cursorButton: "up" | "down";
   scrolledOutside: boolean;
   scrolledOutside: boolean;
-  name: string;
   isResizing: boolean;
   isResizing: boolean;
   isRotating: boolean;
   isRotating: boolean;
   zoom: Zoom;
   zoom: Zoom;