feat: remove name from appState and use in component directly
This commit is contained in:
parent
0513b647ec
commit
b2331ffd98
@ -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()}`,
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
@ -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);
|
||||||
|
@ -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: {
|
||||||
|
@ -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 resaveAsImageWithScene(
|
||||||
: await saveAsJSON(elements, appState, app.files);
|
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,
|
||||||
|
@ -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 },
|
||||||
|
@ -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",
|
||||||
|
@ -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,
|
||||||
|
@ -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) {
|
||||||
|
@ -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)
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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,
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user