@@ -9,7 +9,8 @@ module.exports = { | |||
"NODE_ENV": "development", | |||
"LOG": "debug", | |||
"DEVTOOLS": true, | |||
"ROLLBAR_ACCESS_TOKEN": "6ccfcf317ca54e67830b41570ce23d2a" | |||
"ROLLBAR_ACCESS_TOKEN": "6ccfcf317ca54e67830b41570ce23d2a", | |||
"LOGROCKET_ACCESS_TOKEN": "of2lox/dreamtime" | |||
}, | |||
"production": { | |||
"name": "production", | |||
@@ -23,6 +24,7 @@ module.exports = { | |||
}, | |||
"preview": { | |||
"DEVTOOLS": true, | |||
"ROLLBAR_ACCESS_TOKEN": "6ccfcf317ca54e67830b41570ce23d2a" | |||
"ROLLBAR_ACCESS_TOKEN": "6ccfcf317ca54e67830b41570ce23d2a", | |||
"LOGROCKET_ACCESS_TOKEN": "of2lox/dreamtime" | |||
} | |||
} |
@@ -1,9 +1,7 @@ | |||
module.exports = { | |||
env: { | |||
browser: true, | |||
es2020: true, | |||
node: true, | |||
"shared-node-browser": true, | |||
mocha: true | |||
}, | |||
extends: [ | |||
@@ -37,16 +35,17 @@ module.exports = { | |||
"class-methods-use-this": "off", | |||
"comma-dangle": "warn", | |||
"global-require": "off", | |||
"import/default": "off", | |||
"import/no-webpack-loader-syntax": "off", | |||
"import/order": "error", | |||
"import/default": "warn", | |||
"import/no-webpack-loader-syntax": "warn", | |||
"import/order": ['error'], | |||
"import/prefer-default-export": "off", | |||
"import/no-extraneous-dependencies": "off", | |||
"import/named": "off", | |||
"import/named": "warn", | |||
"import/no-cycle": "off", | |||
"promise/no-callback-in-promise": "off", | |||
"promise/catch-or-return": "off", | |||
"linebreak-style": "warn", | |||
"new-parens": ['error', 'never'], | |||
"lodash/import-scope": [ | |||
"off", | |||
"member" | |||
@@ -116,7 +115,8 @@ module.exports = { | |||
], | |||
"vue/html-self-closing": "error", | |||
"vue/no-v-html": "off", | |||
"vue/singleline-html-element-content-newline": "warn" | |||
"vue/singleline-html-element-content-newline": "warn", | |||
'nuxt/no-cjs-in-config': 'off' | |||
}, | |||
settings: { | |||
"import/resolver": { |
@@ -1,7 +1,7 @@ | |||
<template> | |||
<div class="layout__navbar"> | |||
<div class="navbar__left"> | |||
<nuxt-link v-if="$provider.tools.system.canNudify" to="/" class="navbar__item"> | |||
<nuxt-link v-if="canNudify" to="/" class="navbar__item"> | |||
Nudify | |||
</nuxt-link> | |||
@@ -9,9 +9,13 @@ | |||
About | |||
</nuxt-link> | |||
<nuxt-link v-if="$provider.tools.system.canNudify" class="navbar__item" to="/dreamnet"> | |||
<nuxt-link v-if="canNudify" class="navbar__item" to="/dreamnet"> | |||
DreamNet | |||
</nuxt-link> | |||
<a class="navbar__item" @click.prevent="createError"> | |||
Error | |||
</a> | |||
</div> | |||
<div class="navbar__right"> | |||
@@ -31,10 +35,15 @@ | |||
</template> | |||
<script> | |||
const { nucleus } = $provider.services | |||
import { requirements } from '~/modules/system' | |||
import { nucleus } from '~/modules/services' | |||
export default { | |||
computed: { | |||
canNudify() { | |||
return requirements.canNudify | |||
}, | |||
donateUrl() { | |||
return nucleus.urls?.support?.patreon || 'https://www.patreon.com/dreamnet' | |||
}, | |||
@@ -43,6 +52,12 @@ export default { | |||
return nucleus.urls?.docs?.manual || 'https://forum.dreamnet.tech/d/32-dreamtime-manual' | |||
}, | |||
}, | |||
methods: { | |||
createError() { | |||
throw new Error('UI test error.') | |||
}, | |||
}, | |||
} | |||
</script> | |||
@@ -4,7 +4,7 @@ | |||
<!-- App Navigation --> | |||
<section class="menu-section"> | |||
<nav class="menu-items"> | |||
<nuxt-link v-if="$provider.tools.system.canNudify" to="/" class="menu-item"> | |||
<nuxt-link v-if="canNudify" to="/" class="menu-item"> | |||
<span class="icon">📷</span> | |||
<span>Nudify</span> | |||
</nuxt-link> | |||
@@ -30,10 +30,14 @@ | |||
</template> | |||
<script> | |||
const { settings } = $provider.services | |||
const { settings } = $provider | |||
export default { | |||
computed: { | |||
canNudify() { | |||
return requirements.canNudify | |||
}, | |||
isDev() { | |||
return process.env.NODE_ENV === 'development' | |||
}, |
@@ -1,11 +1,9 @@ | |||
import Vue from 'vue' | |||
import LayoutTopbar from './Topbar' | |||
import LayoutNavigation from './Navigation' | |||
import LayoutNavbar from './Navbar' | |||
import LayoutJobbar from './Jobbar' | |||
Vue.component('layout-topbar', LayoutTopbar) | |||
Vue.component('layout-navbar', LayoutNavbar) | |||
Vue.component('layout-jobbar', LayoutJobbar) | |||
Vue.component('layout-navigation', LayoutNavigation) |
@@ -115,10 +115,10 @@ | |||
<script> | |||
import { isNil } from 'lodash' | |||
import { nucleus } from '~/modules/services' | |||
import { Nudify } from '~/modules/nudify' | |||
const { showSaveDialogSync } = $provider.api.dialog | |||
const { nucleus } = $provider.services | |||
export default { | |||
filters: { |
@@ -132,10 +132,10 @@ import { | |||
isNil, isEmpty, startsWith, | |||
map, isArray, | |||
} from 'lodash' | |||
import { nucleus } from '~/modules/services' | |||
import { Nudify } from '~/modules/nudify' | |||
const { nucleus } = $provider.services | |||
const { instagram } = $provider.tools | |||
const { instagram } = $provider | |||
const { dialog } = $provider.api | |||
export default { |
@@ -17,7 +17,6 @@ export default { | |||
methods: { | |||
openExternal() { | |||
$provider.services.nucleus.track('EXTERNAL_LINK', { href: this.href }) | |||
shell.openExternal(this.href) | |||
}, | |||
}, |
@@ -13,7 +13,7 @@ | |||
</template> | |||
<script> | |||
const { nucleus } = $provider.services | |||
import { nucleus } from '~/modules/services' | |||
export default { | |||
computed: { |
@@ -56,7 +56,7 @@ import { isString, toNumber } from 'lodash' | |||
import * as updateProviders from '~/modules/updater' | |||
const { shell } = $provider.api | |||
const { getPath } = $provider.tools.paths | |||
const { getPath } = $provider.paths | |||
export default { | |||
filters: { |
@@ -25,6 +25,7 @@ | |||
<script> | |||
import { isNil, startsWith } from 'lodash' | |||
import { nucleus } from '~/modules/services' | |||
import { dream } from '~/modules' | |||
const { shell } = $provider.api | |||
@@ -81,7 +82,7 @@ export default { | |||
if (startsWith(this.href, '/')) { | |||
this.$router.push(this.href) | |||
} else { | |||
$provider.services.nucleus.track('EXTERNAL_LINK', { href: this.href }) | |||
nucleus.track('EXTERNAL_LINK', { href: this.href }) | |||
shell.openExternal(this.href) | |||
} | |||
} |
@@ -19,7 +19,7 @@ import { AppError } from './modules/app-error' | |||
import { system } from './modules/tools/system' | |||
import { existsSync, mkdirSync } from './modules/tools/fs' | |||
import { getPath } from './modules/tools/paths' | |||
import { settings, rollbar, nucleus } from './modules/services' | |||
import { settings } from './modules/settings' | |||
import config from '~/nuxt.config' | |||
const logger = Logger.create('electron') | |||
@@ -77,7 +77,6 @@ class DreamApp { | |||
await settings.initialSetup() | |||
if (settings.app ?.disableHardwareAcceleration) { | |||
logger.info('Hardware acceleration disabled.') | |||
app.disableHardwareAcceleration() | |||
} | |||
} | |||
@@ -140,7 +139,6 @@ class DreamApp { | |||
if (startsWith(url, 'http') || startsWith(url, 'mailto')) { | |||
event.preventDefault() | |||
shell.openExternal(url) | |||
nucleus.track('EXTERNAL_LINK', { href: url }) | |||
return | |||
} | |||
@@ -163,15 +161,6 @@ class DreamApp { | |||
await settings.initialSetup() | |||
await settings.setup() | |||
// analytics & app settings. | |||
await nucleus.setup() | |||
// services | |||
await Promise.all([ | |||
rollbar.setup(), // bug tracking. | |||
system.scan(), // requirements. | |||
]) | |||
// | |||
this.createDirs() | |||
} | |||
@@ -180,7 +169,7 @@ class DreamApp { | |||
* | |||
*/ | |||
static async shutdown() { | |||
await rollbar.shutdown() | |||
} | |||
/** |
@@ -11,19 +11,25 @@ import { | |||
isError, isString, isObject, isArray, | |||
} from 'lodash' | |||
import { app, dialog } from 'electron' | |||
import { rollbar } from './services/rollbar' | |||
const logger = require('logplease').create('app-error:main') | |||
/** | |||
* @typedef {Object} ErrorOptions | |||
* @property {string} title | |||
* @property {Error} error | |||
* @property {string} level | |||
* @property {Object} extra | |||
* @property {Error} error | |||
* @property {boolean} fatal | |||
* @property {boolean} quiet | |||
*/ | |||
/** | |||
* @global | |||
*/ | |||
export class AppError extends Error { | |||
/** | |||
* @type {ErrorOptions} | |||
*/ | |||
options = { | |||
title: null, | |||
level: 'error', | |||
@@ -67,26 +73,6 @@ export class AppError extends Error { | |||
} | |||
} | |||
report() { | |||
if (!rollbar.enabled) { | |||
return | |||
} | |||
const { level } = this.options | |||
try { | |||
const error = this.options.error || this | |||
const response = rollbar[level](this.message, error, this.options) | |||
if (response.uuid) { | |||
this.message += `\n\nShare this with a developer:\nhttps://rollbar.com/occurrence/uuid/?uuid=${response.uuid}` | |||
} | |||
} catch (err) { | |||
logger.warn('Error report fail!', err) | |||
} | |||
} | |||
show() { | |||
dialog.showErrorBox( | |||
this.options.title || 'A problem has occurred.', | |||
@@ -104,10 +90,6 @@ export class AppError extends Error { | |||
error, | |||
}) | |||
if (process.env.NODE_ENV !== 'development') { | |||
this.report() | |||
} | |||
if (!quiet) { | |||
this.show() | |||
} |
@@ -7,7 +7,10 @@ | |||
// | |||
// Written by Ivan Bravo Bravo <ivan@dreamnet.tech>, 2019. | |||
/* | |||
export { makeServiceProxy } from './base' | |||
export { settings } from './settings' | |||
export { nucleus } from './nucleus' | |||
export { rollbar } from './rollbar' | |||
export { logrocket } from './logrocket' | |||
*/ |
@@ -9,18 +9,28 @@ | |||
import fs from 'fs-extra' | |||
import { | |||
round, cloneDeep, | |||
round, cloneDeep, isNil, isEmpty, isPlainObject, get, set, | |||
} from 'lodash' | |||
import uuid from 'uuid' | |||
import { BaseService } from './base' | |||
import { paths, system } from '../tools' | |||
import { paths, system } from './tools' | |||
const logger = require('logplease').create('electron:scripts:services:settings') | |||
/** | |||
* User settings. | |||
*/ | |||
class SettingsService extends BaseService { | |||
class Settings { | |||
/** | |||
* the payload. | |||
* a proxy will be used to get or set this information. | |||
* | |||
* @type {Object} | |||
*/ | |||
payload = {} | |||
/** | |||
* @type {Object} | |||
*/ | |||
_default = {} | |||
/** | |||
@@ -32,6 +42,55 @@ class SettingsService extends BaseService { | |||
return paths.getPath('userData', 'settings.json') | |||
} | |||
/** | |||
* Load the service file. | |||
*/ | |||
async load() { | |||
if (isNil(this.path)) { | |||
return | |||
} | |||
if (!fs.existsSync(this.path)) { | |||
return | |||
} | |||
this.payload = fs.readJsonSync(this.path) | |||
logger.debug(this.payload) | |||
} | |||
/** | |||
* Save the service file. | |||
* This function is called automatically if you set a first level variable. | |||
*/ | |||
async save() { | |||
fs.writeJsonSync(this.path, this.payload) | |||
} | |||
/** | |||
* @param {string} path | |||
*/ | |||
get(path = '') { | |||
if (isEmpty(path)) { | |||
return this.payload | |||
} | |||
return get(this.payload, path) | |||
} | |||
/** | |||
* @param {string} path | |||
* @param {any} payload | |||
*/ | |||
set(path, payload) { | |||
if (isPlainObject(path)) { | |||
this.payload = path | |||
} else { | |||
this.payload = set(this.payload, path, payload) | |||
} | |||
this.save() | |||
} | |||
/** | |||
* Setup service | |||
*/ | |||
@@ -244,4 +303,43 @@ class SettingsService extends BaseService { | |||
} | |||
} | |||
export const settings = SettingsService.make() | |||
/** | |||
* Create a new instance with a Proxy. | |||
* | |||
* @return {Proxy} | |||
*/ | |||
export function make(obj) { | |||
return new Proxy(obj, { | |||
get: (obj, prop) => { | |||
if (prop in obj) { | |||
return obj[prop] | |||
} | |||
if (prop in obj.payload) { | |||
return obj.payload[prop] | |||
} | |||
return undefined | |||
}, | |||
/* eslint-disable no-param-reassign */ | |||
set: (obj, prop, value) => { | |||
if (!isNil(obj.payload)) { | |||
if (prop in obj.payload) { | |||
obj.payload[prop] = value | |||
obj.save() | |||
return true | |||
} | |||
} | |||
obj[prop] = value | |||
return true | |||
}, | |||
/* eslint-enable no-param-reassign */ | |||
}) | |||
} | |||
export const settingsRaw = new Settings | |||
export const settings = make(settingsRaw) |
@@ -11,7 +11,7 @@ import { attempt } from 'lodash' | |||
import { join } from 'path' | |||
import fs from 'fs-extra' | |||
import { app } from 'electron' | |||
import { settings } from '../services' | |||
import { settings } from '../settings' | |||
/** | |||
* Returns an absolute path depending on the parameters |
@@ -7,14 +7,14 @@ | |||
// | |||
// Written by Ivan Bravo Bravo <ivan@dreamnet.tech>, 2019. | |||
import { isNil } from 'lodash' | |||
import { isNil, isString } from 'lodash' | |||
import { spawn } from 'child_process' | |||
import EventBus from 'js-event-bus' | |||
import deferred from 'deferred' | |||
import semverRegex from 'semver-regex' | |||
import { existsSync } from './fs' | |||
import * as fs from 'fs-extra' | |||
import { getPowerPath } from './paths' | |||
import { settings } from '../services' | |||
import { settings } from '../settings' | |||
const logger = require('logplease').create('electron:power') | |||
@@ -108,7 +108,7 @@ export const transform = (run) => { | |||
const process = exec(args) | |||
const bus = new EventBus() | |||
const bus = (new EventBus) | |||
process.on('error', (error) => { | |||
logger.error(error) | |||
@@ -130,7 +130,7 @@ export const transform = (run) => { | |||
bus.emit('close', null, code) | |||
if (code === 0 || isNil(code)) { | |||
if (existsSync(run.outputFile.path)) { | |||
if (fs.existsSync(run.outputFile.path)) { | |||
bus.emit('success') | |||
} else { | |||
bus.emit('fail', null, true) | |||
@@ -148,6 +148,36 @@ export const transform = (run) => { | |||
return bus | |||
} | |||
/** | |||
* @return {boolean} | |||
*/ | |||
export function isInstalled() { | |||
const dirpath = getPowerPath() | |||
if (!isString(dirpath)) { | |||
// how the fuck? | |||
return false | |||
} | |||
if (!fs.existsSync(dirpath)) { | |||
return false | |||
} | |||
const binaries = [ | |||
'main.py', | |||
'dreampower.exe', | |||
'dreampower', | |||
] | |||
for (const bin of binaries) { | |||
if (fs.existsSync(getPowerPath(bin))) { | |||
return true | |||
} | |||
} | |||
return false | |||
} | |||
/** | |||
* @return {Promise} | |||
*/ |
@@ -8,18 +8,10 @@ | |||
// Written by Ivan Bravo Bravo <ivan@dreamnet.tech>, 2019. | |||
import { | |||
filter, isString, isNil, toInteger, get, | |||
filter, isNil, | |||
} from 'lodash' | |||
import { existsSync, statSync } from 'fs' | |||
import si from 'systeminformation' | |||
import isOnline from 'is-online' | |||
import compareVersions from 'compare-versions' | |||
import filesize from 'filesize' | |||
import { is } from 'electron-util' | |||
import regedit from 'regedit' | |||
import { nucleus } from '../services' | |||
import { getAppResourcesPath, getPowerPath, getCheckpointsPath } from './paths' | |||
import { getVersion } from './power' | |||
const logger = require('logplease').create('system') | |||
@@ -49,28 +41,6 @@ class System { | |||
*/ | |||
online | |||
/** | |||
* @type {Object} | |||
*/ | |||
requirements = { | |||
power: { | |||
installed: false, | |||
compatible: false, | |||
checkpoints: false, | |||
}, | |||
windows: { | |||
media: false, | |||
}, | |||
ram: { | |||
minimum: false, | |||
recommended: false, | |||
}, | |||
gpuram: { | |||
minimum: false, | |||
recommended: false, | |||
}, | |||
} | |||
/** | |||
* | |||
*/ | |||
@@ -101,37 +71,6 @@ class System { | |||
logger.debug(this) | |||
} | |||
/** | |||
* | |||
*/ | |||
async scan() { | |||
const { requirements } = this | |||
// dreampower | |||
requirements.power.installed = this._hasPower | |||
requirements.power.compatible = await this._hasCompatiblePower() | |||
requirements.power.checkpoints = this._hasCheckpoints | |||
// windows | |||
requirements.windows.media = await this._hasWindowsMedia() | |||
// ram | |||
requirements.ram.recommended = this.memory.total >= 8589934592 // 8 GB | |||
requirements.ram.minimum = this.memory.total >= 6442450944 // 6 GB | |||
// gpu ram | |||
this.requirements = requirements | |||
logger.info('Requirements:', this.requirements) | |||
} | |||
/** | |||
* @type {boolean} | |||
*/ | |||
get canNudify() { | |||
return this.requirements.power.installed && this.requirements.power.compatible && this.requirements.power.checkpoints | |||
} | |||
/** | |||
* @type {Array} | |||
*/ | |||
@@ -142,135 +81,6 @@ class System { | |||
return filter(this._graphics.controllers, { vendor: 'NVIDIA' }) | |||
} | |||
/** | |||
* @type {boolean} | |||
*/ | |||
get _hasPower() { | |||
const dirpath = getPowerPath() | |||
if (!isString(dirpath)) { | |||
// how the fuck? | |||
return false | |||
} | |||
if (!existsSync(dirpath)) { | |||
return false | |||
} | |||
const binaries = [ | |||
'main.py', | |||
'dreampower.exe', | |||
'dreampower', | |||
] | |||
for (const bin of binaries) { | |||
if (existsSync(getPowerPath(bin))) { | |||
return true | |||
} | |||
} | |||
return false | |||
} | |||
/** | |||
* @return {boolean} | |||
*/ | |||
async _hasCompatiblePower() { | |||
if (!this.requirements.power.installed) { | |||
return false | |||
} | |||
try { | |||
const version = await getVersion() | |||
const currentVersion = process.env.npm_package_version | |||
const minimum = nucleus.v1 ?.projects ?.dreamtime ?.releases[`v${currentVersion}`] ?.dreampower ?.minimum || 'v0.0.1' | |||
const maximum = nucleus.v1 ?.projects ?.dreamtime ?.releases[`v${currentVersion}`] ?.dreampower ?.maximum | |||
if (compareVersions.compare(version, minimum, '<')) { | |||
return false | |||
} | |||
if (!isNil(maximum) && compareVersions.compare(version, maximum, '>')) { | |||
return false | |||
} | |||
return true | |||
} catch (err) { | |||
logger.warn('An error occurred while verifying the version of DreamPower.', err) | |||
return false | |||
} | |||
} | |||
/** | |||
* @type {boolean} | |||
*/ | |||
get _hasCheckpoints() { | |||
const dirpath = getCheckpointsPath() | |||
if (!existsSync(dirpath)) { | |||
return false | |||
} | |||
// these files must exist | |||
const files = ['cm.lib', 'mm.lib', 'mn.lib'] | |||
for (const file of files) { | |||
const filepath = getCheckpointsPath(file) | |||
if (!existsSync(filepath)) { | |||
return false | |||
} | |||
const stats = statSync(filepath) | |||
const size = filesize(stats.size, { exponent: 2, output: 'object' }) | |||
if (size.value < 690) { | |||
return false | |||
} | |||
} | |||
return true | |||
} | |||
/** | |||
* @return {boolean} | |||
*/ | |||
async _hasWindowsMedia() { | |||
if (!is.windows) { | |||
return true | |||
} | |||
const version = this.os.release | |||
if (toInteger(version) < 10) { | |||
// no windows 10 | |||
return true | |||
} | |||
if (!is.development) { | |||
// regedit commands | |||
regedit.setExternalVBSLocation( | |||
getAppResourcesPath('vbs'), | |||
) | |||
} | |||
const value = await new Promise((resolve) => { | |||
const regKey = 'HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Setup\\WindowsFeatures' | |||
regedit.list(regKey, (err, result) => { | |||
if (!isNil(err)) { | |||
resolve(false) | |||
return | |||
} | |||
resolve(result[regKey].keys.includes('WindowsMediaVersion')) | |||
}) | |||
}) | |||
return value | |||
} | |||
} | |||
export const system = new System() | |||
export const system = new System |
@@ -1,19 +1,15 @@ | |||
const { remote } = require('electron') | |||
const { makeServiceProxy } = require('./modules/services') | |||
const { make } = require('./modules/settings') | |||
const util = remote.require('electron-util') | |||
const services = remote.require('./modules/services') | |||
const { settingsRaw } = remote.require('./modules/settings') | |||
const tools = remote.require('./modules/tools') | |||
// tools provider | |||
window.$provider = { | |||
services: { | |||
nucleus: makeServiceProxy(services.nucleus), | |||
rollbar: makeServiceProxy(services.rollbar), | |||
settings: makeServiceProxy(services.settings), | |||
}, | |||
...tools, | |||
tools, | |||
settings: make(settingsRaw), | |||
api: util.api, | |||
util, |
@@ -2,12 +2,20 @@ | |||
"compilerOptions": { | |||
"baseUrl": ".", | |||
"paths": { | |||
"~": [ | |||
"*" | |||
"~/*": [ | |||
"./*" | |||
], | |||
"@/*": [ | |||
"./*" | |||
], | |||
"test/*": [ | |||
"test/*" | |||
] | |||
} | |||
} | |||
}, | |||
"exclude": [ | |||
"node_modules", | |||
".nuxt", | |||
"dist" | |||
] | |||
} |
@@ -7,8 +7,9 @@ | |||
// | |||
// Written by Ivan Bravo Bravo <ivan@dreamnet.tech>, 2019. | |||
const { settings } = $provider.services | |||
const { system } = $provider.tools | |||
import { requirements } from '~/modules/system' | |||
const { system, settings } = $provider | |||
/** | |||
* Detects if the user has what it takes to run the program, | |||
@@ -26,7 +27,7 @@ export default function ({ route, redirect }) { | |||
return | |||
} | |||
if (!system.requirements.power.installed || !system.requirements.power.compatible) { | |||
if (!requirements.power.installed || !requirements.power.compatible) { | |||
// DreamPower is missing | |||
if ( | |||
!route.path.includes('/settings') | |||
@@ -38,7 +39,7 @@ export default function ({ route, redirect }) { | |||
return | |||
} | |||
if (!system.requirements.power.checkpoints) { | |||
if (!requirements.power.checkpoints) { | |||
// Checkpoints are missing | |||
if (route.path !== '/about') { | |||
redirect('/about#checkpoints') |
@@ -28,6 +28,6 @@ export default { | |||
data: () => ({ | |||
$nudify: NudifyStore, | |||
$settings: $provider.services.settings, | |||
$settings: $provider.settings, | |||
}), | |||
} |
@@ -11,21 +11,25 @@ import { | |||
isError, isString, isObject, isArray, | |||
} from 'lodash' | |||
import Swal from 'sweetalert2' | |||
import { logrocket } from '~/modules/services' | |||
const logger = require('logplease').create('app-error:renderer') | |||
const { rollbar } = $provider.services | |||
const { app } = $provider.api | |||
/** | |||
* @typedef {Object} ErrorOptions | |||
* @property {string} title | |||
* @property {Error} error | |||
* @property {string} level | |||
* @property {Object} extra | |||
* @property {Error} error | |||
* @property {boolean} fatal | |||
* @property {boolean} quiet | |||
*/ | |||
export class AppError extends Error { | |||
/** | |||
* @type {ErrorOptions} | |||
*/ | |||
options = { | |||
title: null, | |||
level: 'error', | |||
@@ -34,7 +38,10 @@ export class AppError extends Error { | |||
quiet: false, | |||
} | |||
reportUrl | |||
/** | |||
* @type {boolean} | |||
*/ | |||
reported = false | |||
/** | |||
* | |||
@@ -72,27 +79,31 @@ export class AppError extends Error { | |||
} | |||
report() { | |||
/* | |||
if (process.env.NODE_ENV === 'development') { | |||
this.reportUrl = `https://rollbar.com/occurrence/uuid/?uuid={EXAMPLE}` | |||
return | |||
} | |||
*/ | |||
const { level } = this.options | |||
if (!rollbar.enabled || level !== 'error') { | |||
if (!logrocket.enabled || level !== 'error') { | |||
return | |||
} | |||
try { | |||
const error = this.options.error || this | |||
const response = rollbar[level](this.message, error, this.options) | |||
console.log(logrocket) | |||
if (response.uuid) { | |||
this.reportUrl = `https://rollbar.com/occurrence/uuid/?uuid=${response.uuid}` | |||
} | |||
logrocket.captureException(error, { | |||
extra: this.options, | |||
}) | |||
this.reported = true | |||
} catch (err) { | |||
logger.warn('Error report fail!', err) | |||
logger.warn('LogRocket report fail!', err) | |||
} | |||
} | |||
@@ -111,7 +122,7 @@ export class AppError extends Error { | |||
title: this.options.title, | |||
html: this.message, | |||
icon, | |||
footer: this.reportUrl ? `<code>Share this to a developer: ${this.reportUrl}</code>` : null, | |||
footer: this.reported ? `<code>This problem has been reported to the developers.</code>` : null, | |||
}) | |||
} | |||
@@ -150,7 +161,7 @@ export class AppError extends Error { | |||
reportError = new Error(error) | |||
} | |||
appError = new AppError(`The application has encountered an unexpected error:\n<pre>${reportError ?.message}</pre>`, | |||
appError = new AppError(`The application has encountered an unexpected error:\n<pre>${reportError?.message}</pre>`, | |||
{ | |||
error: reportError, | |||
title: 'Unexpected error!', |
@@ -1,17 +1,20 @@ | |||
/* eslint-disable-next-line */ | |||
const debug = require('debug').default('app:modules:app') | |||
import { nucleus } from './services' | |||
export default { | |||
/** | |||
* @type {string} | |||
*/ | |||
name: process.env.npm_package_displayName, | |||
/** | |||
* @type {string} | |||
*/ | |||
version: `v${process.env.npm_package_version}`, | |||
status: 'stable', | |||
/** | |||
* | |||
*/ | |||
setup() { | |||
this.settings = $provider.services.nucleus | |||
this.settings = nucleus | |||
}, | |||
} |
@@ -5,10 +5,10 @@ import { getMetadata } from '~/workers/fs' | |||
const { | |||
writeDataURL, downloadAsync, | |||
unlinkSync, copySync, | |||
} = $provider.tools.fs | |||
} = $provider.fs | |||
const { getPath } = $provider.tools.paths | |||
const { getPath } = $provider.paths | |||
export class File { | |||
name |
@@ -23,7 +23,7 @@ import { getFilesMetadata } from '~/workers/fs' | |||
const logger = require('logplease').create('nudify') | |||
const { settings } = $provider.services | |||
const { settings } = $provider | |||
const MAX_PHOTOS = 1000 | |||
@@ -16,11 +16,12 @@ import { Timer } from '../timer' | |||
import { rand } from '../helpers' | |||
import cliErrors from '../config/cli-errors' | |||
import preferencesConfig from '../config/preferences' | |||
import { nucleus } from '../services' | |||
const { settings, nucleus } = $provider.services | |||
const { transform } = $provider.tools.power | |||
const { settings } = $provider | |||
const { transform } = $provider.power | |||
const { activeWindow } = $provider.util | |||
const { getMasksPath } = $provider.tools.paths | |||
const { getMasksPath } = $provider.paths | |||
export class PhotoRun { | |||
/** |
@@ -19,9 +19,9 @@ import { PhotoRun } from './photo-run' | |||
import { File } from '../file' | |||
import { Timer } from '../timer' | |||
const { settings } = $provider.services | |||
const { settings } = $provider | |||
const { activeWindow } = $provider.util | |||
const { getModelsPath, getCropPath } = $provider.tools.paths | |||
const { getModelsPath, getCropPath } = $provider.paths | |||
export class Photo { | |||
/** |
@@ -0,0 +1,68 @@ | |||
// DreamTime. | |||
// Copyright (C) DreamNet. All rights reserved. | |||
// | |||
// This program is free software: you can redistribute it and/or modify | |||
// it under the terms of the GNU General Public License 3.0 as published by | |||
// the Free Software Foundation. See <https://www.gnu.org/licenses/gpl-3.0.html> | |||
// | |||
// Written by Ivan Bravo Bravo <ivan@dreamnet.tech>, 2019. | |||
import { | |||
isEmpty, get, | |||
} from 'lodash' | |||
export class BaseService { | |||
/** | |||
* the payload. | |||
* a proxy will be used to get or set this information. | |||
* | |||
* @type {Object} | |||
*/ | |||
payload = {} | |||
/** | |||
* @type {Object} | |||
*/ | |||
service | |||
/** | |||
* @type {Boolean} | |||
*/ | |||
enabled = false | |||
/** | |||
* Create a new instance with a Proxy. | |||
* | |||
* @return {BaseService} | |||
*/ | |||
static make() { | |||
return new Proxy(new this(), { | |||
get: (obj, prop) => { | |||
if (prop in obj) { | |||
return obj[prop] | |||
} | |||
if (obj.service && prop in obj.service) { | |||
return obj.service[prop] | |||
} | |||
if (prop in obj.payload) { | |||
return obj.payload[prop] | |||
} | |||
return undefined | |||
}, | |||
}) | |||
} | |||
/** | |||
* @param {string} path | |||
*/ | |||
get(path = '') { | |||
if (isEmpty(path)) { | |||
return this.payload | |||
} | |||
return get(this.payload, path) | |||
} | |||
} |
@@ -0,0 +1,11 @@ | |||
// DreamTime. | |||
// Copyright (C) DreamNet. All rights reserved. | |||
// | |||
// This program is free software: you can redistribute it and/or modify | |||
// it under the terms of the GNU General Public License 3.0 as published by | |||
// the Free Software Foundation. See <https://www.gnu.org/licenses/gpl-3.0.html> | |||
// | |||
// Written by Ivan Bravo Bravo <ivan@dreamnet.tech>, 2019. | |||
export { nucleus } from './nucleus' | |||
export { logrocket } from './logrocket' |
@@ -0,0 +1,74 @@ | |||
// DreamTime. | |||
// Copyright (C) DreamNet. All rights reserved. | |||
// | |||
// This program is free software: you can redistribute it and/or modify | |||
// it under the terms of the GNU General Public License 3.0 as published by | |||
// the Free Software Foundation. See <https://www.gnu.org/licenses/gpl-3.0.html> | |||
// | |||
// Written by Ivan Bravo Bravo <ivan@dreamnet.tech>, 2019. | |||
import { isString, get } from 'lodash' | |||
import LogRocket from 'logrocket' | |||
import { BaseService } from './base' | |||
import { nucleus } from './nucleus' | |||
const { settings, system } = $provider | |||
const logger = require('logplease').create('services:logrocket') | |||
class LogRocketService extends BaseService { | |||
/** | |||
* @type {string} | |||
*/ | |||
get accessToken() { | |||
return process.env.LOGROCKET_ACCESS_TOKEN || nucleus.keys?.logrocket | |||
} | |||
/** | |||
* @type {boolean} | |||
*/ | |||
get can() { | |||
return isString(this.accessToken) | |||
} | |||
get release() { | |||
return process.env.GITHUB_SHA || process.env.npm_package_version | |||
} | |||
/** | |||
* @type {Object} | |||
*/ | |||
get config() { | |||
return { | |||
release: this.release, | |||
shouldCaptureIP: false, | |||
/*dom: { | |||
baseHref: nucleus.urls?.internal?.cdn || '', | |||
}, */ | |||
} | |||
} | |||
async setup() { | |||
if (!this.can) { | |||
return | |||
} | |||
try { | |||
LogRocket.init(this.accessToken) | |||
LogRocket.identify(settings.user || 'unknown', { | |||
settings: settings.payload, | |||
}) | |||
this.service = LogRocket | |||
this.enabled = true | |||
logger.info('LogRocket enabled!') | |||
logger.debug(this.accessToken) | |||
} catch (err) { | |||
logger.warn('LogRocket setup failed!', err) | |||
} | |||
} | |||
} | |||
export const logrocket = LogRocketService.make() |
@@ -10,11 +10,13 @@ | |||
import { isNil } from 'lodash' | |||
import axios from 'axios' | |||
import { BaseService } from './base' | |||
import { system } from '../tools' | |||
import { settings } from './settings' | |||
const { system, settings } = $provider | |||
const logger = require('logplease').create('services:nucleus') | |||
console.log(settings) | |||
/** | |||
* https://nucleus.sh | |||
* Analytics and bug tracking for Javascript desktop apps. | |||
@@ -43,7 +45,6 @@ export class NucleusService extends BaseService { | |||
} | |||
try { | |||
// eslint-disable-next-line global-require | |||
const Nucleus = require('nucleus-nodejs') | |||
// nucleus configuration | |||
@@ -59,7 +60,7 @@ export class NucleusService extends BaseService { | |||
Nucleus.appStarted() | |||
this._service = Nucleus | |||
this.service = Nucleus | |||
await this.fetchData() | |||
setInterval(this.fetchData.bind(this), 15 * 60 * 1000) |
@@ -92,7 +92,6 @@ class RollbarService extends BaseService { | |||
try { | |||
this._service = new Rollbar(this.config) | |||
this.enabled = true | |||
logger.info('Rollbar enabled!') |
@@ -0,0 +1,10 @@ | |||
// DreamTime. | |||
// Copyright (C) DreamNet. All rights reserved. | |||
// | |||
// This program is free software: you can redistribute it and/or modify | |||
// it under the terms of the GNU General Public License 3.0 as published by | |||
// the Free Software Foundation. See <https://www.gnu.org/licenses/gpl-3.0.html> | |||
// | |||
// Written by Ivan Bravo Bravo <ivan@dreamnet.tech>, 2019. | |||
export { requirements } from './requirements' |
@@ -0,0 +1,172 @@ | |||
// DreamTime. | |||
// Copyright (C) DreamNet. All rights reserved. | |||
// | |||
// This program is free software: you can redistribute it and/or modify | |||
// it under the terms of the GNU General Public License 3.0 as published by | |||
// the Free Software Foundation. See <https://www.gnu.org/licenses/gpl-3.0.html> | |||
// | |||
// Written by Ivan Bravo Bravo <ivan@dreamnet.tech>, 2019. | |||
import { isNil, isString, toInteger } from 'lodash' | |||
import { nucleus } from '../services' | |||
const logger = require('logplease').create('app:system:requirements') | |||
const { system, fs } = $provider | |||
const { is } = $provider.util | |||
const { remote } = $provider.api | |||
const { getVersion, isInstalled } = $provider.power | |||
const { getAppResourcesPath, getPowerPath, getCheckpointsPath } = $provider.paths | |||
export const requirements = { | |||
power: { | |||
installed: false, | |||
compatible: false, | |||
checkpoints: false, | |||
}, | |||
windows: { | |||
media: false, | |||
}, | |||
ram: { | |||
minimum: false, | |||
recommended: false, | |||
}, | |||
gpuram: { | |||
minimum: false, | |||
recommended: false, | |||
}, | |||
/** | |||
* @type {boolean} | |||
*/ | |||
get canNudify() { | |||
return this.power.installed && this.power.compatible && this.power.checkpoints | |||
}, | |||
/** | |||
* | |||
*/ | |||
async setup() { | |||
// dreampower | |||
this.power.installed = isInstalled() | |||
this.power.compatible = await this._hasCompatiblePower() | |||
this.power.checkpoints = this._hasCheckpoints | |||
// windows | |||
this.windows.media = await this._hasWindowsMedia() | |||
// ram | |||
this.ram.recommended = system.memory.total >= 8589934592 // 8 GB | |||
this.ram.minimum = system.memory.total >= 6442450944 // 6 GB | |||
logger.info('Requirements:', this) | |||
}, | |||
/** | |||
* @return {boolean} | |||
*/ | |||
async _hasCompatiblePower() { | |||
if (!this.power.installed) { | |||
return false | |||
} | |||
const compareVersions = require('compare-versions') | |||
try { | |||
const version = await getVersion() | |||
const currentVersion = process.env.npm_package_version | |||
const minimum = nucleus.v1?.projects?.dreamtime?.releases[`v${currentVersion}`]?.dreampower?.minimum || 'v0.0.1' | |||
const maximum = nucleus.v1?.projects?.dreamtime?.releases[`v${currentVersion}`]?.dreampower?.maximum | |||
if (compareVersions.compare(version, minimum, '<')) { | |||
return false | |||
} | |||
if (!isNil(maximum) && compareVersions.compare(version, maximum, '>')) { | |||
return false | |||
} | |||
return true | |||
} catch (err) { | |||
logger.warn('An error occurred while verifying the version of DreamPower.', err) | |||
return false | |||
} | |||
}, | |||
/** | |||
* @type {boolean} | |||
*/ | |||
get _hasCheckpoints() { | |||
const dirpath = getCheckpointsPath() | |||
if (!fs.existsSync(dirpath)) { | |||
return false | |||
} | |||
const filesize = require('filesize') | |||
// these files must exist | |||
const files = ['cm.lib', 'mm.lib', 'mn.lib'] | |||
for (const file of files) { | |||
const filepath = getCheckpointsPath(file) | |||
if (!fs.existsSync(filepath)) { | |||
return false | |||
} | |||
const stats = fs.statSync(filepath) | |||
const size = filesize(stats.size, { exponent: 2, output: 'object' }) | |||
if (size.value < 690) { | |||
return false | |||
} | |||
} | |||
return true | |||
}, | |||
/** | |||
* @return {boolean} | |||
*/ | |||
async _hasWindowsMedia() { | |||
if (!is.windows) { | |||
return true | |||
} | |||
const version = system.os.release | |||
if (toInteger(version) < 10) { | |||
// no windows 10 | |||
return true | |||
} | |||
const regedit = remote.require('regedit') | |||
if (!is.development) { | |||
// regedit commands | |||
regedit.setExternalVBSLocation( | |||
getAppResourcesPath('vbs'), | |||
) | |||
} | |||
const value = await new Promise((resolve) => { | |||
const regKey = 'HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Setup\\WindowsFeatures' | |||
regedit.list(regKey, (err, result) => { | |||
if (!isNil(err)) { | |||
resolve(false) | |||
return | |||
} | |||
resolve(result[regKey].keys.includes('WindowsMediaVersion')) | |||
}) | |||
}) | |||
return value | |||
}, | |||
} |
@@ -17,12 +17,12 @@ import deferred from 'deferred' | |||
import filesize from 'filesize' | |||
import delay from 'delay' | |||
import { basename } from 'path' | |||
import { nucleus } from '../services' | |||
import { AppError } from '../app-error' | |||
const { nucleus } = $provider.services | |||
const { system } = $provider.tools | |||
const { getPath } = $provider.tools.paths | |||
const { existsSync, statSync, download } = $provider.tools.fs | |||
const { system } = $provider | |||
const { getPath } = $provider.paths | |||
const { existsSync, statSync, download } = $provider.fs | |||
const { dialog } = $provider.api | |||
const { platform } = $provider.util | |||
@@ -8,10 +8,10 @@ | |||
// Written by Ivan Bravo Bravo <ivan@dreamnet.tech>, 2019. | |||
import { BaseUpdater } from './base' | |||
import { requirements } from '../system' | |||
const { system } = $provider.tools | |||
const { getCheckpointsPath, getPowerPath } = $provider.tools.paths | |||
const { existsSync, read, extractZip } = $provider.tools.fs | |||
const { getCheckpointsPath, getPowerPath } = $provider.paths | |||
const { existsSync, read, extractZip } = $provider.fs | |||
const { activeWindow } = $provider.util | |||
const { app, Notification } = $provider.api | |||
@@ -27,7 +27,7 @@ class CheckpointsUpdater extends BaseUpdater { | |||
* @type {string} | |||
*/ | |||
get currentVersion() { | |||
if (!system.requirements.power.checkpoints) { | |||
if (!requirements.power.checkpoints) { | |||
return 'v0.0.0' | |||
} | |||
@@ -74,4 +74,4 @@ class CheckpointsUpdater extends BaseUpdater { | |||
} | |||
} | |||
export const checkpoints = new CheckpointsUpdater() | |||
export const checkpoints = (new CheckpointsUpdater) |
@@ -10,12 +10,13 @@ | |||
import { isNil, get } from 'lodash' | |||
import compareVersions from 'compare-versions' | |||
import { BaseUpdater } from './base' | |||
import { requirements } from '../system' | |||
import { nucleus } from '../services' | |||
const { nucleus, settings } = $provider.services | |||
const { system } = $provider.tools | |||
const { getVersion } = $provider.tools.power | |||
const { getPowerPath } = $provider.tools.paths | |||
const { extractSeven } = $provider.tools.fs | |||
const { settings } = $provider | |||
const { getVersion } = $provider.power | |||
const { getPowerPath } = $provider.paths | |||
const { extractSeven } = $provider.fs | |||
const { activeWindow } = $provider.util | |||
const { app, Notification } = $provider.api | |||
@@ -46,7 +47,7 @@ class DreamPowerUpdater extends BaseUpdater { | |||
* @return {string} | |||
*/ | |||
async _getCurrentVersion() { | |||
if (!system.requirements.power.installed) { | |||
if (!requirements.power.installed) { | |||
return 'v0.0.0' | |||
} | |||
@@ -66,8 +67,8 @@ class DreamPowerUpdater extends BaseUpdater { | |||
_getLatestCompatible(releases) { | |||
const currentVersion = process.env.npm_package_version | |||
const minimum = nucleus.v1 ?.projects ?.dreamtime ?.releases[`v${currentVersion}`] ?.dreampower ?.minimum || 'v0.0.1' | |||
const maximum = nucleus.v1 ?.projects ?.dreamtime ?.releases[`v${currentVersion}`] ?.dreampower ?.maximum | |||
const minimum = nucleus.v1?.projects?.dreamtime?.releases[`v${currentVersion}`]?.dreampower?.minimum || 'v0.0.1' | |||
const maximum = nucleus.v1?.projects?.dreamtime?.releases[`v${currentVersion}`]?.dreampower?.maximum | |||
for (const release of releases) { | |||
if (compareVersions.compare(release.tag_name, minimum, '<')) { | |||
@@ -125,4 +126,4 @@ class DreamPowerUpdater extends BaseUpdater { | |||
} | |||
} | |||
export const dreampower = new DreamPowerUpdater() | |||
export const dreampower = (new DreamPowerUpdater) |
@@ -1,9 +1,11 @@ | |||
/* eslint-disable no-param-reassign */ | |||
/* eslint-disable nuxt/no-cjs-in-config */ | |||
const dev = process.env.NODE_ENV === 'development' | |||
module.exports = { | |||
/** | |||
* | |||
*/ | |||
mode: 'spa', | |||
/** | |||
@@ -25,16 +27,12 @@ module.exports = { | |||
** Headers of the page | |||
*/ | |||
head: { | |||
title: `${process.env.npm_package_displayName} v${process.env.npm_package_version}`, | |||
title: process.env.npm_package_displayName, | |||
meta: [ | |||
{ charset: 'utf-8' }, | |||
{ name: 'viewport', content: 'width=device-width, initial-scale=1' }, | |||
], | |||
link: [], | |||
scripts: [], | |||
}, | |||
/* | |||
@@ -50,7 +48,6 @@ module.exports = { | |||
'cropperjs/dist/cropper.css', | |||
'tui-image-editor/dist/tui-image-editor.css', | |||
'tui-color-picker/dist/tui-color-picker.css', | |||
'~/assets/css/tailwind.scss', | |||
'~/assets/css/fonts.scss', | |||
], | |||
@@ -58,7 +55,7 @@ module.exports = { | |||
/* | |||
** Plugins to load before mounting the App | |||
*/ | |||
plugins: ['~/plugins/boot.js', '~/plugins/fontawesome.js', '~/components'], | |||
plugins: ['~/plugins/boot.js', '~/plugins/setup.js', '~/plugins/fontawesome.js', '~/components'], | |||
/* | |||
** Nuxt.js dev-modules | |||
@@ -75,12 +72,6 @@ module.exports = { | |||
*/ | |||
modules: [], | |||
/* | |||
** Axios module configuration | |||
** See https://axios.nuxtjs.org/options | |||
*/ | |||
axios: {}, | |||
/** | |||
* | |||
*/ | |||
@@ -92,7 +83,6 @@ module.exports = { | |||
* | |||
*/ | |||
purgeCSS: { | |||
enabled: true, | |||
whitelistPatterns: [/tippy/, /cropper/, /tui/, /color-picker/], | |||
}, | |||
@@ -120,6 +110,9 @@ module.exports = { | |||
extractCSS: !dev, | |||
/** | |||
* | |||
*/ | |||
babel: { | |||
sourceType: 'unambiguous', | |||
@@ -140,16 +133,25 @@ module.exports = { | |||
], | |||
}, | |||
/** | |||
* | |||
*/ | |||
loaders: { | |||
imgUrl: { | |||
limit: 10 * 1000, | |||
}, | |||
}, | |||
/** | |||
* | |||
*/ | |||
terser: { | |||
parallel: true, | |||
}, | |||
/** | |||
* | |||
*/ | |||
optimization: { | |||
splitChunks: { | |||
cacheGroups: { | |||
@@ -174,15 +176,15 @@ module.exports = { | |||
exclude: /(node_modules)/, | |||
}) | |||
const webpack = require('webpack') | |||
// eslint-disable-next-line no-useless-escape | |||
config.plugins.push(new webpack.ContextReplacementPlugin(/moment[\/\\]locale$/, /en/)) | |||
if (isDev) { | |||
config.devtool = 'source-map' | |||
} else { | |||
config.output.publicPath = './_nuxt/' | |||
const webpack = require('webpack') | |||
// eslint-disable-next-line no-useless-escape | |||
config.plugins.push(new webpack.ContextReplacementPlugin(/moment[\/\\]locale$/, /en/)) | |||
} | |||
}, | |||
}, |
@@ -79,6 +79,7 @@ | |||
"js-event-bus": "^1.0.0", | |||
"lodash": "^4.17.15", | |||
"logplease": "^1.2.15", | |||
"logrocket": "^1.0.5", | |||
"md5-file": "^4.0.0", | |||
"mime-types": "^2.1.25", | |||
"moment": "^2.24.0", | |||
@@ -150,4 +151,4 @@ | |||
"tailwindcss-alpha": "hacknug/tailwindcss-alpha#feature/tests", | |||
"worker-loader": "^2.0.0" | |||
} | |||
} | |||
} |
@@ -3,7 +3,7 @@ | |||
<div v-if="alert" class="notification text-lg" v-html="alert" /> | |||
<!-- Offline --> | |||
<section v-if="!$provider.tools.system.online" class="box box--items"> | |||
<section v-if="!$provider.system.online" class="box box--items"> | |||
<div class="box__content"> | |||
<box-item | |||
description="While in offline mode you will not be able to obtain more information about the project or download the latest updates." | |||
@@ -12,7 +12,7 @@ | |||
</section> | |||
<!-- Requirements --> | |||
<section v-if="!$provider.tools.system.canNudify" class="box box--items"> | |||
<section v-if="!requirements.canNudify" class="box box--items"> | |||
<div class="box__content"> | |||
<box-item | |||
:description="`You need to meet all the requirements below to start using ${$dream.name}. Some require an Internet connection to update.`" | |||
@@ -23,7 +23,7 @@ | |||
label="DreamPower" | |||
description="DreamPower is not installed or the installed version is not compatible."> | |||
<template slot="icon"> | |||
<span v-if="$provider.tools.system.requirements.power.installed && $provider.tools.system.requirements.power.compatible" class="item__icon">✔</span> | |||
<span v-if="requirements.power.installed && requirements.power.compatible" class="item__icon">✔</span> | |||
<span v-else class="item__icon">❌</span> | |||
</template> | |||
@@ -37,7 +37,7 @@ | |||
label="Checkpoints" | |||
description="Data models required by DreamPower."> | |||
<template slot="icon"> | |||
<span v-if="$provider.tools.system.requirements.power.checkpoints" class="item__icon">✔</span> | |||
<span v-if="requirements.power.checkpoints" class="item__icon">✔</span> | |||
<span v-else class="item__icon">❌</span> | |||
</template> | |||
@@ -48,7 +48,7 @@ | |||
label="Media Feature Pack" | |||
description="Multimedia package required by some versions of Windows."> | |||
<template slot="icon"> | |||
<span v-if="$provider.tools.system.requirements.windows.media" class="item__icon">✔</span> | |||
<span v-if="requirements.windows.media" class="item__icon">✔</span> | |||
<span v-else class="item__icon">❗</span> | |||
</template> | |||
@@ -99,7 +99,7 @@ | |||
<app-update id="dreampower" project-title="DreamPower" project="dreampower" /> | |||
<app-update v-if="$provider.tools.system.requirements.power.installed" id="checkpoints" project-title="Checkpoints" project="checkpoints" /> | |||
<app-update v-if="requirements.power.installed" id="checkpoints" project-title="Checkpoints" project="checkpoints" /> | |||
<box-item | |||
v-for="(item, index) in dreampower.about.navigation" | |||
@@ -158,11 +158,17 @@ | |||
</template> | |||
<script> | |||
const { nucleus } = $provider.services | |||
const { getAppPath, getPowerPath } = $provider.tools.paths | |||
import { requirements } from '~/modules/system' | |||
import { nucleus } from '~/modules/services' | |||
const { getAppPath, getPowerPath } = $provider.paths | |||
const { shell } = $provider.api | |||
export default { | |||
data: () => ({ | |||
requirements, | |||
}), | |||
computed: { | |||
dreamtime() { | |||
const online = nucleus.v1?.projects?.dreamtime || {} |
@@ -53,8 +53,7 @@ | |||
<script> | |||
import _ from 'lodash' | |||
import { tween, styler } from 'popmotion' | |||
const { nucleus } = $provider.services | |||
import { nucleus } from '~/modules/services' | |||
export default { | |||
computed: { |
@@ -14,10 +14,9 @@ | |||
</template> | |||
<script> | |||
import { nucleus } from '~/modules/services' | |||
import { dreamtime as dreamtimeUpdater } from '~/modules/updater' | |||
const { nucleus } = $provider.services | |||
export default { | |||
data: () => ({ | |||
dreamtimeUpdater, |
@@ -45,7 +45,7 @@ | |||
</template> | |||
<script> | |||
const { settings } = $provider.services | |||
const { settings } = $provider | |||
export default { | |||
middleware: ({ route, redirect }) => { |
@@ -38,7 +38,7 @@ | |||
import _ from 'lodash' | |||
import { VModel } from '~/mixins' | |||
const { existsSync } = $provider.tools.fs | |||
const { existsSync } = $provider.fs | |||
const { dialog } = $provider.api | |||
export default { |
@@ -20,7 +20,7 @@ | |||
label="GPU" | |||
description="Graphics card that will be used to transform the photos."> | |||
<select v-model="currentValue.processing.gpus[0]" class="input"> | |||
<option v-for="(device, index) in $provider.tools.system.graphics" :key="index" :value="index"> | |||
<option v-for="(device, index) in $provider.system.graphics" :key="index" :value="index"> | |||
{{ device.model }} | |||
</option> | |||
<option v-for="n in 5" :key="`slot-${n - 1}`" :value="n - 1"> | |||
@@ -33,7 +33,7 @@ | |||
v-if="currentValue.processing.device === 'CPU'" | |||
label="CPU Cores" | |||
description="Increasing this can improve transformation speed but decrease system stability."> | |||
<input v-model="currentValue.processing.cores" type="number" min="1" :max="$provider.tools.system.cores" class="input"> | |||
<input v-model="currentValue.processing.cores" type="number" min="1" :max="$provider.system.cores" class="input"> | |||
</box-item> | |||
<box-item |
@@ -27,7 +27,7 @@ | |||
export default { | |||
methods: { | |||
next() { | |||
$provider.services.settings.welcome = false | |||
$provider.settings.welcome = false | |||
this.$router.push('/') | |||
}, | |||
}, |
@@ -1,78 +1,46 @@ | |||
/* eslint-disable no-param-reassign */ | |||
import Vue from 'vue' | |||
import moment from 'moment' | |||
import tippy from 'tippy.js' | |||
// DreamTime. | |||
// Copyright (C) DreamNet. All rights reserved. | |||
// | |||
// This program is free software: you can redistribute it and/or modify | |||
// it under the terms of the GNU General Public License 3.0 as published by | |||
// the Free Software Foundation. See <https://www.gnu.org/licenses/gpl-3.0.html> | |||
// | |||
// Written by Ivan Bravo Bravo <ivan@dreamnet.tech>, 2019. | |||
import Logger from 'logplease' | |||
import BaseMixin from '~/mixins/BaseMixin' | |||
import { AppError, dream } from '~/modules' | |||
import { Nudify, NudifyStore } from '~/modules/nudify' | |||
import { AppError } from '~/modules' | |||
import { dreamtime, dreampower, checkpoints } from '~/modules/updater' | |||
import { nucleus, logrocket } from '~/modules/services' | |||
import { requirements } from '~/modules/system' | |||
const logger = Logger.create('plugins:boot') | |||
const { getPath } = $provider.tools.paths | |||
// const logger = Logger.create('plugins:boot') | |||
// logger setup | |||
Logger.setLogLevel(process.env.LOG || 'info') | |||
Logger.setLogfile(getPath('userData', 'renderer.log')) | |||
// lift off! | |||
logger.info('Lift off!') | |||
// base mixin | |||
Vue.mixin(BaseMixin) | |||
// momentjs | |||
moment.locale('en') | |||
// tippyjs | |||
tippy.setDefaultProps({ | |||
delay: 100, | |||
arrow: true, | |||
}) | |||
Logger.setLogLevel(process.env.LOG || 'debug') | |||
// global apperror | |||
window.AppError = AppError | |||
// eslint-disable-next-line no-unused-vars | |||
export default async ({ app }, inject) => { | |||
// update providers | |||
dreamtime.setup() | |||
dreampower.setup() | |||
checkpoints.setup() | |||
// analytics. | |||
await nucleus.setup() | |||
// provider shortcuts | |||
inject('provider', $provider) | |||
inject('settings', $provider.services.settings) | |||
inject('nucleus', $provider.services.nucleus) | |||
// catch errors | |||
window.addEventListener('error', (err) => { | |||
AppError.handle(err) | |||
return true | |||
}) | |||
window.addEventListener('unhandledrejection', (rejection) => { | |||
AppError.handle(rejection.reason) | |||
return true | |||
}) | |||
Vue.config.errorHandler = (err) => { | |||
AppError.handle(err) | |||
throw err | |||
} | |||
// log tracking. | |||
await logrocket.setup() | |||
// dreamtime | |||
dream.setup() | |||
inject('dream', dream) | |||
// dreamtime requirements. | |||
await requirements.setup() | |||
// nudify | |||
Nudify.setup() | |||
// update providers. | |||
dreamtime.setup() | |||
dreampower.setup() | |||
checkpoints.setup() | |||
// nudify store | |||
NudifyStore.setup() | |||
inject('nudify', NudifyStore) | |||
console.log('ready') | |||
// ready | |||
logger.info('The front-end is ready!') | |||
// shortcuts. | |||
inject('provider', $provider) | |||
inject('settings', $provider.settings) | |||
inject('nucleus', nucleus) | |||
} |
@@ -0,0 +1,64 @@ | |||
// DreamTime. | |||
// Copyright (C) DreamNet. All rights reserved. | |||
// | |||
// This program is free software: you can redistribute it and/or modify | |||
// it under the terms of the GNU General Public License 3.0 as published by | |||
// the Free Software Foundation. See <https://www.gnu.org/licenses/gpl-3.0.html> | |||
// | |||
// Written by Ivan Bravo Bravo <ivan@dreamnet.tech>, 2019. | |||
import Vue from 'vue' | |||
import moment from 'moment' | |||
import tippy from 'tippy.js' | |||
import { AppError, dream } from '~/modules' | |||
import { Nudify, NudifyStore } from '~/modules/nudify' | |||
import BaseMixin from '~/mixins/BaseMixin' | |||
const logger = require('logplease').create('plugins:setup') | |||
// lift off! | |||
logger.info('Lift off!') | |||
// base mixin | |||
Vue.mixin(BaseMixin) | |||
// momentjs | |||
moment.locale('en') | |||
// tippyjs | |||
tippy.setDefaultProps({ | |||
delay: 100, | |||
arrow: true, | |||
}) | |||
export default async ({ app }, inject) => { | |||
// catch errors | |||
window.addEventListener('error', (err) => { | |||
AppError.handle(err) | |||
return true | |||
}) | |||
window.addEventListener('unhandledrejection', (rejection) => { | |||
AppError.handle(rejection.reason) | |||
return true | |||
}) | |||
Vue.config.errorHandler = (err) => { | |||
AppError.handle(err) | |||
throw err | |||
} | |||
// dreamtime. | |||
dream.setup() | |||
inject('dream', dream) | |||
// nudify. | |||
Nudify.setup() | |||
// nudify store. | |||
NudifyStore.setup() | |||
inject('nudify', NudifyStore) | |||
// ready | |||
logger.info('The front-end is ready!') | |||
} |