mirror of
https://github.com/gpxstudio/gpx.studio.git
synced 2026-10-19 09:22:12 +00:00
open links in browser
This commit is contained in:
1 parent
8d6885d58b
commit
358253b7a9
9 files changed
+90
No files matched your search
@@ -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);
|
||||
}
|
||||
@@ -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));
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
import { get } from 'svelte/store';
|
||||
import { getURLForLanguage } from '$lib/utils';
|
||||
import { inDesktopApp } from '$lib/engine/backend';
|
||||
import { openLinksInBrowser } from '$lib/desktop/links';
|
||||
import { hoveredPoint, slicedStatistics } from '$lib/state/selection-statistics';
|
||||
import { engine } from '$lib/engine';
|
||||
import { boundsManager } from '$lib/state/bounds';
|
||||
@@ -72,6 +73,7 @@
|
||||
settings.connect(await engine.openStorage());
|
||||
|
||||
if (inDesktopApp()) {
|
||||
openLinksInBrowser();
|
||||
// the window of the desktop app always opens the same page, in English: it goes to the
|
||||
// language that was chosen last
|
||||
const saved = get(settings.language);
|
||||
|
||||
Reference in new issue
Block a user