diff --git a/apps/client/src/menus/custom-items/NoteColorPickerMenuItem.tsx b/apps/client/src/menus/custom-items/NoteColorPickerMenuItem.tsx
index 60757aa15..14a908cc8 100644
--- a/apps/client/src/menus/custom-items/NoteColorPickerMenuItem.tsx
+++ b/apps/client/src/menus/custom-items/NoteColorPickerMenuItem.tsx
@@ -1,5 +1,6 @@
import "./NoteColorPickerMenuItem.css";
-import { useEffect, useState } from "preact/hooks";
+import { useEffect, useRef, useState} from "preact/hooks";
+import {ComponentChildren} from "preact";
import attributes from "../../services/attributes";
import FNote from "../../entities/fnote";
import froca from "../../services/froca";
@@ -55,21 +56,87 @@ export default function NoteColorPickerMenuItem(props: NoteColorPickerMenuItemPr
color={color}
isSelected={(color === currentColor)}
isDisabled={(note === null)}
- onClick={() => onColorCellClicked(color)} />
+ onSelect={() => onColorCellClicked(color)} />
))}
+
+
}
interface ColorCellProps {
+ children?: ComponentChildren,
+ className?: string;
color: string | null,
isSelected: boolean,
isDisabled?: boolean,
- onClick?: () => void
+ onSelect?: (color: string | null) => void
}
function ColorCell(props: ColorCellProps) {
- return
+ onClick={() => props.onSelect?.(props.color)}>
+ {props.children}
;
+}
+
+function CustomColorCell(props: ColorCellProps) {
+ const colorInput = useRef(null);
+ let colorInputDebouncer: Debouncer;
+
+ useEffect(() => {
+ colorInputDebouncer = new Debouncer(500, (color) => {
+ props.onSelect?.(color);
+ });
+
+ return () => {
+ colorInputDebouncer.destroy();
+ }
+ });
+
+ return <>
+ {colorInput.current?.click()}}>
+
+ {colorInputDebouncer.updateValue(colorInput.current?.value ?? null)}}
+ style="width: 0; height: 0; opacity: 0" />
+
+ >
+}
+
+type DebouncerCallback = (value: T) => void;
+
+class Debouncer {
+
+ private debounceInterval: number;
+ private callback: DebouncerCallback;
+ private lastValue: T | undefined;
+ private timeoutId: any | null = null;
+
+ constructor(debounceInterval: number, onUpdate: DebouncerCallback) {
+ this.debounceInterval = debounceInterval;
+ this.callback = onUpdate;
+ }
+
+ updateValue(value: T) {
+ this.lastValue = value;
+ this.destroy();
+ this.timeoutId = setTimeout(this.reportUpdate.bind(this), this.debounceInterval);
+ }
+
+ destroy() {
+ if (this.timeoutId !== null) {
+ clearTimeout(this.timeoutId);
+ }
+ }
+
+ private reportUpdate() {
+ if (this.lastValue !== undefined) {
+ this.callback(this.lastValue);
+ }
+ }
}
\ No newline at end of file