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
}
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 && 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.is_closed = false
if(ref != 'localstorage') {
this.dump()
}
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
}
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.current_track_id = dump_object.current_track_id
this.tracks = dump_object.tracks
if(this.current_track_id) {
await this.setTrack(this.current_track_id, 'localstorage')
}
if(dump_object.time) {
setTimeout(() => {
this.audioPlayer.currentTime = dump_object.time
}, 1000)
}
}
// Добавляем ощущение продуманности.
__highlightActiveTrack() {
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
}
this.ajCreate()
this.__updateFace()
}
} else {
this.ajClose(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) {
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', 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) {
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) {
this.is_closed = true
if(pause) {
this.pause()
}
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()) {
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
}
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()
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(`
`)
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("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 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-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", `
`)
})
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(`
`)
}
})
}
$(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')
})