Browse Source

feat: Show active file name when saving to current file (#3733)

* feat: Show active file name when saving to current file

* Make requested changes

* More changes
Arun 3 years ago
parent
commit
74a2f16501

+ 6 - 9
src/actions/actionExport.tsx

@@ -1,6 +1,6 @@
 import React from "react";
 import { trackEvent } from "../analytics";
-import { load, questionCircle, save, saveAs } from "../components/icons";
+import { load, questionCircle, saveAs } from "../components/icons";
 import { ProjectName } from "../components/ProjectName";
 import { ToolButton } from "../components/ToolButton";
 import "../components/ToolIcon.scss";
@@ -17,6 +17,7 @@ import { getExportSize } from "../scene/export";
 import { DEFAULT_EXPORT_PADDING, EXPORT_SCALES } from "../constants";
 import { getSelectedElements, isSomeElementSelected } from "../scene";
 import { getNonDeletedElements } from "../element";
+import { ActiveFile } from "../components/ActiveFile";
 
 export const actionChangeProjectName = register({
   name: "changeProjectName",
@@ -153,14 +154,10 @@ export const actionSaveToActiveFile = register({
   },
   keyTest: (event) =>
     event.key === KEYS.S && event[KEYS.CTRL_OR_CMD] && !event.shiftKey,
-  PanelComponent: ({ updateData }) => (
-    <ToolButton
-      type="icon"
-      icon={save}
-      title={t("buttons.save")}
-      aria-label={t("buttons.save")}
-      onClick={() => updateData(null)}
-      data-testid="save-button"
+  PanelComponent: ({ updateData, appState }) => (
+    <ActiveFile
+      onSave={() => updateData(null)}
+      fileName={appState.fileHandle?.name}
     />
   ),
 });

+ 21 - 0
src/components/ActiveFile.scss

@@ -0,0 +1,21 @@
+.excalidraw {
+  .ActiveFile {
+    .ActiveFile__fileName {
+      display: flex;
+      align-items: center;
+
+      span {
+        text-overflow: ellipsis;
+        overflow: hidden;
+        white-space: nowrap;
+        width: 9.3em;
+      }
+
+      svg {
+        width: 1.15em;
+        margin-inline-end: 0.3em;
+        transform: scaleY(0.9);
+      }
+    }
+  }
+}

+ 29 - 0
src/components/ActiveFile.tsx

@@ -0,0 +1,29 @@
+import React from "react";
+import Stack from "../components/Stack";
+import { ToolButton } from "../components/ToolButton";
+import { save, file } from "../components/icons";
+import { t } from "../i18n";
+
+import "./ActiveFile.scss";
+
+type ActiveFileProps = {
+  fileName?: string;
+  onSave: () => void;
+};
+
+export const ActiveFile = ({ fileName, onSave }: ActiveFileProps) => (
+  <Stack.Row className="ActiveFile" gap={1} align="center">
+    <span className="ActiveFile__fileName">
+      {file}
+      <span>{fileName}</span>
+    </span>
+    <ToolButton
+      type="icon"
+      icon={save}
+      title={t("buttons.save")}
+      aria-label={t("buttons.save")}
+      onClick={onSave}
+      data-testid="save-button"
+    />
+  </Stack.Row>
+);

+ 0 - 5
src/components/BackgroundPickerAndDarkModeToggle.tsx

@@ -16,10 +16,5 @@ export const BackgroundPickerAndDarkModeToggle = ({
   <div style={{ display: "flex" }}>
     {actionManager.renderAction("changeViewBackgroundColor")}
     {showThemeBtn && actionManager.renderAction("toggleTheme")}
-    {appState.fileHandle && (
-      <div style={{ marginInlineStart: "0.25rem" }}>
-        {actionManager.renderAction("saveToActiveFile")}
-      </div>
-    )}
   </div>
 );

+ 5 - 1
src/components/LayerUI.tsx

@@ -488,6 +488,9 @@ const LayerUI = ({
             setAppState={setAppState}
             showThemeBtn={showThemeBtn}
           />
+          {appState.fileHandle && (
+            <>{actionManager.renderAction("saveToActiveFile")}</>
+          )}
         </Stack.Col>
       </Island>
     </Section>
@@ -506,7 +509,8 @@ const LayerUI = ({
         style={{
           // we want to make sure this doesn't overflow so substracting 200
           // which is approximately height of zoom footer and top left menu items with some buffer
-          maxHeight: `${appState.height - 200}px`,
+          // if active file name is displayed, subtracting 248 to account for its height
+          maxHeight: `${appState.height - (appState.fileHandle ? 248 : 200)}px`,
         }}
       >
         <SelectedShapeActions

+ 5 - 0
src/components/icons.tsx

@@ -477,6 +477,11 @@ export const shield = createIcon(
   { width: 24 },
 );
 
+export const file = createIcon(
+  "M369.9 97.9L286 14C277 5 264.8-.1 252.1-.1H48C21.5 0 0 21.5 0 48v416c0 26.5 21.5 48 48 48h288c26.5 0 48-21.5 48-48V131.9c0-12.7-5.1-25-14.1-34zM332.1 128H256V51.9l76.1 76.1zM48 464V48h160v104c0 13.3 10.7 24 24 24h104v288H48zm32-48h224V288l-23.5-23.5c-4.7-4.7-12.3-4.7-17 0L176 352l-39.5-39.5c-4.7-4.7-12.3-4.7-17 0L80 352v64zm48-240c-26.5 0-48 21.5-48 48s21.5 48 48 48 48-21.5 48-48-21.5-48-48-48z",
+  { width: 384, height: 512 },
+);
+
 export const GroupIcon = React.memo(({ theme }: { theme: "light" | "dark" }) =>
   createIcon(
     <>