Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

14 work on post previews #20

Merged
merged 3 commits into from
Mar 8, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 6 additions & 11 deletions packages/social-media-app/frontend/src/canvas/Canvas.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,16 +36,6 @@ export const Canvas = (
canvas,
} = useCanvas();

// Inside your Canvas component:
const filteredTextRectsCount = useMemo(() => {
const filtered = [...rects, ...pendingRects].filter(
(rect, i) =>
rect.content instanceof StaticContent &&
rect.content.content instanceof StaticMarkdownText
);
return filtered.length;
}, [rects, pendingRects]);

// rects and pendingRects purpose filtered for properties.appearance
const filteredRects = useMemo(() => {
return [...rects, ...pendingRects].filter((rect, i) =>
Expand Down Expand Up @@ -145,6 +135,11 @@ export const Canvas = (
coverParent={
properties.appearance === "chat-view-images"
}
fit={
properties.appearance === "chat-view-images"
? "cover"
: undefined
}
/>
</div>
);
Expand All @@ -160,7 +155,7 @@ export const Canvas = (
? "flex gap-4 p-4"
: ""
} ${properties.fitHeight ? "h-full" : ""} ${
properties.fitWidth ? "w-full" : "min-w-fit"
properties.fitWidth ? "w-full" : ""
}`}
>
{renderRects(filteredRects)}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ const CanvasWithReplies = (props: { canvas?: CanvasDB }) => {
return (
<div className="p-5 flex flex-col">
<Header publicKey={peer.identity.publicKey} />
<div className="rounded-md">
<div className="rounded-md flex">
<CanvasWrapper canvas={props.canvas}>
<Canvas draft={false} />
</CanvasWrapper>
Expand Down Expand Up @@ -123,7 +123,7 @@ export const CanvasAndReplies = () => {

return (
<div className="flex flex-col h-full">
<div className="flex-grow">
<div className="flex-grow max-w-[680px] w-full mx-auto">
<CanvasWithReplies key={0} canvas={lastCanvas} />
</div>
<CanvasWrapper
Expand Down
23 changes: 12 additions & 11 deletions packages/social-media-app/frontend/src/canvas/Preview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,22 +23,23 @@ export const CanvasPreview = (properties: { canvas: CanvasDB }) => {

return (
<button
className="btn w-full flex flex-row p-0 border border-solid"
className="btn w-full flex flex-row p-0 border border-solid max-h-[40vh] overflow-hidden"
onClick={async () => {
navigate(getCanvasPath(properties.canvas), {});
}}
>
<Header publicKey={properties.canvas.publicKey} direction="col" />
<div className="w-full flex">
{/* {name != null ? (
<div className="truncate whitespace-pre-line">{name}</div>
) : (
<div>Failed to create preview</div>
)} */}
<CanvasWrapper canvas={properties.canvas}>
<Canvas />
</CanvasWrapper>
</div>
<CanvasWrapper canvas={properties.canvas}>
<div className="w-full flex flex-col items-center relative overflow-hidden">
{/* Real image preview */}
<Canvas fitHeight />
<div className="absolute inset-0 -z-10">
<div className="relative blur-xl w-full h-full">
<Canvas fitHeight fitWidth />
</div>
</div>
</div>
</CanvasWrapper>
</button>
);
};
2 changes: 2 additions & 0 deletions packages/social-media-app/frontend/src/content/Frame.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ export const Frame = (properties: {
key?: number;
delete(): void;
coverParent?: boolean;
fit?: "cover" | "contain";
}) => {
const navigate = useNavigate();

Expand Down Expand Up @@ -78,6 +79,7 @@ export const Frame = (properties: {
}
}}
coverParent={coverParent}
fit={properties.fit}
/>
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ export type EditableStaticContentProps = {
onChange?: (newContent: StaticContent["content"]) => void;
thumbnail?: boolean;
coverParent?: boolean;
fit?: "cover" | "contain";
};

export const EditableStaticContent = ({
Expand All @@ -22,6 +23,7 @@ export const EditableStaticContent = ({
onChange,
thumbnail,
coverParent,
fit,
}: EditableStaticContentProps) => {
if (staticContent instanceof StaticMarkdownText) {
return (
Expand All @@ -43,6 +45,7 @@ export const EditableStaticContent = ({
onChange={onChange}
thumbnail={thumbnail}
coverParent={coverParent}
fit={fit}
/>
);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,29 +1,54 @@
/**
* @fileoverview React component for displaying and editing images with drag-and-drop functionality.
*/

import React, { useRef, useEffect, useState, useCallback } from "react";
import { StaticImage } from "@dao-xyz/social";
import { readFileAsImage } from "./utils";

/**
* Props interface for the ImageContent component
* ImageContentProps
* content - The image data to display
* onResize - Callback when image dimensions change
* [editable] - Whether the image can be edited/replaced
* [onChange] - Callback when image content changes
* [thumbnail] - Display as thumbnail
* [coverParent] - Cover parent container
* [fit] - How image should fit container. If not given, scales to parent on width and height
*/
export type ImageContentProps = {
content: StaticImage;
onResize: (dims: { width: number; height: number }) => void;
editable?: boolean;
onChange?: (newContent: StaticImage) => void;
thumbnail?: boolean;
coverParent?: boolean;
fit?: "cover" | "contain";
};

/**
* Component for displaying and editing image content
* Supports drag-and-drop uploads and dimension monitoring
*/
export const ImageContent = ({
content,
onResize,
editable = false,
onChange,
coverParent,
fit,
}: ImageContentProps) => {
// References for container element and dimension tracking
const containerRef = useRef<HTMLDivElement>(null);
const lastDims = useRef<{ width: number; height: number } | null>(null);
const threshold = 1;
const [isDragOver, setIsDragOver] = useState(false);

// ResizeObserver to trigger onResize callback
/**
* ResizeObserver setup to monitor container dimensions
* Triggers onResize callback when dimensions change beyond threshold
*/
useEffect(() => {
if (!containerRef.current) return;
const observer = new ResizeObserver((entries) => {
Expand All @@ -47,15 +72,22 @@ export const ImageContent = ({
return () => observer.disconnect();
}, [onResize, threshold]);

// Common file handling logic.
/**
* Handles processing of uploaded image files
*/
const handleFile = useCallback(readFileAsImage(onChange), [onChange]);

/**
* Handles file input change events
*/
const handleFileChange = (e: React.ChangeEvent<HTMLInputElement>) => {
const file = e.target.files && e.target.files[0];
handleFile(file);
};

// Drag and drop handlers
/**
* Drag and drop event handlers
*/
const handleDragOver = (e: React.DragEvent<HTMLDivElement>) => {
e.preventDefault();
setIsDragOver(true);
Expand All @@ -80,7 +112,11 @@ export const ImageContent = ({
onDragLeave={editable ? handleDragLeave : undefined}
onDrop={editable ? handleDrop : undefined}
className={`relative w-full h-full ${
coverParent ? "object-cover" : "min-w-max"
{
cover: "object-cover",
contain: "object-contain",
default: "",
}[fit ?? "default"]
} ${
editable
? "cursor-pointer border-2 border-dashed p-4 transition-colors duration-150 bg-gray-50 dark:bg-gray-800"
Expand All @@ -94,7 +130,13 @@ export const ImageContent = ({
<img
src={`data:${content.mimeType};base64,${content.base64}`}
alt={content.alt}
className="object-contain w-full h-full"
className={`w-full h-full ${
{
cover: "object-cover",
contain: "object-contain",
default: "",
}[fit ?? "default"]
}`}
style={{ maxHeight: "400px" }}
/>
{editable && (
Expand Down
4 changes: 2 additions & 2 deletions packages/social-media-app/frontend/src/context/TagInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -62,11 +62,11 @@ const TagInput = ({ tags, onTagsChange, renderTag }) => {
className="flex items-center gap-1 px-2 py-1 border border-gray-300 rounded h-full cursor-text"
onClick={() => inputRef.current.focus()}
>
<div className="h-full flex max-w-[50%] overflow-x-scroll overflow-y-hidden no-scrollbar">
<div className="h-full flex items-center max-w-[50%] overflow-x-scroll overflow-y-hidden no-scrollbar">
{tags.map((tag, index) => (
<React.Fragment key={index}>
{index > 0 ? (
<span className=" text-gray-400 ml-1 mr-1">/</span>
<span className="text-gray-400 ml-1 mr-1">/</span>
) : null}
<>{renderTagContent(tag, index)}</>
</React.Fragment>
Expand Down
Loading