Skip to content
This repository has been archived by the owner on Jan 13, 2023. It is now read-only.

Commit

Permalink
Merge pull request #216 from dataware-tools/feature/add-rosbag-direct…
Browse files Browse the repository at this point in the history
…-preview

Support previewing rosbag files without rosbridge
  • Loading branch information
d-hayashi authored Nov 10, 2021
2 parents 27403e2 + 90487de commit 8b45a11
Show file tree
Hide file tree
Showing 3 changed files with 90 additions and 44 deletions.
94 changes: 66 additions & 28 deletions src/components/molecules/FilePreviewer/RosbagPreviewer/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ import {
ErrorMessage,
extractErrorMessageFromFetchError,
} from "@dataware-tools/app-common";
import Box from "@mui/material/Box";
import Button from "@mui/material/Button";
import Tab from "@mui/material/Tab";
import Tabs from "@mui/material/Tabs";
import React, { useEffect, useState } from "react";
import { JobSubmitter } from "./JobSubmitter";
import { JobViewer } from "./JobViewer";
Expand All @@ -17,6 +21,9 @@ import {
} from "utils";

type Props = {
tabIndex: number;
handleChangeTab: (_: React.SyntheticEvent, newValue: number) => void;
url: string;
error?: ErrorMessageProps;
onChangeJobTemplate: (jobTemplateId: string) => void;
onSubmitJob: () => void;
Expand All @@ -27,8 +34,11 @@ type Props = {
job?: jobStore.JobPostedModel;
};

export type RosbagPreviewerProps = { filePath: string };
export type RosbagPreviewerProps = { filePath: string; url: string };
const RosbagPreviewerPresentation = ({
tabIndex,
handleChangeTab,
url,
error,
onChangeJobTemplate,
onSubmitJob,
Expand All @@ -41,45 +51,67 @@ const RosbagPreviewerPresentation = ({
return error ? (
<ErrorMessage {...error} />
) : (
<div>
<DialogTitle>Submit a job</DialogTitle>
{jobTemplateList && (
<JobSubmitter
jobTemplateId={jobTemplateId}
jobTemplateList={jobTemplateList}
jobTemplate={jobTemplate}
jobType={jobType}
job={job}
onSubmitJob={onSubmitJob}
onChangeJobTemplate={onChangeJobTemplate}
/>
<Box>
<Box sx={{ borderBottom: 1, borderColor: "divider" }}>
<Tabs value={tabIndex} onChange={handleChangeTab} aria-label="tabs">
<Tab label="webviz" />
<Tab label="webviz with rosbridge" />
</Tabs>
</Box>
{tabIndex === 0 && (
<Box sx={{ paddingTop: "1em" }}>
<Button
onClick={() => {
window.open(
"https://webviz.io/app?remote-bag-url=" + url,
"_blank"
);
}}
>
Open with webviz
</Button>
</Box>
)}
{jobType && job && <JobViewer jobType={jobType} job={job} />}
</div>
{tabIndex === 1 && (
<Box>
<DialogTitle>Submit a job</DialogTitle>
{jobTemplateList && (
<JobSubmitter
jobTemplateId={jobTemplateId}
jobTemplateList={jobTemplateList}
jobTemplate={jobTemplate}
jobType={jobType}
job={job}
onSubmitJob={onSubmitJob}
onChangeJobTemplate={onChangeJobTemplate}
/>
)}
{jobType && job && <JobViewer jobType={jobType} job={job} />}
</Box>
)}
</Box>
);
};

export const RosbagPreviewer = ({
filePath,
url,
}: RosbagPreviewerProps): JSX.Element => {
const { getAccessTokenSilently: getAccessToken } = useAuth0();
const [tabIndex, setTabIndex] = useState<number>(0);
const [error, setError] = useState<ErrorMessageProps | undefined>(undefined);
const [jobTemplateId, setJobTemplateId] = useState<string | undefined>(
undefined
);
const [job, setJob] = useState<jobStore.JobPostedModel | undefined>(
undefined
);
const {
data: listJobTemplateRes,
error: listJobTemplateError,
} = useListJobTemplate(getAccessToken, undefined as never);
const {
data: getJobTemplateRes,
error: getJobTemplateError,
} = useGetJobTemplate(getAccessToken, {
jobTemplateId: jobTemplateId ? parseInt(jobTemplateId, 10) : undefined,
});
const { data: listJobTemplateRes, error: listJobTemplateError } =
useListJobTemplate(getAccessToken, undefined as never);
const { data: getJobTemplateRes, error: getJobTemplateError } =
useGetJobTemplate(getAccessToken, {
jobTemplateId: jobTemplateId ? parseInt(jobTemplateId, 10) : undefined,
});
const { data: getJobTypeRes, error: getJobTypeError } = useGetJobTypes(
getAccessToken,
{
Expand All @@ -91,9 +123,8 @@ export const RosbagPreviewer = ({
listJobTemplateError || getJobTemplateError || getJobTypeError;
useEffect(() => {
if (fetchError) {
const { reason, instruction } = extractErrorMessageFromFetchError(
fetchError
);
const { reason, instruction } =
extractErrorMessageFromFetchError(fetchError);
setError({ reason, instruction });
} else {
setError(undefined);
Expand Down Expand Up @@ -122,8 +153,15 @@ export const RosbagPreviewer = ({
}
};

const handleChangeTab = (_: React.SyntheticEvent, newValue: number) => {
setTabIndex(newValue);
};

return (
<RosbagPreviewerPresentation
tabIndex={tabIndex}
handleChangeTab={handleChangeTab}
url={url}
error={error}
jobTemplateId={jobTemplateId}
onChangeJobTemplate={setJobTemplateId}
Expand Down
10 changes: 8 additions & 2 deletions src/components/molecules/FilePreviewer/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -103,8 +103,14 @@ const filePreviewerCandidates: Record<string, FilePreviewerContentWithSpec> = {
),
},
rosbag: {
spec: { extensions: ["bag"], contentTypes: ["application/rosbag"] },
render: (_, file) => <RosbagPreviewer filePath={file.path} />,
spec: { extensions: [".bag"], contentTypes: ["application/rosbag"] },
render: (databaseId, file) => (
<FileDownloadUrlInjector
databaseId={databaseId}
file={file}
render={(_, url) => <RosbagPreviewer filePath={file.path} url={url} />}
/>
),
},
audio: {
spec: { extensions: [".wav", ".mp3"], contentTypes: ["audio/.*"] },
Expand Down
30 changes: 16 additions & 14 deletions src/components/organisms/FileDownloadUrlInjector.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,23 +17,25 @@ export const FileDownloadUrlInjector = ({
render,
}: FileDownloadUrlInjectorProps): JSX.Element => {
const { getAccessTokenSilently: getAccessToken } = useAuth0();
const {
data: createJwtRes,
error: createJwtError,
} = useCreateJwtToDownloadFile(
getAccessToken,
{
requestBody: {
database_id: databaseId,
file_uuid: file.uuid,
content_type: file["content-type"],
const { data: createJwtRes, error: createJwtError } =
useCreateJwtToDownloadFile(
getAccessToken,
{
requestBody: {
database_id: databaseId,
file_uuid: file.uuid,
content_type: file["content-type"],
},
},
},
Boolean(file.uuid)
);
Boolean(file.uuid)
);

const urlPrefix = API_ROUTE.FILE.BASE.startsWith("http")
? API_ROUTE.FILE.BASE
: `${window.origin}${API_ROUTE.FILE.BASE}`;

const downloadURL = createJwtRes
? `${API_ROUTE.FILE.BASE}/download/${createJwtRes.token}`
? `${urlPrefix}/download/${createJwtRes.token}`
: undefined;
const isFetchFailed = Boolean(createJwtError);

Expand Down

0 comments on commit 8b45a11

Please sign in to comment.