Browse Source

Fixed: New update notifications on homepage don't open the updater on click.

Fixed: `Cannot read property 'trim' of undefined` on startup.
Fixed: IPFS did not start on some systems.
Improvement: Some improvements in texts and design.
Improvement: New `Changelog` page in `About -> DreamTime`.
Improvement: Tooltips have been added in various settings options with detailed information.
Improvement: Videos no longer play in the queuebar for performance reasons.
Improvement: Now the progress in frames is shown when nudifing a video.
Improvement: The way the "Per run" options are presented has been improved.
master
Ivan Bravo Bravo 2 months ago
parent
commit
bda736aa34
53 changed files with 2692 additions and 1675 deletions
  1. 119
    0
      .github/workflows/build-release.yml
  2. 3
    32
      .github/workflows/build.yml
  3. 1
    1
      .github/workflows/lint.yml
  4. 5
    5
      src/assets/css/components/_notification.scss
  5. 5
    0
      src/assets/css/reset/_base.scss
  6. 21
    5
      src/assets/css/reset/_libs.scss
  7. 1
    0
      src/assets/images/undraw/undraw_active_support_6rwo.svg
  8. 4
    0
      src/components/Help/HelpLesson.vue
  9. 6
    1
      src/components/Nudify/NudifyPhotoPreview.vue
  10. 5
    2
      src/components/Nudify/NudifyPhotoRun.vue
  11. 5
    5
      src/components/Queue/QueueMenu.vue
  12. 3
    3
      src/components/Queue/QueuePhoto.vue
  13. 5
    5
      src/components/Settings/Preference.vue
  14. 36
    2
      src/components/Settings/SettingsField.vue
  15. 25
    28
      src/components/Settings/SettingsPreferences.vue
  16. 1
    1
      src/components/UI/AppNotification.vue
  17. 1
    1
      src/components/UI/AppStats.vue
  18. 22
    1
      src/components/UI/MenuItem.vue
  19. 11
    1
      src/electron-builder.js
  20. 8
    0
      src/electron/src/index.js
  21. 27
    7
      src/electron/src/modules/settings.js
  22. 13
    6
      src/electron/src/modules/tools/fs.js
  23. 33
    15
      src/modules/config/help.yml
  24. 72
    33
      src/modules/config/settings.yml
  25. 2
    2
      src/modules/nudify/nudify.js
  26. 23
    11
      src/modules/nudify/photo-run.js
  27. 44
    4
      src/modules/nudify/photo.js
  28. 1
    1
      src/modules/timer.js
  29. 9
    4
      src/modules/updater/base.js
  30. 5
    0
      src/modules/updater/checkpoints.js
  31. 1
    1
      src/nuxt.config.js
  32. 38
    37
      src/package.json
  33. 1
    1
      src/package.min.json
  34. 55
    0
      src/pages/about/changelog.vue
  35. 1
    1
      src/pages/about/dreamnet.vue
  36. 6
    0
      src/pages/about/dreamtime.vue
  37. 5
    3
      src/pages/nudify/_id.vue
  38. 3
    1
      src/pages/nudify/_id/results.vue
  39. 0
    14
      src/pages/settings/app.vue
  40. 1
    1
      src/pages/settings/preferences.vue
  41. 20
    1
      src/pages/settings/processing.vue
  42. 5
    12
      src/pages/settings/share.vue
  43. 1
    1
      src/pages/wizard/checkpoints.vue
  44. 0
    8
      src/pages/wizard/dreamtime.vue
  45. 67
    0
      src/scripts/chocolatey/dreamtime.nuspec
  46. 11
    0
      src/scripts/chocolatey/tools/LICENSE.txt
  47. 13
    0
      src/scripts/chocolatey/tools/VERIFICATION.txt
  48. 9
    0
      src/scripts/chocolatey/tools/chocolateybeforemodify.ps1
  49. 151
    0
      src/scripts/chocolatey/tools/chocolateyinstall.ps1
  50. 84
    0
      src/scripts/chocolatey/tools/chocolateyuninstall.ps1
  51. 15
    14
      src/scripts/deploy.js
  52. 4
    0
      src/tailwind.config.js
  53. 1685
    1404
      src/yarn.lock

+ 119
- 0
.github/workflows/build-release.yml View File

@@ -0,0 +1,119 @@
name: Build Release

on:
push:
paths:
- src/**
- .github/workflows/**
branches:
- release/*
tags:
- v*

jobs:
build:
name: ${{ matrix.platform }} (${{ matrix.type }})
runs-on: ${{ matrix.os }}

# Strategy
# (variables for multiple platforms)
# https://help.github.com/en/articles/workflow-syntax-for-github-actions#jobsjob_idstrategy
strategy:
fail-fast: true
max-parallel: 2
matrix:
os:
- ubuntu-latest
- windows-latest
- macOS-latest
type:
- installer
- portable

include:
- os: ubuntu-latest # Ubuntu
platform: ubuntu
extension: snap
- os: windows-latest # Windows
platform: windows
extension: exe
- os: macOS-latest # macOS
platform: macos
extension: dmg

steps:
- uses: actions/checkout@v1
with:
submodules: true

- name: Install Snapcraft
uses: samuelmeuli/action-snapcraft@v1
with:
snapcraft_token: ${{ secrets.SNAPCRAFT_TOKEN }}

- name: Install Node.js 12.x
uses: actions/setup-node@v1
with:
node-version: 12.x

- name: Install Yarn
run: npm install -g yarn

- name: Setup
working-directory: src/
run: yarn install --network-timeout 1000000

- name: Build Installer
working-directory: src/
if: matrix.type == 'installer'
env:
GITHUB_SHA: ${{ github.sha }}
run: yarn run build

- name: Build Portable
working-directory: src/
if: matrix.type == 'portable'
env:
GITHUB_SHA: ${{ github.sha }}
BUILD_PORTABLE: true
run: yarn run build

- uses: actions/upload-artifact@v2
with:
name: dreamtime-${{ matrix.platform }}-${{ matrix.type }}
path: |
dist/*.zip
dist/*.exe
dist/*.snap
dist/*.dmg

- uses: actions/upload-artifact@v2
with:
name: dreamtime-${{ matrix.platform }}-${{ matrix.type }}-static
path: src/dist

- name: Deploy to Storage
working-directory: src/
continue-on-error: true
timeout-minutes: 20
env:
GITHUB_SHA: ${{ github.sha }}
GITHUB_REF: ${{ github.ref }}
BUILD_PLATFORM: ${{ matrix.platform }}
BUILD_EXTENSION: ${{ matrix.extension }}
DEPLOY_ENCRYPT_KEY: ${{ secrets.DEPLOY_ENCRYPT_KEY }}
DEPLOY_GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
DEPLOY_GITHUB_OWNER: dreamnettech
DEPLOY_TEKNIK_TOKEN: ${{ secrets.DEPLOY_TEKNIK_TOKEN }}
DEPLOY_TEKNIK_OWNER: dreamnet
DEPLOY_PINATA_KEY: ${{ secrets.DEPLOY_PINATA_KEY }}
DEPLOY_PINATA_SECRET: ${{ secrets.DEPLOY_PINATA_SECRET }}
DEPLOY_MEGA_EMAIL: ${{ secrets.DEPLOY_MEGA_EMAIL }}
DEPLOY_MEGA_PASSWORD: ${{ secrets.DEPLOY_MEGA_PASSWORD }}
DEPLOY_MEGA_FOLDER: "/Projects/DreamTime/Releases/"
run: yarn run deploy

- name: Deploy to Snapcraft
if: matrix.type == 'installer' && matrix.platform == 'ubuntu'
working-directory: dist/
run: snapcraft upload --release=stable *.snap

+ 3
- 32
.github/workflows/build.yml View File

@@ -6,11 +6,8 @@ on:
- src/**
- .github/workflows/**
branches:
- release/*
- hotfix/*
- canary
tags:
- v*

jobs:
build:
@@ -22,7 +19,6 @@ jobs:
# https://help.github.com/en/articles/workflow-syntax-for-github-actions#jobsjob_idstrategy
strategy:
fail-fast: true
max-parallel: 2
matrix:
os:
- ubuntu-latest
@@ -48,21 +44,17 @@ jobs:
with:
submodules: true

- name: Use Node.js 12.x
- name: Install Node.js 12.x
uses: actions/setup-node@v1
with:
node-version: 12.x

- name: Use Yarn
- name: Install Yarn
run: npm install -g yarn

- name: Setup
working-directory: src/
run: yarn install

- name: Lint
working-directory: src/
run: yarn run lint
run: yarn install --network-timeout 1000000

- name: Build Installer
working-directory: src/
@@ -87,24 +79,3 @@ jobs:
dist/*.exe
dist/*.snap
dist/*.dmg

- name: Deploy
working-directory: src/
continue-on-error: true
timeout-minutes: 20
env:
GITHUB_SHA: ${{ github.sha }}
GITHUB_REF: ${{ github.ref }}
BUILD_PLATFORM: ${{ matrix.platform }}
BUILD_EXTENSION: ${{ matrix.extension }}
DEPLOY_ENCRYPT_KEY: ${{ secrets.DEPLOY_ENCRYPT_KEY }}
DEPLOY_GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
DEPLOY_GITHUB_OWNER: dreamnettech
DEPLOY_TEKNIK_TOKEN: ${{ secrets.DEPLOY_TEKNIK_TOKEN }}
DEPLOY_TEKNIK_OWNER: dreamnet
DEPLOY_PINATA_KEY: ${{ secrets.DEPLOY_PINATA_KEY }}
DEPLOY_PINATA_SECRET: ${{ secrets.DEPLOY_PINATA_SECRET }}
DEPLOY_MEGA_EMAIL: ${{ secrets.DEPLOY_MEGA_EMAIL }}
DEPLOY_MEGA_PASSWORD: ${{ secrets.DEPLOY_MEGA_PASSWORD }}
DEPLOY_MEGA_FOLDER: "/Projects/DreamTime/Releases/"
run: yarn run deploy

+ 1
- 1
.github/workflows/lint.yml View File

@@ -28,7 +28,7 @@ jobs:

- name: Setup
working-directory: src/
run: yarn install
run: yarn install --network-timeout 1000000

- name: Lint
working-directory: src/

+ 5
- 5
src/assets/css/components/_notification.scss View File

@@ -10,8 +10,8 @@
*/

