window.savedAudiosPages = {} class playersSearcher { constructor(context_type, context_id) { this.context_type = context_type this.context_id = context_id this.searchType = "by_name" this.query = "" this.page = 1 this.successCallback = () => {} this.errorCallback = () => {} this.beforesendCallback = () => {} this.clearContainer = () => {} } execute() { $.ajax({ type: "POST", url: "/audios/context", data: { context: this.context_type, hash: u("meta[name=csrf]").attr("value"), page: this.page, query: this.query, context_entity: this.context_id, type: this.searchType, returnPlayers: 1, }, beforeSend: () => { this.beforesendCallback() }, error: () => { this.errorCallback() }, success: (response) => { this.successCallback(response, this) } }) } movePage(page) { this.page = page this.execute() } } window.player = new class { context = { object: {}, pagesCount: 0, count: 0, playedPages: [], } __linked_player_id = null current_track_id = 0 tracks = [] get timeType() { return localStorage.getItem('audio.timeType') ?? 0 } set timeType(value) { localStorage.setItem('audio.timeType', value) } get audioPlayer() { return this.__realAudioPlayer } get uiPlayer() { return u('.bigPlayer') } get currentTrack() { return this.__findTrack(this.current_track_id) } get previousTrack() { const current = this.__findTrack(this.current_track_id, true) return this.__findByIndex(current - 1) } get nextTrack() { const current = this.__findTrack(this.current_track_id, true) return this.__findByIndex(current + 1) } get linkedInlinePlayer() { if(!this.__linked_player_id) { return null; } return u('#' + this.__linked_player_id) } async init(input_context) { let context = Object.assign({ url: location.pathname }, input_context) this.context.object = !input_context ? null : context this.__realAudioPlayer = document.createElement("audio") this.dashPlayer = dashjs.MediaPlayer().create() await this.loadContext(input_context ? context.page : 0) this.initEvents() this.__setMediaSessionActions() } initEvents() { this.audioPlayer.ontimeupdate = () => { const time = this.audioPlayer.currentTime; const ps = ((time * 100) / this.currentTrack.length).toFixed(3) this.uiPlayer.find(".time").html(fmtTime(time)) this.__updateTime(time) if (ps <= 100) { this.uiPlayer.find(".track .selectableTrack .slider").attr('style', `left:${ ps}%`); if(this.linkedInlinePlayer) { this.linkedInlinePlayer.find(".subTracks .lengthTrackWrapper .slider").attr('style', `left:${ ps}%`) this.linkedInlinePlayer.find('.mini_timer .nobold').html(fmtTime(time)) } } } this.audioPlayer.onvolumechange = () => { const volume = this.audioPlayer.volume; const ps = Math.ceil((volume * 100) / 1); if (ps <= 100) { this.uiPlayer.find(".volumePanel .selectableTrack .slider").attr('style', `left:${ ps}%`); if(this.linkedInlinePlayer) { this.linkedInlinePlayer.find(".subTracks .volumeTrackWrapper .slider").attr('style', `left:${ ps}%`) } } localStorage.setItem('audio.volume', volume) } this.audioPlayer.onprogress = (e) => { u('.loaded_chunk').remove() const buffered = this.audioPlayer.buffered if (buffered.length > 0) { this.listen_coef += 1.25 const end = buffered.end(buffered.length - 1) const percentage = (end / window.player.audioPlayer.duration) * 100 if(this.uiPlayer.length > 0) { this.uiPlayer.find('.track .selectableTrackLoadProgress .load_bar').attr('style', `width:${percentage.toFixed(2)}%`) } if(this.linkedInlinePlayer) { this.linkedInlinePlayer.find('.lengthTrackWrapper .selectableTrackLoadProgress .load_bar').attr('style', `width:${percentage.toFixed(2)}%`) } } if(window.player.listen_coef > 10) { this.__countListen() window.player.listen_coef = -10 } } this.audioPlayer.onended = (e) => { e.preventDefault() if(!this.nextTrack && window.player.context.playedPages.indexOf(1) == -1) { this.loadContext(1, false) this.setTrack(this.__findByIndex(0).id) } else { this.playNextTrack() } if(this.linkedInlinePlayer && this.connectionType) { const parent = this.linkedInlinePlayer.closest(this.connectionType) const real_current = parent.find(`.audioEmbed[data-realid='${this.current_track_id}']`) u('.audioEntry .playerButton .playIcon.paused').removeClass('paused') u('.audioEntry .subTracks.shown').removeClass('shown') real_current.find('.subTracks').addClass('shown') this.linkPlayer(real_current) } } this.audioPlayer.volume = Number(localStorage.getItem('audio.volume') ?? 1) } async loadContext(page = 1, after = true) { if(!this.context.object) { return } const form_data = new FormData switch(this.context.object.name) { case 'entity_audios': form_data.append('context', this.context.object.name) form_data.append('context_entity', this.context.object.entity_id) break case 'playlist_context': form_data.append('context', this.context.object.name) form_data.append('context_entity', this.context.object.entity_id) break case 'classic_search_context': // todo rifictir form_data.append('context', this.context.object.name) form_data.append('context_entity', JSON.stringify({ 'order': this.context.object.order, 'invert': this.context.object.invert, 'genre': this.context.object.genre, 'only_performers': this.context.object.only_performers, 'with_lyrics': this.context.object.with_lyrics, 'query': this.context.object.query, })) break } form_data.append('page', page) form_data.append("hash", u("meta[name=csrf]").attr("value")) this.context.playedPages.push(page) const req = await fetch('/audios/context', { method: 'POST', body: form_data }) const res = await req.json() if(!res.success) { makeError(tr("unable_to_load_queue")) return } this.context.pagesCount = res.pagesCount this.context.count = res.count this.__appendTracks(res.items, after) } linkPlayer(node) { this.__linked_player_id = node.attr('id') u(this.audioPlayer).trigger('volumechange') } async setTrack(id) { if(!this.tracks || this.tracks.length < 1) { makeError('Context is not loaded yet', 'Red', 5000, 1489) return } this.listen_coef = 0.0 this.current_track_id = id const c_track = this.currentTrack if(!c_track) { makeError('Error playing audio: track not found') return } const protData = { "org.w3.clearkey": { "clearkeys": c_track.keys } }; u('.nowPlaying').removeClass('nowPlaying') if(this.isAtAudiosPage()) { u(`.audioEmbed[data-realid='${id}'] .audioEntry`).addClass('nowPlaying') } navigator.mediaSession.setPositionState({ duration: this.currentTrack.length }) this.__updateMediaSession() this.dashPlayer.initialize(this.audioPlayer, c_track.url, false); this.dashPlayer.setProtectionData(protData) if(!this.nextTrack && Math.max(...this.context["playedPages"]) < this.context["pagesCount"]) { await this.loadContext(Number(Math.max(...this.context["playedPages"])) + 1, true) } if(!this.previousTrack && (Math.min(...this.context["playedPages"]) > 1)) { await this.loadContext(Math.min(...this.context["playedPages"]) - 1, false) } this.__updateFace() u(this.audioPlayer).trigger('volumechange') } switchTracks(id1, id2) { const first_audio = this.__findTrack(id1) const first_audio_index = this.__findTrack(id1, true) const second_audio = this.__findTrack(id2) const second_audio_index = this.__findTrack(id2, true) this.tracks[first_audio_index] = second_audio this.tracks[second_audio_index] = first_audio this.__updateFace() } appendTrack(object, after = true) { this.__appendTracks([object], after) } hasTrackWithId(id) { return this.__findTrack(id, true) != -1 } play() { if(!this.currentTrack) { return } document.querySelectorAll('audio').forEach(el => el.pause()) this.audioPlayer.play() this.__setFavicon() this.__updateFace() navigator.mediaSession.playbackState = "playing" } pause() { if(!this.currentTrack) { return } this.audioPlayer.pause() this.__setFavicon('paused') this.__updateFace() navigator.mediaSession.playbackState = "paused" } playPreviousTrack() { if(!this.currentTrack || !this.previousTrack) { return } this.setTrack(this.previousTrack.id) if(!this.currentTrack.available || this.currentTrack.withdrawn) { if(!this.previousTrack) { return } this.playPreviousTrack() } this.play() } playNextTrack() { if(!this.currentTrack || !this.nextTrack) { return } this.setTrack(this.nextTrack.id) if(!this.currentTrack.available || this.currentTrack.withdrawn) { if(!this.nextTrack) { return } this.playNextTrack() } this.play() } // fake shuffle shuffle() { this.tracks.sort(() => Math.random() - 0.59) this.setTrack(this.tracks.at(0).id) } isAtAudiosPage() { return u('.bigPlayer').length > 0 } __setFavicon(state = 'playing') { if(state == 'playing') { document.querySelector('link[rel="icon"], link[rel="shortcut icon"]').setAttribute("href", "/assets/packages/static/openvk/img/favicons/favicon24_paused.png") } else { document.querySelector('link[rel="icon"], link[rel="shortcut icon"]').setAttribute("href", "/assets/packages/static/openvk/img/favicons/favicon24_playing.png") } } __findTrack(id, return_index = false) { if(return_index) { return this.tracks.indexOf(this.tracks.find(item => item.id == id)) } return this.tracks.find(item => item.id == id) } __findByIndex(index) { return this.tracks[index] } __setMediaSessionActions() { navigator.mediaSession.setActionHandler('play', () => { window.player.play() }); navigator.mediaSession.setActionHandler('pause', () => { window.player.pause() }); navigator.mediaSession.setActionHandler('previoustrack', () => { window.player.playPreviousTrack() }); navigator.mediaSession.setActionHandler('nexttrack', () => { window.player.playNextTrack() }); navigator.mediaSession.setActionHandler("seekto", (details) => { window.player.audioPlayer.currentTime = details.seekTime }); } __appendTracks(list, after = true) { if(after) { this.tracks = this.tracks.concat(list) } else { this.tracks = list.concat(this.tracks) } } __updateFace() { // Во второй раз перепутал next и back, но фиксить смысла уже нет. const _c = this.currentTrack const prev_button = this.uiPlayer.find('.nextButton') const next_button = this.uiPlayer.find('.backButton') if(!this.previousTrack) { prev_button.addClass('lagged') } else { prev_button.removeClass('lagged') prev_button.attr('data-title', ovk_proc_strtr(escapeHtml(this.previousTrack.name), 50)) } if(!this.nextTrack) { next_button.addClass('lagged') } else { next_button.removeClass('lagged') next_button.attr('data-title', ovk_proc_strtr(escapeHtml(this.nextTrack.name), 50)) } if(!this.audioPlayer.paused) { this.uiPlayer.find('.playButton').addClass('pause') if(this.linkedInlinePlayer) { this.linkedInlinePlayer.find('.playerButton .playIcon').addClass('paused') } } else { this.uiPlayer.find('.playButton').removeClass('pause') if(this.linkedInlinePlayer) { this.linkedInlinePlayer.find('.playerButton .playIcon').removeClass('paused') } } this.uiPlayer.find('.trackInfo .trackName span').html(escapeHtml(_c.name)) this.uiPlayer.find('.trackInfo .trackPerformers').html('') const performers = _c.performer.split(', ') const lastPerformer = performers[performers.length - 1] performers.forEach(performer => { this.uiPlayer.find('.trackInfo .trackPerformers').append( `${performer.escapeHtml()}${(performer != lastPerformer ? ', ' : '')}`) }) u(`.tip_result`).remove() } __updateTime(new_time) { this.uiPlayer.find(".trackInfo .time").html(fmtTime(new_time)) if(this.timeType == 1) { this.uiPlayer.find(".trackInfo .elapsedTime").html(fmtTime(this.currentTrack.length)) } else { this.uiPlayer.find(".trackInfo .elapsedTime").html(getRemainingTime(this.currentTrack.length, new_time)) } } __updateMediaSession() { const album = document.querySelector(".playlistBlock") const cur = this.currentTrack navigator.mediaSession.metadata = new MediaMetadata({ title: escapeHtml(cur.name), artist: escapeHtml(cur.performer), album: album == null ? "OpenVK Audios" : escapeHtml(album.querySelector(".playlistInfo h4").innerHTML), artwork: [{ src: album == null ? "/assets/packages/static/openvk/img/song.jpg" : album.querySelector(".playlistCover img").src }], }) } async __countListen() { let playlist = 0 if(!this.listen_coef) { return false } if(this.context.object && this.context.object.name == 'playlist_context') { playlist = this.context.object.entity_id } const form_data = new FormData form_data.append('hash', u("meta[name=csrf]").attr("value")) form_data.append('playlist', playlist) if(this.context.object) { form_data.append('listened_from', this.context.object.url) } const req = await fetch(`/audio${this.currentTrack.id}/listen`, { method: 'POST', body: form_data }) const res = await req.json() if(res.success) { console.log('Listen is counted') } else { console.log('Listen is not counted ! ! !') } } } document.addEventListener("DOMContentLoaded", async () => { await window.player.init(window.__current_page_audio_context) }) u(document).on('click', '.audioEntry .playerButton > .playIcon', (e) => { const audioPlayer = u(e.target).closest('.audioEmbed') const id = Number(audioPlayer.attr('data-realid')) if(!window.player) { return } if(!window.player.hasTrackWithId(id) && !window.player.isAtAudiosPage()) { let _nodes = null if(u(e.target).closest('.attachments').length > 0) { window.player.connectionType = '.attachments' _nodes = u(e.target).closest('.attachments').find('.audioEmbed').nodes } else if(u(e.target).closest('.content_list').length > 0) { window.player.connectionType = '.content_list' _nodes = u(e.target).closest('.content_list').find('.audioEmbed').nodes } _nodes.forEach(el => { const tempAudio = u(el) const name = tempAudio.attr('data-name').split(' — ') window.player.appendTrack({ 'id': Number(tempAudio.attr('data-realid')), 'available': true, // , судя по всему 'keys': JSON.parse(tempAudio.attr('data-keys')), 'length': Number(tempAudio.attr('data-length')), 'url': tempAudio.attr('data-url'), 'name': name[1], 'performer': name[0] }) }) } if(window.player.current_track_id != id) { window.player.setTrack(id) } if(window.player.audioPlayer.paused) { window.player.play() if(!window.player.isAtAudiosPage()) { u('.audioEntry .playerButton .playIcon.paused').removeClass('paused') u(e.target).addClass('paused') } } else { window.player.pause() } if(window.player.isAtAudiosPage()) { } else { window.player.linkPlayer(audioPlayer) u('.audioEntry .subTracks.shown').removeClass('shown') audioPlayer.find('.subTracks').addClass('shown') } }) u(document).on('click', '.bigPlayer .playButton', (e) => { if(window.player.audioPlayer.paused) { window.player.play() } else { window.player.pause() } }) u(document).on('click', '.bigPlayer .backButton', (e) => { window.player.playNextTrack() }) u(document).on('click', '.bigPlayer .nextButton', (e) => { window.player.playPreviousTrack() }) u(document).on("click", ".bigPlayer .elapsedTime", (e) => { if(window.player.current_track_id == 0) return const res = window.player.timeType == 0 ? 1 : 0 window.player.timeType = res window.player.__updateTime(window.player.audioPlayer.currentTime) }) u(document).on("click", ".bigPlayer .additionalButtons .repeatButton", (e) => { if(window.player.current_track_id == 0) return const targ = u(e.target) targ.toggleClass("pressed") if(targ.hasClass("pressed")) window.player.audioPlayer.loop = true else window.player.audioPlayer.loop = false }) u(document).on("click", ".bigPlayer .additionalButtons .shuffleButton", (e) => { if(window.player.current_track_id == 0) return window.player.shuffle() }) u(document).on("click", ".bigPlayer .additionalButtons .deviceButton", (e) => { if(window.player.current_track_id == 0) return e.target.classList.toggle("pressed") window.player.audioPlayer.muted = e.target.classList.contains("pressed") }) u(document).on('keydown', (e) => { if(document.activeElement.closest('.page_header')) { return } if(!window.player) { return } if([32, 37, 39, 107, 109].includes(e.keyCode)) { if(window.messagebox_stack.length > 0) return e.preventDefault() } const arrow_click_offset = 3 const volume_offset = 0.1 switch(e.keyCode) { case 32: window.player.listen_coef -= 0.1 window.player.uiPlayer.find('.playButton').trigger('click') break case 37: window.player.listen_coef -= 0.5 window.player.audioPlayer.currentTime = window.player.audioPlayer.currentTime - arrow_click_offset break case 39: window.player.listen_coef -= 0.5 window.player.audioPlayer.currentTime = window.player.audioPlayer.currentTime + arrow_click_offset break case 107: window.player.audioPlayer.volume = Math.max(Math.min(window.player.audioPlayer.volume + volume_offset, 1), 0) break case 109: window.player.audioPlayer.volume = Math.max(Math.min(window.player.audioPlayer.volume - volume_offset, 1), 0) break default: //console.log(e.keyCode) break } }) u(document).on('keyup', (e) => { if(document.activeElement.closest('.page_header')) { return } if(!window.player || !window.player.isAtAudiosPage()) { return } if([87, 65, 83, 68, 82, 77].includes(e.keyCode)) { if(window.messagebox_stack.length > 0) return e.preventDefault() } switch(e.keyCode) { case 87: case 65: window.player.playPreviousTrack() break case 83: case 68: window.player.playNextTrack() break case 82: document.querySelector(".bigPlayer .additionalButtons .repeatButton").click() break case 77: document.querySelector(".bigPlayer .additionalButtons .deviceButton").click() break } }) u(document).on("mousemove click mouseup", ".bigPlayer .trackPanel .selectableTrack, .audioEntry .subTracks .lengthTrackWrapper .selectableTrack", (e) => { if(window.player.isAtAudiosPage() && window.player.current_track_id == 0) return function __defaultAction(i_time) { window.player.listen_coef -= 0.5 window.player.audioPlayer.currentTime = i_time } const taggart = u(e.target).closest('.selectableTrack') const parent = taggart.parent() const rect = taggart.nodes[0].getBoundingClientRect() const width = e.clientX - rect.left const time = Math.ceil((width * window.player.currentTrack.length) / (rect.right - rect.left)) if(e.type == "mousemove") { let buttonsPresseed = _bsdnUnwrapBitMask(e.buttons) if(buttonsPresseed[0]) __defaultAction(time) } if(e.type == 'click' || e.type == 'mouseup') { __defaultAction(time) } if(parent.find('.tip_result').length < 1) { parent.append(`
`) } parent.find('.tip_result').html(fmtTime(time)).attr('style', `left:min(${width - 15}px, 315.5px)`) }) u(document).on("mouseout", ".bigPlayer .trackPanel .selectableTrack, .audioEntry .subTracks .lengthTrackWrapper .selectableTrack", (e) => { if(window.player.isAtAudiosPage() && window.player.current_track_id == 0) return u(e.target).closest('.selectableTrack').parent().find('.tip_result').remove() }) u(document).on("mousemove click mouseup", ".bigPlayer .volumePanelTrack .selectableTrack, .audioEntry .subTracks .volumeTrack .selectableTrack", (e) => { if(window.player.isAtAudiosPage() && window.player.current_track_id == 0) return function __defaultAction(i_volume) { window.player.audioPlayer.volume = i_volume } const rect = u(e.target).closest(".selectableTrack").nodes[0].getBoundingClientRect(); const taggart = u(e.target).closest('.selectableTrack') const parent = taggart.parent() const width = e.clientX - rect.left const volume = Math.max(0, (width * 1) / (rect.right - rect.left)) if(e.type == "mousemove") { let buttonsPresseed = _bsdnUnwrapBitMask(e.buttons) if(buttonsPresseed[0]) __defaultAction(volume) } if(e.type == 'click' || e.type == 'mouseup') { __defaultAction(volume) } if(parent.find('.tip_result').length < 1) { parent.append(`
`) } parent.find('.tip_result').html((volume * 100).toFixed(0) + '%').attr('style', `left:${width - 15}px`) }) u(document).on("mouseout", ".bigPlayer .volumePanelTrack .selectableTrack, .audioEntry .subTracks .volumeTrack .selectableTrack", (e) => { if(window.player.isAtAudiosPage() && window.player.current_track_id == 0) return u(e.target).closest('.selectableTrack').parent().find('.tip_result').remove() }) u(document).on('dragstart', '.audiosContainer .audioEmbed', (e) => { u(e.target).closest('.audioEmbed').addClass('currently_dragging') return }) u(document).on('dragover', '.audiosContainer .audioEmbed', (e) => { e.preventDefault() const target = u(e.target).closest('.audioEmbed') const current = u('.audioEmbed.currently_dragging') if(current.length < 1) { return } if(target.nodes[0].dataset.id != current.nodes[0].dataset.id) { target.addClass('dragged') } return }) u(document).on('dragend', '.audiosContainer .audioEmbed', (e) => { //console.log(e) u(e.target).closest('.audioEmbed').removeClass('dragged') return }) // TODO: write changes on server side (audio.reorder) u(document).on("drop", '.audiosContainer', function(e) { const current = u('.audioEmbed.currently_dragging') if(e.dataTransfer.types.includes('Files')) { e.preventDefault() e.dataTransfer.dropEffect = 'move' } else if(e.dataTransfer.types.length < 1 || e.dataTransfer.types.includes('text/uri-list')) { e.preventDefault() u('.audioEmbed.currently_dragging').removeClass('currently_dragging') const target = u(e.target).closest('.audioEmbed') const first_id = Number(current.attr('data-realid')) const second_id = Number(target.attr('data-realid')) const first_html = target.nodes[0].outerHTML const second_html = current.nodes[0].outerHTML current.nodes[0].outerHTML = first_html target.nodes[0].outerHTML = second_html window.player.switchTracks(first_id, second_id) } }) u(document).on("click", ".musicIcon.edit-icon", (e) => { const player = e.target.closest(".audioEmbed") const id = Number(player.dataset.realid) const performer = e.target.dataset.performer const name = e.target.dataset.title const genre = player.dataset.genre const lyrics = e.target.dataset.lyrics MessageBox(tr("edit_audio"), `
${tr("performer")}
${tr("audio_name")}
${tr("genre")}
${tr("lyrics")}


${tr("fully_delete_audio")}
`, [tr("save"), tr("cancel")], [ function() { const t_name = $(".ovk-diag-body input[name=name]").val(); const t_perf = $(".ovk-diag-body input[name=performer]").val(); const t_genre = $(".ovk-diag-body select[name=genre]").val(); const t_lyrics = $(".ovk-diag-body textarea[name=lyrics]").val(); const t_explicit = document.querySelector(".ovk-diag-body input[name=explicit]").checked; const t_unlisted = document.querySelector(".ovk-diag-body input[name=searchable]").checked; $.ajax({ type: "POST", url: `/audio${id}/action?act=edit`, data: { name: t_name, performer: t_perf, genre: t_genre, lyrics: t_lyrics, unlisted: Number(t_unlisted), explicit: Number(t_explicit), hash: u("meta[name=csrf]").attr("value") }, success: (response) => { if(response.success) { const perf = player.querySelector(".performer a") perf.innerHTML = escapeHtml(response.new_info.performer) perf.setAttribute("href", "/search?q=§ion=audios&order=listens&only_performers=on&q="+response.new_info.performer) e.target.setAttribute("data-performer", escapeHtml(response.new_info.performer)) e.target.setAttribute("data-title", escapeHtml(response.new_info.name)) e.target.setAttribute("data-lyrics", response.new_info.lyrics_unformatted) e.target.setAttribute("data-explicit", Number(response.new_info.explicit)) e.target.setAttribute("data-searchable", Number(!response.new_info.unlisted)) player.setAttribute("data-genre", response.new_info.genre) let name = player.querySelector(".title") name.innerHTML = escapeHtml(response.new_info.name) if(response.new_info.lyrics_unformatted != "") { if(player.querySelector(".lyrics") != null) { player.querySelector(".lyrics").innerHTML = response.new_info.lyrics player.querySelector(".title").classList.add("withLyrics") } else { player.insertAdjacentHTML("beforeend", `
${response.new_info.lyrics}
`) player.querySelector(".title").classList.add("withLyrics") } } else { $(player.querySelector(".lyrics")).remove() player.querySelector(".title").classList.remove("withLyrics") } if(Number(response.new_info.explicit) == 1) { if(!player.querySelector(".mediaInfo .explicitMark")) player.querySelector(".mediaInfo").insertAdjacentHTML("beforeend", `
`) } else { $(player.querySelector(".mediaInfo .explicitMark")).remove() } let url = new URL(location.href) let page = "1" if(url.searchParams.p != null) page = String(url.searchParams.p) window.savedAudiosPages[page] = null } else fastError(response.flash.message) } }); }, Function.noop ]); window.openvk.audio_genres.forEach(elGenre => { document.querySelector(".ovk-diag-body select[name=genre]").insertAdjacentHTML("beforeend", ` `) }) u(".ovk-diag-body #_fullyDeleteAudio").on("click", (e) => { MessageBox(tr('confirm'), tr('confirm_deleting_audio'), [tr('yes'), tr('no')], [() => { $.ajax({ type: "POST", url: `/audio${id}/action?act=delete`, data: { hash: u("meta[name=csrf]").attr("value") }, success: (response) => { u("body").removeClass("dimmed"); u(".ovk-diag-cont").remove(); document.querySelector("html").style.overflowY = "scroll" if(response.success) u(player).remove() else fastError(response.flash.message) } }); }, () => {Function.noop}]) }) }) u(document).on("click", ".title.withLyrics", (e) => { const parent = e.currentTarget.closest(".audioEmbed") parent.querySelector(".lyrics").classList.toggle("showed") }) $(document).on("click", ".musicIcon.remove-icon", (e) => { e.stopImmediatePropagation() const id = e.currentTarget.dataset.id if(e.detail > 1 || e.altKey) { const player = e.target.closest('.audioEmbed') player.querySelector('.add-icon-group').click() return } let formdata = new FormData() formdata.append("hash", u("meta[name=csrf]").attr("value")) ky.post(`/audio${id}/action?act=remove`, { hooks: { beforeRequest: [ (_request) => { e.target.classList.add("lagged") } ], afterResponse: [ async (_request, _options, response) => { let json = await response.json() if(json.success) { e.target.classList.remove("remove-icon") e.target.classList.add("add-icon") e.target.classList.remove("lagged") let withd = e.target.closest(".audioEmbed.withdrawn") if(withd != null) u(withd).remove() } else fastError(json.flash.message) } ] }, body: formdata }) }) $(document).on("click", ".musicIcon.remove-icon-group", (e) => { e.stopImmediatePropagation() let id = e.currentTarget.dataset.id let formdata = new FormData() formdata.append("hash", u("meta[name=csrf]").attr("value")) formdata.append("club", e.currentTarget.dataset.club) ky.post(`/audio${id}/action?act=remove_club`, { hooks: { beforeRequest: [ (_request) => { e.currentTarget.classList.add("lagged") } ], afterResponse: [ async (_request, _options, response) => { let json = await response.json() if(json.success) $(e.currentTarget.closest(".audioEmbed")).remove() else fastError(json.flash.message) } ] }, body: formdata }) }) $(document).on("click", ".musicIcon.add-icon-group", async (ev) => { let current_tab = 'club'; const id = Number(ev.target.dataset.id) const body = `
${tr('add_audio_limitations')}
` MessageBox(tr("add_audio"), body, [tr("cancel"), tr("add")], [Function.noop, () => { const ids = [] u('#_content .entity_vertical_list_item').nodes.forEach(item => { const _checkbox = item.querySelector(`input[type='checkbox'][name='add_to']`) if(_checkbox.checked) { ids.push(item.dataset.id) } }) if(ids.length < 1 || ids.length > 10) { return } switch(current_tab) { case 'club': $.ajax({ type: "POST", url: `/audio${id}/action?act=add_to_club`, data: { hash: u("meta[name=csrf]").attr("value"), clubs: ids.join(',') }, success: (response) => { if(!response.success) fastError(response.flash.message) else NewNotification(tr("audio_was_successfully_added"), '') } }) break case 'playlist': $.ajax({ type: "POST", url: `/audio${id}/action?act=add_to_playlist`, data: { hash: u("meta[name=csrf]").attr("value"), playlists: ids.join(',') }, success: (response) => { if(!response.success) fastError(response.flash.message) else NewNotification(tr("audio_was_successfully_added"), '') } }) break } }]) u(".ovk-diag-body").attr('style', 'padding:0px;height: 260px;') async function switchTab(tab = 'club') { current_tab = tab u(`#_addAudioAdditional .mb_tab`).attr('id', 'ki') u(`#_addAudioAdditional .mb_tab[data-name='${tab}']`).attr('id', 'active') switch(tab) { case 'club': u("#_content").html(`
`) if(window.openvk.writeableClubs == null) { u('.entity_vertical_list').append(`
`) try { window.openvk.writeableClubs = await API.Groups.getWriteableClubs() } catch (e) { u("#_content").html(tr("no_access_clubs")) return } u('.entity_vertical_list #gif_loader').remove() } window.openvk.writeableClubs.forEach(el => { u("#_content .entity_vertical_list").append(` `) }) break case 'playlist': const per_page = 10 let page = 0 u("#_content").html(`
`) async function recievePlaylists(s_page) { res = await fetch(`/method/audio.searchAlbums?auth_mechanism=roaming&query=&limit=10&offset=${s_page * per_page}&from_me=1`) res = await res.json() return res } function appendPlaylists(response) { response.items.forEach(el => { u("#_content .entity_vertical_list").append(` `) }) if(response.count > per_page * page) { u("#_content .entity_vertical_list").append(`${tr('show_more')}`) } } if(window.openvk.writeablePlaylists == null) { u('.entity_vertical_list').append(`
`) try { res = await recievePlaylists(page) page += 1 window.openvk.writeablePlaylists = res.response if(!window.openvk.writeablePlaylists || window.openvk.writeablePlaylists.count < 1) { throw new Error } } catch (e) { u("#_content").html(tr("no_access_playlists")) return } u('.entity_vertical_list #gif_loader').remove() } appendPlaylists(window.openvk.writeablePlaylists) u('#_addAudioAdditional').on('click', '#_pladdwinshowmore', async (e) => { e.target.outerHTML = '' res = await recievePlaylists(page) page += 1 appendPlaylists(res.response) }) break } } switchTab(current_tab) u("#_addAudioAdditional").on("click", ".mb_tab a", async (e) => { await switchTab(u(e.target).closest('.mb_tab').attr('data-name')) }) u("#_addAudioAdditional").on("click", "input[name='add_to']", async (e) => { if(u(`input[name='add_to']:checked`).length > 10) { e.preventDefault() } }) }) $(document).on("click", ".musicIcon.add-icon", (e) => { const id = e.currentTarget.dataset.id if(e.detail > 1 || e.altKey) { const player = e.target.closest('.audioEmbed') player.querySelector('.add-icon-group').click() return } let formdata = new FormData() formdata.append("hash", u("meta[name=csrf]").attr("value")) ky.post(`/audio${id}/action?act=add`, { hooks: { beforeRequest: [ (_request) => { e.target.classList.add("lagged") } ], afterResponse: [ async (_request, _options, response) => { let json = await response.json() if(json.success) { e.target.classList.remove("add-icon") e.target.classList.add("remove-icon") e.target.classList.remove("lagged") } else fastError(json.flash.message) } ] }, body: formdata }) }) $(document).on("click", "#_deletePlaylist", (e) => { let id = e.currentTarget.dataset.id MessageBox(tr("warning"), tr("sure_delete_playlist"), [tr("yes"), tr("no")], [() => { $.ajax({ type: "POST", url: `/playlist${id}/action?act=delete`, data: { hash: u("meta[name=csrf]").attr("value"), }, beforeSend: () => { e.currentTarget.classList.add("lagged") }, success: (response) => { if(response.success) { window.router.route("/playlists" + response.id) } else { fastError(response.flash.message) } } }) }, Function.noop]) }) $(document).on("click", "#__audioAttachment", (e) => { const form = e.target.closest("form") let body = `
` MessageBox(tr("select_audio"), body, [tr("close")], [Function.noop]) document.querySelector(".ovk-diag-body").style.padding = "0" document.querySelector(".ovk-diag-cont").style.width = "580px" document.querySelector(".ovk-diag-body").style.height = "335px" let searcher = new playersSearcher("entity_audios", 0) searcher.successCallback = (response, thisc) => { let domparser = new DOMParser() let result = domparser.parseFromString(response, "text/html") let pagesCount = result.querySelector("input[name='pagesCount']").value let count = Number(result.querySelector("input[name='count']").value) if(count < 1) { document.querySelector(".audiosInsert").innerHTML = thisc.context_type == "entity_audios" ? tr("no_audios_thisuser") : tr("no_results") return } result.querySelectorAll(".audioEmbed").forEach(el => { let id = el.dataset.prettyid const is_attached = (u(form).find(`.post-vertical .vertical-attachment[data-id='${id}']`)).length > 0 document.querySelector(".audiosInsert").insertAdjacentHTML("beforeend", `
${el.outerHTML}
${is_attached ? tr("detach_audio") : tr("attach_audio")}
`) }) u("#loader").remove() u('#show_more').remove() if(thisc.page < pagesCount) { document.querySelector(".audiosInsert").insertAdjacentHTML("beforeend", `
${tr("show_more_audios")}
`) } } searcher.errorCallback = () => { fastError("Error when loading players.") } searcher.beforesendCallback = () => { document.querySelector(".audiosInsert").insertAdjacentHTML("beforeend", ``) } searcher.clearContainer = () => { document.querySelector(".audiosInsert").innerHTML = "" } searcher.movePage(1) u(".audiosInsert").on("click", "#show_more", async (e) => { u(e.target).closest('#show_more').addClass('lagged') searcher.movePage(Number(e.currentTarget.dataset.page)) }) $(".searchBox input").on("change", async (e) => { if(e.currentTarget.value === document.querySelector(".searchBox input").value) { searcher.clearContainer() if(e.currentTarget.value == "") { searcher.context_type = "entity_audios" searcher.context_id = 0 searcher.query = "" searcher.movePage(1) return } searcher.context_type = "search_context" searcher.context_id = 0 searcher.query = e.currentTarget.value searcher.movePage(1) return; } }) $(".searchBox select").on("change", async (e) => { searcher.clearContainer() searcher.searchType = e.currentTarget.value $(".searchBox input").trigger("change") return; }) u(".audiosInsert").on("click", ".attachAudio", (ev) => { const id = ev.currentTarget.dataset.attachmentdata const is_attached = u(form).find(`.post-vertical .vertical-attachment[data-id='${id}']`).length > 0 // 04.11.2024 19:03 if(is_attached) { u(form).find(`.post-vertical .vertical-attachment[data-id='${id}']`).remove() u(ev.currentTarget).find("span").html(tr("attach_audio")) } else { if(u(form).find(`.upload-item`).length > window.openvk.max_attachments) { makeError(tr('too_many_attachments'), 'Red', 10000, 1) return } u(ev.currentTarget).find("span").html(tr("detach_audio")) const header = u(ev.currentTarget).closest('.audio_attachment_header') const player = header.find('.player_part') u(form).find(".post-vertical").append(`
${player.html()}
`) } }) }) $(document).on("click", ".audioEmbed.processed .playerButton", (e) => { const msg = new CMessageBox({ title: tr('error'), body: tr('audio_embed_processing'), unique_name: 'processing_notify', buttons: [tr('ok')], callbacks: [Function.noop] }) }) $(document).on("click", ".audioEmbed.withdrawn", (e) => { 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) => { MessageBox(tr("report_question"), ` ${tr("going_to_report_audio")}
${tr("report_question_text")}

${tr("report_reason")}: `, [tr("confirm_m"), tr("cancel")], [(function() { res = document.querySelector("#uReportMsgInput").value; xhr = new XMLHttpRequest(); xhr.open("GET", "/report/" + e.target.dataset.id + "?reason=" + res + "&type=audio", 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]) }) u(document).on("click", ".audiosContainer .paginator a", (e) => { e.preventDefault() let url = new URL(e.currentTarget.href) let page = url.searchParams.get("p") function searchNode(id) { let node = document.querySelector(`.audioEmbed[data-realid='${id}'] .audioEntry`) if(node != null) { node.classList.add("nowPlaying") } } if(window.savedAudiosPages[page] != null) { history.pushState({}, "", e.currentTarget.href) document.querySelector(".audiosContainer").innerHTML = window.savedAudiosPages[page].innerHTML searchNode(window.player.currentTrack != null ? window.player.currentTrack.id : 0) return } e.currentTarget.parentNode.classList.add("lagged") $.ajax({ type: "GET", url: e.currentTarget.href, success: (response) => { let domparser = new DOMParser() let result = domparser.parseFromString(response, "text/html") document.querySelector(".audiosContainer").innerHTML = result.querySelector(".audiosContainer").innerHTML history.pushState({}, "", e.currentTarget.href) window.savedAudiosPages[page] = result.querySelector(".audiosContainer") searchNode(window.player.currentTrack != null ? window.player.currentTrack.id : 0) if(!window.player.context["playedPages"].includes(page)) { window.player.loadContext(page) } } }) }) $(document).on("click", ".addToPlaylist", (e) => { let audios = document.querySelector("input[name='audios']") let id = e.currentTarget.dataset.id if(!audios.value.includes(id + ",")) { document.querySelector("input[name='audios']").value += (id + ",") e.currentTarget.querySelector("span").innerHTML = tr("remove_from_playlist") } else { document.querySelector("input[name='audios']").value = document.querySelector("input[name='audios']").value.replace(id + ",", "") e.currentTarget.querySelector("span").innerHTML = tr("add_to_playlist") } }) $(document).on("click", "#bookmarkPlaylist, #unbookmarkPlaylist", (e) => { let target = e.currentTarget let id = target.id $.ajax({ type: "POST", url: `/playlist${e.currentTarget.dataset.id}/action?act=${id == "unbookmarkPlaylist" ? "unbookmark" : "bookmark"}`, data: { hash: u("meta[name=csrf]").attr("value"), }, beforeSend: () => { e.currentTarget.classList.add("lagged") }, success: (response) => { if(response.success) { e.currentTarget.setAttribute("id", id == "unbookmarkPlaylist" ? "bookmarkPlaylist" : "unbookmarkPlaylist") e.currentTarget.innerHTML = id == "unbookmarkPlaylist" ? tr("bookmark") : tr("unbookmark") e.currentTarget.classList.remove("lagged") } else fastError(response.flash.message) } }) })