From 98f300da6abebff2ce9e480ed4fbdd960b244b00 Mon Sep 17 00:00:00 2001 From: Anna Viklund Date: Wed, 17 Jun 2026 11:42:47 +0200 Subject: [PATCH 1/5] fix: cleanup --- ui/src/data-services/models/capture.ts | 10 ++++++---- ui/src/pages/captures/capture-columns.tsx | 2 +- ui/src/pages/captures/capture-gallery.tsx | 2 +- ui/src/pages/session-details/session-details.tsx | 2 +- 4 files changed, 9 insertions(+), 7 deletions(-) diff --git a/ui/src/data-services/models/capture.ts b/ui/src/data-services/models/capture.ts index e4e1fc137..4d6d7b303 100644 --- a/ui/src/data-services/models/capture.ts +++ b/ui/src/data-services/models/capture.ts @@ -167,17 +167,19 @@ export class Capture { return this._capture.event?.name ?? '' } - get thumbnail_small(): string { - if (this._capture.thumbnails && this._capture.thumbnails.small) { + get thumbnailSmall(): string { + if (this._capture.thumbnails?.small) { return this._capture.thumbnails.small } + return this._capture.url } - get thumbnail_medium(): string { - if (this._capture.thumbnails && this._capture.thumbnails.medium) { + get thumbnailMedium(): string { + if (this._capture.thumbnails?.medium) { return this._capture.thumbnails.medium } + return this._capture.url } diff --git a/ui/src/pages/captures/capture-columns.tsx b/ui/src/pages/captures/capture-columns.tsx index 2e743ebaf..a17a8eedf 100644 --- a/ui/src/pages/captures/capture-columns.tsx +++ b/ui/src/pages/captures/capture-columns.tsx @@ -39,7 +39,7 @@ export const columns = ({ return ( diff --git a/ui/src/pages/captures/capture-gallery.tsx b/ui/src/pages/captures/capture-gallery.tsx index ddf478ef7..0e69782d9 100644 --- a/ui/src/pages/captures/capture-gallery.tsx +++ b/ui/src/pages/captures/capture-gallery.tsx @@ -20,7 +20,7 @@ export const CaptureGallery = ({ () => captures.map((c) => ({ id: c.id, - image: { src: c.thumbnail_small }, + image: { src: c.thumbnailSmall }, title: c.dateTimeLabel, to: c.sessionId ? getAppRoute({ diff --git a/ui/src/pages/session-details/session-details.tsx b/ui/src/pages/session-details/session-details.tsx index 66abf074d..5cf9ca539 100644 --- a/ui/src/pages/session-details/session-details.tsx +++ b/ui/src/pages/session-details/session-details.tsx @@ -166,7 +166,7 @@ const Content = ({ session }: { session: SessionDetails }) => { detections={activeCapture?.detections ?? []} height={activeCapture?.height ?? session.firstCapture.height} showDetections={settings.showDetections} - src={activeCapture?.thumbnail_medium} + src={activeCapture?.thumbnailMedium} width={activeCapture?.width ?? session.firstCapture.width} /> From 08e592aabb5aee0d6372b5f2f100d095be6ce998 Mon Sep 17 00:00:00 2001 From: Anna Viklund Date: Wed, 17 Jun 2026 12:51:54 +0200 Subject: [PATCH 2/5] feat: make it possible to zoom and pan capture --- ui/package.json | 1 + .../capture/capture.module.scss | 22 +-------- .../pages/session-details/capture/capture.tsx | 49 ++++++++++--------- ui/yarn.lock | 11 +++++ 4 files changed, 39 insertions(+), 44 deletions(-) diff --git a/ui/package.json b/ui/package.json index 624daf146..454c0147c 100644 --- a/ui/package.json +++ b/ui/package.json @@ -38,6 +38,7 @@ "react-markdown": "^9.0.1", "react-plotly.js": "^2.6.0", "react-router-dom": "^6.8.2", + "react-zoom-pan-pinch": "^4.0.3", "tailwind-merge": "^3.6.0" }, "scripts": { diff --git a/ui/src/pages/session-details/capture/capture.module.scss b/ui/src/pages/session-details/capture/capture.module.scss index 04ddb8334..a07d80c29 100644 --- a/ui/src/pages/session-details/capture/capture.module.scss +++ b/ui/src/pages/session-details/capture/capture.module.scss @@ -1,14 +1,6 @@ -.wrapper { - position: relative; - width: 100%; - height: 0; -} - -.image, .overlay, .details, -.detections, -.loadingWrapper { +.detections { position: absolute; width: 100%; height: 100%; @@ -56,15 +48,3 @@ } } } - -.loadingWrapper { - display: flex; - align-items: center; - justify-content: center; -} - -@media only screen and (max-width: $breakpoint-md) { - .wrapper { - grid-column: span 2; - } -} diff --git a/ui/src/pages/session-details/capture/capture.tsx b/ui/src/pages/session-details/capture/capture.tsx index a2bb43e86..03cacb8f4 100644 --- a/ui/src/pages/session-details/capture/capture.tsx +++ b/ui/src/pages/session-details/capture/capture.tsx @@ -8,6 +8,7 @@ import { TABS, } from 'pages/occurrence-details/occurrence-details' import { useLayoutEffect, useMemo, useRef, useState } from 'react' +import { TransformComponent, TransformWrapper } from 'react-zoom-pan-pinch' import { SCORE_THRESHOLDS } from 'utils/constants' import { STRING, translate } from 'utils/language' import { useActiveOccurrences } from '../hooks/useActiveOccurrences' @@ -118,31 +119,33 @@ export const Capture = ({ }, [width, height, naturalSize]) return ( -
- -
- {renderOverlay && } - -
- {isLoading && ( -
+
+ + + +
+ {renderOverlay ? : null} + +
+
+
+ {isLoading ? ( +
- )} + ) : null}
) } diff --git a/ui/yarn.lock b/ui/yarn.lock index 0a7fecfac..188e5ec68 100644 --- a/ui/yarn.lock +++ b/ui/yarn.lock @@ -4752,6 +4752,7 @@ __metadata: react-markdown: "npm:^9.0.1" react-plotly.js: "npm:^2.6.0" react-router-dom: "npm:^6.8.2" + react-zoom-pan-pinch: "npm:^4.0.3" sass: "npm:^1.58.3" tailwind-merge: "npm:^3.6.0" tailwindcss: "npm:^3.4.14" @@ -11396,6 +11397,16 @@ __metadata: languageName: node linkType: hard +"react-zoom-pan-pinch@npm:^4.0.3": + version: 4.0.3 + resolution: "react-zoom-pan-pinch@npm:4.0.3" + peerDependencies: + react: "*" + react-dom: "*" + checksum: 611bc498891550c5e59da5ee94996ff9c31eae533affa10f2fa0b0cb7b5333b51c1e7aa1bb918dcfff2a103c42de0b1963e1fdfe4fa87fcae36b046c37a822b1 + languageName: node + linkType: hard + "react@npm:^18.2.0": version: 18.2.0 resolution: "react@npm:18.2.0" From 2434d3dcbd2a2c5f29dad3dc7a89c3c63dc93747 Mon Sep 17 00:00:00 2001 From: Anna Viklund Date: Wed, 17 Jun 2026 13:50:05 +0200 Subject: [PATCH 3/5] feat: add zoom controls --- .../pages/session-details/capture/capture.tsx | 10 ++++-- .../pages/session-details/session-details.tsx | 11 +++++-- .../pages/session-details/zoom-settings.tsx | 33 +++++++++++++++++++ 3 files changed, 49 insertions(+), 5 deletions(-) create mode 100644 ui/src/pages/session-details/zoom-settings.tsx diff --git a/ui/src/pages/session-details/capture/capture.tsx b/ui/src/pages/session-details/capture/capture.tsx index 03cacb8f4..6e2848ee7 100644 --- a/ui/src/pages/session-details/capture/capture.tsx +++ b/ui/src/pages/session-details/capture/capture.tsx @@ -8,7 +8,11 @@ import { TABS, } from 'pages/occurrence-details/occurrence-details' import { useLayoutEffect, useMemo, useRef, useState } from 'react' -import { TransformComponent, TransformWrapper } from 'react-zoom-pan-pinch' +import { + ReactZoomPanPinchRef, + TransformComponent, + TransformWrapper, +} from 'react-zoom-pan-pinch' import { SCORE_THRESHOLDS } from 'utils/constants' import { STRING, translate } from 'utils/language' import { useActiveOccurrences } from '../hooks/useActiveOccurrences' @@ -29,6 +33,7 @@ interface CaptureProps { height: number | null showDetections?: boolean src?: string + transformRef: React.RefObject width: number | null } @@ -38,6 +43,7 @@ export const Capture = ({ height, showDetections, src, + transformRef, width, }: CaptureProps) => { const [naturalSize, setNaturalSize] = useState<{ @@ -120,7 +126,7 @@ export const Capture = ({ return (
- + { const Content = ({ session }: { session: SessionDetails }) => { // Settings const [poll, setPoll] = useState(false) + const transformRef = useRef(null) const [settings, setSettings] = useState({ defaultFilters: true, showDetections: true, @@ -166,7 +169,8 @@ const Content = ({ session }: { session: SessionDetails }) => { detections={activeCapture?.detections ?? []} height={activeCapture?.height ?? session.firstCapture.height} showDetections={settings.showDetections} - src={activeCapture?.thumbnailMedium} + src={activeCapture?.url} + transformRef={transformRef} width={activeCapture?.width ?? session.firstCapture.width} />
@@ -210,7 +214,8 @@ const Content = ({ session }: { session: SessionDetails }) => { setActiveCaptureId={setActiveCaptureId} />
-
+
+ +}) => ( + <> + + + + +) From b9600a91eae11a611a952628be5eb48639dffb31 Mon Sep 17 00:00:00 2001 From: Anna Viklund Date: Wed, 17 Jun 2026 14:41:45 +0200 Subject: [PATCH 4/5] layout: tweak layout for smaller screens --- ui/src/pages/session-details/session-details.tsx | 12 ++++++------ ui/src/pages/session-details/view-settings.tsx | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/ui/src/pages/session-details/session-details.tsx b/ui/src/pages/session-details/session-details.tsx index 9ad49cbe5..a55dd1ca2 100644 --- a/ui/src/pages/session-details/session-details.tsx +++ b/ui/src/pages/session-details/session-details.tsx @@ -128,8 +128,8 @@ const Content = ({ session }: { session: SessionDetails }) => { > {user.loggedIn ? : null} -
- +
+ { />
-
+
{activeCapture ? ( <> @@ -207,14 +207,14 @@ const Content = ({ session }: { session: SessionDetails }) => { )}
-
+
-
+
{
-
+
From 8cb4150b55ff6de1368e385b703865fbd5e68ef8 Mon Sep 17 00:00:00 2001 From: Anna Viklund Date: Wed, 17 Jun 2026 14:48:18 +0200 Subject: [PATCH 5/5] chore: replace hard coded strings and add tooltips --- .../pages/session-details/zoom-settings.tsx | 38 +++++++++++-------- ui/src/utils/language.ts | 4 ++ 2 files changed, 26 insertions(+), 16 deletions(-) diff --git a/ui/src/pages/session-details/zoom-settings.tsx b/ui/src/pages/session-details/zoom-settings.tsx index 8d5cd5fac..4bf435f11 100644 --- a/ui/src/pages/session-details/zoom-settings.tsx +++ b/ui/src/pages/session-details/zoom-settings.tsx @@ -1,6 +1,7 @@ import { MinusIcon, PlusIcon } from 'lucide-react' -import { Button } from 'nova-ui-kit' +import { BasicTooltip, Button } from 'nova-ui-kit' import { ReactZoomPanPinchRef } from 'react-zoom-pan-pinch' +import { STRING, translate } from 'utils/language' export const ZoomSettings = ({ transformRef, @@ -13,21 +14,26 @@ export const ZoomSettings = ({ size="small" variant="ghost" > - Reset - - - + + + + + + + ) diff --git a/ui/src/utils/language.ts b/ui/src/utils/language.ts index c07f6038c..6c6b3c2be 100644 --- a/ui/src/utils/language.ts +++ b/ui/src/utils/language.ts @@ -49,6 +49,8 @@ export enum STRING { VIEW_ALL, VIEW_DOCS, VIEW_PUBLIC_PROJECTS, + ZOOM_IN, + ZOOM_OUT, /* ENTITY */ ENTITY_ADD, @@ -407,6 +409,8 @@ const ENGLISH_STRINGS: { [key in STRING]: string } = { [STRING.VIEW_ALL]: 'View all', [STRING.VIEW_DOCS]: 'View docs', [STRING.VIEW_PUBLIC_PROJECTS]: 'View public projects', + [STRING.ZOOM_IN]: 'Zoom in', + [STRING.ZOOM_OUT]: 'Zoom out', /* FIELD_LABEL */ [STRING.FIELD_LABEL_ADDED_AT]: 'Added at',