From b731743090aad84aa00100f6ac0b0c30a051a75f Mon Sep 17 00:00:00 2001 From: Arthur de Moulins Date: Mon, 6 Jan 2025 18:58:29 +0100 Subject: [PATCH] WIP --- .../api/migrations/Version20250106174830.php | 32 ++++++++++++++ .../Api/Model/Input/ThreadMessageInput.php | 2 + .../Api/Model/Output/ThreadMessageOutput.php | 3 ++ .../ThreadMessageOutputTransformer.php | 1 + .../Api/Processor/PostMessageProcessor.php | 1 + databox/api/src/Entity/Discussion/Message.php | 13 ++++++ .../Discussion/DiscussionMessage.tsx | 11 +++-- .../src/components/Discussion/Thread.tsx | 4 ++ .../Media/Asset/AssetDiscussion.tsx | 3 +- databox/client/src/types.ts | 44 ++++++++++++++++++- 10 files changed, 108 insertions(+), 6 deletions(-) create mode 100644 databox/api/migrations/Version20250106174830.php diff --git a/databox/api/migrations/Version20250106174830.php b/databox/api/migrations/Version20250106174830.php new file mode 100644 index 000000000..8de31e0a7 --- /dev/null +++ b/databox/api/migrations/Version20250106174830.php @@ -0,0 +1,32 @@ +addSql('ALTER TABLE message ADD attachments JSON DEFAULT NULL'); + } + + public function down(Schema $schema): void + { + // this down() migration is auto-generated, please modify it to your needs + $this->addSql('CREATE SCHEMA public'); + $this->addSql('ALTER TABLE message DROP attachments'); + } +} diff --git a/databox/api/src/Api/Model/Input/ThreadMessageInput.php b/databox/api/src/Api/Model/Input/ThreadMessageInput.php index 4ed83be25..919a22ca3 100644 --- a/databox/api/src/Api/Model/Input/ThreadMessageInput.php +++ b/databox/api/src/Api/Model/Input/ThreadMessageInput.php @@ -11,6 +11,8 @@ final class ThreadMessageInput #[Assert\NotBlank] public ?string $content = null; + public ?array $attachments = null; + public ?string $threadKey = null; public ?string $threadId = null; diff --git a/databox/api/src/Api/Model/Output/ThreadMessageOutput.php b/databox/api/src/Api/Model/Output/ThreadMessageOutput.php index 8446a6f49..e87d078c0 100644 --- a/databox/api/src/Api/Model/Output/ThreadMessageOutput.php +++ b/databox/api/src/Api/Model/Output/ThreadMessageOutput.php @@ -23,4 +23,7 @@ class ThreadMessageOutput extends AbstractUuidOutput #[Groups([Message::GROUP_LIST, Message::GROUP_READ])] public ?string $content = null; + + #[Groups([Message::GROUP_LIST, Message::GROUP_READ])] + public ?array $attachments = null; } diff --git a/databox/api/src/Api/OutputTransformer/ThreadMessageOutputTransformer.php b/databox/api/src/Api/OutputTransformer/ThreadMessageOutputTransformer.php index c3b9281f8..2a9520a55 100644 --- a/databox/api/src/Api/OutputTransformer/ThreadMessageOutputTransformer.php +++ b/databox/api/src/Api/OutputTransformer/ThreadMessageOutputTransformer.php @@ -38,6 +38,7 @@ public function transform(object $data, string $outputClass, array &$context = [ $output->setId($data->getId()); $output->content = $data->getContent(); + $output->attachments = $data->getAttachments(); $output->thread = $data->getThread(); if ($this->hasGroup([ diff --git a/databox/api/src/Api/Processor/PostMessageProcessor.php b/databox/api/src/Api/Processor/PostMessageProcessor.php index 3cc2ad6de..af0789e85 100644 --- a/databox/api/src/Api/Processor/PostMessageProcessor.php +++ b/databox/api/src/Api/Processor/PostMessageProcessor.php @@ -59,6 +59,7 @@ public function process($data, Operation $operation, array $uriVariables = [], a $message->setThread($thread); $message->setAuthorId($user->getId()); $message->setContent($data->content); + $message->setAttachments($data->attachments); $this->em->persist($message); $this->em->flush(); diff --git a/databox/api/src/Entity/Discussion/Message.php b/databox/api/src/Entity/Discussion/Message.php index 54c399772..aba07fbd5 100644 --- a/databox/api/src/Entity/Discussion/Message.php +++ b/databox/api/src/Entity/Discussion/Message.php @@ -99,6 +99,9 @@ class Message extends AbstractUuidEntity #[ORM\Column(type: Types::TEXT, nullable: false)] private ?string $content = null; + #[ORM\Column(type: Types::JSON, nullable: true)] + private ?array $attachments = null; + public function getThread(): ?Thread { return $this->thread; @@ -128,4 +131,14 @@ public function setContent(?string $content): void { $this->content = $content; } + + public function getAttachments(): ?array + { + return $this->attachments; + } + + public function setAttachments(?array $attachments): void + { + $this->attachments = $attachments; + } } diff --git a/databox/client/src/components/Discussion/DiscussionMessage.tsx b/databox/client/src/components/Discussion/DiscussionMessage.tsx index 04c156b1e..4bc303f1f 100644 --- a/databox/client/src/components/Discussion/DiscussionMessage.tsx +++ b/databox/client/src/components/Discussion/DiscussionMessage.tsx @@ -1,19 +1,24 @@ -import {ThreadMessage} from "../../types.ts"; +import {AssetAnnotation, ThreadMessage} from "../../types.ts"; import {Divider} from "@mui/material"; import moment from "moment"; +import {OnAnnotations} from "../Media/Asset/Attribute/Attributes.tsx"; type Props = { message: ThreadMessage; + onAnnotations?: OnAnnotations | undefined; }; export default function DiscussionMessage({ message, + onAnnotations, }: Props) { - const m = moment(message.createdAt); + const annotations: string[] = message.attachments?.filter(a => a.type === 'annotation').map(a => JSON.parse(a.content) as AssetAnnotation) ?? []; return <> -
+
0 ? () => onAnnotations!(annotations) : undefined} + >
diff --git a/databox/client/src/components/Discussion/Thread.tsx b/databox/client/src/components/Discussion/Thread.tsx index 5375d034c..af4e15fb7 100644 --- a/databox/client/src/components/Discussion/Thread.tsx +++ b/databox/client/src/components/Discussion/Thread.tsx @@ -6,15 +6,18 @@ import MessageForm from "./MessageForm.tsx"; import {CircularProgress} from "@mui/material"; import DiscussionMessage from "./DiscussionMessage.tsx"; import {useChannelRegistration} from "../../lib/pusher.ts"; +import {OnAnnotations} from "../Media/Asset/Attribute/Attributes.tsx"; type Props = { threadKey: string; threadId?: string; + onAnnotations: OnAnnotations | undefined; }; export default function Thread({ threadKey, threadId, + onAnnotations, }: Props) { const [messages, setMessages] = React.useState>(); @@ -58,6 +61,7 @@ export default function Thread({ ))} diff --git a/databox/client/src/components/Media/Asset/AssetDiscussion.tsx b/databox/client/src/components/Media/Asset/AssetDiscussion.tsx index 00e6c746e..42ecc609d 100644 --- a/databox/client/src/components/Media/Asset/AssetDiscussion.tsx +++ b/databox/client/src/components/Media/Asset/AssetDiscussion.tsx @@ -11,7 +11,7 @@ type Props = { onAnnotations: OnAnnotations | undefined; }; -export default function AssetDiscussion({asset,}: Props) { +export default function AssetDiscussion({asset,onAnnotations}: Props) { const [expanded, setExpanded] = React.useState(true); const {t} = useTranslation(); @@ -34,6 +34,7 @@ export default function AssetDiscussion({asset,}: Props) { diff --git a/databox/client/src/types.ts b/databox/client/src/types.ts index d1a5f70df..e75cc7f59 100644 --- a/databox/client/src/types.ts +++ b/databox/client/src/types.ts @@ -259,9 +259,15 @@ export interface Thread extends Entity { createdAt: string; } +type MessageAttachment = { + type: string; + content: string; +} + export interface ThreadMessage extends Entity { id: string; content: string; + attachments?: MessageAttachment[]; author: User; createdAt: string; updatedAt: string; @@ -346,10 +352,44 @@ export enum AnnotationType { TimeRange = 'time_range', } -export type AssetAnnotation = { +export interface AssetAnnotation { type: AnnotationType; [prop: string]: any; -}; +} + +export interface PointAnnotation extends AssetAnnotation { + type: AnnotationType.Point; + x: number; + y: number; + page?: number; +} + +export interface CircleAnnotation extends AssetAnnotation { + type: AnnotationType.Circle; + x: number; + y: number; + radius: number; + page?: number; +} + +export interface RectAnnotation extends AssetAnnotation { + type: AnnotationType.Rect; + x: number; + y: number; + width: number; + height: number; +} + +export interface CueAnnotation extends AssetAnnotation { + type: AnnotationType.Cue; + time: number; +} + +export interface TimeRangeAnnotation extends AssetAnnotation { + type: AnnotationType.TimeRange; + start: number; + end: number; +} export interface Entity { id: string;