Revert "Remove unused project name from export dialog (#2427)" (#2436)

This commit is contained in:
David Luzar 2020-12-01 14:00:13 +01:00 committed by GitHub
parent 084aff2bf3
commit 36980160ae
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 605 additions and 0 deletions

View File

@ -1,4 +1,5 @@
import React from "react"; import React from "react";
import { ProjectName } from "../components/ProjectName";
import { saveAsJSON, loadFromJSON } from "../data"; import { saveAsJSON, loadFromJSON } from "../data";
import { load, save, saveAs } from "../components/icons"; import { load, save, saveAs } from "../components/icons";
import { ToolButton } from "../components/ToolButton"; import { ToolButton } from "../components/ToolButton";
@ -8,6 +9,20 @@ import { register } from "./register";
import { KEYS } from "../keys"; import { KEYS } from "../keys";
import { muteFSAbortError } from "../utils"; import { muteFSAbortError } from "../utils";
export const actionChangeProjectName = register({
name: "changeProjectName",
perform: (_elements, appState, value) => {
return { appState: { ...appState, name: value }, commitToHistory: false };
},
PanelComponent: ({ appState, updateData }) => (
<ProjectName
label={t("labels.fileTitle")}
value={appState.name || "Unnamed"}
onChange={(name: string) => updateData(name)}
/>
),
});
export const actionChangeExportBackground = register({ export const actionChangeExportBackground = register({
name: "changeExportBackground", name: "changeExportBackground",
perform: (_elements, appState, value) => { perform: (_elements, appState, value) => {

View File

@ -31,6 +31,7 @@ export {
export { actionFinalize } from "./actionFinalize"; export { actionFinalize } from "./actionFinalize";
export { export {
actionChangeProjectName,
actionChangeExportBackground, actionChangeExportBackground,
actionSaveScene, actionSaveScene,
actionSaveAsScene, actionSaveAsScene,

View File

@ -42,6 +42,7 @@ export type ActionName =
| "undo" | "undo"
| "redo" | "redo"
| "finalize" | "finalize"
| "changeProjectName"
| "changeExportBackground" | "changeExportBackground"
| "changeExportEmbedScene" | "changeExportEmbedScene"
| "changeShouldAddWatermark" | "changeShouldAddWatermark"

View File

@ -1,5 +1,7 @@
import oc from "open-color"; import oc from "open-color";
import { AppState, FlooredNumber, NormalizedZoomValue } from "./types"; import { AppState, FlooredNumber, NormalizedZoomValue } from "./types";
import { getDateTime } from "./utils";
import { t } from "./i18n";
import { import {
DEFAULT_FONT_SIZE, DEFAULT_FONT_SIZE,
DEFAULT_FONT_FAMILY, DEFAULT_FONT_FAMILY,
@ -44,6 +46,7 @@ export const getDefaultAppState = (): Omit<
cursorY: 0, cursorY: 0,
cursorButton: "up", cursorButton: "up",
scrolledOutside: false, scrolledOutside: false,
name: `${t("labels.untitled")}-${getDateTime()}`,
username: "", username: "",
isBindingEnabled: true, isBindingEnabled: true,
isCollaborating: false, isCollaborating: false,
@ -125,6 +128,7 @@ const APP_STATE_STORAGE_CONF = (<
isRotating: { browser: false, export: false }, isRotating: { browser: false, export: false },
lastPointerDownWith: { browser: true, export: false }, lastPointerDownWith: { browser: true, export: false },
multiElement: { browser: false, export: false }, multiElement: { browser: false, export: false },
name: { browser: true, export: false },
openMenu: { browser: true, export: false }, openMenu: { browser: true, export: false },
previousSelectedElementIds: { browser: true, export: false }, previousSelectedElementIds: { browser: true, export: false },
resizingElement: { browser: false, export: false }, resizingElement: { browser: false, export: false },

View File

@ -165,6 +165,9 @@ const ExportModal = ({
onClick={() => onExportToBackend(exportedElements)} onClick={() => onExportToBackend(exportedElements)}
/> />
</Stack.Row> </Stack.Row>
<div className="ExportDialog__name">
{actionManager.renderAction("changeProjectName")}
</div>
<Stack.Row gap={2}> <Stack.Row gap={2}>
{scales.map((s) => { {scales.map((s) => {
const [width, height] = getExportSize( const [width, height] = getExportSize(

View File

@ -326,6 +326,7 @@ const LayerUI = ({
if (canvas) { if (canvas) {
await exportCanvas(type, exportedElements, appState, canvas, { await exportCanvas(type, exportedElements, appState, canvas, {
exportBackground: appState.exportBackground, exportBackground: appState.exportBackground,
name: appState.name,
viewBackgroundColor: appState.viewBackgroundColor, viewBackgroundColor: appState.viewBackgroundColor,
scale, scale,
shouldAddWatermark: appState.shouldAddWatermark, shouldAddWatermark: appState.shouldAddWatermark,

View File

@ -0,0 +1,62 @@
import "./TextInput.scss";
import React, { Component } from "react";
import { selectNode, removeSelection } from "../utils";
type Props = {
value: string;
onChange: (value: string) => void;
label: string;
};
export class ProjectName extends Component<Props> {
private handleFocus = (event: React.FocusEvent<HTMLElement>) => {
selectNode(event.currentTarget);
};
private handleBlur = (event: React.FocusEvent<HTMLElement>) => {
const value = event.currentTarget.innerText.trim();
if (value !== this.props.value) {
this.props.onChange(value);
}
removeSelection();
};
private handleKeyDown = (event: React.KeyboardEvent<HTMLElement>) => {
if (event.key === "Enter") {
event.preventDefault();
if (event.nativeEvent.isComposing || event.keyCode === 229) {
return;
}
event.currentTarget.blur();
}
};
private makeEditable = (editable: HTMLSpanElement | null) => {
if (!editable) {
return;
}
try {
editable.contentEditable = "plaintext-only";
} catch {
editable.contentEditable = "true";
}
};
public render() {
return (
<span
suppressContentEditableWarning
ref={this.makeEditable}
data-type="wysiwyg"
className="TextInput"
role="textbox"
aria-label={this.props.label}
onBlur={this.handleBlur}
onKeyDown={this.handleKeyDown}
onFocus={this.handleFocus}
>
{this.props.value}
</span>
);
}
}

View File

@ -283,12 +283,14 @@ export const exportCanvas = async (
exportBackground, exportBackground,
exportPadding = 10, exportPadding = 10,
viewBackgroundColor, viewBackgroundColor,
name,
scale = 1, scale = 1,
shouldAddWatermark, shouldAddWatermark,
}: { }: {
exportBackground: boolean; exportBackground: boolean;
exportPadding?: number; exportPadding?: number;
viewBackgroundColor: string; viewBackgroundColor: string;
name: string;
scale?: number; scale?: number;
shouldAddWatermark: boolean; shouldAddWatermark: boolean;
}, },
@ -314,6 +316,7 @@ export const exportCanvas = async (
}); });
if (type === "svg") { if (type === "svg") {
await fileSave(new Blob([tempSvg.outerHTML], { type: "image/svg+xml" }), { await fileSave(new Blob([tempSvg.outerHTML], { type: "image/svg+xml" }), {
fileName: `${name}.svg`,
extensions: [".svg"], extensions: [".svg"],
}); });
return; return;
@ -334,6 +337,7 @@ export const exportCanvas = async (
document.body.appendChild(tempCanvas); document.body.appendChild(tempCanvas);
if (type === "png") { if (type === "png") {
const fileName = `${name}.png`;
let blob = await canvasToBlob(tempCanvas); let blob = await canvasToBlob(tempCanvas);
if (appState.exportEmbedScene) { if (appState.exportEmbedScene) {
blob = await ( blob = await (
@ -345,6 +349,7 @@ export const exportCanvas = async (
} }
await fileSave(blob, { await fileSave(blob, {
fileName,
extensions: [".png"], extensions: [".png"],
}); });
} else if (type === "clipboard") { } else if (type === "clipboard") {

View File

@ -36,6 +36,7 @@ export const saveAsJSON = async (
const fileHandle = await fileSave( const fileHandle = await fileSave(
blob, blob,
{ {
fileName: appState.name,
description: "Excalidraw file", description: "Excalidraw file",
extensions: [".excalidraw"], extensions: [".excalidraw"],
}, },

View File

@ -24,6 +24,7 @@ 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,
}; };
}; };

View File

@ -54,6 +54,7 @@
"architect": "Architect", "architect": "Architect",
"artist": "Artist", "artist": "Artist",
"cartoonist": "Cartoonist", "cartoonist": "Cartoonist",
"fileTitle": "File title",
"colorPicker": "Color picker", "colorPicker": "Color picker",
"canvasBackground": "Canvas background", "canvasBackground": "Canvas background",
"drawingCanvas": "Drawing canvas", "drawingCanvas": "Drawing canvas",
@ -62,6 +63,7 @@
"language": "Language", "language": "Language",
"createRoom": "Share a live-collaboration session", "createRoom": "Share a live-collaboration session",
"duplicateSelection": "Duplicate", "duplicateSelection": "Duplicate",
"untitled": "Untitled",
"name": "Name", "name": "Name",
"yourName": "Your name", "yourName": "Your name",
"madeWithExcalidraw": "Made with Excalidraw", "madeWithExcalidraw": "Made with Excalidraw",

File diff suppressed because it is too large Load Diff

View File

@ -68,6 +68,7 @@ export type AppState = {
cursorY: number; cursorY: number;
cursorButton: "up" | "down"; cursorButton: "up" | "down";
scrolledOutside: boolean; scrolledOutside: boolean;
name: string;
username: string; username: string;
isCollaborating: boolean; isCollaborating: boolean;
isResizing: boolean; isResizing: boolean;