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 linkedInlinePlayer() { if(!this.__linked_player_id) { return null; } return u('#' + this.__linked_player_id) } get ajaxPlayer() { return u('#ajax_audio_player') } 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) } async init(input_context) { let context = Object.assign({ url: location.pathname + location.search }, 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 current_track = this.currentTrack if(!current_track) { return } const time = this.audioPlayer.currentTime const ps = ((time * 100) / current_track.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)) } if(this.ajaxPlayer) { this.ajaxPlayer.find('#aj_player_track_length .slider').attr('style', `left:${ ps}%`) this.ajaxPlayer.find('#aj_player_track_name #aj_time').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}%`) } if(this.ajaxPlayer) { this.ajaxPlayer.find('#aj_player_volume .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 = async (e) => { e.preventDefault() if(!this.nextTrack && window.player.context.playedPages.indexOf(1) == -1) { this.loadContext(1, false) await 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 } if(this.context.playedPages.indexOf(page) != -1) { 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': // tidi riwriti 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 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) 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, ref = null) { if(!this.tracks/* || this.tracks.length < 1*/) { makeError('Context is not loaded yet', 'Red', 5000, 1489) return } if(window.__current_page_audio_context && (!this.context.object || this.context.object.url != location.pathname + location.search)) { console.log('Audio | Resetting context because of ajax :3') this.__renewContext() await this.loadContext(window.__current_page_audio_context.page ?? 1) if(!isNaN(parseInt(location.hash.replace('#', '')))) { const adp = parseInt(location.hash.replace('#', '')) await this.loadContext(adp) } else if((new URL(location.href)).searchParams.p) { const adp = (new URL(location.href)).searchParams.p await this.loadContext(adp) } this.__updateFace() } this.listen_coef = 0.0 const old_id = this.current_track_id this.current_track_id = id const c_track = this.currentTrack if(!c_track) { this.current_track_id = old_id //makeError('Error playing audio: track not found') return } const protData = { "org.w3.clearkey": { "clearkeys": c_track.keys } }; u('.nowPlaying').removeClass('nowPlaying') this.__highlightActiveTrack() 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 && this.hasContext() && Math.max(...this.context["playedPages"]) < this.context["pagesCount"]) { await this.loadContext(Number(Math.max(...this.context["playedPages"])) + 1, true) } if(!this.previousTrack && this.hasContext() && (Math.min(...this.context["playedPages"]) > 1)) { await this.loadContext(Math.min(...this.context["playedPages"]) - 1, false) } this.is_closed = false if(ref != 'localstorage') { this.dump() } this.__updateFace() u(this.audioPlayer).trigger('volumechange') } hasContext() { return this.context.object && this.context.object.url } 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 } async play() { if(!this.currentTrack) { return } document.querySelectorAll('audio').forEach(el => el.pause()) await 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" } async playPreviousTrack() { if(!this.currentTrack || !this.previousTrack) { return } await this.setTrack(this.previousTrack.id) if(!this.currentTrack.available || this.currentTrack.withdrawn) { if(!this.previousTrack) { return } this.playPreviousTrack() } await this.play() } async playNextTrack() { if(!this.currentTrack || !this.nextTrack) { return } await this.setTrack(this.nextTrack.id) if(!this.currentTrack.available || this.currentTrack.withdrawn) { if(!this.nextTrack) { return } this.playNextTrack() } await this.play() } // fake shuffle async shuffle() { this.tracks.sort(() => Math.random() - 0.59) await this.setTrack(this.tracks.at(0).id) await this.play() } isAtAudiosPage() { return u('.bigPlayer').length > 0 } isAtCurrentContextPage() { return this.isAtAudiosPage() && this.context.object.url == location.pathname + location.search } dump() { const final = { context: this.context, current_track_id: this.current_track_id, tracks: this.tracks, time: this.audioPlayer.currentTime, } localStorage.setItem('audio.lastDump', JSON.stringify(final)) console.log('Audio | Tracks was dumped') } undump() { localStorage.setItem('audio.lastDump', null) } async loadDump(dump_object) { this.context = dump_object.context this.tracks = dump_object.tracks if(dump_object.current_track_id && this.hasTrackWithId(dump_object.current_track_id)) { this.current_track_id = dump_object.current_track_id await this.setTrack(this.current_track_id, 'localstorage') } if(dump_object.time) { setTimeout(() => { this.audioPlayer.currentTime = dump_object.time }, 1000) } } // Добавляем ощущение продуманности. __highlightActiveTrack() { if(!this.isAtCurrentContextPage()) { return } u(`.audiosContainer .audioEmbed[data-realid='${this.current_track_id}'] .audioEntry, .audios_padding .audioEmbed[data-realid='${this.current_track_id}'] .audioEntry`).addClass('nowPlaying') } __renewContext() { let context = Object.assign({ url: location.pathname + location.search }, window.__current_page_audio_context) this.pause() this.__resetContext() this.context.object = context } __resetContext() { this.context = { object: {}, pagesCount: 0, count: 0, playedPages: [], } this.tracks = [] //this.__realAudioPlayer = document.createElement("audio") this.listen_coef = 0 } async _handlePageTransition() { const state = this.isAtAudiosPage() if(!state) { // AJAX audio player if(this.is_closed) { return } this.ajaxPlayer.removeClass('hidden') if(this.ajaxPlayer.length > 0) { return } else { if(this.audioPlayer.paused) { return } if(!this.current_track_id || this.current_track_id == 0) { return } this.ajCreate() this.__updateFace() } } else { this.ajClose(false, false) this.is_closed = false if(this.tracks.length < 1) { if(window.__current_page_audio_context) { await this.init(window.__current_page_audio_context) } } } this.__linked_player_id = null if(this.currentTrack) { this.__updateFace() } this.__highlightActiveTrack() u(this.audioPlayer).trigger('volumechange') } __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) { try { return this.tracks.indexOf(this.tracks.find(item => item.id == id)) } catch(e) { return -1 } } try { return this.tracks.find(item => item.id == id) } catch(e) { return null } } __findByIndex(index) { return this.tracks[index] } __setMediaSessionActions() { navigator.mediaSession.setActionHandler('play', async () => { await window.player.play() }); navigator.mediaSession.setActionHandler('pause', () => { window.player.pause() }); navigator.mediaSession.setActionHandler('previoustrack', async () => { await window.player.playPreviousTrack() }); navigator.mediaSession.setActionHandler('nexttrack', async () => { await window.player.playNextTrack() }); navigator.mediaSession.setActionHandler("seekto", async (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') if(this.ajaxPlayer.length > 0) { this.ajaxPlayer.find('#aj_player_previous').addClass('lagged') } } else { prev_button.removeClass('lagged') prev_button.attr('data-title', ovk_proc_strtr(escapeHtml(this.previousTrack.name), 50)) if(this.ajaxPlayer.length > 0) { this.ajaxPlayer.find('#aj_player_previous').removeClass('lagged') } } if(!this.nextTrack) { next_button.addClass('lagged') if(this.ajaxPlayer.length > 0) { this.ajaxPlayer.find('#aj_player_next').addClass('lagged') } } else { next_button.removeClass('lagged') next_button.attr('data-title', ovk_proc_strtr(escapeHtml(this.nextTrack.name), 50)) if(this.ajaxPlayer.length > 0) { this.ajaxPlayer.find('#aj_player_next').removeClass('lagged') } } if(!this.audioPlayer.paused) { this.uiPlayer.find('.playButton').addClass('pause') if(this.linkedInlinePlayer) { this.linkedInlinePlayer.find('.playerButton .playIcon').addClass('paused') } if(this.ajaxPlayer.length > 0) { this.ajaxPlayer.find('#aj_player_play_btn').addClass('paused') } } else { this.uiPlayer.find('.playButton').removeClass('pause') if(this.linkedInlinePlayer) { this.linkedInlinePlayer.find('.playerButton .playIcon').removeClass('paused') } if(this.ajaxPlayer.length > 0) { this.ajaxPlayer.find('#aj_player_play_btn').removeClass('paused') } } if(_c) { 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 ? ', ' : '')}`) }) } else { this.uiPlayer.find('.trackInfo .trackName span').html(tr('track_noname')) this.uiPlayer.find('.trackInfo .trackPerformers').html(`${tr('track_unknown')}`) } if(this.ajaxPlayer.length > 0) { if(_c) { this.ajaxPlayer.find('#aj_player_track_title b').html(escapeHtml(_c.performer)) this.ajaxPlayer.find('#aj_player_track_title span').html(escapeHtml(_c.name)) } } 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 ! ! !') } } ajClose(pause = true, clearTracks = true) { this.is_closed = true if(pause) { this.pause() } if(clearTracks) { this.__resetContext() this.__updateFace() this.current_track_id = null this.audioPlayer.currentTime = 0 this.undump() } u('#ajax_audio_player').addClass('hidden') } ajReveal() { this.is_closed = false if(u('#ajax_audio_player').length == 0) { this.ajCreate() } u('#ajax_audio_player').removeClass('hidden') } ajCreate() { const previous_time_x = localStorage.getItem('audio.lastX') ?? 100 const previous_time_y = localStorage.getItem('audio.lastY') ?? scrollY const miniplayer_template = u(`
`) u('body').append(miniplayer_template) miniplayer_template.attr('style', `left:${previous_time_x}px;top:${previous_time_y}px`) miniplayer_template.find('#aj_player_close_btn').on('click', (e) => { this.ajClose() }) miniplayer_template.find('#aj_time').on('click', (e) => { if(window.player && window.player.context && window.player.context.object) { window.router.route(window.player.context.object.url) } }) $('#ajax_audio_player').draggable({ cursor: 'grabbing', containment: 'window', cancel: '#aj_player_track .selectableTrack, #aj_player_volume .selectableTrack, #aj_player_buttons', stop: function(e) { if(window.player.ajaxPlayer.length > 0) { const left = parseInt(window.player.ajaxPlayer.nodes[0].style.left) const top = parseInt(window.player.ajaxPlayer.nodes[0].style.top) localStorage.setItem('audio.lastX', left) localStorage.setItem('audio.lastY', top) } } }) } } document.addEventListener("DOMContentLoaded", async () => { let parsed = null try { parsed = JSON.parse(localStorage.getItem('audio.lastDump')) } catch(e) {} if(window.openvk.current_id == 0) { return } if(parsed) { await window.player.init(null) await window.player.loadDump(parsed) if(!window.player.isAtAudiosPage() && parsed.current_track_id) { window.player.ajReveal() window.player.__updateFace() u(window.player.audioPlayer).trigger('timeupdate') } } else { await window.player.init(window.__current_page_audio_context) } }) window.addEventListener('beforeunload', (e) => { window.player.dump() }) u(document).on('click', '.audioEntry .playerButton > .playIcon', async (e) => { const audioPlayer = u(e.target).closest('.audioEmbed') const id = Number(audioPlayer.attr('data-realid')) if(!window.player) { return } if(window.openvk.current_id == 0) { 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 } else if(u(e.target).closest('.generic_audio_list').length > 0) { window.player.connectionType = '.generic_audio_list' _nodes = u(e.target).closest('.generic_audio_list').find('.audioEmbed').nodes } else if(u(e.target).closest('.audiosInsert').length > 0) { window.player.connectionType = '.audiosInsert' _nodes = u(e.target).closest('.audiosInsert').find('.audioEmbed').nodes } else if(u(e.target).closest('.scroll_container').length > 0) { window.player.connectionType = '.scroll_container' _nodes = u(e.target).closest('.scroll_container').find('.audioEmbed').nodes } window.player.tracks = [] _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] }) }) } else if(!window.player.hasTrackWithId(id) && window.player.isAtAudiosPage()) { window.player.__renewContext() await window.player.loadContext(window.__current_page_audio_context.page ?? 1) if(!isNaN(parseInt(location.hash.replace('#', '')))) { const adp = parseInt(location.hash.replace('#', '')) await window.player.loadContext(adp) } else if((new URL(location.href)).searchParams.p) { const adp = (new URL(location.href)).searchParams.p await window.player.loadContext(adp) } } if(window.player.current_track_id != id) { await window.player.setTrack(id) } if(window.player.audioPlayer.paused) { await 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, #ajax_audio_player #aj_player_play_btn', async (e) => { if(window.player.audioPlayer.paused) { await window.player.play() } else { window.player.pause() } }) u(document).on('click', '.bigPlayer .backButton, #ajax_audio_player #aj_player_next', async (e) => { await window.player.playNextTrack() }) u(document).on('click', '.bigPlayer .nextButton, #ajax_audio_player #aj_player_previous', async (e) => { await 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, #ajax_audio_player #aj_player_repeat", (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", async (e) => { if(window.player.current_track_id == 0) return await 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 || !window.player.isAtAudiosPage()) { 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, #aj_player_track_length .selectableTrack", (e) => { if(window.player.isAtAudiosPage() && window.player.current_track_id == 0) return if(u('.ui-draggable-dragging').length > 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, #aj_player_track_length .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, #aj_player_volume .selectableTrack", (e) => { if(window.player.isAtAudiosPage() && window.player.current_track_id == 0) return if(u('.ui-draggable-dragging').length > 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, #aj_player_volume .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() if(window.player && !window.player.isAtCurrentContextPage()) { return } 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('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(`
${tr('copy_link_to_audio')} ${ctx_type == 'main_player' ? ` ${tr('repeat_tip')} ${tr('shuffle_tip')} ${tr('mute_tip_noun')} ` : ''} ${ctx_type == 'mini_player' ? ` ` : ''} ${tr('audio_ctx_add_to_group')} ${tr('audio_ctx_add_to_playlist')} ${ctx_type == 'main_player' ? ` ${tr('audio_ctx_clear_context')}` : ''} ${ctx_type == 'main_player' ? `BigPlayer v1.1 by MrIlyew` : ''}
`) 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() } }) ctx_u.find('#audio_ctx_clear_context').on('click', (ev) => { const old_url = window.player.context.object.url window.player.pause() window.player.ajClose() window.player.__resetContext() window.player.__updateFace() window.player.undump() window.router.route(old_url) }) }) 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) } 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 }) }) function __showAudioAddDialog(id, current_tab = 'club') { 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 window.OVKAPI.call('groups.get', {'filter': 'admin', 'count': 100, 'fields': 'photo_50'}) } catch (e) { u("#_content").html(tr("no_access_clubs")) return } u('.entity_vertical_list #gif_loader').remove() } window.openvk.writeableClubs.items.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-group", async (ev) => { const id = Number(ev.target.dataset.id) __showAudioAddDialog(id) }) $(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]) }) function showAudioAttachment(type = 'form', form = null) { const msg = new CMessageBox({ title: tr("select_audio"), body: `
`, buttons: [tr('close')], callbacks: [Function.noop], }) msg.getNode().find('.ovk-diag-body').attr('style', 'padding:0px;height:335px') msg.getNode().attr('style', 'width:580px') 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 = 0 if(type == 'form') { id = el.dataset.prettyid } else { id = el.dataset.realid } let is_attached = false if(type == 'form') { is_attached = (u(form).find(`.post-vertical .vertical-attachment[data-id='${id}']`)).length > 0 } else { is_attached = (u(form).find(`.PE_audios .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)) }) u(".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; } }) u(".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 let is_attached = false if(type == 'form') { is_attached = u(form).find(`.post-vertical .vertical-attachment[data-id='${id}']`).length > 0 } else { is_attached = u(form).find(`.PE_audios .vertical-attachment[data-id='${id}']`).length > 0 } // 04.11.2024 19:03 // 30.11.2024 19:03 if(is_attached) { if(type == 'form') { u(form).find(`.post-vertical .vertical-attachment[data-id='${id}']`).remove() } else { u(form).find(`.PE_audios .vertical-attachment[data-id='${id}']`).remove() } u(ev.currentTarget).find("span").html(tr("attach_audio")) } else { if(type == 'form' && 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(type == 'form' ? ".post-vertical" : '.PE_audios').append(`
${player.html()}
`) } }) } $(document).on("click", "#__audioAttachment", (e) => { const form = e.target.closest("form") showAudioAttachment('form', form) }) $(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]) }) $(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) } }) }) u(document).on('click', '.upload_container_element #small_remove_button', (e) => { if(u('.uploading').length > 0) { return } // 1984 const element = u(e.target).closest('.upload_container_element') const element_index = Number(element.attr('data-index')) element.remove() window.__audio_upload_page.files_list[element_index] = null if(u('#lastStep .upload_container_element').length < 1) { window.__audio_upload_page.showFirstPage() } }) u(document).on('click', `#upload_container #uploadMusic`, async (e) => { const current_upload_page = location.href let error = null let end_redir = '' u('#lastStepButtons').addClass('lagged') for(const elem of u('#lastStepContainers .upload_container_element').nodes) { if(!elem) { return } const elem_u = u(elem) const index = elem.dataset.index const file = window.__audio_upload_page.files_list[index] if(!file || !index) { return } elem_u.addClass('lagged').find('.upload_container_name').addClass('uploading') // Upload process const fd = serializeForm(elem) fd.append('blob', file.file) fd.append('ajax', 1) fd.append('hash', window.router.csrf) const result = await fetch(current_upload_page, { method: 'POST', body: fd, }) const result_text = await result.json() if(result_text.success) { end_redir = result_text.redirect_link } else { makeError(escapeHtml(result_text.flash.message)) } await sleep(6000) elem_u.remove() } if(!end_redir) { u('#lastStepButtons').removeClass('lagged') window.__audio_upload_page.showFirstPage() return } if(current_upload_page == location.href) { window.router.route(end_redir) } }) u(document).on("drop", "#upload_container", function (e) { e.preventDefault() e.dataTransfer.dropEffect = 'move'; document.getElementById("audio_input").files = e.dataTransfer.files u("#audio_input").trigger("change") }) u(document).on('click', '#_playlistAppendTracks', (e) => { showAudioAttachment('playlist', u('.PE_wrapper').nodes[0]) }) u(document).on('drop', '.PE_audios .vertical-attachment', (e) => { const current = u('.upload-item.currently_dragging') if(e.dataTransfer.types.length < 1 || e.dataTransfer.types.includes('text/uri-list')) { e.preventDefault() const target = u(e.target).closest('.upload-item') u('.dragged').removeClass('dragged') current.removeClass('currently_dragging') if(!current.closest('.vertical-attachment').length < 1 && target.closest('.vertical-attachment').length < 1 || current.closest('.vertical-attachment').length < 1 && !target.closest('.vertical-attachment').length < 1) { return } 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 } }) u(document).on("change", `input[name='cover']`, (e) => { const file = e.target.files[0] if(!file.type.startsWith("image/")) { makeError(tr("not_a_photo")) return } const image = URL.createObjectURL(file) u(".playlistCover img").attr('src', image).attr('style', 'display:block') }) u(document).on("drop", `.playlistCover`, (e) => { e.preventDefault() e.dataTransfer.dropEffect = 'move'; document.querySelector(`input[name='cover']`).files = e.dataTransfer.files u(`input[name='cover']`).trigger("change") }) u(document).on('click', '.PE_end #playlist_create, .PE_end #playlist_edit', async (e) => { const ids = [] u('.PE_audios .vertical-attachment').nodes.forEach(vatch => { ids.push(vatch.dataset.id) }) /*if(!ids || ids.length < 1) { makeError(tr('error_playlist_creating_too_small'), 'Red', 5000, 77) return }*/ u(e.target).addClass('lagged') const fd = serializeForm(u('.PE_playlistEditPage').nodes[0]) fd.append('hash', window.router.csrf) fd.append('ajax', 1) fd.append('audios', ids) const req = await fetch(location.href, { method: 'POST', body: fd, }) const req_json = await req.json() if(req_json.success) { window.router.route(req_json.redirect) } else { makeError(req_json.flash.message) } u(e.target).removeClass('lagged') })