Make shuffle and "наушники" buttons work, add f...

avicons when playing audio, save some values (like volume and last played track) to localstorage, add ability to toggle time type in player, fix uploading audios with cover (maybe) and add dragndrop to upload page
This commit is contained in:
lalka2018 2023-10-17 16:02:28 +03:00
parent 75f93b7cfc
commit d71620dfd8
13 changed files with 207 additions and 41 deletions

View file

@ -14,7 +14,6 @@ class Audio extends Media
{ {
protected $tableName = "audios"; protected $tableName = "audios";
protected $fileExtension = "mpd"; protected $fileExtension = "mpd";
// protected $fileExtension = "mp3";
# Taken from winamp :D # Taken from winamp :D
const genres = [ const genres = [
@ -63,7 +62,10 @@ class Audio extends Media
throw new \DomainException("$filename does not contain any audio streams"); throw new \DomainException("$filename does not contain any audio streams");
$vstreams = Shell::ffprobe("-i", $filename, "-show_streams", "-select_streams v", "-loglevel error")->execute($error); $vstreams = Shell::ffprobe("-i", $filename, "-show_streams", "-select_streams v", "-loglevel error")->execute($error);
if(!empty($vstreams) && !ctype_space($vstreams))
# check if audio has cover (attached_pic)
preg_match("%attached_pic=([0-1])%", $vstreams, $hasCover);
if(!empty($vstreams) && !ctype_space($vstreams) && ((int)($hasCover[1]) !== 1))
throw new \DomainException("$filename is a video"); throw new \DomainException("$filename is a video");
$durations = []; $durations = [];

View file

@ -23,7 +23,7 @@ Set-Location -Path $temp
Move-Item $filename $audioFile Move-Item $filename $audioFile
ffmpeg -i $audioFile -f dash -encryption_scheme cenc-aes-ctr -encryption_key $key ` ffmpeg -i $audioFile -f dash -encryption_scheme cenc-aes-ctr -encryption_key $key `
-encryption_kid $keyID -map 0 -c:a aac -ar 44100 -seg_duration $seg ` -encryption_kid $keyID -map 0:a -c:a aac -ar 44100 -seg_duration $seg `
-use_timeline 1 -use_template 1 -init_seg_name ($fileHash + '_fragments/0_0.$ext$') ` -use_timeline 1 -use_template 1 -init_seg_name ($fileHash + '_fragments/0_0.$ext$') `
-media_seg_name ($fileHash + '_fragments/chunk$Number%06d$_$RepresentationID$.$ext$') -adaptation_sets 'id=0,streams=a' ` -media_seg_name ($fileHash + '_fragments/chunk$Number%06d$_$RepresentationID$.$ext$') -adaptation_sets 'id=0,streams=a' `
"$fileHash.mpd" "$fileHash.mpd"

View file

@ -236,10 +236,9 @@ final class AudioPresenter extends OpenVKPresenter
$audio = $this->audios->get($id); $audio = $this->audios->get($id);
if ($audio && !$audio->isDeleted() && !$audio->isWithdrawn()) { if ($audio && !$audio->isDeleted() && !$audio->isWithdrawn()) {
$audio->listen($this->user->identity); $listen = $audio->listen($this->user->identity);
$this->returnJson(["success" => $listen]);
} }
$this->returnJson(["response" => true]);
} }
} }
@ -458,8 +457,6 @@ final class AudioPresenter extends OpenVKPresenter
function renderApiGetContext() function renderApiGetContext()
{ {
$this->assertUserLoggedIn();
if ($_SERVER["REQUEST_METHOD"] !== "POST") { if ($_SERVER["REQUEST_METHOD"] !== "POST") {
header("HTTP/1.1 405 Method Not Allowed"); header("HTTP/1.1 405 Method Not Allowed");
exit("<select><select><select><select>"); exit("<select><select><select><select>");

View file

@ -149,5 +149,26 @@
document.querySelector("#audio_upload > form").submit(); document.querySelector("#audio_upload > form").submit();
}) })
$(document).on("dragover drop", (e) => {
e.preventDefault()
return false;
})
$(".container_gray").on("drop", (e) => {
e.originalEvent.dataTransfer.dropEffect = 'move';
e.preventDefault()
let file = e.originalEvent.dataTransfer.files[0]
if(!file.type.startsWith('audio/')) {
MessageBox(tr("error"), tr("only_audios_accepted", escapeHtml(file.name)), [tr("ok")], [() => Function.noop])
return;
}
document.getElementById("audio_input").files = e.originalEvent.dataTransfer.files
u("#audio_input").trigger("change")
})
</script> </script>
{/block} {/block}

