Archived
1
0

Implement video upload to posts

This commit is contained in:
Marcel 2018-12-30 18:52:30 +01:00
parent 1f3e0243cf
commit ebb5c473f6
11 changed files with 1063 additions and 571 deletions

View File

@ -63,6 +63,8 @@
$route['user/getComments'] = 'user/getComments';
$route['user/getBlogPosts'] = 'user/getBlogPosts';
$route['user/publishPost'] = 'user/publishPost';
$route['user/uploadPostMedia'] = 'user/uploadPostMedia';
$route['user/deletePostMedia'] = 'user/deletePostMedia';
$route['user/switchFollowing'] = 'user/switchFollowing';
$route['user/getReportModal'] = 'user/getReportModal';
$route['user/(:any)'] = 'user/index/$1';

View File

@ -1,10 +1,10 @@
<?php
defined('BASEPATH') OR exit('No direct script access allowed');
defined('BASEPATH') OR exit('No direct script access allowed');
use Coduo\PHPHumanizer\DateTimeHumanizer;
use Coduo\PHPHumanizer\DateTimeHumanizer;
class User extends MY_Controller
{
class User extends MY_Controller
{
public function __construct()
{
@ -199,21 +199,58 @@ class User extends MY_Controller
}
}
public function uploadPostMedia()
{
if (!isset($_SESSION['user']) || empty($_SESSION['user']))
redirect(base_url());
if(empty($_FILES) || !isset($_FILES['postMedia']))
redirect(base_url());
header('Content-Type: application/json');
$file = $_FILES['postMedia'];
list('name' => $name, 'type' => $type) = $file;
switch (explode('/', $type)[0]) {
case 'video':
$path = $this->FileModel->uploadVideo('postMedia', 0, $name, 1920, $_SESSION['user']['username']);
$mediaType = 'video';
break;
case 'image':
$path = $this->FileModel->uploadImage('postMedia', 0, $name, 1920, $_SESSION['user']['username']);
$mediaType = 'image';
break;
default:
exit;
break;
}
echo json_encode(['success' => true, 'type' => $mediaType, 'path' => $path]);
}
public function deletePostMedia() {
if (!isset($_SESSION['user']) || empty($_SESSION['user']))
redirect(base_url());
if(empty($_POST) || !isset($_POST['path']))
redirect(base_url());
$url = $_POST['path'];
$filePath = $this->FileModel->getFilePath(substr($url, 3), $_SESSION['user']['ID']);
if($filePath != null)
unlink($filePath);
}
public function publishPost()
{
if (!isset($_SESSION['user']) || empty($_SESSION['user'])) {
?>
<div class="alert alert-danger" role="alert">
<b>Veröffentlichen des Posts fehlgeschlagen!</b>
Du musst in deinen Account eingeloggt sein, um Posts erstellen zu können.<br>
Bitte erstelle dir entweder
<a href="<?= base_url('login') ?>">kostenlos einen neuen Account</a>
oder
<a href="<?= base_url('login') ?>">melde dich an</a>
.
</div>
<?php
echo json_encode(['success' => false,
'title' => lang('post_error_login_title'),
'message' => lang('post_error_login_lines')
]);
exit;
}
@ -249,14 +286,39 @@ class User extends MY_Controller
$media = $this->input->post('postMedia');
if (!empty($media)) {
$allowedMedia = [];
foreach ($media as $entry) {
$image = str_replace(' ', '+', $entry['image']);
$image = substr($image, strpos($image, ',') + 1);
$image = base64_decode($image);
$name = substr($entry['path'], 3);
$file = $this->FileModel->getFileID($name, $_SESSION['user']['ID']);
$fileUrl = $this->FileModel->uploadFileByContent($image, $entry['name'], $entry['type'], $entry['size']);
if (empty($file)) {
continue;
}
$this->PostsModel->addImageToPost($postID, $fileUrl);
$fileID = $file[0]['ID'];
if ($entry['type'] === 'video' || $entry['type'] === 'audio') {
$allowedMedia = [
[
'type' => $entry['type'],
'fileID' => $fileID
]
];
break;
}
if (sizeof($allowedMedia) < 4) {
$allowedMedia[] = [
'type' => $entry['type'],
'fileID' => $fileID
];
} else {
break;
}
}
foreach ($allowedMedia as $entry) {
$this->PostsModel->addMediaToPost($postID, $entry['type'], $entry['fileID']);
}
}
?>
@ -264,11 +326,11 @@ class User extends MY_Controller
<b>Dein Post wurde erfolgreich veröffentlicht!</b> Möchtest du nun deine Posts ansehen? <br>
<button type="button" class="btn btn-sm btn-default" data-dismiss="modal">Nein</button>
<a href='<?= base_url('user/' . $_SESSION['user']['username'] . '/posts') ?>'
class='btn btn-sm btn-primary'>Ja</a>
class='btn btn-sm btn-primary'>Ja
</a>
</div>
<?php
}
}
public function followers($user = "")
{
@ -623,4 +685,4 @@ class User extends MY_Controller
$this->load->view('network/posts/user_post_content', ['message' => $message, 'post' => $post, 'replies' => $replies]);
}
}
}

