purify getDefaultAppState by removing `name`

make_defaultAppState_pure
dwelle 4 years ago
parent ade2565f49
commit fe973e3513

@ -15,7 +15,7 @@ import { getNormalizedZoom, getSelectedElements } from "../scene";
import { centerScrollOn } from "../scene/scroll";
import { getNewZoom } from "../scene/zoom";
import { AppState, NormalizedZoomValue } from "../types";
import { getShortcutKey } from "../utils";
import { getNewSceneName, getShortcutKey } from "../utils";
import { register } from "./register";
export const actionChangeViewBackgroundColor = register({
@ -59,6 +59,7 @@ export const actionClearCanvas = register({
),
appState: {
...getDefaultAppState(),
name: getNewSceneName(),
appearance: appState.appearance,
elementLocked: appState.elementLocked,
exportBackground: appState.exportBackground,

@ -12,6 +12,7 @@ import { KEYS } from "../keys";
import { muteFSAbortError } from "../utils";
import { register } from "./register";
import "../components/ToolIcon.scss";
import { SCENE_NAME_FALLBACK } from "../constants";
export const actionChangeProjectName = register({
name: "changeProjectName",
@ -22,7 +23,7 @@ export const actionChangeProjectName = register({
PanelComponent: ({ appState, updateData }) => (
<ProjectName
label={t("labels.fileTitle")}
value={appState.name || "Unnamed"}
value={appState.name || SCENE_NAME_FALLBACK}
onChange={(name: string) => updateData(name)}
/>
),

@ -2,16 +2,20 @@ import oc from "open-color";
import {
DEFAULT_FONT_FAMILY,
DEFAULT_FONT_SIZE,
SCENE_NAME_FALLBACK,
DEFAULT_TEXT_ALIGN,
} from "./constants";
import { t } from "./i18n";
import { AppState, FlooredNumber, NormalizedZoomValue } from "./types";
import { getDateTime } from "./utils";
export const getDefaultAppState = (): Omit<
AppState,
"offsetTop" | "offsetLeft"
> => {
type DefaultAppState = Omit<AppState, "offsetTop" | "offsetLeft" | "name"> & {
/**
* You should override this with current appState.name, or whatever is
* applicable at a given place where you get default appState.
*/
name: undefined;
};
export const getDefaultAppState = (): DefaultAppState => {
return {
appearance: "light",
collaborators: new Map(),
@ -50,7 +54,11 @@ export const getDefaultAppState = (): Omit<
isRotating: false,
lastPointerDownWith: "mouse",
multiElement: null,
name: `${t("labels.untitled")}-${getDateTime()}`,
// for safety (because TS mostly doesn't distinguish optional types and
// undefined values), we set `name` to the fallback name, but we cast it to
// `undefined` so that TS forces us to explicitly specify it wherever
// possible
name: (SCENE_NAME_FALLBACK as unknown) as undefined,
openMenu: null,
pasteDialog: { shown: false, data: null },
previousSelectedElementIds: {},

@ -148,6 +148,7 @@ import {
import {
debounce,
distance,
getNewSceneName,
isInputLike,
isToolIcon,
isWritableElement,
@ -281,6 +282,7 @@ class App extends React.Component<ExcalidrawProps, AppState> {
} = props;
this.state = {
...defaultAppState,
name: getNewSceneName(),
isLoading: true,
width,
height,
@ -528,6 +530,7 @@ class App extends React.Component<ExcalidrawProps, AppState> {
this.scene.replaceAllElements([]);
this.setState((state) => ({
...getDefaultAppState(),
name: getNewSceneName(),
isLoading: opts?.resetLoadingState ? false : state.isLoading,
appearance: this.state.appearance,
}));

@ -88,3 +88,5 @@ export const STORAGE_KEYS = {
export const TAP_TWICE_TIMEOUT = 300;
export const TOUCH_CTX_MENU_TIMEOUT = 500;
export const TITLE_TIMEOUT = 10000;
export const SCENE_NAME_FALLBACK = "Untitled";

@ -15,6 +15,7 @@ import {
DEFAULT_VERTICAL_ALIGN,
} from "../constants";
import { getDefaultAppState } from "../appState";
import { getNewSceneName } from "../utils";
const getFontFamilyByName = (fontFamilyName: string): FontFamily => {
for (const [id, fontFamilyString] of Object.entries(FONT_FAMILY)) {
@ -166,6 +167,7 @@ const restoreAppState = (
return {
...nextAppState,
name: appState.name ?? localAppState?.name ?? getNewSceneName(),
offsetLeft: appState.offsetLeft || 0,
offsetTop: appState.offsetTop || 0,
// Migrates from previous version where appState.zoom was a number

@ -6,6 +6,7 @@ import {
} from "../../appState";
import { clearElementsForLocalStorage } from "../../element";
import { STORAGE_KEYS as APP_STORAGE_KEYS } from "../../constants";
import { ImportedDataState } from "../../data/types";
export const STORAGE_KEYS = {
LOCAL_STORAGE_ELEMENTS: "excalidraw",
@ -81,7 +82,7 @@ export const importFromLocalStorage = () => {
}
}
let appState = null;
let appState: ImportedDataState["appState"] = null;
if (savedState) {
try {
appState = {

@ -1,5 +1,6 @@
import { exportToCanvas } from "./scene/export";
import { getDefaultAppState } from "./appState";
import { SCENE_NAME_FALLBACK } from "./constants";
const { registerFont, createCanvas } = require("canvas");
@ -61,6 +62,7 @@ const canvas = exportToCanvas(
elements as any,
{
...getDefaultAppState(),
name: SCENE_NAME_FALLBACK,
offsetTop: 0,
offsetLeft: 0,
},

@ -6,6 +6,7 @@ import { getDefaultAppState } from "../appState";
import { AppState } from "../types";
import { ExcalidrawElement } from "../element/types";
import { getNonDeletedElements } from "../element";
import { SCENE_NAME_FALLBACK } from "../constants";
type ExportOpts = {
elements: readonly ExcalidrawElement[];
@ -18,7 +19,7 @@ type ExportOpts = {
export const exportToCanvas = ({
elements,
appState = getDefaultAppState(),
appState = { ...getDefaultAppState(), name: SCENE_NAME_FALLBACK },
getDimensions = (width, height) => ({ width, height, scale: 1 }),
}: ExportOpts) => {
return _exportToCanvas(
@ -74,7 +75,7 @@ export const exportToBlob = (
export const exportToSvg = ({
elements,
appState = getDefaultAppState(),
appState = { ...getDefaultAppState(), name: SCENE_NAME_FALLBACK },
exportPadding,
metadata,
}: ExportOpts & {

@ -8,6 +8,7 @@ import { FontFamily, FontString } from "./element/types";
import { Zoom } from "./types";
import { unstable_batchedUpdates } from "react-dom";
import { isDarwin } from "./keys";
import { t } from "./i18n";
export const SVG_NS = "http://www.w3.org/2000/svg";
@ -32,6 +33,10 @@ export const getDateTime = () => {
return `${year}-${month}-${day}-${hr}${min}`;
};
export const getNewSceneName = () => {
return `${t("labels.untitled")}-${getDateTime()}`;
};
export const capitalizeString = (str: string) =>
str.charAt(0).toUpperCase() + str.slice(1);

Loading…
Cancel
Save