feat(layout/file): upload new revision button

This commit is contained in:
Elian Doran
2025-12-14 22:14:05 +02:00
parent 20f4990d48
commit 8ba2357d91
3 changed files with 63 additions and 26 deletions

View File

@@ -1,7 +1,9 @@
import { Ref } from "preact";
import Button, { ButtonProps } from "./Button";
import { useEffect, useRef } from "preact/hooks";
import ActionButton, { ActionButtonProps } from "./ActionButton";
import Button, { ButtonProps } from "./Button";
interface FormFileUploadProps {
name?: string;
onChange: (files: FileList | null) => void;
@@ -26,7 +28,7 @@ export default function FormFileUpload({ inputRef, name, onChange, multiple, hid
multiple={multiple}
onChange={e => onChange((e.target as HTMLInputElement).files)} />
</label>
)
);
}
/**
@@ -49,5 +51,27 @@ export function FormFileUploadButton({ onChange, ...buttonProps }: Omit<ButtonPr
onChange={onChange}
/>
</>
)
);
}
/**
* Similar to {@link FormFileUploadButton}, but uses an {@link ActionButton} instead of a normal {@link Button}.
* @param param the change listener for the file upload and the properties for the button.
*/
export function FormFileUploadActionButton({ onChange, ...buttonProps }: Omit<ActionButtonProps, "onClick"> & Pick<FormFileUploadProps, "onChange">) {
const inputRef = useRef<HTMLInputElement>(null);
return (
<>
<ActionButton
{...buttonProps}
onClick={() => inputRef.current?.click()}
/>
<FormFileUpload
inputRef={inputRef}
hidden
onChange={onChange}
/>
</>
);
}

View File

@@ -1,13 +1,13 @@
import FNote from "../../entities/fnote";
import { t } from "../../services/i18n";
import { downloadFileNote, openNoteExternally } from "../../services/open";
import protected_session_holder from "../../services/protected_session_holder";
import server from "../../services/server";
import toast from "../../services/toast";
import { formatSize } from "../../services/utils";
import Button from "../react/Button";
import { FormFileUploadButton } from "../react/FormFileUpload";
import { useNoteBlob, useNoteLabel } from "../react/hooks";
import Button from "../react/Button";
import protected_session_holder from "../../services/protected_session_holder";
import { downloadFileNote, openNoteExternally } from "../../services/open";
import toast from "../../services/toast";
import server from "../../services/server";
import FNote from "../../entities/fnote";
export default function FilePropertiesTab({ note }: { note?: FNote | null }) {
const [ originalFileName ] = useNoteLabel(note, "originalFileName");
@@ -54,19 +54,7 @@ export default function FilePropertiesTab({ note }: { note?: FNote | null }) {
icon="bx bx-folder-open"
text={t("file_properties.upload_new_revision")}
disabled={!canAccessProtectedNote}
onChange={(fileToUpload) => {
if (!fileToUpload) {
return;
}
server.upload(`notes/${note.noteId}/file`, fileToUpload[0]).then((result) => {
if (result.uploaded) {
toast.showMessage(t("file_properties.upload_success"));
} else {
toast.showError(t("file_properties.upload_failed"));
}
});
}}
onChange={buildUploadNewFileRevisionListener(note)}
/>
</div>
</td>
@@ -77,3 +65,19 @@ export default function FilePropertiesTab({ note }: { note?: FNote | null }) {
</div>
);
}
export function buildUploadNewFileRevisionListener(note: FNote) {
return (fileToUpload: FileList | null) => {
if (!fileToUpload) {
return;
}
server.upload(`notes/${note.noteId}/file`, fileToUpload[0]).then((result) => {
if (result.uploaded) {
toast.showMessage(t("file_properties.upload_success"));
} else {
toast.showError(t("file_properties.upload_failed"));
}
});
};
}

View File

@@ -20,10 +20,12 @@ import CreatePaneButton from "../buttons/create_pane_button";
import MovePaneButton from "../buttons/move_pane_button";
import ActionButton from "../react/ActionButton";
import Dropdown from "../react/Dropdown";
import { FormFileUploadActionButton } from "../react/FormFileUpload";
import { FormDropdownDivider, FormDropdownSubmenu, FormListHeader, FormListItem, FormListToggleableItem } from "../react/FormList";
import { useIsNoteReadOnly, useNoteContext, useNoteLabel, useNoteLabelBoolean, useNoteProperty, useTriliumOption } from "../react/hooks";
import { ParentComponent } from "../react/react_utils";
import { NoteTypeDropdownContent, useNoteBookmarkState, useShareState } from "./BasicPropertiesTab";
import { buildUploadNewFileRevisionListener } from "./FilePropertiesTab";
const isNewLayout = isExperimentalFeatureEnabled("new-layout");
@@ -283,11 +285,11 @@ function FileActions({ note }: { note: FNote }) {
return (note.type === "file" &&
<>
<ActionButton
icon="bx bx-download"
text={t("file_properties.download")}
<FormFileUploadActionButton
icon="bx bx-folder-open"
text={t("file_properties.upload_new_revision")}
disabled={!canAccessProtectedNote}
onClick={() => downloadFileNote(note.noteId)}
onChange={buildUploadNewFileRevisionListener(note)}
/>
<ActionButton
@@ -296,6 +298,13 @@ function FileActions({ note }: { note: FNote }) {
disabled={note.isProtected}
onClick={() => openNoteExternally(note.noteId, note.mime)}
/>
<ActionButton
icon="bx bx-download"
text={t("file_properties.download")}
disabled={!canAccessProtectedNote}
onClick={() => downloadFileNote(note.noteId)}
/>
</>
);
}