diff --git a/Web/Models/Repositories/Videos.php b/Web/Models/Repositories/Videos.php
index e78a1b0f..8dbda7ab 100644
--- a/Web/Models/Repositories/Videos.php
+++ b/Web/Models/Repositories/Videos.php
@@ -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']) {
diff --git a/Web/Presenters/VideosPresenter.php b/Web/Presenters/VideosPresenter.php
index 625f4877..49ed1b43 100644
--- a/Web/Presenters/VideosPresenter.php
+++ b/Web/Presenters/VideosPresenter.php
@@ -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);
}
}
}
diff --git a/Web/Presenters/templates/components/comment.xml b/Web/Presenters/templates/components/comment.xml
index f99f7ddb..31e47071 100644
--- a/Web/Presenters/templates/components/comment.xml
+++ b/Web/Presenters/templates/components/comment.xml
@@ -27,7 +27,7 @@
{var $attachmentsLayout = $comment->getChildrenWithLayout(288)}
- {include "attachment.xml", attachment => $attachment[2], parent => $comment, parentType => "comment"}
+ {include "attachment.xml", attachment => $attachment[2], parent => $comment, parentType => "comment", tilesCount => sizeof($attachmentsLayout->tiles)}
diff --git a/Web/Presenters/templates/components/video.xml b/Web/Presenters/templates/components/video.xml
index f9ab070e..d2ab40ff 100644
--- a/Web/Presenters/templates/components/video.xml
+++ b/Web/Presenters/templates/components/video.xml
@@ -19,6 +19,9 @@
{$video->getName()}
+ {if $video->getLength()}
+ ({$video->getFormattedLength()})
+ {/if}
{$video->getDescription() ?? ""}
diff --git a/Web/static/js/al_music.js b/Web/static/js/al_music.js
index 51590511..ac609358 100644
--- a/Web/static/js/al_music.js
+++ b/Web/static/js/al_music.js
@@ -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) => {
diff --git a/Web/static/js/al_wall.js b/Web/static/js/al_wall.js
index be2e51ef..ee5bda47 100644
--- a/Web/static/js/al_wall.js
+++ b/Web/static/js/al_wall.js
@@ -4,6 +4,7 @@ function initGraffiti(event) {
title: tr("draw_graffiti"),
body: "
",
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: `
@@ -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: `
+
+ `,
+ 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(`
+
+ `)
+ break
+ case 'youtube':
+ msg.getNode().find('#__content').html(`
+
+ `)
+ 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()
diff --git a/Web/static/js/messagebox.js b/Web/static/js/messagebox.js
index 33b3b3cf..0bc51d86 100644
--- a/Web/static/js/messagebox.js
+++ b/Web/static/js/messagebox.js
@@ -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()
+ }
}
}
})
\ No newline at end of file
diff --git a/locales/en.strings b/locales/en.strings
index ece69a9f..eae93644 100644
--- a/locales/en.strings
+++ b/locales/en.strings
@@ -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.";
diff --git a/locales/ru.strings b/locales/ru.strings
index e2020569..be398411 100644
--- a/locales/ru.strings
+++ b/locales/ru.strings
@@ -796,6 +796,9 @@
"no_videos" = "У вас нет видео.";
"no_videos_results" = "Нет результатов.";
+"video_file_upload" = "Загрузить файл";
+"video_youtube_upload" = "Добавить с YouTube";
+
/* Audios */
"my" = "Моё";