Browse Source

made a start on tune sets in the ui

master
Cerys 4 weeks ago
parent
commit
6c88ac15fe
  1. 1
      Localisation/en-GB.yaml
  2. 48
      Pages/tune-set/uuid.php
  3. 46
      Pages/tune/uuid.php
  4. 14
      Routing/Router.php
  5. 57
      Templates/Pages/profile.html.twig
  6. 117
      Templates/Pages/tune-set/uuid.html.twig
  7. 10
      Templates/Pages/tune/uuid.html.twig

1
Localisation/en-GB.yaml

@ -133,6 +133,7 @@ Password: Password
##################################################
# S
##################################################
Sets this tune is in: Sets this tune is in
Suggest another: Suggest another
Summary: Summary

48
Pages/tune-set/uuid.php

@ -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,
]
);

46
Pages/tune/uuid.php

@ -26,54 +26,26 @@ $tuneDetails = $db->RunOneSelect(
)
);
$dances = $db->RunSelect(
$setsThisTuneIsIn = $db->RunSelect(
queryBuilder: SQLQueryBuilderWrapper::SELECT(
table: 'Dances',
table: 'TuneSetTunes'
)
->cols(cols: [
"CONCAT('[', GROUP_CONCAT(
CONCAT(
'{\"ID\":', JSON_QUOTE(T_DS.ID), ',',
'\"CreatedAt\":', JSON_QUOTE(T_DS.CreatedAt), ',',
'\"DanceID\":', JSON_QUOTE(T_DS.DanceID), ',',
'\"BarCountAtStart\":', T_DS.BarCountAtStart, ',',
'\"BarCountAtEnd\":', T_DS.BarCountAtEnd, ',',
'\"Description\":', JSON_QUOTE(T_DS.Description), '}'
)
), ']') AS Steps"
'T_TS.ID AS TuneSetID',
'T_TS.Description AS TuneSetName',
])
->join(
join: 'INNER',
spec: 'DanceSteps AS T_DS',
cond: 'T.ID=T_DS.DanceID'
spec: 'TuneSets AS T_TS',
cond: 'T.TuneSetID=T_TS.ID',
)
->join(
join: 'INNER',
spec: '_Junction_Tunes_Dances AS _J_T_D',
cond: 'T.ID=_J_T_D.DanceID'
)
->where(cond: '_J_T_D.TuneID=:__tune_id__')
->where(cond: 'T.TuneID LIKE :__tune_id__')
->bindValue(name: '__tune_id__', value: $_GET["tune-id"])
->groupBy(spec: [
'T.ID',
'T.CreatedAt',
'T.Title',
'_J_T_D.ID',
'_J_T_D.CreatedAt',
'_J_T_D.TuneID',
'_J_T_D.DanceID',
'T.TuneSetID',
])
);
for ($i = 0; $i < count($dances); $i++)
$dances[$i]['Steps'] = json_decode(
$dances[$i]['Steps'],
true,
JSON_THROW_ON_ERROR
);
$myVote = 0;
if(SessionWrapper::Get(SessionElement::IS_LOGGED_IN))
{
@ -102,7 +74,7 @@ TwigWrapper::RenderTwig(
target: "Pages/tune/uuid.html.twig",
arguments: [
"TuneDetails"=>$tuneDetails,
"Dances"=>$dances,
"SetsThisTuneIsIn" => $setsThisTuneIsIn,
"MyVote"=>$myVote,
]
);

14
Routing/Router.php

@ -57,10 +57,20 @@ if ($requestElements[0] === "tune" && isset($requestElements[1]))
require_once __DIR__ . '/../Pages/tune/uuid.php';
return true;
}
}
elseif ($requestElements[0] === "tune-set" && isset($requestElements[1]))
{
$_GET['tune-set-id'] = $requestElements[1];
if (count($requestElements) === 2)
{
require_once __DIR__ . '/../Pages/tune-set/uuid.php';
return true;
}
$tuneSubRoutes = [
"suggest-variant" => '/../Pages/tune/uuid/suggest-variant.php',
"suggest-dance" => '/../Pages/tune/uuid/suggest-dance.php',
"suggest-variant" => '/../Pages/tune-set/uuid/suggest-variant.php',
"suggest-dance" => '/../Pages/tune-set/uuid/suggest-dance.php',
];
if (isset($tuneSubRoutes[$requestElements[2]])) {

57
Templates/Pages/profile.html.twig

@ -20,6 +20,8 @@
<div class="Tab">
<button id="DefaultOpenTab" class="TabLink" onclick="openTuneTab(event, 'MyUploadedTunes')">{{ "My Uploaded Tunes"|translate }}</button>
<button class="TabLink" onclick="openTuneTab(event, 'MyTuneSets')">{{ "My Tune Sets"|translate }}</button>
<button class="TabLink" onclick="openTuneTab(event, 'MyBookmarkedTunes')">{{ "My Bookmarked Tunes"|translate }}</button>
<button class="TabLink" onclick="openTuneTab(event, 'MyLikedTunes')">{{ "My Liked Tunes"|translate }}</button>
<button class="TabLink" onclick="openTuneTab(event, 'MyDislikedTunes')">{{ "My Disliked Tunes"|translate }}</button>
</div>
@ -46,6 +48,61 @@
</table>
</div>
<div id="MyTuneSets" class="TabContent">
<h2>{{ "My Tune Sets"|translate }}</h2>
<table>
<thead>
<tr>
<th>{{ "Title"|translate }}</th>
<th>{{ "Created At"|translate }}</th>
<th>{{ "Tunes In Set"|translate }}</th>
</tr>
</thead>
<tbody>
{% for tuneSetDetails in YourTuneSets %}
<tr>
<td><a href="/tune-set/{{ tuneSetDetails.ID }}">{{ tuneSetDetails.Description }}</a></td>
<td>{{ tuneSetDetails.CreatedAt }}</td>
<td>
<table>
<tbody>
{% for tuneDetails in tuneSetDetails.TunesInSet %}
<tr>
<td><a href="/tune/{{ tuneDetails.ID }}">{{ tuneDetails.Title }}</a></td>
<td>{{ tuneDetails.TimesThrough }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
<div id="MyBookmarkedTunes" class="TabContent">
<h2>{{ "My Bookmarked Tunes"|translate }}</h2>
<table>
<thead>
<tr>
<th>{{ "Title"|translate }}</th>
<th>{{ "Created At"|translate }}</th>
<th>{{ "Copyright"|translate }}</th>
</tr>
</thead>
<tbody>
{% for tuneDetails in YourBookmarkedTunes %}
<tr>
<td><a href="/tune/{{ tuneDetails.TuneID }}">{{ tuneDetails.Title }}</a></td>
<td>{{ tuneDetails.CreatedAt }}</td>
<td>{{ tuneDetails.Copyright }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
<div id="MyLikedTunes" class="TabContent">
<h2>{{ "My Liked Tunes"|translate }}</h2>
<table>

117
Templates/Pages/tune-set/uuid.html.twig

@ -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 %}

10
Templates/Pages/tune/uuid.html.twig

@ -82,6 +82,16 @@
<h2>{{ "Audio"|translate }}</h2>
<div id="MIDI--{{ TuneDetails.ID }}"></div>
<div id="TuneSetContainer">
<h2>{{ "Sets this tune is in"|translate }}</h2>
<ul>
{% for tuneSet in SetsThisTuneIsIn %}
<li>
<a href="/tune-set/{{ tuneSet.TuneSetID }}">{{ tuneSet.TuneSetName }}</a>
</li>
{% endfor %}
</ul>
</div>
</div>
</div>
</div>

Loading…
Cancel
Save