Merge pull request 'Change how tags are displayed on photo page' (#46) from tag-list into master

Reviewed-on: Public/pics#46
Reviewed-by: Bart Schuurmans <bart@minnozz.com>
This commit is contained in:
Bart Schuurmans 2024-01-13 17:28:09 +01:00
commit d556032a83
2 changed files with 78 additions and 65 deletions

View File

@ -526,34 +526,27 @@ a#previous_photo:hover, a#next_photo:hover {
#sub_photo h2, #sub_photo h3 { #sub_photo h2, #sub_photo h3 {
margin-bottom: 1rem; margin-bottom: 1rem;
} }
#sub_photo #tag_list { #sub_photo .tag-list {
list-style: none; list-style: none;
margin: 1em 0; margin: 1em 0;
padding: 0; padding: 0;
} }
#sub_photo #tag_list li { #sub_photo .tag-list > li {
display: inline; display: inline-block;
padding-right: 0.75em; margin-bottom: 0.75em;
margin-right: 0.75em;
} }
#tag_list .delete-tag { #sub_photo .tag-list .input-group-text {
opacity: 0.25; color: inherit;
} }
#tag_list .delete-tag:hover { [data-bs-theme=light] #sub_photo .tag-list .btn-danger {
opacity: 1.0; background-color: rgba(175, 0, 0, 0.5);
border-color: rgba(175, 0, 0, 0.5);
} }
.photo_meta { [data-bs-theme=dark] #sub_photo .tag-list .btn-danger {
background-color: var(--bs-body-bg); background-color: rgba(100, 0, 0, 0.5);
box-shadow: 0 0.25rem 0.5rem rgba(0,0,0,0.1); border-color: rgb(100, 0, 0);
}
.photo_meta li {
padding: 0.6rem 1rem;
}
.photo_meta h4 {
font-family: 'Coda', sans-serif;
font-size: inherit;
font-weight: bold;
margin: 0;
} }

View File

