diff --git a/VKAPI/Handlers/Video.php b/VKAPI/Handlers/Video.php index bc962b70..a296a17c 100755 --- a/VKAPI/Handlers/Video.php +++ b/VKAPI/Handlers/Video.php @@ -11,24 +11,55 @@ use openvk\Web\Models\Repositories\Comments as CommentsRepo; final class Video extends VKAPIRequestHandler { - function get(int $owner_id, string $videos = "", string $fields = "", int $offset = 0, int $count = 30, int $extended = 0): object + function get(int $owner_id = 0, string $videos = "", string $fields = "", int $offset = 0, int $count = 30, int $extended = 0): object { $this->requireUser(); if(!empty($videos)) { $vids = explode(',', $videos); - - foreach($vids as $vid) - { + $profiles = []; + $groups = []; + foreach($vids as $vid) { $id = explode("_", $vid); - $items = []; $video = (new VideosRepo)->getByOwnerAndVID(intval($id[0]), intval($id[1])); if($video) { - $items[] = $video->getApiStructure($this->getUser()); + $out_video = $video->getApiStructure($this->getUser())->video; + $items[] = $out_video; + if($out_video['owner_id']) { + if($out_video['owner_id'] > 0) + $profiles[] = $out_video['owner_id']; + else + $groups[] = abs($out_video['owner_id']); + } } } + + if($extended == 1) { + $profiles = array_unique($profiles); + $groups = array_unique($groups); + + $profilesFormatted = []; + $groupsFormatted = []; + + foreach($profiles as $prof) { + $profile = (new UsersRepo)->get($prof); + $profilesFormatted[] = $profile->toVkApiStruct($this->getUser(), $fields); + } + + foreach($groups as $gr) { + $group = (new ClubsRepo)->get($gr); + $groupsFormatted[] = $group->toVkApiStruct($this->getUser(), $fields); + } + + return (object) [ + "count" => sizeof($items), + "items" => $items, + "profiles" => $profilesFormatted, + "groups" => $groupsFormatted, + ]; + } return (object) [ "count" => count($items), diff --git a/Web/Models/Entities/Video.php b/Web/Models/Entities/Video.php index e7a2d6e5..8e3c18f0 100644 --- a/Web/Models/Entities/Video.php +++ b/Web/Models/Entities/Video.php @@ -170,6 +170,7 @@ class Video extends Media "repeat" => 0, "type" => "video", "views" => 0, + "is_processed" => $this->isProcessed(), "reposts" => [ "count" => 0, "user_reposted" => 0 diff --git a/Web/Presenters/templates/@layout.xml b/Web/Presenters/templates/@layout.xml index 3b23952b..5cbc6c42 100644 --- a/Web/Presenters/templates/@layout.xml +++ b/Web/Presenters/templates/@layout.xml @@ -27,6 +27,7 @@ {css "js/node_modules/tippy.js/dist/border.css"} {css "js/node_modules/tippy.js/dist/svg-arrow.css"} {css "js/node_modules/tippy.js/themes/light.css"} + {css "js/node_modules/jquery-ui/themes/base/resizable.css"} {script "js/node_modules/@popperjs/core/dist/umd/popper.min.js"} {script "js/node_modules/tippy.js/dist/tippy-bundle.umd.min.js"} {script "js/node_modules/handlebars/dist/handlebars.min.js"} diff --git a/Web/Presenters/templates/Photos/Photo.xml b/Web/Presenters/templates/Photos/Photo.xml index 590d6830..9bbd67c6 100644 --- a/Web/Presenters/templates/Photos/Photo.xml +++ b/Web/Presenters/templates/Photos/Photo.xml @@ -65,7 +65,7 @@ {_"open_original"} {_report} - + {_share} diff --git a/Web/Presenters/templates/Videos/View.xml b/Web/Presenters/templates/Videos/View.xml index 845ca9b1..9289d0d5 100644 --- a/Web/Presenters/templates/Videos/View.xml +++ b/Web/Presenters/templates/Videos/View.xml @@ -75,10 +75,10 @@ {_delete} - - {_share} - + + {_share} + {if isset($thisUser)} @@ -87,31 +87,7 @@ {/if} {/if} - {_report} - - + {_report} diff --git a/Web/Presenters/templates/components/attachment.xml b/Web/Presenters/templates/components/attachment.xml index 54a224a5..19d63a6b 100644 --- a/Web/Presenters/templates/components/attachment.xml +++ b/Web/Presenters/templates/components/attachment.xml @@ -26,11 +26,11 @@
- {$attachment->getName()} + {$attachment->getName()} ({$attachment->getFormattedLength()})
{else} - +
diff --git a/Web/Presenters/templates/components/textArea.xml b/Web/Presenters/templates/components/textArea.xml index 9074e86a..15610813 100644 --- a/Web/Presenters/templates/components/textArea.xml +++ b/Web/Presenters/templates/components/textArea.xml @@ -2,7 +2,7 @@ {var $textAreaId = ($post ?? NULL) === NULL ? (++$GLOBALS["textAreaCtr"]) : $post->getId()} {var $textAreaId = ($custom_id ?? NULL) === NULL ? $textAreaId : $custom_id} -
+
diff --git a/Web/Presenters/templates/components/video.xml b/Web/Presenters/templates/components/video.xml index d2ab40ff..b1037d93 100644 --- a/Web/Presenters/templates/components/video.xml +++ b/Web/Presenters/templates/components/video.xml @@ -3,7 +3,7 @@ - +
@@ -15,7 +15,7 @@ {include infotable, x => $dat} {else} - + {$video->getName()} @@ -29,7 +29,7 @@ {_video_uploaded} {$video->getPublicationTime()}

- {_view_video} + {_view_video} {if $video->getCommentsCount() > 0}| {_comments} ({$video->getCommentsCount()}){/if}

{/ifset} diff --git a/Web/static/css/dialog.css b/Web/static/css/dialog.css index 6f940d40..81f7248a 100644 --- a/Web/static/css/dialog.css +++ b/Web/static/css/dialog.css @@ -64,243 +64,147 @@ body.dimmed > .dimmer #absolute_territory { margin-left: 10px; } +/* Modal player */ -/* fullscreen player */ - -.ovk-fullscreen-player { - top: 9%; - left: 50%; - margin-right: -50%; - transform: translate(-50%, 0%); - z-index: 6667; - position: absolute; +.ovk-modal-player-window { + box-shadow: 0px 0px 9px 2px rgba(0, 0, 0, 0.2); width: 823px; min-height: 400px; - box-shadow: 0px 0px 9px 2px rgba(0, 0, 0, 0.2); + margin: 9vh auto 0 auto; } -.top-part span { +.ovk-modal-player-window #ovk-player-part { + height: 70vh; + background: black; + padding: 15px 20px; + box-sizing: border-box; + display: flex; + flex-direction: column; + justify-content: space-between; +} + +.ovk-modal-player-window #ovk-player-part .top-part { + display: flex; + flex-direction: row; + justify-content: space-between; + align-items: center; +} + +.ovk-modal-player-window #ovk-player-part .top-part b { color: #515151; - font-size: 13px; - transition: color 200ms ease-in-out; + font-size: 12px; } -.top-part .clickable:hover { - color: #ffffff; +.ovk-modal-player-window #ovk-player-part .top-part .top-part-buttons, .ovk-modal-player-window #ovk-player-part .bottom-part { + color: #515151; } -.ovk-fullscreen-player .bsdn_teaserTitleBox span { - color: unset; - font-size: unset; +.ovk-modal-player-window #ovk-player-part .top-part .top-part-buttons a, .ovk-modal-player-window #ovk-player-part .bottom-part a { + color: #515151; } -.ovk-fullscreen-player .bsdn-player { - max-width: 80%; - max-height: 350px; -} - -.inner-player { - background: #000000; - min-height: 438px; - max-height: 439px; - position: relative; - padding-top: 11px; -} - -.top-part-name { - font-size: 15px; - font-weight: bolder; - margin-left: 20px; - margin-top: 5px; -} - -.top-part-buttons { - float: right; - margin-right: 20px; -} - -.top-part-buttons span { - cursor: pointer; - user-select: none; -} - -.fplayer { - text-align: center; - margin-top: 20px; -} - -.top-part-bottom-buttons { - position: absolute; - margin-left: 20px; - bottom: 0; - margin-bottom: 20px; -} - -.top-part-bottom-buttons span { - user-select: none; -} - -.top-part .clickable { - cursor: pointer; -} - -.bottom-part { +.ovk-modal-player-window #ovk-player-info { display: none; +} + +.ovk-modal-player-window #ovk-player-info.shown { + display: block; +} + +.ovk-modal-player-window #ovk-player-info { background: white; - padding-bottom: 20px; - padding-top: 30px; + min-height: 200px; + padding: 5px 15px; } -.left_block { - padding-left: 20px; - /*padding-top: 20px;*/ - width: 75%; - float: left; - background: white; - padding-right: 6px; - max-height: 400px; - overflow-y: auto; +.ovk-modal-player-window .media-page-wrapper-comments { + width: 100%; } -.right_block { - padding-left: 10px; - /*padding-top: 20px;*/ - width: 20%; - border-left: 1px solid gray; - float: right; +.ovk-modal-player-window .center-part { + text-align: center; + height: 90%; + display: flex; + align-items: center; + justify-content: center; } -.bottom-part span { - font-size: 13px; -} - -.bottom-part .gray { +.ovk-modal-player-window .center-part .gray { color: gray; } -.ovk-fullscreen-dimmer { - /* спижжено у пулла с несколькими картинками там где просмотрщик фоток */ - position: fixed; - left: 0px; - top: 0px; - right: 0px; - bottom: 0px; - overflow: auto; - padding-bottom: 20px; - z-index: 300; -} - -.v_author { - margin-top: 20px; +.ovk-modal-player-window .center-part .bsdn, .ovk-modal-player-window .center-part .bsdn-player { + height: 100%; + width: 100%; } .miniplayer { position: absolute; - top:0; - background: rgba(54, 54, 54, 0.9); + background: rgba(54, 54, 54, 0.95); border-radius: 3px; min-width: 299px; min-height: 192px; - padding-top: 3px; - z-index: 9999; + z-index: 7777; + padding: 2px 7px; + display: flex; + flex-direction: column; } -.miniplayer .bsdn-player { - max-height: 150px; +.miniplayer .miniplayer-head { + display: flex; + justify-content: space-between; + align-items: center; } -.miniplayer .fplayer { - max-width: 286px; - margin-left: 6px; - margin-top: 10px; -} - -.miniplayer-actions { - float: right; - margin-right: 8px; - margin-top: 4px; -} - -.miniplayer-name { - color: #8a8a8a; - font-size: 14px; - margin-left: 7px; - margin-top: -6px; - font-weight: bolder; +.miniplayer .miniplayer-head b { + color: white; user-select: none; } -.ui-draggable { - position:fixed !important; +.miniplayer .miniplayer-head .miniplayer-head-buttons { + display: flex; + align-items: center; + gap: 4px; } -.miniplayer-actions img { - max-width: 11px; +.miniplayer .miniplayer-head .miniplayer-head-buttons div { + width: 16px; + height: 16px; + background: url(/assets/packages/static/openvk/img/wall.png) no-repeat 1px 0; + background-repeat: no-repeat; + opacity: 0.5; cursor: pointer; - transition: opacity 200ms ease-in-out; - opacity: 70%; } -.miniplayer .fplayer iframe { - max-width: 260px; - max-height: 160px; +.miniplayer .miniplayer-head .miniplayer-head-buttons div:hover { + opacity: 1; } -.miniplayer-actions img:hover { - opacity: 100%; +.miniplayer .miniplayer-head .miniplayer-head-buttons #__miniplayer_return { + background-position: -28px 0px; } -#vidComments { - margin-top: 10px; +.miniplayer .miniplayer-head .miniplayer-head-buttons #__miniplayer_close { + background-position: -12px 0px; } -.showMoreComments { - background: #eaeaea; - cursor: pointer; - text-align: center; - padding: 10px; - user-select: none; - margin-top: 10px; +.miniplayer .miniplayer-head-buttons { + height: 20px; } -.loader { - display: none; - position: fixed; - top: -10%; - background: rgba(26, 26, 26, 0.9);; - padding-top: 12px; - width: 91px; - height: 25px; - text-align: center; - border-radius: 1px; - margin: auto; - left: 0; - right: 0; - bottom: 0; - z-index: 5555; +.miniplayer .miniplayer-body { + height: 100%; } -.right-arrow, .left-arrow { - position: absolute; - cursor: pointer; - transition: all 200ms ease-in-out; - margin-left: -50px; - background: none; - height: 449px; - width: 57px; - user-select: none; +.miniplayer .miniplayer-body .bsdn { + height: 100%; } -.right-arrow img, .left-arrow img { - user-select: none; - opacity: 5%; - transition: all 200ms ease-in-out; +.miniplayer .miniplayer-body .bsdn .bsdn-player { + height: 100%; } -.right-arrow:hover, .left-arrow:hover { - background: rgba(0, 0, 0, 0.5); -} - -.right-arrow img:hover, .left-arrow img:hover { - opacity: 50%; +.miniplayer .miniplayer-body iframe { + width: 100%; + height: 100%; } diff --git a/Web/static/css/main.css b/Web/static/css/main.css index 93ef4eb4..8d517c6e 100644 --- a/Web/static/css/main.css +++ b/Web/static/css/main.css @@ -2630,6 +2630,7 @@ a.poll-retract-vote { overflow-y: auto; overflow-x: hidden; min-height: 300px; + width: 100%; } .ovk-photo-view .ovk-photo-details { @@ -3649,3 +3650,32 @@ hr { .media-page-author-block .media-page-author-block-name span { text-transform: lowercase; } + +#ajloader { + display: none; + position: fixed; + top: -10%; + background: rgba(26, 26, 26, 0.9);; + padding-top: 12px; + width: 91px; + height: 25px; + text-align: center; + border-radius: 1px; + margin: auto; + left: 0; + right: 0; + bottom: 0; + z-index: 5555; +} + +#ajloader.shown { + display: block; +} + +.hoverable_color { + transition: all 0.17s ease-in-out; +} + +.hoverable_color:hover { + color: white !important; +} diff --git a/Web/static/js/al_wall.js b/Web/static/js/al_wall.js index 1ca0fe6c..a4b14bfe 100644 --- a/Web/static/js/al_wall.js +++ b/Web/static/js/al_wall.js @@ -288,6 +288,177 @@ async function OpenMiniature(e, photo, post, photo_id, type = "post") { return photo_viewer.getNode() } +async function OpenVideo(video_arr = [], init_player = true) +{ + CMessageBox.toggleLoader() + const video_owner = video_arr[0] + const video_id = video_arr[1] + let video_api = null + try { + video_api = await window.OVKAPI.call('video.get', {'videos': `${video_owner}_${video_id}`, 'extended': 1}) + + if(!video_api.items || !video_api.items[0]) { + throw new Error('Not found') + } + } catch(e) { + CMessageBox.toggleLoader() + fastError(e.message) + + return + } + + // TODO: video lists + const video_object = video_api.items[0] + const pretty_id = `${video_object.owner_id}_${video_object.id}` + const author = find_author(video_object.owner_id, video_api.profiles, video_api.groups) + let player_html = '' + if(init_player) { + if(video_object.platform == 'youtube') { + const video_url = new URL(video_object.player) + const video_id = video_url.pathname.replace('/', '') + player_html = ` + + ` + } else { + if(!video_object.is_processed) { + player_html = `${tr('video_processing')}` + } else { + const author_name = `${author.first_name} ${author.last_name}` + player_html = ` +
+ +
+ ` + } + } + } + + const msgbox = new CMessageBox({ + title: '...', + close_on_buttons: false, + warn_on_exit: true, + custom_template: u(` +
+
+
+
+ ${escapeHtml(video_object.title)} + + +
+
+ ${player_html} +
+ +
+
+
+
+ `) + }) + + if(video_object.platform != 'youtube' && video_object.is_processed) { + bsdnInitElement(msgbox.getNode().find('.bsdn').nodes[0]) + } + + msgbox.getNode().find('#ovk-player-part #__modal_player_close').on('click', (e) => { + msgbox.close() + }) + + msgbox.getNode().find('#__toggle_comments').on('click', async (e) => { + if(msgbox.getNode().find('#ovk-player-info').hasClass('shown')) { + msgbox.getNode().find('#__toggle_comments').html(tr('show_comments')) + } else { + msgbox.getNode().find('#__toggle_comments').html(tr('close_comments')) + } + + msgbox.getNode().find('#ovk-player-info').toggleClass('shown') + if(msgbox.getNode().find('#ovk-player-info').html().length < 1) { + u('#ovk-player-info').html(`
`) + + const fetcher = await fetch(`/video${pretty_id}`) + const fetch_r = await fetcher.text() + const dom_parser = new DOMParser + const results = u(dom_parser.parseFromString(fetch_r, 'text/html')) + const details = results.find('.ovk-vid-details') + details.find('.media-page-wrapper-description b').remove() + + u('#ovk-player-info').html(details.html()) + } + }) + + msgbox.getNode().find('#__modal_player_minimize').on('click', (e) => { + e.preventDefault() + + const miniplayer = u(` +
+
+ ${escapeHtml(video_object.title)} +
+
+
+
+
+
+
+ `) + msgbox.hide() + + u('body').append(miniplayer) + miniplayer.find('.miniplayer-body').nodes[0].append(msgbox.getNode().find('.center-part > *').nodes[0]) + miniplayer.attr('style', `left:100px;top:${scrollY}px;`) + miniplayer.find('#__miniplayer_return').on('click', (e) => { + msgbox.reveal() + msgbox.getNode().find('.center-part').nodes[0].append(miniplayer.find('.miniplayer-body > *').nodes[0]) + u('.miniplayer').remove() + }) + + miniplayer.find('#__miniplayer_close').on('click', (e) => { + msgbox.close() + u('.miniplayer').remove() + }) + + $('.miniplayer').draggable({cursor: 'grabbing', containment: 'body', cancel: '.miniplayer-body'}) + $('.miniplayer').resizable({ + maxHeight: 2000, + maxWidth: 3000, + minHeight: 150, + minWidth: 200 + }) + }) + + CMessageBox.toggleLoader() +} + +u(document).on('click', '#videoOpen', (e) => { + e.preventDefault() + + try { + const target = e.target.closest('#videoOpen') + const vid = target.dataset.id + const split = vid.split('_') + + OpenVideo(split) + } catch(ec) { + return + } +}) + u("#write > form").on("keydown", function(event) { if(event.ctrlKey && event.keyCode === 13) this.submit(); @@ -315,6 +486,28 @@ function reportPhoto(photo_id) { ]); } +function reportVideo(video_id) { + uReportMsgTxt = tr("going_to_report_video"); + uReportMsgTxt += "
"+tr("report_question_text"); + uReportMsgTxt += "

"+tr("report_reason")+": " + + MessageBox(tr("report_question"), uReportMsgTxt, [tr("confirm_m"), tr("cancel")], [ + (function() { + res = document.querySelector("#uReportMsgInput").value; + xhr = new XMLHttpRequest(); + xhr.open("GET", "/report/" + video_id + "?reason=" + res + "&type=video", true); + xhr.onload = (function() { + if(xhr.responseText.indexOf("reason") === -1) + MessageBox(tr("error"), tr("error_sending_report"), ["OK"], [Function.noop]); + else + MessageBox(tr("action_successfully"), tr("will_be_watched"), ["OK"], [Function.noop]); + }); + xhr.send(null); + }), + Function.noop + ]); +} + var tooltipClientTemplate = Handlebars.compile(` @@ -637,7 +830,7 @@ u('#write').on("drop", function(e) { } }) -u('#write > form').on('submit', (e) => { +u(document).on('submit', '#write > form', (e) => { const target = u(e.target) const horizontal_array = [] const horizontal_input = target.find(`input[name='horizontal_attachments']`) @@ -1271,6 +1464,12 @@ u(document).on('click', '.post.post-nsfw .post-content', (e) => { u(e.target).closest('.post-nsfw').removeClass('post-nsfw') }) +u(document).on('focusin', '#write', (e) => { + const target = u(e.target).closest('#write') + target.find('.post-buttons').attr('style', 'display:block') + target.find('.small-textarea').addClass('expanded-textarea') +}) + async function repost(id, repost_type = 'post') { const repostsCount = u(`#repostsCount${id}`) const previousVal = repostsCount.length > 0 ? Number(repostsCount.html()) : 0; @@ -1730,3 +1929,19 @@ u(document).on('click', '#__sourceAttacher', (e) => { u('.ovk-diag-cont').attr('style', 'width: 325px;') u('#source_flex_kunteynir input').nodes[0].focus() }) + +u(document).on('keyup', async (e) => { + if(u('#ovk-player-part .bsdn').length > 0) { + switch(e.keyCode) { + case 32: + u('#ovk-player-part .bsdn .bsdn_playButton').trigger('click') + break + case 39: + u('#ovk-player-part video').nodes[0].currentTime = u('#ovk-player-part video').nodes[0].currentTime + 2 + break + case 37: + u('#ovk-player-part video').nodes[0].currentTime = u('#ovk-player-part video').nodes[0].currentTime - 2 + break + } + } +}) diff --git a/Web/static/js/messagebox.js b/Web/static/js/messagebox.js index e75d2c7e..5953f392 100644 --- a/Web/static/js/messagebox.js +++ b/Web/static/js/messagebox.js @@ -97,6 +97,22 @@ class CMessageBox { close() { this.__exitDialog() } + + hide() { + u('body').removeClass('dimmed') + u('html').attr('style', 'overflow-y:scroll') + this.getNode().attr('style', 'display: none;') + } + + reveal() { + u('body').addClass('dimmed') + u('html').attr('style', 'overflow-y:hidden') + this.getNode().attr('style', 'display: block;') + } + + static toggleLoader() { + u('#ajloader').toggleClass('shown') + } } window.messagebox_stack = [] diff --git a/Web/static/js/openvk.cls.js b/Web/static/js/openvk.cls.js index 8b5bee57..428fd165 100644 --- a/Web/static/js/openvk.cls.js +++ b/Web/static/js/openvk.cls.js @@ -2,13 +2,6 @@ console.error('!!! You forgot to install NPM packages !!!') } -function expand_wall_textarea(id) { - var el = document.getElementById('post-buttons'+id); - var wi = document.getElementById('wall-post-input'+id); - el.style.display = "block"; - wi.className = "expanded-textarea"; -} - function expand_comment_textarea(id) { var el = document.getElementById('commentTextArea'+id); var wi = document.getElementById('wall-post-input'+id); diff --git a/Web/static/js/utils.js b/Web/static/js/utils.js index a8f7836a..93c5c5b2 100644 --- a/Web/static/js/utils.js +++ b/Web/static/js/utils.js @@ -140,3 +140,20 @@ function strip_tags(text) { return text.replace(/(<([^>]+)>)/gi, "") } + +function find_author(id, profiles, groups) +{ + if(id > 0) { + const profile = profiles.find(prof => prof.id == id) + if(profile) { + return profile + } + } else { + const group = groups.find(grou => grou.id == Math.abs(id)) + if(group) { + return group + } + } + + return null +} diff --git a/locales/ru.strings b/locales/ru.strings index be398411..4ed85015 100644 --- a/locales/ru.strings +++ b/locales/ru.strings @@ -2016,7 +2016,7 @@ /* Fullscreen player */ -"hide_player" = "Скрыть"; +"hide_player" = "Свернуть"; "close_player" = "Закрыть"; "show_comments" = "Показать информацию"; "close_comments" = "Скрыть информацию";