diff --git a/Web/Presenters/templates/Audio/List.xml b/Web/Presenters/templates/Audio/List.xml index 189cd4a0..f7add614 100644 --- a/Web/Presenters/templates/Audio/List.xml +++ b/Web/Presenters/templates/Audio/List.xml @@ -41,7 +41,7 @@ <input n:if="$mode == 'popular'" type="hidden" name="bigplayer_context" data-type="popular_audios" data-entity="0" data-page="1"> <div style="width: 100%;display: flex;margin-bottom: -10px;"> - <div style="width: 74%;" n:if="$mode != 'playlists'"> + <div style="width: 74%;" class="audiosContainer" n:if="$mode != 'playlists'"> <div style="padding: 8px;"> <div n:if="$audiosCount <= 0"> {include "../components/nothing.xml"} diff --git a/Web/Presenters/templates/Audio/player.xml b/Web/Presenters/templates/Audio/player.xml index 764e8dd2..558a1aea 100644 --- a/Web/Presenters/templates/Audio/player.xml +++ b/Web/Presenters/templates/Audio/player.xml @@ -4,7 +4,7 @@ {php $id = $audio->getId() . rand(0, 1000)} {php $isWithdrawn = $audio->isWithdrawn()} {php $editable = $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()}) : console.log('Player already inited.')"> +<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)"> <audio class="audio" /> <div id="miniplayer" class="audioEntry" style="min-height: 37px;"> diff --git a/Web/static/css/audios.css b/Web/static/css/audios.css index 3abbd486..50f1864d 100644 --- a/Web/static/css/audios.css +++ b/Web/static/css/audios.css @@ -5,7 +5,7 @@ } .musicIcon.pressed { - filter: brightness(59%); + filter: brightness(0%); } .bigPlayer { @@ -229,7 +229,7 @@ color: white !important; } -.audioEntry.nowPlaying .buttons .musicIcon { +.audioEntry.nowPlaying .buttons .musicIcon, .audioEntry.nowPlaying svg { filter: brightness(187%) opacity(72%); } diff --git a/Web/static/img/play_buttons.gif b/Web/static/img/play_buttons.gif index 35bc6bc3..c561bb89 100644 Binary files a/Web/static/img/play_buttons.gif and b/Web/static/img/play_buttons.gif differ diff --git a/Web/static/js/al_music.js b/Web/static/js/al_music.js index 15865fbb..797b77dc 100644 --- a/Web/static/js/al_music.js +++ b/Web/static/js/al_music.js @@ -4,6 +4,10 @@ function fmtTime(time) { return `${ mins}:${ secs}`; } +function fastError(message) { + MessageBox(tr("error"), message, [tr("ok")], [Function.noop]) +} + // нихуя я тут насрал class bigPlayer { contextObject = [] @@ -15,6 +19,9 @@ class bigPlayer { this.context = context this.context_id = context_id this.playerNode = document.querySelector(".bigPlayer") + + this.playerNode.classList.add("lagged") + this.performer = this.playerNode.querySelector(".trackInfo b") this.name = this.playerNode.querySelector(".trackInfo span") this.time = this.playerNode.querySelector(".trackInfo .time") @@ -34,6 +41,7 @@ class bigPlayer { afterResponse: [ async (_request, _options, response) => { this.contextObject = await response.json() + this.playerNode.classList.remove("lagged") console.info("Context is successfully loaded") } ] @@ -56,6 +64,7 @@ class bigPlayer { if (ps <= 100) this.playerNode.querySelector(".selectableTrack .slider").style.left = `${ ps}%`; + }) u(this.player()).on("volumechange", (e) => { @@ -187,8 +196,13 @@ class bigPlayer { document.querySelectorAll(".audioEntry.nowPlaying").forEach(el => el.classList.remove("nowPlaying")) let obj = this.contextObject["items"].find(item => item.id == id) - this.name.innerHTML = obj.name - this.performer.innerHTML = obj.performer + if(obj == null) { + fastError("No audio in context") + return + } + + this.name.innerHTML = escapeHtml(obj.name) + this.performer.innerHTML = escapeHtml(obj.performer) this.time.innerHTML = fmtTime(obj.length) this.currentTrack = obj @@ -201,7 +215,6 @@ class bigPlayer { this.previousTrack = null } - // todo поменьше копипастить код if(this.nextTrack == null && this.contextObject.page < this.contextObject.pagesCount || this.previousTrack == null && (this.contextObject.page > 1)) { let formdata = new FormData() @@ -422,14 +435,14 @@ $(document).on("click", ".musicIcon.edit-icon", (e) => { success: (response) => { if(response.success) { let perf = player.querySelector(".performer a") - perf.innerHTML = response.new_info.performer + perf.innerHTML = escapeHtml(response.new_info.performer) perf.setAttribute("href", "/search?query=&type=audios&sort=id&only_performers=on&query="+response.new_info.performer) - e.currentTarget.setAttribute("data-performer", response.new_info.performer) + e.currentTarget.setAttribute("data-performer", escapeHtml(response.new_info.performer)) let name = player.querySelector(".title") name.innerHTML = escapeHtml(response.new_info.name) - e.currentTarget.setAttribute("data-title", response.new_info.name) + e.currentTarget.setAttribute("data-title", escapeHtml(response.new_info.name)) if(player.querySelector(".lyrics") != null) { player.querySelector(".lyrics").innerHTML = response.new_info.lyrics @@ -575,4 +588,70 @@ $(document).on("click", "#bookmarkPlaylist", (e) => { $(document).on("click", "#unbookmarkPlaylist", (e) => { -}) \ No newline at end of file +}) + +$(document).on("click", ".audiosContainer .paginator a", (e) => { + e.preventDefault() + + e.currentTarget.parentNode.classList.add("lagged") + + ky(e.currentTarget.href, { + hooks: { + afterResponse: [ + async (_request, _options, response) => { + let text = await response.text() + let domparse = (new DOMParser()).parseFromString(text, "text/html") + + document.querySelector(".audiosContainer").innerHTML = domparse.querySelector(".audiosContainer").innerHTML + history.pushState(null, null, e.currentTarget.href) + + let playingId = window.player.currentTrack["id"] ?? 0 + let maybePlayer = document.querySelector(`.audioEmbed[data-realid='${playingId}'] .audioEntry`) + console.log(playingId) + + if(maybePlayer != null) { + maybePlayer.classList.add("nowPlaying") + } + } + ] + } + }) + + let url = new URL(location.href) + let lesser = Number(url.searchParams.get("p")) < window.player.contextObject["page"] + + let formdata = new FormData() + formdata.append("context", window.player.context) + formdata.append("context_entity", window.player.context_id) + formdata.append("hash", u("meta[name=csrf]").attr("value")) + formdata.append("page", Number(url.searchParams.get("p")) + (lesser ? -1 : 1)) + + ky.post("/audios/context", { + hooks: { + afterResponse: [ + async (_request, _options, response) => { + let newArr = await response.json() + let indexOfCurrentTrack = window.player.contextObject["items"].indexOf(window.player.currentTrack) ?? 0 + + if(lesser) { + window.player.contextObject["items"] = newArr["items"].concat(window.player.contextObject["items"]) + } else { + window.player.contextObject["items"] = window.player.contextObject["items"].concat(newArr["items"]) + } + + window.player.contextObject["page"] = newArr["page"] + + if(lesser) { + window.player.previousTrack = window.player.contextObject["items"].at(window.player.contextObject["items"].indexOf(obj) - 1).id + } else { + window.player.nextTrack = window.player.contextObject["items"].at(indexOfCurrentTrack + 1) != null ? window.player.contextObject["items"].at(indexOfCurrentTrack + 1).id : null + } + + window.player.updateButtons() + console.info("Context is successfully loaded") + } + ] + }, + body: formdata + }) +})