diff --git a/desktop/package.json b/desktop/package.json
index 44783828..a3b929db 100644
--- a/desktop/package.json
+++ b/desktop/package.json
@@ -6,7 +6,7 @@
"license": "SEE LICENSE IN LICENSE.txt",
"scripts": {
"tsc": "tsup-node ./src/main.ts",
- "dev": "tsup-node ./src/main.ts ./src/preload/index.ts --watch --onSuccess 'yarn electron dist/main.js'",
+ "dev": "tsup-node ./src/main.ts ./src/sidebar/preload.ts ./src/app/preload.js --watch --onSuccess 'yarn electron dist/main.js'",
"prod": "tsc && node --max-old-space-size=4096 ./dist/server.js",
"runprod": "node --max-old-space-size=4096 ./dist/server.js",
"profile": "tsc && node --prof ./dist/server.js",
diff --git a/desktop/sidebar/index.html b/desktop/sidebar/index.html
new file mode 100644
index 00000000..7621461d
--- /dev/null
+++ b/desktop/sidebar/index.html
@@ -0,0 +1,59 @@
+
+
+
+
+ WorkAdventure Desktop Demo
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/desktop/sidebar/index.js b/desktop/sidebar/index.js
new file mode 100644
index 00000000..ce9a4334
--- /dev/null
+++ b/desktop/sidebar/index.js
@@ -0,0 +1,34 @@
+// let muted = false;
+
+if (window?.WorkAdventureDesktopApi?.desktop) {
+ (async () => {
+ const servers = await window.WorkAdventureDesktopApi.getServers();
+ servers.forEach((e) => {
+ const server = document.createElement("div");
+ server.innerText = e.name;
+ server.onclick = () => {
+ window.WorkAdventureDesktopApi.selectServer(e._id);
+ };
+ document.getElementById("servers").appendChild(server);
+ });
+ })();
+}
+
+document.getElementById("btn-reload").onclick = () => {
+ location.reload();
+};
+
+// window?.WorkAdventureDesktopApi?.onMutedKeyPress((event) => {
+// if (muted) {
+// document.getElementById("demo").innerHTML =
+// "Ready to speak! Press ctrl-alt-m to mute.";
+// } else {
+// document.getElementById("demo").innerHTML =
+// "Muted! Press ctrl-alt-m to unmute again.";
+// }
+// muted = !muted;
+// });
+
+// document.getElementById("btn-api").onclick = () => {
+// window.WorkAdventureDesktopApi.notify("Hello from website");
+// };
diff --git a/desktop/src/preload/index.ts b/desktop/src/app/preload.ts
similarity index 65%
rename from desktop/src/preload/index.ts
rename to desktop/src/app/preload.ts
index e1381cb8..74bcb048 100644
--- a/desktop/src/preload/index.ts
+++ b/desktop/src/app/preload.ts
@@ -2,7 +2,7 @@ import { contextBridge, ipcRenderer, IpcRendererEvent } from "electron";
contextBridge.exposeInMainWorld("WorkAdventureDesktopApi", {
desktop: true,
- notify: (txt: string) => ipcRenderer.send("notify", txt),
+ notify: (txt: string) => ipcRenderer.send("app:notify", txt),
onMutedKeyPress: (callback: (event: IpcRendererEvent) => void) =>
- ipcRenderer.on("on-muted-key-press", callback),
+ ipcRenderer.on("app:on-muted-key-press", callback),
});
diff --git a/desktop/src/ipc.ts b/desktop/src/ipc.ts
index 7d6dc95d..cedc0084 100644
--- a/desktop/src/ipc.ts
+++ b/desktop/src/ipc.ts
@@ -1,6 +1,7 @@
import { ipcMain } from "electron";
import { createAndShowNotification } from "./notification";
-import { getWindow } from "./window";
+import settings from "./settings";
+import { getAppView, getWindow } from "./window";
export function emitMutedKeyPress() {
const mainWindow = getWindow();
@@ -8,11 +9,62 @@ export function emitMutedKeyPress() {
throw new Error("Main window not found");
}
- mainWindow.webContents.send("on-muted-key-press");
+ mainWindow.webContents.send("app:on-muted-key-press");
}
export default () => {
- ipcMain.on("notify", (event, txt) => {
+ ipcMain.on("app:notify", (event, txt) => {
createAndShowNotification({ body: txt });
});
+
+ ipcMain.handle("sidebar:getServers", () => {
+ // TODO: remove
+ if (!settings.get("servers")) {
+ settings.set("servers", [
+ {
+ _id: "1",
+ name: "WA Demo",
+ url: "https://play.staging.workadventu.re/@/tcm/workadventure/wa-village",
+ },
+ {
+ _id: "2",
+ name: "My Server",
+ url: "http://play.workadventure.localhost/",
+ },
+ ]);
+ }
+
+ return settings.get("servers", []);
+ });
+
+ ipcMain.handle("sidebar:selectServer", (event, serverId: string) => {
+ const appView = getAppView();
+ if (!appView) {
+ throw new Error("App view not found");
+ }
+
+ const servers = settings.get("servers", []);
+ const selectedServer = servers.find((s) => s._id === serverId);
+
+ if (!selectedServer) {
+ return new Error("Server not found");
+ }
+
+ appView.webContents.loadURL(selectedServer.url);
+ return true;
+ });
+
+ ipcMain.handle(
+ "sidebar:addServer",
+ (event, serverName: string, serverUrl: string) => {
+ const servers = settings.get("servers", []);
+ servers.push({
+ _id: `${servers.length + 1}`,
+ name: serverName,
+ url: serverUrl,
+ });
+ settings.set("servers", servers);
+ return true;
+ }
+ );
};
diff --git a/desktop/src/log.ts b/desktop/src/log.ts
index 5378115d..5fab521f 100644
--- a/desktop/src/log.ts
+++ b/desktop/src/log.ts
@@ -1,5 +1,4 @@
import { dialog, shell } from "electron";
-import electronIsDev from "electron-is-dev";
import log from "electron-log";
import settings from "./settings";
@@ -40,18 +39,12 @@ function onRejection(reason: Error) {
function init() {
const logLevel = settings.get("log_level", "info");
- log.transports.file.level = logLevel;
log.transports.console.level = logLevel;
+ log.transports.file.level = logLevel;
// eslint-disable-next-line no-console
console.log = log.log.bind(log);
- if (!electronIsDev) {
- log.transports.file.fileName = "work-adventure.log";
- } else {
- console.log("Log file is disabled in dev. Using console output instead.");
- }
-
process.on("uncaughtException", onError);
process.on("unhandledRejection", onRejection);
}
diff --git a/desktop/src/settings.ts b/desktop/src/settings.ts
index c19a9979..fb61621c 100644
--- a/desktop/src/settings.ts
+++ b/desktop/src/settings.ts
@@ -1,9 +1,16 @@
import ElectronLog from "electron-log";
import Settings from "electron-settings";
+type Server = {
+ _id: string;
+ name: string;
+ url: string;
+};
+
type SettingsData = {
log_level: ElectronLog.LogLevel;
auto_launch_enabled: boolean;
+ servers: Server[];
};
let settings: SettingsData;
diff --git a/desktop/src/sidebar/preload.ts b/desktop/src/sidebar/preload.ts
new file mode 100644
index 00000000..71ba33ed
--- /dev/null
+++ b/desktop/src/sidebar/preload.ts
@@ -0,0 +1,10 @@
+import { contextBridge, ipcRenderer } from "electron";
+
+contextBridge.exposeInMainWorld("WorkAdventureDesktopApi", {
+ desktop: true,
+ getServers: () => ipcRenderer.invoke("sidebar:getServers"),
+ selectServer: (serverId: string) =>
+ ipcRenderer.invoke("sidebar:selectServer", serverId),
+ addServer: (serverName: string, serverUrl: string) =>
+ ipcRenderer.invoke("sidebar:addServer", serverName, serverUrl),
+});
diff --git a/desktop/src/tray.ts b/desktop/src/tray.ts
index 9396e438..984cdc5b 100644
--- a/desktop/src/tray.ts
+++ b/desktop/src/tray.ts
@@ -20,7 +20,7 @@ export function createTray() {
const trayContextMenu = Menu.buildFromTemplate([
{
id: "open",
- label: "Open / Close",
+ label: "Show / Hide",
click() {
const mainWindow = getWindow();
if (!mainWindow) {
diff --git a/desktop/src/window.ts b/desktop/src/window.ts
index a8f8babf..7bdb3262 100644
--- a/desktop/src/window.ts
+++ b/desktop/src/window.ts
@@ -1,17 +1,20 @@
-import { BrowserWindow } from "electron";
-import electronIsDev from "electron-is-dev";
+import { BrowserView, BrowserWindow } from "electron";
import windowStateKeeper from "electron-window-state";
import path from "path";
let mainWindow: BrowserWindow | undefined;
+let appView: BrowserView | undefined;
-const url = process.env.PLAY_URL;
-// "https://play.staging.workadventu.re/@/tcm/workadventure/wa-village"; // TODO
+const sidebarWidth = 70;
export function getWindow() {
return mainWindow;
}
+export function getAppView() {
+ return appView;
+}
+
export function createWindow() {
// do not re-create window if still existing
if (mainWindow) {
@@ -32,13 +35,8 @@ export function createWindow() {
height: windowState.height,
autoHideMenuBar: true,
show: false,
- title: "WorkAdventure",
webPreferences: {
- preload: path.join(__dirname, "../dist/preload/index.js"),
- // allowRunningInsecureContent: false,
- // contextIsolation: true, // TODO: remove in electron 12
- // nodeIntegration: false,
- // sandbox: true,
+ preload: path.join(__dirname, "../dist/sidebar/preload.js"),
},
});
@@ -47,18 +45,10 @@ export function createWindow() {
// and restore the maximized or full screen state
windowState.manage(mainWindow);
- mainWindow.on("show", () => {
- // TODO
- });
-
mainWindow.on("closed", () => {
mainWindow = undefined;
});
- mainWindow.once("ready-to-show", () => {
- mainWindow?.show();
- });
-
// mainWindow.on('close', async (event) => {
// if (!app.confirmedExitPrompt) {
// event.preventDefault(); // Prevents the window from closing
@@ -77,11 +67,37 @@ export function createWindow() {
// }
// });
- if (!url || electronIsDev) {
- // TODO
- mainWindow.loadFile("../test-app/index.html");
- mainWindow.webContents.openDevTools();
- } else {
- mainWindow.loadURL(url); // TODO: load app on demand
- }
+ appView = new BrowserView({
+ webPreferences: {
+ preload: path.join(__dirname, "../dist/app/index.js"),
+ },
+ });
+ mainWindow.setBrowserView(appView);
+ appView.setBounds({
+ x: sidebarWidth,
+ y: 0,
+ width: mainWindow.getBounds().width - sidebarWidth,
+ height: mainWindow.getBounds().height,
+ });
+ appView.setAutoResize({
+ width: true,
+ height: true,
+ });
+
+ mainWindow.once("ready-to-show", () => {
+ (async () => {
+ await appView?.webContents.loadURL("https://workadventu.re/"); // TODO: use some splashscreen ?
+ // appView.webContents.openDevTools({
+ // mode: "detach",
+ // });
+ mainWindow?.show();
+ // mainWindow?.webContents.openDevTools({ mode: "detach" });
+ })();
+ });
+
+ mainWindow.webContents.on("did-finish-load", () => {
+ mainWindow?.setTitle("WorkAdventure Desktop");
+ });
+
+ mainWindow.loadFile("../sidebar/index.html");
}
diff --git a/desktop/test-app/index.html b/desktop/test-app/index.html
deleted file mode 100644
index 4ce24a29..00000000
--- a/desktop/test-app/index.html
+++ /dev/null
@@ -1,13 +0,0 @@
-
-
-
-
- WorkAdventure Desktop Demo
-
-
- Hello World!
-
-
-
-
-
\ No newline at end of file
diff --git a/desktop/test-app/web.js b/desktop/test-app/web.js
deleted file mode 100644
index 8495a393..00000000
--- a/desktop/test-app/web.js
+++ /dev/null
@@ -1,25 +0,0 @@
-let muted = false;
-
-if (window?.WorkAdventureDesktopApi?.desktop) {
- document.getElementById("demo").innerHTML =
- "Hello Desktop app! Press ctrl-alt-m to mute.";
-
- window?.WorkAdventureDesktopApi?.onMutedKeyPress((event) => {
- if (muted) {
- document.getElementById("demo").innerHTML =
- "Ready to speak! Press ctrl-alt-m to mute.";
- } else {
- document.getElementById("demo").innerHTML =
- "Muted! Press ctrl-alt-m to unmute again.";
- }
- muted = !muted;
- });
-}
-
-document.getElementById("btn-reload").onclick = () => {
- location.reload();
-};
-
-document.getElementById("btn-api").onclick = () => {
- window.WorkAdventureDesktopApi.notify("Hello from website");
-};