diff --git a/controllers/backend/uploading.js b/controllers/backend/uploading.js index adad0a7a..8eafbed9 100644 --- a/controllers/backend/uploading.js +++ b/controllers/backend/uploading.js @@ -601,7 +601,7 @@ exports.postFileUpload = async(req, res) => { uploadLogger.info('Update users push notifications', logObject); - // user + // do email notifications for the user updateUsersEmailNotifications(user, upload, req.host); uploadLogger.info('Update users email notifications', logObject); diff --git a/controllers/frontend/account.js b/controllers/frontend/account.js index 68bbfc7b..44ce971f 100644 --- a/controllers/frontend/account.js +++ b/controllers/frontend/account.js @@ -14,7 +14,7 @@ const SocialPost = require('../../models/index').SocialPost; const Subscription = require('../../models/index').Subscription; const PushSubscription = require('../../models/index').PushSubscription; const EmailSubscription = require('../../models/index').EmailSubscription; - +const LastWatchedTime = require('../../models/index').LastWatchedTime; const PushEndpoint = require('../../models/index').PushEndpoint; const RSS = require('rss'); @@ -503,6 +503,24 @@ exports.getChannel = async(req, res) => { user.totalViews = totalViews; + for(const upload in uploads){ + console.log(uploads[upload].durationInSeconds); + let lastWatchedTime; + if(uploads[upload].durationInSeconds >= 900){ + console.log('This watch'); + console.log(uploads[upload]._id); + console.log(user._id); + lastWatchedTime = await LastWatchedTime.findOne({ + user : req.user._id, + upload: uploads[upload]._id + }); + } + if(lastWatchedTime !== undefined && lastWatchedTime !== null){ + uploads[upload].lastWatchedTime = lastWatchedTime.secondsWatched; + console.log(lastWatchedTime.secondsWatched); + } + } + user.uploads = uploads; // for(const upload of uploads){ @@ -513,19 +531,23 @@ exports.getChannel = async(req, res) => { const joinedTimeAgo = timeAgoEnglish.format(user.createdAt); - const pushSubscriptionSearchQuery = { - subscribedToUser : user._id, - subscribingUser: req.user._id, - active: true - } - let existingPushSub; if(req.user){ + const pushSubscriptionSearchQuery = { + subscribedToUser : user._id, + subscribingUser: req.user._id, + active: true + }; existingPushSub = await PushSubscription.findOne(pushSubscriptionSearchQuery); } let existingEmailSub; if(req.user){ + const pushSubscriptionSearchQuery = { + subscribedToUser : user._id, + subscribingUser: req.user._id, + active: true + }; existingEmailSub = await EmailSubscription.findOne(pushSubscriptionSearchQuery); } diff --git a/controllers/frontend/mediaBrowsing.js b/controllers/frontend/mediaBrowsing.js index c86b28f9..c658106d 100644 --- a/controllers/frontend/mediaBrowsing.js +++ b/controllers/frontend/mediaBrowsing.js @@ -7,12 +7,12 @@ const User = require('../../models/index').User; const Upload = require('../../models/index').Upload; const SearchQuery = require('../../models/index').SearchQuery; const View = require('../../models/index').View; - +const LastWatchedTime = require('../../models/index').LastWatchedTime; const uploadHelpers = require('../../lib/helpers/settings'); const uploadServer = uploadHelpers.uploadServer; const getFromCache = require('../../caching/getFromCache'); const uploadFilters = require('../../lib/mediaBrowsing/helpers'); - +const timeHelper = require('../../lib/helpers/time'); const { getUploadDuration } = require('../../lib/mediaBrowsing/helpers'); const getSensitivityFilter = uploadFilters.getSensitivityFilter; @@ -40,17 +40,38 @@ if(!process.env.FILE_HOST || process.env.FILE_HOST == 'false'){ const pageLimit = 42; +async function addLastTimeWatched(upload, user){ + console.log("AddLastWatchedTime") + console.log(upload.durationInSeconds) + let lastWatchedTime; + if(upload.durationInSeconds >= 900){ + console.log("This watch") + console.log(upload._id) + console.log(user._id) + lastWatchedTime = await LastWatchedTime.findOne({ + user : user._id, + upload: upload._id + }); + } + if(lastWatchedTime !== undefined && lastWatchedTime !== null){ + // uploads[upload].lastWatchedTime = lastWatchedTime.secondsWatched + console.log(lastWatchedTime.secondsWatched) + return lastWatchedTime.secondsWatched + } + +} + // TODO: pull this function out async function addValuesIfNecessary(upload, channelUrl){ if(upload.fileType == 'video' || upload.fileType == 'audio'){ - if(!upload.durationInSeconds || !upload.formattedDuration){ + if(true){ 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); @@ -59,13 +80,13 @@ async function addValuesIfNecessary(upload, channelUrl){ uploadDocument.durationInSeconds = Math.round(duration.seconds); uploadDocument.formattedDuration = duration.formattedTime; - + const value = Math.round(duration.seconds); const saveDocument = await uploadDocument.save(); - // console.log(saveDocument); - + // console.log("saveDocument") + return value; } catch(err){ /** if the file has been deleted then it won't blow up **/ - // console.log(err); + console.log(err); } // console.log('have to add'); @@ -134,6 +155,14 @@ exports.recentUploads = async(req, res) => { // console.log('rendering'); + if(uploads && uploads.length){ + for(const upload in uploads){ + // console.log(uploads[upload]); + uploads[upload].durationInSeconds = await addValuesIfNecessary(uploads[upload], uploads[upload].uploader && uploads[upload].uploader.channelUrl); + uploads[upload].lastWatchedTime = await addLastTimeWatched(uploads[upload], req.user) + } + } + res.render('mediaBrowsing/recentUploads', { title: 'Recent Uploads', uploads, @@ -316,10 +345,28 @@ exports.popularUploads = async(req, res) => { if(uploads && uploads.length){ for(const upload in uploads){ - // console.log(upload); - addValuesIfNecessary(upload, upload.uploader && upload.uploader.channelUrl); + // console.log(uploads[upload]); + uploads[upload].durationInSeconds = await addValuesIfNecessary(uploads[upload], uploads[upload].uploader && uploads[upload].uploader.channelUrl); + uploads[upload].lastWatchedTime = await addLastTimeWatched(uploads[upload], req.user) } } + // console.log(uploads) + // for(const upload in uploads){ + // // console.log(uploads[upload]._id) + // let lastWatchedTime; + // if(uploads[upload].lastWatchedTime === undefined){ + // lastWatchedTime = await LastWatchedTime.findOne({ + // user : req.user._id, + // upload: uploads[upload]._id + // }); + // } + // if(lastWatchedTime !== null){ + // uploads[upload].lastWatchedTime = lastWatchedTime.secondsWatched + // // console.log(lastWatchedTime.secondsWatched) + // } + // // console.log(uploads[upload].durationInSeconds); + // } + res.render('mediaBrowsing/popularUploads', { title: 'Popular Uploads', @@ -524,6 +571,14 @@ exports.search = async(req, res) => { // error } + if(uploads && uploads.length){ + for(const upload in uploads){ + // console.log(uploads[upload]); + uploads[upload].durationInSeconds = await addValuesIfNecessary(uploads[upload], uploads[upload].uploader && uploads[upload].uploader.channelUrl); + uploads[upload].lastWatchedTime = await addLastTimeWatched(uploads[upload], req.user) + } + } + const siteVisitor = req.siteVisitor; const media = mediaType || 'all'; diff --git a/views/account/channel.pug b/views/account/channel.pug index 93640184..ea6c5380 100644 --- a/views/account/channel.pug +++ b/views/account/channel.pug @@ -86,9 +86,16 @@ block content if user div(style="margin-top:12px") // TODO: this should create a push subsciption, and it will also send a query to see if it should create a new service worker - h2.share-button.pushNotificationIcon(style="display:inline") + h2.fw.share-button.pushNotificationIcon(style="display:inline") i.share-icon.fas.fa-bell(aria-hidden="true" style="cursor:pointer;font-size:25px;margin-left:0px;color:white;") - h2.share-button.emailNotificationIcon(style="display:inline") + h2.fw.share-button.emailNotificationIcon(style="display:inline") + i.share-icon.fas.fa-envelope(aria-hidden="true" style="cursor:pointer;font-size:25px;margin-left:10px;color:white;") + else + div(style="margin-top:12px") + // TODO: this should create a push subsciption, and it will also send a query to see if it should create a new service worker + h2.fw.share-button.pushNotificationIcon(style="display:inline") + i.share-icon.fas.fa-bell(aria-hidden="true" style="cursor:pointer;font-size:25px;margin-left:0px;color:white;") + h2.fw.share-button.emailNotificationIcon(style="display:inline") i.share-icon.fas.fa-envelope(aria-hidden="true" style="cursor:pointer;font-size:25px;margin-left:10px;color:white;") // todo: else @@ -149,7 +156,7 @@ block content //button.undelete-account.btn.btn-warning Undelete Account And Unban Ip if user.role == 'admin' button.delete-ips.btn.btn-warning Undelete All Accounts / Unban All Ips - + div @@ -259,7 +266,7 @@ block content $(document).ready(function(){ var alreadyHaveEmailNotifsOn = '#{alreadySubscribedForEmails}' == 'true' - + console.log('already have email notis on') if (alreadyHaveEmailNotifsOn) { @@ -434,6 +441,33 @@ block content main(); }) + $('.emailNotificationIcon').click(function () { + // TODO: How to make it so that the user immediately gets email subs after + // signing in. + Swal.mixin({ + title: 'Choose method of email subscription', + showCancelButton: true, + }).queue([ + { + html: '
' + + '

Please sign in to continue.

', + confirmButtonText: 'Subscribe without sign in', + }, + { + title: 'Choose method of email subscription', + confirmButtonText: 'Subscribe', + input: 'email', + inputLabel: 'Get updates without sign in', + inputPlaceholder: 'Enter your email address' + } + ]).then((result) => { + console.log('result', result.value) + if (result.value) { + const email = result.value[1] + } + }) + }) + diff --git a/views/admin/adminOverview.pug b/views/admin/adminOverview.pug index 22aafe2c..1ce8f416 100644 --- a/views/admin/adminOverview.pug +++ b/views/admin/adminOverview.pug @@ -2,8 +2,33 @@ extends ../layout block content div - div + div.col-sm-3 h2 a(href="/admin/users") Users h2 a(href="/admin/subscriptions") Subscriptions + h2 + a(href="/admin/comments") Comments + h2 + a(href="/admin/uploads") Uploads + h2 + a(href="/admin/dailyStats") Daily stats + h2 + a(href="/admin/reacts") Reacts + h2 + a(href="/admin/siteVisitors") Site Visitors + h2 + a(href="/admin/notifications") Notifications + h2 + a(href="/admin/adminAudit") Admin audit + h2 + a(href="/admin/createSocialPost") Create Social Post + h2 + a(href="/admin/oneOffSocialPost") One off social post + h2 + a(href="/pending") Pending requests + h2 + a(href="/support/emails") Support emails + h2 + a(href="/support/reports") Support reports + diff --git a/views/layout.pug b/views/layout.pug index 29104bd4..e9e4189f 100644 --- a/views/layout.pug +++ b/views/layout.pug @@ -32,6 +32,7 @@ html link(rel='manifest', href='/manifest.json') link(rel='alternate', type='application/rss+xml', href='/media/recent/rss') link(href='https://gitcdn.github.io/bootstrap-toggle/2.2.2/css/bootstrap-toggle.min.css', rel='stylesheet') + link(href='https://cdn.plyr.io/3.6.2/plyr.css', rel='stylesheet') block extra_css script(src='/js/lib/jquery-3.1.1.min.js') diff --git a/views/media.pug b/views/media.pug index 81c1eba5..87ee69a4 100644 --- a/views/media.pug +++ b/views/media.pug @@ -1,7 +1,7 @@ extends layout -block content +block content if !upload.description style. @media (min-width: 900px) { @@ -400,11 +400,36 @@ block content if upload.fileType === 'video' && upload.status !== 'processing' div.display-div.magnetic(style="min-width:50%;min-height:50%;margin:0 auto;margin-top: -25px;") // margin-top:46px; - - video#media_player.display-element(playsinline poster=`${uploadServer}/${upload.uploader.channelUrl}/${upload.thumbnails.generated || upload.thumbnails.medium}` controls='', style="max-width:100%;background-color:black;") + + //- video#my_video_1.video-js.vjs-default-skin(controls='' data-setup='{}') + //- source(src=`${serverToUse}/${upload.uploader.channelUrl}/${upload.uniqueTag}.mp4`, type='video/mp4') + + //- script. + //- videojs.autoSetup(); + + //- videojs('my_video_1).ready(function(){ + //- console.log(this.options()); + + + //- var myPlayer = this, id = myPlayer.id(); + + //- var aspectRatio = 264/640; + + //- function resizeVideoJS(){ + //- var width = document.getElementById(id).parentElement.offsetWidth; + //- myPlayer.width(width).height( width * aspectRatio ); + + //- } + + + //- resizeVideoJS(); + + //- window.onresize = resizeVideoJS; + //- }); + video#media_player.display-element(playsinline autoplayposter=`${uploadServer}/${upload.uploader.channelUrl}/${upload.thumbnails.generated || upload.thumbnails.medium}` controls='', style="max-width:100%;background-color:black;") // to source.video-source(src=`${serverToUse}/${upload.uploader.channelUrl}/${upload.uniqueTag}.mp4`, type='video/mp4') - + // TODO: load captions programatically if upload.webVTTPath track(kind='captions', label='English captions', src=`${uploadServer}/${upload.uploader.channelUrl}/${upload.webVTTPath}`, srclang='en', default='') @@ -490,11 +515,11 @@ block content // TODO: show this if it's pending or not - if upload.visibility != 'pending' - if alreadySubbed - button.subscribe.btn.fw.btn-danger.op80.unsubscribeButton(style="border-radius:4px;") Unsubscribe (#{subscriberAmount}) - else - button.subscribe.btn.fw.btn-success.op80.subscribeButton(style="border-radius:4px;") Subscribe (#{subscriberAmount}) + + if alreadySubbed + button.subscribe.btn.fw.btn-danger.op80.unsubscribeButton(style="border-radius:4px;") Unsubscribe (#{subscriberAmount}) + else + button.subscribe.btn.fw.btn-success.op80.subscribeButton(style="border-radius:4px;") Subscribe (#{subscriberAmount}) if user div(style="margin-top:12px") @@ -671,7 +696,12 @@ block content if ( upload.durationInSeconds > (15 * 60) ) && user if lastWatchedTime - p.fw.fileSizeText(style="margin-top:15px;color:a5a5a5;") Last Watched Time: #{formattedLastWatchedTime} + p.fw.fileSizeText(style="margin-top:15px;color:a5a5a5;") Las Watched Time: #{formattedLastWatchedTime} + script. + document.getElementById('media_player').addEventListener('loadedmetadata', function() { + this.currentTime = lastWatchedTime; + }, false); + //- document.getElementById('media_player').src = '' + serverToUse + '/' + upload.uploader.channelUrl + '/' upload.uniqueTag + '.mp4#t=00:00:' + lastWatchedTime else p.fw.fileSizeText(style="margin-top:15px;color:a5a5a5;") No Last Watched Time @@ -860,7 +890,7 @@ block extra_js if user script. - + $(document).ready(function(){ var alreadyHaveEmailNotifsOn = '#{alreadySubscribedForEmails}' == 'true' @@ -1016,9 +1046,10 @@ block extra_js // when show less button is clicked showLessButton.click(function () { uploadDescriptionText.height('194'); - + showMoreButton.show() showLessButton.hide() + document.getElementsByTagName('h2')[2].scrollIntoView(); }) diff --git a/views/mediaBrowsing/popularUploads.pug b/views/mediaBrowsing/popularUploads.pug index f1332f46..589ba02c 100644 --- a/views/mediaBrowsing/popularUploads.pug +++ b/views/mediaBrowsing/popularUploads.pug @@ -54,7 +54,7 @@ block content each upload in uploads div.col-xs-12.col-sm-6.col-md-6.col-lg-4(style="text-align:center;height:340px;margin-bottom:34px;") - + include ../viewPartials/uploadThumbnail include ../viewPartials/uploadDetails diff --git a/views/nodeTubeCss.pug b/views/nodeTubeCss.pug index 7a235807..fd336043 100644 --- a/views/nodeTubeCss.pug +++ b/views/nodeTubeCss.pug @@ -144,6 +144,9 @@ style. margin: 0 auto; border-radius: 5px; } + .plyr--full-ui input[type="range"] { + color: red; + } .plyr.plyr__video-wrapper { background: white; @@ -162,7 +165,7 @@ style. max-width: 405px; height: 210px; max-height: 210px; - border-radius: 7px; + max-width:100%; /*border:1px solid white;*/ } @@ -291,6 +294,7 @@ style. } .image-container { + height: 220px; display:inline-block; border:1px solid #5b5a5a; margin:0 auto; @@ -304,7 +308,7 @@ style. /*transform: scale(1.05) translate(0px, 30px);*/ - transform: scale(1.12); + transform: scale(1.05); -webkit-filter: brightness(120%); } diff --git a/views/viewPartials/uploadThumbnail.pug b/views/viewPartials/uploadThumbnail.pug index 349c5f2f..62dbff1a 100644 --- a/views/viewPartials/uploadThumbnail.pug +++ b/views/viewPartials/uploadThumbnail.pug @@ -1,3 +1,12 @@ +style. + progress { + width: 100%; + border: 0px solid red; + background: LightGray; + height: 10px; + } + progress::-moz-progress-bar { background: red; } + progress::-webkit-progress-value { background: red; } div.holder(style="border:") a.title-anchor(href=`/user/${upload.uploader.channelUrl || channelUrl}/${upload.uniqueTag}` style="color:#7d7373;" ) div.image-container(style="") @@ -5,8 +14,12 @@ div.holder(style="border:") img.upload-thumbnail.preview-image(src=`${uploadServer}/${channelUrl || upload.uploader.channelUrl}/${upload.thumbnails.custom}` style="") else if upload.fileType == 'video' && upload.thumbnails && upload.thumbnails.generated - img.upload-thumbnail.preview-image(src=`${uploadServer}/${channelUrl || upload.uploader.channelUrl}/${upload.thumbnails.generated}` style="") - + + if !upload.lastWatchedTime + img.upload-thumbnail.preview-image(src=`${uploadServer}/${channelUrl || upload.uploader.channelUrl}/${upload.thumbnails.generated}` style="margin-bottom: -1.5%; height: 220px; max-height: 220px") + else + img.upload-thumbnail.preview-image(src=`${uploadServer}/${channelUrl || upload.uploader.channelUrl}/${upload.thumbnails.generated}` style="margin-bottom: -1.5%") + progress(value=upload.lastWatchedTime max=upload.durationInSeconds) else if upload.fileType == 'video' && upload.thumbnails && upload.thumbnails.medium img.upload-thumbnail.preview-image(src=`${uploadServer}/${channelUrl || upload.uploader.channelUrl}/${upload.thumbnails.medium}` style="") @@ -23,3 +36,4 @@ div.holder(style="border:") else if upload.fileType == 'unknown' img.upload-thumbnail.preview-image(src='/images/no_img.png') +