Browse Source

Design improvements, DreamPower v1.2.2 and new features.

tags/v1.4.4
Ivan Bravo Bravo 11 months ago
parent
commit
18ac4499e6
79 changed files with 2980 additions and 1495 deletions
  1. 8
    7
      README.md
  2. 1
    1
      src/.env
  3. 29
    20
      src/.eslintrc.js
  4. 22
    2
      src/assets/css/base/_reset.scss
  5. 37
    13
      src/assets/css/components/_box.scss
  6. 1
    1
      src/assets/css/components/_button.scss
  7. 6
    1
      src/assets/css/components/_container.scss
  8. 2
    2
      src/assets/css/components/_form.scss
  9. 3
    3
      src/assets/css/components/_markdown.scss
  10. 1
    1
      src/assets/css/components/_notification.scss
  11. 1
    1
      src/assets/css/components/_section.scss
  12. 11
    8
      src/components/Form/InlineField.vue
  13. 3
    3
      src/components/Layout/Jobs.vue
  14. 27
    11
      src/components/Layout/Navigation.vue
  15. 47
    29
      src/components/Nudity/Job.vue
  16. 10
    9
      src/components/Nudity/Preview.vue
  17. 290
    0
      src/components/Nudity/Upload.backup.vue
  18. 133
    61
      src/components/Nudity/Upload.vue
  19. 342
    226
      src/components/Settings/SettingsPreferences.vue
  20. 4
    5
      src/components/UI/AppExternalLink.vue
  21. 5
    5
      src/components/UI/AppPhoto.vue
  22. 35
    16
      src/components/UI/AppUpdate.vue
  23. 151
    0
      src/components/UI/BoxItem.vue
  24. 29
    26
      src/components/UI/BoxSectionItem.vue
  25. 2
    0
      src/components/UI/index.js
  26. 24
    34
      src/electron/index.js
  27. 2
    1
      src/electron/modules/index.js
  28. 7
    6
      src/electron/modules/nucleus.js
  29. 10
    9
      src/electron/modules/rollbar.js
  30. 102
    49
      src/electron/modules/settings.js
  31. 3
    1
      src/electron/preload.js
  32. 16
    15
      src/electron/tools/fs.js
  33. 86
    44
      src/electron/tools/index.js
  34. 1
    1
      src/electron/tools/paths.js
  35. 5
    7
      src/electron/tools/shell.js
  36. 66
    0
      src/electron/tools/system.js
  37. 1
    1
      src/layouts/default.vue
  38. 3
    3
      src/middleware/checks.js
  39. 13
    11
      src/middleware/nudity.js
  40. 4
    4
      src/mixins/BaseMixin.js
  41. 10
    10
      src/mixins/VModel.js
  42. 6
    1
      src/modules/config/cli-errors.json
  43. 1
    1
      src/modules/dream.js
  44. 1
    1
      src/modules/file.js
  45. 1
    3
      src/modules/helpers.js
  46. 45
    77
      src/modules/models/photo-job.js
  47. 43
    75
      src/modules/models/photo.js
  48. 1
    1
      src/modules/nudify.js
  49. 39
    24
      src/modules/platform.js
  50. 50
    44
      src/modules/update/base.js
  51. 8
    4
      src/modules/update/checkpoints.js
  52. 24
    23
      src/modules/update/dreampower.js
  53. 3
    3
      src/modules/update/dreamtime.js
  54. 10
    12
      src/modules/updater.js
  55. 6
    6
      src/modules/web-error.js
  56. 18
    10
      src/nuxt.config.js
  57. 14
    8
      src/package.json
  58. 2
    2
      src/pages/index.vue
  59. 7
    6
      src/pages/models/add.vue
  60. 3
    2
      src/pages/models/index.vue
  61. 80
    0
      src/pages/nudify.vue
  62. 27
    17
      src/pages/nudify/crop.backup.vue
  63. 471
    0
      src/pages/nudify/crop.vue
  64. 21
    0
      src/pages/nudify/preferences.vue
  65. 172
    0
      src/pages/nudify/results.vue
  66. 67
    0
      src/pages/nudify/summary.vue
  67. 0
    190
      src/pages/nudity/results.vue
  68. 0
    112
      src/pages/nudity/settings.vue
  69. 35
    28
      src/pages/system/about.vue
  70. 24
    16
      src/pages/system/settings.vue
  71. 46
    40
      src/pages/system/settings/folders.vue
  72. 40
    27
      src/pages/system/settings/notifications.vue
  73. 4
    2
      src/pages/system/settings/preferences.vue
  74. 65
    25
      src/pages/system/settings/processing.vue
  75. 17
    13
      src/pages/system/settings/telemetry.vue
  76. 13
    7
      src/pages/system/welcome.vue
  77. 15
    9
      src/plugins/boot.client.js
  78. 2
    10
      src/scripts/release.js
  79. 46
    49
      src/tailwind.config.js

+ 8
- 7
README.md View File

@@ -46,37 +46,38 @@ Do you have any problem? Doubts? or you are simply interested in chatting with t

---

# ๐Ÿ’œ Binaries
# ๐Ÿ’œ Releases

## Requirements

- 64 bits OS
- Windows 7 SP1, Windows 8, Windows 10 1803+
- Ubuntu 16.04+
- macOS 10.13+
- macOS Catalina 10.15+
- **8 GB+** of RAM.

