From e50a0c67ebbd0542af339571646dbcb952fbf37e Mon Sep 17 00:00:00 2001 From: arunachalam-monk Date: Fri, 30 Aug 2024 17:38:30 +0530 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20sending=20image=20to=20backend.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/PhotoCapture/PhotoCapture.tsx | 2 + .../PhotoCapture/hooks/useAddDamageMode.ts | 2 +- .../src/PhotoCapture/hooks/useUploadQueue.ts | 43 ++++++++- packages/network/src/api/image/requests.ts | 88 ++++++++++++++++--- packages/network/src/api/models/image.ts | 1 + 5 files changed, 121 insertions(+), 15 deletions(-) diff --git a/packages/inspection-capture-web/src/PhotoCapture/PhotoCapture.tsx b/packages/inspection-capture-web/src/PhotoCapture/PhotoCapture.tsx index cc0d540b2..9b5b601d4 100644 --- a/packages/inspection-capture-web/src/PhotoCapture/PhotoCapture.tsx +++ b/packages/inspection-capture-web/src/PhotoCapture/PhotoCapture.tsx @@ -25,6 +25,7 @@ import { PhotoCaptureTutorialOption, Sight, AddDamage, + VehiclePart, } from '@monkvision/types'; import { useState } from 'react'; import { useTranslation } from 'react-i18next'; @@ -204,6 +205,7 @@ export function PhotoCapture({ additionalTasks, complianceOptions, eventHandlers: [adaptiveUploadEventHandlers, badConnectionWarningUploadEventHandlers], + damageVehicleParts: [VehiclePart.BUMPER_FRONT], // TODO: Handle this properly }); const images = usePhotoCaptureImages(inspectionId); const handlePictureTaken = usePictureTaken({ diff --git a/packages/inspection-capture-web/src/PhotoCapture/hooks/useAddDamageMode.ts b/packages/inspection-capture-web/src/PhotoCapture/hooks/useAddDamageMode.ts index 976fad6f1..1f3a933a1 100644 --- a/packages/inspection-capture-web/src/PhotoCapture/hooks/useAddDamageMode.ts +++ b/packages/inspection-capture-web/src/PhotoCapture/hooks/useAddDamageMode.ts @@ -75,7 +75,7 @@ export function useAddDamageMode(): AddDamageHandle { case AddDamage.PART_SELECT: setMode(PhotoCaptureMode.ADD_DAMAGE_PART_SELECT); trackEvent('AddDamage Selected', { - mode: PhotoCaptureMode.ADD_DAMAGE_1ST_SHOT, + mode: PhotoCaptureMode.ADD_DAMAGE_PART_SELECT, }); return; case AddDamage.DISABLED: diff --git a/packages/inspection-capture-web/src/PhotoCapture/hooks/useUploadQueue.ts b/packages/inspection-capture-web/src/PhotoCapture/hooks/useUploadQueue.ts index 1e4aaf280..e96b8fbeb 100644 --- a/packages/inspection-capture-web/src/PhotoCapture/hooks/useUploadQueue.ts +++ b/packages/inspection-capture-web/src/PhotoCapture/hooks/useUploadQueue.ts @@ -1,6 +1,13 @@ import { Queue, uniq, useQueue } from '@monkvision/common'; import { AddImageOptions, ImageUploadType, MonkApiConfig, useMonkApi } from '@monkvision/network'; -import { CaptureAppConfig, ComplianceOptions, MonkPicture, TaskName } from '@monkvision/types'; +import { + CaptureAppConfig, + ComplianceOptions, + ImageType, + MonkPicture, + TaskName, + VehiclePart, +} from '@monkvision/types'; import { useRef } from 'react'; import { useMonitoring } from '@monkvision/monitoring'; import { PhotoCaptureMode } from './useAddDamageMode'; @@ -41,6 +48,10 @@ export interface UploadQueueParams extends Pick { const { handleError } = useMonitoring(); const siblingIdRef = useRef(0); @@ -159,6 +197,7 @@ export function useUploadQueue({ true, additionalTasks, complianceOptions, + damageVehicleParts, ), ); const uploadDurationMs = Date.now() - startTs; diff --git a/packages/network/src/api/image/requests.ts b/packages/network/src/api/image/requests.ts index 682329e72..df2987746 100644 --- a/packages/network/src/api/image/requests.ts +++ b/packages/network/src/api/image/requests.ts @@ -1,6 +1,11 @@ import ky from 'ky'; import { Dispatch } from 'react'; -import { getFileExtensions, MonkActionType, MonkCreatedOneImageAction } from '@monkvision/common'; +import { + getFileExtensions, + MonkActionType, + MonkCreatedOneImageAction, + vehiclePartLabels, +} from '@monkvision/common'; import { ComplianceOptions, Image, @@ -12,6 +17,7 @@ import { MonkPicture, TaskName, TranslationObject, + VehiclePart, } from '@monkvision/types'; import { v4 } from 'uuid'; import { labels, sights } from '@monkvision/sights'; @@ -33,6 +39,11 @@ export enum ImageUploadType { * add damage workflow. */ CLOSE_UP_2_SHOT = 'close_up_2_shot', + /** + * Upload type corresponding to a part selection shot in the PhotoCapture process. when using the part select add + * damage workflow. + */ + PART_SELECT_SHOT = 'part_select_shot', /** * Upload type corresponding to a video frame in the VideoCapture process. */ @@ -110,6 +121,15 @@ export interface Add2ShotCloseUpImageOptions { compliance?: ComplianceOptions; } +export type AddPartSelectCloseUpImageOptions = Pick< + Add2ShotCloseUpImageOptions, + 'picture' | 'inspectionId' | 'compliance' | 'useThumbnailCaching' +> & { + uploadType: ImageUploadType.PART_SELECT_SHOT; + image_type: ImageType.CLOSE_UP; + vehicleParts: VehiclePart[]; +}; + /** * Options specififed when adding a video frame to a VideoCapture inspection. */ @@ -143,7 +163,8 @@ export interface AddVideoFrameOptions { export type AddImageOptions = | AddBeautyShotImageOptions | Add2ShotCloseUpImageOptions - | AddVideoFrameOptions; + | AddVideoFrameOptions + | AddPartSelectCloseUpImageOptions; interface AddImageData { filename: string; @@ -151,7 +172,10 @@ interface AddImageData { } function getImageType(options: AddImageOptions): ImageType { - if (options.uploadType === ImageUploadType.CLOSE_UP_2_SHOT) { + if ( + options.uploadType === ImageUploadType.CLOSE_UP_2_SHOT || + options.uploadType === ImageUploadType.PART_SELECT_SHOT + ) { return ImageType.CLOSE_UP; } return ImageType.BEAUTY_SHOT; @@ -169,12 +193,24 @@ function getImageLabel(options: AddImageOptions): TranslationObject | undefined nl: `Videoframe ${options.frameIndex}`, }; } - return { - en: options.firstShot ? 'Close Up (part)' : 'Close Up (damage)', - fr: options.firstShot ? 'Photo Zoomée (partie)' : 'Photo Zoomée (dégât)', - de: options.firstShot ? 'Gezoomtes Foto (Teil)' : 'Close Up (Schaden)', - nl: options.firstShot ? 'Nabij (onderdeel)' : 'Nabij (schade)', - }; + if (options.uploadType === ImageUploadType.PART_SELECT_SHOT) { + const partsTranslation = options.vehicleParts.map((part) => vehiclePartLabels[part]); + return { + en: `Damage on ${partsTranslation.map((part) => part.en).join(', ')}`, + fr: `Dommages sur ${partsTranslation.map((part) => part.en).join(', ')}`, + de: `Schaden an ${partsTranslation.map((part) => part.en).join(', ')}`, + nl: `Schade aan ${partsTranslation.map((part) => part.en).join(', ')}`, + }; + } + if (options.uploadType === ImageUploadType.CLOSE_UP_2_SHOT) { + return { + en: options.firstShot ? 'Close Up (part)' : 'Close Up (damage)', + fr: options.firstShot ? 'Photo Zoomée (partie)' : 'Photo Zoomée (dégât)', + de: options.firstShot ? 'Gezoomtes Foto (Teil)' : 'Close Up (Schaden)', + nl: options.firstShot ? 'Nabij (onderdeel)' : 'Nabij (schade)', + }; + } + return undefined as never; } function getAdditionalData(options: AddImageOptions): ImageAdditionalData { @@ -229,7 +265,33 @@ function createBeautyShotImageData( return { filename, body }; } -function createCloseUpImageData( +function createPartSelectImageData(options: AddPartSelectCloseUpImageOptions): AddImageData { + const filename = `part-select-${options.inspectionId}-${Date.now()}.jpg`; + + const body: ApiImagePost = { + acquisition: { + strategy: 'upload_multipart_form_keys', + file_key: MULTIPART_KEY_IMAGE, + }, + image_type: ImageType.CLOSE_UP, + tasks: [ + TaskName.DAMAGE_DETECTION, + { + name: TaskName.COMPLIANCES, + wait_for_result: + options.compliance?.enableCompliance && options.compliance?.useLiveCompliance, + }, + ], + detailed_viewpoint: { + centers_on: options.vehicleParts, + }, + additional_data: getAdditionalData(options), + }; + + return { filename, body }; +} + +function createCloseUp2ShotImageData( options: Add2ShotCloseUpImageOptions, filetype: string, ): AddImageData { @@ -278,11 +340,13 @@ function getAddImageData(options: AddImageOptions, filetype: string): AddImageDa case ImageUploadType.BEAUTY_SHOT: return createBeautyShotImageData(options, filetype); case ImageUploadType.CLOSE_UP_2_SHOT: - return createCloseUpImageData(options, filetype); + return createCloseUp2ShotImageData(options, filetype); case ImageUploadType.VIDEO_FRAME: return createVideoFrameData(options, filetype); + case ImageUploadType.PART_SELECT_SHOT: + return createPartSelectImageData(options); default: - throw new Error('Unknown image upload type.'); + return 'Unknown image upload type.' as never; } } diff --git a/packages/network/src/api/models/image.ts b/packages/network/src/api/models/image.ts index 06da6b64f..a6a9b9ff7 100644 --- a/packages/network/src/api/models/image.ts +++ b/packages/network/src/api/models/image.ts @@ -90,4 +90,5 @@ export interface ApiImagePost { image_sibling_key?: string; compliances?: ApiCompliance; additional_data?: ApiImageAdditionalData; + detailed_viewpoint?: ApiViewpointComponent; }