Skip to content

Commit

Permalink
updated to use SourceDocumentDataRead when necessary
Browse files Browse the repository at this point in the history
  • Loading branch information
bigabig committed Oct 18, 2024
1 parent ee704fc commit f3dd09a
Show file tree
Hide file tree
Showing 16 changed files with 161 additions and 101 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { MouseEventHandler, useRef } from "react";
import { CodeRead } from "../../../../api/openapi/models/CodeRead.ts";
import { SourceDocumentWithDataRead } from "../../../../api/openapi/models/SourceDocumentWithDataRead.ts";
import { SourceDocumentDataRead } from "../../../../api/openapi/models/SourceDocumentDataRead.ts";
import { SpanAnnotationReadResolved } from "../../../../api/openapi/models/SpanAnnotationReadResolved.ts";
import SdocHooks from "../../../../api/SdocHooks.ts";
import DocumentRenderer from "../../../../views/annotation/DocumentRenderer/DocumentRenderer.tsx";
Expand All @@ -27,12 +27,12 @@ function TextAnnotationValidator({
annotations,
handleChangeAnnotations,
}: TextAnnotatorValidatorProps) {
const sdoc = SdocHooks.useGetDocument(sdocId);
const sdocData = SdocHooks.useGetDocumentData(sdocId);

if (sdoc.isSuccess) {
if (sdocData.isSuccess) {
return (
<TextAnnotationValidatorWithSdoc
sdoc={sdoc.data}
sdocData={sdocData.data}
codesForSelection={codesForSelection}
annotations={annotations}
handleChangeAnnotations={handleChangeAnnotations}
Expand All @@ -43,11 +43,11 @@ function TextAnnotationValidator({
}

interface TextAnnotatorValidatorWithSdocProps extends TextAnnotatorValidatorSharedProps {
sdoc: SourceDocumentWithDataRead;
sdocData: SourceDocumentDataRead;
}

function TextAnnotationValidatorWithSdoc({
sdoc,
sdocData,
codesForSelection,
annotations,
handleChangeAnnotations,
Expand All @@ -57,7 +57,7 @@ function TextAnnotationValidatorWithSdoc({

// computed
const { tokenData, annotationsPerToken, annotationMap } = useComputeTokenDataWithAnnotations({
sdoc: sdoc,
sdocData,
annotations: annotations,
});

Expand Down Expand Up @@ -136,12 +136,12 @@ function TextAnnotationValidatorWithSdoc({
<DocumentRenderer
className="myFlexFillAllContainer"
onMouseUp={handleMouseUp}
html={sdoc.html}
html={sdocData.html}
tokenData={tokenData}
annotationsPerToken={annotationsPerToken}
annotationMap={annotationMap}
isViewer={false}
projectId={sdoc.project_id}
projectId={sdocData.project_id}
style={{ zIndex: 1, overflowY: "auto" }}
/>
</>
Expand Down
26 changes: 16 additions & 10 deletions frontend/src/components/SourceDocument/SdocSentenceRenderer.tsx
Original file line number Diff line number Diff line change
@@ -1,32 +1,38 @@
import { SourceDocumentDataRead } from "../../api/openapi/models/SourceDocumentDataRead.ts";
import SdocHooks from "../../api/SdocHooks.ts";
import { SourceDocumentWithDataRead } from "../../api/openapi/models/SourceDocumentWithDataRead.ts";

interface SdocSentenceRendererProps {
sdoc: number | SourceDocumentWithDataRead;
sdoc: number | SourceDocumentDataRead;
sentenceId: number;
}

function SdocSentenceRenderer({ sdoc, sentenceId }: SdocSentenceRendererProps) {
if (typeof sdoc === "number") {
return <SdocSentenceRendererWithoutData sdocId={sdoc} sentenceId={sentenceId} />;
}
return <SdocSentenceRendererWithData sdoc={sdoc} sentenceId={sentenceId} />;
return <SdocSentenceRendererWithData sdocData={sdoc} sentenceId={sentenceId} />;
}

function SdocSentenceRendererWithoutData({ sdocId, sentenceId }: { sdocId: number; sentenceId: number }) {
const sdoc = SdocHooks.useGetDocument(sdocId);
const sdocData = SdocHooks.useGetDocumentData(sdocId);

if (sdoc.isSuccess) {
return <SdocSentenceRendererWithData sdoc={sdoc.data} sentenceId={sentenceId} />;
} else if (sdoc.isError) {
return <div>{sdoc.error.message}</div>;
if (sdocData.isSuccess) {
return <SdocSentenceRendererWithData sdocData={sdocData.data} sentenceId={sentenceId} />;
} else if (sdocData.isError) {
return <div>{sdocData.error.message}</div>;
} else {
return <div>Loading...</div>;
}
}

function SdocSentenceRendererWithData({ sdoc, sentenceId }: { sdoc: SourceDocumentWithDataRead; sentenceId: number }) {
return <>{sdoc.sentences[sentenceId]}</>;
function SdocSentenceRendererWithData({
sdocData,
sentenceId,
}: {
sdocData: SourceDocumentDataRead;
sentenceId: number;
}) {
return <>{sdocData.sentences[sentenceId]}</>;
}

export default SdocSentenceRenderer;
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { useMemo } from "react";
import { SourceDocumentDataRead } from "../../../api/openapi/models/SourceDocumentDataRead.ts";

interface HighlightTokenRendererProps {
beginToken: number;
endToken: number;
contextSize: number;
sdocData: SourceDocumentDataRead;
}

function HighlightTokenRenderer({ beginToken, endToken, contextSize, sdocData }: HighlightTokenRendererProps) {
const tokens = sdocData.tokens;
const { textBefore, textHighlight, textAfter } = useMemo(() => {
const textBefore = tokens.slice(beginToken - contextSize, beginToken).join(" ");
const textHighlight = tokens.slice(beginToken, endToken).join(" ");
const textAfter = tokens.slice(endToken, endToken + contextSize).join(" ");
return { textBefore, textHighlight, textAfter };
}, [tokens, beginToken, endToken, contextSize]);
return (
<>
{textBefore} <strong>{textHighlight}</strong> {textAfter}
</>
);
}

export default HighlightTokenRenderer;
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { AttachedObjectType } from "../../../api/openapi/models/AttachedObjectTy
import MemoButton from "../../../components/Memo/MemoButton.tsx";
import { CRUDDialogActions } from "../../../components/dialogSlice.ts";
import { useAppDispatch, useAppSelector } from "../../../plugins/ReduxHooks.ts";
import HighlightTokenRenderer from "./HighlightTokenRenderer.tsx";

interface SpanAnnotationCardProps {
annotationId: number | undefined;
Expand All @@ -23,7 +24,7 @@ interface SpanAnnotationCardProps {
function SpanAnnotationCard({ annotationId, ...props }: SpanAnnotationCardProps & Omit<CardProps, "elevation">) {
// global server state (react-query)
const spanAnnotation = SpanAnnotationHooks.useGetAnnotation(annotationId);
const sdoc = SdocHooks.useGetDocument(spanAnnotation.data?.sdoc_id);
const sdocData = SdocHooks.useGetDocumentData(spanAnnotation.data?.sdoc_id);

// global client state (redux)
const contextSize = useAppSelector((state) => state.annotatedSegments.contextSize);
Expand All @@ -42,18 +43,21 @@ function SpanAnnotationCard({ annotationId, ...props }: SpanAnnotationCardProps
<Typography variant="body1" component="div" sx={{ mt: 2 }}>
<i>Select an annotation to view it & it's context :)</i>
</Typography>
) : spanAnnotation.isSuccess && sdoc.isSuccess ? (
) : spanAnnotation.isSuccess && sdocData.isSuccess ? (
<Typography variant="body1" component="div" sx={{ mt: 2 }}>
{sdoc.data.content.substring(spanAnnotation.data.begin - contextSize, spanAnnotation.data.begin)}
<b>{sdoc.data.content.substring(spanAnnotation.data.begin, spanAnnotation.data.end)}</b>
{sdoc.data.content.substring(spanAnnotation.data.end, spanAnnotation.data.end + contextSize)}
<HighlightTokenRenderer
beginToken={spanAnnotation.data.begin_token}
endToken={spanAnnotation.data.end_token}
contextSize={contextSize}
sdocData={sdocData.data}
/>
</Typography>
) : spanAnnotation.isLoading || sdoc.isLoading ? (
) : spanAnnotation.isLoading || sdocData.isLoading ? (
<CircularProgress />
) : (
<Typography variant="body1" component="div">
{spanAnnotation.error?.message}
{sdoc.error?.message}
{sdocData.error?.message}
</Typography>
)}
</CardContent>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ const initialState: TableState & AnnotatedSegmentsState = {
...initialTableState,
// app state:
isSplitView: false,
contextSize: 100,
contextSize: 10,
};

export const AnnotatedSegmentsSlice = createSlice({
Expand Down
20 changes: 13 additions & 7 deletions frontend/src/views/annotation/Annotation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ function Annotation() {

// global server state (react query)
const sdoc = SdocHooks.useGetDocument(sdocId);
const sdocData = SdocHooks.useGetDocumentData(sdocId);

// rename document
const openSnackbar = useOpenSnackbar();
Expand Down Expand Up @@ -190,7 +191,7 @@ function Annotation() {
<CardContent>
{sdocId ? (
<>
{sdoc.isSuccess ? (
{sdoc.isSuccess && sdocData.isSuccess ? (
<Stack spacing={2}>
<div style={{ display: "flex", alignItems: "center" }}>
<EditableTypography
Expand All @@ -206,27 +207,32 @@ function Annotation() {
</div>
{sdoc.data.doctype === DocType.IMAGE ? (
isAnnotationMode ? (
<ImageAnnotator sdoc={sdoc.data} />
<ImageAnnotator sdocData={sdocData.data} />
) : (
<ImageViewer sdoc={sdoc.data} />
<ImageViewer sdocData={sdocData.data} />
)
) : sdoc.data.doctype === DocType.TEXT ? (
isAnnotationMode ? (
<TextAnnotator sdoc={sdoc.data} />
<TextAnnotator sdocData={sdocData.data} />
) : (
<TextViewer sdoc={sdoc.data} />
<TextViewer sdocData={sdocData.data} />
)
) : sdoc.data.doctype === DocType.AUDIO ? (
isAnnotationMode ? (
<div>Annotation is not (yet) supported for Audio Documents.</div>
) : (
<AudioVideoViewer sdoc={sdoc.data} showEntities={true} height={200} />
<AudioVideoViewer sdocData={sdocData.data} showEntities={true} height={200} />
)
) : sdoc.data.doctype === DocType.VIDEO ? (
isAnnotationMode ? (
<div>Annotation is not (yet) supported for Video Documents.</div>
) : (
<AudioVideoViewer sdoc={sdoc.data} showEntities={true} width={800} height={600} />
<AudioVideoViewer
sdocData={sdocData.data}
showEntities={true}
width={800}
height={600}
/>
)
) : (
<div>ERROR! This DocType is not (yet) supported!</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import AnnotationCardActionsMenu from "./AnnotationCardActionMenu.tsx";
import { AnnotationCardProps } from "./AnnotationCardProps.ts";

function BBoxAnnotationCard({ annotation, onClick, cardProps }: AnnotationCardProps<BBoxAnnotationReadResolved>) {
const sdoc = SdocHooks.useGetDocument(annotation.sdoc_id);
const sdocData = SdocHooks.useGetDocumentData(annotation.sdoc_id);

return (
<Card {...cardProps}>
Expand All @@ -32,9 +32,9 @@ function BBoxAnnotationCard({ annotation, onClick, cardProps }: AnnotationCardPr
/>
<CardActionArea onClick={onClick}>
<CardContent sx={{ pt: 1, pb: "16px !important", textAlign: "center" }}>
{sdoc.isSuccess ? (
{sdocData.isSuccess ? (
<ImageCropper
imageUrl={sdoc.data.content}
imageUrl={encodeURI(import.meta.env.VITE_APP_CONTENT + "/" + sdocData.data.html)}
x={annotation.x_min}
y={annotation.y_min}
width={annotation.x_max - annotation.x_min}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
import { useMemo } from "react";
import SdocHooks from "../../../api/SdocHooks.ts";
import { SourceDocumentDataRead } from "../../../api/openapi/models/SourceDocumentDataRead.ts";
import { SpanAnnotationReadResolved } from "../../../api/openapi/models/SpanAnnotationReadResolved.ts";
import { IToken } from "./IToken.ts";

function useComputeTokenData({ sdocId, userIds }: { sdocId: number; userIds: number[] }) {
function useComputeTokenData({ sdocData, userIds }: { sdocData: SourceDocumentDataRead; userIds: number[] }) {
// global server state (react query)
const sdoc = SdocHooks.useGetDocument(sdocId);
const annotations = SdocHooks.useGetSpanAnnotationsBatch(sdocId, userIds);
const annotations = SdocHooks.useGetSpanAnnotationsBatch(sdocData.id, userIds);

// computed
// todo: maybe implement with selector?
const tokenData: IToken[] | undefined = useMemo(() => {
if (!sdoc.data) return undefined;
if (!sdoc.data.token_character_offsets) return undefined;
if (!sdocData) return undefined;
if (!sdocData.token_character_offsets) return undefined;

const offsets = sdoc.data.token_character_offsets;
const texts = sdoc.data.tokens;
const offsets = sdocData.token_character_offsets;
const texts = sdocData.tokens;
const result = texts.map((text, index) => ({
beginChar: offsets[index][0],
endChar: offsets[index][1],
Expand All @@ -25,7 +25,7 @@ function useComputeTokenData({ sdocId, userIds }: { sdocId: number; userIds: num
newLine: text.split("\n").length - 1,
}));
return result;
}, [sdoc.data]);
}, [sdocData]);

// annotationMap stores annotationId -> SpanAnnotationReadResolved
// annotationsPerToken map stores tokenId -> spanAnnotationId[]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
import { useMemo } from "react";
import { SourceDocumentWithDataRead } from "../../../api/openapi/models/SourceDocumentWithDataRead.ts";
import { SourceDocumentDataRead } from "../../../api/openapi/models/SourceDocumentDataRead.ts";
import { SpanAnnotationReadResolved } from "../../../api/openapi/models/SpanAnnotationReadResolved.ts";
import { IToken } from "./IToken.ts";

function useComputeTokenDataWithAnnotations({
sdoc,
sdocData,
annotations,
}: {
sdoc: SourceDocumentWithDataRead;
sdocData: SourceDocumentDataRead;
annotations: SpanAnnotationReadResolved[];
}) {
// computed
// todo: maybe implement with selector?
const tokenData: IToken[] | undefined = useMemo(() => {
const offsets = sdoc.token_character_offsets;
const texts = sdoc.tokens;
const offsets = sdocData.token_character_offsets;
const texts = sdocData.tokens;
const result = texts.map((text, index) => ({
beginChar: offsets[index][0],
endChar: offsets[index][1],
Expand All @@ -24,7 +24,7 @@ function useComputeTokenDataWithAnnotations({
newLine: text.split("\n").length - 1,
}));
return result;
}, [sdoc]);
}, [sdocData]);

// todo: maybe implement with selector?
// this map stores annotationId -> SpanAnnotationReadResolved
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,23 @@ import { useMemo, useRef, useState } from "react";
import ReactPlayer from "react-player";
import type { OnProgressProps } from "react-player/base.d.ts";
import SdocHooks from "../../../api/SdocHooks.ts";
import { SourceDocumentWithDataRead } from "../../../api/openapi/models/SourceDocumentWithDataRead.ts";
import { SourceDocumentDataRead } from "../../../api/openapi/models/SourceDocumentDataRead.ts";

interface AudioVideoViewerProps {
sdoc: SourceDocumentWithDataRead;
sdocData: SourceDocumentDataRead;
showEntities: boolean;
width?: number;
height?: number;
}

function AudioVideoViewer({ sdoc, width, height }: AudioVideoViewerProps) {
function AudioVideoViewer({ sdocData, width, height }: AudioVideoViewerProps) {
// local client state
const [highlightedWordId, setHighlightedWordId] = useState(-1);
const playerRef = useRef<ReactPlayer>(null);
const currentHighlightedWordSpanRef = useRef<HTMLSpanElement>(null);

// global server state (react-query)
const transcriptWords = SdocHooks.useGetWordLevelTranscriptions(sdoc.id);
const transcriptWords = SdocHooks.useGetWordLevelTranscriptions(sdocData.id);

// ui events
const handleProgress = (state: OnProgressProps) => {
Expand Down Expand Up @@ -71,7 +71,7 @@ function AudioVideoViewer({ sdoc, width, height }: AudioVideoViewerProps) {
<>
<Box sx={{ display: "flex", justifyContent: "center", alignItems: "center" }}>
<ReactPlayer
url={sdoc.content}
url={encodeURI(import.meta.env.VITE_APP_CONTENT + "/" + sdocData.html)}
controls={true}
width={width ?? 640}
height={height ?? 360}
Expand Down
Loading

0 comments on commit f3dd09a

Please sign in to comment.