fix(mobile): fill the note column for images on narrow screens
A stored desktop width such as 35% stays in the note. Phone-width layouts show the image at the text column width.
This commit is contained in:
1 parent
3725ab6f80
commit
0681e70c97
6 files changed
+61
-1
No files matched your search
@@ -45,11 +45,12 @@ import {
|
||||
import { createEdgeEverMathematics } from "@edgeever/shared/mathematics";
|
||||
import { createIosImageGallery } from "./document-nodes";
|
||||
import { createImageInsertTransaction, groupUploadedImages, NATIVE_IMAGE_GALLERY_CSS } from "@edgeever/shared/native-image-gallery";
|
||||
import { NEW_IMAGE_WIDTH_PERCENT } from "@edgeever/shared/image-display";
|
||||
import { installPhoneImageFillStyle, NEW_IMAGE_WIDTH_PERCENT } from "@edgeever/shared/image-display";
|
||||
|
||||
const galleryStyle = document.createElement("style");
|
||||
galleryStyle.textContent = NATIVE_IMAGE_GALLERY_CSS;
|
||||
document.head.append(galleryStyle);
|
||||
installPhoneImageFillStyle();
|
||||
|
||||
const detailsStyle = document.createElement("style");
|
||||
detailsStyle.textContent = DETAILS_EDITOR_CSS;
|
||||
|
||||
@@ -56,6 +56,7 @@ import {
|
||||
DEFAULT_IMAGE_WIDTH_PERCENT,
|
||||
NEW_IMAGE_WIDTH_PERCENT,
|
||||
IMAGE_WIDTH_PRESETS,
|
||||
PHONE_IMAGE_FILL_CSS,
|
||||
clampImageWidth,
|
||||
parseImageWidth,
|
||||
} from "@edgeever/shared/image-display";
|
||||
@@ -3358,5 +3359,6 @@ const getEditorStyles = (theme: "light" | "dark", options?: { viewer?: boolean }
|
||||
.edgeever-image-upload-spinner { width: 18px; height: 18px; border: 2px solid ${theme === "dark" ? "#475569" : "#cbd5e1"}; border-top-color: #0f766e; border-radius: 999px; animation: edgeever-image-upload-spin 0.8s linear infinite; }
|
||||
@keyframes edgeever-image-upload-spin { to { transform: rotate(360deg); } }
|
||||
.edgeever-editor-content hr { margin: 24px 0; border: 0; border-top: 1px solid #cbd5e1; }
|
||||
${PHONE_IMAGE_FILL_CSS}
|
||||
`;
|
||||
};
|
||||
@@ -8,6 +8,7 @@ import { bootstrapI18n } from "./i18n";
|
||||
import { emitPwaUpdateNotice } from "./lib/pwa-update-notice";
|
||||
import { withEnvironmentTitlePrefix } from "./lib/environment-title";
|
||||
import { initializeTheme, ThemeProvider } from "./components/ThemeProvider";
|
||||
import { installPhoneImageFillStyle } from "@edgeever/shared/image-display";
|
||||
import { applyEditorBodyFontPreference } from "./lib/editor-body-font";
|
||||
import { installEditorBodyFontFaces } from "./lib/editor-body-font-faces";
|
||||
import { applyUiFontPreference } from "./lib/ui-font";
|
||||
@@ -16,6 +17,8 @@ import { reportDesktopRendererReadyAfterPaint } from "./lib/desktop-renderer-rea
|
||||
import "./styles/globals.css";
|
||||
import "./styles/editor-body-fonts.css";
|
||||
|
||||
installPhoneImageFillStyle();
|
||||
|
||||
const PWA_UPDATE_CHECK_INTERVAL_MS = 10 * 60 * 1_000;
|
||||
const DEVELOPMENT_PWA_RELOAD_KEY = "edgeever.dev-pwa-reset";
|
||||
const isDesktopRenderer = __EDGEEVER_DESKTOP_BUILD__ || window.edgeeverDesktop?.isAvailable === true;
|
||||
|
||||
@@ -6,11 +6,14 @@ import { initializeTheme } from "@/components/ThemeProvider";
|
||||
import { applyEditorBodyFontPreference } from "@/lib/editor-body-font";
|
||||
import { installEditorBodyFontFaces } from "@/lib/editor-body-font-faces";
|
||||
import { applyUiFontPreference } from "@/lib/ui-font";
|
||||
import { installPhoneImageFillStyle } from "@edgeever/shared/image-display";
|
||||
import { bootstrapI18n } from "@/i18n";
|
||||
import { defaultLocale, getBrowserLocale } from "@/i18n/locales";
|
||||
import "./styles/mobile-markdown-editor.css";
|
||||
import "./styles/editor-body-fonts.css";
|
||||
|
||||
installPhoneImageFillStyle();
|
||||
|
||||
declare global {
|
||||
interface Window {
|
||||
edgeeverMobileEditorBootstrap?: {
|
||||
|
||||
@@ -1,12 +1,17 @@
|
||||
import { describe, expect, test } from "bun:test";
|
||||
import { readFileSync } from "node:fs";
|
||||
import {
|
||||
DEFAULT_IMAGE_WIDTH_PERCENT,
|
||||
NEW_IMAGE_WIDTH_PERCENT,
|
||||
IMAGE_WIDTH_PRESETS,
|
||||
PHONE_IMAGE_FILL_CSS,
|
||||
PHONE_IMAGE_FILL_MAX_WIDTH_PX,
|
||||
clampImageWidth,
|
||||
parseImageWidth,
|
||||
} from "./image-display.ts";
|
||||
|
||||
const readRepoFile = (relativePath) => readFileSync(new URL(relativePath, import.meta.url), "utf8");
|
||||
|
||||
describe("shared image display widths", () => {
|
||||
test("keeps the four editor presets stable across clients", () => {
|
||||
expect(DEFAULT_IMAGE_WIDTH_PERCENT).toBe(72);
|
||||
@@ -26,4 +31,18 @@ describe("shared image display widths", () => {
|
||||
expect(clampImageWidth(24.6)).toBe(25);
|
||||
expect(clampImageWidth(71.6)).toBe(72);
|
||||
});
|
||||
|
||||
test("fills the phone column without changing the stored desktop percent", () => {
|
||||
expect(PHONE_IMAGE_FILL_MAX_WIDTH_PX).toBe(640);
|
||||
expect(PHONE_IMAGE_FILL_CSS).toContain("@media screen and (max-width: 640px)");
|
||||
expect(PHONE_IMAGE_FILL_CSS).toContain("width: 100% !important");
|
||||
expect(PHONE_IMAGE_FILL_CSS).toContain("max-width: 100% !important");
|
||||
expect(PHONE_IMAGE_FILL_CSS).toContain(".edgeever-image-node");
|
||||
expect(PHONE_IMAGE_FILL_CSS).toContain(".ProseMirror img[data-width]");
|
||||
expect(PHONE_IMAGE_FILL_CSS).toContain(":not(.edgeever-image-card *)");
|
||||
expect(readRepoFile("../../../apps/mobile/src/components/LocalTiptapEditor.tsx")).toContain("${PHONE_IMAGE_FILL_CSS}");
|
||||
expect(readRepoFile("../../../apps/ios/EditorSource/src/main.ts")).toContain("installPhoneImageFillStyle(");
|
||||
expect(readRepoFile("../../../apps/web/src/main.tsx")).toContain("installPhoneImageFillStyle(");
|
||||
expect(readRepoFile("../../../apps/web/src/mobile-edit.tsx")).toContain("installPhoneImageFillStyle(");
|
||||
});
|
||||
});
|
||||
@@ -11,6 +11,38 @@ export const IMAGE_WIDTH_PRESETS = [
|
||||
|
||||
export const NEW_IMAGE_WIDTH_PERCENT = IMAGE_WIDTH_PRESETS[0].width;
|
||||
|
||||
/**
|
||||
* Phone columns are already narrow. A desktop percent such as 35% ("较小")
|
||||
* paints a stamp there, and the image action button covers most of it.
|
||||
* At or below this viewport, images fill the column. The stored percent stays
|
||||
* in the note for wide layouts.
|
||||
*/
|
||||
export const PHONE_IMAGE_FILL_MAX_WIDTH_PX = 640;
|
||||
|
||||
/**
|
||||
* `!important` overrides the inline percent on the image figure.
|
||||
* `screen` leaves print on the stored percent.
|
||||
* Share-as-image cards (`.edgeever-image-card`) keep the stored percent:
|
||||
* they are a fixed-width document, not the phone column.
|
||||
*/
|
||||
export const PHONE_IMAGE_FILL_CSS = `
|
||||
@media screen and (max-width: ${PHONE_IMAGE_FILL_MAX_WIDTH_PX}px) {
|
||||
:is(.edgeever-image-node, .edgeever-image-upload-result, .edgeever-image-upload-placeholder, .ProseMirror img[data-width]):not(.edgeever-image-card *) {
|
||||
width: 100% !important;
|
||||
max-width: 100% !important;
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
export const installPhoneImageFillStyle = () => {
|
||||
if (typeof document === "undefined") return;
|
||||
if (document.head.querySelector("style[data-edgeever-phone-image-fill]")) return;
|
||||
const style = document.createElement("style");
|
||||
style.dataset.edgeeverPhoneImageFill = "true";
|
||||
style.textContent = PHONE_IMAGE_FILL_CSS;
|
||||
document.head.append(style);
|
||||
};
|
||||
|
||||
export type ImageWidthPresetId = (typeof IMAGE_WIDTH_PRESETS)[number]["id"];
|
||||
|
||||
export const clampImageWidth = (width: number): number =>
|
||||
|
||||
Reference in new issue
Block a user