View file

@ -17,7 +17,8 @@
<div class="timer" style="float:right"> <div class="timer" style="float:right">
<span class="time">00:00</span> <span class="time">00:00</span>
<span class="elapsedTime">-00:00</span> <span>/</span>
<span class="elapsedTime" style="cursor:pointer">-00:00</span>
</div> </div>
</div> </div>

View file

@ -3,8 +3,8 @@
{php $id = $audio->getId() . rand(0, 1000)} {php $id = $audio->getId() . rand(0, 1000)}
{php $isWithdrawn = $audio->isWithdrawn()} {php $isWithdrawn = $audio->isWithdrawn()}
{php $editable = $audio->canBeModifiedBy($thisUser)} {php $editable = isset($thisUser) && $audio->canBeModifiedBy($thisUser)}
<div id="audioEmbed-{$id}" data-realid="{$audio->getId()}" data-genre="{$audio->getGenre()}" class="audioEmbed {if !$audio->isAvailable()}lagged{/if} {if $isWithdrawn}withdrawn{/if}" onmouseenter="!this.classList.contains('inited') ? initPlayer({$id}, {$audio->getKeys()}, {$audio->getURL()}, {$audio->getLength()}) : void(0)"> <div id="audioEmbed-{$id}" data-realid="{$audio->getId()}" data-genre="{$audio->getGenre()}" class="audioEmbed {if !$audio->isAvailable()}processed{/if} {if $isWithdrawn}withdrawn{/if}" onmouseenter="!this.classList.contains('inited') ? initPlayer({$id}, {$audio->getKeys()}, {$audio->getURL()}, {$audio->getLength()}) : void(0)">
<audio class="audio" /> <audio class="audio" />
<div id="miniplayer" class="audioEntry" style="min-height: 37px;"> <div id="miniplayer" class="audioEntry" style="min-height: 37px;">
@ -40,13 +40,13 @@
<div class="volume" style="display: flex; flex-direction: column;width:14%;"> <div class="volume" style="display: flex; flex-direction: column;width:14%;">
<span class="nobold" data-unformatted="{$audio->getLength()}" style="text-align: center;margin-top: 12px;">{$audio->getFormattedLength()}</span> <span class="nobold" data-unformatted="{$audio->getLength()}" style="text-align: center;margin-top: 12px;">{$audio->getFormattedLength()}</span>
<div class="buttons" style="margin-top: 8px;"> <div class="buttons" style="margin-top: 8px;">
{php $hasAudio = $audio->isInLibraryOf($thisUser)} {php $hasAudio = isset($thisUser) && $audio->isInLibraryOf($thisUser)}
{if !$addToPlaylistButton} {if !$addToPlaylistButton}
<div class="remove-icon musicIcon" data-id="{$audio->getId()}" n:if="$hasAudio" ></div> <div class="remove-icon musicIcon" data-id="{$audio->getId()}" n:if="isset($thisUser) && $hasAudio" ></div>
<div class="add-icon musicIcon" data-id="{$audio->getId()}" n:if="!$hasAudio" ></div> <div class="add-icon musicIcon" data-id="{$audio->getId()}" n:if="isset($thisUser) && !$hasAudio && !$isWithdrawn" ></div>
<div class="edit-icon musicIcon" data-lyrics="{$audio->getLyrics()}" data-title="{$audio->getTitle()}" data-performer="{$audio->getPerformer()}" data-explicit="{(int)$audio->isExplicit()}" n:if="$editable && !$isWithdrawn" ></div> <div class="edit-icon musicIcon" data-lyrics="{$audio->getLyrics()}" data-title="{$audio->getTitle()}" data-performer="{$audio->getPerformer()}" data-explicit="{(int)$audio->isExplicit()}" n:if="isset($thisUser) && $editable && !$isWithdrawn" ></div>
<div class="report-icon musicIcon" data-id="{$audio->getId()}" n:if="!$editable && !$isWithdrawn" ></div> <div class="report-icon musicIcon" data-id="{$audio->getId()}" n:if="isset($thisUser) && !$editable && !$isWithdrawn" ></div>
{else} {else}
jrgnwighweif jrgnwighweif
{/if} {/if}

