Remote modal
This commit is contained in:
parent
b77cfe70e4
commit
683299735f
|
@ -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}
|
||||
*/
|
||||
|
|
|
@ -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 {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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>
|
|
@ -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.
|
||||
|
|
Loading…
Reference in New Issue