diff --git a/app/src/assets/localization/en/run_details.json b/app/src/assets/localization/en/run_details.json index 5e41e36f266..eb088382820 100644 --- a/app/src/assets/localization/en/run_details.json +++ b/app/src/assets/localization/en/run_details.json @@ -21,6 +21,7 @@ "cancel_run_module_info": "Additionally, any hardware modules used within the protocol will remain active and maintain their current states until deactivated.", "canceling_run": "Canceling Run", "canceling_run_dot": "canceling run...", + "capture_image": "Capture image", "clear_protocol": "Clear protocol", "clear_protocol_to_make_available": "Clear protocol from robot to make it available.", "close_door": "Close robot door", diff --git a/app/src/pages/Desktop/LivestreamViewer/index.tsx b/app/src/pages/Desktop/LivestreamViewer/index.tsx index c3c42aa0890..1ad5e9706e5 100644 --- a/app/src/pages/Desktop/LivestreamViewer/index.tsx +++ b/app/src/pages/Desktop/LivestreamViewer/index.tsx @@ -1,7 +1,14 @@ import { useState } from 'react' import { useTranslation } from 'react-i18next' -import { Chip } from '@opentrons/components' +import { + Btn, + Chip, + COLORS, + Flex, + Icon, + StyledText, +} from '@opentrons/components' import { useHlsVideo } from '/app/pages/Desktop/LivestreamViewer/hooks/useHlsVideo' import { useReportWindowDurationEvent } from '/app/pages/Desktop/LivestreamViewer/hooks/useReportWindowDurationEvent' @@ -9,6 +16,7 @@ import { LivestreamInfoScreen, useLivestreamInfoScreen, } from '/app/pages/Desktop/LivestreamViewer/LivestreamInfoScreen' +import { useFeatureFlag } from '/app/redux/config' import { useCurrentRunId, useNotifyRunQuery } from '/app/resources/runs' import styles from './livestream.module.css' @@ -19,6 +27,8 @@ export function LivestreamViewer(): JSX.Element { // We make UI affordances when a run has ended, even if it is un-currented. // The livestream viewer makes the assumption that it will not *initially* render // for a run that is already historical. + const { t } = useTranslation('run_details') + const [retainedRunId, setRetainedRunId] = useState(null) const currentRunId = useCurrentRunId({ refetchInterval: RUN_POLLING_INTERVAL_MS, @@ -44,6 +54,7 @@ export function LivestreamViewer(): JSX.Element { isCurrentRunLoading, videoError ) + const liveStreamImageCaptureEnabled = useFeatureFlag('camera') useReportWindowDurationEvent( retainedRunId, @@ -72,6 +83,19 @@ export function LivestreamViewer(): JSX.Element { )} + {infoScreenType == null && liveStreamImageCaptureEnabled && ( + + + + + {t('capture_image')} + + + + )} ) } diff --git a/app/src/pages/Desktop/LivestreamViewer/livestream.module.css b/app/src/pages/Desktop/LivestreamViewer/livestream.module.css index 25cfbd9bdcb..f07e62b8a1e 100644 --- a/app/src/pages/Desktop/LivestreamViewer/livestream.module.css +++ b/app/src/pages/Desktop/LivestreamViewer/livestream.module.css @@ -36,3 +36,16 @@ .video_inactive { display: none; } + +.capture_image_button { + width: 100%; + height: 36px; + border-radius: var(--border-radius-8); +} + +.capture_image_button_text { + flex-direction: row; + align-items: center; + justify-content: center; + gap: var(--spacing-8); +}