From 61c4c61241b8321161bcbf4790d43fdb12ed588d Mon Sep 17 00:00:00 2001 From: Anthony Date: Thu, 22 Apr 2021 22:12:26 +0200 Subject: [PATCH 01/18] adding add thumbnail on upload --- controllers/backend/uploading.js | 12 +++++++++- routes.js | 2 ++ views/uploading.pug | 38 +++++++++++++++++++++++++++++--- 3 files changed, 48 insertions(+), 4 deletions(-) diff --git a/controllers/backend/uploading.js b/controllers/backend/uploading.js index 800693d8..0693f750 100644 --- a/controllers/backend/uploading.js +++ b/controllers/backend/uploading.js @@ -165,7 +165,8 @@ function testIfUserRestricted(user, logObject, res){ function aboutToProcess(res, channelUrl, uniqueTag){ res.send({ message: 'ABOUT TO PROCESS', - url: `/user/${channelUrl}/${uniqueTag}?u=t` + url: `/user/${channelUrl}/${uniqueTag}?u=t`, + uniqueTag }); } @@ -732,3 +733,12 @@ exports.adminUpload = async(req, res) => { // }); }; + + +/** + * POST /api/uploadFileThumbnail + * Upload file thumbnail + */ +exports.postThumbnailUpload = async(req, res) => { + // TODO: implement here +} diff --git a/routes.js b/routes.js index 98319b90..5a91fb66 100644 --- a/routes.js +++ b/routes.js @@ -259,6 +259,8 @@ function frontendRoutes(app){ app.post('/api/upload/:uniqueTag/edit', passportConfig.isAuthenticated, internalApiController.editUpload); app.post('/api/upload/:uniqueTag/thumbnail/delete', passportConfig.isAuthenticated, internalApiController.deleteUploadThumbnail); app.post('/api/upload/:uniqueTag/captions/delete', passportConfig.isAuthenticated, internalApiController.deleteUploadCaption); + app.post('/api/thumbnailUpload', passportConfig.isAuthenticated, uploadingController.postThumbnailUpload); + /** API ENDPOINTS **/ app.post('/api/react/:upload/:user', passportConfig.isAuthenticated, internalApiController.react); diff --git a/views/uploading.pug b/views/uploading.pug index a7540516..db7f4a6c 100644 --- a/views/uploading.pug +++ b/views/uploading.pug @@ -449,9 +449,41 @@ block content }) } - // TODO: add a post here to add a thumbnail - if (response.url) { - window.location.href = response.url; + var thumbnailFile = $('#filetoupload')[0].files[0] + + let files = new FormData(); + + files.append('fileName', thumbnailFile) + + var addThumbnailUrl = '/api/uploadFileThumbnail'; + + if(thumbnailFile){ + $.ajax({ + type: 'POST', + url: addThumbnailUrl, + processData: false, + contentType: false, + data: thumbnailFile, + success: function (response) { + console.log(response); + + if (response.url) { + window.location.href = response.url; + } + + }, + error: function (err) { + // hopefully this never happens? + console.log(err); + } + }); + + } else { + + // no thumbnail added, just redirect to the url + if (response.url) { + window.location.href = response.url; + } } From 638b5cb971ac6b6c3bdb8db64882e141c8d9c329 Mon Sep 17 00:00:00 2001 From: Anthony Date: Fri, 23 Apr 2021 22:00:28 +0200 Subject: [PATCH 02/18] continuing work on thumbnail --- app.js | 1 + controllers/backend/uploading.js | 59 ++++++++++++++++++++++++++------ routes.js | 2 +- views/uploading.pug | 30 +++++++++++----- 4 files changed, 71 insertions(+), 21 deletions(-) diff --git a/app.js b/app.js index 78326faf..67cb026a 100644 --- a/app.js +++ b/app.js @@ -227,6 +227,7 @@ if(cluster.isMaster){ requestPath === '/upload' || requestPath === '/account/profile' || requestPath === '/api/channel/thumbnail/delete' || + requestPath === '/api/uploadFileThumbnail' || requestPath.match(editUploadRegexp) || requestPath.match(deleteUploadThumbnailRegexp) || requestPath === '/livestream/on-live-auth' || diff --git a/controllers/backend/uploading.js b/controllers/backend/uploading.js index 0693f750..b47293fd 100644 --- a/controllers/backend/uploading.js +++ b/controllers/backend/uploading.js @@ -588,25 +588,32 @@ exports.postFileUpload = async(req, res) => { uploadLogger.info('Upload marked as complete', logObject); - updateUsersUnreadSubscriptions(user); - - uploadLogger.info('Updated subscribed users subscriptions', logObject); - // this is admin upload for all alertAdminOfNewUpload(user, upload); uploadLogger.info('Alert admins of a new upload', logObject); - if(upload.visibility == 'public'){ - // update user push notifications - updateUsersPushNotifications(user, upload); + // if visibility is public, send push and email notifications + if(upload.visibility === 'public'){ + + // update the subscription amount of subscribing users + updateUsersUnreadSubscriptions(user); - uploadLogger.info('Update users push notifications', logObject); + uploadLogger.info('Updated subscribed users subscriptions', logObject); - // update user email notifications - updateUsersEmailNotifications(user, upload, req.host); + // send push and email notifs if production + if(process.env.NODE_ENV === 'production'){ + // update user push notifications + updateUsersPushNotifications(user, upload); + + uploadLogger.info('Update users push notifications', logObject); + + // update user email notifications + updateUsersEmailNotifications(user, upload, req.host); + + uploadLogger.info('Update users email notifications', logObject); + } - uploadLogger.info('Update users email notifications', logObject); } // upload is complete, send it off to user (aboutToProcess is a misnomer here) @@ -740,5 +747,35 @@ exports.adminUpload = async(req, res) => { * Upload file thumbnail */ exports.postThumbnailUpload = async(req, res) => { + console.log('files') + console.log(req.files); + + + console.log('body') + console.log(req.body); + + + if(req.files && req.files.filetoupload){ + filename = req.files.filetoupload.originalFilename; + fileType = getMediaType(filename); + + fileExtension = path.extname(filename); + } + + // console.log(req.files); + // console.log(req.files.length); + + // + const fileIsNotImage = req.files && req.files.filetoupload && req.files.filetoupload.size > 0 && fileType && fileType !== 'image'; + + console.log('req files'); + console.log(req.files); + + // TODO: you have to make this smarter by checking the FileType + + const fileIsImage = req.files && req.files.filetoupload && req.files.filetoupload.size > 0 && fileType == 'image'; + + const imagePath = req.files && req.files.filetoupload && req.files.filetoupload.path; + // TODO: implement here } diff --git a/routes.js b/routes.js index 5a91fb66..d04d8db2 100644 --- a/routes.js +++ b/routes.js @@ -259,7 +259,7 @@ function frontendRoutes(app){ app.post('/api/upload/:uniqueTag/edit', passportConfig.isAuthenticated, internalApiController.editUpload); app.post('/api/upload/:uniqueTag/thumbnail/delete', passportConfig.isAuthenticated, internalApiController.deleteUploadThumbnail); app.post('/api/upload/:uniqueTag/captions/delete', passportConfig.isAuthenticated, internalApiController.deleteUploadCaption); - app.post('/api/thumbnailUpload', passportConfig.isAuthenticated, uploadingController.postThumbnailUpload); + app.post('/api/uploadFileThumbnail', passportConfig.isAuthenticated, uploadingController.postThumbnailUpload); /** API ENDPOINTS **/ diff --git a/views/uploading.pug b/views/uploading.pug index db7f4a6c..2d5e7bed 100644 --- a/views/uploading.pug +++ b/views/uploading.pug @@ -133,8 +133,8 @@ block content div(style="margin:0 auto;text-align:center;margin-bottom:11px;") h4.fw(style="margin-bottom:3px;font-size:17px;") (Optional) - label.fw(for='title' style="font-size:20px") Select A Thumbnail - input.btn.btn-primary.center-block.text-center.upload-thumbnail-input(data-max-size="500000000" type="file" id="filetoupload" name="filetoupload" accept="image/*" style="width:211px;border-radius:6px;") + label.fw(for='title' style="font-size:20px") Custom Thumbnail + input.btn.btn-primary.center-block.text-center.upload-thumbnail-input(data-max-size="500000000" type="file" id="filetoupload" name="filetoupload" accept="image/*" style="width:176px;border-radius:6px;font-size:11px;") br label.fw(for='title' style="font-size:20px") Select A Category @@ -457,13 +457,23 @@ block content var addThumbnailUrl = '/api/uploadFileThumbnail'; - if(thumbnailFile){ + if(!thumbnailFile){ + + // alert('no thumbnail url'); + if (response.url) { + window.location.href = response.url; + } + + } else { + + // alert('thumbnail url'); + $.ajax({ type: 'POST', url: addThumbnailUrl, processData: false, contentType: false, - data: thumbnailFile, + data: files, success: function (response) { console.log(response); @@ -475,15 +485,17 @@ block content error: function (err) { // hopefully this never happens? console.log(err); + + // alert('there was an error'); + + // no thumbnail added, just redirect to the url + // if (response.url) { + // window.location.href = response.url; + // } } }); - } else { - // no thumbnail added, just redirect to the url - if (response.url) { - window.location.href = response.url; - } } From 5cc7c1f5864c7e884fb3d3405cf0d5811b05bac9 Mon Sep 17 00:00:00 2001 From: Anthony Date: Sat, 24 Apr 2021 22:17:11 +0200 Subject: [PATCH 03/18] check file size on the frontend --- controllers/backend/uploading.js | 23 +++++++++++++++++------ views/uploading.pug | 30 +++++++++++++++++++++++++----- 2 files changed, 42 insertions(+), 11 deletions(-) diff --git a/controllers/backend/uploading.js b/controllers/backend/uploading.js index b47293fd..1b461440 100644 --- a/controllers/backend/uploading.js +++ b/controllers/backend/uploading.js @@ -754,19 +754,30 @@ exports.postThumbnailUpload = async(req, res) => { console.log('body') console.log(req.body); + // check if there's a thumbnail + let thumbnailFile; + + // if req there are files and + if(req.files && req.files.thumbnailFile){ + thumbnailFile = req.files.thumbnailFile; + } else { + res.status(500) + return res.send('no thumbnail file'); + } - if(req.files && req.files.filetoupload){ - filename = req.files.filetoupload.originalFilename; - fileType = getMediaType(filename); + const filename = thumbnailFile.originalFilename; + // size in bytes + const fileSize = thumbnailFile.size; - fileExtension = path.extname(filename); - } + fileType = getMediaType(filename); + + fileExtension = path.extname(filename); // console.log(req.files); // console.log(req.files.length); // - const fileIsNotImage = req.files && req.files.filetoupload && req.files.filetoupload.size > 0 && fileType && fileType !== 'image'; + const fileIsNotImage = req.files.filetoupload.size > 0 && fileType && fileType !== 'image'; console.log('req files'); console.log(req.files); diff --git a/views/uploading.pug b/views/uploading.pug index 2d5e7bed..4765747f 100644 --- a/views/uploading.pug +++ b/views/uploading.pug @@ -134,7 +134,7 @@ block content div(style="margin:0 auto;text-align:center;margin-bottom:11px;") h4.fw(style="margin-bottom:3px;font-size:17px;") (Optional) label.fw(for='title' style="font-size:20px") Custom Thumbnail - input.btn.btn-primary.center-block.text-center.upload-thumbnail-input(data-max-size="500000000" type="file" id="filetoupload" name="filetoupload" accept="image/*" style="width:176px;border-radius:6px;font-size:11px;") + input.btn.btn-primary.center-block.text-center.upload-thumbnail-input(data-max-size="5000000" type="file" id="filetoupload" name="filetoupload" accept="image/*" style="width:176px;border-radius:6px;font-size:11px;") br label.fw(for='title' style="font-size:20px") Select A Category @@ -230,6 +230,22 @@ block content script. $(document).ready(function () { + function checkIfFileSizeAcceptable(){ + var fileInput = $('#filetoupload'); + + var maxSize = fileInput.data('max-size'); + + if (fileInput.get(0).files.length) { + var fileSize = fileInput.get(0).files[0].size; // in bytes + + if (fileSize > maxSize) { + return false; + } else { + return true + } + } + } + // focus the button so you can just click enter to start uploading $('.resumable-browser').focus(); @@ -284,8 +300,6 @@ block content console.log(value, displayName); }) - - var privs = #{user.privs} var maxSize; @@ -294,7 +308,6 @@ block content maxSize = '#{user.privs.uploadSize}' || 500; } else { maxSize = 500; - } var maxSizeInBytes = maxSize * 1000000 @@ -370,6 +383,12 @@ block content $('.submit-button').on('click', function (e) { + const fileSizeAcceptable = checkIfFileSizeAcceptable() + + if(!fileSizeAcceptable){ + return swal('Please select a thumbnail under 5MB'); + } + var title = $('#title').val(); var description = $('#description').val(); @@ -453,7 +472,7 @@ block content let files = new FormData(); - files.append('fileName', thumbnailFile) + files.append('thumbnailFile', thumbnailFile) var addThumbnailUrl = '/api/uploadFileThumbnail'; @@ -606,3 +625,4 @@ block content }, 1000 * 1) } }); + From cb92cf0256d392c7e15a403c8ae7c68588dbfd9e Mon Sep 17 00:00:00 2001 From: Anthony Date: Sun, 25 Apr 2021 22:06:09 +0200 Subject: [PATCH 04/18] completing add thumbnail on upload --- controllers/backend/uploading.js | 59 ++- package-lock.json | 26 ++ package.json | 1 + views/pugJavascript/uploadingJavascript.pug | 414 ++++++++++++++++++++ views/uploading.pug | 404 +------------------ 5 files changed, 490 insertions(+), 414 deletions(-) create mode 100644 views/pugJavascript/uploadingJavascript.pug diff --git a/controllers/backend/uploading.js b/controllers/backend/uploading.js index 1b461440..a58769d9 100644 --- a/controllers/backend/uploading.js +++ b/controllers/backend/uploading.js @@ -10,6 +10,8 @@ const path = require('path'); const mkdirp = Promise.promisifyAll(require('mkdirp')); var randomstring = require('randomstring'); var CombinedStream = require('combined-stream'); +const FileType = require('file-type'); +const readChunk = require('read-chunk'); const redisClient = require('../../config/redis'); @@ -769,24 +771,57 @@ exports.postThumbnailUpload = async(req, res) => { // size in bytes const fileSize = thumbnailFile.size; - fileType = getMediaType(filename); + // 5 MB + if(fileSize > 5242880){ + res.status(500); + res.send('file too large'); + } - fileExtension = path.extname(filename); + const filePath = thumbnailFile.path; - // console.log(req.files); - // console.log(req.files.length); + const buffer = readChunk.sync(filePath, 0, 4100); - // - const fileIsNotImage = req.files.filetoupload.size > 0 && fileType && fileType !== 'image'; + const bufferFileType = await FileType.fromBuffer(buffer); - console.log('req files'); - console.log(req.files); + console.log('Buffer file type ' + bufferFileType); + + const extension = '.' + String(bufferFileType.ext); + + console.log('extension'); + console.log(extension) + + const fileType = getMediaType('hackforsetup' + extension); + + if(fileType !== 'image'){ + res.status(500); + res.send('not an image'); + } + + console.log('File type'); + console.log(fileType); + + + + console.log(bufferFileType); + + const channelUrl = req.user.channelUrl; + + const saveFileDirectory = `${saveAndServeFilesDirectory}/${channelUrl}/${upload.uniqueTag}-custom${extension}`; + + await fs.move(filePath, saveFileDirectory); + + upload.thumbnails.custom = `${upload.uniqueTag}-custom${extension}`; + + if(process.env.UPLOAD_TO_B2 === 'true'){ + // TODO: check this + // await backblaze.editploadThumbnailToB2(req.user.channelUrl, upload.uniqueTag, extension, saveFileDirectory); + } + + // sendUploadThumbnailToB2(args) - // TODO: you have to make this smarter by checking the FileType + await upload.save(); - const fileIsImage = req.files && req.files.filetoupload && req.files.filetoupload.size > 0 && fileType == 'image'; + return res.send('success'); - const imagePath = req.files && req.files.filetoupload && req.files.filetoupload.path; - // TODO: implement here } diff --git a/package-lock.json b/package-lock.json index e6cf1b97..92c1d79e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8716,6 +8716,15 @@ "mute-stream": "~0.0.4" } }, + "read-chunk": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/read-chunk/-/read-chunk-3.2.0.tgz", + "integrity": "sha512-CEjy9LCzhmD7nUpJ1oVOE6s/hBkejlcJEgLQHVnQznOSilOPb+kpKktlLfFDK3/WP43+F80xkUTM2VOkYoSYvQ==", + "requires": { + "pify": "^4.0.1", + "with-open-file": "^0.1.6" + } + }, "read-pkg": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", @@ -11572,6 +11581,23 @@ "resolved": "https://registry.npmjs.org/with-callback/-/with-callback-1.0.2.tgz", "integrity": "sha1-oJYpuakgAo1yFAT7Q1vc/1yRvCE=" }, + "with-open-file": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/with-open-file/-/with-open-file-0.1.7.tgz", + "integrity": "sha512-ecJS2/oHtESJ1t3ZfMI3B7KIDKyfN0O16miWxdn30zdh66Yd3LsRFebXZXq6GU4xfxLf6nVxp9kIqElb5fqczA==", + "requires": { + "p-finally": "^1.0.0", + "p-try": "^2.1.0", + "pify": "^4.0.1" + }, + "dependencies": { + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" + } + } + }, "word-wrap": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", diff --git a/package.json b/package.json index f926a73c..359a3b93 100644 --- a/package.json +++ b/package.json @@ -108,6 +108,7 @@ "paypal-rest-sdk": "^1.8.1", "pug": "^2.0.3", "randomstring": "^1.1.5", + "read-chunk": "^3.2.0", "recaptcha2": "^1.3.3", "redis": "^2.8.0", "request": "^2.88.0", diff --git a/views/pugJavascript/uploadingJavascript.pug b/views/pugJavascript/uploadingJavascript.pug new file mode 100644 index 00000000..ffcfeb3a --- /dev/null +++ b/views/pugJavascript/uploadingJavascript.pug @@ -0,0 +1,414 @@ +script(src='/js/lib/jquery-3.1.1.min.js') +script(src='/js/lib/resumable.js') +script. + $(document).ready(function () { + + function checkIfFileSizeAcceptable(){ + var fileInput = $('#filetoupload'); + + var maxSize = fileInput.data('max-size'); + + if (fileInput.get(0).files.length) { + var fileSize = fileInput.get(0).files[0].size; // in bytes + + if (fileSize > maxSize) { + return false; + } else { + return true + } + } + } + + // focus the button so you can just click enter to start uploading + $('.resumable-browser').focus(); + + // scroll down and focus description when category is changed + $('.categoryValue').on('click', function(){ + $('#description').focus() + // have to do a setTimeout for event loop + setTimeout(function(){ + document.getElementById('categoryName').scrollIntoView({ behavior: 'smooth' }); + }, 1) + }) + + // scroll down and focus description when category is changed + $('.subcategoryOption').on('click', function () { + $('#description').focus() + // TODO: would be better if it scrolled down just a smidge to visually bring attention back to description + setTimeout(function () { + document.getElementById('description').scrollIntoView({behavior: 'smooth'}); + }, 1) + }) + + // progress bar stuff + var bar1 = new ldBar("#myItem1"); + + var selectedCategory; + var selectedSubcategory; + + // hide uploading gif + $(".upload-gif").hide(); + + // when a new category is selected + $('.categoryValue').click(function(){ + var value = $(this).data("value"); + + var displayName = $(this).data("displayname"); + + // hide all subcategories + $('.subcategories').hide(); + + selectedCategory = value; + + // display selected category + $('.categoryDisplayName').text('Category: ' + displayName) + + // show subcategories if they exist + $('.categoryName').show(); + $('.' + value).show(); + + + + + console.log(value, displayName); + }) + + var privs = #{user.privs} + + var maxSize; + + if(privs){ + maxSize = '#{user.privs.uploadSize}' || 500; + } else { + maxSize = 500; + } + + var maxSizeInBytes = maxSize * 1000000 + + console.log(maxSizeInBytes) + + // set chunk size to 25MB + var chunkSize = 1000 * 1000 * 25; + + // on submit, build a resumable, and then fire it off + + var r = new Resumable({ + target: '#{uploadUrl}', + chunkSize: chunkSize, + simultaneousUploads: 1, + testChunks: false, + throttleProgressCallbacks: 1, + maxFiles: 1, + maxFileSize: maxSizeInBytes, + maxFileSizeErrorCallback: function (file, errorCount) { + swal(`Please upload a file smaller than ${maxSize} MB`); + // console.log(file); + } + + }); + + // Resumable.js isn't supported, fall back on a different method + if (!r.support) { + swal('Sorry, your browser isn\'t supported currently, please update your browser'); + } else { + var setProgressAndTimeRemaining = null; + var barProgress = null; + var estimatedUploadTimeLeft = null; + var secondsElapsed = null; + + r.assignBrowse($('.resumable-browse')[0]); + + r.assignDrop(document.getElementById('dropTarget')); + + // Handle file add event + + r.on('fileAdded', function (file) { + + var fileType = file.file.type.split('/')[0]; + + if(fileType === 'video' || fileType === 'audio'){ + $('#customThumbnailDiv').show(); + } else if (fileType === 'image') { + $('#customThumbnailDiv').hide(); + } + + console.log('filetype'); + console.log(fileType); + + console.log(file); + + // replace underlines with spaces just to be nice + var fileName = file.fileName.replace(/_/g, " "); + + fileName = fileName.substring(0, fileName.lastIndexOf('.')); + + var title = $('#title').val(); + + console.log(title); + + if(!title || title == ""){ + $('#title').val(fileName); + } + + // scroll to the div when file selected + document.getElementById('scrollTo').scrollIntoView({behavior: 'smooth'}); + + + // have to use setTimeout for event loop + setTimeout(function(){ + + // focus and scroll down the div + $('#title').focus(); + }, 750) + + // auto fill in title + + // console.log(file); + + }); + + $('.submit-button').on('click', function (e) { + + const fileSizeAcceptable = checkIfFileSizeAcceptable() + + if(!fileSizeAcceptable){ + return swal('Please select a thumbnail under 5MB'); + } + + var title = $('#title').val(); + var description = $('#description').val(); + + var visibility = $('input[name=visibility]:checked').val(); + var rating = $(".rating label input[type='radio']:checked").val(); + + var subcategory = $(".subcategory label input[type='radio']:checked").val(); + + if(!rating){ + return swal('Please select a rating') + } + + if(!visibility){ + visibility = 'public' + } + + $('.upload-title-name').text('File: ' + title); + + if (r.files.length == 0) { + swal('Please select a file') + return + } + + if (title == '') { + swal('Please enter a title') + return + } + + // HIDE FORM SHOW GIF + $(".upload-form").hide(); + + $('.upload-information').hide(); + + $(".upload-gif").show(); + + + + var uploadToken = '#{user.uploadToken}' + + r.opts.query = { + title, + description, + uploadToken, + visibility, + rating, + category: selectedCategory, + subcategory + }; + + r.upload(); + + $('.file-progress').html('BEGINNING UPLOAD...'); + }); + + + // when receiving a success response from the backend + r.on('fileSuccess', function (file, response) { + + console.log('message:') + console.log(response); + + response = JSON.parse(response); + + if(response.message == 'ALREADY-UPLOADED'){ + // HIDE FORM SHOW GIF + $(".upload-form").show(); + $(".upload-gif").hide(); + + + $('.upload-information').show(); + + + // auto fill in title + $('#title').val(''); + return swal({ title: 'File Already Uploaded', text: 'Sorry, this file has already been uploaded, please try another'}, function(){ + window.location.href = '/upload' + }) + } + + var thumbnailFile = $('#filetoupload')[0].files[0] + + let files = new FormData(); + + files.append('thumbnailFile', thumbnailFile) + + var addThumbnailUrl = '/api/uploadFileThumbnail'; + + if(!thumbnailFile){ + + // alert('no thumbnail url'); + if (response.url) { + window.location.href = response.url; + } + + } else { + + // alert('thumbnail url'); + + $.ajax({ + type: 'POST', + url: addThumbnailUrl, + processData: false, + contentType: false, + data: files, + success: function (response) { + console.log(response); + + if (response.url) { + window.location.href = response.url; + } + + }, + error: function (err) { + // hopefully this never happens? + console.log(err); + + // alert('there was an error'); + + // no thumbnail added, just redirect to the url + // if (response.url) { + // window.location.href = response.url; + // } + } + }); + + + } + + + // Reflect that the file upload has completed + $('.file-progress').html('UPLOAD COMPLETED'); + }); + + + // if receiving an error from the backend + r.on('fileError', function (file, response) { + + response = JSON.parse(response); + + console.log(response.message); + + console.log('file error'); + + if (response.message == 'UNKNOWN-FILETYPE') { + // HIDE FORM SHOW GIF + $(".upload-form").show(); + $(".upload-gif").hide(); + $('.upload-information').show(); + + + // auto fill in title + $('#title').val(''); + return swal({ + title: 'File Type Not Supported', + text: 'Sorry, this file type is not supported, please try another file' + }, function () { + window.location.href = '/upload' + }) + } + + if (response.message == 'ALREADY-UPLOADED') { + // HIDE FORM SHOW GIF + $(".upload-form").show(); + $(".upload-gif").hide(); + $('.upload-information').show(); + + + // auto fill in title + $('#title').val(''); + return swal({ + title: 'File Already Uploaded', + text: 'Sorry, this file has already been uploaded, please try another' + }, function () { + window.location.href = '/upload' + }) + } + + if (response.message == 'UPLOADS_OFF') { + // HIDE FORM SHOW GIF + $(".upload-form").show(); + $(".upload-gif").hide(); + + // auto fill in title + $('#title').val(''); + return swal({ + title: 'Uploads Temporarily Off', + text: 'Sorry uploads are temporarily turned off (only app moderator is offline)' + }, function () { + window.location.href = '/upload' + }) + } + + // Reflect that the file upload has resulted in error + $('.file-progress').html('File could not be uploaded: (' + response.message + ')'); + }); + r.on('fileProgress', function (file, response) { + + const progress = Math.floor(file.progress() * 100); + + if (progress === 0 || progress === '0') { + uploadStartTime = new Date() + $('.file-progress').html('BEGINNING UPLOAD...'); + } else { + secondsElapsed = Math.round((new Date() - uploadStartTime) / 1000) + const progressSpeed = (file.progress() * 100) / secondsElapsed + + estimatedUploadSecondsLeft = Math.ceil((100 - (file.progress() * 100)) / progressSpeed) + + barProgress = progress + } + }); + + setInterval(function() { + if (barProgress) { + $('.file-progress').html('PROGRESS: ' + barProgress + '%'); + + bar1.set(barProgress); + + var secondsToFormattedTime = #{secondsToFormattedTime} + estimatedUploadSecondsLeft = estimatedUploadSecondsLeft > 0 ? estimatedUploadSecondsLeft - 1 : 0 + secondsElapsed += 1 + + var formattedElapsedTime = secondsElapsed && secondsToFormattedTime(secondsElapsed) + var formattedTimeLeft = estimatedUploadSecondsLeft !== null && secondsToFormattedTime(estimatedUploadSecondsLeft) + var formattedTotalEstimatedProcessingTime = estimatedUploadSecondsLeft !== null && secondsToFormattedTime(estimatedUploadSecondsLeft + secondsElapsed) + + $('#uploadTimeElapsed').text(`Time elapsed: ${formattedElapsedTime ? formattedElapsedTime : "calculating ..."}`) + + $('#estimatedUploadTimeLeft').text(`Estimated time to completion: ${formattedTimeLeft ? formattedTimeLeft : "calculating ..." }`); + } + + $('#estimatedTotalUploadTime').text(`Total estimated upload time: ${formattedTotalEstimatedProcessingTime ? formattedTotalEstimatedProcessingTime : "calculating ..."}`) + + }, 1000 * 1) + } + }); + diff --git a/views/uploading.pug b/views/uploading.pug index 4765747f..457bac06 100644 --- a/views/uploading.pug +++ b/views/uploading.pug @@ -131,7 +131,7 @@ block content | Private br - div(style="margin:0 auto;text-align:center;margin-bottom:11px;") + div#customThumbnailDiv(style="margin:0 auto;text-align:center;margin-bottom:11px;display:none;") h4.fw(style="margin-bottom:3px;font-size:17px;") (Optional) label.fw(for='title' style="font-size:20px") Custom Thumbnail input.btn.btn-primary.center-block.text-center.upload-thumbnail-input(data-max-size="5000000" type="file" id="filetoupload" name="filetoupload" accept="image/*" style="width:176px;border-radius:6px;font-size:11px;") @@ -225,404 +225,4 @@ block content - script(src='/js/lib/jquery-3.1.1.min.js') - script(src='/js/lib/resumable.js') - script. - $(document).ready(function () { - - function checkIfFileSizeAcceptable(){ - var fileInput = $('#filetoupload'); - - var maxSize = fileInput.data('max-size'); - - if (fileInput.get(0).files.length) { - var fileSize = fileInput.get(0).files[0].size; // in bytes - - if (fileSize > maxSize) { - return false; - } else { - return true - } - } - } - - // focus the button so you can just click enter to start uploading - $('.resumable-browser').focus(); - - // scroll down and focus description when category is changed - $('.categoryValue').on('click', function(){ - $('#description').focus() - // have to do a setTimeout for event loop - setTimeout(function(){ - document.getElementById('categoryName').scrollIntoView({ behavior: 'smooth' }); - }, 1) - }) - - // scroll down and focus description when category is changed - $('.subcategoryOption').on('click', function () { - $('#description').focus() - // TODO: would be better if it scrolled down just a smidge to visually bring attention back to description - setTimeout(function () { - document.getElementById('description').scrollIntoView({behavior: 'smooth'}); - }, 1) - }) - - // progress bar stuff - var bar1 = new ldBar("#myItem1"); - - var selectedCategory; - var selectedSubcategory; - - // hide uploading gif - $(".upload-gif").hide(); - - // when a new category is selected - $('.categoryValue').click(function(){ - var value = $(this).data("value"); - - var displayName = $(this).data("displayname"); - - // hide all subcategories - $('.subcategories').hide(); - - selectedCategory = value; - - // display selected category - $('.categoryDisplayName').text('Category: ' + displayName) - - // show subcategories if they exist - $('.categoryName').show(); - $('.' + value).show(); - - - - - console.log(value, displayName); - }) - - var privs = #{user.privs} - - var maxSize; - - if(privs){ - maxSize = '#{user.privs.uploadSize}' || 500; - } else { - maxSize = 500; - } - - var maxSizeInBytes = maxSize * 1000000 - - console.log(maxSizeInBytes) - - // set chunk size to 25MB - var chunkSize = 1000 * 1000 * 25; - - // on submit, build a resumable, and then fire it off - - var r = new Resumable({ - target: '#{uploadUrl}', - chunkSize: chunkSize, - simultaneousUploads: 1, - testChunks: false, - throttleProgressCallbacks: 1, - maxFiles: 1, - maxFileSize: maxSizeInBytes, - maxFileSizeErrorCallback: function (file, errorCount) { - swal(`Please upload a file smaller than ${maxSize} MB`); - // console.log(file); - } - - }); - - // Resumable.js isn't supported, fall back on a different method - if (!r.support) { - swal('Sorry, your browser isn\'t supported currently, please update your browser'); - } else { - var setProgressAndTimeRemaining = null; - var barProgress = null; - var estimatedUploadTimeLeft = null; - var secondsElapsed = null; - - r.assignBrowse($('.resumable-browse')[0]); - - r.assignDrop(document.getElementById('dropTarget')); - - // Handle file add event - - r.on('fileAdded', function (file) { - - // replace underlines with spaces just to be nice - var fileName = file.fileName.replace(/_/g, " "); - - fileName = fileName.substring(0, fileName.lastIndexOf('.')); - - var title = $('#title').val(); - - console.log(title); - - if(!title || title == ""){ - $('#title').val(fileName); - } - - // scroll to the div when file selected - document.getElementById('scrollTo').scrollIntoView({behavior: 'smooth'}); - - - // have to use setTimeout for event loop - setTimeout(function(){ - - // focus and scroll down the div - $('#title').focus(); - }, 750) - - // auto fill in title - - // console.log(file); - - }); - - $('.submit-button').on('click', function (e) { - - const fileSizeAcceptable = checkIfFileSizeAcceptable() - - if(!fileSizeAcceptable){ - return swal('Please select a thumbnail under 5MB'); - } - - var title = $('#title').val(); - var description = $('#description').val(); - - var visibility = $('input[name=visibility]:checked').val(); - var rating = $(".rating label input[type='radio']:checked").val(); - - var subcategory = $(".subcategory label input[type='radio']:checked").val(); - - if(!rating){ - return swal('Please select a rating') - } - - if(!visibility){ - visibility = 'public' - } - - $('.upload-title-name').text('File: ' + title); - - if (r.files.length == 0) { - swal('Please select a file') - return - } - - if (title == '') { - swal('Please enter a title') - return - } - - // HIDE FORM SHOW GIF - $(".upload-form").hide(); - - $('.upload-information').hide(); - - $(".upload-gif").show(); - - - - var uploadToken = '#{user.uploadToken}' - - r.opts.query = { - title, - description, - uploadToken, - visibility, - rating, - category: selectedCategory, - subcategory - }; - - r.upload(); - - $('.file-progress').html('BEGINNING UPLOAD...'); - }); - - - // when receiving a success response from the backend - r.on('fileSuccess', function (file, response) { - - console.log('message:') - console.log(response); - - response = JSON.parse(response); - - if(response.message == 'ALREADY-UPLOADED'){ - // HIDE FORM SHOW GIF - $(".upload-form").show(); - $(".upload-gif").hide(); - - - $('.upload-information').show(); - - - // auto fill in title - $('#title').val(''); - return swal({ title: 'File Already Uploaded', text: 'Sorry, this file has already been uploaded, please try another'}, function(){ - window.location.href = '/upload' - }) - } - - var thumbnailFile = $('#filetoupload')[0].files[0] - - let files = new FormData(); - - files.append('thumbnailFile', thumbnailFile) - - var addThumbnailUrl = '/api/uploadFileThumbnail'; - - if(!thumbnailFile){ - - // alert('no thumbnail url'); - if (response.url) { - window.location.href = response.url; - } - - } else { - - // alert('thumbnail url'); - - $.ajax({ - type: 'POST', - url: addThumbnailUrl, - processData: false, - contentType: false, - data: files, - success: function (response) { - console.log(response); - - if (response.url) { - window.location.href = response.url; - } - - }, - error: function (err) { - // hopefully this never happens? - console.log(err); - - // alert('there was an error'); - - // no thumbnail added, just redirect to the url - // if (response.url) { - // window.location.href = response.url; - // } - } - }); - - - } - - - // Reflect that the file upload has completed - $('.file-progress').html('UPLOAD COMPLETED'); - }); - - - // if receiving an error from the backend - r.on('fileError', function (file, response) { - - response = JSON.parse(response); - - console.log(response.message); - - console.log('file error'); - - if (response.message == 'UNKNOWN-FILETYPE') { - // HIDE FORM SHOW GIF - $(".upload-form").show(); - $(".upload-gif").hide(); - $('.upload-information').show(); - - - // auto fill in title - $('#title').val(''); - return swal({ - title: 'File Type Not Supported', - text: 'Sorry, this file type is not supported, please try another file' - }, function () { - window.location.href = '/upload' - }) - } - - if (response.message == 'ALREADY-UPLOADED') { - // HIDE FORM SHOW GIF - $(".upload-form").show(); - $(".upload-gif").hide(); - $('.upload-information').show(); - - - // auto fill in title - $('#title').val(''); - return swal({ - title: 'File Already Uploaded', - text: 'Sorry, this file has already been uploaded, please try another' - }, function () { - window.location.href = '/upload' - }) - } - - if (response.message == 'UPLOADS_OFF') { - // HIDE FORM SHOW GIF - $(".upload-form").show(); - $(".upload-gif").hide(); - - // auto fill in title - $('#title').val(''); - return swal({ - title: 'Uploads Temporarily Off', - text: 'Sorry uploads are temporarily turned off (only app moderator is offline)' - }, function () { - window.location.href = '/upload' - }) - } - - // Reflect that the file upload has resulted in error - $('.file-progress').html('File could not be uploaded: (' + response.message + ')'); - }); - r.on('fileProgress', function (file, response) { - - const progress = Math.floor(file.progress() * 100); - - if (progress === 0 || progress === '0') { - uploadStartTime = new Date() - $('.file-progress').html('BEGINNING UPLOAD...'); - } else { - secondsElapsed = Math.round((new Date() - uploadStartTime) / 1000) - const progressSpeed = (file.progress() * 100) / secondsElapsed - - estimatedUploadSecondsLeft = Math.ceil((100 - (file.progress() * 100)) / progressSpeed) - - barProgress = progress - } - }); - - setInterval(function() { - if (barProgress) { - $('.file-progress').html('PROGRESS: ' + barProgress + '%'); - - bar1.set(barProgress); - - var secondsToFormattedTime = #{secondsToFormattedTime} - estimatedUploadSecondsLeft = estimatedUploadSecondsLeft > 0 ? estimatedUploadSecondsLeft - 1 : 0 - secondsElapsed += 1 - - var formattedElapsedTime = secondsElapsed && secondsToFormattedTime(secondsElapsed) - var formattedTimeLeft = estimatedUploadSecondsLeft !== null && secondsToFormattedTime(estimatedUploadSecondsLeft) - var formattedTotalEstimatedProcessingTime = estimatedUploadSecondsLeft !== null && secondsToFormattedTime(estimatedUploadSecondsLeft + secondsElapsed) - - $('#uploadTimeElapsed').text(`Time elapsed: ${formattedElapsedTime ? formattedElapsedTime : "calculating ..."}`) - - $('#estimatedUploadTimeLeft').text(`Estimated time to completion: ${formattedTimeLeft ? formattedTimeLeft : "calculating ..." }`); - } - - $('#estimatedTotalUploadTime').text(`Total estimated upload time: ${formattedTotalEstimatedProcessingTime ? formattedTotalEstimatedProcessingTime : "calculating ..."}`) - - }, 1000 * 1) - } - }); - + include pugJavascript/uploadingJavascript From 811b1245a1a5b1138851445a1064abb1c62c4eae Mon Sep 17 00:00:00 2001 From: Anthony Date: Sun, 25 Apr 2021 22:18:10 +0200 Subject: [PATCH 05/18] working but one bug --- controllers/backend/uploading.js | 9 +++++++-- views/pugJavascript/uploadingJavascript.pug | 17 +++++++++-------- 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/controllers/backend/uploading.js b/controllers/backend/uploading.js index a58769d9..b5aff39e 100644 --- a/controllers/backend/uploading.js +++ b/controllers/backend/uploading.js @@ -756,6 +756,8 @@ exports.postThumbnailUpload = async(req, res) => { console.log('body') console.log(req.body); + const uniqueTag = req.body.uploadUniqueTag; + // check if there's a thumbnail let thumbnailFile; @@ -785,6 +787,7 @@ exports.postThumbnailUpload = async(req, res) => { console.log('Buffer file type ' + bufferFileType); + // comes back at 'mp4' to prepend . to make .mp4 const extension = '.' + String(bufferFileType.ext); console.log('extension'); @@ -806,11 +809,11 @@ exports.postThumbnailUpload = async(req, res) => { const channelUrl = req.user.channelUrl; - const saveFileDirectory = `${saveAndServeFilesDirectory}/${channelUrl}/${upload.uniqueTag}-custom${extension}`; + const saveFileDirectory = `${saveAndServeFilesDirectory}/${channelUrl}/${uniqueTag}-custom${extension}`; await fs.move(filePath, saveFileDirectory); - upload.thumbnails.custom = `${upload.uniqueTag}-custom${extension}`; + upload.thumbnails.custom = `${uniqueTag}-custom${extension}`; if(process.env.UPLOAD_TO_B2 === 'true'){ // TODO: check this @@ -821,6 +824,8 @@ exports.postThumbnailUpload = async(req, res) => { await upload.save(); + res.status(200); + return res.send('success'); diff --git a/views/pugJavascript/uploadingJavascript.pug b/views/pugJavascript/uploadingJavascript.pug index ffcfeb3a..ba10be7d 100644 --- a/views/pugJavascript/uploadingJavascript.pug +++ b/views/pugJavascript/uploadingJavascript.pug @@ -238,6 +238,8 @@ script. response = JSON.parse(response); + var redirectUrl = response.url + if(response.message == 'ALREADY-UPLOADED'){ // HIDE FORM SHOW GIF $(".upload-form").show(); @@ -260,14 +262,15 @@ script. files.append('thumbnailFile', thumbnailFile) + files.append('uploadUniqueTag', response.uniqueTag) + var addThumbnailUrl = '/api/uploadFileThumbnail'; + // if there's thumbnail file, just redirect if(!thumbnailFile){ // alert('no thumbnail url'); - if (response.url) { - window.location.href = response.url; - } + window.location.href = response.url; } else { @@ -282,8 +285,8 @@ script. success: function (response) { console.log(response); - if (response.url) { - window.location.href = response.url; + if (response === 'success') { + window.location.href = response.url } }, @@ -294,9 +297,7 @@ script. // alert('there was an error'); // no thumbnail added, just redirect to the url - // if (response.url) { - // window.location.href = response.url; - // } + window.location.href = response.url } }); From 34a020b3b1d592438463905c40475fc36534f5fb Mon Sep 17 00:00:00 2001 From: Anthony Date: Sun, 25 Apr 2021 23:01:22 +0200 Subject: [PATCH 06/18] couple last bug fixes --- controllers/backend/uploading.js | 4 ++-- views/pugJavascript/uploadingJavascript.pug | 20 +++++++++++++++++--- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/controllers/backend/uploading.js b/controllers/backend/uploading.js index b5aff39e..82168f22 100644 --- a/controllers/backend/uploading.js +++ b/controllers/backend/uploading.js @@ -776,7 +776,7 @@ exports.postThumbnailUpload = async(req, res) => { // 5 MB if(fileSize > 5242880){ res.status(500); - res.send('file too large'); + return res.send('file too large'); } const filePath = thumbnailFile.path; @@ -797,7 +797,7 @@ exports.postThumbnailUpload = async(req, res) => { if(fileType !== 'image'){ res.status(500); - res.send('not an image'); + return res.send('not an image'); } console.log('File type'); diff --git a/views/pugJavascript/uploadingJavascript.pug b/views/pugJavascript/uploadingJavascript.pug index ba10be7d..db1210b0 100644 --- a/views/pugJavascript/uploadingJavascript.pug +++ b/views/pugJavascript/uploadingJavascript.pug @@ -4,18 +4,30 @@ script. $(document).ready(function () { function checkIfFileSizeAcceptable(){ - var fileInput = $('#filetoupload'); + var fileInput = $('.upload-thumbnail-input'); var maxSize = fileInput.data('max-size'); + console.log('max size'); + + console.log(maxSize); + + + if (fileInput.get(0).files.length) { var fileSize = fileInput.get(0).files[0].size; // in bytes + console.log('file size'); + + console.log(fileSize) + if (fileSize > maxSize) { return false; } else { return true } + } else { + return true } } @@ -286,7 +298,7 @@ script. console.log(response); if (response === 'success') { - window.location.href = response.url + window.location.href = redirectUrl } }, @@ -297,7 +309,7 @@ script. // alert('there was an error'); // no thumbnail added, just redirect to the url - window.location.href = response.url + window.location.href = redirectUrl } }); @@ -371,6 +383,8 @@ script. // Reflect that the file upload has resulted in error $('.file-progress').html('File could not be uploaded: (' + response.message + ')'); }); + + r.on('fileProgress', function (file, response) { const progress = Math.floor(file.progress() * 100); From 0b4b18563cad8f7e7a6b727be9ab0e55b2653d40 Mon Sep 17 00:00:00 2001 From: Anthony Date: Sun, 25 Apr 2021 23:01:43 +0200 Subject: [PATCH 07/18] eslint fix --- controllers/backend/uploading.js | 15 +++++---------- routes.js | 1 - 2 files changed, 5 insertions(+), 11 deletions(-) diff --git a/controllers/backend/uploading.js b/controllers/backend/uploading.js index 82168f22..725c919b 100644 --- a/controllers/backend/uploading.js +++ b/controllers/backend/uploading.js @@ -743,17 +743,15 @@ exports.adminUpload = async(req, res) => { }; - /** * POST /api/uploadFileThumbnail * Upload file thumbnail */ exports.postThumbnailUpload = async(req, res) => { - console.log('files') + console.log('files'); console.log(req.files); - - console.log('body') + console.log('body'); console.log(req.body); const uniqueTag = req.body.uploadUniqueTag; @@ -765,7 +763,7 @@ exports.postThumbnailUpload = async(req, res) => { if(req.files && req.files.thumbnailFile){ thumbnailFile = req.files.thumbnailFile; } else { - res.status(500) + res.status(500); return res.send('no thumbnail file'); } @@ -791,7 +789,7 @@ exports.postThumbnailUpload = async(req, res) => { const extension = '.' + String(bufferFileType.ext); console.log('extension'); - console.log(extension) + console.log(extension); const fileType = getMediaType('hackforsetup' + extension); @@ -803,8 +801,6 @@ exports.postThumbnailUpload = async(req, res) => { console.log('File type'); console.log(fileType); - - console.log(bufferFileType); const channelUrl = req.user.channelUrl; @@ -828,5 +824,4 @@ exports.postThumbnailUpload = async(req, res) => { return res.send('success'); - -} +}; diff --git a/routes.js b/routes.js index d04d8db2..c1615a5a 100644 --- a/routes.js +++ b/routes.js @@ -261,7 +261,6 @@ function frontendRoutes(app){ app.post('/api/upload/:uniqueTag/captions/delete', passportConfig.isAuthenticated, internalApiController.deleteUploadCaption); app.post('/api/uploadFileThumbnail', passportConfig.isAuthenticated, uploadingController.postThumbnailUpload); - /** API ENDPOINTS **/ app.post('/api/react/:upload/:user', passportConfig.isAuthenticated, internalApiController.react); From 74922ea809af492e9aca2627dc26afac150f844c Mon Sep 17 00:00:00 2001 From: Anthony Date: Sun, 25 Apr 2021 23:13:54 +0200 Subject: [PATCH 08/18] make the check on change --- views/pugJavascript/uploadingJavascript.pug | 48 +++++++++++---------- 1 file changed, 26 insertions(+), 22 deletions(-) diff --git a/views/pugJavascript/uploadingJavascript.pug b/views/pugJavascript/uploadingJavascript.pug index db1210b0..46a68751 100644 --- a/views/pugJavascript/uploadingJavascript.pug +++ b/views/pugJavascript/uploadingJavascript.pug @@ -1,35 +1,45 @@ script(src='/js/lib/jquery-3.1.1.min.js') script(src='/js/lib/resumable.js') script. - $(document).ready(function () { - - function checkIfFileSizeAcceptable(){ - var fileInput = $('.upload-thumbnail-input'); - var maxSize = fileInput.data('max-size'); + function checkIfFileSizeAcceptable() { + var fileInput = $('.upload-thumbnail-input'); - console.log('max size'); + var maxSize = fileInput.data('max-size'); - console.log(maxSize); + console.log('max size'); + console.log(maxSize); - if (fileInput.get(0).files.length) { - var fileSize = fileInput.get(0).files[0].size; // in bytes + if (fileInput.get(0).files.length) { + var fileSize = fileInput.get(0).files[0].size; // in bytes - console.log('file size'); + console.log('file size'); - console.log(fileSize) + console.log(fileSize) - if (fileSize > maxSize) { - return false; - } else { - return true - } + if (fileSize > maxSize) { + return false; } else { return true } + } else { + return true } + } + + $(document).ready(function () { + + $('.upload-thumbnail-input').on('change', function () { + const fileSizeAcceptable = checkIfFileSizeAcceptable() + + if (!fileSizeAcceptable) { + $(this).val(null); + + return swal('Please select a thumbnail under 5MB'); + } + }); // focus the button so you can just click enter to start uploading $('.resumable-browser').focus(); @@ -181,12 +191,6 @@ script. $('.submit-button').on('click', function (e) { - const fileSizeAcceptable = checkIfFileSizeAcceptable() - - if(!fileSizeAcceptable){ - return swal('Please select a thumbnail under 5MB'); - } - var title = $('#title').val(); var description = $('#description').val(); From cb519465b44b401f200efd5ffc581bb80de8ee22 Mon Sep 17 00:00:00 2001 From: Anthony Date: Sun, 25 Apr 2021 23:26:14 +0200 Subject: [PATCH 09/18] bugfix for converts --- controllers/backend/uploading.js | 6 ++++++ views/pugJavascript/uploadingJavascript.pug | 3 +++ views/uploading.pug | 1 + 3 files changed, 10 insertions(+) diff --git a/controllers/backend/uploading.js b/controllers/backend/uploading.js index 725c919b..f1f4c2e0 100644 --- a/controllers/backend/uploading.js +++ b/controllers/backend/uploading.js @@ -809,6 +809,12 @@ exports.postThumbnailUpload = async(req, res) => { await fs.move(filePath, saveFileDirectory); + const upload = await Upload.findOne({ uniqueTag }); + + if(!upload.thumbnails){ + upload.thumbnails = {}; + } + upload.thumbnails.custom = `${uniqueTag}-custom${extension}`; if(process.env.UPLOAD_TO_B2 === 'true'){ diff --git a/views/pugJavascript/uploadingJavascript.pug b/views/pugJavascript/uploadingJavascript.pug index 46a68751..0c4b9e33 100644 --- a/views/pugJavascript/uploadingJavascript.pug +++ b/views/pugJavascript/uploadingJavascript.pug @@ -39,6 +39,9 @@ script. return swal('Please select a thumbnail under 5MB'); } + + document.getElementById('scrollToThumbnail').scrollIntoView({behavior: 'smooth'}); + }); // focus the button so you can just click enter to start uploading diff --git a/views/uploading.pug b/views/uploading.pug index 457bac06..76519e21 100644 --- a/views/uploading.pug +++ b/views/uploading.pug @@ -131,6 +131,7 @@ block content | Private br + div#scrollToThumbnail div#customThumbnailDiv(style="margin:0 auto;text-align:center;margin-bottom:11px;display:none;") h4.fw(style="margin-bottom:3px;font-size:17px;") (Optional) label.fw(for='title' style="font-size:20px") Custom Thumbnail From 412c9fd1b241cb6a131177c2e7cb81a6ce44abe2 Mon Sep 17 00:00:00 2001 From: Anthony Date: Mon, 26 Apr 2021 16:14:34 +0200 Subject: [PATCH 10/18] couple of bug fixes --- controllers/backend/uploading.js | 2 ++ controllers/frontend/account.js | 45 ++++++-------------------------- views/uploading.pug | 11 +++++--- 3 files changed, 18 insertions(+), 40 deletions(-) diff --git a/controllers/backend/uploading.js b/controllers/backend/uploading.js index f1f4c2e0..f768e277 100644 --- a/controllers/backend/uploading.js +++ b/controllers/backend/uploading.js @@ -420,6 +420,8 @@ exports.postFileUpload = async(req, res) => { uploadLogger.info('Concat done', logObject); + // TODO: pull this out into its own function + let bitrate, codecName, codecProfile; if(upload.fileType !== 'image'){ diff --git a/controllers/frontend/account.js b/controllers/frontend/account.js index 6a378651..88cd759f 100644 --- a/controllers/frontend/account.js +++ b/controllers/frontend/account.js @@ -59,6 +59,12 @@ const forgotEmailFunctionalityOn = process.env.FORGOT_PASSWORD_EMAIL_FUNCTIONALI const { attachDataToUploadsAsUploads } = require('../../lib/helpers/addFieldsToUploads'); +const stripeToken = process.env.STRIPE_FRONTEND_TOKEN; + +const plusEnabled = process.env.PLUS_ENABLED === 'true'; + +const verifyEmailFunctionalityOn = process.env.CONFIRM_EMAIL_FUNCTIONALITY_ON === 'true'; + // TODO: pull this function out function removeTrailingSlash(requestPath){ if(requestPath.charAt(requestPath.length - 1) == '/'){ @@ -68,37 +74,6 @@ function removeTrailingSlash(requestPath){ return requestPath; } -// TODO: pull this function out -async function addValuesIfNecessary(upload, channelUrl){ - if(upload.fileType == 'video' || upload.fileType == 'audio'){ - if(!upload.durationInSeconds || !upload.formattedDuration){ - - var server = uploadServer; - if(server.charAt(0) == '/') // the slash confuses the file reading, because host root directory is not the same as machine root directory - server = server.substr(1); - - const uploadLocation = `${server}/${channelUrl}/${upload.uniqueTag + upload.fileExtension}`; - - try { - const duration = await getUploadDuration(uploadLocation, upload.fileType); - console.log(duration); - - let uploadDocument = await Upload.findOne({uniqueTag: upload.uniqueTag}); - - uploadDocument.durationInSeconds = duration.seconds; - uploadDocument.formattedDuration = duration.formattedTime; - - await uploadDocument.save(); - - } catch(err){ - /** if the file has been deleted then it won't blow up **/ - // console.log(err); - } - // console.log('have to add'); - } - } -} - /** * GET /upload * Page to facilitate user uploads @@ -124,7 +99,8 @@ exports.getFileUpload = async(req, res) => { categories, maxRatingAllowed: process.env.MAX_RATING_ALLOWED, userCanUploadContentOfThisRating, - secondsToFormattedTime + secondsToFormattedTime, + plusEnabled }); }; @@ -903,11 +879,6 @@ exports.getSignup = (req, res) => { * Account page. */ exports.getAccount = async(req, res) => { - const stripeToken = process.env.STRIPE_FRONTEND_TOKEN; - - const plusEnabled = process.env.PLUS_ENABLED == 'true'; - - const verifyEmailFunctionalityOn = process.env.CONFIRM_EMAIL_FUNCTIONALITY_ON == 'true'; // give user an upload token if(!req.user.uploadToken){ diff --git a/views/uploading.pug b/views/uploading.pug index 76519e21..2ce201ee 100644 --- a/views/uploading.pug +++ b/views/uploading.pug @@ -30,6 +30,11 @@ block content font-weight: 300; } + .ldBar path.mainline { + stroke-width: 6 !important; + stroke: white !important; + } + .ldBar { margin: 0 auto; } @@ -73,9 +78,9 @@ block content //h3.fw(style="font-size: 30px;") Select Upload - if user.plan == 'free' && plus_enabled - p You can raise this limit to 2000 MB by subscribing for  - a(href="/account?to=pt-plus") #{brandName} Plus + if user.plan === 'free' && plusEnabled + p You can raise this limit to 2000 MB (2GB) by subscribing for  + a(href="/account?to=nt-plus") #{brandName} Plus if site_rating From c86c06d046a610d9fb6df0370dec5f8e660d3519 Mon Sep 17 00:00:00 2001 From: Anthony Date: Mon, 26 Apr 2021 17:14:35 +0200 Subject: [PATCH 11/18] fix bug --- controllers/frontend/mediaPlayer.js | 14 +++++++++++- views/media.pug | 2 +- .../mediaPlayerPartials/progressTrackerJs.pug | 1 + views/pugJavascript/uploadingJavascript.pug | 22 +++++++++++-------- 4 files changed, 28 insertions(+), 11 deletions(-) diff --git a/controllers/frontend/mediaPlayer.js b/controllers/frontend/mediaPlayer.js index 0570f696..6855827d 100644 --- a/controllers/frontend/mediaPlayer.js +++ b/controllers/frontend/mediaPlayer.js @@ -74,10 +74,15 @@ function getFormattedFileSize(upload){ */ exports.getMedia = async(req, res) => { + // TODO: pull out plus redirect thing + + // get the amount of slashes, to determine if the user is allowed // to access the vanity url version of this url let requestPath = req.path; + var queryParams = req.url.split('?')[1] + if(requestPath.charAt(requestPath.length - 1) == '/'){ requestPath = requestPath.substr(0, requestPath.length - 1); } @@ -118,10 +123,17 @@ exports.getMedia = async(req, res) => { }); } + console.log(req.path); + // TODO: make sure to add query params here // if it's three but you're plus, then move to shortened url if(amountOfSlashes === 3 && user.plan == 'plus'){ - return res.redirect(`/${user.channelUrl}/${upload.uniqueTag}`); + let redirectPath = `/${user.channelUrl}/${upload.uniqueTag}`; + if(queryParams){ + redirectPath = redirectPath + '?' + queryParams + } + + return res.redirect(redirectPath); } // TODO: pull this thing out diff --git a/views/media.pug b/views/media.pug index 6d063f2d..97b03e02 100644 --- a/views/media.pug +++ b/views/media.pug @@ -307,7 +307,7 @@ block content .secondLine { - border-bottom: 1px solid #3f3f3f !important; + border-bottom: 0px solid #3f3f3f !important; } .lampIcon { diff --git a/views/mediaPlayerPartials/progressTrackerJs.pug b/views/mediaPlayerPartials/progressTrackerJs.pug index e5ff7a04..d39e2353 100644 --- a/views/mediaPlayerPartials/progressTrackerJs.pug +++ b/views/mediaPlayerPartials/progressTrackerJs.pug @@ -26,6 +26,7 @@ script. $('#processing').text(`${data.uploadProgress !== undefined ? data.uploadProgress : 'Completed'}`); if(parseInt(data) == 100){ + // TODO: this should be a u=t link location.reload(); } diff --git a/views/pugJavascript/uploadingJavascript.pug b/views/pugJavascript/uploadingJavascript.pug index 0c4b9e33..826fa3f1 100644 --- a/views/pugJavascript/uploadingJavascript.pug +++ b/views/pugJavascript/uploadingJavascript.pug @@ -275,24 +275,28 @@ script. }) } + // get the thumbnail file var thumbnailFile = $('#filetoupload')[0].files[0] - let files = new FormData(); - - files.append('thumbnailFile', thumbnailFile) - - files.append('uploadUniqueTag', response.uniqueTag) - - var addThumbnailUrl = '/api/uploadFileThumbnail'; - // if there's thumbnail file, just redirect if(!thumbnailFile){ + // alert('Redirecting to ' + redirectUrl); + // alert('no thumbnail url'); - window.location.href = response.url; + return window.location.href = redirectUrl; } else { + // initiate a form to send for thumbnail upload + let files = new FormData(); + + files.append('thumbnailFile', thumbnailFile) + + files.append('uploadUniqueTag', response.uniqueTag) + + var addThumbnailUrl = '/api/uploadFileThumbnail'; + // alert('thumbnail url'); $.ajax({ From d39a1c68d289ced5436141a7e064c5cc32ebbd4e Mon Sep 17 00:00:00 2001 From: Anthony Date: Mon, 26 Apr 2021 21:41:38 +0200 Subject: [PATCH 12/18] add play pause toggle button --- controllers/frontend/mediaPlayer.js | 2 +- views/media.pug | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/controllers/frontend/mediaPlayer.js b/controllers/frontend/mediaPlayer.js index 6855827d..4d06a60e 100644 --- a/controllers/frontend/mediaPlayer.js +++ b/controllers/frontend/mediaPlayer.js @@ -123,7 +123,7 @@ exports.getMedia = async(req, res) => { }); } - console.log(req.path); + // console.log(req.path); // TODO: make sure to add query params here // if it's three but you're plus, then move to shortened url diff --git a/views/media.pug b/views/media.pug index 97b03e02..28e5a57b 100644 --- a/views/media.pug +++ b/views/media.pug @@ -1739,17 +1739,28 @@ block extra_footer_js if (activeElement && plyrElementNotFocused && inputElementNotFocused) { + // left keypad if (e.keyCode === 37) { mediaPlayer.currentTime = mediaPlayer.currentTime - 5; return false; + // right keypad } else if (e.keyCode === 39) { mediaPlayer.currentTime = mediaPlayer.currentTime + 5; return false; + + // space button + } else if (e.keyCode === 32) { + // toggle play/pause button + if (mediaPlayer.paused){ + mediaPlayer.play(); + } else { + mediaPlayer.pause(); + } } } }); From 8fd9eb0af3896d0ed3d37a8776a39a2e6740ade2 Mon Sep 17 00:00:00 2001 From: Anthony Date: Mon, 26 Apr 2021 22:22:46 +0200 Subject: [PATCH 13/18] everything works but a bit slow could use an optimization --- views/media.pug | 46 +++++++++++++++++++++++++++++++++++++++------- 1 file changed, 39 insertions(+), 7 deletions(-) diff --git a/views/media.pug b/views/media.pug index 28e5a57b..11b6c4cd 100644 --- a/views/media.pug +++ b/views/media.pug @@ -1753,15 +1753,47 @@ block extra_footer_js return false; - // space button + // space button } else if (e.keyCode === 32) { - // toggle play/pause button - if (mediaPlayer.paused){ - mediaPlayer.play(); - } else { - mediaPlayer.pause(); - } + // dont scroll down + e.preventDefault() + + // toggle play/pause button + if (mediaPlayer.paused) { + mediaPlayer.play(); + } else { + mediaPlayer.pause(); + } + + return false + } + } else if (inputElementNotFocused && e.keyCode === 13){ + mediaPlayer.requestFullscreen(); } }); + script. + $(document).keypress(function (e) { + + var activeElement = document.activeElement; + var inputs = ['input', 'textarea']; + + var plyrElementNotFocused = !document.activeElement.classList.contains('plyr') + + var inputElementNotFocused = inputs.indexOf(activeElement.tagName.toLowerCase()) === -1; + + if (activeElement && plyrElementNotFocused && inputElementNotFocused) { + + if (e.keyCode === 32) { + // dont scroll down + e.preventDefault() + + return false + + } + } + }); + + + From 69896f46e3b010cd37b826d1419f9114540557ae Mon Sep 17 00:00:00 2001 From: Anthony Date: Mon, 26 Apr 2021 22:26:58 +0200 Subject: [PATCH 14/18] optimized code --- views/media.pug | 72 ++++++++++++++++++++++++++----------------------- 1 file changed, 39 insertions(+), 33 deletions(-) diff --git a/views/media.pug b/views/media.pug index 11b6c4cd..d4262b40 100644 --- a/views/media.pug +++ b/views/media.pug @@ -1728,64 +1728,69 @@ block extra_footer_js script. $(document).keyup(function (e) { - var mediaPlayer = document.getElementById("media_player"); - var activeElement = document.activeElement; - var inputs = ['input', 'textarea']; + var oneOfTheUsedKeys = e.keyCode === 37 || e.keyCode === 39 || e.keyCode === 32 || e.keyCode === 13; - var plyrElementNotFocused = !document.activeElement.classList.contains('plyr') + if(oneOfTheUsedKeys){ + var mediaPlayer = document.getElementById("media_player"); - var inputElementNotFocused = inputs.indexOf(activeElement.tagName.toLowerCase()) === -1; + var activeElement = document.activeElement; + var inputs = ['input', 'textarea']; - if (activeElement && plyrElementNotFocused && inputElementNotFocused) { + var plyrElementNotFocused = !document.activeElement.classList.contains('plyr') - // left keypad - if (e.keyCode === 37) { + var inputElementNotFocused = inputs.indexOf(activeElement.tagName.toLowerCase()) === -1; - mediaPlayer.currentTime = mediaPlayer.currentTime - 5; + if (activeElement && plyrElementNotFocused && inputElementNotFocused) { - return false; + // left keypad + if (e.keyCode === 37) { - // right keypad - } else if (e.keyCode === 39) { + mediaPlayer.currentTime = mediaPlayer.currentTime - 5; - mediaPlayer.currentTime = mediaPlayer.currentTime + 5; + return false; - return false; + // right keypad + } else if (e.keyCode === 39) { - // space button - } else if (e.keyCode === 32) { - // dont scroll down - e.preventDefault() + mediaPlayer.currentTime = mediaPlayer.currentTime + 5; - // toggle play/pause button - if (mediaPlayer.paused) { - mediaPlayer.play(); - } else { - mediaPlayer.pause(); - } + return false; - return false + // space button + } else if (e.keyCode === 32) { + // dont scroll down + e.preventDefault() + // toggle play/pause button + if (mediaPlayer.paused) { + mediaPlayer.play(); + } else { + mediaPlayer.pause(); + } + + return false + + } + } else if (inputElementNotFocused && e.keyCode === 13) { + mediaPlayer.requestFullscreen(); } - } else if (inputElementNotFocused && e.keyCode === 13){ - mediaPlayer.requestFullscreen(); } }); script. $(document).keypress(function (e) { - var activeElement = document.activeElement; - var inputs = ['input', 'textarea']; + if(e.keyCode === 32){ + var activeElement = document.activeElement; + var inputs = ['input', 'textarea']; - var plyrElementNotFocused = !document.activeElement.classList.contains('plyr') + var plyrElementNotFocused = !document.activeElement.classList.contains('plyr') - var inputElementNotFocused = inputs.indexOf(activeElement.tagName.toLowerCase()) === -1; + var inputElementNotFocused = inputs.indexOf(activeElement.tagName.toLowerCase()) === -1; - if (activeElement && plyrElementNotFocused && inputElementNotFocused) { + if (activeElement && plyrElementNotFocused && inputElementNotFocused) { - if (e.keyCode === 32) { // dont scroll down e.preventDefault() @@ -1793,6 +1798,7 @@ block extra_footer_js } } + }); From 6e2da03a41fe5a873647daad67498cf1889e7e96 Mon Sep 17 00:00:00 2001 From: Anthony Date: Mon, 26 Apr 2021 22:41:55 +0200 Subject: [PATCH 15/18] eslint fix --- controllers/frontend/mediaPlayer.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/controllers/frontend/mediaPlayer.js b/controllers/frontend/mediaPlayer.js index 4d06a60e..7686af5b 100644 --- a/controllers/frontend/mediaPlayer.js +++ b/controllers/frontend/mediaPlayer.js @@ -76,12 +76,11 @@ exports.getMedia = async(req, res) => { // TODO: pull out plus redirect thing - // get the amount of slashes, to determine if the user is allowed // to access the vanity url version of this url let requestPath = req.path; - var queryParams = req.url.split('?')[1] + var queryParams = req.url.split('?')[1]; if(requestPath.charAt(requestPath.length - 1) == '/'){ requestPath = requestPath.substr(0, requestPath.length - 1); @@ -130,7 +129,7 @@ exports.getMedia = async(req, res) => { if(amountOfSlashes === 3 && user.plan == 'plus'){ let redirectPath = `/${user.channelUrl}/${upload.uniqueTag}`; if(queryParams){ - redirectPath = redirectPath + '?' + queryParams + redirectPath = redirectPath + '?' + queryParams; } return res.redirect(redirectPath); From 3888527e08818d4c0062f60bc4ddcbb7b668b384 Mon Sep 17 00:00:00 2001 From: Anthony Date: Mon, 26 Apr 2021 23:09:53 +0200 Subject: [PATCH 16/18] bugfix --- views/media.pug | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/views/media.pug b/views/media.pug index d4262b40..abf59efa 100644 --- a/views/media.pug +++ b/views/media.pug @@ -1737,10 +1737,11 @@ block extra_footer_js var activeElement = document.activeElement; var inputs = ['input', 'textarea']; - var plyrElementNotFocused = !document.activeElement.classList.contains('plyr') - + // match against an input or text area input var inputElementNotFocused = inputs.indexOf(activeElement.tagName.toLowerCase()) === -1; + var plyrElementNotFocused = !document.activeElement.classList.contains('plyr') + if (activeElement && plyrElementNotFocused && inputElementNotFocused) { // left keypad @@ -1772,7 +1773,9 @@ block extra_footer_js return false } - } else if (inputElementNotFocused && e.keyCode === 13) { + } + + if (inputElementNotFocused && e.keyCode === 13) { mediaPlayer.requestFullscreen(); } } From 1e59d1e389c6b0eeaef2057e3d95db47f8420626 Mon Sep 17 00:00:00 2001 From: Anthony Date: Mon, 26 Apr 2021 23:33:08 +0200 Subject: [PATCH 17/18] when plyr is focused show controls when seeking --- views/media.pug | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/views/media.pug b/views/media.pug index abf59efa..a2fb45a2 100644 --- a/views/media.pug +++ b/views/media.pug @@ -1747,14 +1747,32 @@ block extra_footer_js // left keypad if (e.keyCode === 37) { - mediaPlayer.currentTime = mediaPlayer.currentTime - 5; + e.preventDefault() + + $('button[data-plyr="rewind"]').click() + + player.toggleControls(true); + setTimeout(function () { + player.toggleControls(true); + }, 150) + + // mediaPlayer.currentTime = mediaPlayer.currentTime - 5; return false; // right keypad } else if (e.keyCode === 39) { - mediaPlayer.currentTime = mediaPlayer.currentTime + 5; + e.preventDefault() + + $('button[data-plyr="fast-forward"]').click() + + player.toggleControls(true); + setTimeout(function () { + player.toggleControls(true); + }, 150) + + // mediaPlayer.currentTime = mediaPlayer.currentTime + 5; return false; @@ -1778,6 +1796,12 @@ block extra_footer_js if (inputElementNotFocused && e.keyCode === 13) { mediaPlayer.requestFullscreen(); } + + var leftOrRightKey = e.keyCode === 37 || e.keyCode === 39; + + if (!plyrElementNotFocused && leftOrRightKey) { + player.toggleControls(true); + } } }); From aec77c71aadc0f9030ef294ea1f03252cbc24ddf Mon Sep 17 00:00:00 2001 From: Anthony Date: Mon, 26 Apr 2021 23:37:30 +0200 Subject: [PATCH 18/18] add f button for fullscreen --- views/media.pug | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/views/media.pug b/views/media.pug index a2fb45a2..a272d859 100644 --- a/views/media.pug +++ b/views/media.pug @@ -1729,7 +1729,7 @@ block extra_footer_js script. $(document).keyup(function (e) { - var oneOfTheUsedKeys = e.keyCode === 37 || e.keyCode === 39 || e.keyCode === 32 || e.keyCode === 13; + var oneOfTheUsedKeys = e.keyCode === 37 || e.keyCode === 39 || e.keyCode === 32 || e.keyCode === 13 || e.keyCode === 70; if(oneOfTheUsedKeys){ var mediaPlayer = document.getElementById("media_player"); @@ -1793,7 +1793,7 @@ block extra_footer_js } } - if (inputElementNotFocused && e.keyCode === 13) { + if (inputElementNotFocused && ( e.keyCode === 13 || e.keyCode === 70)) { mediaPlayer.requestFullscreen(); }