Remote modal

This commit is contained in:
Jiiks 2018-12-07 03:02:52 +02:00
parent b77cfe70e4
commit 683299735f
5 changed files with 155 additions and 5 deletions

View File

@ -236,7 +236,7 @@ export default class {
/**
* Common loading procedure for loading content before passing it to the actual loader
* @param {any} dirName Base directory for content
* @param {any} dirName Base directory for unpacked content | info about packed content
* @param {any} reload Is content being reloaded
* @param {any} index Index of content in {localContent}
*/

View File

@ -107,6 +107,18 @@ export default class PackageInstaller {
* @param {String} remoteLocation Remote resource location
*/
static async installRemotePackage(remoteLocation) {
let outputPath = null;
try {
const modalResult = await Modals.remoteInstallModal(remoteLocation).promise;
console.log(modalResult);
await this.dragAndDropHandler(modalResult);
} catch (err) {
throw err;
}
return;
try {
const { hostname } = Object.assign(document.createElement('a'), { href: remoteLocation });
if (hostname !== 'api.github.com' && hostname !== 'secretbdapi') throw 'Invalid host!';
@ -121,18 +133,78 @@ export default class PackageInstaller {
};
const response = await request.get(options);
const outputPath = path.join(Globals.getPath('tmp'), Security.hash('sha256', response, 'hex'));
outputPath = path.join(Globals.getPath('tmp'), Security.hash('sha256', response, 'hex'));
fs.writeFileSync(outputPath, response);
console.log('response', response);
console.log('output', outputPath);
await this.dragAndDropHandler(outputPath);
const config = JSON.parse(asar.extractFile(outputPath, 'config.json').toString());
const { info, main } = config;
let icon = null;
if (info.icon && info.icon_type) {
const extractIcon = asar.extractFile(outputPath, info.icon);
icon = `data:${info.icon_type};base64,${Utils.arrayBufferToBase64(extractIcon)}`;
}
const isPlugin = info.type && info.type === 'plugin' || main.endsWith('.js');
// Show install modal
const modalResult = await Modals.installModal(isPlugin ? 'plugin' : 'theme', config, filePath, icon).promise;
} catch (err) {
throw err;
} finally {
if (!outputPath) return;
rimraf(outputPath, err => {
if (err) console.log(err);
});
}
}
static async downloadRemotePackage(remoteLocation) {
let outputPath = null;
try {
const { hostname } = Object.assign(document.createElement('a'), { href: remoteLocation });
if (hostname !== 'api.github.com' && hostname !== 'secretbdapi') throw 'Invalid host!';
const options = {
uri: remoteLocation,
encoding: null,
headers: {
'User-Agent': 'BetterDiscordClient',
'Accept': 'application/octet-stream'
}
};
const response = await request.get(options);
outputPath = path.join(Globals.getPath('tmp'), Security.hash('sha256', response, 'hex'));
fs.writeFileSync(outputPath, response);
const config = JSON.parse(asar.extractFile(outputPath, 'config.json').toString());
const { info, main } = config;
let icon = null;
if (info.icon && info.icon_type) {
const extractIcon = asar.extractFile(outputPath, info.icon);
icon = `data:${info.icon_type};base64,${Utils.arrayBufferToBase64(extractIcon)}`;
}
const isPlugin = info.type && info.type === 'plugin' || main.endsWith('.js');
return {
response,
outputPath,
config,
icon,
isPlugin
};
} catch (err) {
throw err;
} finally {
}
}
/**

View File

@ -84,6 +84,22 @@
}
}
}
.bd-spinnerContainer {
display: flex;
flex-direction: column;
flex-grow: 1;
justify-content: center;
span {
font-size: 20px;
text-align: center;
}
.bd-spinner7 {
align-self: center;
}
}
}
.bd-installModalFooter {

View File

@ -0,0 +1,48 @@
<template>
<Modal class="bd-installModal" :headertext="modal.title" :closing="modal.closing" @close="modal.close" :noheader="true" :class="{'bd-err': !verifying && !verified, 'bd-installModalDone': installed, 'bd-installModalFail': err}">
<div v-if="loadingInfo" class="bd-spinnerContainer" slot="body">
<span>Loading Remote Package</span>
<div class="bd-spinner7"></div>
</div>
</Modal>
</template>
<script>
// Imports
import { Modal, MiExtension, MiSuccessCircle, MiError } from '../../common';
import { PluginManager, ThemeManager, PackageInstaller, Settings } from 'modules';
export default {
data() {
return {
loadingInfo: true,
installing: false,
installed: false,
verifying: true,
alreadyInstalled: false,
upToDate: true,
allowUnsafe: Settings.getSetting('security', 'default', 'unsafe-content').value,
installed: false,
err: null
}
},
props: ['modal'],
components: {
Modal, MiExtension, MiSuccessCircle, MiError
},
methods: {
async loadRemote() {
try {
const info = await PackageInstaller.downloadRemotePackage(this.modal.remoteLocation);
this.modal.confirm(info.outputPath);
this.modal.close();
} catch (err) {
console.log(err);
}
}
},
mounted() {
this.loadRemote();
}
}
</script>

View File

@ -18,6 +18,7 @@ import SettingsModal from './components/bd/modals/SettingsModal.vue';
import PermissionModal from './components/bd/modals/PermissionModal.vue';
import InputModal from './components/bd/modals/InputModal.vue';
import InstallModal from './components/bd/modals/InstallModal.vue';
import RemoteInstallModal from './components/bd/modals/RemoteInstallModal.vue';
let modals = 0;
@ -204,6 +205,19 @@ export default class Modals {
return new Modal(modal, InstallModal);
}
static remoteInstallModal(remoteLocation) {
return this.add(this.createRemoteInstallModal(remoteLocation));
}
static createRemoteInstallModal(remoteLocation) {
const modal = { remoteLocation };
modal.promise = new Promise((resolve, reject) => {
modal.confirm = value => resolve(value);
modal.beforeClose = () => reject();
});
return new Modal(modal, RemoteInstallModal);
}
/**
* Creates a new permissions modal and adds it to the open stack.
* The modal will have a promise property that will be set to a Promise object that is resolved or rejected if the user accepts the permissions or closes the modal.