mirror of
https://github.com/zadam/trilium.git
synced 2025-12-16 21:29:56 +01:00
feat(layout): integrate file-similar options to image
This commit is contained in:
@@ -199,8 +199,7 @@ export function getLocaleName(locale: Locale | null | undefined) {
|
|||||||
//#region Note info
|
//#region Note info
|
||||||
export function NoteInfoBadge({ note }: { note: FNote | null | undefined }) {
|
export function NoteInfoBadge({ note }: { note: FNote | null | undefined }) {
|
||||||
const { metadata, ...sizeProps } = useNoteMetadata(note);
|
const { metadata, ...sizeProps } = useNoteMetadata(note);
|
||||||
const [ originalFileName ] = useNoteLabel(note?.type === "file" ? note : null, "originalFileName");
|
const [ originalFileName ] = useNoteLabel(note, "originalFileName");
|
||||||
|
|
||||||
|
|
||||||
return (note &&
|
return (note &&
|
||||||
<StatusBarDropdown
|
<StatusBarDropdown
|
||||||
|
|||||||
@@ -1,14 +1,16 @@
|
|||||||
import { t } from "../../services/i18n";
|
|
||||||
import { useNoteBlob, useNoteLabel } from "../react/hooks";
|
|
||||||
import { TabContext } from "./ribbon-interface";
|
|
||||||
import { clearBrowserCache, formatSize } from "../../services/utils";
|
|
||||||
import Button from "../react/Button";
|
|
||||||
import { downloadFileNote, openNoteExternally } from "../../services/open";
|
|
||||||
import { ParentComponent } from "../react/react_utils";
|
|
||||||
import { useContext } from "preact/hooks";
|
import { useContext } from "preact/hooks";
|
||||||
import { FormFileUploadButton } from "../react/FormFileUpload";
|
|
||||||
|
import FNote from "../../entities/fnote";
|
||||||
|
import { t } from "../../services/i18n";
|
||||||
|
import { downloadFileNote, openNoteExternally } from "../../services/open";
|
||||||
import server from "../../services/server";
|
import server from "../../services/server";
|
||||||
import toast from "../../services/toast";
|
import toast from "../../services/toast";
|
||||||
|
import { clearBrowserCache, formatSize } from "../../services/utils";
|
||||||
|
import Button from "../react/Button";
|
||||||
|
import { FormFileUploadButton } from "../react/FormFileUpload";
|
||||||
|
import { useNoteBlob, useNoteLabel } from "../react/hooks";
|
||||||
|
import { ParentComponent } from "../react/react_utils";
|
||||||
|
import { TabContext } from "./ribbon-interface";
|
||||||
|
|
||||||
export default function ImagePropertiesTab({ note, ntxId }: TabContext) {
|
export default function ImagePropertiesTab({ note, ntxId }: TabContext) {
|
||||||
const [ originalFileName ] = useNoteLabel(note, "originalFileName");
|
const [ originalFileName ] = useNoteLabel(note, "originalFileName");
|
||||||
@@ -60,23 +62,27 @@ export default function ImagePropertiesTab({ note, ntxId }: TabContext) {
|
|||||||
<FormFileUploadButton
|
<FormFileUploadButton
|
||||||
text={t("image_properties.upload_new_revision")}
|
text={t("image_properties.upload_new_revision")}
|
||||||
icon="bx bx-folder-open"
|
icon="bx bx-folder-open"
|
||||||
onChange={async (files) => {
|
onChange={buildUploadNewImageRevisionListener(note)}
|
||||||
if (!files) return;
|
|
||||||
const fileToUpload = files[0]; // copy to allow reset below
|
|
||||||
|
|
||||||
const result = await server.upload(`images/${note.noteId}`, fileToUpload);
|
|
||||||
|
|
||||||
if (result.uploaded) {
|
|
||||||
toast.showMessage(t("image_properties.upload_success"));
|
|
||||||
await clearBrowserCache();
|
|
||||||
} else {
|
|
||||||
toast.showError(t("image_properties.upload_failed", { message: result.message }));
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
)
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function buildUploadNewImageRevisionListener(note: FNote) {
|
||||||
|
return async (files: FileList | null) => {
|
||||||
|
if (!files) return;
|
||||||
|
const fileToUpload = files[0]; // copy to allow reset below
|
||||||
|
|
||||||
|
const result = await server.upload(`images/${note.noteId}`, fileToUpload);
|
||||||
|
|
||||||
|
if (result.uploaded) {
|
||||||
|
toast.showMessage(t("image_properties.upload_success"));
|
||||||
|
await clearBrowserCache();
|
||||||
|
} else {
|
||||||
|
toast.showError(t("image_properties.upload_failed", { message: result.message }));
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import protected_session_holder from "../../services/protected_session_holder";
|
|||||||
import ActionButton from "../react/ActionButton";
|
import ActionButton from "../react/ActionButton";
|
||||||
import { FormFileUploadActionButton } from "../react/FormFileUpload";
|
import { FormFileUploadActionButton } from "../react/FormFileUpload";
|
||||||
import { buildUploadNewFileRevisionListener } from "./FilePropertiesTab";
|
import { buildUploadNewFileRevisionListener } from "./FilePropertiesTab";
|
||||||
|
import { buildUploadNewImageRevisionListener } from "./ImagePropertiesTab";
|
||||||
|
|
||||||
interface NoteActionsCustomProps {
|
interface NoteActionsCustomProps {
|
||||||
note: FNote;
|
note: FNote;
|
||||||
@@ -22,38 +23,74 @@ export default function NoteActionsCustom({ note }: NoteActionsCustomProps) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//#region Note type mappings
|
||||||
function NoteActionsCustomInner(props: NoteActionsCustomProps) {
|
function NoteActionsCustomInner(props: NoteActionsCustomProps) {
|
||||||
switch (props.note.type) {
|
switch (props.note.type) {
|
||||||
case "file":
|
case "file":
|
||||||
return <FileActions {...props} />;
|
return <FileActions {...props} />;
|
||||||
|
case "image":
|
||||||
|
return <ImageActions {...props} />;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function FileActions({ note }: NoteActionsCustomProps) {
|
function FileActions({ note }: NoteActionsCustomProps) {
|
||||||
const canAccessProtectedNote = !note?.isProtected || protected_session_holder.isProtectedSessionAvailable();
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<FormFileUploadActionButton
|
<UploadNewRevisionButton note={note} onChange={buildUploadNewFileRevisionListener(note)} />
|
||||||
icon="bx bx-folder-open"
|
<OpenExternallyButton note={note} />
|
||||||
text={t("file_properties.upload_new_revision")}
|
<DownloadFileButton note={note} />
|
||||||
disabled={!canAccessProtectedNote}
|
|
||||||
onChange={buildUploadNewFileRevisionListener(note)}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<ActionButton
|
|
||||||
icon="bx bx-link-external"
|
|
||||||
text={t("file_properties.open")}
|
|
||||||
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)}
|
|
||||||
/>
|
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function ImageActions({ note }: NoteActionsCustomProps) {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<UploadNewRevisionButton note={note} onChange={buildUploadNewImageRevisionListener(note)} />
|
||||||
|
<OpenExternallyButton note={note} />
|
||||||
|
<DownloadFileButton note={note} />
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
//#endregion
|
||||||
|
|
||||||
|
//#region Shared buttons
|
||||||
|
function UploadNewRevisionButton({ note, onChange }: NoteActionsCustomProps & {
|
||||||
|
onChange: (files: FileList | null) => void;
|
||||||
|
}) {
|
||||||
|
const canAccessProtectedNote = !note?.isProtected || protected_session_holder.isProtectedSessionAvailable();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<FormFileUploadActionButton
|
||||||
|
icon="bx bx-folder-open"
|
||||||
|
text={t("image_properties.upload_new_revision")}
|
||||||
|
disabled={!canAccessProtectedNote}
|
||||||
|
onChange={onChange}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function OpenExternallyButton({ note }: NoteActionsCustomProps) {
|
||||||
|
return (
|
||||||
|
<ActionButton
|
||||||
|
icon="bx bx-link-external"
|
||||||
|
text={t("file_properties.open")}
|
||||||
|
disabled={note.isProtected}
|
||||||
|
onClick={() => openNoteExternally(note.noteId, note.mime)}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function DownloadFileButton({ note }: NoteActionsCustomProps) {
|
||||||
|
const canAccessProtectedNote = !note?.isProtected || protected_session_holder.isProtectedSessionAvailable();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ActionButton
|
||||||
|
icon="bx bx-download"
|
||||||
|
text={t("file_properties.download")}
|
||||||
|
disabled={!canAccessProtectedNote}
|
||||||
|
onClick={() => downloadFileNote(note.noteId)}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
//#endregion
|
||||||
|
|||||||
@@ -82,7 +82,7 @@ export const RIBBON_TAB_DEFINITIONS: TabConfiguration[] = [
|
|||||||
title: t("image_properties.title"),
|
title: t("image_properties.title"),
|
||||||
icon: "bx bx-image",
|
icon: "bx bx-image",
|
||||||
content: ImagePropertiesTab,
|
content: ImagePropertiesTab,
|
||||||
show: ({ note }) => note?.type === "image",
|
show: ({ note }) => !isNewLayout && note?.type === "image",
|
||||||
toggleCommand: "toggleRibbonTabImageProperties",
|
toggleCommand: "toggleRibbonTabImageProperties",
|
||||||
activate: true,
|
activate: true,
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user