.notification {
@apply mb-4 py-4 px-4 rounded;
@apply bg-white text-black text-sm;
@apply mb-4 py-4 pl-4 pr-6 rounded;
@apply bg-menus-light text-white text-sm;

h5 {
@apply font-bold;
@@ -23,15 +23,15 @@
}

&.notification--warning {
@apply bg-warning-500;
@apply bg-warning-500 text-black;
}

&.notification--danger {
@apply bg-danger-400;
@apply bg-danger-400 text-black;
}

&.notification--success {
@apply bg-success-500;
@apply bg-success-500 text-black;
}

.icon {

+ 5
- 0
src/assets/css/reset/_base.scss View File

@@ -26,3 +26,8 @@ html,
#__layout {
@apply h-full;
}

code {
@apply rounded px-1 text-sm break-words shadow-sm;
background-color: #444950;
}

+ 21
- 5
src/assets/css/reset/_libs.scss View File

@@ -38,10 +38,6 @@
max-height: 100px;
}

code {
@apply bg-black px-2 text-sm rounded-sm break-words;
}

a {
@apply underline text-white font-bold;
}
@@ -49,7 +45,7 @@

.swal2-footer {
code {
@apply text-sm text-center;
@apply text-center;
}
}

@@ -82,3 +78,23 @@
.introjs-overlay {
backdrop-filter: blur(10px);
}

.tippy-content {
@apply px-6 py-3 bg-menus-light shadow;

ul {
@apply list-disc;

li {
@apply text-sm ml-3;

&:not(:last-child) {
@apply mb-2;
}
}
}
}

.vue-slider-dot-tooltip-inner {
@apply bg-primary border-primary;
}

+ 1
- 0
src/assets/images/undraw/undraw_active_support_6rwo.svg
File diff suppressed because it is too large
View File


+ 4
- 0
src/components/Help/HelpLesson.vue View File

@@ -135,6 +135,10 @@ export default {
.photo--masks {
background-image: url('~assets/images/undraw/undraw_making_art_759c.svg')
}

.photo--support {
background-image: url('~assets/images/undraw/undraw_active_support_6rwo.svg')
}
}
}


+ 6
- 1
src/components/Nudify/NudifyPhotoPreview.vue View File

@@ -2,7 +2,7 @@
<div class="preview" :style="photoURL" data-private>
<video v-if="isVideo"
:src="file.url"
autoplay
:autoplay="autoplay"
muted
loop />

@@ -27,6 +27,11 @@ export default {
type: Boolean,
default: false,
},

autoplay: {
type: Boolean,
default: true,
},
},

