add fast video uploader, come back unlisted param

This commit is contained in:
mrilyew 2024-11-06 18:19:11 +03:00
parent 873f00788d
commit 6c2d6f9dd6
9 changed files with 234 additions and 18 deletions

View file

@ -56,7 +56,7 @@ class Videos
function find(string $query = "", array $params = [], array $order = ['type' => 'id', 'invert' => false]): Util\EntityStream
{
$query = "%$query%";
$result = $this->videos->where("CONCAT_WS(' ', name, description) LIKE ?", $query)->where("deleted", 0);
$result = $this->videos->where("CONCAT_WS(' ', name, description) LIKE ?", $query)->where("deleted", 0)->where("unlisted", 0);
$order_str = 'id';
switch($order['type']) {

View file

@ -62,6 +62,7 @@ final class VideosPresenter extends OpenVKPresenter
$this->flashFail("err", tr("error"), tr("video_uploads_disabled"));
if($_SERVER["REQUEST_METHOD"] === "POST") {
$is_ajax = (int)($this->postParam('ajax') ?? '0') == 1;
if(!empty($this->postParam("name"))) {
$video = new Video;
$video->setOwner($this->user->id);
@ -75,18 +76,29 @@ final class VideosPresenter extends OpenVKPresenter
else if(!empty($this->postParam("link")))
$video->setLink($this->postParam("link"));
else
$this->flashFail("err", tr("no_video_error"), tr("no_video_description"));
$this->flashFail("err", tr("no_video_error"), tr("no_video_description"), 10, $is_ajax);
} catch(\DomainException $ex) {
$this->flashFail("err", tr("error_video"), tr("file_corrupted"));
$this->flashFail("err", tr("error_video"), tr("file_corrupted"), 10, $is_ajax);
} catch(ISE $ex) {
$this->flashFail("err", tr("error_video"), tr("link_incorrect"));
$this->flashFail("err", tr("error_video"), tr("link_incorrect"), 10, $is_ajax);
}
if((int)($this->postParam("unlisted") ?? '0') == 1) {
$video->setUnlisted(true);
}
$video->save();
if($is_ajax) {
$object = $video->getApiStructure();
$this->returnJson([
'payload' => $object->video,
]);
}
$this->redirect("/video" . $video->getPrettyId());
} else {
$this->flashFail("err", tr("error_video"), tr("no_name_error"));
$this->flashFail("err", tr("error_video"), tr("no_name_error"), 10, $is_ajax);
}
}
}

View file

@ -27,7 +27,7 @@
{var $attachmentsLayout = $comment->getChildrenWithLayout(288)}
<div n:ifcontent class="attachments attachments_b" style="height: {$attachmentsLayout->height|noescape}; width: {$attachmentsLayout->width|noescape};">
<div class="attachment" n:foreach="$attachmentsLayout->tiles as $attachment" style="float: {$attachment[3]|noescape}; width: {$attachment[0]|noescape}; height: {$attachment[1]|noescape};" data-localized-nsfw-text="{_nsfw_warning}">
{include "attachment.xml", attachment => $attachment[2], parent => $comment, parentType => "comment"}
{include "attachment.xml", attachment => $attachment[2], parent => $comment, parentType => "comment", tilesCount => sizeof($attachmentsLayout->tiles)}
</div>
</div>

View file

@ -19,6 +19,9 @@
{$video->getName()}
</b>
</a>
{if $video->getLength()}
({$video->getFormattedLength()})
{/if}
<br/>
<p>
<span class='video_description'>{$video->getDescription() ?? ""}</span>

View file

