Skip to content

Commit

Permalink
change check for if a file is shareable (#439)
Browse files Browse the repository at this point in the history
* change check for if a file is shareable

* use constant for trajFileName

* use selector instead of type guard

* add unit test

* remove accidental auto import
  • Loading branch information
meganrm authored Oct 9, 2023
1 parent 67f2f58 commit 72f1a23
Show file tree
Hide file tree
Showing 8 changed files with 73 additions and 36 deletions.
13 changes: 6 additions & 7 deletions src/components/DownloadTrajectoryMenu/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,34 +3,33 @@ import { Button, Tooltip } from "antd";
import { ISimulariumFile } from "@aics/simularium-viewer/type-declarations";

import { DATA_BUCKET_URL, TOOLTIP_COLOR } from "../../constants";
import {
NetworkedSimFile,
LocalSimFile,
isNetworkSimFileInterface,
} from "../../state/trajectory/types";
import { NetworkedSimFile, LocalSimFile } from "../../state/trajectory/types";
import { Download } from "../Icons";

import styles from "./style.css";

interface DownloadTrajectoryMenuProps {
isBuffering: boolean;
isNetworkedFile: boolean;
simulariumFile: LocalSimFile | NetworkedSimFile;
}

const DownloadTrajectoryMenu = ({
isBuffering,
simulariumFile,
isNetworkedFile,
}: DownloadTrajectoryMenuProps): JSX.Element => {
const fileIsLoaded = () => !!simulariumFile.name;

const getHref = () => {
if (!fileIsLoaded()) {
return "";
}
if (isNetworkSimFileInterface(simulariumFile)) {
if (isNetworkedFile) {
return `${DATA_BUCKET_URL}/trajectory/${simulariumFile.name}`;
} else {
const data: ISimulariumFile = simulariumFile.data;
const localFile = simulariumFile as LocalSimFile; // isNetworkedFile checks for this
const data: ISimulariumFile = localFile.data;
const blob = data.getAsBlob();
return URL.createObjectURL(blob);
}
Expand Down
11 changes: 4 additions & 7 deletions src/components/ShareTrajectoryButton/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,12 @@ import React from "react";
import { Button, Tooltip } from "antd";

import { TOOLTIP_COLOR } from "../../constants";
import {
NetworkedSimFile,
LocalSimFile,
isLocalFileInterface,
} from "../../state/trajectory/types";
import { NetworkedSimFile, LocalSimFile } from "../../state/trajectory/types";
import { Share } from "../Icons";
import ShareTrajectoryModal from "../ShareTrajectoryModal";

import styles from "./style.css";
import { isOnlineTrajectory } from "../../util/userUrlHandling";

interface ShareTrajectoryButtonProps {
simulariumFile: LocalSimFile | NetworkedSimFile;
Expand All @@ -21,7 +18,7 @@ const ShareTrajectoryButton = ({
}: ShareTrajectoryButtonProps): JSX.Element => {
const [isSharing, setIsSharing] = React.useState(false);

const isLocalFile = isLocalFileInterface(simulariumFile);
const trajectoryIsSharable = isOnlineTrajectory(location.href);

const handleShare = () => {
setIsSharing(!isSharing);
Expand All @@ -42,7 +39,7 @@ const ShareTrajectoryButton = ({
{isSharing ? (
<div className={styles.overlay}>
<ShareTrajectoryModal
isLocalFile={isLocalFile}
trajectoryIsSharable={trajectoryIsSharable}
closeModal={handleShare}
/>
</div>
Expand Down
22 changes: 11 additions & 11 deletions src/components/ShareTrajectoryModal/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,14 @@ import styles from "./style.css";
import theme from "../theme/light-theme.css";

interface ShareTrajectoryModalProps {
isLocalFile: boolean;
trajectoryIsSharable: boolean;
closeModal: () => void;
timeUnits: TimeUnits;
displayTimes: DisplayTimes;
}

const ShareTrajectoryModal = ({
isLocalFile,
trajectoryIsSharable,
closeModal,
timeUnits,
displayTimes,
Expand Down Expand Up @@ -102,7 +102,7 @@ const ShareTrajectoryModal = ({
};

const modalOptions = {
localFile: {
errorMessage: {
content: (
<>
<h4>{Warn} The current file is stored on your device.</h4>
Expand Down Expand Up @@ -134,7 +134,7 @@ const ShareTrajectoryModal = ({
</Button>
),
},
networkedFile: {
isSharable: {
content: (
<>
<div>
Expand Down Expand Up @@ -177,20 +177,20 @@ const ShareTrajectoryModal = ({
<CustomModal
className={classNames(styles.uploadModal, theme.lightTheme)}
title="Share Trajectory"
width={isLocalFile ? 611 : 550}
width={trajectoryIsSharable ? 550 : 611}
onCancel={closeModal}
mask={false}
centered
open
footer={
isLocalFile
? modalOptions.localFile.footer
: modalOptions.networkedFile.footer
trajectoryIsSharable
? modalOptions.isSharable.footer
: modalOptions.errorMessage.footer
}
>
{isLocalFile
? modalOptions.localFile.content
: modalOptions.networkedFile.content}
{trajectoryIsSharable
? modalOptions.isSharable.content
: modalOptions.errorMessage.content}
<Divider />
</CustomModal>
);
Expand Down
6 changes: 5 additions & 1 deletion src/components/ViewerTitle/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { VIEWER_PATHNAME } from "../../routes";
import TRAJECTORIES from "../../constants/networked-trajectories";

import styles from "./style.css";
import { URL_PARAM_KEY_FILE_NAME } from "../../constants";

interface ViewerTitleProps {
simulariumFileName: string;
Expand All @@ -27,7 +28,10 @@ const ViewerTitle: React.FunctionComponent<ViewerTitleProps> = (
// networked-trajectories.ts to get its version info
// TODO: Eventually we should put all the contents of networked-trajectories.ts in the
// Simularium files themselves
const trajectoryId = location.search.replace("?trajFileName=", "");
const trajectoryId = location.search.replace(
`?${URL_PARAM_KEY_FILE_NAME}=`,
""
);
const currentTrajectory = TRAJECTORIES.find(
(trajectory) => trajectory.id === trajectoryId
);
Expand Down
5 changes: 5 additions & 0 deletions src/containers/AppHeader/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import DownloadTrajectoryMenu from "../../components/DownloadTrajectoryMenu";
interface AppHeaderProps {
simulariumFile: LocalSimFile | NetworkedSimFile;
isBuffering: boolean;
isNetworkedFile: boolean;
clearSimulariumFile: ActionCreator<ClearSimFileDataAction>;
changeToLocalSimulariumFile: ActionCreator<RequestLocalFileAction>;
changeToNetworkedFile: ActionCreator<RequestNetworkFileAction>;
Expand All @@ -48,6 +49,7 @@ class AppHeader extends React.Component<AppHeaderProps> {
setViewerStatus,
clearSimulariumFile,
setError,
isNetworkedFile,
} = this.props;
let lastModified = 0;
let displayName = "";
Expand Down Expand Up @@ -89,6 +91,7 @@ class AppHeader extends React.Component<AppHeaderProps> {
<DownloadTrajectoryMenu
isBuffering={isBuffering}
simulariumFile={simulariumFile}
isNetworkedFile={isNetworkedFile}
/>
</div>
</div>
Expand All @@ -101,6 +104,8 @@ function mapStateToProps(state: State) {
simulariumFile:
trajectoryStateBranch.selectors.getSimulariumFile(state),
isBuffering: viewerStateBranch.selectors.getIsBuffering(state),
isNetworkedFile:
trajectoryStateBranch.selectors.getIsNetworkedFile(state),
};
}

Expand Down
1 change: 1 addition & 0 deletions src/state/trajectory/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ export interface NetworkedSimFile {
}
export const isLocalFileInterface = (file: any): file is LocalSimFile =>
!!file.lastModified;

export const isNetworkSimFileInterface = (
file: any
): file is NetworkedSimFile => !!file.title;
Expand Down
24 changes: 23 additions & 1 deletion src/util/test/index.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import * as React from "react";

import { USER_TRAJ_REDIRECTS } from "../../constants";
import {
URL_PARAM_KEY_FILE_NAME,
URL_PARAM_KEY_USER_URL,
USER_TRAJ_REDIRECTS,
} from "../../constants";
import {
bindAll,
convertToSentenceCase,
Expand All @@ -16,6 +20,7 @@ import {
getRedirectUrl,
getUserTrajectoryUrl,
isGoogleDriveUrl,
isOnlineTrajectory,
urlCheck,
} from "../userUrlHandling";

Expand Down Expand Up @@ -373,4 +378,21 @@ describe("User Url handling", () => {
expect(result).toEqual("dl.dropboxusercontent.com/path");
});
});
describe("isOnlineTrajectory", () => {
it("it returns true if the trajectory is hosted online", () => {
const cloudTrajectoryUrl = `simularium?${URL_PARAM_KEY_USER_URL}=url`;
const result = isOnlineTrajectory(cloudTrajectoryUrl);
expect(result).toBeTruthy;
});
it("true if the trajectory is one of our networked models", () => {
const networkedUrl = `simularium?${URL_PARAM_KEY_FILE_NAME}=url`;
const result = isOnlineTrajectory(networkedUrl);
expect(result).toBeTruthy;
});
it("it returns false if no relevant url params are present", () => {
const url = `simularium?other_url_param=value`;
const result = isOnlineTrajectory(url);
expect(result).toBeFalsy;
});
});
});
27 changes: 18 additions & 9 deletions src/util/userUrlHandling.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
import { isString } from "lodash";

import { USER_TRAJ_REDIRECTS } from "../constants";
import {
URL_PARAM_KEY_FILE_NAME,
URL_PARAM_KEY_USER_URL,
USER_TRAJ_REDIRECTS,
} from "../constants";

const googleDriveUrlRegEx = /(?:drive.google\.com\/file\/d\/)(.*)(?=\/)|(?:drive.google\.com\/file\/d\/)(.*)/g;
const googleDriveUrlRegEx =
/(?:drive.google\.com\/file\/d\/)(.*)(?=\/)|(?:drive.google\.com\/file\/d\/)(.*)/g;
const googleDriveUrlExcludingIdRegEx = /(drive.google\.com\/file\/d\/)(?=.*)/g;

export const urlCheck = (urlToCheck: any): string => {
Expand All @@ -14,7 +19,8 @@ export const urlCheck = (urlToCheck: any): string => {
* I had to modify the original to allow s3 buckets which have multiple `.letters-letters.` in them
* and I made the http(s) required
*/
const regEx = /(https?:\/\/)([\w\-]){0,200}(\.[a-zA-Z][^\-])([\/\w]*)*\/?\??([^\n\r]*)?([^\n\r]*)/g;
const regEx =
/(https?:\/\/)([\w\-]){0,200}(\.[a-zA-Z][^\-])([\/\w]*)*\/?\??([^\n\r]*)?([^\n\r]*)/g;
if (regEx.test(urlToCheck)) {
return urlToCheck;
}
Expand Down Expand Up @@ -68,18 +74,14 @@ export const getFileIdFromUrl = (
export const getRedirectUrl = (url: string, fileName: string | undefined) => {
if (url && fileName && USER_TRAJ_REDIRECTS.includes(url)) {
// ex) simularium.allencell.org/viewer?trajFileName=endocytosis.simularium
return `${location.origin}${
location.pathname
}?trajFileName=${fileName}`;
return `${location.origin}${location.pathname}?${URL_PARAM_KEY_FILE_NAME}=${fileName}`;
} else {
return "";
}
};

export const getGoogleApiUrl = (id: string) => {
return `https://www.googleapis.com/drive/v2/files/${id}?alt=media&key=${
process.env.GOOGLE_API_KEY
}`;
return `https://www.googleapis.com/drive/v2/files/${id}?alt=media&key=${process.env.GOOGLE_API_KEY}`;
};

export const getUserTrajectoryUrl = (url: string, fileId?: string) => {
Expand All @@ -89,3 +91,10 @@ export const getUserTrajectoryUrl = (url: string, fileId?: string) => {
return url.replace("dropbox.com", "dl.dropboxusercontent.com");
}
};

export const isOnlineTrajectory = (url: string) => {
return (
url.includes(URL_PARAM_KEY_USER_URL) ||
url.includes(URL_PARAM_KEY_FILE_NAME)
);
};

0 comments on commit 72f1a23

Please sign in to comment.