@ -32,8 +32,8 @@ class PhotoPage extends Template
echo ' echo '
<h2 class="entry-title">', $this->photo->getTitle(), '</h2>'; <h2 class="entry-title">', $this->photo->getTitle(), '</h2>';
$this->taggedPeople(); $this->printTags('Album', 'Album', false);
$this->linkNewTags(); $this->printTags('Tagged People', 'Person', true);
echo ' echo '
</div> </div>
@ -118,91 +118,111 @@ class PhotoPage extends Template
</ul>'; </ul>';
} }
private function taggedPeople() private function printTags($header, $tagKind, $allowLinkingNewTags)
{ {
static $nextTagListId = 1;
$tagListId = 'tagList' . ($nextTagListId++);
echo ' echo '
<h3>Tags</h3> <h3>', $header, '</h3>
<ul id="tag_list">'; <ul id="', $tagListId, '" class="tag-list">';
foreach ($this->photo->getTags() as $tag) foreach ($this->photo->getTags() as $tag)
{ {
if ($tag->kind !== $tagKind)
continue;
echo ' echo '
<li id="tag-', $tag->id_tag, '"> <li id="tag-', $tag->id_tag, '">
<a rel="tag" title="View all posts tagged ', $tag->tag, '" href="', $tag->getUrl(), '" class="entry-tag">', $tag->tag, '</a>'; <div class="input-group">
<a class="input-group-text" href="', $tag->getUrl(), '" title="View all posts tagged ', $tag->tag, '">
', $tag->tag, '
</a>';
if ($tag->kind === 'Person') if ($tag->kind === 'Person')
{
echo ' echo '
<a class="delete-tag" title="Unlink this tag from this photo" href="#" data-id="', $tag->id_tag, '"></a>'; <a class="delete-tag btn btn-danger px-1" title="Unlink this tag from this photo" href="#" data-id="', $tag->id_tag, '">
<i class="bi bi-x"></i>
</a>';
}
echo ' echo '
</div>
</li>';
}
static $nextNewTagId = 1;
$newTagId = 'newTag' . ($nextNewTagId++);
if ($allowLinkingNewTags)
{
echo '
<li style="position: relative">
<input class="form-control w-auto" type="text" id="', $newTagId, '" placeholder="Type to link a new tag">
</li>'; </li>';
} }
echo ' echo '
</ul>'; </ul>';
$this->printNewTagScript($tagKind, $tagListId, $newTagId);
} }
private function linkNewTags() private function printNewTagScript($tagKind, $tagListId, $newTagId)
{ {
echo ' echo '
<div>
<h3>Link tags</h3>
<p style="position: relative">
<input class="form-control w-auto" type="text" id="new_tag" placeholder="Type to link a new tag">
</p>
</div>
<script type="text/javascript" src="', BASEURL, '/js/ajax.js"></script> <script type="text/javascript" src="', BASEURL, '/js/ajax.js"></script>
<script type="text/javascript" src="', BASEURL, '/js/autosuggest.js"></script> <script type="text/javascript" src="', BASEURL, '/js/autosuggest.js"></script>
<script type="text/javascript"> <script type="text/javascript">
setTimeout(function() { setTimeout(function() {
var removeTag = function(event) { const removeTag = function(event) {
event.preventDefault(); event.preventDefault();
var that = this; const request = new HttpRequest("post", "', $this->photo->getPageUrl(), '",
var request = new HttpRequest("post", "', $this->photo->getPageUrl(), '", "id_tag=" + this.dataset["id"] + "&delete", (response) => {
"id_tag=" + this.dataset["id"] + "&delete", function(response) {
if (!response.success) { if (!response.success) {
return; return;
} }
var tagNode = document.getElementById("tag-" + that.dataset["id"]); const tagNode = document.getElementById("tag-" + this.dataset["id"]);
tagNode.parentNode.removeChild(tagNode); tagNode.parentNode.removeChild(tagNode);
}); });
}; };
var tagRemovalTargets = document.getElementsByClassName("delete-tag"); let tagRemovalTargets = document.querySelectorAll(".delete-tag");
for (var i = 0; i < tagRemovalTargets.length; i++) { tagRemovalTargets.forEach(el => el.addEventListener("click", removeTag));
tagRemovalTargets[i].addEventListener("click", removeTag);
}
var tag_autosuggest = new TagAutoSuggest({ let tag_autosuggest = new TagAutoSuggest({
inputElement: "new_tag", inputElement: "', $newTagId, '",
listElement: "tag_list", listElement: "', $tagListId, '",
baseUrl: "', BASEURL, '", baseUrl: "', BASEURL, '",
appendCallback: function(item) { appendCallback: (item) => {
var request = new HttpRequest("post", "', $this->photo->getPageUrl(), '", const request = new HttpRequest("post", "', $this->photo->getPageUrl(), '",
"id_tag=" + item.id_tag, function(response) { "id_tag=" + item.id_tag, (response) => {
var newLink = document.createElement("a"); const newListItem = document.createElement("li");
newListItem.id = "tag-" + item.id_tag;
const newInputGroup = document.createElement("div");
newInputGroup.className = "input-group";
newListItem.appendChild(newInputGroup);
const newLink = document.createElement("a");
newLink.className = "input-group-text";
newLink.href = item.url; newLink.href = item.url;
newLink.title = "View all posts tagged " + item.label;
newLink.textContent = item.label;
newInputGroup.appendChild(newLink);
var newLabel = document.createTextNode(item.label); const removeLink = document.createElement("a");
newLink.appendChild(newLabel); removeLink.className = "delete-tag btn btn-danger px-1";
var removeLink = document.createElement("a");
removeLink.className = "delete-tag";
removeLink.dataset["id"] = item.id_tag; removeLink.dataset["id"] = item.id_tag;
removeLink.href = "#"; removeLink.href = "#";
removeLink.innerHTML = \'<i class="bi bi-x"></i>\';
removeLink.addEventListener("click", removeTag); removeLink.addEventListener("click", removeTag);
newInputGroup.appendChild(removeLink);
var crossmark = document.createTextNode(""); const list = document.getElementById("', $tagListId, '");
removeLink.appendChild(crossmark); list.insertBefore(newListItem, list.querySelector("li:last-child"));
var newNode = document.createElement("li");
newNode.id = "tag-" + item.id_tag;
newNode.appendChild(newLink);
newNode.appendChild(removeLink);
var list = document.getElementById("tag_list");
list.appendChild(newNode);
}, this); }, this);
} }
}); });