|
| 1 | +import { TeGames } from "./te-enums"; |
| 2 | +import * as path from "path"; |
| 3 | +import { |
| 4 | + app, |
| 5 | + BrowserWindow, |
| 6 | + dialog, |
| 7 | + Menu, |
| 8 | + shell as electronShell |
| 9 | +} from "electron"; |
| 10 | +import { APP_NAME } from "./te-consts"; |
| 11 | +import { newTEProcess } from "./te-process"; |
| 12 | + |
| 13 | +const BASE_DIR = path.join(__dirname, ".."); |
| 14 | + |
| 15 | +const FILE_BASE = "file://" + BASE_DIR; |
| 16 | +const FILE_URL_FAILURE = FILE_BASE + "/resources/failure.html" |
| 17 | +const FILE_URL_PREFS = FILE_BASE + "/resources/prefs/prefs.html"; |
| 18 | + |
| 19 | +export abstract class TeWindow { |
| 20 | + protected httpUrl: string; |
| 21 | + /** The underlying electron browser window */ |
| 22 | + public browserWindow: BrowserWindow; |
| 23 | + protected prefsWin: BrowserWindow; |
| 24 | + protected windowTitle: string = APP_NAME; |
| 25 | + protected windowBgColor: string = "#000000"; |
| 26 | + |
| 27 | + /* TODO: Find out if class properties can be overriden before constructor() is called.. */ |
| 28 | + _constructor(httpUrl: string) { |
| 29 | + this.httpUrl = httpUrl; |
| 30 | + |
| 31 | + let bwin = new BrowserWindow({ |
| 32 | + width: 800, |
| 33 | + height: 600, |
| 34 | + frame: true, // show default OS window frame |
| 35 | + useContentSize: true, // make width & height relative to the content, not the whole window |
| 36 | + show: true, // show app background instantly until content is loaded |
| 37 | + backgroundColor: this.windowBgColor, |
| 38 | + title: this.windowTitle, |
| 39 | + icon: path.join(BASE_DIR, "resources", "icon.png"), |
| 40 | + webPreferences: { |
| 41 | + plugins: true, |
| 42 | + sandbox: true, |
| 43 | + contextIsolation: false, |
| 44 | + preload: path.join(__dirname, "preload.js") |
| 45 | + } |
| 46 | + }); |
| 47 | + |
| 48 | + bwin.setMenu(Menu.buildFromTemplate([ |
| 49 | + { |
| 50 | + label: 'Zoom In', |
| 51 | + click: () => { |
| 52 | + var webContents = bwin.webContents; |
| 53 | + /* JS messes up when doing arithmetics against floats */ |
| 54 | + var zoomFactor = Math.round(webContents.getZoomFactor() * 100 + 10) / 100; |
| 55 | + webContents.setZoomFactor(zoomFactor); |
| 56 | + } |
| 57 | + }, |
| 58 | + { |
| 59 | + label: 'Zoom Out', |
| 60 | + click: () => { |
| 61 | + var webContents = bwin.webContents; |
| 62 | + /* JS messes up when doing arithmetics against floats */ |
| 63 | + var zoomFactor = Math.round(webContents.getZoomFactor() * 100 - 10) / 100; |
| 64 | + if (zoomFactor > 0) webContents.setZoomFactor(zoomFactor); |
| 65 | + } |
| 66 | + }, |
| 67 | + { |
| 68 | + label: 'Reset Zoom', |
| 69 | + click: () => { |
| 70 | + var webContents = bwin.webContents |
| 71 | + var currentZoomFactor = webContents.getZoomFactor(); |
| 72 | + webContents.setZoomFactor(1); |
| 73 | + } |
| 74 | + }, |
| 75 | + { |
| 76 | + label: 'More', |
| 77 | + submenu: [ |
| 78 | + { |
| 79 | + label: 'Reload', |
| 80 | + click: () => { |
| 81 | + this.load(); |
| 82 | + } |
| 83 | + }, |
| 84 | + { |
| 85 | + label: 'Fullscreen', |
| 86 | + click: () => { |
| 87 | + bwin.setFullScreen(!bwin.isFullScreen()); |
| 88 | + } |
| 89 | + }, |
| 90 | + { |
| 91 | + label: 'Fit Window', |
| 92 | + click: () => { |
| 93 | + bwin.unmaximize(); |
| 94 | + bwin.setFullScreen(false); |
| 95 | + bwin.setContentSize(800, 600); |
| 96 | + } |
| 97 | + }, |
| 98 | + { |
| 99 | + label: 'Clear Cache', |
| 100 | + click: () => { |
| 101 | + dialog.showMessageBox(bwin, { |
| 102 | + type: "question", |
| 103 | + title: "Clear Cache", |
| 104 | + message: "Are you sure you want to clear the cache?", |
| 105 | + detail: "This will delete cached images such as profile pictures. This is useful to reload profile pictures that have since changed. Flash player cache is NOT cleared. Please also reload the app for changes to apply.", |
| 106 | + buttons: ["Cancel", "Yes"], |
| 107 | + cancelId: 0, |
| 108 | + defaultId: 1 |
| 109 | + }).then((res) => { |
| 110 | + if (res.response == 1) { |
| 111 | + bwin.webContents.session.clearCache().then(() => { |
| 112 | + dialog.showMessageBox(bwin, { |
| 113 | + type: "info", |
| 114 | + title: "Clear Cache", |
| 115 | + message: "Successfully cleared cache." |
| 116 | + }); |
| 117 | + }); |
| 118 | + } |
| 119 | + }); |
| 120 | + } |
| 121 | + }, |
| 122 | + { |
| 123 | + label: 'Preferences', |
| 124 | + click: () => { |
| 125 | + this.showPreferences(); |
| 126 | + } |
| 127 | + }, |
| 128 | + { |
| 129 | + label: 'DevTools', |
| 130 | + accelerator: 'CmdOrCtrl+Shift+I', |
| 131 | + click: () => { |
| 132 | + bwin.webContents.openDevTools(); |
| 133 | + } |
| 134 | + }, |
| 135 | + { |
| 136 | + label: 'About', |
| 137 | + click: () => { |
| 138 | + dialog.showMessageBox(bwin, { |
| 139 | + type: "info", |
| 140 | + title: "About " + APP_NAME, |
| 141 | + message: "Version: " + app.getVersion() |
| 142 | + }); |
| 143 | + } |
| 144 | + }, |
| 145 | + ] |
| 146 | + }, |
| 147 | + { |
| 148 | + label: 'Other Games', |
| 149 | + submenu: [ |
| 150 | + { |
| 151 | + label: 'Transformice', |
| 152 | + click: () => { |
| 153 | + newTEProcess(TeGames.TRANSFORMICE); |
| 154 | + } |
| 155 | + }, |
| 156 | + { |
| 157 | + label: 'DeadMaze', |
| 158 | + click: () => { |
| 159 | + newTEProcess(TeGames.DEADMAZE); |
| 160 | + } |
| 161 | + }, |
| 162 | + ] |
| 163 | + }]) |
| 164 | + ); |
| 165 | + |
| 166 | + bwin.webContents.on('did-finish-load', () => { |
| 167 | + //this.onReady(); |
| 168 | + }); |
| 169 | + |
| 170 | + bwin.webContents.on('did-fail-load', (event, errCode, errDesc) => { |
| 171 | + this.onFail(errDesc); |
| 172 | + }); |
| 173 | + |
| 174 | + /* Open external links in user's preferred browser rather than in Electron */ |
| 175 | + bwin.webContents.on('new-window', (event, url) => { |
| 176 | + event.preventDefault(); |
| 177 | + electronShell.openExternal(url); |
| 178 | + }); |
| 179 | + |
| 180 | + /* Don't change the window title */ |
| 181 | + bwin.on('page-title-updated', (event) => { |
| 182 | + event.preventDefault(); |
| 183 | + }); |
| 184 | + |
| 185 | + this.browserWindow = bwin; |
| 186 | + } |
| 187 | + |
| 188 | + onFail(errDesc: string) { |
| 189 | + let bwin = this.browserWindow; |
| 190 | + if (!bwin.isDestroyed()) { |
| 191 | + bwin.loadURL(FILE_URL_FAILURE); |
| 192 | + //win.show(); |
| 193 | + } |
| 194 | + //this.errorDesc = errDesc; |
| 195 | + } |
| 196 | + |
| 197 | + showPreferences() { |
| 198 | + if (this.prefsWin) { |
| 199 | + /* already open - focus and bail out */ |
| 200 | + this.prefsWin.focus(); |
| 201 | + return; |
| 202 | + } |
| 203 | + |
| 204 | + this.prefsWin = new BrowserWindow({ |
| 205 | + width: 680, |
| 206 | + height: 400, |
| 207 | + frame: true, /* show the default window frame (exit buttons, etc.) */ |
| 208 | + useContentSize: true, /* make width & height relative to the content, not the whole window */ |
| 209 | + autoHideMenuBar: true, |
| 210 | + title: APP_NAME, |
| 211 | + icon: path.join(BASE_DIR, "resources", "icon.png"), |
| 212 | + parent: this.browserWindow, |
| 213 | + webPreferences: { |
| 214 | + plugins: false, |
| 215 | + contextIsolation: false, |
| 216 | + enableRemoteModule: true, |
| 217 | + preload: path.join(BASE_DIR, "resources", "prefs", "preload_prefs.js") |
| 218 | + } |
| 219 | + }); |
| 220 | + |
| 221 | + this.prefsWin.on("closed", () => { |
| 222 | + this.prefsWin = null; |
| 223 | + this.browserWindow.focus(); |
| 224 | + }); |
| 225 | + |
| 226 | + this.prefsWin.loadURL(FILE_URL_PREFS); |
| 227 | + } |
| 228 | + |
| 229 | + /** This is called when the window needs to display content. */ |
| 230 | + abstract load(): void; |
| 231 | +} |
0 commit comments