diff --git a/packages/client/components/RetroReflectPhase/PhaseItemEditor.tsx b/packages/client/components/RetroReflectPhase/PhaseItemEditor.tsx
index f845732767d..6ab44e95a98 100644
--- a/packages/client/components/RetroReflectPhase/PhaseItemEditor.tsx
+++ b/packages/client/components/RetroReflectPhase/PhaseItemEditor.tsx
@@ -226,7 +226,7 @@ const PhaseItemEditor = (props: Props) => {
>
({
})
export const useBlockResizer = (
width: number,
- setWidth: (width: number) => void,
updateAttributes: (attrs: Record
) => void,
- aspectRatioRef: RefObject
+ aspectRatioRef: RefObject,
+ maxWidth: number
) => {
const dragRef = useRef(makeDrag())
const onMouseUp = useEventCallback((e: MouseEvent | TouchEvent) => {
@@ -41,8 +41,8 @@ export const useBlockResizer = (
const sideCoefficient = drag.side === 'left' ? 1 : -1
const delta = (drag.lastX - clientX) * sideCoefficient
drag.lastX = clientX
- const nextWidth = Math.max(48, width + delta)
- setWidth(nextWidth)
+ const nextWidth = Math.min(maxWidth, Math.max(48, width + delta))
+ updateAttributes({width: nextWidth, height: Math.round(nextWidth / aspectRatioRef.current!)})
})
const onMouseDown = useEventCallback(
diff --git a/packages/client/hooks/useTipTapReflectionEditor.ts b/packages/client/hooks/useTipTapReflectionEditor.ts
index 9a493006083..7a644485328 100644
--- a/packages/client/hooks/useTipTapReflectionEditor.ts
+++ b/packages/client/hooks/useTipTapReflectionEditor.ts
@@ -70,7 +70,10 @@ export const useTipTapReflectionEditor = (
'To-do list': false
}),
Focus,
- ImageUpload.configure({editorWidth: ElementWidth.REFLECTION_CARD, editorHeight: 88}),
+ ImageUpload.configure({
+ editorWidth: ElementWidth.REFLECTION_CARD - 16 * 2,
+ editorHeight: 88
+ }),
ImageBlock,
LoomExtension,
Placeholder.configure({
diff --git a/packages/client/tiptap/extensions/imageBlock/ImageBlock.ts b/packages/client/tiptap/extensions/imageBlock/ImageBlock.ts
index e574f6ee54d..e0e59746c79 100644
--- a/packages/client/tiptap/extensions/imageBlock/ImageBlock.ts
+++ b/packages/client/tiptap/extensions/imageBlock/ImageBlock.ts
@@ -13,14 +13,14 @@ export const ImageBlock = ImageBlockBase.extend({
})
},
height: {
- default: '100%',
+ default: undefined,
parseHTML: (element) => element.getAttribute('height'),
renderHTML: (attributes) => ({
height: attributes.height
})
},
width: {
- default: '100%',
+ default: undefined,
parseHTML: (element) => element.getAttribute('width'),
renderHTML: (attributes) => ({
width: attributes.width
diff --git a/packages/client/tiptap/extensions/imageBlock/ImageBlockView.tsx b/packages/client/tiptap/extensions/imageBlock/ImageBlockView.tsx
index 19295a9068c..014440f8d9e 100644
--- a/packages/client/tiptap/extensions/imageBlock/ImageBlockView.tsx
+++ b/packages/client/tiptap/extensions/imageBlock/ImageBlockView.tsx
@@ -1,5 +1,5 @@
import {NodeViewWrapper, type NodeViewProps} from '@tiptap/react'
-import {useCallback, useEffect, useRef, useState} from 'react'
+import {useCallback, useRef, useState} from 'react'
import {useBlockResizer} from '../../../hooks/useBlockResizer'
import {cn} from '../../../ui/cn'
import {BlockResizer} from './BlockResizer'
@@ -7,8 +7,8 @@ import {ImageBlockBubbleMenu} from './ImageBlockBubbleMenu'
export const ImageBlockView = (props: NodeViewProps) => {
const {editor, getPos, node, updateAttributes} = props
const imageWrapperRef = useRef(null)
- const {src, align} = node.attrs
-
+ const {attrs} = node
+ const {src, align, height, width} = attrs
const alignClass =
align === 'left' ? 'justify-start' : align === 'right' ? 'justify-end' : 'justify-center'
@@ -16,19 +16,20 @@ export const ImageBlockView = (props: NodeViewProps) => {
editor.commands.setNodeSelection(getPos())
}, [getPos, editor.commands])
- const maxHeightRef = useRef(editor.storage.imageUpload.editorHeight)
- const {current: maxHeight} = maxHeightRef
- const aspectRatioRef = useRef(0)
- const ref = useRef(null)
- const [width, setWidth] = useState(node.attrs.width || 0)
- const {onMouseDown} = useBlockResizer(width, setWidth, updateAttributes, aspectRatioRef)
+ const [maxHeight, setMaxHeight] = useState(
+ // if no height is provided (first load), make sure the image is no taller than the editor
+ height ? undefined : editor.storage.imageUpload.editorHeight
+ )
+
+ const aspectRatioRef = useRef(1)
+ const {onMouseDown} = useBlockResizer(
+ width,
+ updateAttributes,
+ aspectRatioRef,
+ editor.storage.imageUpload.editorWidth
+ )
const onMouseDownLeft = onMouseDown('left')
const onMouseDownRight = onMouseDown('right')
- useEffect(() => {
- if (width === node.attrs.width) return
- // the attributes will change if another instance (e.g. a reflection in an expanded stack) edits them
- setWidth(node.attrs.width)
- }, [node.attrs.width])
return (
@@ -38,15 +39,15 @@ export const ImageBlockView = (props: NodeViewProps) => {
src={src}
alt=''
onClick={onClick}
- style={{maxHeight, width: width === 0 ? undefined : width}}
- ref={ref}
+ style={{maxHeight}}
+ width={width}
+ height={height}
onLoad={(e) => {
const img = e.target as HTMLImageElement
- console.log('loaded', img.width, img.height, maxHeightRef.current)
- maxHeightRef.current = undefined
aspectRatioRef.current = img.width / img.height
- if (img.width !== node.attrs.width) {
- setWidth(img.width)
+ if (img.width !== width) {
+ // on initial load, once we grab the h/w/ar, remove the maxH constraint
+ setMaxHeight(undefined)
updateAttributes({width: img.width, height: img.height})
}
}}