open links in browser

This commit is contained in:
vcoppe committed 2026-10-17 19:57:50 +02:00
1 parent 8d6885d58b
commit 358253b7a9
9 files changed
+90

No files matched your search

+52
View File
@@ -0,0 +1,52 @@
import { engine } from '$lib/engine';
/** Where the pages of the website are, for the links of the desktop app to them. */
const website = 'https://gpx.studio';
let installed = false;
/** The address to open in the browser for a link: the pages of the website are on the website. */
function browserURL(href: string): string {
const url = new URL(href, location.href);
return url.origin === location.origin
? `${website}${url.pathname}${url.search}${url.hash}`
: url.href;
}
/**
* Opens the links that leave the app in the browser of the system, as the window of the desktop app
* does not follow them: the external links, the links that open a new tab (the pages of the
* website, like the help), and what `window.open` is given. The other links are pages of the app.
* It is done once, for as long as the window is open.
*/
export function openLinksInBrowser() {
if (installed) {
return;
}
installed = true;
const onClick = (e: MouseEvent) => {
// the main button, or the middle one which opens a new tab
if (e.button > 1) {
return;
}
const link = (e.target as Element | null)?.closest?.('a[href]');
if (!(link instanceof HTMLAnchorElement)) {
return;
}
const url = new URL(link.href, location.href);
if (url.origin === location.origin && link.target !== '_blank' && e.button === 0) {
return;
}
e.preventDefault();
engine.openUrl(browserURL(link.href));
};
window.open = (url?: string | URL) => {
if (url !== undefined) {
engine.openUrl(browserURL(String(url)));
}
return null;
};
// before the router of the app, which would follow the link
document.addEventListener('click', onClick, true);
document.addEventListener('auxclick', onClick, true);
}
+1
View File
@@ -221,6 +221,7 @@ export async function createTauriBackend(): Promise<Backend> {
exportFiles: (fileIds, options) =>
invoke<boolean>('export_files', { fileIds, options }),
listFolder: (path) => invoke<FolderEntry[]>('list_folder', { path }),
openUrl: (url) => invoke('open_url', { url }),
listen: async (onEngineChanged, onWorkspaceChanged, onFilesOpened, onFolderChanged) => {
await listen<Outcome>('files-opened', (event) => onFilesOpened(event.payload));
await listen<Outcome>('engine-changed', (event) => onEngineChanged(event.payload));
+2
View File
@@ -89,6 +89,8 @@ export interface DesktopFiles {
exportFiles(fileIds: string[], options: ExportOptions): Promise<boolean>;
/** The folders and GPX files in a folder of the open folder (the open folder by default). */
listFolder(path?: string): Promise<FolderEntry[]>;
/** Opens a web page (or an email to write) in the app of the system for it. */
openUrl(url: string): Promise<void>;
/**
* Tells when the engine changed without being asked, because the files on the disk did (the
* outcome to apply), when the status of the files changed, when files were opened with the
+10
View File
@@ -617,6 +617,16 @@ class Engine {
await this.enqueue(async () => this.refreshWorkspace(this.backend!));
}
/** Opens a web page in the browser of the system (the desktop app). */
async openUrl(url: string) {
await this.ready;
try {
await this.backend!.desktop?.openUrl(url);
} catch (error) {
console.error('The page could not be opened', error);
}
}
/** The folders and GPX files in a folder of the open folder (the open folder by default). */
async listFolder(path?: string): Promise<FolderEntry[]> {
await this.ready;