mirror of
https://github.com/zadam/trilium.git
synced 2025-12-15 11:54:24 +01:00
feat(status_bar): add new attachment count
This commit is contained in:
parent
95d2160c76
commit
6eff62f73f
@ -2156,8 +2156,9 @@
|
||||
"status_bar": {
|
||||
"language_title": "Change the language of the entire content",
|
||||
"note_info_title": "View information about this note such as the creation/modification date or the note size.",
|
||||
"backlinks": "{{count}}",
|
||||
"backlinks_title_one": "This note is linked from {{count}} other note.\n\nClick to view the list of backlinks.",
|
||||
"backlinks_title_other": "This note is linked from {{count}} other notes.\n\nClick to view the list of backlinks."
|
||||
"backlinks_title_other": "This note is linked from {{count}} other notes.\n\nClick to view the list of backlinks.",
|
||||
"attachments_title_one": "This note has {{count}} attachment. Click to open the list of attachments in a new tab.",
|
||||
"attachments_title_other": "This note has {{count}} attachments. Click to open the list of attachments in a new tab."
|
||||
}
|
||||
}
|
||||
|
||||
@ -15,27 +15,29 @@
|
||||
padding: 0.1em;
|
||||
display: flex;
|
||||
gap: 0.1em;
|
||||
font-size: 0.85em;
|
||||
|
||||
.status-bar-dropdown-button {
|
||||
background: transparent;
|
||||
.btn {
|
||||
padding: 0 0.5em !important;
|
||||
background: transparent;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
&:after {
|
||||
content: unset;
|
||||
}
|
||||
border: 0;
|
||||
|
||||
&:focus,
|
||||
&:hover {
|
||||
background: var(--input-background-color);
|
||||
}
|
||||
}
|
||||
|
||||
.status-bar-dropdown-button {
|
||||
&:after {
|
||||
content: unset;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.dropdown {
|
||||
font-size: 0.85em;
|
||||
|
||||
.dropdown-toggle {
|
||||
padding: 0.1em 0.25em;
|
||||
}
|
||||
|
||||
@ -4,7 +4,7 @@ import { Locale } from "@triliumnext/commons";
|
||||
import clsx from "clsx";
|
||||
import { type ComponentChildren } from "preact";
|
||||
import { createPortal } from "preact/compat";
|
||||
import { useState } from "preact/hooks";
|
||||
import { useContext, useRef, useState } from "preact/hooks";
|
||||
|
||||
import NoteContext from "../../components/note_context";
|
||||
import FNote from "../../entities/fnote";
|
||||
@ -15,12 +15,17 @@ import { formatDateTime } from "../../utils/formatters";
|
||||
import { BacklinksList, useBacklinkCount } from "../FloatingButtonsDefinitions";
|
||||
import Dropdown, { DropdownProps } from "../react/Dropdown";
|
||||
import { FormDropdownDivider, FormListItem } from "../react/FormList";
|
||||
import { useActiveNoteContext } from "../react/hooks";
|
||||
import { useActiveNoteContext, useStaticTooltip, useTooltip } from "../react/hooks";
|
||||
import Icon from "../react/Icon";
|
||||
import { ContentLanguagesModal, useLanguageSwitcher } from "../ribbon/BasicPropertiesTab";
|
||||
import { NoteSizeWidget, useNoteMetadata } from "../ribbon/NoteInfoTab";
|
||||
import { useProcessedLocales } from "../type_widgets/options/components/LocaleSelector";
|
||||
import Breadcrumb from "./Breadcrumb";
|
||||
import { useAttachments } from "../type_widgets/Attachment";
|
||||
import ActionButton from "../react/ActionButton";
|
||||
import Button from "../react/Button";
|
||||
import { CommandNames } from "../../components/app_context";
|
||||
import { ParentComponent } from "../react/react_utils";
|
||||
|
||||
interface StatusBarContext {
|
||||
note: FNote;
|
||||
@ -40,6 +45,7 @@ export default function StatusBar() {
|
||||
</div>
|
||||
|
||||
<div className="actions-row">
|
||||
<AttachmentCount {...context} />
|
||||
<BacklinksBadge {...context} />
|
||||
<LanguageSwitcher {...context} />
|
||||
<NoteInfoBadge {...context} />
|
||||
@ -75,6 +81,35 @@ function StatusBarDropdown({ children, icon, text, buttonClassName, titleOptions
|
||||
);
|
||||
}
|
||||
|
||||
function StatusBarButton({ className, icon, text, title, triggerCommand }: {
|
||||
className?: string;
|
||||
icon: string;
|
||||
title: string;
|
||||
text?: string | number;
|
||||
disabled?: boolean;
|
||||
triggerCommand: CommandNames;
|
||||
}) {
|
||||
const parentComponent = useContext(ParentComponent);
|
||||
const buttonRef = useRef<HTMLButtonElement>(null);
|
||||
useStaticTooltip(buttonRef, {
|
||||
placement: "top",
|
||||
fallbackPlacements: [ "top" ],
|
||||
popperConfig: { strategy: "fixed" },
|
||||
title
|
||||
});
|
||||
|
||||
return (
|
||||
<button
|
||||
ref={buttonRef}
|
||||
className={clsx("btn select-button", className)}
|
||||
type="button"
|
||||
onClick={() => parentComponent?.triggerCommand(triggerCommand)}
|
||||
>
|
||||
<Icon icon={icon} /> {text}
|
||||
</button>
|
||||
);
|
||||
}
|
||||
|
||||
//#region Language Switcher
|
||||
function LanguageSwitcher({ note }: StatusBarContext) {
|
||||
const [ modalShown, setModalShown ] = useState(false);
|
||||
@ -166,7 +201,7 @@ function BacklinksBadge({ note, viewScope }: StatusBarContext) {
|
||||
<StatusBarDropdown
|
||||
className="backlinks-badge backlinks-widget"
|
||||
icon="bx bx-revision"
|
||||
text={t("status_bar.backlinks", { count })}
|
||||
text={count}
|
||||
title={t("status_bar.backlinks_title", { count })}
|
||||
dropdownContainerClassName="backlinks-items"
|
||||
>
|
||||
@ -175,3 +210,20 @@ function BacklinksBadge({ note, viewScope }: StatusBarContext) {
|
||||
);
|
||||
}
|
||||
//#endregion
|
||||
|
||||
//#region Attachment count
|
||||
function AttachmentCount({ note }: StatusBarContext) {
|
||||
const attachments = useAttachments(note);
|
||||
const count = attachments.length;
|
||||
|
||||
return (note && count > 0 &&
|
||||
<StatusBarButton
|
||||
className="attachment-count"
|
||||
icon="bx bx-paperclip"
|
||||
text={count}
|
||||
title={t("status_bar.attachments_title", { count })}
|
||||
triggerCommand="showAttachments"
|
||||
/>
|
||||
);
|
||||
}
|
||||
//#endregion
|
||||
|
||||
@ -26,24 +26,13 @@ import ws from "../../services/ws";
|
||||
import appContext from "../../components/app_context";
|
||||
import { ConvertAttachmentToNoteResponse } from "@triliumnext/commons";
|
||||
import options from "../../services/options";
|
||||
import FNote from "../../entities/fnote";
|
||||
|
||||
/**
|
||||
* Displays the full list of attachments of a note and allows the user to interact with them.
|
||||
*/
|
||||
export function AttachmentList({ note }: TypeWidgetProps) {
|
||||
const [ attachments, setAttachments ] = useState<FAttachment[]>([]);
|
||||
|
||||
function refresh() {
|
||||
note.getAttachments().then(attachments => setAttachments(Array.from(attachments)));
|
||||
}
|
||||
|
||||
useEffect(refresh, [ note ]);
|
||||
|
||||
useTriliumEvent("entitiesReloaded", ({ loadResults }) => {
|
||||
if (loadResults.getAttachmentRows().some((att) => att.attachmentId && att.ownerId === note.noteId)) {
|
||||
refresh();
|
||||
}
|
||||
});
|
||||
const attachments = useAttachments(note);
|
||||
|
||||
return (
|
||||
<>
|
||||
@ -59,7 +48,25 @@ export function AttachmentList({ note }: TypeWidgetProps) {
|
||||
)}
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
export function useAttachments(note: FNote) {
|
||||
const [ attachments, setAttachments ] = useState<FAttachment[]>([]);
|
||||
|
||||
function refresh() {
|
||||
note.getAttachments().then(attachments => setAttachments(Array.from(attachments)));
|
||||
}
|
||||
|
||||
useEffect(refresh, [ note ]);
|
||||
|
||||
useTriliumEvent("entitiesReloaded", ({ loadResults }) => {
|
||||
if (loadResults.getAttachmentRows().some((att) => att.attachmentId && att.ownerId === note.noteId)) {
|
||||
refresh();
|
||||
}
|
||||
});
|
||||
|
||||
return attachments;
|
||||
}
|
||||
|
||||
function AttachmentListHeader({ noteId }: { noteId: string }) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user