mirror of
https://github.com/CringeStudios/element-desktop.git
synced 2025-01-18 23:44:59 +01:00
Search for the webapp resources on startup
and error if we can't find them.
This commit is contained in:
parent
8322676df7
commit
8d3529787a
@ -15,7 +15,7 @@
|
|||||||
"mkdirs": "mkdirp packages deploys",
|
"mkdirs": "mkdirp packages deploys",
|
||||||
"fetch": "yarn run mkdirs && node scripts/fetch-package.js",
|
"fetch": "yarn run mkdirs && node scripts/fetch-package.js",
|
||||||
"check": "node scripts/check-webapp.js",
|
"check": "node scripts/check-webapp.js",
|
||||||
"start": "yarn run check && yarn install:electron && electron .",
|
"start": "electron .",
|
||||||
"lint": "eslint src/",
|
"lint": "eslint src/",
|
||||||
"build": "yarn run check && electron-builder",
|
"build": "yarn run check && electron-builder",
|
||||||
"clean": "rimraf webapp.asar dist packages deploys"
|
"clean": "rimraf webapp.asar dist packages deploys"
|
||||||
|
@ -50,6 +50,15 @@ try {
|
|||||||
console.warn("seshat unavailable", e);
|
console.warn("seshat unavailable", e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Things we need throughout the file but need to be created
|
||||||
|
// async to are initialised in setupGlobals()
|
||||||
|
let asarPath;
|
||||||
|
let resPath;
|
||||||
|
let vectorConfig;
|
||||||
|
let iconPath;
|
||||||
|
let trayConfig;
|
||||||
|
let launcher;
|
||||||
|
|
||||||
if (argv["help"]) {
|
if (argv["help"]) {
|
||||||
console.log("Options:");
|
console.log("Options:");
|
||||||
console.log(" --profile-dir {path}: Path to where to store the profile.");
|
console.log(" --profile-dir {path}: Path to where to store the profile.");
|
||||||
@ -69,34 +78,87 @@ if (argv['profile-dir']) {
|
|||||||
app.setPath('userData', `${app.getPath('userData')}-${argv['profile']}`);
|
app.setPath('userData', `${app.getPath('userData')}-${argv['profile']}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
let vectorConfig = {};
|
async function tryAsarPaths(rawPaths) {
|
||||||
try {
|
// Make everything relative to the current file
|
||||||
vectorConfig = require('../webapp.asar/config.json');
|
const paths = rawPaths.map(p => path.join(__dirname, p));
|
||||||
} catch (e) {
|
|
||||||
// it would be nice to check the error code here and bail if the config
|
for (const p of paths) {
|
||||||
// is unparseable, but we get MODULE_NOT_FOUND in the case of a missing
|
try {
|
||||||
// file or invalid json, so node is just very unhelpful.
|
await afs.stat(p);
|
||||||
// Continue with the defaults (ie. an empty config)
|
return p + '/';
|
||||||
|
} catch (e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
console.log("Couldn't find webapp files in any of: ");
|
||||||
|
for (const p of paths) {
|
||||||
|
console.log("\t"+path.resolve(p));
|
||||||
|
}
|
||||||
|
throw new Error("Failed to find webapp files");
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
// Find the webapp resources and set up things that require them
|
||||||
// Load local config and use it to override values from the one baked with the build
|
async function setupGlobals() {
|
||||||
const localConfig = require(path.join(app.getPath('userData'), 'config.json'));
|
// find the webapp asar.
|
||||||
|
asarPath = await tryAsarPaths([
|
||||||
|
// If run from the source checkout, this will be in the directory above
|
||||||
|
'../webapp.asar',
|
||||||
|
// but if run from a packaged application, electron-main.js will be in
|
||||||
|
// a different asar file so it will be two levels above
|
||||||
|
'../../webapp.asar',
|
||||||
|
// also try without the 'asar' suffix to allow symlinking in a directory
|
||||||
|
'../webapp',
|
||||||
|
]);
|
||||||
|
// we assume the resources path is in the same place as the asar
|
||||||
|
resPath = path.join(path.dirname(asarPath), 'res');
|
||||||
|
|
||||||
// If the local config has a homeserver defined, don't use the homeserver from the build
|
try {
|
||||||
// config. This is to avoid a problem where Riot thinks there are multiple homeservers
|
vectorConfig = require(asarPath + 'config.json');
|
||||||
// defined, and panics as a result.
|
} catch (e) {
|
||||||
const homeserverProps = ['default_is_url', 'default_hs_url', 'default_server_name', 'default_server_config'];
|
// it would be nice to check the error code here and bail if the config
|
||||||
if (Object.keys(localConfig).find(k => homeserverProps.includes(k))) {
|
// is unparseable, but we get MODULE_NOT_FOUND in the case of a missing
|
||||||
// Rip out all the homeserver options from the vector config
|
// file or invalid json, so node is just very unhelpful.
|
||||||
vectorConfig = Object.keys(vectorConfig)
|
// Continue with the defaults (ie. an empty config)
|
||||||
.filter(k => !homeserverProps.includes(k))
|
vectorConfig = {};
|
||||||
.reduce((obj, key) => {obj[key] = vectorConfig[key]; return obj;}, {});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
vectorConfig = Object.assign(vectorConfig, localConfig);
|
try {
|
||||||
} catch (e) {
|
// Load local config and use it to override values from the one baked with the build
|
||||||
// Could not load local config, this is expected in most cases.
|
const localConfig = require(path.join(app.getPath('userData'), 'config.json'));
|
||||||
|
|
||||||
|
// If the local config has a homeserver defined, don't use the homeserver from the build
|
||||||
|
// config. This is to avoid a problem where Riot thinks there are multiple homeservers
|
||||||
|
// defined, and panics as a result.
|
||||||
|
const homeserverProps = ['default_is_url', 'default_hs_url', 'default_server_name', 'default_server_config'];
|
||||||
|
if (Object.keys(localConfig).find(k => homeserverProps.includes(k))) {
|
||||||
|
// Rip out all the homeserver options from the vector config
|
||||||
|
vectorConfig = Object.keys(vectorConfig)
|
||||||
|
.filter(k => !homeserverProps.includes(k))
|
||||||
|
.reduce((obj, key) => {obj[key] = vectorConfig[key]; return obj;}, {});
|
||||||
|
}
|
||||||
|
|
||||||
|
vectorConfig = Object.assign(vectorConfig, localConfig);
|
||||||
|
} catch (e) {
|
||||||
|
// Could not load local config, this is expected in most cases.
|
||||||
|
}
|
||||||
|
|
||||||
|
// The tray icon
|
||||||
|
// It's important to call `path.join` so we don't end up with the packaged asar in the final path.
|
||||||
|
const iconFile = `riot.${process.platform === 'win32' ? 'ico' : 'png'}`;
|
||||||
|
iconPath = path.join(resPath, "img", iconFile);
|
||||||
|
console.log("loading tray icon from " + iconPath);
|
||||||
|
trayConfig = {
|
||||||
|
icon_path: iconPath,
|
||||||
|
brand: vectorConfig.brand || 'Riot',
|
||||||
|
};
|
||||||
|
|
||||||
|
// launcher
|
||||||
|
launcher = new AutoLaunch({
|
||||||
|
name: vectorConfig.brand || 'Riot',
|
||||||
|
isHidden: true,
|
||||||
|
mac: {
|
||||||
|
useLaunchAgent: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const eventStorePath = path.join(app.getPath('userData'), 'EventStore');
|
const eventStorePath = path.join(app.getPath('userData'), 'EventStore');
|
||||||
@ -107,14 +169,6 @@ let eventIndex = null;
|
|||||||
let mainWindow = null;
|
let mainWindow = null;
|
||||||
global.appQuitting = false;
|
global.appQuitting = false;
|
||||||
|
|
||||||
// It's important to call `path.join` so we don't end up with the packaged asar in the final path.
|
|
||||||
const iconFile = `riot.${process.platform === 'win32' ? 'ico' : 'png'}`;
|
|
||||||
const iconPath = path.join(__dirname, "..", "..", "img", iconFile);
|
|
||||||
const trayConfig = {
|
|
||||||
icon_path: iconPath,
|
|
||||||
brand: vectorConfig.brand || 'Riot',
|
|
||||||
};
|
|
||||||
|
|
||||||
// handle uncaught errors otherwise it displays
|
// handle uncaught errors otherwise it displays
|
||||||
// stack traces in popup dialogs, which is terrible (which
|
// stack traces in popup dialogs, which is terrible (which
|
||||||
// it will do any time the auto update poke fails, and there's
|
// it will do any time the auto update poke fails, and there's
|
||||||
@ -399,14 +453,6 @@ if (!gotLock) {
|
|||||||
app.exit();
|
app.exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
const launcher = new AutoLaunch({
|
|
||||||
name: vectorConfig.brand || 'Riot',
|
|
||||||
isHidden: true,
|
|
||||||
mac: {
|
|
||||||
useLaunchAgent: true,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
// Register the scheme the app is served from as 'standard'
|
// Register the scheme the app is served from as 'standard'
|
||||||
// which allows things like relative URLs and IndexedDB to
|
// which allows things like relative URLs and IndexedDB to
|
||||||
// work.
|
// work.
|
||||||
@ -421,7 +467,19 @@ protocol.registerSchemesAsPrivileged([{
|
|||||||
},
|
},
|
||||||
}]);
|
}]);
|
||||||
|
|
||||||
app.on('ready', () => {
|
app.on('ready', async () => {
|
||||||
|
try {
|
||||||
|
await setupGlobals();
|
||||||
|
} catch (e) {
|
||||||
|
console.log("App setup failed: exiting", e);
|
||||||
|
process.exit(1);
|
||||||
|
// process.exit doesn't cause node to stop running code immediately,
|
||||||
|
// so return (we could let the exception propagate but then we end up
|
||||||
|
// with node printing all sorts of stuff about unhandled exceptions
|
||||||
|
// when we want the actual error to be as obvious as possible).
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (argv['devtools']) {
|
if (argv['devtools']) {
|
||||||
try {
|
try {
|
||||||
const { default: installExt, REACT_DEVELOPER_TOOLS, REACT_PERF } = require('electron-devtools-installer');
|
const { default: installExt, REACT_DEVELOPER_TOOLS, REACT_PERF } = require('electron-devtools-installer');
|
||||||
@ -466,7 +524,7 @@ app.on('ready', () => {
|
|||||||
|
|
||||||
let baseDir;
|
let baseDir;
|
||||||
if (target[1] === 'webapp') {
|
if (target[1] === 'webapp') {
|
||||||
baseDir = path.join(__dirname, "../webapp.asar");
|
baseDir = asarPath;
|
||||||
} else {
|
} else {
|
||||||
callback({error: -6}); // FILE_NOT_FOUND
|
callback({error: -6}); // FILE_NOT_FOUND
|
||||||
return;
|
return;
|
||||||
|
Loading…
Reference in New Issue
Block a user