computed: {

+ 5
- 2
src/components/Nudify/NudifyPhotoRun.vue View File

@@ -18,15 +18,18 @@
@click="openPreview" />

<div v-if="run.algorithmStatus !== ALGORITHM.NONE" class="run__photo__status">
<span v-if="run.algorithmStatus === ALGORITHM.DREAMPOWER" key="dreampower" v-tooltip="'The photo is being nudified by DreamPower.'">Nudifying</span>
<span v-if="run.algorithmStatus === ALGORITHM.DREAMPOWER" key="dreampower" v-tooltip="'The photo is being nudified by the algorithm.'">
Nudifying
</span>
<span v-if="run.algorithmStatus === ALGORITHM.WAIFU2X" key="waifu2x" v-tooltip="'The photo is being upscaled by Waifu2X.'">Upscaling</span>
<span v-if="run.algorithmStatus === ALGORITHM.DREAMTIME" key="dreamtime" v-tooltip="'The photo is being prepared by DreamTime.'">Other</span>
<span v-if="run.frameStatus" v-tooltip="'Video frame.'"> ({{ run.frameStatus }})</span>
</div>
</div>

<!-- Preferences -->
<div
v-if="run.preferences.body.randomize || run.preferences.body.progressive.enabled"
v-if="run.preferences.body.runs.mode !== false"
class="run__preferences">
<div class="preference">
<span>Boobs</span>

+ 5
- 5
src/components/Queue/QueueMenu.vue View File

@@ -11,17 +11,17 @@

<div v-show="$nudify.waiting.length > 0" class="queue__section__actions">
<button
v-tooltip="{placement: 'bottom', content: 'Forget those who wait'}"
v-tooltip="{placement: 'bottom', content: 'Remove all'}"
class="button button--danger button--xs"
@click.prevent="$nudify.forgetAll('waiting')">
<font-awesome-icon icon="trash-alt" />
</button>

<button
v-tooltip="{placement: 'bottom', content: 'Cancel those who wait' }"
v-tooltip="{placement: 'bottom', content: 'Cancel all' }"
class="button button--xs"
@click.prevent="$nudify.cancelAll('waiting')">
<font-awesome-icon icon="stop" />
<font-awesome-icon icon="sign-out-alt" />
</button>
</div>
</div>
@@ -45,7 +45,7 @@

<div v-show="$nudify.pending.length > 0" class="queue__section__actions">
<button
v-tooltip="'Forget all'"
v-tooltip="'Remove all'"
class="button button--danger button--xs"
@click.prevent="$nudify.forgetAll()">
<font-awesome-icon icon="trash-alt" />
@@ -79,7 +79,7 @@

<div v-show="$nudify.finished.length > 0" class="queue_section__actions">
<button
v-tooltip="'Forget all'"
v-tooltip="'Remove all'"
class="button button--danger button--xs"
@click.prevent="$nudify.forgetAll('finished')">
<font-awesome-icon icon="trash-alt" />

+ 3
- 3
src/components/Queue/QueuePhoto.vue View File

@@ -1,12 +1,12 @@
<template>
<div class="photo" :class="photoClass">
<NudifyPhotoPreview :photo="photo" :live="true" />
<NudifyPhotoPreview :photo="photo" :live="false" :autoplay="false" />

<div class="photo__content">
<div class="photo__content__actions">
<span v-show="photo.running || photo.finished">{{ photo.timer.duration }}s</span>

<button v-tooltip="'Open'" @click="open">
<button v-tooltip="'Photo Panel'" @click="open">
<font-awesome-icon icon="external-link-square-alt" />
</button>

@@ -14,7 +14,7 @@
<font-awesome-icon icon="play" />
</button>

<button v-show="photo.waiting" v-tooltip="'Remove from Queue'" @click="cancel">
<button v-show="photo.waiting" v-tooltip="'Cancel'" @click="cancel">
<font-awesome-icon icon="sign-out-alt" />
</button>


+ 5
- 5
src/components/Settings/Preference.vue View File

@@ -2,7 +2,7 @@
<section v-if="!readonly" class="box">
<div class="box__content">
<MenuItem :description="`Value: ${value$.size}`" :label="`${label} size`">
<div v-if="!body.randomize">
<div v-if="body.runs.mode === false">
<VueSlider v-model="value$.size"
:min="min"
:max="max"
@@ -11,9 +11,9 @@
</MenuItem>

<MenuItem
v-if="!body.randomize && body.progressive.enabled"
label="Progressive?"
description="Increase this body part progressively in each run.">
v-if="body.runs.mode === 'increase'"
label="Increase?"
description="Indicates if this should increase with each run.">
<select v-model="value$.progressive" class="input">
<option :value="true">
Enabled
@@ -24,7 +24,7 @@
</select>
</MenuItem>

<div v-if="body.randomize">
<div v-if="body.runs.mode === 'randomize'">
<MenuItem
label="Randomize?"
description="Randomize this body part in each run.">

+ 36
- 2
src/components/Settings/SettingsField.vue View File

@@ -2,6 +2,7 @@
<MenuItem
:label="fieldLabel"
:description="fieldDescription"
:tooltip="fieldTooltip"
:data-id="field.id">
<slot>
<div v-if="!readonly" class="flex-1">
@@ -9,6 +10,7 @@
<select v-if="field.input === 'select'"
v-model="localValue"
class="input"
:disabled="disabled"
v-bind="inputAttrs">
<option v-for="(option, index) in selectOptions" :key="index" :value="option.value">
{{ option.label }}
@@ -19,6 +21,7 @@
<input v-if="field.input === 'input'"
v-model="localValue"
class="input"
:disabled="disabled"
v-bind="inputAttrs">
</div>

@@ -28,7 +31,9 @@
</template>

<script>
import { get, set, find } from 'lodash'
import {
get, set, find, isObject,
} from 'lodash'
import { VModel } from '~/mixins'

export default {
@@ -50,6 +55,11 @@ export default {
default: null,
},

tooltip: {
type: String,
default: null,
},

options: {
type: Array,
default: null,
@@ -70,6 +80,11 @@ export default {
default: false,
},

disabled: {
type: Boolean,
default: false,
},

ignoreHardcoded: {
type: Boolean,
defalt: false,
@@ -127,6 +142,14 @@ export default {
return this.field.description
},

fieldTooltip() {
if (this.tooltip) {
return this.tooltip
}

return this.field.tooltip
},

inputAttrs() {
if (this.attrs) {
return this.attrs
@@ -143,6 +166,15 @@ export default {
return
}

if (this.readonly || this.disabled) {
return
}

if (this.value$ && !isObject(this.value$)) {
console.warn('Saving has been prevented because value$ is not an object.')
return
}

if (this.value$) {
this.value$ = set(this.value$, this.localFieldId, value)
} else {
@@ -160,8 +192,10 @@ export default {
throw new Error(`Invalid field ID: ${this.fieldId}`)
}

if (this.value) {
if (isObject(this.value)) {
this.localValue = get(this.value, this.localFieldId)
} else if (this.value) {
this.localValue = this.value
} else {
this.localValue = this.$settings.get(this.fieldId)
}

+ 25
- 28
src/components/Settings/SettingsPreferences.vue View File

@@ -12,6 +12,31 @@
</div>
</section>

<!-- Runs -->
<section v-if="value$.mode === 2" id="preferences-runs" class="box">
<div class="box__header">
<h2 class="title">
Per run.
</h2>
<h3 class="subtitle">
Customize body preferences for multiple runs.
</h3>
</div>

<div class="box__content">
<SettingsField
v-model="value$"
field-id="preferences.body.runs.mode" />

<SettingsField v-if="value$.body.runs.mode !== false" v-model="value$" field-id="preferences.body.runs.count" />

<SettingsField v-if="value$.body.runs.mode === 'increase'"
v-model="value$"
field-id="preferences.body.runs.rate"
:description="`Body preferences will increase ${value$.body.runs.rate} at each run.`" />
</div>
</section>

<!-- Boobs -->
<Preference id="preferences-body"
v-model="value$.body.boobs"
@@ -38,34 +63,6 @@
label="Pubic Hair"
:min="0" />

<!-- Runs -->
<section v-if="value$.mode === 2" id="preferences-runs" class="box">
<div class="box__header">
<h2 class="title">
Per run.
</h2>
<h3 class="subtitle">
Customize what will happen each run.
<AppTip tooltip="The runs allow you to nudify the same photo with different preferences." />
</h3>
</div>

<div class="box__content">
<SettingsField v-model="value$" field-id="preferences.body.executions" />

<SettingsField v-model="value$" field-id="preferences.body.randomize" />

<SettingsField v-model="value$"
field-id="preferences.body.progressive.enabled"
:description="`Body preferences will increase ${value$.body.progressive.rate} at each run.`" />

<SettingsField v-if="!value$.body.randomize && value$.body.progressive.enabled"
v-model="value$"
field-id="preferences.body.progressive.rate"
:description="`Value: ${value$.body.progressive.rate}`" />
</div>
</section>

<!-- Advanced -->
<section v-if="value$.mode > 1" id="preferences-advanced" class="box">
<div class="box__header">

+ 1
- 1
src/components/UI/AppNotification.vue View File

@@ -1,5 +1,5 @@
<template>
<div v-if="canShow" class="notification">
<div v-if="canShow" class="notification" @click="$emit('click')">
<span class="close-icon" @click="close()">
<FontAwesomeIcon icon="times-circle" />
</span>

+ 1
- 1
src/components/UI/AppStats.vue View File

@@ -9,7 +9,7 @@
</div>

<div v-tippy
data-tippy-content="Number of different users who have used the application."
data-tippy-content="Number of unique users who have used the application."
data-tippy-placement="bottom"
class="box">
<span class="stats__value">{{ stats | stat('users.total') }}</span>

+ 22
- 1
src/components/UI/MenuItem.vue View File

@@ -10,7 +10,10 @@

<!-- Title & Description -->
<div v-if="label" class="item__label">
<span class="item__title" v-html="label" />
<div class="item__title">
<span v-html="label" />
<AppTip v-if="tooltip" :tooltip="prettyTooltip" />
</div>

<slot name="description">
<span v-if="description" class="item__description" v-html="description" />
@@ -26,8 +29,11 @@

<script>
import { isNil, startsWith } from 'lodash'
import MarkdownIt from 'markdown-it'
import { dreamtrack } from '~/modules/services'

const md = new MarkdownIt()

const { shell } = $provider.api

export default {
@@ -47,6 +53,11 @@ export default {
default: undefined,
},

tooltip: {
type: String,
default: undefined,
},

href: {
type: String,
default: undefined,
@@ -77,6 +88,10 @@ export default {
'item--link': !isNil(this.href) || this.isLink,
}
},

prettyTooltip() {
return md.render(this.tooltip)
},
},

methods: {
@@ -145,6 +160,12 @@ export default {
@apply block font-semibold;
}

&::v-deep {
.tip {
@apply ml-1;
}
}

.item__description {
@apply block text-xs text-common-dark;
}

+ 11
- 1
src/electron-builder.js View File

@@ -2,6 +2,12 @@

const pkg = require('./package.json')

let isRelease = false

if (process.env.GITHUB_REF) {
isRelease = process.env.GITHUB_REF.substring(0, 9) === 'refs/tags'
}

/**
* Windows Release
*/
@@ -38,7 +44,7 @@ const linux = {
linux: {
target: process.env.BUILD_PORTABLE ? 'zip' : 'snap',
artifactName: process.env.BUILD_PORTABLE ? '${productName}-v${version}-ubuntu-portable.${ext}' : '${productName}-v${version}-ubuntu-installer.${ext}',
executableName: process.env.npm_package_name,
executableName: 'dreamtimetech',
synopsis: pkg.description,
category: 'Graphics',
extraResources: [
@@ -48,6 +54,10 @@ const linux = {
},
],
},
snap: {
confinement: 'strict',
grade: isRelease ? 'stable' : 'devel',
},
}

/**

+ 8
- 0
src/electron/src/index.js View File

@@ -182,6 +182,13 @@ class DreamApp {
return
}

if (url.host === 'github.com' || url.host === 'dreamnet.tech' || url.host === 'dreamtime.tech' || url.host === 'dreamcore.tech') {
// Probably come from the changelog, we open in the browser.
event.preventDefault()
shell.openExternal(navigationUrl)
return
}

event.preventDefault()

logger.warn('Illegal page load blocked!', {
@@ -263,6 +270,7 @@ class DreamApp {
icon,

webPreferences: {
enableRemoteModule: true,
nodeIntegration: true,
nodeIntegrationInWorker: true,
webSecurity: false, // Necessary to load filesystem photos.

+ 27
- 7
src/electron/src/modules/settings.js View File

@@ -9,7 +9,7 @@

import fs from 'fs-extra'
import {
cloneDeep, isNil, isEmpty, isPlainObject, get, set, merge,
cloneDeep, isNil, isEmpty, isPlainObject, get, set, merge, omit,
} from 'lodash'
import { AppError } from './app-error'
import { paths, system } from './tools'
@@ -136,7 +136,7 @@ class Settings {
const hasGPU = process.platform === 'darwin' ? false : system.graphics.length > 0

this.payload = {
version: 11,
version: 12,
user: uuid(),

wizard: {
@@ -190,11 +190,9 @@ class Settings {

preferences: {
body: {
executions: 1,
randomize: false,

progressive: {
enabled: false,
runs: {
mode: false,
count: 1,
rate: 0.1,
},

@@ -529,6 +527,28 @@ class Settings {
}
}

// 11 -> 12
if (this.payload?.version === 11 && this._default.version >= 12) {
this.payload = merge(this.payload, {
version: 12,
preferences: {
body: {
runs: {
mode: false,
count: 2,
rate: 0.1,
},
},
},
})

this.payload = omit(this.payload, [
'preferences.body.executions',
'preferences.body.randomize',
'preferences.body.progressive',
])
}

this.save()
}
}

+ 13
- 6
src/electron/src/modules/tools/fs.js View File

@@ -211,14 +211,16 @@ export async function downloadFromIPFS(cid, options, events, writeStream) {

// Utility functions
const createNode = async function () {
const ipfsBin = require('go-ipfs-dep').path().replace('app.asar', 'app.asar.unpacked')

logger.debug('Creating IPFS node...')
logger.debug(require('go-ipfs-dep').path())
logger.debug(ipfsBin)

fs.ensureDirSync(getPath('temp', 'ipfs'))

node = await IpfsCtl.createController({
ipfsHttpModule: require('ipfs-http-client'),
ipfsBin: require('go-ipfs-dep').path().replace('app.asar', 'app.asar.unpacked'),
ipfsBin,
ipfsOptions: {
repo: getPath('temp', 'ipfs'),
start: true,
@@ -244,8 +246,6 @@ export async function downloadFromIPFS(cid, options, events, writeStream) {
logger.debug('Connecting to providers...')

try {
await node.api.swarm.connect('/ip4/64.227.19.223/tcp/4001/p2p/QmSarArpxemsPESa6FNkmuu9iSE1QWqPX2R3Aw6f5jq4D5')
await node.api.swarm.connect('/ip4/64.227.27.182/tcp/4001/p2p/QmRjLSisUCHVpFa5ELVvX3qVPfdxajxWJEHs9kN3EcxAW6')
await node.api.swarm.connect('/dns4/mariana.dreamnet.tech/tcp/4001/p2p/QmcWoy1FzBicbYuopNT2rT6EDQSBDfco1TxibEyYgWbiMq')
} catch (err) {
logger.warn(err)
@@ -257,12 +257,19 @@ export async function downloadFromIPFS(cid, options, events, writeStream) {

await connectToProviders()

logger.debug('Connected!')

if (!node) {
// It seems that the user has canceled it
return
}

stats = await node.api.object.stat(cid, { timeout: 3000 })
logger.debug(`Obtaining download information... (${cid})`)

stats = await node.api.object.stat(cid, { timeout: 30000 })

// eslint-disable-next-line no-console
console.log(stats)

logger.debug('Downloading...')

@@ -273,7 +280,7 @@ export async function downloadFromIPFS(cid, options, events, writeStream) {
}

// eslint-disable-next-line promise/always-return
all(node.api.dht.findProvs(cid, { timeout: 10000 })).then((provs) => {
all(node.api.dht.findProvs(cid, { timeout: 30000 })).then((provs) => {
events.emit('peers', provs.length)
}).catch(() => { })


+ 33
- 15
src/modules/config/help.yml View File

@@ -41,7 +41,7 @@
- title: Photo preferences.
photo: preferences
buttons:
- text: Go to preferences
- text: Go to photo preferences
href: /settings/preferences
summary: |-
Create the nude of your dreams by customizing the body, using algorithms to improve the result and more!
@@ -50,7 +50,7 @@

- Change the size of the body parts to your liking.
- Use different scale methods or additional algorithms to improve the result.
- Set additional photo runs with random or progressive preferences.
- Set additional photo runs with random or increased preferences.
- More!

- title: Get better results.
@@ -63,9 +63,17 @@
content: |-
Is your photo not giving good results? Changing and experimenting with the photo preferences can help a lot:

- **Scale method:** The `Crop` and `Overlay` options usually give the best results but each photo is unique and other options can help more.
- **Scale method:** The `Crop` and `Overlay` options usually give the best results.
- **Crop position:** If you are using `Crop`, `Overlay` or `Color Padding` the position of the crop tool can be the key to a good result, even moving it a few pixels can make a difference.

And remember the photos that work best:

- Only one person in the photo.
- Less clothing as possible. Bikinis work better.
- Body facing the camera.
- Person standing in a straight position without crossing arms or legs.
- Body visible and unobstructed.


- title: Preferences Mode.
photo: preferences-mode
@@ -77,10 +85,12 @@
content: |-
Preferences mode allows you to increase or decrease the number of options depending on your style or experience using the application.

- **Minimal:** Only options for body personalization. Everything will be adjusted to make the process totally automatic.
- **Simple:** Same as Minimal. Allows you to change the Scale mode.
- **Normal:** All options available, this is the original DreamTime experience.
- **Advanced:** Custom masks mode. The results interface changes to work with each mask, this mode requires time and experience making manual modifications to the photos but can improve the results dramatically.
- **Minimal**: Only the body preferences are shown, all other options will be set to make the process as automatic as possible.
- **Simple**: Same as Minimal but you can change the `Scale method`.
- **Normal**: All options available, this is the original DreamTime experience.
- **Custom masks**: Advanced mode that requires experience and time. In this mode you will work with the masks generated by the algorithm making manual modifications to each one of them, this allows to drastically improve the quality of the fake nude if it is done correctly.
- The `Nudify` or `Start` buttons are disabled for the photo since the masks must be generated one by one.
- The `Per run` preferences are disabled.

- title: Custom masks.
photo: masks
@@ -88,9 +98,9 @@
- text: Guide
href: https://dreamtime.tech/docs/guide/custom-masks
summary: |-
The custom masks or "advanced mode" allows you to obtain results that only a human could create!
The custom masks allows you to obtain results that only a human could create!
content: |-
With the custom masks or "advanced mode" you can work with the masks generated by the algorithm and obtain results that DreamPower alone is not capable of.
With the custom masks mode you can work with the masks generated by the algorithm and obtain results that DreamPower alone is not capable of.

Visit the guide to get all the information and tips necessary to start using this mode!

@@ -100,7 +110,7 @@
- text: Go to settings
href: /settings
- text: Report ad
href: https://time.dreamnet.tech/docs/support/feedback#others
href: https://dreamtime.tech/docs/support/feedback#others
summary: |-
Now you can find help tips and ads in this space. You can enable or disable this behavior in the settings.
content: |-
@@ -108,15 +118,23 @@

You can enable or disable this behavior in the settings.

- The ads displayed are controlled by DreamNet and is a way to support us and continue the development of the application.

- title: Create nudes of videos!
- title: Video nudification.
photo: videos
summary: |-
Don't just stay with static photos, you can also nudify gifs, webm and mp4 videos!
content: |-
With DreamTime you can nudify gifs, webm and mp4 videos, from the Internet or by uploading the files to the application.

**Be sure to use short duration videos, otherwise prepare to meet the RAM eating beast.**

**Be sure to use short duration videos, otherwise prepare to meet the memory eating beast.**

- title: Technical support.
photo: support
buttons:
- text: Go to chat
href: https://chat.dreamnet.tech
- text: More contact options
href: https://dreamtime.tech/docs/support/feedback
summary: |-
Something not working? Have you found a bug? Use our chat or communicate with a developer easily.
content: |-
Whether you have a problem or just want to talk to other people who use the application, our contact channels are available to everyone.

+ 72
- 33
src/modules/config/settings.yml View File

@@ -5,7 +5,8 @@

- id: app.disableHardwareAcceleration
label: Hardware acceleration.
description: Can improve performance on some devices. *Requires restart to take effect.
description: Can improve performance on some devices.<br>* Requires restart to take effect.
tooltip: Use your GPU to speed up the application performance. (Not the nudification algorithm)
input: select
options:
- label: Disabled
@@ -16,6 +17,10 @@
- id: app.uploadMode
label: Upload mode.
description: The uploaded photos will be added to the selected section.
tooltip: |-
- **Pending:** The photos will keep waiting to be configured and nudified.
- **Pending -> Preferences:** When uploading a photo it will be placed in `Pending` and then you will be transferred to the preferences of the photo, in case of uploading multiple photos you will be transferred to the preferences of the last photo.
- **Queue:** The uploaded photos will be placed in the queue where they will be nudified as soon as possible.
input: select
options:
- label: Pending
@@ -28,6 +33,8 @@
- id: app.duplicates
label: Allow duplicates.
description: Allow the upload of the same photo multiple times.
tooltip: |-
With this you can upload a photo multiple times and set different preferences or crop areas without having to wait, this will also make the photos show a unique identification to be able to differentiate.
input: select
options:
- label: Enabled
@@ -47,7 +54,8 @@

- id: app.showAds
label: Show Ads.
description: Show ads at the bottom of the menu. This is a way to support the development of DreamTime.
description: Show ads at the bottom of the menu.
tooltip: Allowing ads helps DreamTime development. These ads are selected by DreamNet.
input: select
options:
- label: Enabled
@@ -68,6 +76,12 @@
- id: preferences.advanced.device
label: Device.
description: GPU is faster but depends on the device VRAM. CPU is slower but uses system RAM.
tooltip: |-
Nudification times:
---

- **NVIDIA GPU:** Between 5 and 60 seconds.
- **CPU:** Between 1 and 15 minutes.
input: select
options:
- label: CPU
@@ -81,7 +95,7 @@

- id: processing.cores
label: CPU Cores.
description: "Using more cores increases the nudification speed for GIFs and videos but decrease stability. Recommended: 1"
description: "Using more cores increases the nudification speed for GIFs and videos but decrease system stability.<br>Recommended: 1"
input: input

- id: processing.usePython
@@ -96,7 +110,14 @@

- id: preferences.mode
label: Preferences Mode.
description: Complexity of options for the photo.
description: Complexity of options.
tooltip: |-
- **Minimal**: Only the body preferences are shown, all other options will be set to make the process as automatic as possible.
- **Simple**: Same as Minimal but you can change the `Scale method`.
- **Normal**: All options available, this is the original DreamTime experience.
- **Custom masks**: Advanced mode that requires experience and time. In this mode you will work with the masks generated by the algorithm making manual modifications to each one of them, this allows to drastically improve the quality of the fake nude if it is done correctly.
- The `Nudify` or `Start` buttons are disabled for the photo since the masks must be generated one by one.
- The `Per run` preferences are disabled.
input: select
options:
- label: Minimal
@@ -117,7 +138,15 @@

- id: preferences.advanced.scaleMode
label: Scale method.
description: Indicates how the photo will be scaled.
description: Indicates how the photo will be scaled to a size compatible with the algorithm.
tooltip: |-
- **None:** The algorithm will be forced to process the photo using an approximation of its original size. Please note that this option can considerably increase memory consumption and return worse results.
- **Automatic Resize:** The algorithm will resize the photo without maintaining the aspect ratio.
- **Automatic Padding:** The algorithm will resize the photo while maintaining the aspect ratio.
- **Automatic Crop:** The algorithm will crop the photo while maintaining the aspect ratio.
- **Overlay:** Allows you to select which area of the photo you want to crop, nudify and then restore to the original photo. This tool makes the photos keep their original size.
- **Crop:** Allows you to crop the photo manually. (Like in DeepNude)
- **Color padding:** This method tricks the algorithm into avoiding the color change that occurs during nudification but sacrificing photo and fake nude quality.
input: select
options:
- label: None
@@ -144,38 +173,37 @@
- label: "Automatic Crop"
value: auto-resize-crop

- id: preferences.body.executions
label: Runs.
description: Number of times the photo will be nudified.
input: input
attrs:
type: number
min: 1

- id: preferences.body.randomize
label: Randomize.
description: Set random body preferences at each run.
- id: preferences.body.runs.mode
label: Mode.
description: How the body preferences will be changed in each run.
tooltip: |-
- **Randomize:** Each run will have random body preferences.
- **Increase by Step:** Each run will increase the body preferences by the specified step.
input: select
options:
- label: Enabled
value: true
- label: Disabled
value: false
- label: Randomize
value: randomize
- label: Increase by Step
value: increase

- id: preferences.body.progressive.enabled
label: Progressive.
description: Body preferences increase.
input: select
options:
- label: Enabled
value: true
- label: Disabled
value: false
- id: preferences.body.runs.count
label: Count.
description: Number of times the photo will be nudified.
input: input
attrs:
type: number
min: 2

- id: preferences.body.progressive.rate
label: Progressive rate.
description: Rate.
- id: preferences.body.runs.rate
label: Step.
input: input
attrs:
type: number
min: 0.1
step: 0.1
max: 2

- id: preferences.advanced.useColorPaddingStrip
label: Color Padding Removal.
@@ -199,7 +227,7 @@

- id: preferences.advanced.imageSize
label: Image size.
description: Photo scale size. Larger sizes requires more RAM and can produce less satisfactory results.
description: Sets the internal size of the photo that the algorithm will accept. Sizes other than 512x512 can consume more memory and give worse results.
input: select
options:
- label: 256x256
@@ -215,7 +243,7 @@

- id: preferences.advanced.compress
label: Compression level.
description: Compress the photo sacrificing quality but reducing RAM consumption.
description: High level of compression sacrifices quality for less memory consumption.
input: select
options:
- label: Disabled
@@ -229,7 +257,7 @@

- id: preferences.advanced.waifu.enabled
label: Waifu2X.
description: Use the algorithm to upscale & denoise the nudified photo.
description: Use the algorithm to upscale & denoise the fake nude.
input: select
options:
- label: Enabled
@@ -340,6 +368,11 @@
- id: telemetry.bugs
label: Error report.
description: Allow to report errors automatically.
tooltip: |-
- Operating system.
- CPU, RAM and GPU.
- User settings.
- Console log.
input: select
options:
- label: Enabled
@@ -350,6 +383,12 @@
- id: telemetry.dom
label: Session tracking.
description: Allow to send information about how you use the application. (No sensitive information or photos will be sent)
tooltip: |-
- Operating system.
- CPU, RAM and GPU.
- User settings.
- Console log.
- Actions inside the application. (Photos and sensitive information are censored.)
input: select
options:
- label: Enabled

+ 2
- 2
src/modules/nudify/nudify.js View File

@@ -268,11 +268,11 @@ export const Nudify = {
async forgetAll(status = 'pending') {
const response = await Swal.fire({
title: 'Are you sure?',
text: 'Forgetting will remove all photos from the queue (it will not delete the files) and free up memory.',
text: 'All photos in this section will be removed.',
icon: 'warning',
showCancelButton: true,
confirmButtonColor: '#F44336',
confirmButtonText: 'Yes, forget it',
confirmButtonText: 'Yes, remove all',
})

if (!response.value) {

+ 23
- 11
src/modules/nudify/photo-run.js View File

@@ -79,6 +79,11 @@ export class PhotoRun {
*/
algorithmStatus = ALGORITHM.NONE

/**
* @type {string}
*/
frameStatus

/**
* @type {Boolean}
*/
@@ -193,10 +198,8 @@ export class PhotoRun {
if (mode === PMODE.MINIMAL || mode === PMODE.SIMPLE) {
this.preferences = merge(this.preferences, {
body: {
executions: 1,
randomize: false,
progressive: {
enabled: false,
runs: {
mode: false,
},
},
advanced: {
@@ -216,11 +219,11 @@ export class PhotoRun {
}

if (mode !== PMODE.ADVANCED) {
// Body randomize/progresive.
// Body randomize/increase.
const { body } = this.preferences

if (body.randomize) {
// randomize.
if (body.runs.mode === 'randomize') {
// Randomize.
forIn(preferencesConfig, (payload, key) => {
const { enabled, min, max } = body[key].randomize

@@ -228,9 +231,9 @@ export class PhotoRun {
body[key].size = random(min, max, true)
}
})
} else if (body.progressive.enabled) {
// progressive.
const add = body.progressive.rate * (this.id - 1)
} else if (body.runs.mode === 'increase') {
// Increase by Step.
const add = body.runs.rate * (this.id - 1)

forIn(preferencesConfig, (payload, key) => {
if (body[key].progressive) {
@@ -288,6 +291,7 @@ export class PhotoRun {
}

this.algorithmStatus = ALGORITHM.NONE
this.frameStatus = undefined
}

runNudification() {
@@ -317,7 +321,15 @@ export class PhotoRun {
this.process.on('stdout', (output) => {
// DreamPower output.
output.forEach((text) => {
text = toString(text)
text = trim(toString(text))

if (this.photo.file.isAnimated && text.includes('Multiple Image Processing')) {
const frameDetect = text.match(/^(.*) : ([0-9]*)\/([0-9]*)$/)

if (frameDetect && frameDetect[2] && frameDetect[3]) {
this.frameStatus = `${frameDetect[2]}/${frameDetect[3]}`
}
}

this.cli.lines.unshift({
text,

+ 44
- 4
src/modules/nudify/photo.js View File

@@ -296,7 +296,15 @@ export class Photo {
* @readonly
*/
get runsCount() {
return this.mode === PMODE.ADVANCED ? 1 : this.preferences.body.executions
if (this.mode === PMODE.ADVANCED) {
return 1
}

if (this.preferences.body.runs.mode !== false) {
return this.preferences.body.runs.count
}

return 1
}

/**
@@ -384,6 +392,38 @@ export class Photo {
return scaleMode !== this.scaleMode
}

get scaleModeName() {
switch (this.preferences.advanced.scaleMode) {
case 'overlay':
return 'Overlay'

case 'cropjs':
return 'Crop'

case 'padding':
return 'Padding'

default:
return 'Automatic'
}
}

get scaleModeURL() {
switch (this.preferences.advanced.scaleMode) {
case 'overlay':
return `/nudify/${this.id}/overlay`

case 'cropjs':
return `/nudify/${this.id}/crop`

case 'padding':
return `/nudify/${this.id}/padding`

default:
return `/nudify/${this.id}`
}
}

/**
*
*
@@ -868,7 +908,7 @@ export class Photo {
track() {
const { mode } = this.preferences
const { useColorTransfer } = this.preferences.advanced
const { randomize, progressive } = this.preferences.body
const { mode: runsMode } = this.preferences.body.runs

consola.track('DREAM_START', { mode })

@@ -876,11 +916,11 @@ export class Photo {
consola.track('DREAM_COLOR_TRANSFER')
}

if (randomize) {
if (runsMode === 'randomize') {
consola.track('DREAM_RANDOMIZE')
}

if (progressive.enabled) {
if (runsMode === 'increase') {
consola.track('DREAM_PROGRESSIVE')
}
}

+ 1
- 1
src/modules/timer.js View File

@@ -47,7 +47,7 @@ export class Timer {
update() {
this.duration = dayjs().diff(this.startTime, 'second')

if (this.duration > 10800) {
if (this.duration === 54001) {
// This does not seem normal.
consola.warn('Timer out of control.').report()
this.stop()

+ 9
- 4
src/modules/updater/base.js View File

@@ -68,6 +68,11 @@ export class BaseUpdater {
*/
http

/**
* @type {Array}
*/
releases = []

/**
* @type {Object}
*/
@@ -367,18 +372,18 @@ export class BaseUpdater {
const response = await this.http.get('/releases')

// only final releases
const releases = filter(response.data, {
this.releases = filter(response.data, {
draft: false,
prerelease: false,
})

if (releases.length === 0) {
if (this.releases.length === 0) {
throw new Exception('Github has returned that there are no releases!')
}

// eslint-disable-next-line prefer-destructuring
this.latest = releases[0]
this.latestCompatible = this._getLatestCompatible(releases)
this.latest = this.releases[0]
this.latestCompatible = this._getLatestCompatible(this.releases)

if (isNil(this.latestCompatible)) {
throw new Exception('Unable to fetch the latest compatible version.')

+ 5
- 0
src/modules/updater/checkpoints.js View File

@@ -7,6 +7,7 @@
//
// Written by Ivan Bravo Bravo <ivan@dreamnet.tech>, 2019.

import { isString } from 'lodash'
import { BaseUpdater } from './base'
import { requirements } from '../system'

@@ -46,6 +47,10 @@ class CheckpointsUpdater extends BaseUpdater {

const version = read(filepath) || 'v0.0.1'

if (!isString(version)) {
return 'v0.0.1'
}

return version.trim()
}


+ 1
- 1
src/nuxt.config.js View File

@@ -9,7 +9,7 @@ module.exports = {
/**
*
*/
mode: 'spa',
ssr: false,

/**
* Deployment target

+ 38
- 37
src/package.json View File

@@ -3,7 +3,7 @@
"private": true,
"displayName": "DreamTime",
"description": "Application that uses artificial intelligence to generate fake nudes.",
"version": "1.5.6",
"version": "1.5.7",
"homepage": "https://time.dreamnet.tech",
"main": "electron/dist/index.js",
"license": "GPL-3.0-only",
@@ -46,72 +46,72 @@
"@fortawesome/free-brands-svg-icons": "^5.14.0",
"@fortawesome/free-regular-svg-icons": "^5.14.0",
"@fortawesome/free-solid-svg-icons": "^5.14.0",
"@fortawesome/vue-fontawesome": "^0.1.10",
"@fortawesome/vue-fontawesome": "^2.0.0",
"@imagemagick/magick-wasm": "^0.0.3",
"@sweetalert2/theme-dark": "^3.2.0",
"axios": "^0.19.2",
"@sweetalert2/theme-dark": "^4.0.0",
"axios": "^0.20.0",
"chokidar": "^3.4.2",
"combokeys": "^3.0.1",
"compare-versions": "^3.6.0",
"cropperjs": "^1.5.7",
"cropperjs": "^1.5.9",
"cryptr": "^6.0.2",
"dayjs": "^1.8.33",
"dayjs": "^1.8.36",
"deferred": "^0.7.11",
"delay": "^4.4.0",
"electron-context-menu": "^2.3.0",
"electron-devtools-installer": "^3.1.1",
"electron-util": "^0.14.2",
"emoji-strip": "^1.0.1",
"eventemitter3": "^4.0.4",
"fabric": "^3.6.3",
"eventemitter3": "^4.0.7",
"fabric": "^4.1.0",
"filesize": "^6.1.0",
"form-data": "^3.0.0",
"fs-extra": "^9.0.1",
"go-ipfs-dep": "^0.6.0",
"go-ipfs-dep": "^0.7.0",
"he": "^1.2.0",
"instagram-save": "^1.3.2",
"intro.js": "^2.9.3",
"ipfs": "^0.49.0",
"ipfs-http-client": "^44.0.3",
"ipfsd-ctl": "^4.1.0",
"ipfs": "^0.50.2",
"ipfs-http-client": "^47.0.1",
"ipfsd-ctl": "^7.0.1",
"is-online": "^8.4.0",
"it-all": "^1.0.2",
"it-all": "^1.0.4",
"it-to-stream": "^0.1.2",
"js-event-bus": "^1.0.3",
"js-yaml": "^3.14.0",
"lodash": "^4.17.20",
"logrocket": "^1.0.11",
"markdown-it": "^11.0.0",
"logrocket": "^1.0.13",
"markdown-it": "^11.0.1",
"md5-file": "^5.0.0",
"melanke-watchjs": "^1.5.2",
"mime-types": "^2.1.27",
"node-7z": "^2.1.1",
"normalize-path": "^3.0.0",
"nuxt": "^2.14.3",
"nuxt": "^2.14.6",
"patch-package": "^6.2.2",
"popmotion": "^8.7.3",
"popmotion": "^8.7.5",
"portal-vue": "^2.1.7",
"postinstall-postinstall": "^2.1.0",
"promise-worker": "^2.0.1",
"randomcolor": "^0.6.2",
"regedit": "^3.0.3",
"rollbar": "^2.19.2",
"rollbar": "^2.19.3",
"semver-regex": "^3.1.1",
"slash": "^3.0.0",
"sourcemapped-stacktrace": "^1.1.11",
"sweetalert2": "^9.17.1",
"systeminformation": "^4.26.10",
"sweetalert2": "^10.3.5",
"systeminformation": "^4.27.5",
"tippy.js": "^6.2.6",
"tui-image-editor": "3.9.0",
"unique-names-generator": "^4.3.0",
"unique-names-generator": "^4.3.1",
"unzipper": "^0.10.11",
"uuid": "^8.3.0",
"vue-slider-component": "^3.2.4",
"vue-slider-component": "^3.2.5",
"webtorrent": "^0.108.6"
},
"devDependencies": {
"@babel/cli": "^7.10.5",
"@babel/core": "^7.11.1",
"@babel/cli": "^7.11.6",
"@babel/core": "^7.11.6",
"@babel/plugin-proposal-class-properties": "^7.10.4",
"@babel/plugin-proposal-export-default-from": "^7.10.4",
"@babel/plugin-proposal-optional-chaining": "^7.11.0",
@@ -120,45 +120,46 @@
"@nuxtjs/eslint-config": "^3.1.0",
"@nuxtjs/eslint-module": "^2.0.0",
"@nuxtjs/style-resources": "^1.0.0",
"@nuxtjs/tailwindcss": "^3.0.0",
"@nuxtjs/tailwindcss": "^3.1.0",
"babel-eslint": "^10.1.0",
"babel-plugin-lodash": "^3.3.4",
"babel-plugin-module-resolver": "^4.0.0",
"babel-plugin-transform-inline-environment-variables": "^0.4.3",
"babel-watch": "^7.0.0",
"cross-env": "^7.0.2",
"electron": "9.2.1",
"electron-builder": "^22.8.0",
"electron": "10.1.2",
"electron-builder": "^22.8.1",
"env-cmd": "^10.1.0",
"eslint": "^7.7.0",
"eslint": "^7.9.0",
"eslint-config-airbnb-base": "^14.2.0",
"eslint-config-standard": ">=14.1.1",
"eslint-import-resolver-node": "^0.3.4",
"eslint-import-resolver-nuxt": "^1.0.1",
"eslint-import-resolver-webpack": "^0.12.2",
"eslint-plugin-import": ">=2.22.0",
"eslint-plugin-jest": ">=23.20.0",
"eslint-plugin-jest": ">=24.0.2",
"eslint-plugin-lodash": "^7.1.0",
"eslint-plugin-mocha": "^7.0.1",
"eslint-plugin-mocha": "^8.0.0",
"eslint-plugin-node": ">=11.1.0",
"eslint-plugin-nuxt": ">=1.0.0",
"eslint-plugin-promise": ">=4.2.1",
"eslint-plugin-standard": ">=4.0.1",
"eslint-plugin-vue": "^6.2.2",
"fibers": "^5.0.0",
"husky": "^4.2.5",
"husky": "^4.3.0",
"js-yaml-loader": "^1.2.2",
"lint-staged": "^10.2.11",
"mocha": "^8.1.0",
"lint-staged": "^10.4.0",
"mocha": "^8.1.3",
"modclean": "^3.0.0-beta.1",
"ndjson-parse": "^1.0.4",
"ngrok": "^3.2.7",
"nuxt-purgecss": "^1.0.0",
"sass": "^1.26.10",
"sass-loader": "^9.0.3",
"sass": "^1.26.11",
"sass-loader": "^10.0.2",
"sha256-file": "^1.0.0",
"shx": "^0.3.2",
"spectron": "^11.1.0",
"tailwindcss": "1.6.3",
"spectron": "^12.0.0",
"tailwindcss": "1.8.10",
"tailwindcss-alpha": "hacknug/tailwindcss-alpha#feature/tests",
"worker-loader": "^2.0.0"
},

+ 1
- 1
src/package.min.json View File

@@ -3,7 +3,7 @@
"private": true,
"displayName": "DreamTime",
"description": "Application that uses artificial intelligence to generate fake nudes.",
"version": "1.5.6",
"version": "1.5.7",
"main": "electron/dist/index.js",
"license": "GPL-3.0-only"
}

+ 55
- 0
src/pages/about/changelog.vue View File

@@ -0,0 +1,55 @@
<template>
<div class="changelog">
<PageHeader>
<h2 class="title">
<span class="icon"><font-awesome-icon icon="book" /></span>
<span>{{ $dreamtime.name }} Changelog</span>
</h2>
</PageHeader>

<AppBox
v-for="release in releases"
:key="release.name"
:title="release.name"
:content="release.body" />
</div>
</template>

<script>
import { take } from 'lodash'

export default {
computed: {
releases() {
return take(this.$dreamtime.updater.releases, 5)
},
},
}
</script>

<style lang="scss" scoped>
.changelog {

&::v-deep {
h3 {
@apply text-lg text-white font-semibold mb-3;
}

ul {
@apply list-disc;

&:not(:last-child) {
@apply mb-6;
}

li {
@apply text-sm ml-6;

&:not(:last-child) {
@apply mb-1;
}
}
}
}
}
</style>

+ 1
- 1
src/pages/about/dreamnet.vue View File

@@ -72,7 +72,7 @@ export default {
}

.community__sections {
@apply grid grid-cols-2 col-gap-6;
@apply grid grid-cols-2 gap-x-6;
}

.box--community {

+ 6
- 0
src/pages/about/dreamtime.vue View File

@@ -26,6 +26,12 @@
<!-- Updater -->
<AppUpdate :project="$dreamtime" href="/wizard/dreamtime" />

<MenuItem
label="Changelog"
description="Look at the changes that have happened between versions."
icon="book"
href="/about/changelog" />

<!-- Remote navigation -->
<MenuItem
v-for="(item, index) in $dreamtime.data.about.navigation"

+ 5
- 3
src/pages/nudify/_id.vue View File

@@ -69,7 +69,7 @@
<button
v-if="photo.finished && photo.runsCount > 1"
key="save-all"
v-tooltip="{content: 'Save all the nudes.', placement: 'right'}"
v-tooltip="{content: 'Save all the fake nudes.', placement: 'right'}"
class="button button--info"
@click.prevent="saveAll">
<span class="icon"><font-awesome-icon icon="save" /></span>
@@ -80,8 +80,10 @@
<button
v-if="photo.waiting"
key="cancel"
v-tooltip="{content: 'Remove the photo from the queue.', placement: 'right'}"
class="button button--danger"
@click.prevent="cancel">
<span class="icon"><font-awesome-icon icon="sign-out-alt" /></span>
<span>Cancel</span>
</button>

@@ -99,13 +101,13 @@
<button
id="nudify-forget"
v-tooltip="{
content: 'Free memory by removing the photo from the application. (Nudified photos will not be deleted)',
content: 'Remove the photo from the application and free up memory. (Fake nudes files will not be removed)',
placement: 'right',
boundary: 'viewport'}"
class="button"
@click.prevent="forget">
<span class="icon"><font-awesome-icon icon="trash-alt" /></span>
<span>Forget</span>
<span>Remove</span>
</button>
</section>
</portal>

+ 3
- 1
src/pages/nudify/_id/results.vue View File

@@ -51,7 +51,9 @@

<div v-if="photo.isScaleModeCorrected && !photo.pending" class="notification notification--warning">
<span class="icon"><font-awesome-icon icon="exclamation-triangle" /></span>
You have selected the scale method <strong>{{ photo.preferences.advanced.scaleMode }}</strong> but have not used the tool! <strong>Automatic Resize</strong> will be used instead.
The <strong>{{ photo.scaleModeName }}</strong> scale method has been selected but the tool has not been used, this will generate lower quality fake nudes. <nuxt-link :to="photo.scaleModeURL">
Please use the tool
</nuxt-link>.
</div>

<!-- Custom Masks -->

+ 0
- 14
src/pages/settings/app.vue View File

@@ -36,20 +36,6 @@
Please move the application to another place.
</span>
</div>

<!-- GPU -->
<div v-if="$settings.preferences.advanced.device === 'GPU'">
<div v-if="!requirements.recommended.vram" class="notification notification--warning">
<span class="icon"><font-awesome-icon icon="exclamation-triangle" /></span>
<span>Your NVIDIA GPU has very low VRAM! The algorithm is very likely to fail.</span>
</div>
</div>

<!-- RAM -->
<div v-if="!requirements.recommended.ram" class="notification notification--warning">
<span class="icon"><font-awesome-icon icon="exclamation-triangle" /></span>
<span>Your system has less than <strong>12 GB</strong> of RAM.</span>
</div>
</div>

<section class="box">

+ 1
- 1
src/pages/settings/preferences.vue View File

@@ -20,7 +20,7 @@

<AppNotification v-if="value$.preferences.mode === 3" name="advanced-mode" class="notification--info">
<span class="icon"><font-awesome-icon icon="exclamation-triangle" /></span>
<span>Custom masks mode is recommended only for experienced users. <a href="https://dreamtime.tech/docs/guide/custom-masks/" target="_blank">Click here to visit the guide</a>.</span>
<span>Custom masks mode is recommended only for experienced users. Are you sure this is the mode you want? You can get more information <a href="https://dreamtime.tech/docs/guide/custom-masks/" target="_blank">here</a>.</span>
</AppNotification>

<SettingsPreferences v-model="value$.preferences" />

+ 20
- 1
src/pages/settings/processing.vue View File

@@ -7,7 +7,7 @@
</h2>

<h3 class="subtitle">
Settings that affect the use of resources for the nudification.
Settings that affect the performance of the nudification algorithm.
</h3>

<template v-slot:right>
@@ -17,6 +17,20 @@
</template>
</PageHeader>

<!-- GPU -->
<div v-if="$settings.preferences.advanced.device === 'GPU'">
<div v-if="!requirements.recommended.vram" class="notification notification--warning">
<span class="icon"><font-awesome-icon icon="exclamation-triangle" /></span>
<span>Your NVIDIA GPU has low VRAM! It is very possible that the nudification fails.</span>
</div>
</div>

<!-- RAM -->
<div v-if="!requirements.recommended.ram" class="notification notification--warning">
<span class="icon"><font-awesome-icon icon="exclamation-triangle" /></span>
<span>Your system has less than <strong>12 GB</strong> of RAM. It is very possible that the nudification fails.</span>
</div>

<AppNotification name="device-change">
The <strong>device</strong> option is now part of the preferences for each photo. If you already have photos in the queue, you should change the device in those photos too.
</AppNotification>
@@ -61,11 +75,16 @@
<script>
import { cloneDeep, merge } from 'lodash'
import Swal from 'sweetalert2/dist/sweetalert2'
import { requirements } from '~/modules/system'
import { VModel } from '~/mixins'

export default {
mixins: [VModel],

data: () => ({
requirements,
}),

computed: {
isMacOS() {
return process.platform === 'darwin'

+ 5
- 12
src/pages/settings/share.vue View File

@@ -119,18 +119,11 @@

<SettingsField v-model="importPreferences" field-id="preferences.advanced.waifu.arch" readonly />

<SettingsField v-model="importPreferences" field-id="preferences.body.executions" readonly />

<SettingsField v-if="importPreferences.body.randomize"
v-model="importPreferences"
field-id="preferences.body.randomize"
readonly />

<SettingsField v-if="importPreferences.body.progressive.enabled && !importPreferences.body.randomize"
v-model="importPreferences"
field-id="preferences.body.progressive.enabled"
:description="`Body preferences will increase ${importPreferences.body.progressive.rate} at each run.`"
readonly />
<SettingsField v-model="importPreferences" field-id="preferences.body.runs.mode" readonly />

<SettingsField v-model="importPreferences" field-id="preferences.body.runs.count" readonly />

<SettingsField v-model="importPreferences" field-id="preferences.body.runs.rate" readonly />

<!-- Boobs -->
<Preference v-if="importPreferences.body.boobs"

+ 1
- 1
src/pages/wizard/checkpoints.vue View File

@@ -20,7 +20,7 @@

<div class="project__content">
<div v-if="!requirements.power.checkpoints" class="notification notification--warning">
This component is required to continue using {{ $dreamtime.name }}.
This component needs to be installed to continue.
</div>

<div v-else class="notification">

+ 0
- 8
src/pages/wizard/dreamtime.vue View File

@@ -36,14 +36,6 @@ import { dreamtime } from '~/modules/updater'
export default {
layout: 'wizard',

middleware({ redirect, route }) {
if (!route.query.forced) {
if (!dreamtime.available) {
redirect('/')
}
}
},

computed: {
updater() {
return dreamtime

+ 67
- 0
src/scripts/chocolatey/dreamtime.nuspec View File

@@ -0,0 +1,67 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Read this before creating packages: https://chocolatey.org/docs/create-packages -->
<!-- It is especially important to read the above link to understand additional requirements when publishing packages to the community feed aka dot org (https://chocolatey.org/packages). -->

<!-- Test your packages in a test environment: https://github.com/chocolatey/chocolatey-test-environment -->

<!--
This is a nuspec. It mostly adheres to https://docs.nuget.org/create/Nuspec-Reference. Chocolatey uses a special version of NuGet.Core that allows us to do more than was initially possible. As such there are certain things to be aware of:

* the package xmlns schema url may cause issues with nuget.exe
* Any of the following elements can ONLY be used by choco tools - projectSourceUrl, docsUrl, mailingListUrl, bugTrackerUrl, packageSourceUrl, provides, conflicts, replaces
* nuget.exe can still install packages with those elements but they are ignored. Any authoring tools or commands will error on those elements
-->

<!-- You can embed software files directly into packages, as long as you are not bound by distribution rights. -->
<!-- * If you are an organization making private packages, you probably have no issues here -->
<!-- * If you are releasing to the community feed, you need to consider distribution rights. -->
<!-- Do not remove this test for UTF-8: if “Ω” doesn’t appear as greek uppercase omega letter enclosed in quotation marks, you should use an editor that supports UTF-8, not this one. -->
<package xmlns="http://schemas.microsoft.com/packaging/2015/06/nuspec.xsd">
<metadata>
<!-- == PACKAGE SPECIFIC SECTION == -->
<id>dreamtime</id>
<version>1.5.7</version>
<packageSourceUrl>https://github.com/dreamnettech/dreamtime</packageSourceUrl>
<owners>Ivan Bravo Bravo [ivan@dreamnet.tech]</owners>
<!-- == SOFTWARE SPECIFIC SECTION == -->
<title>DreamTime (Install)</title>
<authors>Ivan Bravo Bravo [ivan@dreamnet.tech]</authors>
<projectUrl>https://dreamtime.tech/</projectUrl>
<iconUrl>https://raw.githubusercontent.com/dreamnettech/dreamtime/master/src/build/icon.ico</iconUrl>
<copyright>Copyright (C) DreamNet. All rights reserved.</copyright>
<licenseUrl>https://raw.githubusercontent.com/dreamnettech/dreamtime/master/LICENSE</licenseUrl>
<requireLicenseAcceptance>true</requireLicenseAcceptance>
<projectSourceUrl>https://github.com/dreamnettech/dreamtime</projectSourceUrl>
<docsUrl>https://dreamtime.tech/docs/development/getting-started</docsUrl>
<!--<mailingListUrl></mailingListUrl>-->
<bugTrackerUrl>https://github.com/dreamnettech/dreamtime/issues</bugTrackerUrl>
<tags>dreamtime dreampower dreamnet deepnude</tags>
<summary>Use artificial intelligence to create fake nudes.</summary>
<description>DreamTime is an application that allows you to easily create fake nudes from a photo using artificial intelligence.

DreamTime's user interface has been created from scratch and is far superior to DeepNude. DreamTime also uses an improved version of the DeepNude algorithm that generates better results.</description>
<!-- Specifying dependencies and version ranges? https://docs.nuget.org/create/versioning#specifying-version-ranges-in-.nuspec-files -->
<!--<dependencies>
<dependency id="" version="__MINIMUM_VERSION__" />
<dependency id="" version="[__EXACT_VERSION__]" />
<dependency id="" version="[_MIN_VERSION_INCLUSIVE, MAX_VERSION_INCLUSIVE]" />
<dependency id="" version="[_MIN_VERSION_INCLUSIVE, MAX_VERSION_EXCLUSIVE)" />
<dependency id="" />
<dependency id="chocolatey-core.extension" version="1.1.0" />
</dependencies>-->
<!-- chocolatey-core.extension - https://chocolatey.org/packages/chocolatey-core.extension
- You want to use Get-UninstallRegistryKey on less than 0.9.10 (in chocolateyUninstall.ps1)
- You want to use Get-PackageParameters and on less than 0.11.0
- You want to take advantage of other functions in the core community maintainer's team extension package
-->

<!--<provides>NOT YET IMPLEMENTED</provides>-->
<!--<conflicts>NOT YET IMPLEMENTED</conflicts>-->
<!--<replaces>NOT YET IMPLEMENTED</replaces>-->
</metadata>
<files>
<!-- this section controls what actually gets packaged into the Chocolatey package -->
<file src="tools\**" target="tools" />
<!--Building from Linux? You may need this instead: <file src="tools/**" target="tools" />-->
</files>
</package>

+ 11
- 0
src/scripts/chocolatey/tools/LICENSE.txt View File

@@ -0,0 +1,11 @@

Note: Include this file if including binaries you have the right to distribute.
Otherwise delete. this file.

===DELETE ABOVE THIS LINE AND THIS LINE===

From: <insert applicable license url here>

LICENSE

<Insert License Here>

+ 13
- 0
src/scripts/chocolatey/tools/VERIFICATION.txt View File

@@ -0,0 +1,13 @@

Note: Include this file if including binaries you have the right to distribute.
Otherwise delete. this file. If you are the software author, you can change this
mention you are the author of the software.

===DELETE ABOVE THIS LINE AND THIS LINE===

VERIFICATION
Verification is intended to assist the Chocolatey moderators and community
in verifying that this package's contents are trustworthy.
<Include details of how to verify checksum contents>
<If software vendor, explain that here - checksum verification instructions are optional>

+ 9
- 0
src/scripts/chocolatey/tools/chocolateybeforemodify.ps1 View File

@@ -0,0 +1,9 @@
# This runs in 0.9.10+ before upgrade and uninstall.
# Use this file to do things like stop services prior to upgrade or uninstall.
# NOTE: It is an anti-pattern to call chocolateyUninstall.ps1 from here. If you
# need to uninstall an MSI prior to upgrade, put the functionality in this
# file without calling the uninstall script. Make it idempotent in the
# uninstall script so that it doesn't fail when it is already uninstalled.
# NOTE: For upgrades - like the uninstall script, this script always runs from
# the currently installed version, not from the new upgraded package version.


+ 151
- 0
src/scripts/chocolatey/tools/chocolateyinstall.ps1 View File

@@ -0,0 +1,151 @@
# IMPORTANT: Before releasing this package, copy/paste the next 2 lines into PowerShell to remove all comments from this file:
# $f='c:\path\to\thisFile.ps1'
# gc $f | ? {$_ -notmatch "^\s*#"} | % {$_ -replace '(^.*?)\s*?[^``]#.*','$1'} | Out-File $f+".~" -en utf8; mv -fo $f+".~" $f

# 1. See the _TODO.md that is generated top level and read through that
# 2. Follow the documentation below to learn how to create a package for the package type you are creating.
# 3. In Chocolatey scripts, ALWAYS use absolute paths - $toolsDir gets you to the package's tools directory.
$ErrorActionPreference = 'Stop'; # stop on all errors
$toolsDir = "$(Split-Path -parent $MyInvocation.MyCommand.Definition)"
# Internal packages (organizations) or software that has redistribution rights (community repo)
# - Use `Install-ChocolateyInstallPackage` instead of `Install-ChocolateyPackage`
# and put the binaries directly into the tools folder (we call it embedding)
#$fileLocation = Join-Path $toolsDir 'NAME_OF_EMBEDDED_INSTALLER_FILE'
# If embedding binaries increase total nupkg size to over 1GB, use share location or download from urls
#$fileLocation = '\\SHARE_LOCATION\to\INSTALLER_FILE'
# Community Repo: Use official urls for non-redist binaries or redist where total package size is over 200MB
# Internal/Organization: Download from internal location (internet sources are unreliable)
$url = '' # download url, HTTPS preferred
$url64 = 'https://downloads.dreamnet.tech/dreamtime/v1.5.6/windows?direct=1' # 64bit URL here (HTTPS preferred) or remove - if installer contains both (very rare), use $url

$packageArgs = @{
packageName = $env:ChocolateyPackageName
unzipLocation = $toolsDir
fileType = 'exe' #only one of these: exe, msi, msu
url = $url
url64bit = $url64
#file = $fileLocation

softwareName = 'DreamTime' #part or all of the Display Name as you see it in Programs and Features. It should be enough to be unique