Skip to content

Commit

Permalink
Move from subdomains for special hosted builds to just URLs (#627)
Browse files Browse the repository at this point in the history
  • Loading branch information
theosanderson authored Oct 26, 2024
1 parent 6ff4a1e commit afe628e
Show file tree
Hide file tree
Showing 3 changed files with 118 additions and 113 deletions.
179 changes: 66 additions & 113 deletions taxonium_website/src/App.jsx
Original file line number Diff line number Diff line change
@@ -1,90 +1,98 @@
import React, { useState, Suspense, useRef, useEffect } from "react";
import AboutOverlay from "./components/AboutOverlay";
import TaxoniumBit from "./components/TaxoniumBit";

import { CgListTree } from "react-icons/cg";
import { BsInfoSquare } from "react-icons/bs";
import { FaGithub } from "react-icons/fa";
import { HiOutlineBookOpen } from "react-icons/hi";
import useQueryAsState from "./hooks/useQueryAsState";
import classNames from "classnames";
import { useInputHelper } from "./hooks/useInputHelper";

import InputSupplier from "./components/InputSupplier";
import treeConfig from "./trees.json";

import { HiOutlineBookOpen } from "react-icons/hi";

const default_query = {};
// Hardcoded list of paths to show in the showcase
const SHOWCASE_PATHS = [
"sars-cov-2/public",
"taxonomy/visual",
"taxonomy/full",
"mpox/public",
];

default_query.backend = null;
if (window.location.hostname.includes("viridian.taxonium.org")) {
default_query.backend = "https://viridian-api.cov2tree.org";
}
if (window.location.hostname.includes("cov2tree.org")) {
default_query.backend = "https://api.cov2tree.org";
}
function checkLegacyHostname() {
const currentHostname = window.location.hostname;

if (window.location.hostname.includes("mpx.taxonium.org")) {
default_query.protoUrl = "https://mpx-tree.vercel.app/mpx.jsonl.gz";
default_query.configUrl = "https://mpx-tree.vercel.app/config.json";
}
// Look through all configurations for matching legacy hostnames
for (const [path, config] of Object.entries(treeConfig)) {
if (
config.legacyHostnames &&
config.legacyHostnames.includes(currentHostname)
) {
// If we find a match, redirect to the new path
// Preserve any query parameters
const newPath = `${window.location.protocol}//${window.location.host}/${path}${window.location.search}`;

if (window.location.hostname.includes("taxonomy.taxonium.org")) {
default_query.treeUrl =
"https://cov2tree.nyc3.digitaloceanspaces.com/ncbi/tree.nwk.gz";
// Only redirect if we're not already on the correct path
if (!window.location.pathname.startsWith(`/${path}`)) {
window.location.href = newPath;
return true;
}
}
}

default_query.metaUrl =
"https://cov2tree.nyc3.digitaloceanspaces.com/ncbi/metadata.tsv.gz";
return false;
}

default_query.configUrl =
"https://cov2tree.nyc3.digitaloceanspaces.com/ncbi/config.json";
function getConfigFromPath() {
// First check for legacy hostname redirects
if (checkLegacyHostname()) {
return null; // Return null as we're about to redirect
}

default_query.ladderizeTree = "true";
}
// Remove leading slash and get full path
const path = window.location.pathname.substring(1);

if (window.location.hostname.includes("visualtreeoflife.taxonium.org")) {
default_query.protoUrl =
"https://cov2tree.nyc3.digitaloceanspaces.com/wikidata/out.jsonl.gz";
// Return the configuration for this path, if it exists
return treeConfig[path] || null;
}

function App() {
useEffect(() => {
import("taxonium-component");
}, []);
const [uploadedData, setUploadedData] = useState(null);

// check if .epicov.org is in the URL
const pathConfig = getConfigFromPath();
const default_query = pathConfig || {};

const [uploadedData, setUploadedData] = useState(null);
const [query, updateQuery] = useQueryAsState(default_query);
const [title, setTitle] = useState(null);
const [beingDragged, setBeingDragged] = useState(false);
const [aboutEnabled, setAboutEnabled] = useState(false);
const [overlayContent, setOverlayContent] = useState(null);

const dragTimeout = useRef(null);

const inputHelper = useInputHelper({
setUploadedData,
updateQuery,
query,
uploadedData,
});
const [title, setTitle] = useState(null);
const [beingDragged, setBeingDragged] = useState(false);

const dragTimeout = useRef(null);

function onDrop(ev) {
console.log("File(s) dropped");
setBeingDragged(false);

// Prevent default behavior (Prevent file from being opened)
ev.preventDefault();

if (ev.dataTransfer.items) {
// Use DataTransferItemList interface to access the file(s)
for (var i = 0; i < ev.dataTransfer.items.length; i++) {
// If dropped items aren't files, reject them
if (ev.dataTransfer.items[i].kind === "file") {
var file = ev.dataTransfer.items[i].getAsFile();
inputHelper.readFile(file);
}
}
} else {
// Use DataTransfer interface to access the file(s)
inputHelper.readFile(ev.dataTransfer.files[0]);
}
}
Expand All @@ -97,18 +105,14 @@ function App() {
ev.preventDefault();
return;
}
console.log("File(s) in drop zone");
setBeingDragged(true);
if (dragTimeout.current) {
clearTimeout(dragTimeout.current);
}

// Prevent default behavior (Prevent file from being opened)
ev.preventDefault();
}

function onDragLeave(ev) {
//debounce:
if (dragTimeout.current) {
clearTimeout(dragTimeout.current);
}
Expand All @@ -117,62 +121,19 @@ function App() {
}, 500);
}

const [aboutEnabled, setAboutEnabled] = useState(false);

const protoUrl = query.protoUrl;
if (protoUrl && protoUrl.includes(".pb")) {
const url_parts = window.location.href.split("?", 2);
if (url_parts[1]) {
console.log(url_parts, "parts");
// V1 format
if (!window.redirecting) {
window.alert(
"It looks like you are trying to load a Taxonium V1 proto. We will now redirect you to the V1 site. "
);
}
window.redirecting = 1;
// split url into before question mark and after

window.location.href =
"https://cov2tree-git-v1-theosanderson.vercel.app/?" + url_parts[1];
} else {
if (!window.redirecting) {
window.alert(
"It looks like you are trying to load a Taxonium V1 proto. We will now redirect you to the V1 site. "
);
}
window.redirecting = 1;
window.location.href =
"https://cov2tree-git-v1-theosanderson.vercel.app/?protoUrl=" +
protoUrl;
// Generate showcase items from hardcoded list
const showCase = SHOWCASE_PATHS.map((path) => {
const config = treeConfig[path];
if (!config) {
console.warn(`No configuration found for showcase path: ${path}`);
return null;
}
}
const [overlayContent, setOverlayContent] = useState(null);
// does the window location contain epicov anywhere
const isGisaid = window.location.toString().includes("epicov.org");

const showCase = [
{
title: "SARS-CoV-2",
url: "/?backend=https://api.cov2tree.org",
desc: "All seven million public sequences of SARS-CoV-2 from the INSDC databases",
},
{
title: "Wikidata visual tree of life",
url: "/?configUrl=https%3A%2F%2Fcov2tree.nyc3.digitaloceanspaces.com%2Fncbi%2Fconfig_special2.json&protoUrl=https%3A%2F%2Fcov2tree.nyc3.cdn.digitaloceanspaces.com%2Fncbi%2Fspecial_filtered.jsonl.gz&xType=x_dist",
desc: "The tree of life, showing species from Wikidata with images. Links to Wikipedia.",
},
{
title: "NCBI Taxonomy (full)",
url: "https://taxonomy.taxonium.org",
desc: "Full 2.2M NCBI Taxonomy of species",
},
{
title: "Mpox",
url: "https://mpx.taxonium.org",
desc: "Mpox sequences from GenBank",
},
];
return {
title: config.title,
url: `/${path}`,
desc: config.description,
};
}).filter(Boolean); // Remove any null entries from missing configs

return (
<>
Expand All @@ -195,20 +156,19 @@ function App() {
className={classNames(
"from-gray-500 to-gray-600 bg-gradient-to-bl shadow-md",
"flex justify-between items-center px-4 flex-shrink-0",
isGisaid ? "h-11" : "h-16"
"h-16"
)}
>
<h1 className="text-xl text-white flex items-center space-x-2">
{title ? (
<>
{window.screen.width < 600 && (
<>
{" "}
<span className="font-medium pr-2">{title}</span>
<span className="flex flex-col text-center">
<span className="text-xs">visualised with</span>
<a
href="//taxonium.org"
href="/"
className="underline hover:no-underline text-sm flex items-center"
target="_top"
>
Expand All @@ -225,7 +185,7 @@ function App() {
<CgListTree className="h- ml-1 w-4 mr-1" />
<span className="text-xs ml-1">visualised with </span>
<a
href="//taxonium.org"
href="/"
className="underline hover:no-underline text-xs ml-0.5"
target="_top"
>
Expand All @@ -236,17 +196,13 @@ function App() {
)}
</>
) : (
<a
href="//taxonium.org"
className="hover:underline"
target="_top"
>
<a href="/" className="hover:underline" target="_top">
<CgListTree className="h-6 w-6 inline-block mr-2 -mt-1" />
<span className="font-bold">Taxonium</span>
</a>
)}
</h1>
<div className="flex ">
<div className="flex">
<button
onClick={() => setAboutEnabled(true)}
className="text-white font-bold hover:underline flex items-center"
Expand All @@ -260,7 +216,7 @@ function App() {
title="Source code"
target="_top"
>
<FaGithub className="w-6 h-6 opacity-80 mr-2 " />
<FaGithub className="w-6 h-6 opacity-80 mr-2" />
</a>
</div>
</div>
Expand All @@ -287,15 +243,13 @@ function App() {
</p>
<InputSupplier inputHelper={inputHelper} />
<div className="flex flex-col space-y-3 pt-6">
{/* Horizontal separator and text "or load an existing tree:"*/}
<div className="flex flex-row items-center">
<div className="flex-1 border-t border-gray-300"></div>
<div className="px-2 text-gray-500 text-sm">
or load an existing tree:
</div>
<div className="flex-1 border-t border-gray-300"></div>
</div>
{/* Showcases */}
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
{showCase.map((item, i) => (
<div key={i} className="border border-gray-300 rounded p-3">
Expand All @@ -311,14 +265,13 @@ function App() {
))}
</div>
</div>
{/* documentation link, centered with react-icons*/}
<div className="flex justify-center pt-5">
<a
href="//docs.taxonium.org"
className="text-gray-500 hover:underline"
target="_top"
>
<HiOutlineBookOpen className="w-6 h-4 opacity-80 mr-2 inline-block " />
<HiOutlineBookOpen className="w-6 h-4 opacity-80 mr-2 inline-block" />
Read the Taxonium documentation
</a>
</div>
Expand Down
36 changes: 36 additions & 0 deletions taxonium_website/src/trees.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
{
"sars-cov-2/public": {
"backend": "https://api.cov2tree.org",
"title": "SARS-CoV-2",
"description": "All seven million public sequences of SARS-CoV-2 from the INSDC databases",
"legacyHostnames": ["cov2tree.org"]
},
"sars-cov-2/viridian": {
"backend": "https://viridian-api.cov2tree.org",
"title": "SARS-CoV-2 Viridian",
"description": "SARS-CoV-2 sequences processed through Viridian pipeline",
"legacyHostnames": ["viridian.taxonium.org"]
},
"mpox/public": {
"protoUrl": "https://mpx-tree.vercel.app/mpx.jsonl.gz",
"configUrl": "https://mpx-tree.vercel.app/config.json",
"title": "Mpox",
"description": "Mpox sequences from GenBank",
"legacyHostnames": ["mpx.taxonium.org"]
},
"taxonomy/full": {
"treeUrl": "https://cov2tree.nyc3.digitaloceanspaces.com/ncbi/tree.nwk.gz",
"metaUrl": "https://cov2tree.nyc3.digitaloceanspaces.com/ncbi/metadata.tsv.gz",
"configUrl": "https://cov2tree.nyc3.digitaloceanspaces.com/ncbi/config.json",
"ladderizeTree": true,
"title": "NCBI Taxonomy (full)",
"description": "Full 2.2M NCBI Taxonomy of species",
"legacyHostnames": ["taxonomy.taxonium.org"]
},
"taxonomy/visual": {
"protoUrl": "https://cov2tree.nyc3.digitaloceanspaces.com/wikidata/out.jsonl.gz",
"title": "Wikidata visual tree of life",
"description": "The tree of life, showing species from Wikidata with images. Links to Wikipedia.",
"legacyHostnames": ["visualtreeoflife.taxonium.org"]
}
}
16 changes: 16 additions & 0 deletions taxonium_website/vercel.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"routes": [
{
"src": "/assets/(.*)",
"dest": "/assets/$1"
},
{
"src": "/(.*)",
"dest": "/index.html"
},
{
"src": "/favicon.ico",
"dest": "/favicon.ico"
}
]
}

0 comments on commit afe628e

Please sign in to comment.