View file

@ -1,17 +1,17 @@
<div class="searchOptions newer"> <div class="searchOptions newer">
<ul class="searchList"> <ul class="searchList">
<a n:attr="id => $mode === 'list' && $isMy ? 'used' : 'ki'" href="/audios{$thisUser->getId()}">{_my_music}</a> <a n:attr="id => $mode === 'list' && $isMy ? 'used' : 'ki'" href="/audios{$thisUser->getId()}" n:if="isset($thisUser)">{_my_music}</a>
<a n:if="!$isMy && $mode === 'list'" id="used" href="/audios{$ownerId}">{if $ownerId > 0}{_music_user}{else}{_music_club}{/if}</a> <a n:if="!$isMy && $mode === 'list'" id="used" href="/audios{$ownerId}">{if $ownerId > 0}{_music_user}{else}{_music_club}{/if}</a>
<a href="/player/upload{if $isMyClub}?gid={abs($ownerId)}{/if}">{_upload_audio}</a> <a href="/player/upload{if $isMyClub}?gid={abs($ownerId)}{/if}" n:if="isset($thisUser)">{_upload_audio}</a>
<a n:attr="id => $mode === 'playlists' ? 'used' : 'ki'" href="/playlists{$thisUser->getId()}">{_my_playlists}</a> <a n:attr="id => $mode === 'playlists' ? 'used' : 'ki'" href="/playlists{$thisUser->getId()}" n:if="isset($thisUser)">{_my_playlists}</a>
<a n:if="$mode === 'playlists'" href="/audios/newPlaylist{if $isMyClub}?owner={abs($ownerId)}{/if}">{_new_playlist}</a> <a n:if="$mode === 'playlists' && isset($thisUser)" href="/audios/newPlaylist{if $isMyClub}?owner={abs($ownerId)}{/if}">{_new_playlist}</a>
<a n:attr="id => $mode === 'new' ? 'used' : 'ki'" href="/audios/new">{_audio_new}</a> <a n:attr="id => $mode === 'new' ? 'used' : 'ki'" href="/audios/new">{_audio_new}</a>
<a n:attr="id => $mode === 'popular' ? 'used' : 'ki'" href="/audios/popular">{_audio_popular}</a> <a n:attr="id => $mode === 'popular' ? 'used' : 'ki'" href="/audios/popular">{_audio_popular}</a>
<a href="/search?type=audios">{_audio_search}</a> <a href="/search?type=audios" n:if="isset($thisUser)">{_audio_search}</a>
</ul> </ul>
</div> </div>

View file

@ -35,7 +35,7 @@
<div class="limits" style="margin-top:17px"> <div class="limits" style="margin-top:17px">
<b style="color:#45688E">{_admin_limits}</b> <b style="color:#45688E">{_admin_limits}</b>
<ul class="blueList" style="margin-left: -25px;margin-top: 1px;"> <ul style="margin-top: 6px;">
<li>{_supported_formats}</li> <li>{_supported_formats}</li>
<li>{_max_load_photos}</li> <li>{_max_load_photos}</li>
</ul> </ul>

View file

@ -52,7 +52,7 @@
{css "css/dialog.css"} {css "css/dialog.css"}
{css "css/nsfw-posts.css"} {css "css/nsfw-posts.css"}
{css "css/notifications.css"} {css "css/notifications.css"}
{css "css/avataredit.css"} {css "css/audios.css"}
{if $isXmas} {if $isXmas}
{css "css/xmas.css"} {css "css/xmas.css"}

View file

