fix(markdown): address code review findings — updateItem, height measurement, CSS injection, paste fallback, resize sprite update
This commit is contained in:
@@ -126,7 +126,8 @@ export class MarkdownOverlay {
|
|||||||
if (!entry || !item || item.type !== 'markdown') return;
|
if (!entry || !item || item.type !== 'markdown') return;
|
||||||
|
|
||||||
requestAnimationFrame(() => {
|
requestAnimationFrame(() => {
|
||||||
const h = entry.el.offsetHeight / this._viewport.scale.x;
|
// offsetHeight is the CSS layout height at unscaled width — already in world space
|
||||||
|
const h = entry.el.offsetHeight;
|
||||||
if (Math.abs(h - item.data.h) > 1) {
|
if (Math.abs(h - item.data.h) > 1) {
|
||||||
item.data.h = h;
|
item.data.h = h;
|
||||||
// Redraw MarkdownSprite background
|
// Redraw MarkdownSprite background
|
||||||
|
|||||||
@@ -465,6 +465,9 @@ export class SceneManager {
|
|||||||
const imgData = data as ImageObject;
|
const imgData = data as ImageObject;
|
||||||
obj.applyCrop(imgData.crop);
|
obj.applyCrop(imgData.crop);
|
||||||
}
|
}
|
||||||
|
if (data.type === 'markdown' && obj instanceof MarkdownSprite) {
|
||||||
|
obj.updateFromData(data as MarkdownObject);
|
||||||
|
}
|
||||||
|
|
||||||
// Update stored data
|
// Update stored data
|
||||||
item.data = { ...data };
|
item.data = { ...data };
|
||||||
|
|||||||
@@ -8,6 +8,8 @@
|
|||||||
|
|
||||||
import { Container, Graphics, FederatedPointerEvent, Text, TextStyle } from 'pixi.js';
|
import { Container, Graphics, FederatedPointerEvent, Text, TextStyle } from 'pixi.js';
|
||||||
import type { Viewport } from 'pixi-viewport';
|
import type { Viewport } from 'pixi-viewport';
|
||||||
|
import { MarkdownSprite } from './sprites/MarkdownSprite';
|
||||||
|
import type { MarkdownObject } from './scene-format';
|
||||||
import { type SceneItem, getItemWorldBounds } from './SceneManager';
|
import { type SceneItem, getItemWorldBounds } from './SceneManager';
|
||||||
import type { SnapGuides } from './SnapGuides';
|
import type { SnapGuides } from './SnapGuides';
|
||||||
import { applyImageDisplayTransform } from './imageTransforms';
|
import { applyImageDisplayTransform } from './imageTransforms';
|
||||||
@@ -360,6 +362,9 @@ export class TransformBox extends Container {
|
|||||||
item.data.x = orig.x;
|
item.data.x = orig.x;
|
||||||
item.data.y = orig.y;
|
item.data.y = orig.y;
|
||||||
item.displayObject.position.set(item.data.x, item.data.y);
|
item.displayObject.position.set(item.data.x, item.data.y);
|
||||||
|
if (item.displayObject instanceof MarkdownSprite) {
|
||||||
|
item.displayObject.updateFromData(item.data as MarkdownObject);
|
||||||
|
}
|
||||||
this._onItemTransform?.(item);
|
this._onItemTransform?.(item);
|
||||||
continue; // Skip normal sx/sy scaling
|
continue; // Skip normal sx/sy scaling
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -346,13 +346,16 @@ export function setupPaste(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (textContent) {
|
if (textContent) {
|
||||||
|
if (textContent.length > 20 && opts?.onTextPaste) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
if (textContent.length > 20) {
|
opts.onTextPaste({ text: textContent, html: htmlContent, hasImage: hasMedia });
|
||||||
opts?.onTextPaste?.({ text: textContent, html: htmlContent, hasImage: hasMedia });
|
|
||||||
} else {
|
|
||||||
opts?.onShortTextPaste?.(textContent);
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
|
} else if (textContent.length <= 20 && opts?.onShortTextPaste) {
|
||||||
|
e.preventDefault();
|
||||||
|
opts.onShortTextPaste(textContent);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// No callback provided — let native paste behavior through
|
||||||
}
|
}
|
||||||
|
|
||||||
// ── Media paste logic (unchanged) ──
|
// ── Media paste logic (unchanged) ──
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import React, { useCallback, useEffect, useRef } from 'react';
|
|||||||
import { useCreateBlockNote } from '@blocknote/react';
|
import { useCreateBlockNote } from '@blocknote/react';
|
||||||
import { BlockNoteViewRaw } from '@blocknote/react';
|
import { BlockNoteViewRaw } from '@blocknote/react';
|
||||||
import '@blocknote/react/style.css';
|
import '@blocknote/react/style.css';
|
||||||
|
import { MD_BLOCKNOTE_DARK_CSS } from '../canvas/markdownStyles';
|
||||||
|
|
||||||
interface MarkdownEditViewProps {
|
interface MarkdownEditViewProps {
|
||||||
initialContent: string;
|
initialContent: string;
|
||||||
@@ -24,6 +25,17 @@ export default function MarkdownEditView(props: MarkdownEditViewProps) {
|
|||||||
const { initialContent, accentColor, onSave, onCancel } = props;
|
const { initialContent, accentColor, onSave, onCancel } = props;
|
||||||
const savedRef = useRef(false);
|
const savedRef = useRef(false);
|
||||||
|
|
||||||
|
// Inject BlockNote dark theme CSS overrides (once)
|
||||||
|
useEffect(() => {
|
||||||
|
const id = 'bn-dark-theme-overrides';
|
||||||
|
if (!document.getElementById(id)) {
|
||||||
|
const style = document.createElement('style');
|
||||||
|
style.id = id;
|
||||||
|
style.textContent = MD_BLOCKNOTE_DARK_CSS;
|
||||||
|
document.head.appendChild(style);
|
||||||
|
}
|
||||||
|
}, []);
|
||||||
|
|
||||||
const editor = useCreateBlockNote({
|
const editor = useCreateBlockNote({
|
||||||
domAttributes: {
|
domAttributes: {
|
||||||
editor: {
|
editor: {
|
||||||
|
|||||||
Reference in New Issue
Block a user