import { useMemo } from "react"; import type { Attachment } from "@/types/proto/api/v1/attachment_service_pb"; import { getAttachmentUrl } from "@/utils/attachment"; interface PositionedImageViewProps { imageId: string; className?: string; style?: React.CSSProperties | { cssText: string }; alt?: string; } // Simplified positioned image view for memo display (read-only) export const PositionedImageView = ({ imageId, className, style, alt }: PositionedImageViewProps) => { // Debug: log component props // console.log('PositionedImageView props:', { imageId, style }); // Construct the URL directly using Memos standard URL structure // Format: /file/{attachment-name}/{filename} const imageUrl = useMemo(() => { // Extract filename from imageId if it contains path info // For simple IDs, we'll use a generic filename const filename = imageId.includes('/') ? imageId.split('/').pop() || 'image' : 'image.jpg'; return `${window.location.origin}/file/${imageId}/${filename}`; }, [imageId]); const containerStyle = useMemo(() => { const baseStyles: React.CSSProperties = { display: 'block', }; // Handle different style input types if (style) { if ('cssText' in style) { // Handle string-based styles const styleStr = style.cssText; if (styleStr.includes('text-align: left')) baseStyles.textAlign = 'left'; if (styleStr.includes('text-align: center')) baseStyles.textAlign = 'center'; if (styleStr.includes('text-align: right')) baseStyles.textAlign = 'right'; if (styleStr.includes('float: left')) baseStyles.float = 'left'; if (styleStr.includes('float: right')) baseStyles.float = 'right'; // Handle margin - only set if not already defined if (styleStr.includes('margin:') && !('margin' in baseStyles)) { const marginMatch = styleStr.match(/margin:\s*([^;]+)/); if (marginMatch) baseStyles.margin = marginMatch[1].trim(); } // Set default margin-bottom only if no margin is specified if (!styleStr.includes('margin:') && !('margin' in baseStyles) && !('marginBottom' in baseStyles)) { baseStyles.marginBottom = '1rem'; } } else { // Handle CSSProperties object Object.assign(baseStyles, style); // Set default margin-bottom only if no margin properties exist if (!('margin' in baseStyles) && !('marginBottom' in baseStyles)) { baseStyles.marginBottom = '1rem'; } } } return baseStyles; }, [style]); const imageStyle = useMemo(() => { const baseStyles: React.CSSProperties = { maxWidth: '100%', height: 'auto', borderRadius: '0.5rem', }; // Extract width/height from style if present if (style) { if ('cssText' in style) { const styleStr = style.cssText; const widthMatch = styleStr.match(/width:\s*([^;]+)/); const heightMatch = styleStr.match(/height:\s*([^;]+)/); if (widthMatch) baseStyles.width = widthMatch[1].trim(); if (heightMatch) baseStyles.height = heightMatch[1].trim(); } } return baseStyles; }, [style]); // Debug: log image URL // console.log('Image URL:', imageUrl); // Fallback to showing the tag if image URL cannot be constructed if (!imageUrl || imageUrl.includes('undefined')) { return ( [img:{imageId}] ); } return (
{alt { // Fallback if image fails to load const target = e.target as HTMLImageElement; target.style.display = 'none'; const fallback = document.createElement('span'); fallback.className = 'inline-block bg-red-100 text-red-800 px-1 rounded text-sm'; fallback.textContent = `[img:${imageId}] (failed to load)`; target.parentNode?.appendChild(fallback); }} />
); }; // Alternative approach: Create a hook to get attachments for the current memo export const useMemoAttachments = () => { // This would need to be implemented based on how memos are loaded // For now, return empty array return []; };