View File

@ -52,5 +52,5 @@
$lang['header_post'] = 'Post';
$lang['header_post_title'] = 'Post verfassen';
$lang['header_post_content'] = 'Inhalt';
$lang['header_post_notice'] = 'Es wird an einer Funktion zum Uploaden von Fotos, Videos und anderen Medien gearbeitet. In hoffentlich naher Zukunft wirst du auch die Möglichkeit haben, diese zu deinen Posts hinzuzufügen!';
$lang['header_post_notice'] = 'Derzeit arbeiten wir intensiv daran, dir die Möglichkeit zu bieten, neben Bildern und Videos auch Audio-Aufnahmen hinzuzufügen und vor allem mithilfe von unter anderem einer direkten Kamera-Integration das Nutzererlebnis deutlich besser zu gestalten. Auch möchten wir die Text-Eingabe deutlich komfortabler gestalten. Also, stay tuned!';
$lang['header_post_publish'] = 'Veröffentlichen';

View File

@ -61,3 +61,27 @@
$lang['post_copy_link'] = 'Link zum Post kopieren';
$lang['post_report'] = 'Post melden';
$lang['post_delete'] = 'Post löschen';
$lang['post_error_login_title'] = 'Veröffentlichung des Posts nicht möglich!';
$lang['post_error_login_lines'] = [
'Du musst in deinen Account eingeloggt sein, um Posts erstellen zu können.',
'Bitte erstelle dir entweder <a href="' . base_url('login') . '">kostenlos einen neuen Account</a> oder <a href="' . base_url('login') . '">melde dich an</a>.'
];
$lang['post_error_too_long_title'] = 'Veröffentlichung des Posts fehlgeschlagen!';
$lang['post_error_too_long_lines'] = [
'Dein Post ist leider zu lang. Er darf maximal 10.000 Zeichen umfassen.',
];
$lang['post_error_reply_title'] = 'Veröffentlichung des Posts fehlgeschlagen!';
$lang['post_error_reply_lines'] = [
'Der Post, an den du deine Antwort richten willst, existiert nicht (mehr).',
'Solltest du dies für einen Fehler halten, versuche es später erneut oder kontaktiere uns.',
];
$lang['post_error_no_conent_title'] = 'Veröffentlichung des Posts nicht möglich!';
$lang['post_error_no_conent_lines'] = [
'Du hast uns leider keinen Inhalt angegeben, den wir veröffentlichen können.',
'Sollte es sich dabei um ein Irrtum handeln, so kontaktiere uns bitte über das Kontakt-Formular.',
];
$lang['post_success_title'] = '';
$lang['post_success_lines'] = [
'',
];

View File

