mirror of
https://github.com/openvk/openvk
synced 2024-12-22 16:42:32 +03:00
Add context menu for audios
This commit is contained in:
parent
2cff603e11
commit
1d719309c7
15 changed files with 270 additions and 25 deletions
|
@ -97,9 +97,12 @@ final class AudioPresenter extends OpenVKPresenter
|
|||
$this->template->club = $owner < 0 ? $entity : NULL;
|
||||
$this->template->isMy = ($owner > 0 && ($entity->getId() === $this->user->id));
|
||||
$this->template->isMyClub = ($owner < 0 && $entity->canBeModifiedBy($this->user->identity));
|
||||
} else {
|
||||
$audios = $this->audios->getPopular();
|
||||
$audiosCount = $audios->size();
|
||||
} else if ($mode === 'alone_audio') {
|
||||
$audios = [$this->template->alone_audio];
|
||||
$audiosCount = 1;
|
||||
|
||||
$this->template->owner = $this->user->identity;
|
||||
$this->template->ownerId = $this->user->id;
|
||||
}
|
||||
|
||||
// $this->renderApp("owner=$owner");
|
||||
|
@ -271,6 +274,19 @@ final class AudioPresenter extends OpenVKPresenter
|
|||
}
|
||||
}
|
||||
|
||||
function renderAloneAudio(int $owner_id, int $audio_id): void
|
||||
{
|
||||
$this->assertUserLoggedIn();
|
||||
|
||||
$found_audio = $this->audios->get($audio_id);
|
||||
if(!$found_audio || $found_audio->isDeleted() || !$found_audio->canBeViewedBy($this->user->identity)) {
|
||||
$this->notFound();
|
||||
}
|
||||
|
||||
$this->template->alone_audio = $found_audio;
|
||||
$this->renderList(NULL, 'alone_audio');
|
||||
}
|
||||
|
||||
function renderListen(int $id): void
|
||||
{
|
||||
if ($_SERVER["REQUEST_METHOD"] === "POST") {
|
||||
|
@ -762,6 +778,15 @@ final class AudioPresenter extends OpenVKPresenter
|
|||
$audios = $stream->page($page, 10);
|
||||
$audiosCount = $stream->size();
|
||||
break;
|
||||
case 'alone_audio':
|
||||
$found_audio = $this->audios->get($ctx_id);
|
||||
if(!$found_audio || $found_audio->isDeleted() || !$found_audio->canBeViewedBy($this->user->identity)) {
|
||||
$this->flashFail("err", "Error", "Not found", 89, true);
|
||||
}
|
||||
|
||||
$audios = [$found_audio];
|
||||
$audiosCount = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
$pagesCount = ceil($audiosCount / $perPage);
|
||||
|
|
|
@ -11,6 +11,8 @@
|
|||
{_audio_new}
|
||||
{elseif $mode == 'popular'}
|
||||
{_audio_popular}
|
||||
{elseif $mode == 'alone_audio'}
|
||||
{$alone_audio->getName()}
|
||||
{else}
|
||||
{if $ownerId > 0}
|
||||
{_playlists} {$owner->getMorphedName("genitive", false)}
|
||||
|
@ -47,6 +49,10 @@
|
|||
»
|
||||
{if $isMy}{_my_playlists}{else}{_playlists}{/if}
|
||||
</div>
|
||||
|
||||
<div n:if="$mode == 'alone_audio'">
|
||||
{_my_audios_small}
|
||||
</div>
|
||||
{/block}
|
||||
|
||||
{block content}
|
||||
|
@ -62,6 +68,12 @@
|
|||
entity_id: {$ownerId},
|
||||
page: {$page}
|
||||
}
|
||||
{elseif $mode == 'alone_audio'}
|
||||
window.__current_page_audio_context = {
|
||||
name: 'alone_audio',
|
||||
entity_id: {$alone_audio->getId()},
|
||||
page: 1
|
||||
}
|
||||
{/if}
|
||||
</script>
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<div n:class="bigPlayer, $tidy ? tidy">
|
||||
<div n:class="bigPlayer, ctx_place, $tidy ? tidy">
|
||||
<div class="bigPlayerWrapper">
|
||||
<div class="playButtons">
|
||||
<div class="playButton musicIcon" data-tip='simple' data-title="{_play_tip} [Space]"></div>
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
{php $isAvailable = $audio->isAvailable()}
|
||||
{php $performers = $audio->getPerformers()}
|
||||
{php $editable = isset($thisUser) && $audio->canBeModifiedBy($thisUser)}
|
||||
<div id="audioEmbed-{$id}" data-realid="{$audio->getId()}" {if $hideButtons}data-prettyid="{$audio->getPrettyId()}"{/if} data-name="{$audio->getName()}" data-genre="{$audio->getGenre()}" n:class="audioEmbed, !$isAvailable ? processed, $isWithdrawn ? withdrawn" data-length="{$audio->getLength()}" data-keys="{json_encode($audio->getKeys())}" data-url="{$audio->getURL()}">
|
||||
<div id="audioEmbed-{$id}" data-realid="{$audio->getId()}" {if $hideButtons}data-prettyid="{$audio->getPrettyId()}"{/if} data-name="{$audio->getName()}" data-genre="{$audio->getGenre()}" n:class="audioEmbed, ctx_place, !$isAvailable ? processed, $isWithdrawn ? withdrawn" data-length="{$audio->getLength()}" data-keys="{json_encode($audio->getKeys())}" data-url="{$audio->getURL()}">
|
||||
<audio class="audio" />
|
||||
|
||||
<div id="miniplayer" class="audioEntry">
|
||||
|
|
|
@ -203,6 +203,8 @@ routes:
|
|||
handler: "Audio->list"
|
||||
- url: "/audio{num}/listen"
|
||||
handler: "Audio->listen"
|
||||
- url: "/audio{num}_{num}"
|
||||
handler: "Audio->aloneAudio"
|
||||
- url: "/audios/search"
|
||||
handler: "Audio->search"
|
||||
- url: "/audios/newPlaylist"
|
||||
|
|
|
@ -34,7 +34,7 @@
|
|||
box-shadow: 1px 0px 8px 0px rgba(34, 60, 80, 0.2);
|
||||
position: sticky;
|
||||
top: 0px;
|
||||
z-index: 1;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
/* for search */
|
||||
|
|
|
@ -139,7 +139,7 @@ body.dimmed > .dimmer #absolute_territory {
|
|||
}
|
||||
|
||||
.miniplayer {
|
||||
position: absolute;
|
||||
position: fixed;
|
||||
background: rgba(54, 54, 54, 0.95);
|
||||
border-radius: 3px;
|
||||
min-width: 299px;
|
||||
|
|
|
@ -3859,3 +3859,36 @@ hr {
|
|||
.tippy-box[data-animation='up_down'][data-state='visible'] {
|
||||
inset: auto auto 0px 0px;
|
||||
}
|
||||
|
||||
.ctx_place {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
#ctx_menu {
|
||||
position: absolute;
|
||||
z-index: 100;
|
||||
background: #f7f7f7;
|
||||
border: 1px solid #d8d8d8;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
min-width: 185px;
|
||||
}
|
||||
|
||||
#ctx_menu a {
|
||||
padding: 6px 6px 6px 26px;
|
||||
color: black;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
#ctx_menu a:hover {
|
||||
background: #e9e9e9;
|
||||
}
|
||||
|
||||
#ctx_menu a.pressed::before {
|
||||
content: '✓';
|
||||
display: inline-block;
|
||||
position: absolute;
|
||||
left: 9px;
|
||||
top: 3px;
|
||||
font-size: 15px;
|
||||
}
|
||||
|
|
|
@ -217,7 +217,7 @@ window.player = new class {
|
|||
form_data.append('context_entity', this.context.object.entity_id)
|
||||
break
|
||||
case 'classic_search_context':
|
||||
// todo rifictir
|
||||
// tidi riwriti
|
||||
form_data.append('context', this.context.object.name)
|
||||
form_data.append('context_entity', JSON.stringify({
|
||||
'order': this.context.object.order,
|
||||
|
@ -228,6 +228,9 @@ window.player = new class {
|
|||
'query': this.context.object.query,
|
||||
}))
|
||||
break
|
||||
case 'alone_audio':
|
||||
form_data.append('context', this.context.object.name)
|
||||
form_data.append('context_entity', this.context.object.entity_id)
|
||||
}
|
||||
|
||||
form_data.append('page', page)
|
||||
|
@ -395,6 +398,7 @@ window.player = new class {
|
|||
async shuffle() {
|
||||
this.tracks.sort(() => Math.random() - 0.59)
|
||||
await this.setTrack(this.tracks.at(0).id)
|
||||
this.play()
|
||||
}
|
||||
|
||||
isAtAudiosPage() {
|
||||
|
@ -447,7 +451,7 @@ window.player = new class {
|
|||
this.__updateFace()
|
||||
}
|
||||
} else {
|
||||
this.ajClose()
|
||||
this.ajClose(false)
|
||||
this.is_closed = false
|
||||
if(this.tracks.length < 1) {
|
||||
if(window.__current_page_audio_context) {
|
||||
|
@ -622,9 +626,12 @@ window.player = new class {
|
|||
}
|
||||
}
|
||||
|
||||
ajClose() {
|
||||
ajClose(pause = true) {
|
||||
this.is_closed = true
|
||||
if(pause) {
|
||||
this.pause()
|
||||
}
|
||||
|
||||
u('#ajax_audio_player').addClass('hidden')
|
||||
}
|
||||
|
||||
|
@ -637,7 +644,7 @@ window.player = new class {
|
|||
const previous_time_x = localStorage.getItem('audio.lastX') ?? 100
|
||||
const previous_time_y = localStorage.getItem('audio.lastY') ?? scrollY
|
||||
const miniplayer_template = u(`
|
||||
<div id='ajax_audio_player'>
|
||||
<div id='ajax_audio_player' class='ctx_place'>
|
||||
<div id='aj_player'>
|
||||
<div id='aj_player_internal_controls'>
|
||||
<div id='aj_player_play'>
|
||||
|
@ -691,7 +698,7 @@ window.player = new class {
|
|||
$('#ajax_audio_player').draggable({
|
||||
cursor: 'grabbing',
|
||||
containment: 'window',
|
||||
cancel: '#aj_player_track .selectableTrack, #aj_player_volume .selectableTrack',
|
||||
cancel: '#aj_player_track, #aj_player_volume, #aj_player_buttons',
|
||||
stop: function(e) {
|
||||
if(window.player.ajaxPlayer.length > 0) {
|
||||
const left = parseInt(window.player.ajaxPlayer.nodes[0].style.left)
|
||||
|
@ -1022,6 +1029,127 @@ u(document).on("drop", '.audiosContainer', function(e) {
|
|||
}
|
||||
})
|
||||
|
||||
u(document).on('contextmenu', '.bigPlayer, .audioEmbed, #ajax_audio_player', (e) => {
|
||||
e.preventDefault()
|
||||
|
||||
u('#ctx_menu').remove()
|
||||
const ctx_type = u(e.target).closest('.bigPlayer, #ajax_audio_player').length > 0 ? 'main_player' : 'mini_player'
|
||||
const parent = e.target.closest('.ctx_place')
|
||||
if(!parent) {
|
||||
return
|
||||
}
|
||||
|
||||
const rect = parent.getBoundingClientRect()
|
||||
let x, y;
|
||||
let rx = rect.x + window.scrollX, ry = rect.y + window.scrollY
|
||||
x = e.pageX - rx
|
||||
y = e.pageY - ry
|
||||
|
||||
const ctx_u = u(`
|
||||
<div id='ctx_menu' style='top:${y}px;left:${x}px;' data-type='ctx_type'>
|
||||
<a id='audio_ctx_copy'>${tr('copy_link_to_audio')}</a>
|
||||
${ctx_type == 'main_player' ? `
|
||||
<a id='audio_ctx_repeat' ${window.player.audioPlayer.loop ? `class='pressed'` : ''}>${tr('repeat_tip')}</a>
|
||||
<a id='audio_ctx_shuffle'>${tr('shuffle_tip')}</a>
|
||||
<a id='audio_ctx_mute' ${window.player.audioPlayer.muted ? `class='pressed'` : ''}>${tr('mute_tip_noun')}</a>
|
||||
` : ''}
|
||||
${ctx_type == 'mini_player' ? `
|
||||
<a id='audio_ctx_play_next'>${tr('audio_ctx_play_next')}</a>
|
||||
` : ''}
|
||||
<a id='audio_ctx_add_to_group'>${tr('audio_ctx_add_to_group')}</a>
|
||||
<a id='audio_ctx_add_to_playlist'>${tr('audio_ctx_add_to_playlist')}</a>
|
||||
${ctx_type == 'main_player' ? `<a href='https://github.com/mrilyew' target='_blank'>BigPlayer v1.1 by MrIlyew</a>` : ''}
|
||||
</div>
|
||||
`)
|
||||
u(parent).append(ctx_u)
|
||||
ctx_u.find('#audio_ctx_copy').on('click', async (e) => {
|
||||
if(ctx_type == 'main_player') {
|
||||
if(window.player.current_track_id == 0) {
|
||||
makeError(tr('copy_link_to_audio_error_not_selected_track'), 'Red', 4000, 80)
|
||||
return
|
||||
}
|
||||
|
||||
const url = location.origin + `/audio${window.openvk.current_id}_${window.player.current_track_id}`
|
||||
await copyToClipboard(url)
|
||||
} else {
|
||||
const url = location.origin + `/audio${window.openvk.current_id}_${u(e.target).closest('.audioEmbed').attr('data-realid')}`
|
||||
await copyToClipboard(url)
|
||||
}
|
||||
})
|
||||
ctx_u.find('#audio_ctx_repeat').on('click', () => {
|
||||
if(window.player.current_track_id == 0) {
|
||||
return
|
||||
}
|
||||
|
||||
if(!window.player.audioPlayer.loop) {
|
||||
window.player.audioPlayer.loop = true
|
||||
window.player.uiPlayer.find('.repeatButton').addClass('pressed')
|
||||
} else {
|
||||
window.player.audioPlayer.loop = false
|
||||
window.player.uiPlayer.find('.repeatButton').removeClass('pressed')
|
||||
}
|
||||
})
|
||||
ctx_u.find('#audio_ctx_shuffle').on('click', async () => {
|
||||
if(window.player.current_track_id == 0) {
|
||||
return
|
||||
}
|
||||
|
||||
await window.player.shuffle()
|
||||
})
|
||||
ctx_u.find('#audio_ctx_mute').on('click', async () => {
|
||||
if(window.player.current_track_id == 0) {
|
||||
return
|
||||
}
|
||||
|
||||
window.player.uiPlayer.find('.deviceButton').toggleClass('pressed')
|
||||
window.player.audioPlayer.muted = window.player.uiPlayer.find('.deviceButton').hasClass('pressed')
|
||||
})
|
||||
ctx_u.find('#audio_ctx_add_to_group').on('click', async () => {
|
||||
if(ctx_type == 'main_player') {
|
||||
if(window.player.current_track_id == 0) {
|
||||
return
|
||||
}
|
||||
|
||||
__showAudioAddDialog(window.player.current_track_id)
|
||||
} else {
|
||||
__showAudioAddDialog(Number(u(e.target).closest('.audioEmbed').attr('data-realid')))
|
||||
}
|
||||
})
|
||||
ctx_u.find('#audio_ctx_add_to_playlist').on('click', async () => {
|
||||
if(ctx_type == 'main_player') {
|
||||
if(window.player.current_track_id == 0) {
|
||||
return
|
||||
}
|
||||
|
||||
__showAudioAddDialog(window.player.current_track_id, 'playlist')
|
||||
} else {
|
||||
__showAudioAddDialog(Number(u(e.target).closest('.audioEmbed').attr('data-realid')), 'playlist')
|
||||
}
|
||||
})
|
||||
ctx_u.find('#audio_ctx_play_next').on('click', (ev) => {
|
||||
const current_id = window.player.current_track_id
|
||||
const move_id = Number(u(e.target).closest('.audioEmbed').attr('data-realid'))
|
||||
if(current_id == 0) {
|
||||
return
|
||||
}
|
||||
|
||||
if(current_id == move_id) {
|
||||
return
|
||||
}
|
||||
|
||||
const current_index = window.player.__findTrack(current_id, true)
|
||||
const next_track = window.player.__findTrack(move_id)
|
||||
const next_track_player = u(`.audioEmbed[data-realid='${window.player.nextTrack.id}']`)
|
||||
const moving_track_player = u(`.audioEmbed[data-realid='${move_id}']`)
|
||||
|
||||
window.player.tracks.splice(current_index + 1, 0, next_track)
|
||||
if(next_track_player.length > 0 && moving_track_player.length > 0) {
|
||||
next_track_player.nodes[0].outerHTML = moving_track_player.nodes[0].outerHTML + next_track_player.nodes[0].outerHTML
|
||||
moving_track_player.remove()
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
u(document).on("click", ".musicIcon.edit-icon", (e) => {
|
||||
const player = e.target.closest(".audioEmbed")
|
||||
const id = Number(player.dataset.realid)
|
||||
|
@ -1241,9 +1369,7 @@ $(document).on("click", ".musicIcon.remove-icon-group", (e) => {
|
|||
})
|
||||
})
|
||||
|
||||
$(document).on("click", ".musicIcon.add-icon-group", async (ev) => {
|
||||
let current_tab = 'club';
|
||||
const id = Number(ev.target.dataset.id)
|
||||
function __showAudioAddDialog(id, current_tab = 'club') {
|
||||
const body = `
|
||||
<div id='_addAudioAdditional'>
|
||||
<div id='_tabs'>
|
||||
|
@ -1443,6 +1569,10 @@ $(document).on("click", ".musicIcon.add-icon-group", async (ev) => {
|
|||
e.preventDefault()
|
||||
}
|
||||
})
|
||||
}
|
||||
$(document).on("click", ".musicIcon.add-icon-group", async (ev) => {
|
||||
const id = Number(ev.target.dataset.id)
|
||||
__showAudioAddDialog(id)
|
||||
})
|
||||
|
||||
$(document).on("click", ".musicIcon.add-icon", (e) => {
|
||||
|
|
|
@ -436,7 +436,7 @@ async function OpenVideo(video_arr = [], init_player = true)
|
|||
u('.miniplayer').remove()
|
||||
})
|
||||
|
||||
$('.miniplayer').draggable({cursor: 'grabbing', containment: 'body', cancel: '.miniplayer-body'})
|
||||
$('.miniplayer').draggable({cursor: 'grabbing', containment: 'window', cancel: '.miniplayer-body'})
|
||||
$('.miniplayer').resizable({
|
||||
maxHeight: 2000,
|
||||
maxWidth: 3000,
|
||||
|
@ -2405,14 +2405,15 @@ function setStatusEditorShown(shown) {
|
|||
document.getElementById("status_editor").style.display = shown ? "block" : "none";
|
||||
}
|
||||
|
||||
document.addEventListener("click", event => {
|
||||
u(document).on('click', (event) => {
|
||||
u('#ctx_menu').remove()
|
||||
if(u('#status_editor').length < 1) {
|
||||
return
|
||||
}
|
||||
|
||||
if(!event.target.closest("#status_editor") && !event.target.closest("#page_status_text"))
|
||||
setStatusEditorShown(false);
|
||||
});
|
||||
})
|
||||
|
||||
u(document).on('click', '#page_status_text', (e) => {
|
||||
setStatusEditorShown(true)
|
||||
|
|
|
@ -102,12 +102,14 @@ class CMessageBox {
|
|||
u('body').removeClass('dimmed')
|
||||
u('html').attr('style', 'overflow-y:scroll')
|
||||
this.getNode().attr('style', 'display: none;')
|
||||
this.hidden = true
|
||||
}
|
||||
|
||||
reveal() {
|
||||
u('body').addClass('dimmed')
|
||||
u('html').attr('style', 'overflow-y:hidden')
|
||||
this.getNode().attr('style', 'display: block;')
|
||||
this.hidden = false
|
||||
}
|
||||
|
||||
static toggleLoader() {
|
||||
|
|
|
@ -48,7 +48,13 @@ window.router = new class {
|
|||
}
|
||||
|
||||
__closeMsgs() {
|
||||
window.messagebox_stack.forEach(msg => msg.close())
|
||||
window.messagebox_stack.forEach(msg => {
|
||||
if(msg.hidden) {
|
||||
return
|
||||
}
|
||||
|
||||
msg.close()
|
||||
})
|
||||
}
|
||||
|
||||
__appendPage(parsed_content) {
|
||||
|
@ -218,6 +224,11 @@ u(document).on('click', 'a', async (e) => {
|
|||
return
|
||||
}
|
||||
|
||||
if(target.download != null) {
|
||||
console.log('AJAX | Skipped because its download')
|
||||
return
|
||||
}
|
||||
|
||||
if(!dom_url || dom_url == '#' || dom_url.indexOf('javascript:') != -1) {
|
||||
console.log('AJAX | Skipped because its anchor or function call')
|
||||
return
|
||||
|
@ -308,7 +319,6 @@ u(document).on('submit', 'form', async (e) => {
|
|||
history.pushState({'from_router': 1}, '', __new_url)
|
||||
}
|
||||
|
||||
console.log(form_res)
|
||||
window.router.__appendPage(parsed_content)
|
||||
await window.router.__integratePage()
|
||||
|
||||
|
|
|
@ -222,3 +222,19 @@ function serializeForm(form)
|
|||
|
||||
return fd
|
||||
}
|
||||
|
||||
async function copyToClipboard(text) {
|
||||
let fallback = () => {
|
||||
prompt(text);
|
||||
}
|
||||
|
||||
if(typeof navigator.clipboard == "undefined") {
|
||||
fallback()
|
||||
} else {
|
||||
try {
|
||||
await navigator.clipboard.writeText(text)
|
||||
} catch(e) {
|
||||
fallback()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -995,9 +995,16 @@
|
|||
"repeat_tip" = "Repeat";
|
||||
"shuffle_tip" = "Shuffle";
|
||||
"mute_tip" = "Mute";
|
||||
"mute_tip_noun" = "Muted";
|
||||
"playlist_hide_from_search" = "Unlisted";
|
||||
"confirm_deleting_audio" = "Do you sure want to delete this audio?";
|
||||
|
||||
"copy_link_to_audio" = "Copy link to clipboard";
|
||||
"copy_link_to_audio_error_not_selected_track" = "Track was not selected";
|
||||
"audio_ctx_add_to_group" = "Add to group";
|
||||
"audio_ctx_add_to_playlist" = "Add to playlist";
|
||||
"audio_ctx_play_next" = "Play next";
|
||||
|
||||
/* Notifications */
|
||||
|
||||
"feedback" = "Feedback";
|
||||
|
|
|
@ -950,9 +950,16 @@
|
|||
"repeat_tip" = "Повторение";
|
||||
"shuffle_tip" = "Перемешать";
|
||||
"mute_tip" = "Заглушить";
|
||||
"mute_tip_noun" = "Заглушено";
|
||||
"playlist_hide_from_search" = "Не показывать в поиске";
|
||||
"confirm_deleting_audio" = "Вы действительно хотите полностью удалить аудиозапись?";
|
||||
|
||||
"copy_link_to_audio" = "Копировать ссылку на аудио";
|
||||
"copy_link_to_audio_error_not_selected_track" = "Трек не выбран";
|
||||
"audio_ctx_add_to_group" = "Добавить в группу";
|
||||
"audio_ctx_add_to_playlist" = "Добавить в плейлист";
|
||||
"audio_ctx_play_next" = "Воспроизвести следующим";
|
||||
|
||||
/* Notifications */
|
||||
|
||||
"feedback" = "Ответы";
|
||||
|
|
Loading…
Reference in a new issue