Implement video upload to posts
This commit is contained in:
@@ -30,8 +30,6 @@ $('#contentField').on('keyup', function (e) {
|
||||
return `<span class="hashtag">${match}</span>`;
|
||||
});
|
||||
|
||||
console.log(html);
|
||||
|
||||
if (!/ $/.test($(this).html())) {
|
||||
filter += ' ';
|
||||
}
|
||||
@@ -102,7 +100,7 @@ function set_range(start, end, element) {
|
||||
|
||||
$.fn.selectRange = function (start, end) {
|
||||
var e = document.getElementById($(this).attr('id'));
|
||||
if (!e) return;
|
||||
if (!e)
|
||||
else if (e.setSelectionRange) {
|
||||
e.focus();
|
||||
e.setSelectionRange(start, end);
|
||||
@@ -120,12 +118,12 @@ $.fn.selectRange = function (start, end) {
|
||||
}
|
||||
};
|
||||
|
||||
let postMedia = {};
|
||||
let postMedia = [];
|
||||
|
||||
function publishPost() {
|
||||
let isFilled = true;
|
||||
let content = $('#contentField').text();
|
||||
console.log(content);
|
||||
if (content === "") {
|
||||
if (postMedia.length === 0 && content === "") {
|
||||
$('#postModal #content').addClass('has-error');
|
||||
isFilled = false;
|
||||
} else {
|
||||
@@ -135,46 +133,231 @@ function publishPost() {
|
||||
if (isFilled) {
|
||||
const replyTo = $('#postModal #replyTo').val();
|
||||
submitPost(content, replyTo);
|
||||
} else {
|
||||
addSnackbar('primary', 'Wir haben leider noch nicht erlernt, wie man leere Posts veröffentlicht.');
|
||||
}
|
||||
}
|
||||
|
||||
$('#postFiles').on('change', function() {
|
||||
console.log(this.files);
|
||||
const match = ['image/jpeg', 'image/jpg', 'image/png'];
|
||||
const mediaCount = Object.keys(postMedia).length;
|
||||
if(mediaCount < 4) {
|
||||
for (let i = 0; i < this.files.length && i < 4 - mediaCount; i++) {
|
||||
const file = this.files[i];
|
||||
if (match.indexOf(file.type) === -1)
|
||||
continue;
|
||||
let uploadingFiles = [];
|
||||
|
||||
const reader = new FileReader();
|
||||
reader.addEventListener('load', () => {
|
||||
$('.post-images').append(`<div class="post-image" style="background-image: url(${reader.result})"></div>`);
|
||||
postMedia[mediaCount + i] = {
|
||||
image: reader.result,
|
||||
type: file.type,
|
||||
size: file.size,
|
||||
name: file.name
|
||||
};
|
||||
});
|
||||
reader.readAsDataURL(file);
|
||||
(function () {
|
||||
// file drag hover
|
||||
function fileDragHover(e) {
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
e.target.className = (e.type == "dragover" ? "hover" : "");
|
||||
}
|
||||
|
||||
// file selection
|
||||
function fileSelectHandler(e) {
|
||||
|
||||
// cancel event and hover styling
|
||||
fileDragHover(e);
|
||||
|
||||
// fetch FileList object
|
||||
const files = e.target.files || e.dataTransfer.files;
|
||||
|
||||
// process all File objects
|
||||
let i = 0;
|
||||
for (let f of files) {
|
||||
const generalType = f.type.split('/')[0];
|
||||
|
||||
if (postMedia.length + i > 4 || postMedia.find(media => media.type !== 'image' || media.type !== generalType)) {
|
||||
addSnackbar('warning', 'Du kannst maximal vier Bilder zu einem Post hinzufügen.');
|
||||
continue;
|
||||
}
|
||||
|
||||
parseFile(f);
|
||||
uploadFile(f);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
if(Object.keys(postMedia).length >= 4) {
|
||||
$('.postImageUpload').hide();
|
||||
}
|
||||
});
|
||||
|
||||
$('#postModal').on('hidden.bs.modal', () => {
|
||||
$('#postModal #replyTo').val(-1);
|
||||
});
|
||||
// output file information
|
||||
function parseFile(file) {
|
||||
$('#postModalPublish').addClass('disabled').attr('disabled', true);
|
||||
uploadingFiles.push(file);
|
||||
|
||||
const thumbnailEl = $('<div class="post-image"></div>');
|
||||
$('.post-images').append(thumbnailEl);
|
||||
switch (file.type.split('/')[0]) {
|
||||
case 'image':
|
||||
const reader = new FileReader();
|
||||
reader.addEventListener('load', () => {
|
||||
thumbnailEl.css('background-image', `url(${reader.result})`);
|
||||
});
|
||||
break;
|
||||
|
||||
if (postMedia.length >= 4)
|
||||
$('.postImageUpload').hide();
|
||||
case 'video':
|
||||
const video = document.createElement('video');
|
||||
video.src = URL.createObjectURL(file);
|
||||
|
||||
video.addEventListener('loadeddata', () => {
|
||||
const width = video.videoWidth;
|
||||
const height = video.videoHeight;
|
||||
|
||||
const canvas = document.createElement('canvas');
|
||||
canvas.width = width;
|
||||
canvas.height = height;
|
||||
canvas.getContext('2d').drawImage(video, 0, 0, width, height);
|
||||
|
||||
thumbnailEl.css('background-image', `url(${canvas.toDataURL()})`);
|
||||
});
|
||||
|
||||
$('.postImageUpload').hide();
|
||||
break;
|
||||
case 'audio':
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// upload JPEG files
|
||||
function uploadFile(file) {
|
||||
var xhr = new XMLHttpRequest();
|
||||
const allowedTypes = ['image/jpg', 'image/jpeg', 'image/gif', 'image/png', 'video/mp4'];
|
||||
if (xhr.upload && allowedTypes.includes(file.type) && file.size <= 100000000) {
|
||||
const formData = new FormData();
|
||||
formData.append('postMedia', file);
|
||||
|
||||
$.ajax({
|
||||
url: '/user/uploadPostMedia',
|
||||
method: 'POST',
|
||||
data: formData,
|
||||
processData: false,
|
||||
contentType: false,
|
||||
success: (data) => {
|
||||
postMedia.push({
|
||||
type: data.type,
|
||||
path: data.path,
|
||||
});
|
||||
|
||||
uploadingFiles.splice(uploadingFiles.indexOf(file), 1);
|
||||
if(uploadingFiles.length === 0) {
|
||||
$('#postModalPublish').removeClass('disabled').attr('disabled', false);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// initialize
|
||||
function init() {
|
||||
|
||||
var fileselect = $('#postFiles')[0],
|
||||
filedrag = $('#postFiles')[0];
|
||||
// submitbutton = $id("submitbutton");
|
||||
|
||||
if (!fileselect)
|
||||
return;
|
||||
|
||||
// file select
|
||||
fileselect.addEventListener("change", fileSelectHandler, false);
|
||||
|
||||
// is XHR2 available?
|
||||
var xhr = new XMLHttpRequest();
|
||||
if (xhr.upload) {
|
||||
|
||||
// file drop
|
||||
filedrag.addEventListener("dragover", fileDragHover, false);
|
||||
filedrag.addEventListener("dragleave", fileDragHover, false);
|
||||
filedrag.addEventListener("drop", fileSelectHandler, false);
|
||||
filedrag.style.display = "block";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// call initialization file
|
||||
if (window.File && window.FileList && window.FileReader) {
|
||||
init();
|
||||
}
|
||||
|
||||
|
||||
})();
|
||||
|
||||
$('#postModal')
|
||||
.on('hide.bs.modal', function (e) {
|
||||
if (!this.forceQuit && (postMedia.length > 0 || $('#contentField').text().trim().length > 0)) {
|
||||
e.preventDefault();
|
||||
|
||||
let allowClosing = false;
|
||||
const confirmModal = $(`
|
||||
<div class="modal fade" role="dialog">
|
||||
<div class="modal-dialog modal-dialog-centered" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h4 class="modal-title">Post verwerfen?</h4>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button class="btn btn-sm btn-outline btn-red dismiss" type="button" data-dismiss="modal">Ja, Post verwerfen</button>
|
||||
<button class="btn btn-sm btn-primary continue" type="submit" data-dismiss="modal">Nein, Post behalten</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`);
|
||||
confirmModal.modal('show');
|
||||
|
||||
$('.dismiss', confirmModal).click(() => {
|
||||
allowClosing = true;
|
||||
|
||||
this.forceQuit = true;
|
||||
$(this).modal('hide');
|
||||
});
|
||||
|
||||
$('.continue', confirmModal).click(() => {
|
||||
allowClosing = true;
|
||||
});
|
||||
|
||||
confirmModal
|
||||
.on('hide.bs.modal', function (e) {
|
||||
if (!allowClosing)
|
||||
e.preventDefault();
|
||||
})
|
||||
.on('hidden.bs.modal', function () {
|
||||
$(this).remove();
|
||||
});
|
||||
} else {
|
||||
this.forceQuit = false;
|
||||
}
|
||||
})
|
||||
.on('hidden.bs.modal', () => {
|
||||
$('#postModal #replyTo').val(-1);
|
||||
|
||||
if(postMedia.length > 0) {
|
||||
postMedia.forEach(media => {
|
||||
$.ajax({
|
||||
url: '/user/deletePostMedia',
|
||||
method: 'POST',
|
||||
data: {
|
||||
path: media.path
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
resetPostForm();
|
||||
$('#postModalBody > *:not(#postForm)').remove();
|
||||
$('#postForm').show();
|
||||
$('#postModal .modal-footer').show();
|
||||
});
|
||||
|
||||
function resetPostForm() {
|
||||
uploadingFiles = [];
|
||||
postMedia = [];
|
||||
$('.post-images').empty();
|
||||
$('.postImageUpload').show();
|
||||
$('#contentField').text('');
|
||||
}
|
||||
|
||||
function submitPost(content, replyTo) {
|
||||
if(postMedia.length > 4) {
|
||||
if (postMedia.length > 4) {
|
||||
return;
|
||||
}
|
||||
|
||||
const body = $('#postModalBody');
|
||||
$.ajax({
|
||||
url: "/user/publishPost",
|
||||
method: 'POST',
|
||||
@@ -184,14 +367,15 @@ function submitPost(content, replyTo) {
|
||||
postMedia
|
||||
},
|
||||
beforeSend: function () {
|
||||
$('#postModalBody').empty().append("<i class='fa fa-cog fa-spin fa-5x'></i>");
|
||||
$('#postModalPublish').button('loading');
|
||||
body.children().hide().parent().append('<div class="loadingSpinner"></div>');
|
||||
$('#postModal .modal-footer').hide();
|
||||
resetPostForm();
|
||||
},
|
||||
success: function (data) {
|
||||
$('#postModalBody').empty().append(data);
|
||||
$('.loadingSpinner', body).remove();
|
||||
body.append(data);
|
||||
},
|
||||
error: function (data) {
|
||||
console.log(data);
|
||||
}
|
||||
});
|
||||
}
|
@@ -68,7 +68,6 @@ function registerPostEvents() {
|
||||
$('.action-btn.reply-button').click((e) => {
|
||||
e.preventDefault();
|
||||
const target = $(e.currentTarget);
|
||||
console.log(target, $('.postFullviewModal'));
|
||||
$('.postFullviewModal').modal('hide');
|
||||
$('#postModal #replyTo').val(target.data('uuid'));
|
||||
$('#postModal').modal('show');
|
||||
@@ -82,7 +81,7 @@ function registerPostEvents() {
|
||||
$('.post-item').click(function (e) {
|
||||
const target = e.target;
|
||||
|
||||
if(target.tagName !== 'A' && target.tagName !== 'IMG' && target.tagName !== 'I' && !target.classList.contains('post-media')) {
|
||||
if(target.tagName !== 'BUTTON' && target.tagName !== 'INPUT' && target.tagName !== 'A' && target.tagName !== 'IMG' && target.tagName !== 'I' && !target.classList.contains('post-media')) {
|
||||
e.preventDefault();
|
||||
const uuid = $(this).data('uuid');
|
||||
const username = $(this).data('username');
|
||||
@@ -94,6 +93,23 @@ function registerPostEvents() {
|
||||
$('.post-media').click(function () {
|
||||
showFullscreenImage($(this).data('full-image'));
|
||||
});
|
||||
|
||||
addVideoListeners();
|
||||
|
||||
$(window).scroll(() => {
|
||||
const pageOffsetTop = $(window).scrollTop();
|
||||
const pageOffsetBottom = pageOffsetTop + $(window).height();
|
||||
$('.post-media.post-video').each(function () {
|
||||
const elemTop = $(this).offset().top;
|
||||
const elemBottom = elemTop + $(this).height();
|
||||
|
||||
if(elemBottom <= pageOffsetBottom || elemTop >= pageOffsetTop) {
|
||||
$(this)[0].play();
|
||||
} else {
|
||||
$(this)[0].pause();
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
registerPostEvents();
|
||||
|
||||
@@ -101,7 +117,6 @@ const pendingRequests = [];
|
||||
function addPostLike(el) {
|
||||
const uuid = el.data('uuid');
|
||||
|
||||
console.log(el, uuid);
|
||||
if(pendingRequests.indexOf(uuid) !== -1)
|
||||
return;
|
||||
|
||||
@@ -115,7 +130,6 @@ function addPostLike(el) {
|
||||
postUUID: uuid
|
||||
},
|
||||
success: (result) => {
|
||||
console.log(result);
|
||||
if(result.success) {
|
||||
text.text(result.likeCount);
|
||||
if(result.isLiked) {
|
||||
@@ -150,7 +164,6 @@ function addPostLike(el) {
|
||||
icon.toggleClass('far').toggleClass('fas');
|
||||
icon.parent().toggleClass('active');
|
||||
},
|
||||
error: console.log
|
||||
});
|
||||
}
|
||||
|
||||
@@ -225,7 +238,6 @@ function submitReportForm(postUuid, reportReason, reportText) {
|
||||
setTimeout(() => {
|
||||
$('#postReportBody').find('.fa').fadeOut();
|
||||
}, 500);
|
||||
console.log(data);
|
||||
if(data.success) {
|
||||
$('#postReportBody').append(`<div class="alert alert-success" role="alert" style="display: none;">${data.message}</div>`);
|
||||
} else {
|
||||
@@ -311,4 +323,7 @@ function deletePost(uuid) {
|
||||
}, 2000);
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function addScrollListener() {
|
||||
}
|
114
assets/js/video-controls.js
Normal file
114
assets/js/video-controls.js
Normal file
@@ -0,0 +1,114 @@
|
||||
function getVideo(el) {
|
||||
return $(el).parent().prev('.video')[0];
|
||||
}
|
||||
|
||||
function updateMuteBtn(video) {
|
||||
const muteBtn = $(video).next('.video-controls').find('.video-mute i.fa');
|
||||
muteBtn.removeClass('fa-volume-up fa-volume-down fa-volume-mute');
|
||||
if (video.muted) {
|
||||
muteBtn.addClass('fa-volume-mute');
|
||||
} else {
|
||||
if (video.volume > .5) {
|
||||
muteBtn.addClass('fa-volume-up');
|
||||
} else {
|
||||
muteBtn.addClass('fa-volume-down');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function formatTime(time) {
|
||||
const minutes = Math.floor(time / 60);
|
||||
let seconds = Math.round(time) % 60;
|
||||
if(seconds < 10)
|
||||
seconds = "0" + seconds;
|
||||
return `${minutes}:${seconds}`
|
||||
}
|
||||
|
||||
function addVideoListeners() {
|
||||
$('.video-controls .video-toggle-play').click(function () {
|
||||
getVideo(this).toggle();
|
||||
});
|
||||
|
||||
$('.video-controls .video-mute').click(function () {
|
||||
const video = getVideo(this);
|
||||
video.toggleMuted();
|
||||
|
||||
updateMuteBtn(video);
|
||||
});
|
||||
|
||||
$('.video-controls .video-volume').change(function () {
|
||||
const video = getVideo(this);
|
||||
video.volume = $(this).val();
|
||||
|
||||
if (video.volume > 0)
|
||||
video.muted = false;
|
||||
|
||||
updateMuteBtn(video);
|
||||
});
|
||||
|
||||
$('.video-seek-bar')
|
||||
.on('mousedown', function () {
|
||||
getVideo(this).pause();
|
||||
})
|
||||
.on('mouseup', function () {
|
||||
getVideo(this).play();
|
||||
})
|
||||
.on('change', function () {
|
||||
const video = getVideo(this);
|
||||
video.currentTime = video.duration * (this.value / 100);
|
||||
});
|
||||
|
||||
$('.video-fullscreen').on('click', function () {
|
||||
const video = getVideo(this);
|
||||
|
||||
if(video.requestFullscreen) {
|
||||
video.requestFullscreen();
|
||||
} else if(video.mozRequestFullScreen) {
|
||||
video.mozRequestFullScreen();
|
||||
} else if(video.webkitRequestFullScreen) {
|
||||
video.webkitRequestFullScreen();
|
||||
}
|
||||
});
|
||||
|
||||
$('.video')
|
||||
.on('loadeddata', function () {
|
||||
const duration = formatTime(this.duration);
|
||||
$(this).next('.video-controls').find('.video-length').text(duration);
|
||||
})
|
||||
.on('play pause', function () {
|
||||
const togglePlay = $(this).next('.video-controls').find('.video-toggle-play').find('i.fa');
|
||||
if (this.paused) {
|
||||
togglePlay.removeClass('fa-pause').addClass('fa-play');
|
||||
} else {
|
||||
togglePlay.removeClass('fa-play').addClass('fa-pause');
|
||||
}
|
||||
})
|
||||
.on('timeupdate', function () {
|
||||
const value = (100 / this.duration) * this.currentTime;
|
||||
$(this).next('.video-controls').find('.video-seek-bar').val(value)
|
||||
.prev('.video-time').text(formatTime(this.currentTime));
|
||||
})
|
||||
.on('click', function () {
|
||||
if(!this.startedManually) {
|
||||
this.play();
|
||||
this.muted = false;
|
||||
updateMuteBtn(this);
|
||||
|
||||
this.startedManually = true;
|
||||
} else {
|
||||
this.toggle();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Node.prototype.toggle = function () {
|
||||
if (this.paused)
|
||||
this.play();
|
||||
else
|
||||
this.pause();
|
||||
};
|
||||
|
||||
Node.prototype.toggleMuted = function () {
|
||||
this.muted = !this.muted;
|
||||
};
|
||||
|
Reference in New Issue
Block a user