@ -11,8 +11,24 @@ class FileModel extends CI_Model
parent::__construct();
}
private function getPath($fileName, $userContent) {
return 'files/' . ($userContent ? 'userContent/' : '') . $fileName;
private function getPath($fileName, $user) {
return 'files/' . ($user != null ? 'userContent/' . $user . '/' : '') . $fileName;
}
private function addToDatabase($name, $originalName, $type, $size, $path, $user) {
$userID = NULL;
if(is_string($user)) {
$user = $this->db->query('SELECT ID FROM users WHERE username = lower(?)', [$user])->result_array();
if(!empty($user)) {
$userID = $user[0]['ID'];
}
} else if(is_integer($user)) {
$userID = $user;
}
$this->db->query('INSERT INTO files (name, original_name, type, size, path, user) VALUES (?, ?, ?, ?, ?, ?)', [$name, $originalName, $type, $size, $path, $userID]);
$this->db->cache_delete('admin', 'files');
}
public function uploadFile($original_name, $tmpname, $size, $type, $userContent = true)
@ -28,20 +44,51 @@ class FileModel extends CI_Model
$target_file = str_replace('\\', '/', $target_file);
$this->db->query('INSERT INTO files (name, original_name, type, size, path, isUserData) VALUES (?, ?, ?, ?, ?, ?)', [$name, $original_name, $type, $size, $target_file, $userContent]);
$this->db->cache_delete('admin', 'files');
$this->addToDatabase($name, $original_name, $type, $size, $target_file, $userContent);
echo shell_exec('python /var/www/codeigniter/duplicates.py');
return "/f/" . $name;
}
public function uploadImage($name, $max_size, $originalname, $max_width, $userContent = true) {
$config['upload_path'] = '.' . DIRECTORY_SEPARATOR . 'files' . DIRECTORY_SEPARATOR . ($userContent ? 'userContent' . DIRECTORY_SEPARATOR : '');
public function uploadVideo($name, $max_size, $originalName, $max_width, $user = null) {
$path = '.' . DIRECTORY_SEPARATOR . 'files' . DIRECTORY_SEPARATOR;
if($user !== null) {
$path .= 'userContent' . DIRECTORY_SEPARATOR . $user . DIRECTORY_SEPARATOR;
}
$config['upload_path'] = $path;
if(!file_exists($path)) {
mkdir($path, 0777);
}
$config['allowed_types'] = 'mp4';
$config['max_size'] = $max_size;
$config['file_name'] = $this->generateName() . '.' . pathinfo(basename($originalName), PATHINFO_EXTENSION);
$this->load->library('upload', $config);
if(!$this->upload->do_upload($name)) {
return null;
} else {
$data = $this->upload->data();
$this->upload->display_errors();
$this->addToDatabase($data['raw_name'], $originalName, $data['file_type'], $data['file_size'] * 1024, $this->getPath($data['file_name'], $user), $user);
return '/f/' . $data['raw_name'];
}
}
public function uploadImage($name, $max_size, $originalName, $max_width, $user = null) {
$config['upload_path'] = '.' . DIRECTORY_SEPARATOR . 'files' . DIRECTORY_SEPARATOR;
if($user != null) {
$config['upload_path'] .= 'userContent' . DIRECTORY_SEPARATOR . $user . DIRECTORY_SEPARATOR;
}
$config['allowed_types'] = 'gif|jpg|png';
$config['max_size'] = $max_size;
$config['file_name'] = $this->generateName() . "." . pathinfo(basename($originalname), PATHINFO_EXTENSION);
$config['file_name'] = $this->generateName() . "." . pathinfo(basename($originalName), PATHINFO_EXTENSION);
$this->load->library('upload', $config);
@ -60,9 +107,7 @@ class FileModel extends CI_Model
$this->image_lib->resize();
$this->db->query('INSERT INTO files (name, original_name, type, size, path, isUserData) VALUES (?, ?, ?, ?, ?, ?)', [$data['raw_name'], $originalname, $data['file_type'], $data['file_size'] * 1024, $this->getPath($data['file_name'], $userContent), $userContent]);
$this->db->cache_delete('admin', 'files');
$this->addToDatabase($data['raw_name'], $originalName, $data['file_type'], $data['file_size'] * 1024, $this->getPath($data['file_name'], $user), $user);
echo shell_exec('python /var/www/codeigniter/duplicates.py');
@ -164,6 +209,16 @@ class FileModel extends CI_Model
return $result;
}
public function getFileID($name, $userID = null) {
$result = $this->db->query('SELECT ID FROM files WHERE name = ? AND user = ?', [$name, $userID])->result_array();
return $result;
}
public function getFilePath($name, $userID = null) {
$result = $this->db->query('SELECT path FROM files WHERE name = ? AND user = ?', [$name, $userID])->result_array();
return !empty($result) ? $result[0]['path'] : null;
}
public function delete($id) {
$filePath = $this->db->query('SELECT path FROM files WHERE ID = ? LIMIT 1', [$id])->result_array()[0];
unlink($filePath['path']);

View File

@ -48,8 +48,8 @@
$this->db->query('DELETE FROM user_posts_media WHERE postID = ?', [$postID]);
}
public function addImageToPost($postID, $imageUrl) {
$this->db->query('INSERT INTO user_posts_media (postID, mediaType, mediaUrl) VALUES (?, ?, ?)', [$postID, 'image', $imageUrl]);
public function addMediaToPost($postID, $type, $fileID) {
$this->db->query('INSERT INTO user_posts_media (postID, mediaType, fileID) VALUES (?, ?, ?)', [$postID, $type, $fileID]);
}
public function preparePostContent($content)
@ -149,7 +149,7 @@
}
public function getPostMedia($postID) {
$result = $this->db->query('SELECT * FROM user_posts_media WHERE postID = ?', [$postID])->result_array();
$result = $this->db->query('SELECT m.mediaType type, f.name name FROM user_posts_media m LEFT JOIN files f ON f.ID = m.fileID WHERE postID = ?', [$postID])->result_array();
return $result;
}

View File

@ -110,7 +110,8 @@
'lib/jquery.PageScroll2id.min.js',
'lib/jquery.mobile.custom.min.js',
'post-create.js',
'post-item.js'
'post-item.js',
'video-controls.js',
];
if (isset($additionalScripts)) {
$scripts = array_merge($scripts, $additionalScripts);

View File

@ -35,11 +35,46 @@
<?php if (!empty($media)): ?>
<div class="post-media-list row">
<?php foreach ($media as $item): ?>
<?php foreach ($media as $item) {
$url = '/f/' . $item['name'];
switch ($item['type']) {
case 'image':
?>
<div class="col">
<div class="post-media" data-full-image="<?= $item['mediaUrl'] ?>" style="background-image: url(<?= $item['mediaUrl'] ?>?w=500"></div>
<div class="post-media post-image" data-full-image="<?= $url ?>" style="background-image: url('<?= $url ?>?w=500')"></div>
</div>
<?php endforeach; ?>
<?php
break;
case 'video':
?>
<div class="col">
<div class="video-container">
<video class="video" src="<?= $url ?>" muted></video>
<div class="video-controls">
<button type="button" class="video-control-btn video-toggle-play">
<i class="fa fa-play"></i>
</button>
<div class="video-volume-container">
<button type="button" class="video-control-btn video-mute">
<i class="fa fa-volume-muted"></i>
</button>
<input type="range" class="video-volume" min="0" max="1" step="0.1" value="1">
</div>
<output class="video-time">0:00</output>
<input type="range" class="video-seek-bar" value="0">
<output class="video-length">0:00</output>
<button type="button" class="video-control-btn video-fullscreen">
<i class="fa fa-expand"></i>
</button>
</div>
</div>
</div>
<?php
break;
case 'audio':
break;
}
} ?>
</div>
<?php endif; ?>
</div>

View File

@ -30,8 +30,6 @@ $('#contentField').on('keyup', function (e) {
return `<span class="hashtag">${match}</span>`;
});
console.log(html);
if (!/&nbsp;$/.test($(this).html())) {
filter += '&nbsp;';
}
@ -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 = [];
(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++;
}
}
// 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', () => {
$('.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
};
thumbnailEl.css('background-image', `url(${reader.result})`);
});
reader.readAsDataURL(file);
}
}
if(Object.keys(postMedia).length >= 4) {
$('.postImageUpload').hide();
}
});
break;
$('#postModal').on('hidden.bs.modal', () => {
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);
}
});
}

View File

@ -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 {
@ -312,3 +324,6 @@ function deletePost(uuid) {
}
})
}
function addScrollListener() {
}

114
assets/js/video-controls.js Normal file
View 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;
};