From 0a2ad7ec8ed2ea8aa5f115f1fc1bc503b1fd6d1d Mon Sep 17 00:00:00 2001 From: Connor Burns Date: Tue, 9 Apr 2024 19:46:09 -0600 Subject: [PATCH] Support for file drop into window --- src/main/globals.ts | 4 ++++ src/main/main.ts | 31 ++++++++++++------------------- src/main/pluto.ts | 38 +++++++++++++++++--------------------- src/main/startup.ts | 10 +++------- src/main/util.ts | 9 ++++----- 5 files changed, 40 insertions(+), 52 deletions(-) diff --git a/src/main/globals.ts b/src/main/globals.ts index dd8fef1..a00c936 100644 --- a/src/main/globals.ts +++ b/src/main/globals.ts @@ -5,4 +5,8 @@ export class Globals { public static JULIA_PROJECT: string; public static PLUTO_LOCATION: string; public static PLUTO_SECRET: string = generateSecret(); + public static PLUTO_URL: URL; + public static get PLUTO_STARTED(): boolean { + return !!this.PLUTO_URL; + } } diff --git a/src/main/main.ts b/src/main/main.ts index efe255b..bbbe962 100644 --- a/src/main/main.ts +++ b/src/main/main.ts @@ -22,6 +22,7 @@ import { store } from './store'; import { GlobalWindowManager } from './windowHelpers'; import { initGlobals, startup } from './startup'; import { Globals } from './globals'; +import axios from 'axios'; generalLogger.verbose('---------- NEW SESSION ----------'); generalLogger.verbose('Application Version:', app.getVersion()); @@ -68,25 +69,6 @@ ipcMain.on('ipc-example', async (event, args) => { */ const createWindow = () => { - /** - * If window with {pathOrURL} is already open, focus on it - * else open a new one - */ - // if (!forceNew && pathOrURL) { - // const id = Pluto.notebook.getId(pathOrURL); - // if (id) { - // const windows = BrowserWindow.getAllWindows(); - // const windowId = windows.findIndex((window) => - // window.webContents.getURL().includes(id) - // ); - // if (windowId !== -1) { - // windows[windowId].focus(); - // return; - // } - // } else { - // generalLogger.log(`Opening ${pathOrURL} in new window.`); - // } - // } generalLogger.announce('Creating a new window.'); const firstPluto = new Pluto(); @@ -115,6 +97,8 @@ app.on('open-file', async (_event, file) => { // TODO: Implement filesystem open _event.preventDefault(); console.log(file); + console.log(app.isReady()); + console.log(GlobalWindowManager.getInstance().plutoWindows.length); // await createWindow(file); }); @@ -226,6 +210,15 @@ function createRequestListener() { }); return; } + // this route gets called when pasting a notebook into the welcome page + if (tail === 'notebookupload') { + next({ + redirectURL: new URL( + `notebookupload?secret=${Globals.PLUTO_SECRET}`, + Globals.PLUTO_URL + ).toString(), + }); + } } next({ cancel }); diff --git a/src/main/pluto.ts b/src/main/pluto.ts index 7c30a10..deab93f 100644 --- a/src/main/pluto.ts +++ b/src/main/pluto.ts @@ -28,10 +28,6 @@ class Pluto { private id: string | undefined; constructor(landingUrl: string | null = Pluto.resolveHtmlPath('index.html')) { - // currently Pluto functions as a singleton - // TODO: refactor to support arbitrary window counts - - Pluto.url ??= null; this.win = _createPlutoBrowserWindow(); if (landingUrl) { this.win.loadURL(landingUrl); @@ -127,14 +123,14 @@ class Pluto { const loader = new Loader(window); - if (Pluto.url) { + if (Globals.PLUTO_URL) { let params = {}; if (pathOrURL) { generalLogger.log(`Trying to open ${pathOrURL}`); if (type === 'path') { setBlockScreenText(pathOrURL); window.webContents.send('pluto-url', `Trying to open ${pathOrURL}`); - params = { secret: Pluto.url?.secret, path: pathOrURL }; + params = { secret: Globals.PLUTO_SECRET, path: pathOrURL }; } else if (type === 'url') { const newURL = new URL(pathOrURL); if (newURL.searchParams.has('path')) { @@ -144,7 +140,7 @@ class Pluto { `Trying to open ${newURL.searchParams.get('path')}` ); params = { - secret: Pluto.url?.secret, + secret: Globals.PLUTO_SECRET, path: newURL.searchParams.get('path'), }; } else { @@ -154,14 +150,14 @@ class Pluto { `Trying to open ${pathOrURL}` ); params = { - secret: Pluto.url?.secret, + secret: Globals.PLUTO_SECRET, url: pathOrURL, }; } } } else { params = { - secret: Pluto.url?.secret, + secret: Globals.PLUTO_SECRET, }; } @@ -224,7 +220,7 @@ class Pluto { * @returns nothing */ private static exportNotebook = async (id: string, type: PlutoExport) => { - if (!this.url) { + if (!Globals.PLUTO_STARTED) { dialog.showErrorBox( 'Pluto not intialized', 'Please wait for pluto to initialize first' @@ -245,13 +241,13 @@ class Pluto { let url: string | null; switch (type) { case PlutoExport.FILE: - url = `http://localhost:${this.url.port}/notebookfile?secret=${this.url.secret}&id=${id}`; + url = `http://localhost:${Globals.PLUTO_URL.port}/notebookfile?secret=${Globals.PLUTO_SECRET}&id=${id}`; break; case PlutoExport.HTML: - url = `http://localhost:${this.url.port}/notebookexport?secret=${this.url.secret}&id=${id}`; + url = `http://localhost:${Globals.PLUTO_URL.port}/notebookexport?secret=${Globals.PLUTO_SECRET}&id=${id}`; break; case PlutoExport.STATE: - url = `http://localhost:${this.url.port}/statefile?secret=${this.url.secret}&id=${id}`; + url = `http://localhost:${Globals.PLUTO_URL.port}/statefile?secret=${Globals.PLUTO_SECRET}&id=${id}`; break; default: window.webContents.print(); @@ -270,7 +266,7 @@ class Pluto { */ private static shutdownNotebook = async (_id?: string) => { try { - if (!this.url) { + if (!Globals.PLUTO_STARTED) { dialog.showErrorBox( 'Pluto not intialized', 'Please wait for pluto to initialize first' @@ -285,7 +281,7 @@ class Pluto { const res = await axios.get('shutdown', { params: { - secret: Pluto.url?.secret, + secret: Globals.PLUTO_SECRET, id, }, }); @@ -313,7 +309,7 @@ class Pluto { */ private static moveNotebook = async (_id?: string) => { try { - if (!this.url) { + if (!Globals.PLUTO_STARTED) { dialog.showErrorBox( 'Pluto not intialized', 'Please wait for pluto to initialize first' @@ -342,7 +338,7 @@ class Pluto { {}, { params: { - secret: Pluto.url?.secret, + secret: Globals.PLUTO_SECRET, id, newpath: filePath, }, @@ -376,7 +372,7 @@ class Pluto { let result; try { - if (!this.url) { + if (!Globals.PLUTO_STARTED) { dialog.showErrorBox( 'Pluto not intialized', 'Please wait for pluto to initialize first' @@ -387,7 +383,7 @@ class Pluto { const res = await axios.get('notebooklist', { responseType: 'arraybuffer', params: { - secret: Pluto.url?.secret, + secret: Globals.PLUTO_SECRET, }, }); @@ -415,7 +411,7 @@ class Pluto { let result: string | boolean = false; try { - if (!this.url) { + if (!Globals.PLUTO_STARTED) { dialog.showErrorBox( 'Pluto not intialized', 'Please wait for pluto to initialize first' @@ -426,7 +422,7 @@ class Pluto { const res = await axios.get('notebooklist', { responseType: 'arraybuffer', params: { - secret: Pluto.url?.secret, + secret: Globals.PLUTO_SECRET, }, }); diff --git a/src/main/startup.ts b/src/main/startup.ts index 134ef00..526258a 100644 --- a/src/main/startup.ts +++ b/src/main/startup.ts @@ -72,21 +72,17 @@ export async function startup(app: App) { if (dataString.includes('Loading') || dataString.includes('loading')) statusUpdate('loading'); - if (Pluto.url === null) { + if (!Globals.PLUTO_URL) { const plutoLog = dataString; if (plutoLog.includes('?secret=')) { const urlMatch = plutoLog.match(/http\S+/g); const entryUrl = urlMatch[0]; const tempURL = new URL(entryUrl); - Pluto.url = { - url: entryUrl, - port: tempURL.port, - secret: tempURL.searchParams.get('secret')!, - }; + Globals.PLUTO_URL = new URL(`${tempURL.protocol}//${tempURL.host}`); statusUpdate('loaded'); - setAxiosDefaults(Pluto.url); + setAxiosDefaults(Globals.PLUTO_URL); generalLogger.announce('Entry url found:', Pluto.url); } else if ( diff --git a/src/main/util.ts b/src/main/util.ts index 618d5d6..e87ae0a 100644 --- a/src/main/util.ts +++ b/src/main/util.ts @@ -95,14 +95,13 @@ const isUrlOrPath = (text: string) => { return 'none'; }; -const setAxiosDefaults = (url: PlutoURL) => { - const baseURL = new URL(url.url); - if (baseURL.hostname === 'localhost') { +const setAxiosDefaults = (url: URL) => { + if (url.hostname === 'localhost') { // there are issues with IPv6 and Node.JS on certain hardware / operating systems // the loopback IP is generally safer - baseURL.hostname = '127.0.0.1'; + url.hostname = '127.0.0.1'; } - axios.defaults.baseURL = baseURL.origin; + axios.defaults.baseURL = url.origin; axios.defaults.headers.common.Connection = 'keep-alive'; generalLogger.verbose('Base URL set to', axios.defaults.baseURL); };