@ -1459,7 +1459,13 @@ $(document).on("click", ".audioEmbed.processed .playerButton", (e) => {
})
$(document).on("click", ".audioEmbed.withdrawn", (e) => {
MessageBox(tr("error"), tr("audio_embed_withdrawn"), [tr("ok")], [Function.noop])
const msg = new CMessageBox({
title: tr('error'),
body: tr('audio_embed_withdrawn'),
unique_name: 'withdrawn_notify',
buttons: [tr('ok')],
callbacks: [Function.noop]
})
})
$(document).on("click", ".musicIcon.report-icon", (e) => {

View file

@ -4,6 +4,7 @@ function initGraffiti(event) {
title: tr("draw_graffiti"),
body: "<div id='ovkDraw'></div>",
close_on_buttons: false,
warn_on_exit: true,
buttons: [tr("save"), tr("cancel")],
callbacks: [function() {
canvas.getImage({includeWatermark: false}).toBlob(blob => {
@ -746,7 +747,7 @@ u(document).on('click', '#__videoAttachment', async (e) => {
body: `
<div class='attachment_selector'>
<div class="topGrayBlock display_flex_row">
<a href="/videos/upload">${tr("upload_new_video")}</a>
<a id='__fast_video_upload' href="/videos/upload"><input class='button' type='button' value='${tr("upload_button")}'></a>
<input type="search" id="video_query" maxlength="20" placeholder="${tr("header_search")}">
</div>
@ -890,6 +891,11 @@ u(document).on('click', '#__videoAttachment', async (e) => {
}
})
u(".ovk-diag-body .attachment_selector").on('click', '#__fast_video_upload', (ev) => {
ev.preventDefault()
showFastVideoUpload(form)
})
__recieveVideos(0)
})
@ -1012,6 +1018,184 @@ u(document).on('click', '#__notesAttachment', async (e) => {
__recieveNotes(0)
})
function showFastVideoUpload(node) {
let current_tab = 'file'
const msg = new CMessageBox({
title: tr('upload_video'),
close_on_buttons: false,
unique_name: 'video_uploader',
body: `
<div id='_fast_video_upload'>
<div id='_tabs'>
<div class="mb_tabs">
<div class="mb_tab" data-name='file'>
<a>
${tr('video_file_upload')}
</a>
</div>
<div class="mb_tab" data-name='youtube'>
<a>
${tr('video_youtube_upload')}
</a>
</div>
</div>
</div>
<div id='__content'></div>
</div>
`,
buttons: [tr('close'), tr('upload_button')],
callbacks: [() => {msg.close()}, async () => {
const video_name = u(`#_fast_video_upload input[name='name']`).nodes[0].value
const video_desc = u(`#_fast_video_upload textarea[name='desc']`).nodes[0].value
let append_result = null
if(video_name.length < 1) {
u(`#_fast_video_upload input[name='name']`).nodes[0].focus()
return
}
const form_data = new FormData
switch(current_tab) {
default:
case 'file':
const video_file = u(`#_fast_video_upload input[name='blob']`).nodes[0]
if(video_file.files.length < 1) {
return
}
const video_blob = video_file.files[0]
form_data.append('ajax', '1')
form_data.append('name', video_name)
form_data.append('desc', video_desc)
form_data.append('blob', video_blob)
form_data.append('unlisted', 1)
form_data.append("hash", u("meta[name=csrf]").attr("value"))
window.messagebox_stack[1].getNode().find('.ovk-diag-action button').nodes[1].classList.add('lagged')
const fetcher = await fetch(`/videos/upload`, {
method: 'POST',
body: form_data
})
const fetcher_results = await fetcher.json()
append_result = fetcher_results
break
case 'youtube':
const video_url = u(`#_fast_video_upload input[name='link']`).nodes[0]
const video_link = video_url.value
if(video_link.length < 1) {
u(`#_fast_video_upload input[name='link']`).nodes[0].focus()
return
}
form_data.append('ajax', '1')
form_data.append('name', video_name)
form_data.append('desc', video_desc)
form_data.append('link', video_link)
form_data.append('unlisted', 1)
form_data.append("hash", u("meta[name=csrf]").attr("value"))
window.messagebox_stack[1].getNode().find('.ovk-diag-action button').nodes[1].classList.add('lagged')
const fetcher_yt = await fetch(`/videos/upload`, {
method: 'POST',
body: form_data
})
const fetcher_yt_results = await fetcher_yt.json()
append_result = fetcher_yt_results
break
}
if(append_result.payload) {
append_result = append_result.payload
const preview = append_result.image[0]
__appendToTextarea({
'type': 'video',
'preview': preview.url,
'id': append_result.owner_id + '_' + append_result.id,
'fullsize_preview': preview.url,
}, node)
window.messagebox_stack.forEach(msg_ => {
msg_.close()
})
} else {
fastError(append_result.flash.message)
msg.close()
}
}]
})
msg.getNode().find('.ovk-diag-body').attr('style', 'padding:0px;height: 161px;')
async function __switchTab(tab_name) {
current_tab = tab_name
u(`#_fast_video_upload .mb_tab`).attr('id', 'ki')
u(`#_fast_video_upload .mb_tab[data-name='${current_tab}']`).attr('id', 'active')
switch(current_tab) {
case 'file':
msg.getNode().find('#__content').html(`
<table cellspacing="7" cellpadding="0" width="80%" border="0" align="center">
<tbody>
<tr>
<td width="120" valign="top"><span class="nobold">${tr('info_name')}:</span></td>
<td><input type="text" name="name" /></td>
</tr>
<tr>
<td width="120" valign="top"><span class="nobold">${tr('description')}:</span></td>
<td><textarea name="desc"></textarea></td>
</tr>
<tr>
<td width="120" valign="top"><span class="nobold">${tr('video')}:</span></td>
<td>
<label class="button" style="">
${tr('browse')}
<input type="file" id="blob" name="blob" style="display: none;" accept="video/*" />
</label>
<span id="filename" style="margin-left: 7px;"></span>
</td>
</tr>
</tbody>
</table>
`)
break
case 'youtube':
msg.getNode().find('#__content').html(`
<table cellspacing="7" cellpadding="0" width="80%" border="0" align="center">
<tbody>
<tr>
<td width="120" valign="top"><span class="nobold">${tr('info_name')}:</span></td>
<td><input type="text" name="name" /></td>
</tr>
<tr>
<td width="120" valign="top"><span class="nobold">${tr('description')}:</span></td>
<td><textarea name="desc"></textarea></td>
</tr>
<tr>
<td width="120" valign="top"><span class="nobold">${tr('video_link_to_yt')}:</span></td>
<td>
<input type="text" name="link" placeholder="https://www.youtube.com/watch?v=9FWSRQEqhKE" />
</td>
</tr>
</tbody>
</table>
`)
break
}
}
u('#_fast_video_upload').on('click', '.mb_tab', (e) => {
__switchTab(u(e.target).closest('.mb_tab').nodes[0].dataset.name)
})
u('#_fast_video_upload').on('change', '#blob', (e) => {
u('#_fast_video_upload #filename').html(escapeHtml(e.target.files[0].name))
u(`#_fast_video_upload input[name='name']`).nodes[0].value = escapeHtml(e.target.files[0].name)
})
__switchTab('file')
}
u(document).on('click', `.post-horizontal .upload-item .upload-delete`, (e) => {
e.preventDefault()
u(e.target).closest('.upload-item').remove()

View file

@ -8,12 +8,17 @@ class CMessageBox {
const callbacks = options.callbacks ?? []
const close_on_buttons = options.close_on_buttons ?? true
const unique_name = options.unique_name ?? null
const warn_on_exit = options.warn_on_exit ?? false
if(unique_name && window.messagebox_stack.find(item => item.unique_name == unique_name) != null) {
return
}
this.title = title
this.body = body
this.id = random_int(0, 10000)
this.close_on_buttons = close_on_buttons
this.unique_name = unique_name
this.warn_on_exit = warn_on_exit
u('body').addClass('dimmed').append(this.__getTemplate())
u('html').attr('style', 'overflow-y:hidden')
@ -49,10 +54,6 @@ class CMessageBox {
}
async __showCloseConfirmationDialog() {
if(window.messagebox_stack.find(item => item.unique_name == 'close_confirmation') != null) {
return
}
return new Promise((resolve, reject) => {
const msg = new CMessageBox({
title: tr('exit_noun'),
@ -120,9 +121,11 @@ u(document).on('keyup', async (e) => {
return
}
const res = await msg.__showCloseConfirmationDialog()
if(res === true) {
msg.close()
if(msg.warn_on_exit) {
const res = await msg.__showCloseConfirmationDialog()
if(res === true) {
msg.close()
}
}
}
})
@ -140,9 +143,11 @@ u(document).on('click', 'body.dimmed .dimmer', async (e) => {
return
}
const res = await msg.__showCloseConfirmationDialog()
if(res === true) {
msg.close()
if(msg.warn_on_exit) {
const res = await msg.__showCloseConfirmationDialog()
if(res === true) {
msg.close()
}
}
}
})

View file

@ -836,6 +836,9 @@
"no_videos" = "You don't have uploaded videos.";
"no_videos_results" = "No results.";
"video_file_upload" = "Upload file";
"video_youtube_upload" = "Add from YouTube";
"change_video" = "Change video";
"unknown_video" = "This video is not supported in your version of OpenVK.";

View file

@ -796,6 +796,9 @@
"no_videos" = "У вас нет видео.";
"no_videos_results" = "Нет результатов.";
"video_file_upload" = "Загрузить файл";
"video_youtube_upload" = "Добавить с YouTube";
/* Audios */
"my" = "Моё";