Skip to content
This repository has been archived by the owner on Mar 24, 2024. It is now read-only.

Commit

Permalink
Register studio as a url handler for foxglove:// files (#604)
Browse files Browse the repository at this point in the history
This change adds support for foxglove:// urls and File -> New Window.

foxglove:// url support provides a way for hyperlinks links to invoke actions into the studio app. Such actions could include features like loading a bag file and jumping to a particular time, loading specific layouts, etc.

The first supported link is foxglove://open?type=rosbag&url=http://.... Clicking the link will inform studio to open the remote bag file.

Co-authored-by: John Hurliman <jhurliman@jhurliman.org>
  • Loading branch information
defunctzombie and jhurliman committed Apr 16, 2021
1 parent be8033e commit d5a96d3
Show file tree
Hide file tree
Showing 8 changed files with 606 additions and 362 deletions.
3 changes: 3 additions & 0 deletions app/OsContext.ts
Expand Up @@ -77,6 +77,9 @@ export interface OsContext {
// Get the version string from package.json
getAppVersion: () => string;

// Get an array of deep links provided on app launch
getDeepLinks: () => string[];

// file backed key/value storage
storage: Storage;
}
29 changes: 29 additions & 0 deletions app/components/PlayerManager.tsx
Expand Up @@ -14,6 +14,7 @@
import { PropsWithChildren, useCallback, useEffect, useMemo, useRef, useState } from "react";
import { connect, ConnectedProps } from "react-redux";
import { useAsync, useLocalStorage, useMountedState } from "react-use";
import { URL } from "universal-url";

import OsContextSingleton from "@foxglove-studio/app/OsContextSingleton";
import {
Expand Down Expand Up @@ -423,6 +424,34 @@ function PlayerManager({
}
}, []);

useEffect(() => {
const links = OsContextSingleton?.getDeepLinks() ?? [];
const firstLink = links[0];
if (firstLink == undefined) {
return;
}

try {
const url = new URL(firstLink);
// only support the open command

// Test if the pathname matches //open or //open/
if (!/\/\/open\/?/.test(url.pathname)) {
return;
}

// only support rosbag urls
const type = url.searchParams.get("type");
const bagUrl = url.searchParams.get("url");
if (type !== "rosbag" || bagUrl == undefined) {
return;
}
setPlayer(async (options: BuildPlayerOptions) => buildPlayerFromBagURLs([bagUrl], options));
} catch (err) {
log.error(err);
}
}, [setPlayer]);

// The first time we load a source, we restore the previous source state (i.e. url)
// and try to automatically load the source.
// Subsequent source changes do not restore the state which typically results in a user prompt
Expand Down

0 comments on commit d5a96d3

Please sign in to comment.