7 changed files with 254 additions and 39 deletions
@ -0,0 +1,48 @@ |
|||||
|
<?php |
||||
|
|
||||
|
use App\Enumerators\SessionElement; |
||||
|
use App\Wrappers\DatabaseInteractions; |
||||
|
use App\Wrappers\SessionWrapper; |
||||
|
use App\Wrappers\SQLQueryBuilderWrapper; |
||||
|
use App\Wrappers\TwigWrapper; |
||||
|
|
||||
|
require_once __DIR__ . "/../../vendor/autoload.php"; |
||||
|
|
||||
|
$db = new DatabaseInteractions(); |
||||
|
|
||||
|
|
||||
|
$tuneSetDetails = $db->RunOneSelect( |
||||
|
queryBuilder: SQLQueryBuilderWrapper::SELECT_ONE( |
||||
|
table: 'TuneSets', |
||||
|
id: $_GET["tune-set-id"] |
||||
|
) |
||||
|
); |
||||
|
|
||||
|
$tunesInSet = $db->RunSelect( |
||||
|
queryBuilder: SQLQueryBuilderWrapper::SELECT( |
||||
|
table: 'TuneSetTunes' |
||||
|
) |
||||
|
->cols(cols: [ |
||||
|
'T_T.ID AS TuneID', |
||||
|
'T_T.CreatedAt AS TuneCreatedAT', |
||||
|
'T_T.CreatedBy AS TuneCreatedBy', |
||||
|
'T_T.Title AS TuneTitle', |
||||
|
'T_T.Copyright AS TuneCopyright', |
||||
|
]) |
||||
|
->join( |
||||
|
join: 'INNER', |
||||
|
spec: 'Tunes AS T_T', |
||||
|
cond: 'T.TuneID=T_T.ID', |
||||
|
) |
||||
|
->orderBy(spec: [ |
||||
|
'T.Order ASC', |
||||
|
]) |
||||
|
); |
||||
|
|
||||
|
TwigWrapper::RenderTwig( |
||||
|
target: "Pages/tune-set/uuid.html.twig", |
||||
|
arguments: [ |
||||
|
"TuneSetDetails"=>$tuneSetDetails, |
||||
|
"TunesInSet"=>$tunesInSet, |
||||
|
] |
||||
|
); |
@ -0,0 +1,117 @@ |
|||||
|
{% extends "/Bases/StandardWebPage.html.twig" %} |
||||
|
|
||||
|
{% block content %} |
||||
|
|
||||
|
|
||||
|
<script src="/Static/JS/ThirdParty/abcjs-basic.js"></script> |
||||
|
<!--<script src="/Static/JS/ThirdParty/abcjs-plugin-min.js"></script>--> |
||||
|
<link rel="stylesheet" href="/Static/CSS/ThirdParty/abcjs-audio.css"> |
||||
|
|
||||
|
|
||||
|
<div class="InnerContent"> |
||||
|
<div> |
||||
|
<div class="container"> |
||||
|
<div class="left"> |
||||
|
<div class="DLContainer"> |
||||
|
<h2>{{ "Tune Set Overview"|translate }}</h2> |
||||
|
<dl> |
||||
|
<dt>{{ "Description"|translate }}</dt> |
||||
|
<dd>{{ TuneSetDetails.Description }}</dd> |
||||
|
</dl> |
||||
|
</div> |
||||
|
<div id="RatingContainer"> |
||||
|
<h2>{{ "Rating"|translate }}</h2> |
||||
|
<div class="RatingButtons"> |
||||
|
{% if _SESSION_.IS_LOGGED_IN %} |
||||
|
<button id="DislikeButton" onclick="VoteOnTune('DISLIKE');" {% if MyVote == -1 %}class="active"{% endif %}>👎</button> |
||||
|
<button id="LikeButton" onclick="VoteOnTune('LIKE');" {% if MyVote == 1 %}class="active"{% endif %}>👍</button> |
||||
|
{% else %} |
||||
|
<em>{{ "Log in to vote"|translate }}</em> |
||||
|
{% endif %} |
||||
|
</div> |
||||
|
<div class="Counts"> |
||||
|
| |
||||
|
<span>👎 <span id="DislikeCount">{{ TuneSetDetails.Dislikes }}</span></span> |
||||
|
| |
||||
|
<span>👍 <span id="LikeCount">{{ TuneSetDetails.Likes }}</span></span> |
||||
|
| |
||||
|
<span>⭐ <span id="BookmarkCount">{{ TuneSetDetails.Bookmarks }}</span></span> |
||||
|
| |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="center"> |
||||
|
<div> |
||||
|
{% for tune in TunesInSet %} |
||||
|
<pre id="NotationContainer--{{ tune.TuneID }}"></pre> |
||||
|
{% endfor %} |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="right"> |
||||
|
<h2>{{ "Audio"|translate }}</h2> |
||||
|
<div id="MIDI--{{ TuneSetDetails.ID }}"></div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<script> |
||||
|
if (!window.ABCJS) { |
||||
|
console.error("ABCJS library failed to load."); |
||||
|
} |
||||
|
</script> |
||||
|
<script> |
||||
|
document.addEventListener("DOMContentLoaded", function () { |
||||
|
function populateABC(targetTuneID) |
||||
|
{ |
||||
|
API_GET_TEXT("/V1/GetABCFile.php?tune-variant-id=" + targetTuneID) |
||||
|
.then(payload => { |
||||
|
// Ensure required DOM elements exist |
||||
|
const notationContainer = document.getElementById("NotationContainer--" + targetTuneID); |
||||
|
|
||||
|
if (!notationContainer) { |
||||
|
console.error(`Missing DOM elements for targetTuneID: ${targetTuneID}`); |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
console.log(window.ABCJS); |
||||
|
|
||||
|
// Render the ABC notation |
||||
|
const tunes = window.ABCJS.renderAbc( |
||||
|
notationContainer.id, |
||||
|
payload, |
||||
|
{ |
||||
|
add_classes: true, |
||||
|
format: { |
||||
|
gchordfont: "Atkinson Hyperlegible", |
||||
|
annotationfont: "Atkinson Hyperlegible", |
||||
|
headerfont: "Atkinson Hyperlegible", |
||||
|
infofont: "Atkinson Hyperlegible", |
||||
|
repeatfont: "Atkinson Hyperlegible", |
||||
|
tempofont: "Atkinson Hyperlegible", |
||||
|
titlefont: "Atkinson Hyperlegible", |
||||
|
voicefont: "Atkinson Hyperlegible", |
||||
|
wordsfont: "Atkinson Hyperlegible", |
||||
|
}, |
||||
|
} |
||||
|
); |
||||
|
|
||||
|
// Display raw ABC notation |
||||
|
rawABCContainer.innerHTML = payload; |
||||
|
|
||||
|
|
||||
|
|
||||
|
window.ABCJS.startAnimation(notationContainer.id, tunes[0], { |
||||
|
showCursor: true, |
||||
|
}); |
||||
|
}) |
||||
|
.catch(error => { |
||||
|
console.error("Error fetching ABC data:", error); |
||||
|
}); |
||||
|
} |
||||
|
{% for tune in TunesInSet %} |
||||
|
populateABC('{{ tune.TuneID }}'); |
||||
|
{% endfor %} |
||||
|
}); |
||||
|
</script> |
||||
|
{% endblock %} |
Loading…
Reference in new issue