Merge branch 'main' into fix/split_pane
Some checks are pending
Checks / main (push) Waiting to run

This commit is contained in:
SiriusXT 2025-11-29 11:39:05 +08:00
commit 53a8f6b4c0
4 changed files with 58 additions and 34 deletions

View File

@ -8,6 +8,7 @@ import Color, { ColorInstance } from "color";
import Debouncer from "../../utils/debouncer"; import Debouncer from "../../utils/debouncer";
import FNote from "../../entities/fnote"; import FNote from "../../entities/fnote";
import froca from "../../services/froca"; import froca from "../../services/froca";
import { isMobile } from "../../services/utils";
const COLOR_PALETTE = [ const COLOR_PALETTE = [
"#e64d4d", "#e6994d", "#e5e64d", "#99e64d", "#4de64d", "#4de699", "#e64d4d", "#e6994d", "#e5e64d", "#99e64d", "#4de64d", "#4de699",
@ -62,13 +63,13 @@ export default function NoteColorPicker(props: NoteColorPickerProps) {
} else { } else {
attributes.removeOwnedLabelByName(note, "color"); attributes.removeOwnedLabelByName(note, "color");
} }
setCurrentColor(color); setCurrentColor(color);
} }
}, [note, currentColor]); }, [note, currentColor]);
return <div className="note-color-picker"> return <div className="note-color-picker">
<ColorCell className="color-cell-reset" <ColorCell className="color-cell-reset"
tooltip={t("note-color.clear-color")} tooltip={t("note-color.clear-color")}
color={null} color={null}
@ -81,8 +82,8 @@ export default function NoteColorPicker(props: NoteColorPickerProps) {
<path d="M19,6.41L17.59,5L12,10.59L6.41,5L5,6.41L10.59,12L5,17.59L6.41,19L12,13.41L17.59,19L19,17.59L13.41,12L19,6.41Z" /> <path d="M19,6.41L17.59,5L12,10.59L6.41,5L5,6.41L10.59,12L5,17.59L6.41,19L12,13.41L17.59,19L19,17.59L13.41,12L19,6.41Z" />
</svg> </svg>
</ColorCell> </ColorCell>
{COLOR_PALETTE.map((color) => ( {COLOR_PALETTE.map((color) => (
<ColorCell key={color} <ColorCell key={color}
tooltip={t("note-color.set-color")} tooltip={t("note-color.set-color")}
@ -128,7 +129,6 @@ function CustomColorCell(props: ColorCellProps) {
const colorInput = useRef<HTMLInputElement>(null); const colorInput = useRef<HTMLInputElement>(null);
const colorInputDebouncer = useRef<Debouncer<string | null> | null>(null); const colorInputDebouncer = useRef<Debouncer<string | null> | null>(null);
const callbackRef = useRef(props.onSelect); const callbackRef = useRef(props.onSelect);
const isSafari = useRef(/^((?!chrome|android).)*safari/i.test(navigator.userAgent));
useEffect(() => { useEffect(() => {
colorInputDebouncer.current = new Debouncer(250, (color) => { colorInputDebouncer.current = new Debouncer(250, (color) => {
@ -160,13 +160,13 @@ function CustomColorCell(props: ColorCellProps) {
}, [pickedColor]); }, [pickedColor]);
return <div style={`--foreground: ${getForegroundColor(props.color)};`} return <div style={`--foreground: ${getForegroundColor(props.color)};`}
onClick={(e) => { onClick={isMobile() ? (e) => {
// The color picker dropdown will close on Safari if the parent context menu is // The color picker dropdown will close on some browser if the parent context menu is
// dismissed, so stop the click propagation to prevent dismissing the menu. // dismissed, so stop the click propagation to prevent dismissing the menu.
isSafari.current && e.stopPropagation(); e.stopPropagation();
}}> } : undefined}>
<ColorCell {...props} <ColorCell {...props}
color={pickedColor} color={pickedColor}
className={clsx("custom-color-cell", { className={clsx("custom-color-cell", {
"custom-color-cell-empty": (pickedColor === null) "custom-color-cell-empty": (pickedColor === null)
})} })}
@ -201,4 +201,4 @@ function tryParseColor(colorStr: string): ColorInstance | null {
} }
return null; return null;
} }

View File

@ -1316,7 +1316,7 @@ body.mobile #context-menu-container.mobile-bottom-menu {
inset-inline-end: 0 !important; inset-inline-end: 0 !important;
bottom: 0 !important; bottom: 0 !important;
top: unset !important; top: unset !important;
max-height: 70vh; max-height: 90vh;
overflow: auto !important; overflow: auto !important;
user-select: none; user-select: none;
-webkit-user-select: none; -webkit-user-select: none;

View File

@ -119,17 +119,6 @@ body.backdrop-effects-disabled {
font-size: 0.9rem !important; font-size: 0.9rem !important;
} }
body.mobile .dropdown-menu {
backdrop-filter: var(--dropdown-backdrop-filter);
border-radius: var(--dropdown-border-radius);
position: relative;
}
body.mobile .dropdown-menu .dropdown-menu {
backdrop-filter: unset !important;
border-radius: unset !important;
}
body.desktop .dropdown-menu::before, body.desktop .dropdown-menu::before,
:root .ck.ck-dropdown__panel::before, :root .ck.ck-dropdown__panel::before,
:root .excalidraw .popover::before, :root .excalidraw .popover::before,
@ -157,17 +146,12 @@ body.desktop .dropdown-submenu .dropdown-menu::before {
content: unset; content: unset;
} }
body.mobile .dropdown-submenu .dropdown-menu {
background: transparent !important;
}
body.desktop .dropdown-submenu .dropdown-menu { body.desktop .dropdown-submenu .dropdown-menu {
backdrop-filter: var(--dropdown-backdrop-filter); backdrop-filter: var(--dropdown-backdrop-filter);
background: transparent; background: transparent;
} }
.dropdown-item, .dropdown-item,
body.mobile .dropdown-submenu .dropdown-toggle,
.excalidraw .context-menu .context-menu-item { .excalidraw .context-menu .context-menu-item {
--menu-item-start-padding: 8px; --menu-item-start-padding: 8px;
--menu-item-end-padding: 22px; --menu-item-end-padding: 22px;
@ -201,10 +185,6 @@ body.mobile .dropdown-item:not(:last-of-type) {
margin-bottom: 0.5em; margin-bottom: 0.5em;
} }
body.mobile .dropdown-submenu:hover {
background: transparent !important;
}
html body .dropdown-item.disabled, html body .dropdown-item.disabled,
html body .dropdown-item[disabled] { html body .dropdown-item[disabled] {
color: var(--menu-text-color) !important; color: var(--menu-text-color) !important;
@ -322,13 +302,25 @@ body.desktop .dropdown-menu.static .dropdown-item.active {
} }
/* #region Mobile tweaks for dropdown menus */ /* #region Mobile tweaks for dropdown menus */
body.mobile #context-menu-cover {
transition: background-color 150ms ease-in;
&.show {
background: rgba(0, 0, 0, 0.7);
}
}
body.mobile .dropdown-menu { body.mobile .dropdown-menu {
--dropdown-menu-padding-vertical: 0.7em; --dropdown-menu-padding-vertical: 0.7em;
--dropdown-menu-padding-horizontal: 1em; --dropdown-menu-padding-horizontal: 1em;
--hover-item-background-color: var(--card-background-color);
font-size: 1em !important; font-size: 1em !important;
backdrop-filter: var(--dropdown-backdrop-filter);
border-radius: var(--dropdown-border-radius) var(--dropdown-border-radius) 0 0;
position: relative;
.dropdown-toggle::after { .dropdown-toggle::after {
top: var(--dropdown-menu-padding-vertical); top: 0.5em;
right: var(--dropdown-menu-padding-horizontal); right: var(--dropdown-menu-padding-horizontal);
transform: translateX(50%) rotate(90deg); transform: translateX(50%) rotate(90deg);
} }
@ -366,6 +358,37 @@ body.mobile .dropdown-menu {
.dropdown-divider { .dropdown-divider {
visibility: hidden; visibility: hidden;
} }
.dropdown-submenu {
padding: 0 !important;
backdrop-filter: unset !important;
.dropdown-toggle {
padding: var(--dropdown-menu-padding-vertical) var(--dropdown-menu-padding-horizontal);
}
.dropdown-menu {
--menu-background-color: rgba(0, 0, 0, 0.15);
border-radius: 0;
max-height: 0;
transition: max-height 100ms ease-in;
display: block !important;
&.show {
max-height: 1000px;
}
.dropdown-item {
background: transparent;
}
}
&.submenu-open {
.dropdown-toggle {
padding-bottom: var(--dropdown-menu-padding-vertical);
}
}
}
} }
/* #endregion */ /* #endregion */

View File

@ -27,7 +27,8 @@ async function register(app: express.Application) {
appType: "custom", appType: "custom",
cacheDir: path.join(srcRoot, "../../.cache/vite"), cacheDir: path.join(srcRoot, "../../.cache/vite"),
base: `/${assetUrlFragment}/`, base: `/${assetUrlFragment}/`,
root: clientDir root: clientDir,
css: { devSourcemap: true }
}); });
app.use(`/${assetUrlFragment}/`, (req, res, next) => { app.use(`/${assetUrlFragment}/`, (req, res, next) => {
req.url = `/${assetUrlFragment}` + req.url; req.url = `/${assetUrlFragment}` + req.url;