chore(react/note_icon): react to icon changes

This commit is contained in:
Elian Doran 2025-08-21 15:50:14 +03:00
parent 9d54503ef7
commit a106510924
No known key found for this signature in database
3 changed files with 34 additions and 28 deletions

View File

@ -20,20 +20,6 @@ export default class NoteIconWidget extends NoteContextAwareWidget {
this.$iconList = this.$widget.find(".icon-list");
}
async entitiesReloadedEvent({ loadResults }: EventData<"entitiesReloaded">) {
if (this.noteId && loadResults.isNoteReloaded(this.noteId)) {
this.refresh();
return;
}
for (const attr of loadResults.getAttributeRows()) {
if (attr.type === "label" && ["iconClass", "workspaceIconClass"].includes(attr.name ?? "") && attributeService.isAffecting(attr, this.note)) {
this.refresh();
break;
}
}
}
async renderDropdown() {
this.$iconList.empty();

View File

@ -1,7 +1,7 @@
import Dropdown from "./react/Dropdown";
import "./note_icon.css";
import { t } from "i18next";
import { useNoteContext } from "./react/hooks";
import { useNoteContext, useNoteLabel } from "./react/hooks";
import { useCallback, useEffect, useRef, useState } from "preact/hooks";
import server from "../services/server";
import type { Category, Icon } from "./icon_list";
@ -28,26 +28,24 @@ let iconToCountCache!: Promise<IconToCountCache> | null;
export default function NoteIcon() {
const { note, viewScope } = useNoteContext();
const [ icon, setIcon ] = useState("bx bx-empty");
const [ icon, setIcon ] = useState<string | null | undefined>();
const [ iconClass ] = useNoteLabel(note, "iconClass");
const [ workspaceIconClass ] = useNoteLabel(note, "workspaceIconClass");
const refreshIcon = useCallback(() => {
if (note) {
setIcon(note.getIcon());
}
}, [ note ]);
useEffect(refreshIcon, [ note ]);
useEffect(() => {
setIcon(note?.getIcon());
}, [ note, iconClass, workspaceIconClass ]);
return (
<Dropdown
className="note-icon-widget"
title={t("note_icon.change_note_icon")}
dropdownContainerStyle={{ width: "610px" }}
buttonClassName={`note-icon ${icon}`}
buttonClassName={`note-icon ${icon ?? "bx bx-empty"}`}
hideToggleArrow
disabled={viewScope?.viewMode !== "default"}
>
<NoteIconList note={note} />
{ note && <NoteIconList note={note} /> }
</Dropdown>
)
}

View File

@ -1,5 +1,5 @@
import { useCallback, useContext, useEffect, useMemo, useRef, useState } from "preact/hooks";
import appContext, { BeforeUploadListener, EventData, EventNames } from "../../components/app_context";
import { EventData, EventNames } from "../../components/app_context";
import { ParentComponent } from "./react_utils";
import SpacedUpdate from "../../services/spaced_update";
import { OptionNames } from "@triliumnext/commons";
@ -9,8 +9,7 @@ import Component from "../../components/component";
import NoteContext from "../../components/note_context";
import { ReactWrappedWidget } from "../basic_widget";
import FNote from "../../entities/fnote";
import froca from "../../services/froca";
import toast from "../../services/toast";
import attributes from "../../services/attributes";
type TriliumEventHandler<T extends EventNames> = (data: EventData<T>) => void;
const registeredHandlers: Map<Component, Map<EventNames, TriliumEventHandler<any>[]>> = new Map();
@ -316,3 +315,26 @@ export function useNoteProperty<T extends keyof FNote>(note: FNote | null | unde
return note[property];
}
export function useNoteLabel(note: FNote | undefined | null, labelName: string): [string | undefined, (newValue: string) => void] {
const [ labelValue, setNoteValue ] = useState<string | null | undefined>(note?.getLabelValue(labelName));
useTriliumEventBeta("entitiesReloaded", ({ loadResults }) => {
for (const attr of loadResults.getAttributeRows()) {
if (attr.type === "label" && attr.name === labelName && attributes.isAffecting(attr, note)) {
setNoteValue(attr.value ?? null);
}
}
});
const setter = useCallback((value: string | undefined) => {
if (note) {
attributes.setLabel(note.noteId, labelName, value)
}
}, [note]);
return [
labelValue,
setter
] as const;
}