You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

Upload.vue 5.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284
  1. <template>
  2. <div class="c-nudity-upload">
  3. <!-- Dropzone -->
  4. <div
  5. :class="{'is-dragging': isDraggingFile}"
  6. class="upload-dropzone"
  7. @dragenter="onDragEnter"
  8. @dragover="onDragOver"
  9. @dragleave="onDragLeave"
  10. @drop="onDrop">
  11. <p class="dropzone-hint">👇 Drop the photo here!</p>
  12. </div>
  13. <!-- Hidden input -->
  14. <input
  15. v-show="false"
  16. ref="photo"
  17. type="file"
  18. accept="image/jpeg, image/png"
  19. @change="onPhotoSelected" />
  20. <div class="box py-5">
  21. <div class="upload-url">
  22. <input v-model="webAddress" type="url" class="input" placeholder="🌍 or enter a web address..." />
  23. <button class="button" @click="onURL">
  24. Go!
  25. </button>
  26. </div>
  27. <!-- Action button -->
  28. <button class="button" @click.prevent="$refs.photo.click()">
  29. 📂 or open a photo...
  30. </button>
  31. </div>
  32. </div>
  33. </template>
  34. <script>
  35. import _ from 'lodash'
  36. import swal from 'sweetalert'
  37. import { Photo } from '~/modules/models'
  38. import { File } from '~/modules'
  39. export default {
  40. props: {
  41. model: {
  42. type: String,
  43. default: undefined
  44. }
  45. },
  46. data: () => ({
  47. webAddress: '',
  48. // Indicates if the user is dragging a file in the window (we apply the drag style)
  49. isDraggingFile: false
  50. }),
  51. created() {
  52. // Restarts the information of a previous process
  53. this.$nudify.reset()
  54. },
  55. methods: {
  56. /**
  57. * File selected, start a new transformation process
  58. */
  59. startFromFile(inputFile) {
  60. if (_.isNil(inputFile)) {
  61. swal(
  62. 'Upload failed',
  63. 'It seems that you have not selected a photo!',
  64. 'info'
  65. )
  66. return
  67. }
  68. // New File instance
  69. const file = File.fromPath(inputFile.path)
  70. this.start(file)
  71. },
  72. /**
  73. *
  74. */
  75. async startFromURL(url) {
  76. if (_.isNil(url)) {
  77. swal('Upload failed', 'This does not seem like a valid URL', 'info')
  78. return
  79. }
  80. swal({
  81. title: 'Loading...',
  82. text: 'We are downloading the photo and preparing it!',
  83. button: false,
  84. closeOnClickOutside: false,
  85. closeOnEsc: false
  86. })
  87. try {
  88. // New File instance
  89. const file = await File.fromURL(url)
  90. swal.close()
  91. this.start(file)
  92. } catch (err) {
  93. swal({
  94. icon: 'error',
  95. title: 'Upload failed',
  96. 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 ${
  97. $dream.name
  98. } has permissions to save files.`
  99. })
  100. $rollbar.warn(err)
  101. }
  102. },
  103. /**
  104. *
  105. */
  106. start(file) {
  107. // Create a photo for the model ("null" model for now)
  108. const photo = new Photo(null, file)
  109. // Get any error message from the file
  110. const validationErrorMessage = photo.getValidationErrorMessage()
  111. if (!_.isNil(validationErrorMessage)) {
  112. swal('Upload failed', validationErrorMessage, 'error')
  113. return
  114. }
  115. // Start the transformation process!
  116. this.$nudify.start(photo)
  117. // It's time to crop the photo
  118. this.$router.push('/nudity/crop')
  119. },
  120. /**
  121. *
  122. */
  123. onPhotoSelected(event) {
  124. const { files } = event.target
  125. if (files.length === 0) {
  126. return
  127. }
  128. $nucleus.track('UPLOAD_SELECTED')
  129. this.startFromFile(files[0])
  130. event.target.value = ''
  131. },
  132. /**
  133. *
  134. */
  135. onURL() {
  136. if (_.isNil(this.webAddress) || this.webAddress.length === 0) {
  137. swal('Upload failed', 'Please enter a valid web address', 'error')
  138. return
  139. }
  140. $nucleus.track('UPLOAD_URL')
  141. this.startFromURL(this.webAddress)
  142. },
  143. /**
  144. *
  145. */
  146. onDragEnter(event) {
  147. event.dataTransfer.dropEffect = 'copy'
  148. this.isDraggingFile = true
  149. },
  150. /**
  151. *
  152. */
  153. onDragLeave() {
  154. this.isDraggingFile = false
  155. },
  156. /**
  157. *
  158. */
  159. onDragOver(event) {
  160. event.preventDefault()
  161. event.stopPropagation()
  162. event.dataTransfer.dropEffect = 'copy'
  163. this.isDraggingFile = true
  164. },
  165. /**
  166. *
  167. */
  168. onDrop(event) {
  169. event.preventDefault()
  170. event.stopPropagation()
  171. this.isDraggingFile = false
  172. const { files } = event.dataTransfer
  173. const externalURL = event.dataTransfer.getData('url')
  174. if (files.length > 0) {
  175. $nucleus.track('UPLOAD_DROP')
  176. this.startFromFile(files[0])
  177. } else if (externalURL.length > 0) {
  178. $nucleus.track('UPLOAD_DROP_URL')
  179. this.startFromURL(externalURL)
  180. }
  181. }
  182. }
  183. }
  184. </script>
  185. <style lang="scss">
  186. .c-nudity-upload {
  187. @apply w-full
  188. relative
  189. text-center
  190. mb-5;
  191. .upload-dropzone {
  192. @apply flex
  193. items-center
  194. justify-center
  195. bg-dark-400
  196. rounded
  197. border-transparent
  198. border-2
  199. border-dashed
  200. mb-5;
  201. height: 150px;
  202. transition: all 0.1s linear;
  203. &.is-dragging {
  204. @apply bg-dark-700 border-white;
  205. .dropzone-hint {
  206. @apply text-white;
  207. }
  208. }
  209. .dropzone-hint {
  210. @apply text-generic-300 uppercase;
  211. transition: all 0.1s linear;
  212. }
  213. }
  214. .upload-url {
  215. @apply mb-5 flex;
  216. .input {
  217. @apply flex-1 mr-3;
  218. }
  219. }
  220. &.is-dragging {
  221. @apply border-white border-dotted;
  222. .dragging-overlay {
  223. //display: block;
  224. }
  225. }
  226. .dragging-overlay {
  227. @apply bg-white absolute top-0 left-0 right-0 bottom-0 hidden;
  228. opacity: 0.3;
  229. }
  230. .fu-hint {
  231. @apply text-sm text-gray-600;
  232. }
  233. }
  234. </style>