feat(breadcrumb/note_info): note size

This commit is contained in:
Elian Doran 2025-12-11 00:34:25 +02:00
parent e5696713de
commit 4b74ad5577
No known key found for this signature in database
2 changed files with 35 additions and 21 deletions

View File

@ -10,7 +10,7 @@ import { BacklinksList, useBacklinkCount } from "./FloatingButtonsDefinitions";
import Dropdown, { DropdownProps } from "./react/Dropdown"; import Dropdown, { DropdownProps } from "./react/Dropdown";
import { useIsNoteReadOnly, useNoteContext, useStaticTooltip } from "./react/hooks"; import { useIsNoteReadOnly, useNoteContext, useStaticTooltip } from "./react/hooks";
import Icon from "./react/Icon"; import Icon from "./react/Icon";
import { useNoteMetadata } from "./ribbon/NoteInfoTab"; import { NoteSizeWidget, useNoteMetadata } from "./ribbon/NoteInfoTab";
import { useShareInfo } from "./shared_info"; import { useShareInfo } from "./shared_info";
export default function BreadcrumbBadges() { export default function BreadcrumbBadges() {
@ -26,18 +26,20 @@ export default function BreadcrumbBadges() {
function NoteInfoBadge() { function NoteInfoBadge() {
const { note } = useNoteContext(); const { note } = useNoteContext();
const { isLoading, metadata, noteSizeResponse, subtreeSizeResponse, requestSizeInfo } = useNoteMetadata(note); const { metadata, ...sizeProps } = useNoteMetadata(note);
return (note && return (note &&
<BadgeWithDropdown <BadgeWithDropdown
icon="bx bx-info-circle" icon="bx bx-info-circle"
className="note-info-badge" className="note-info-badge"
dropdownOptions={{ dropdownOptions: { autoClose: "outside" } }}
> >
<ul> <ul>
<NoteInfoValue text={t("note_info_widget.created")} value={metadata?.dateCreated ? formatDateTime(metadata.dateCreated) : ""} /> <NoteInfoValue text={t("note_info_widget.created")} value={metadata?.dateCreated ? formatDateTime(metadata.dateCreated) : ""} />
<NoteInfoValue text={t("note_info_widget.modified")} value={metadata?.dateModified ? formatDateTime(metadata.dateModified) : ""} /> <NoteInfoValue text={t("note_info_widget.modified")} value={metadata?.dateModified ? formatDateTime(metadata.dateModified) : ""} />
<NoteInfoValue text={t("note_info_widget.type")} value={<span>{note.type} {note.mime && <span>({note.mime})</span>}</span>} /> <NoteInfoValue text={t("note_info_widget.type")} value={<span>{note.type} {note.mime && <span>({note.mime})</span>}</span>} />
<NoteInfoValue text={t("note_info_widget.note_id")} value={<code>{note.noteId}</code>} /> <NoteInfoValue text={t("note_info_widget.note_id")} value={<code>{note.noteId}</code>} />
<NoteInfoValue text={t("note_info_widget.note_size")} value={<NoteSizeWidget {...sizeProps} />} />
</ul> </ul>
</BadgeWithDropdown> </BadgeWithDropdown>
); );
@ -161,8 +163,14 @@ function BadgeWithDropdown({ children, tooltip, className, dropdownOptions, ...p
hideToggleArrow hideToggleArrow
title={tooltip} title={tooltip}
titlePosition="bottom" titlePosition="bottom"
dropdownOptions={{ popperConfig: { placement: "bottom", strategy: "fixed" } }}
{...dropdownOptions} {...dropdownOptions}
dropdownOptions={{
...dropdownOptions?.dropdownOptions,
popperConfig: {
...dropdownOptions?.dropdownOptions?.popperConfig,
placement: "bottom", strategy: "fixed"
}
}}
>{children}</Dropdown> >{children}</Dropdown>
); );
} }

View File

@ -13,7 +13,7 @@ import FNote from "../../entities/fnote";
const isNewLayout = isExperimentalFeatureEnabled("new-layout"); const isNewLayout = isExperimentalFeatureEnabled("new-layout");
export default function NoteInfoTab({ note }: { note: FNote | null | undefined }) { export default function NoteInfoTab({ note }: { note: FNote | null | undefined }) {
const { isLoading, metadata, noteSizeResponse, subtreeSizeResponse, requestSizeInfo } = useNoteMetadata(note); const { metadata, ...sizeProps } = useNoteMetadata(note);
return ( return (
<div className="note-info-widget"> <div className="note-info-widget">
@ -41,23 +41,7 @@ export default function NoteInfoTab({ note }: { note: FNote | null | undefined }
<div className="note-info-item"> <div className="note-info-item">
<span title={t("note_info_widget.note_size_info")}>{t("note_info_widget.note_size")}:</span> <span title={t("note_info_widget.note_size_info")}>{t("note_info_widget.note_size")}:</span>
<span className="note-info-size-col-span"> <span className="note-info-size-col-span">
{!isLoading && !noteSizeResponse && !subtreeSizeResponse && ( <NoteSizeWidget {...sizeProps} />
<Button
className="calculate-button"
icon="bx bx-calculator"
text={t("note_info_widget.calculate")}
onClick={requestSizeInfo}
/>
)}
<span className="note-sizes-wrapper selectable-text">
<span className="note-size">{formatSize(noteSizeResponse?.noteSize)}</span>
{" "}
{subtreeSizeResponse && subtreeSizeResponse.subTreeNoteCount > 1 &&
<span className="subtree-size">{t("note_info_widget.subtree_size", { size: formatSize(subtreeSizeResponse.subTreeSize), count: subtreeSizeResponse.subTreeNoteCount })}</span>
}
{isLoading && <LoadingSpinner />}
</span>
</span> </span>
</div> </div>
</> </>
@ -66,6 +50,28 @@ export default function NoteInfoTab({ note }: { note: FNote | null | undefined }
); );
} }
export function NoteSizeWidget({ isLoading, noteSizeResponse, subtreeSizeResponse, requestSizeInfo }: Omit<ReturnType<typeof useNoteMetadata>, "metadata">) {
return <>
{!isLoading && !noteSizeResponse && !subtreeSizeResponse && (
<Button
className="calculate-button"
icon="bx bx-calculator"
text={t("note_info_widget.calculate")}
onClick={requestSizeInfo}
/>
)}
<span className="note-sizes-wrapper selectable-text">
<span className="note-size">{formatSize(noteSizeResponse?.noteSize)}</span>
{" "}
{subtreeSizeResponse && subtreeSizeResponse.subTreeNoteCount > 1 &&
<span className="subtree-size">{t("note_info_widget.subtree_size", { size: formatSize(subtreeSizeResponse.subTreeSize), count: subtreeSizeResponse.subTreeNoteCount })}</span>
}
{isLoading && <LoadingSpinner />}
</span>
</>;
}
export function useNoteMetadata(note: FNote | null | undefined) { export function useNoteMetadata(note: FNote | null | undefined) {
const [ isLoading, setIsLoading ] = useState(false); const [ isLoading, setIsLoading ] = useState(false);
const [ noteSizeResponse, setNoteSizeResponse ] = useState<NoteSizeResponse>(); const [ noteSizeResponse, setNoteSizeResponse ] = useState<NoteSizeResponse>();