@ -74,7 +74,7 @@
} }
.bigPlayer .paddingLayer .additionalButtons .deviceButton { .bigPlayer .paddingLayer .additionalButtons .deviceButton {
width: 16px; width: 12px;
height: 16px; height: 16px;
background-position: -202px -51px; background-position: -202px -51px;
margin-left: 6px; margin-left: 6px;
@ -82,7 +82,6 @@
} }
.bigPlayer .paddingLayer .playButtons .arrowsButtons { .bigPlayer .paddingLayer .playButtons .arrowsButtons {
/* скибиди пидорас */
float: left; float: left;
display: flex; display: flex;
padding-left: 4px; padding-left: 4px;
@ -363,7 +362,7 @@
text-decoration: underline; text-decoration: underline;
} }
.audioEmbed.withdrawn .status > *, .audioEmbed.withdrawn .playerButton > * { .audioEmbed.withdrawn .status > *, .audioEmbed.processed .status > *, .audioEmbed.withdrawn .playerButton > *, .audioEmbed.processed .playerButton > * {
pointer-events: none; pointer-events: none;
} }

Binary file not shown.

After

Width:  |  Height:  |  Size: 1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

View file

@ -37,10 +37,12 @@ class bigPlayer {
playButtons: null, playButtons: null,
} }
timeType = 0
constructor(context, context_id, page = 1) { constructor(context, context_id, page = 1) {
this.context["context_type"] = context this.context["context_type"] = context
this.context["context_id"] = context_id this.context["context_id"] = context_id
this.context["playedPages"].push(page) this.context["playedPages"].push(Number(page))
this.nodes["thisPlayer"] = document.querySelector(".bigPlayer") this.nodes["thisPlayer"] = document.querySelector(".bigPlayer")
this.nodes["thisPlayer"].classList.add("lagged") this.nodes["thisPlayer"].classList.add("lagged")
@ -74,6 +76,12 @@ class bigPlayer {
this.nodes["thisPlayer"].classList.remove("lagged") this.nodes["thisPlayer"].classList.remove("lagged")
this.tracks["tracks"] = contextObject["items"] this.tracks["tracks"] = contextObject["items"]
this.context["pagesCount"] = contextObject["pagesCount"] this.context["pagesCount"] = contextObject["pagesCount"]
if(localStorage.lastPlayedTrack != null && this.tracks["tracks"].find(item => item.id == localStorage.lastPlayedTrack) != null) {
this.setTrack(localStorage.lastPlayedTrack)
this.pause()
}
console.info("Context is successfully loaded") console.info("Context is successfully loaded")
} }
] ]
@ -93,7 +101,8 @@ class bigPlayer {
const time = this.player().currentTime; const time = this.player().currentTime;
const ps = Math.ceil((time * 100) / this.tracks["currentTrack"].length); const ps = Math.ceil((time * 100) / this.tracks["currentTrack"].length);
this.nodes["thisPlayer"].querySelector(".time").innerHTML = fmtTime(time) this.nodes["thisPlayer"].querySelector(".time").innerHTML = fmtTime(time)
this.nodes["thisPlayer"].querySelector(".elapsedTime").innerHTML = getElapsedTime(this.tracks["currentTrack"].length, time) this.timeType == 0 ? this.nodes["thisPlayer"].querySelector(".elapsedTime").innerHTML = getElapsedTime(this.tracks["currentTrack"].length, time)
: null
if (ps <= 100) if (ps <= 100)
this.nodes["thisPlayer"].querySelector(".selectableTrack .slider").style.left = `${ ps}%`; this.nodes["thisPlayer"].querySelector(".selectableTrack .slider").style.left = `${ ps}%`;
@ -106,6 +115,8 @@ class bigPlayer {
if (ps <= 100) if (ps <= 100)
this.nodes["thisPlayer"].querySelector(".volumePanel .selectableTrack .slider").style.left = `${ ps}%`; this.nodes["thisPlayer"].querySelector(".volumePanel .selectableTrack .slider").style.left = `${ ps}%`;
localStorage.volume = volume
}) })
u(".bigPlayer .track > div").on("click mouseup", (e) => { u(".bigPlayer .track > div").on("click mouseup", (e) => {
@ -134,6 +145,20 @@ class bigPlayer {
this.player().volume = volume; this.player().volume = volume;
}) })
u(".bigPlayer .elapsedTime").on("click", (e) => {
if(this.tracks["currentTrack"] == null) {
return
}
this.timeType == 0 ? (this.timeType = 1) : (this.timeType = 0)
localStorage.playerTimeType = this.timeType
this.nodes["thisPlayer"].querySelector(".elapsedTime").innerHTML = this.timeType == 1 ?
fmtTime(this.tracks["currentTrack"].length)
: getElapsedTime(this.tracks["currentTrack"].length, this.player().currentTime)
})
u(".bigPlayer .additionalButtons .repeatButton").on("click", (e) => { u(".bigPlayer .additionalButtons .repeatButton").on("click", (e) => {
if(this.tracks["currentTrack"] == null) { if(this.tracks["currentTrack"] == null) {
return return
@ -148,6 +173,30 @@ class bigPlayer {
} }
}) })
u(".bigPlayer .additionalButtons .shuffleButton").on("click", (e) => {
if(this.tracks["currentTrack"] == null) {
return
}
this.tracks["tracks"].sort(() => Math.random() - 0.5)
this.setTrack(this.tracks["tracks"].at(0).id)
})
// хз что она делала в самом вк, но тут сделаем вид что это просто мут музыки
u(".bigPlayer .additionalButtons .deviceButton").on("click", (e) => {
if(this.tracks["currentTrack"] == null) {
return
}
e.currentTarget.classList.toggle("pressed")
if(e.currentTarget.classList.contains("pressed")) {
this.player().muted = true
} else {
this.player().muted = false
}
})
u(".bigPlayer .arrowsButtons .nextButton").on("click", (e) => { u(".bigPlayer .arrowsButtons .nextButton").on("click", (e) => {
this.showPreviousTrack() this.showPreviousTrack()
}) })
@ -204,9 +253,20 @@ class bigPlayer {
this.showNextTrack() this.showNextTrack()
}) })
if(localStorage.volume != null && localStorage.volume < 1 && localStorage.volume > 0) {
this.player().volume = localStorage.volume
} else {
this.player().volume = 0.75 this.player().volume = 0.75
} }
// В хромиумах - 'null', а в фурифоксах - null. Гыгы.
if(localStorage.playerTimeType == 'null' || localStorage.playerTimeType == null) {
this.timeType = 0
} else {
this.timeType = localStorage.playerTimeType
}
}
play() { play() {
if(this.tracks["currentTrack"] == null) { if(this.tracks["currentTrack"] == null) {
return return
@ -216,6 +276,7 @@ class bigPlayer {
document.querySelector(`.audioEmbed[data-realid='${this.tracks["currentTrack"].id}'] .audioEntry .playerButton .playIcon`) != null ? document.querySelector(`.audioEmbed[data-realid='${this.tracks["currentTrack"].id}'] .audioEntry .playerButton .playIcon`).classList.add("paused") : void(0) document.querySelector(`.audioEmbed[data-realid='${this.tracks["currentTrack"].id}'] .audioEntry .playerButton .playIcon`) != null ? document.querySelector(`.audioEmbed[data-realid='${this.tracks["currentTrack"].id}'] .audioEntry .playerButton .playIcon`).classList.add("paused") : void(0)
this.player().play() this.player().play()
this.nodes["playButtons"].querySelector(".playButton").classList.add("pause") this.nodes["playButtons"].querySelector(".playButton").classList.add("pause")
document.querySelector('link[rel="icon"], link[rel="shortcut icon"]').setAttribute("href", "/assets/packages/static/openvk/img/favicons/favicon24_paused.png")
} }
pause() { pause() {
@ -226,6 +287,7 @@ class bigPlayer {
document.querySelector(`.audioEmbed[data-realid='${this.tracks["currentTrack"].id}'] .audioEntry .playerButton .playIcon`) != null ? document.querySelector(`.audioEmbed[data-realid='${this.tracks["currentTrack"].id}'] .audioEntry .playerButton .playIcon`).classList.remove("paused") : void(0) document.querySelector(`.audioEmbed[data-realid='${this.tracks["currentTrack"].id}'] .audioEntry .playerButton .playIcon`) != null ? document.querySelector(`.audioEmbed[data-realid='${this.tracks["currentTrack"].id}'] .audioEntry .playerButton .playIcon`).classList.remove("paused") : void(0)
this.player().pause() this.player().pause()
this.nodes["playButtons"].querySelector(".playButton").classList.remove("pause") this.nodes["playButtons"].querySelector(".playButton").classList.remove("pause")
document.querySelector('link[rel="icon"], link[rel="shortcut icon"]').setAttribute("href", "/assets/packages/static/openvk/img/favicons/favicon24_playing.png")
} }
showPreviousTrack() { showPreviousTrack() {
@ -290,18 +352,22 @@ class bigPlayer {
this.tracks["previousTrack"] = null this.tracks["previousTrack"] = null
} }
if(this.tracks["nextTrack"] == null && Math.max(this.context["playedPages"]) < this.context["pagesCount"] if(this.tracks["nextTrack"] == null && Math.max(...this.context["playedPages"]) < this.context["pagesCount"]
|| this.tracks["previousTrack"] == null && (Math.min(this.context["playedPages"]) > 1)) { || this.tracks["previousTrack"] == null && (Math.min(...this.context["playedPages"]) > 1)) {
// idk how it works
let lesser = this.tracks["previousTrack"] == null ? (Math.min(...this.context["playedPages"]) > 1)
: Math.max(...this.context["playedPages"]) > this.context["pagesCount"]
let formdata = new FormData() let formdata = new FormData()
formdata.append("context", this.context["context_type"]) formdata.append("context", this.context["context_type"])
formdata.append("context_entity", this.context["context_id"]) formdata.append("context_entity", this.context["context_id"])
formdata.append("hash", u("meta[name=csrf]").attr("value")) formdata.append("hash", u("meta[name=csrf]").attr("value"))
let lesser = Math.max(this.context["playedPages"]) > 1
if(lesser) { if(lesser) {
formdata.append("page", Number(Math.min(this.context["playedPages"])) - 1) formdata.append("page", Math.min(...this.context["playedPages"]) - 1)
} else { } else {
formdata.append("page", Number(Math.max(this.context["playedPages"])) + 1) formdata.append("page", Number(Math.max(...this.context["playedPages"])) + 1)
} }
ky.post("/audios/context", { ky.post("/audios/context", {
@ -316,7 +382,7 @@ class bigPlayer {
this.tracks["tracks"] = this.tracks["tracks"].concat(newArr["items"]) this.tracks["tracks"] = this.tracks["tracks"].concat(newArr["items"])
} }
this.context["playedPages"].push(newArr["page"]) this.context["playedPages"].push(Number(newArr["page"]))
if(lesser) { if(lesser) {
this.tracks["previousTrack"] = this.tracks["tracks"].at(this.tracks["tracks"].indexOf(obj) - 1).id this.tracks["previousTrack"] = this.tracks["tracks"].at(this.tracks["tracks"].indexOf(obj) - 1).id
@ -355,6 +421,33 @@ class bigPlayer {
null null
document.querySelectorAll(`.audioEntry .playerButton .playIcon.paused`).forEach(el => el.classList.remove("paused")) document.querySelectorAll(`.audioEntry .playerButton .playIcon.paused`).forEach(el => el.classList.remove("paused"))
localStorage.lastPlayedTrack = this.tracks["currentTrack"].id
if(this.timeType == 1) {
this.nodes["thisPlayer"].querySelector(".elapsedTime").innerHTML = fmtTime(this.tracks["currentTrack"].length)
}
let tempThisTrack = this.tracks["currentTrack"]
// если трек слушали больше 10 сек.
setTimeout(() => {
if(tempThisTrack.id != this.tracks["currentTrack"].id)
return;
$.ajax({
type: "POST",
url: `/audio${id}/listen`,
data: {
hash: u("meta[name=csrf]").attr("value"),
},
success: (response) => {
if(response.success) {
console.info("Listen is counted.")
} else {
console.info("Listen is not counted.")
}
}
})
}, "10000")
} }
} }
@ -385,6 +478,7 @@ function initPlayer(id, keys, url, length) {
if(window.player.tracks["currentTrack"] == null || window.player.tracks["currentTrack"].id != playerObject.dataset.realid) { if(window.player.tracks["currentTrack"] == null || window.player.tracks["currentTrack"].id != playerObject.dataset.realid) {
window.player.setTrack(playerObject.dataset.realid) window.player.setTrack(playerObject.dataset.realid)
playButton.addClass("paused")
} else { } else {
document.querySelector(".bigPlayer .playButton").click() document.querySelector(".bigPlayer .playButton").click()
} }
@ -462,13 +556,13 @@ $(document).on("click", ".musicIcon.edit-icon", (e) => {
let lyrics = e.currentTarget.dataset.lyrics let lyrics = e.currentTarget.dataset.lyrics
MessageBox(tr("edit"), ` MessageBox(tr("edit"), `
<div> <div>
${tr("audio_name")} ${tr("performer")}
<input name="name" maxlength="40" type="text" value="${name}"> <input name="performer" maxlength="40" type="text" value="${performer}">
</div> </div>
<div style="margin-top: 11px"> <div style="margin-top: 11px">
${tr("performer")} ${tr("audio_name")}
<input name="performer" maxlength="40" type="text" value="${performer}"> <input name="name" maxlength="40" type="text" value="${name}">
</div> </div>
<div style="margin-top: 11px"> <div style="margin-top: 11px">
@ -624,7 +718,7 @@ $(document).on("click", "#_audioAttachment", (e) => {
MessageBox(tr("select_audio"), body, [tr("ok")], [Function.noop]) MessageBox(tr("select_audio"), body, [tr("ok")], [Function.noop])
}) })
$(document).on("click", ".audioEmbed.lagged", (e) => { $(document).on("click", ".audioEmbed.processed", (e) => {
MessageBox(tr("error"), tr("audio_embed_processing"), [tr("ok")], [Function.noop]) MessageBox(tr("error"), tr("audio_embed_processing"), [tr("ok")], [Function.noop])
}) })
@ -660,3 +754,55 @@ $(document).on("click", "#bookmarkPlaylist", (e) => {
$(document).on("click", "#unbookmarkPlaylist", (e) => { $(document).on("click", "#unbookmarkPlaylist", (e) => {
}) })
window.savedAudiosPages = {}
$(document).on("click", ".audiosContainer .paginator a", (e) => {
e.preventDefault()
e.currentTarget.parentNode.classList.add("lagged")
let url = new URL(e.currentTarget.href)
let page = Number(url.searchParams.get("p"))
if(window.savedAudiosPages[page] != null) {
history.pushState({}, "", e.currentTarget.href)
document.querySelector(".audiosContainer").innerHTML = window.savedAudiosPages[page].innerHTML
return
}
$.ajax({
type: "GET",
url: e.currentTarget.href,
success: (response) => {
let domparser = new DOMParser()
let result = domparser.parseFromString(response, "text/html")
document.querySelector(".audiosContainer").innerHTML = result.querySelector(".audiosContainer").innerHTML
history.pushState({}, "", e.currentTarget.href)
window.savedAudiosPages[page] = result.querySelector(".audiosContainer")
if(window.player.context["playedPages"].indexOf(page) == -1) {
$.ajax({
type: "POST",
url: "/audios/context",
data: {
context: window.player["context"].context_type,
context_entity: window.player["context"].context_id,
hash: u("meta[name=csrf]").attr("value"),
page: page
},
success: (response_2) => {
window.player.tracks["tracks"] = window.player.tracks["tracks"].concat(response_2["items"])
window.player.context["playedPages"].push(page)
console.info("Page is switched")
}
})
}
}
})
let node = document.querySelector(`.audioEmbed[data-realid='${window.player["tracks"].currentTrack != null ? window.player["tracks"].currentTrack.id : 0}'] .audioEntry`)
if(node != null) {
node.classList.add("nowPlaying")
}
})