From d48473ab878f6bfdb6c884f22e4070020e13d4a6 Mon Sep 17 00:00:00 2001 From: Elian Doran Date: Mon, 2 Feb 2026 16:38:12 +0200 Subject: [PATCH] feat(mobile/note_icon): single menu for filtering & resetting --- apps/client/src/stylesheets/style.css | 6 +- apps/client/src/widgets/note_icon.tsx | 140 +++++++++++++++++--------- 2 files changed, 100 insertions(+), 46 deletions(-) diff --git a/apps/client/src/stylesheets/style.css b/apps/client/src/stylesheets/style.css index 23a986985..f05441db3 100644 --- a/apps/client/src/stylesheets/style.css +++ b/apps/client/src/stylesheets/style.css @@ -1540,7 +1540,7 @@ body:not(.mobile) #launcher-pane.horizontal .dropdown-submenu > .dropdown-menu { @media (max-width: 991px) { body.mobile #launcher-pane .dropdown.global-menu > .dropdown-menu.show, body.mobile #launcher-container .dropdown > .dropdown-menu.show, - body.mobile .dropdown.note-actions > .dropdown-menu.show { + body.mobile .dropdown-menu.mobile-bottom-menu.show { --dropdown-bottom: calc(var(--mobile-bottom-offset) + var(--launcher-pane-size)); position: fixed !important; bottom: var(--dropdown-bottom) !important; @@ -1552,6 +1552,10 @@ body:not(.mobile) #launcher-pane.horizontal .dropdown-submenu > .dropdown-menu { max-height: calc(var(--tn-modal-max-height) - var(--dropdown-bottom)); } + body.mobile .modal-dialog .dropdown-menu.mobile-bottom-menu.show { + --dropdown-bottom: 0; + } + #mobile-sidebar-container { position: fixed; top: 0; diff --git a/apps/client/src/widgets/note_icon.tsx b/apps/client/src/widgets/note_icon.tsx index b5afb5471..5cc97d5c1 100644 --- a/apps/client/src/widgets/note_icon.tsx +++ b/apps/client/src/widgets/note_icon.tsx @@ -13,7 +13,7 @@ import { CellComponentProps, Grid } from "react-window"; import FNote from "../entities/fnote"; import attributes from "../services/attributes"; import server from "../services/server"; -import { isMobile } from "../services/utils"; +import { isDesktop, isMobile } from "../services/utils"; import ActionButton from "./react/ActionButton"; import Dropdown from "./react/Dropdown"; import { FormDropdownDivider, FormListItem } from "./react/FormList"; @@ -98,7 +98,6 @@ function NoteIconList({ note, onHide, columnCount }: { onHide: () => void; columnCount: number; }) { - const searchBoxRef = useRef(null); const iconListRef = useRef(null); const [ search, setSearch ] = useState(); const [ filterByPrefix, setFilterByPrefix ] = useState(null); @@ -114,49 +113,15 @@ function NoteIconList({ note, onHide, columnCount }: { return ( <> -
- {t("note_icon.search")} - s.prefix === filterByPrefix)?.name ?? "" - }) - : t("note_icon.search_placeholder", { number: filteredIcons.length ?? 0, count: glob.iconRegistry.sources.length })} - currentValue={search} onChange={setSearch} - autoFocus - /> - - {getIconLabels(note).length > 0 && ( -
- { - if (!note) return; - for (const label of getIconLabels(note)) { - attributes.removeAttributeById(note.noteId, label.attributeId); - } - onHide(); - }} - /> -
- )} - - {glob.iconRegistry.sources.length > 0 && - - } -
+
void; + setFilterByPrefix: (value: string | null) => void; + filteredIcons: IconWithName[]; + onHide: () => void; +}) { + const searchBoxRef = useRef(null); + const hasIconPacks = glob.iconRegistry.sources.length > 0; + const hasCustomIcon = getIconLabels(note).length > 0; + + function resetToDefaultIcon() { + if (!note) return; + for (const label of getIconLabels(note)) { + attributes.removeAttributeById(note.noteId, label.attributeId); + } + onHide(); + } + + return ( +
+ {t("note_icon.search")} + s.prefix === filterByPrefix)?.name ?? "" + }) + : t("note_icon.search_placeholder", { number: filteredIcons.length ?? 0, count: glob.iconRegistry.sources.length })} + currentValue={search} onChange={setSearch} + autoFocus + /> + + {isDesktop() + ? <> + {hasCustomIcon && ( +
+ +
+ )} + + {hasIconPacks && + + } + : ( + + {hasIconPacks && <> + {t("note_icon.reset-default")} + + } + + + + )} +
+ ); +} + function IconItemCell({ rowIndex, columnIndex, style, filteredIcons, columnCount }: CellComponentProps<{ filteredIcons: IconWithName[]; columnCount: number;