> โš  **N versions of Windows 10** require installing the [Media Feature Pack](https://www.microsoft.com/en-us/software-download/mediafeaturepack).

### GPU Processing

- NVIDIA Graphics card with minimum [3.5 CUDA compute capability.](https://developer.nvidia.com/cuda-gpus)
- NVIDIA GPU with minimum [3.5 CUDA compute capability.](https://developer.nvidia.com/cuda-gpus)
- [Latest NVIDIA drivers.](https://www.nvidia.com/Download/index.aspx)

> ๐Ÿ‘‰ If you do not have an NVIDIA or compatible graphics card you can use CPU processing.
> ๐Ÿ‘‰ If you do not have an NVIDIA or compatible GPU you can use CPU processing.

## Download

> ๐Ÿ’• [Patrons](https://www.patreon.com/dreamnet) can get access to the latest versions before everyone else!

[![GitHub All Releases](https://img.shields.io/github/downloads/dreamnettech/dreamtime/total?logo=github&logoColor=white&style=for-the-badge&labelColor=181717&color=blue)](https://github.com/dreamnettech/dreamtime/releases)

### Mirrors

[![Windows](https://img.shields.io/badge/dreamlink-v1.1.1-0078D6?logo=windows&logoColor=white&style=for-the-badge)](https://catalina.dreamnet.tech/ipns/QmUvudWPzRa7hgDSVFiwzFzviAZJohTrvHJNhnvytuPv3H/Releases/DreamTime/v1.1.1/DreamTime-v1.1.1-windows.exe)
[![Windows](https://img.shields.io/badge/windows-v1.1.1-0078D6?logo=windows&logoColor=white&style=for-the-badge)](https://catalina.dreamnet.tech/ipns/QmUvudWPzRa7hgDSVFiwzFzviAZJohTrvHJNhnvytuPv3H/Releases/DreamTime/v1.1.1/DreamTime-v1.1.1-windows.exe)

[![Ubuntu](https://img.shields.io/badge/dreamlink-v1.1.1-E95420?logo=ubuntu&logoColor=white&style=for-the-badge)](https://catalina.dreamnet.tech/ipns/QmUvudWPzRa7hgDSVFiwzFzviAZJohTrvHJNhnvytuPv3H/Releases/DreamTime/v1.1.1/DreamTime-v1.1.1-ubuntu.deb)
[![Ubuntu](https://img.shields.io/badge/ubuntu-v1.1.1-E95420?logo=ubuntu&logoColor=white&style=for-the-badge)](https://catalina.dreamnet.tech/ipns/QmUvudWPzRa7hgDSVFiwzFzviAZJohTrvHJNhnvytuPv3H/Releases/DreamTime/v1.1.1/DreamTime-v1.1.1-ubuntu.deb)

[![macOS](https://img.shields.io/badge/dreamlink-v1.1.1-999999?logo=Apple&logoColor=white&style=for-the-badge)](https://catalina.dreamnet.tech/ipns/QmUvudWPzRa7hgDSVFiwzFzviAZJohTrvHJNhnvytuPv3H/Releases/DreamTime/v1.1.1/DreamTime-v1.1.1-macos.dmg)
[![macOS](https://img.shields.io/badge/macos-v1.1.1-999999?logo=Apple&logoColor=white&style=for-the-badge)](https://catalina.dreamnet.tech/ipns/QmUvudWPzRa7hgDSVFiwzFzviAZJohTrvHJNhnvytuPv3H/Releases/DreamTime/v1.1.1/DreamTime-v1.1.1-macos.dmg)

## F.A.Q.


+ 1
- 1
src/.env View File

@@ -1,6 +1,6 @@
APP_NAME = DreamTime
APP_STATUS = stable
APP_VERSION = 1.1.1
APP_VERSION = 1.1.2

SERVER_PORT = 3000
SERVER_HOST = localhost

+ 29
- 20
src/.eslintrc.js View File

@@ -3,6 +3,7 @@ module.exports = {
env: {
browser: true,
node: true,
es2020: true,
'shared-node-browser': true,
},
parserOptions: {
@@ -11,47 +12,53 @@ module.exports = {
extends: [
'@nuxtjs',
'airbnb-base',
'plugin:import/errors',
'plugin:import/warnings',
'plugin:promise/recommended',
'plugin:lodash/recommended',
'plugin:vue/recommended',
'plugin:nuxt/recommended',
'prettier',
'prettier/vue',
'plugin:nuxt/recommended'
],
plugins: ['lodash', 'vue', 'prettier'],
// add your custom rules here
plugins: ['import', 'promise', 'lodash', 'vue'],
settings: {
'import/resolver': {
nuxt: {}
}
},
rules: {
quotes: ['error', 'single', { allowTemplateLiterals: true }],
semi: ['error', 'never'],
'max-len': 'off',
'comma-dangle': 'warn',
'class-methods-use-this': 'off',
'global-require': 'off',
'import/no-unresolved': 'off',
'padded-blocks': ['error', 'never'],
'no-await-in-loop': 'warn',
'no-console': 'off',
'no-alert': 'off',
'no-continue': 'off',
'no-param-reassign': 'off',
'no-restricted-syntax': 'off',
'no-useless-constructor': 'warn',
'no-underscore-dangle': 'off',
'no-underscore-dangle': ['error', { allowAfterThis: true }],
'no-shadow': 'off',
'no-unused-vars': 'warn',
'no-debugger': 'warn',
'no-restricted-globals': 'warn',
'no-unreachable': 'warn',
'no-lone-blocks': 'off',
'no-param-reassign': 'off',
'object-shorthand': ['error', 'always'],
'quote-props': ['error', 'as-needed'],
'spaced-comment': 'warn',
'import/no-webpack-loader-syntax': 'warn',
'import/no-webpack-loader-syntax': 'off',
'vue/no-v-html': 'off',
'vue/html-indent': ['warn', 2],
'vue/html-self-closing': 'off',
'vue/singleline-html-element-content-newline': 'off',
'vue/html-self-closing': 'error',
'vue/singleline-html-element-content-newline': 'warn',
'vue/html-closing-bracket-newline': [
'warn',
{
singleline: 'never',
multiline: 'never',
},
multiline: 'never'
}
],
'lodash/import-scope': ['warn', 'full'],
'lodash/prefer-lodash-method': 'off',
@@ -60,16 +67,18 @@ module.exports = {
'lodash/prefer-includes': 'warn',
'lodash/prefer-lodash-typecheck': 'warn',
'lodash/prefer-constant': 'off',
'import/order': 'warn',
'import/order': 'error',
'import/prefer-default-export': 'off',
'import/default': 'off',
'import/no-extraneous-dependencies': [
'off',
{
devDependencies: true,
devDependencies: false,
optionalDependencies: false,
peerDependencies: false,
},
peerDependencies: false
}
],
'nuxt/no-globals-in-created': 'off',
'nuxt/no-globals-in-created': 'off'
},
globals: {
$dream: false,

+ 22
- 2
src/assets/css/base/_reset.scss View File

@@ -6,7 +6,7 @@
}

html {
@apply text-generic bg-dark-800;
@apply bg-black text-generic-500;
font-family: theme('fontFamily.sans');
font-size: 16px;
word-spacing: 1px;
@@ -26,10 +26,30 @@ html {
font-size: 16px;

p {
@apply mb-3;
@apply mb-2;
}

a {
@apply text-primary underline;
}
}

*::-webkit-scrollbar-track
{
-webkit-box-shadow: inset 0 0 6px rgba(0,0,0,0.3);
border-radius: 10px;
@apply bg-dark-800;
}

*::-webkit-scrollbar
{
width: 12px;
@apply bg-dark-800;
}

*::-webkit-scrollbar-thumb
{
border-radius: 10px;
-webkit-box-shadow: inset 0 0 6px rgba(0,0,0,.3);
@apply bg-dark-500;
}

+ 37
- 13
src/assets/css/components/_box.scss View File

@@ -1,31 +1,55 @@
/*
* DreamTime | (C) 2019 by Ivan Bravo Bravo <ivan@dreamnet.tech>
*
* 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.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
* the Free Software Foundation. See <https://www.gnu.org/licenses/gpl-3.0.html>
*
* Written by Ivan Bravo Bravo <ivan@dreamnet.tech>, 2019.
*/

.box {
@apply bg-dark-500 rounded px-5 py-3 shadow mb-5;
@apply bg-dark-500 rounded shadow mb-6;

&.is-transparent {
@apply bg-transparent rounded-none shadow-none;
.box__photo {
@apply relative;
@apply bg-cover bg-center;
min-height: 120px;

.box__photo__content {
@apply absolute w-full h-full;
@apply bg-black-70;
}
}

.box__header {
@apply px-4 pt-2;

.title {
@apply text-lg font-bold text-white;
}

.subtitle {
@apply text-sm mb-2 font-light text-white;
}
}

.box__content {
@apply px-4 py-2;
}

.box-title {
@apply font-bold text-generic-300 text-lg mb-2;
.box__footer {
@apply px-4 py-2 text-sm;
@apply border-t border-dark-400;
}
}

.box-section {
@apply px-0 py-1;
@apply px-0 py-2;

.box-section-item {
@apply flex py-3 px-5;
@apply flex py-2 px-4;

&:not(:last-child) {
@apply border-b border-dark-400;

+ 1
- 1
src/assets/css/components/_button.scss View File

@@ -2,7 +2,7 @@
@apply inline-flex
items-center
justify-center
px-3
px-4
rounded
uppercase
font-semibold;

+ 6
- 1
src/assets/css/components/_container.scss View File

@@ -10,7 +10,7 @@
min-height: 80px;

.button {
@apply mx-3;
@apply mx-4;
}
}
}
@@ -18,3 +18,8 @@
.content-body {
@apply p-6;
}

.content__body {
@apply pt-6 pl-6 pr-6;
height: calc(100vh - 70px);
}

+ 2
- 2
src/assets/css/components/_form.scss View File

@@ -7,11 +7,11 @@
}

.label {
@apply block font-bold mb-1;
@apply block font-bold mb-2;
}

.input {
@apply border border-dark-800 bg-dark-600 rounded py-1 px-3 w-full text-generic-300 shadow-inner;
@apply border border-dark-800 bg-dark-600 rounded py-2 px-4 w-full text-generic-300 shadow-inner;
outline: none !important;
transition: all .2s ease-in-out;


+ 3
- 3
src/assets/css/components/_markdown.scss View File

@@ -11,7 +11,7 @@
@apply text-lg mb-2;

&:not(:first-child) {
@apply mt-5;
@apply mt-4;
}
}

@@ -23,7 +23,7 @@
@apply list-disc ml-6;

li {
@apply mt-1;
@apply mt-2;
}
}

@@ -36,6 +36,6 @@
}

code {
@apply bg-gray-200 font-mono py-1 px-2 text-sm;
@apply bg-gray-200 font-mono py-2 px-2 text-sm;
}
}

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

@@ -1,5 +1,5 @@
.notification {
@apply mb-5 p-4 bg-dark-600 border-2 border-dark-300 text-sm text-generic-100 rounded;
@apply mb-4 p-4 bg-dark-600 border-2 border-dark-300 text-sm text-generic-100 rounded;

a {
@apply underline;

+ 1
- 1
src/assets/css/components/_section.scss View File

@@ -13,7 +13,7 @@
}

.section-header {
@apply mb-3;
@apply mb-2;
}

.section-header-title {

+ 11
- 8
src/components/Form/InlineField.vue View File

@@ -1,8 +1,12 @@
<template>
<div class="c-inline-field">
<div class="inline-field-left">
<p class="inline-field-label">{{ label }}</p>
<p v-if="hint" class="inline-field-hint">{{ hint }}</p>
<p class="inline-field-label">
{{ label }}
</p>
<p v-if="hint" class="inline-field-hint">
{{ hint }}
</p>
</div>

<div class="inline-field-right">
@@ -16,14 +20,14 @@ export default {
props: {
label: {
type: String,
required: true
required: true,
},

hint: {
type: String,
default: undefined
}
}
default: undefined,
},
},
}
</script>

@@ -32,7 +36,7 @@ export default {
@apply flex;

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

.inline-field-left {
@@ -53,4 +57,3 @@ export default {
}
}
</style>


+ 3
- 3
src/components/Layout/Jobs.vue View File

@@ -20,11 +20,11 @@

<style lang="scss">
.layout-jobs {
@apply p-3 shadow h-screen flex flex-col;
@apply p-2 shadow h-screen flex flex-col;
width: 200px;

.jobs-pending {
@apply flex-1 border-b border-gray-300 mb-3;
@apply flex-1 border-b border-gray-300 mb-2;
}

.jobs-recent {
@@ -32,7 +32,7 @@
}

.job-section {
@apply mb-5;
@apply mb-4;
}

.section-title {

+ 27
- 11
src/components/Layout/Navigation.vue View File

@@ -32,15 +32,30 @@
</nav>
</section>

<!-- Developer Navigation -->
<section v-if="isDev" class="navbar-section">
<!-- Nice links -->
<section v-if="!$platform.isLimited" class="navbar-section">
<nav class="navbar-items">
<a href="#" class="navbar-item" @click.prevent="testBug">
<span class="icon">๐Ÿ›</span>
<span>I am a error!</span>
</a>
<app-external-link :href="$nucleus.urls.web" class="navbar-item">
<span class="icon">๐ŸŒŽ</span>
<span>Website</span>
</app-external-link>

<app-external-link :href="$nucleus.urls.chat" class="navbar-item">
<span class="icon">๐Ÿ’ฌ</span>
<span>Chat</span>
</app-external-link>

<app-external-link :href="$nucleus.urls.forum" class="navbar-item">
<span class="icon">๐Ÿ‘ฅ</span>
<span>Forum</span>
</app-external-link>
</nav>
</section>

<!-- Developer Navigation -->
<section v-if="isDev" class="navbar-section">
<nav class="navbar-items" />
</section>
</div>
</div>
</template>
@@ -73,16 +88,17 @@ export default {
},

isActive() {
// eslint-disable-next-line no-underscore-dangle
return $settings._settings.welcome !== true
}
},
},

methods: {
testBug() {
$tools.testError()
throw new Error('wow much error')
}
}
},
},
}
</script>

@@ -127,7 +143,7 @@ export default {
}

.navbar-header {
@apply mb-5 text-gray-300 flex flex-col items-center justify-center;
@apply mb-4 text-gray-300 flex flex-col items-center justify-center;
animation: 20s ease-in-out infinite bgAnim;
height: 70px;

@@ -163,7 +179,7 @@ export default {
}

.navbar-section {
@apply mb-5;
@apply mb-4;
}

.section-title {

+ 47
- 29
src/components/Nudity/Job.vue View File

@@ -1,23 +1,31 @@
<template>
<div class="c-nudity-job">
<figure class="__preview">
<img v-if="job.hasFinished" :src="outputDataURL" />
<img v-if="job.hasFinished" :src="outputDataURL">
<span v-else v-tooltip="'Loading...'">๐Ÿ’ญ</span>
</figure>

<div class="__content">
<!-- Actions -->
<details class="__section" open>
<summary class="__title">Actions</summary>
<summary class="__title">
Actions
</summary>

<div class="__buttons">
<button v-if="job.hasFinished" class="button is-success" @click.prevent="save">Save</button>
<button v-if="job.hasFinished || job.hasFailed" class="button is-danger is-sm" @click.prevent="rerun">Rerun</button>
<button v-if="job.hasFinished" class="button is-success" @click.prevent="save">
Save
</button>
<button v-if="job.hasFinished || job.hasFailed" class="button is-danger is-sm" @click.prevent="rerun">
Rerun
</button>
</div>
</details>

<details v-if="job.hasFinished || job.isLoading" class="__section" open>
<summary class="__title">Duration</summary>
<summary class="__title">
Duration
</summary>

<div class="__status">
<p>{{ job.timer.duration }}s</p>
@@ -25,7 +33,9 @@
</details>

<details v-else-if="job.hasFailed" class="__section" open>
<summary class="__title">Status</summary>
<summary class="__title">
Status
</summary>

<div class="__status text-danger">
<p>Fail</p>
@@ -33,7 +43,9 @@
</details>

<details v-else class="__section" open>
<summary class="__title">Status</summary>
<summary class="__title">
Status
</summary>

<div class="__status">
<p>Pending...</p>
@@ -42,42 +54,48 @@

<!-- Preferences -->
<details class="__section">
<summary class="__title">Preferences</summary>
<summary class="__title">
Preferences
</summary>

<div class="__preferences">
<p>
<span class="__name">Boobs size</span>
<span class="__value">{{ job.preferences.boobs.size | size }}</span>
<span class="__value">{{ job.preferences.body.boobs.size | size }}</span>
</p>

<p>
<span class="__name">Areola size</span>
<span class="__value">{{ job.preferences.areola.size | size }}</span>
<span class="__value">{{ job.preferences.body.areola.size | size }}</span>
</p>

<p>
<span class="__name">Nipple size</span>
<span class="__value">{{ job.preferences.nipple.size | size }}</span>
<span class="__value">{{ job.preferences.body.nipple.size | size }}</span>
</p>

<p>
<span class="__name">Vagina size</span>
<span class="__value">{{ job.preferences.vagina.size | size }}</span>
<span class="__value">{{ job.preferences.body.vagina.size | size }}</span>
</p>

<p>
<span class="__name">Pubic Hair size</span>
<span class="__value">{{ job.preferences.pubicHair.size | size }}</span>
<span class="__value">{{ job.preferences.body.pubicHair.size | size }}</span>
</p>
</div>
</details>

<!-- Console -->
<details class="__section">
<summary class="__title">Console</summary>
<summary class="__title">
Console
</summary>

<div class="__console">
<li v-for="(item, index) in job.cli.lines" :key="index" :class="item.css">> {{ item.text }}</li>
<li v-for="(item, index) in job.cli.lines" :key="index" :class="item.css">
> {{ item.text }}
</li>
</div>
</details>
</div>
@@ -91,25 +109,25 @@ export default {
filters: {
size(value) {
return Number.parseFloat(value).toFixed(2)
}
},
},
props: {
job: {
type: Object,
required: true
}
required: true,
},
},

data: () => ({
outputDataURL: undefined
outputDataURL: undefined,
}),

watch: {
async 'job.hasFinished'(value) {
if (value) {
this.outputDataURL = await this.job.getFile().readAsDataURL()
this.outputDataURL = await this.job.file.readAsDataURL()
}
}
},
},

methods: {
@@ -119,22 +137,22 @@ export default {
const savePath = $tools.shell.showSaveDialog({
defaultPath: this.job.getFileName(),
filters: [
{ name: 'PNG', extensions: ['png'] }
{ name: 'PNG', extensions: ['png'] },
// { name: 'JPEG', extensions: ['jpg'] }
]
],
})

if (_.isNil(savePath)) {
return
}

this.job.getFile().copy(savePath)
this.job.file.copy(savePath)
},

rerun() {
this.job.photo.rerunJob(this.job.id)
}
}
},
},
}
</script>

@@ -173,7 +191,7 @@ export default {
width: 200px;

.__section {
@apply py-3;
@apply py-2;

&:not(:last-child) {
@apply border-b border-dark-400;
@@ -193,11 +211,11 @@ export default {
}

.__console {
@apply p-3 bg-black overflow-auto rounded;
@apply p-2 bg-black overflow-auto rounded;
height: 150px;

li {
@apply font-mono text-xs text-generic-100 mb-3 block;
@apply font-mono text-xs text-generic-100 mb-2 block;

&.text-danger {
@apply text-danger;

+ 10
- 9
src/components/Nudity/Preview.vue View File

@@ -1,6 +1,6 @@
<template>
<figure class="cnudity-preview">
<img :src="nudityPreview" :style="{ 'width': width + 'px', 'height': height + 'px' }" />
<img :src="nudityPreview" :style="{ 'width': width + 'px', 'height': height + 'px' }">
</figure>
</template>

@@ -9,22 +9,22 @@ export default {
props: {
width: {
type: Number,
default: 312
default: 312,
},

height: {
type: Number,
default: 312
default: 312,
},

type: {
type: String,
default: 'output'
}
default: 'output',
},
},

data: () => ({
nudityPreview: undefined
nudityPreview: undefined,
}),

async created() {
@@ -34,6 +34,7 @@ export default {
methods: {
async getPreviewDataURL() {
if (!this.$nudity.hasModelPhoto()) {
// eslint-disable-next-line global-require
return require('~/assets/images/d1hpv9d-e1c2c577-d272-41b0-bd73-a89209108efd.jpg')
}

@@ -46,13 +47,13 @@ export default {
}

return this.$nudity.modelPhoto.getSourceFile().readAsDataURL()
}
}
},
},
}
</script>

<style lang="scss">
.cnudity-preview {
@apply flex justify-center items-center py-5;
@apply flex justify-center items-center py-4;
}
</style>

+ 290
- 0
src/components/Nudity/Upload.backup.vue View File

@@ -0,0 +1,290 @@
/*
* Filename: c:\src\dream\apps\dreamtime\src\components\Nudity\Upload.backup.vue
* Path: c:\src\dream\apps\dreamtime\src
* Created Date: Saturday, November 16th 2019, 3:43:30 pm
* Author: Ivan Bravo Bravo <ivan@dreamnet.tech>
*
* Copyright (c) 2019 DreamNet
*/
<template>
<div class="c-nudity-upload">
<!-- Dropzone -->
<div
:class="{'is-dragging': isDraggingFile}"
class="upload-dropzone"
@dragenter="onDragEnter"
@dragover="onDragOver"
@dragleave="onDragLeave"
@drop="onDrop">
<p class="dropzone-hint">๐Ÿ‘‡ Drop the photo here!</p>
</div>

<!-- Hidden input -->
<input
v-show="false"
ref="photo"
type="file"
accept="image/jpeg, image/png"
@change="onPhotoSelected" />

<div class="box py-5">
<div class="upload-url">
<input v-model="webAddress" type="url" class="input" placeholder="๐ŸŒ or enter a web address..." />

<button class="button" @click="onURL">
Go!
</button>
</div>

<!-- Action button -->
<button class="button" @click.prevent="$refs.photo.click()">
๐Ÿ“‚ or open a photo...
</button>
</div>
</div>
</template>

<script>
import _ from 'lodash'
import swal from 'sweetalert'
import { Photo } from '~/modules/models'
import { File } from '~/modules'

export default {
props: {
model: {
type: String,
default: undefined
}
},

data: () => ({
webAddress: '',

// Indicates if the user is dragging a file in the window (we apply the drag style)
isDraggingFile: false
}),

created() {
// Restarts the information of a previous process
this.$nudify.reset()
},

methods: {
/**
* File selected, start a new transformation process
*/
startFromFile(inputFile) {
if (_.isNil(inputFile)) {
swal(
'Upload failed',
'It seems that you have not selected a photo!',
'info'
)
return
}

// New File instance
const file = File.fromPath(inputFile.path)

this.start(file)
},

/**
*
*/
async startFromURL(url) {
if (_.isNil(url)) {
swal('Upload failed', 'This does not seem like a valid URL', 'info')
return
}

swal({
title: 'Loading...',
text: 'We are downloading the photo and preparing it!',
button: false,
closeOnClickOutside: false,
closeOnEsc: false
})

try {
// New File instance
const file = await File.fromURL(url)

swal.close()

this.start(file)
} catch (err) {
swal({
icon: 'error',
title: 'Upload failed',
text: `An error has occurred downloading the photo or saving it in the temporary folder, please make sure you are connected to the Internet and that ${
$dream.name
} has permissions to save files.`
})

$rollbar.warn(err)
}
},

/**
*
*/
start(file) {
// Create a photo for the model ("null" model for now)
const photo = new Photo(null, file)

// Get any error message from the file
const validationErrorMessage = photo.getValidationErrorMessage()

if (!_.isNil(validationErrorMessage)) {
swal('Upload failed', validationErrorMessage, 'error')
return
}

// Start the transformation process!
this.$nudify.start(photo)

// It's time to crop the photo
this.$router.push('/nudity/hub')
},

/**
*
*/
onPhotoSelected(event) {
const { files } = event.target

if (files.length === 0) {
return
}

$nucleus.track('UPLOAD_SELECTED')

this.startFromFile(files[0])
event.target.value = ''
},

/**
*
*/
onURL() {
if (_.isNil(this.webAddress) || this.webAddress.length === 0) {
swal('Upload failed', 'Please enter a valid web address', 'error')
return
}

$nucleus.track('UPLOAD_URL')

this.startFromURL(this.webAddress)
},

/**
*
*/
onDragEnter(event) {
event.dataTransfer.dropEffect = 'copy'
this.isDraggingFile = true
},

/**
*
*/
onDragLeave() {
this.isDraggingFile = false
},

/**
*
*/
onDragOver(event) {
event.preventDefault()
event.stopPropagation()
event.dataTransfer.dropEffect = 'copy'
this.isDraggingFile = true
},

/**
*
*/
onDrop(event) {
event.preventDefault()
event.stopPropagation()
this.isDraggingFile = false

const { files } = event.dataTransfer
const externalURL = event.dataTransfer.getData('url')

if (files.length > 0) {
$nucleus.track('UPLOAD_DROP')
this.startFromFile(files[0])
} else if (externalURL.length > 0) {
$nucleus.track('UPLOAD_DROP_URL')
this.startFromURL(externalURL)
}
}
}
}
</script>

<style lang="scss">
.c-nudity-upload {
@apply w-full
relative
text-center
mb-4;

.upload-dropzone {
@apply flex
items-center
justify-center
bg-dark-400
rounded
border-transparent
border-2
border-dashed
mb-4;

height: 150px;
transition: all 0.1s linear;

&.is-dragging {
@apply bg-dark-700 border-white;

.dropzone-hint {
@apply text-white;
}
}

.dropzone-hint {
@apply text-generic-300 uppercase;
transition: all 0.1s linear;
}
}

.upload-url {
@apply mb-4 flex;

.input {
@apply flex-1 mr-4;
}
}

&.is-dragging {
@apply border-white border-dotted;

.dragging-overlay {
//display: block;
}
}

.dragging-overlay {
@apply bg-white absolute top-0 left-0 right-0 bottom-0 hidden;
opacity: 0.3;
}

.fu-hint {
@apply text-sm text-gray-600;
}
}
</style>

+ 133
- 61
src/components/Nudity/Upload.vue View File

@@ -1,37 +1,81 @@
<template>
<div class="c-nudity-upload">
<div class="c-uploader">
<!-- Dropzone -->
<div
:class="{'is-dragging': isDraggingFile}"
class="upload-dropzone"
class="uploader__dropzone"
:class="{'is-dragging': isDragging}"
@dragenter="onDragEnter"
@dragover="onDragOver"
@dragleave="onDragLeave"
@drop="onDrop">
<p class="dropzone-hint">๐Ÿ‘‡ Drop the photo here!</p>
<p class="dropzone-hint">
๐Ÿ“ท Drop the photo here!
</p>
</div>

<!-- Hidden input -->
<input
v-show="false"
ref="photo"
type="file"
accept="image/jpeg, image/png"
@change="onPhotoSelected" />

<div class="box py-5">
<div class="upload-url">
<input v-model="webAddress" type="url" class="input" placeholder="๐ŸŒ or enter a web address..." />

<button class="button" @click="onURL">
Go!
</button>
<div class="uploader__alt">
<!-- Computer File -->
<div class="box">
<div class="box__header">
<h2 class="title">
Computer File
</h2>
<h3 class="subtitle">
Select a file from your computer.
</h3>
</div>

<div class="box__content">
<input
v-show="false"
ref="photo"
type="file"
accept="image/jpeg, image/png"
@change="onPhotoSelected">

<button class="button" @click.prevent="$refs.photo.click()">
๐Ÿ“‚ open a photo...
</button>
</div>
</div>

<!-- Action button -->
<button class="button" @click.prevent="$refs.photo.click()">
๐Ÿ“‚ or open a photo...
</button>
<!-- Computer Folder
<div class="box">
<div class="box__header">
<h2 class="title">
Computer Folder
</h2>
<h3 class="subtitle">
All valid photos in the folder will be processed.
</h3>
</div>

<div class="box__content">
<button class="button" @click.prevent="openFolder">
๐Ÿ“‚ import folder...
</button>
</div>
</div>-->

<!-- Web Address -->
<div class="box">
<div class="box__header">
<h2 class="title">
Web Address
</h2>
<h3 class="subtitle">
It must be the direct web address to a photo and must end with the jpg, png or gif format.
</h3>
</div>

<div class="box__content">
<input v-model="webAddress" type="url" class="input mb-2" placeholder="https://">

<button class="button" @click="onURL">
Go!
</button>
</div>
</div>
</div>
</div>
</template>
@@ -46,15 +90,15 @@ export default {
props: {
model: {
type: String,
default: undefined
}
default: undefined,
},
},

data: () => ({
webAddress: '',

// Indicates if the user is dragging a file in the window (we apply the drag style)
isDraggingFile: false
isDragging: false,
}),

created() {
@@ -71,7 +115,7 @@ export default {
swal(
'Upload failed',
'It seems that you have not selected a photo!',
'info'
'info',
)
return
}
@@ -96,7 +140,7 @@ export default {
text: 'We are downloading the photo and preparing it!',
button: false,
closeOnClickOutside: false,
closeOnEsc: false
closeOnEsc: false,
})

try {
@@ -112,7 +156,7 @@ export default {
title: 'Upload failed',
text: `An error has occurred downloading the photo or saving it in the temporary folder, please make sure you are connected to the Internet and that ${
$dream.name
} has permissions to save files.`
} has permissions to save files.`,
})

$rollbar.warn(err)
@@ -137,8 +181,15 @@ export default {
// Start the transformation process!
this.$nudify.start(photo)

// It's time to crop the photo
this.$router.push('/nudity/crop')
// It's time to nudify the photo
this.$router.push('/nudify')
},

/**
*
*/
openFolder() {

},

/**
@@ -176,14 +227,14 @@ export default {
*/
onDragEnter(event) {
event.dataTransfer.dropEffect = 'copy'
this.isDraggingFile = true
this.isDragging = true
},

/**
*
*/
onDragLeave() {
this.isDraggingFile = false
this.isDragging = false
},

/**
@@ -193,7 +244,7 @@ export default {
event.preventDefault()
event.stopPropagation()
event.dataTransfer.dropEffect = 'copy'
this.isDraggingFile = true
this.isDragging = true
},

/**
@@ -202,7 +253,7 @@ export default {
onDrop(event) {
event.preventDefault()
event.stopPropagation()
this.isDraggingFile = false
this.isDragging = false

const { files } = event.dataTransfer
const externalURL = event.dataTransfer.getData('url')
@@ -214,37 +265,60 @@ export default {
$nucleus.track('UPLOAD_DROP_URL')
this.startFromURL(externalURL)
}
}
}
},
},
}
</script>

<style lang="scss">
.c-nudity-upload {
@apply w-full
relative
text-center
mb-5;

.upload-dropzone {
@apply flex
items-center
justify-center
bg-dark-400
rounded
border-transparent
border-2
border-dashed
mb-5;

height: 150px;
<style lang="scss" scoped>
.c-uploader {
@apply w-full relative;

.uploader__alt {
@apply flex flex-wrap;

.box {
@apply flex flex-col;
width: 48%;
min-height: 200px;

&:not(:last-child) {
@apply mr-4;
}

.box__header {
h2 {
@apply text-lg font-bold;
}

h3 {
@apply text-sm mb-4 font-light;
}

.help {
@apply text-xs align-text-top font-bold underline;
cursor: help;
}
}

.box__content {
@apply flex-1 flex flex-col justify-center items-center;
}
}
}

.uploader__dropzone {
@apply flex items-center justify-center;
@apply bg-dark-400 mb-6;
@apply rounded border-2 border-dashed border-gray-600;
height: 200px;
transition: all 0.1s linear;

&.is-dragging {
@apply bg-dark-700 border-white;

.dropzone-hint {
@apply text-white;
@apply text-white text-xl;
}
}

@@ -255,10 +329,10 @@ export default {
}

.upload-url {
@apply mb-5 flex;
@apply mb-6 flex;

.input {
@apply flex-1 mr-3;
@apply flex-1 mr-4;
}
}

@@ -280,5 +354,3 @@ export default {
}
}
</style>



+ 342
- 226
src/components/Settings/SettingsPreferences.vue View File

@@ -1,236 +1,353 @@
<template>
<div class="c-settings-preferences">
<section class="box box-section">
<box-section-item
label="Number of runs"
description="The transformation can be different each time, here you can set how many times your photo will be processed. In the end you can save the one you like best.">
<input v-model="currentValue.executions" type="number" min="1" class="input" />
</box-section-item>

<box-section-item
label="Randomize every run"
description="Random preferences will be set at each run">
<select v-model="currentValue.randomizePreferences" class="input">
<option :value="true">Enabled</option>
<option :value="false">Disabled</option>
</select>
</box-section-item>

<box-section-item
v-show="!currentValue.randomizePreferences"
label="Progressive every run"
description="Preferences will increase their value +0.2 in each run">
<select v-model="currentValue.progressivePreferences" class="input">
<option :value="true">Enabled</option>
<option :value="false">Disabled</option>
</select>
</box-section-item>
</section>
<div class="c-preferences">
<section class="box box--items">
<div class="box__header">
<h2 class="title">
Runs
</h2>
<h3 class="subtitle">
Customize what will happen in each processing.
</h3>
</div>

<section class="box box-section">
<box-section-item :description="`Current value: ${currentValue.boobs.size}`" label="Boob Size">
<div class="slider-container">
<input
v-model="currentValue.boobs.size"
type="range"
class="slider"
in="0.3"
max="2"
step="0.1" />
<span class="min">0.3</span>
<span class="max">2.0</span>
</div>
</box-section-item>

<box-section-item
v-show="currentValue.randomizePreferences"
label="Randomize"
description="Randomize the value in each run.">
<select v-model="currentValue.boobs.randomize" class="input">
<option :value="true">Enabled</option>
<option :value="false">Disabled</option>
</select>
</box-section-item>

<box-section-item
v-show="!currentValue.randomizePreferences && currentValue.progressivePreferences"
label="Progressive"
description="Increase the value progressively in each run">
<select v-model="currentValue.boobs.progressive" class="input">
<option :value="true">Enabled</option>
<option :value="false">Disabled</option>
</select>
</box-section-item>
</section>
<div class="box__content">
<box-item
label="Number of runs"
description="How many times will the photo be processed?">
<input v-model="currentValue.body.executions" type="number" min="1" class="input">
</box-item>

<section class="box box-section">
<box-section-item :description="`Current value: ${currentValue.areola.size}`" label="Areola Size">
<div class="slider-container">
<input
v-model="currentValue.areola.size"
type="range"
class="slider"
in="0.3"
max="2"
step="0.1" />
<span class="min">0.3</span>
<span class="max">2.0</span>
</div>
</box-section-item>

<box-section-item
v-show="currentValue.randomizePreferences"
label="Randomize"
description="Randomize the value in each run.">
<select v-model="currentValue.areola.randomize" class="input">
<option :value="true">Enabled</option>
<option :value="false">Disabled</option>
</select>
</box-section-item>

<box-section-item
v-show="!currentValue.randomizePreferences && currentValue.progressivePreferences"
label="Progressive"
description="Increase the value progressively in each run">
<select v-model="currentValue.areola.progressive" class="input">
<option :value="true">Enabled</option>
<option :value="false">Disabled</option>
</select>
</box-section-item>
</section>
<box-item
label="Randomize"
description="Random body preferences will be set at each run.">
<select v-model="currentValue.body.randomize" class="input">
<option :value="true">
Enabled
</option>
<option :value="false">
Disabled
</option>
</select>
</box-item>

<section class="box box-section">
<box-section-item :description="`Current value: ${currentValue.nipple.size}`" label="Nipple Size">
<div class="slider-container">
<input
v-model="currentValue.nipple.size"
type="range"
class="slider"
in="0.3"
max="2"
step="0.1" />
<span class="min">0.3</span>
<span class="max">2.0</span>
</div>
</box-section-item>

<box-section-item
v-show="currentValue.randomizePreferences"
label="Randomize"
description="Randomize the value in each run.">
<select v-model="currentValue.nipple.randomize" class="input">
<option :value="true">Enabled</option>
<option :value="false">Disabled</option>
</select>
</box-section-item>

<box-section-item
v-show="!currentValue.randomizePreferences && currentValue.progressivePreferences"
label="Progressive"
description="Increase the value progressively in each run">
<select v-model="currentValue.nipple.progressive" class="input">
<option :value="true">Enabled</option>
<option :value="false">Disabled</option>
</select>
</box-section-item>
</section>
<box-item
v-show="!currentValue.body.randomize"
label="Progressive"
:description="`Body preferences will increase their value ${currentValue.body.progressive.rate} at each run.`">
<select v-model="currentValue.body.progressive.enabled" class="input">
<option :value="true">
Enabled
</option>
<option :value="false">
Disabled
</option>
</select>
</box-item>

<section class="box box-section">
<box-section-item :description="`Current value: ${currentValue.vagina.size}`" label="Vagina Size">
<div class="slider-container">
<input
v-model="currentValue.vagina.size"
type="range"
class="slider"
in="0.3"
max="1.5"
step="0.1"></input>
<span class="min">0.3</span>
<span class="max">1.5</span>
</div>
</box-section-item>

<box-section-item
v-show="currentValue.randomizePreferences"
label="Randomize"
description="Randomize the value in each run.">
<select v-model="currentValue.vagina.randomize" class="input">
<option :value="true">Enabled</option>
<option :value="false">Disabled</option>
</select>
</box-section-item>

<box-section-item
v-show="!currentValue.randomizePreferences && currentValue.progressivePreferences"
label="Progressive"
description="Increase the value progressively in each run">
<select v-model="currentValue.vagina.progressive" class="input">
<option :value="true">Enabled</option>
<option :value="false">Disabled</option>
</select>
</box-section-item>
<box-item
v-show="!currentValue.body.randomize"
label="Progressive rate"
:description="`Current value: ${currentValue.body.progressive.rate}`">
<div class="slider-container">
<input
v-model="currentValue.body.progressive.rate"
type="range"
class="slider"
min="0.1"
max="0.9"
step="0.1">
<span class="min">0.1</span>
<span class="max">0.9</span>
</div>
</box-item>
</div>
</section>

<section class="box box-section">
<box-section-item :description="`Current value: ${currentValue.pubicHair.size}`" label="Pubic Hair">
<div class="slider-container">
<input
v-model="currentValue.pubicHair.size"
type="range"
class="slider"
in="0"
max="2"
step="0.1"></input>
<span class="min">Disabled</span>
<span class="max">2.0</span>
</div>
</box-section-item>

<box-section-item
v-show="currentValue.randomizePreferences"
label="Randomize"
description="Randomize the value in each run.">
<select v-model="currentValue.pubicHair.randomize" class="input">
<option :value="true">Enabled</option>
<option :value="false">Disabled</option>
</select>
</box-section-item>

<box-section-item
v-show="!currentValue.randomizePreferences && currentValue.progressivePreferences"
label="Progressive"
description="Increase the value progressively in each run">
<select v-model="currentValue.pubicHair.progressive" class="input">
<option :value="true">Enabled</option>
<option :value="false">Disabled</option>
</select>
</box-section-item>
<section class="box box--items">
<div class="box__header">
<h2 class="title">
Body
</h2>
<h3 class="subtitle">
Customize the body of your dream.
</h3>
</div>

<div class="box__content">
<!-- Boobs -->
<box-item :description="`Current value: ${currentValue.body.boobs.size}`" label="Boobs size">
<div class="slider-container">
<input
v-model="currentValue.body.boobs.size"
type="range"
class="slider"
in="0.3"
max="2"
step="0.1">
<span class="min">0.3</span>
<span class="max">2.0</span>
</div>
</box-item>

<box-item
v-show="currentValue.body.randomize"
label="Randomize"
description="Randomize the value in each run."
class="box__item--sub">
<select v-model="currentValue.body.boobs.randomize" class="input">
<option :value="true">
Enabled
</option>
<option :value="false">
Disabled
</option>
</select>
</box-item>

<box-item
v-show="!currentValue.body.randomize && currentValue.body.progressive.enabled"
label="Progressive"
description="Increase the value progressively in each run"
class="box__item--sub">
<select v-model="currentValue.body.boobs.progressive" class="input">
<option :value="true">
Enabled
</option>
<option :value="false">
Disabled
</option>
</select>
</box-item>

<!-- Areola -->
<box-item :description="`Current value: ${currentValue.body.areola.size}`" label="Areola size">
<div class="slider-container">
<input
v-model="currentValue.body.areola.size"
type="range"
class="slider"
in="0.3"
max="2"
step="0.1">
<span class="min">0.3</span>
<span class="max">2.0</span>
</div>
</box-item>

<box-item
v-show="currentValue.body.randomize"
label="Randomize"
description="Randomize the value in each run."
class="box__item--sub">
<select v-model="currentValue.body.areola.randomize" class="input">
<option :value="true">
Enabled
</option>
<option :value="false">
Disabled
</option>
</select>
</box-item>

<box-item
v-show="!currentValue.body.randomize && currentValue.body.progressive.enabled"
label="Progressive"
description="Increase the value progressively in each run"
class="box__item--sub">
<select v-model="currentValue.body.areola.progressive" class="input">
<option :value="true">
Enabled
</option>
<option :value="false">
Disabled
</option>
</select>
</box-item>

<!-- Nipple -->
<box-item :description="`Current value: ${currentValue.body.nipple.size}`" label="Nipple Size">
<div class="slider-container">
<input
v-model="currentValue.body.nipple.size"
type="range"
class="slider"
in="0.3"
max="2"
step="0.1">
<span class="min">0.3</span>
<span class="max">2.0</span>
</div>
</box-item>

<box-item
v-show="currentValue.body.randomize"
label="Randomize"
description="Randomize the value in each run."
class="box__item--sub">
<select v-model="currentValue.body.nipple.randomize" class="input">
<option :value="true">
Enabled
</option>
<option :value="false">
Disabled
</option>
</select>
</box-item>

<box-item
v-show="!currentValue.body.randomize && currentValue.body.progressive.enabled"
label="Progressive"
description="Increase the value progressively in each run"
class="box__item--sub">
<select v-model="currentValue.body.nipple.progressive" class="input">
<option :value="true">
Enabled
</option>
<option :value="false">
Disabled
</option>
</select>
</box-item>

<!-- Vagina -->
<box-item :description="`Current value: ${currentValue.body.vagina.size}`" label="Vagina Size">
<div class="slider-container">
<input
v-model="currentValue.body.vagina.size"
type="range"
class="slider"
in="0.3"
max="1.5"
step="0.1"></input>
<span class="min">0.3</span>
<span class="max">1.5</span>
</div>
</box-item>

<box-item
v-show="currentValue.body.randomize"
label="Randomize"
description="Randomize the value in each run."
class="box__item--sub">
<select v-model="currentValue.body.vagina.randomize" class="input">
<option :value="true">
Enabled
</option>
<option :value="false">
Disabled
</option>
</select>
</box-item>

<box-item
v-show="!currentValue.body.randomize && currentValue.body.progressive.enabled"
label="Progressive"
description="Increase the value progressively in each run"
class="box__item--sub">
<select v-model="currentValue.body.vagina.progressive" class="input">
<option :value="true">
Enabled
</option>
<option :value="false">
Disabled
</option>
</select>
</box-item>

<box-item :description="`Current value: ${currentValue.body.pubicHair.size}`" label="Pubic Hair">
<div class="slider-container">
<input
v-model="currentValue.body.pubicHair.size"
type="range"
class="slider"
in="0"
max="2"
step="0.1"></input>
<span class="min">Disabled</span>
<span class="max">2.0</span>
</div>
</box-item>

<box-item
v-show="currentValue.body.randomize"
label="Randomize"
description="Randomize the value in each run."
class="box__item--sub">
<select v-model="currentValue.body.pubicHair.randomize" class="input">
<option :value="true">
Enabled
</option>
<option :value="false">
Disabled
</option>
</select>
</box-item>

<box-item
v-show="!currentValue.body.randomize && currentValue.body.progressive.enabled"
label="Progressive"
description="Increase the value progressively in each run"
class="box__item--sub">
<select v-model="currentValue.body.pubicHair.progressive" class="input">
<option :value="true">
Enabled
</option>
<option :value="false">
Disabled
</option>
</select>
</box-item>
</div>
</section>

<section class="box box-section">
<box-section-item v-if="false" label="Photo restoration" description="Restore the cropped photo to the original photo.">
<select v-model="currentValue.useRestoration" class="input">
<option :value="true">Enabled</option>
<option :value="false">Disabled</option>
</select>
</box-section-item>

<box-section-item v-if="false" label="waifu2x" description="waifu2x will try to resize your transformed photo to 1024x1024 with the least possible quality loss.">
<select v-model="currentValue.useWaifu" class="input">
<option :value="true">Enabled</option>
<option :value="false">Disabled</option>
</select>
</box-section-item>

<box-section-item
v-if="false"
label="Use Custom Mask"
hint="(Advanced) You can edit the masks of the photo before processing.">
<select v-model="currentValue.useCustomMask" class="input">
<option :value="false">Disabled</option>
<option :value="true">Enabled</option>
</select>
</box-section-item>
<section class="box box--items">
<div class="box__header">
<h2 class="title">
Advanced
</h2>
<h3 class="subtitle">
Additional processing settings.
</h3>
</div>

<div class="box__content">
<box-item
label="Scale mode"
description="Method that will be used to scale your photo to 512x512.">
<select v-model="currentValue.advanced.scaleMode" class="input">
<option value="none">
None
</option>
<option value="cropjs">
Manual Crop (Not recommended)
</option>
<option value="auto-rescale">
Fixed Scale
</option>
<option value="auto-resize">
Scale and pad
</option>
<!--
<option value="auto-resize-crop">
Scale and crop
</option>
-->
</select>
</box-item>

<box-item
label="Color transfer"
description="(Experimental) At the end of the transformation, a color transfer algorithm will be applied to try to recover the original colors of the photo.">
<select v-model="currentValue.advanced.useColorTransfer" class="input">
<option :value="true">
Enabled
</option>
<option :value="false">
Disabled
</option>
</select>
</box-item>
</div>
</section>
</div>
</template>
@@ -239,7 +356,6 @@
import { VModel } from '~/mixins'

export default {
mixins: [VModel]
mixins: [VModel],
}
</script>


+ 4
- 5
src/components/UI/AppExternalLink.vue View File

@@ -9,16 +9,15 @@ export default {
props: {
href: {
type: String,
required: true
}
required: true,
},
},

methods: {
openExternal() {
$nucleus.track('EXTERNAL_LINK', { href: this.href })
$tools.shell.openExternal(this.href)
}
}
},
},
}
</script>


+ 5
- 5
src/components/UI/AppPhoto.vue View File

@@ -1,6 +1,6 @@
<template>
<figure class="app-photo">
<img :src="src" />
<img :src="src">

<p class="app-photo-label">
<slot />
@@ -13,9 +13,9 @@ export default {
props: {
src: {
type: undefined,
required: true
}
}
required: true,
},
},
}
</script>

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

.app-photo-label {
@apply p-1 bg-dark-600 text-generic-300 text-sm rounded-b font-semibold text-center;
@apply p-2 bg-dark-600 text-generic-300 text-sm rounded-b font-semibold text-center;
}
}
</style>

+ 35
- 16
src/components/UI/AppUpdate.vue View File

@@ -2,14 +2,14 @@
<!-- Cannot update, only show the version... -->
<box-section-item
v-if="!updater.enabled"
:label="updater.getCurrentVersion()"
:label="currentVersion"
icon="๐ŸŒ" />

<!-- Updated! -->
<box-section-item
v-else-if="!updater.available"
:label="`${projectTitle} is up to date.`"
:description="updater.getCurrentVersion()"
:description="currentVersion"
icon="๐ŸŒ" />

<!-- Update available -->
@@ -18,8 +18,12 @@
:label="`${projectTitle} ${updater.latest.tag_name} available.`"
icon="๐ŸŒ"
class="update-item">
<button v-tooltip="'Download and install the update automatically.'" type="button" class="button is-sm" @click.prevent="updater.download()">Update</button>
<app-external-link v-tooltip="'Download the update manually.'" :href="downloadURL" class="button is-sm">Manual</app-external-link>
<button v-tooltip="'Download and install the update automatically.'" type="button" class="button is-sm" @click.prevent="updater.download()">
Update
</button>
<app-external-link v-tooltip="'Download the update manually.'" :href="downloadURL" class="button is-sm">
Manual
</app-external-link>
</box-section-item>