Rename tag_object -> tag_card.

This commit is contained in:
voussoir 2021-01-08 13:57:27 -08:00
parent 7373730f90
commit 7f9c7085f0
9 changed files with 72 additions and 73 deletions

View file

@ -156,7 +156,6 @@ Here is a brief overview of the project to help you learn your way around:
- When batch fetching objects, consider whether or not a NoSuch should be raised. Perhaps a warningbag should be used.
- Find a way to batch the fetching of photo tags in a way that isn't super ugly (e.g. on an album page, the photos themselves are batched, but then the `photo.get_tags()` on each one is not. In order to batch this we would have to have a separate function that fetches a whole bunch of tags and assigns them to the photo object).
- Check for embedded cover art when thumbnailing audio files.
- Rename "tag_object" to tag card and unify the card experience.
- Batch movement of Albums... but without winding up with a second clipboard system?
- Overall, more dynamism with cards and tag objects and updating page without requiring refresh.
- Serve RSS/Atom forms of search results.

View file

@ -165,22 +165,22 @@ is hovered over.
{
display: none;
}
.tag_object:hover ~ * .remove_tag_button,
.tag_object:hover ~ .remove_tag_button,
.tag_card:hover ~ * .remove_tag_button,
.tag_card:hover ~ .remove_tag_button,
.remove_tag_button:hover,
.remove_tag_button_perm:hover
{
display:inline;
}
.tag_object
.tag_card
{
border-radius: 2px;
padding-left: 2px;
padding-right: 2px;
background-color: var(--color_tag_object_bg);
color: var(--color_tag_object_fg);
background-color: var(--color_tag_card_bg);
color: var(--color_tag_card_fg);
font-size: 0.9em;
text-decoration: none;

View file

@ -15,6 +15,6 @@
--color_shadow: rgba(0, 0, 0, 0.5);
--color_highlight: rgba(255, 255, 255, 0.5);
--color_tag_object_bg: #fff;
--color_tag_object_fg: black;
--color_tag_card_bg: #fff;
--color_tag_card_fg: black;
}

View file

@ -15,8 +15,8 @@
--color_shadow: rgba(0, 0, 0, 0.5);
--color_highlight: rgba(255, 255, 255, 0.5);
--color_tag_object_bg: #e6e6e6;
--color_tag_object_fg: black;
--color_tag_card_bg: #e6e6e6;
--color_tag_card_fg: black;
}
button,

View file

@ -15,6 +15,6 @@
--color_shadow: rgba(0, 0, 0, 0.5);
--color_highlight: rgba(255, 255, 255, 0.5);
--color_tag_object_bg: #fff;
--color_tag_object_fg: blue;
--color_tag_card_bg: #fff;
--color_tag_card_fg: blue;
}

View file

@ -2,7 +2,7 @@
<html>
<head>
{% import "header.html" as header %}
{% import "tag_object.html" as tag_object %}
{% import "tag_card.html" as tag_card %}
<title>{{photo.basename}} | Photos</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
@ -161,7 +161,7 @@
{% set tags = photo.get_tags()|sort(attribute='name') %}
{% for tag in tags %}
<li>
{{tag_object.tag_object(tag, link="info", with_alt_description=True)}}<!--
{{tag_card.create_tag_card(tag, link="info", with_alt_description=True)}}<!--
--><button
class="remove_tag_button red_button"
onclick="return remove_photo_tag_form('{{photo.id}}', '{{tag.name}}');">
@ -305,26 +305,26 @@ function add_photo_tag_callback(response)
return;
}
const this_tags = document.getElementById("this_tags");
const tag_objects = this_tags.getElementsByClassName("tag_object");
for (const tag_object of tag_objects)
const tag_cards = this_tags.getElementsByClassName("tag_card");
for (const tag_card of tag_cards)
{
if (tag_object.innerText === response.data.tagname)
if (tag_card.innerText === response.data.tagname)
{
return;
}
}
const li = document.createElement("li");
const tag_object = document.createElement("a");
tag_object.className = "tag_object"
tag_object.href = "/tag/" + response.data.tagname;
tag_object.innerText = response.data.tagname;
const tag_card = document.createElement("a");
tag_card.className = "tag_card"
tag_card.href = "/tag/" + response.data.tagname;
tag_card.innerText = response.data.tagname;
const remove_button = document.createElement("button");
remove_button.className = "remove_tag_button red_button"
remove_button.onclick = () => remove_photo_tag_form(PHOTO_ID, response.data.tagname);
li.appendChild(tag_object);
li.appendChild(tag_card);
li.appendChild(remove_button);
this_tags.appendChild(li);
sort_tag_objects();
sort_tag_cards();
}
function remove_photo_tag_form(photo_id, tagname)
@ -340,12 +340,12 @@ function remove_photo_tag_callback(response)
{
return;
}
const tag_objects = document.getElementById("this_tags").getElementsByClassName("tag_object");
for (const tag_object of tag_objects)
const tag_cards = document.getElementById("this_tags").getElementsByClassName("tag_card");
for (const tag_card of tag_cards)
{
if (tag_object.innerText === response.data.tagname)
if (tag_card.innerText === response.data.tagname)
{
const li = tag_object.parentElement;
const li = tag_card.parentElement;
li.parentElement.removeChild(li);
}
}
@ -456,14 +456,14 @@ function set_searchhidden_callback(response)
// UI //////////////////////////////////////////////////////////////////////////////////////////////
function sort_tag_objects()
function sort_tag_cards()
{
const tag_list = document.getElementById("this_tags");
const lis = Array.from(tag_list.children).filter(el => el.getElementsByClassName("tag_object").length);
const lis = Array.from(tag_list.children).filter(el => el.getElementsByClassName("tag_card").length);
function compare(li1, li2)
{
const tag1 = li1.querySelector(".tag_object:last-of-type").innerText;
const tag2 = li2.querySelector(".tag_object:last-of-type").innerText;
const tag1 = li1.querySelector(".tag_card:last-of-type").innerText;
const tag2 = li2.querySelector(".tag_card:last-of-type").innerText;
return tag1 < tag2 ? -1 : 1;
}
lis.sort(compare);

View file

@ -1,10 +1,10 @@
<!DOCTYPE html5>
<html>
<head>
{% import "photo_card.html" as photo_card %}
{% import "album_card.html" as album_card %}
{% import "header.html" as header %}
{% import "tag_object.html" as tag_object %}
{% import "album_card.html" as album_card %}
{% import "photo_card.html" as photo_card %}
{% import "tag_card.html" as tag_card %}
{% import "clipboard_tray.html" as clipboard_tray %}
<title>Search</title>
<meta charset="UTF-8">
@ -200,7 +200,7 @@
{% if search_kwargs[key] %}
{% for tag in search_kwargs[key] %}
<li class="search_builder_{{tagtype}}_inputted">
{{tag_object.tag_object(tag, link='info', with_alt_description=True)}}<!--
{{tag_card.create_tag_card(tag, link='info', with_alt_description=True)}}<!--
--><button class="remove_tag_button red_button"
onclick="return remove_searchtag(ul_{{tagtype}}, '{{tag.name}}', inputted_{{tagtype}});"></button>
</li>
@ -327,28 +327,28 @@
<ul id="tags_on_this_page_list">
{% for tag in total_tags %}
<li>
{{tag_object.tag_object(
{{tag_card.create_tag_card(
tag,
link=None,
onclick="return tags_on_this_page_add_must(event, '" + tag.name + "');",
innertext="(+)",
)}}
{{tag_object.tag_object(
{{tag_card.create_tag_card(
tag,
link=None,
onclick="return tags_on_this_page_add_may(event, '" + tag.name + "');",
innertext="(~)",
)}}
{{tag_object.tag_object(
{{tag_card.create_tag_card(
tag,
link=None,
onclick="return tags_on_this_page_add_forbid(event, '" + tag.name + "');",
innertext="(x)",
)}}
{{tag_object.tag_object(
{{tag_card.create_tag_card(
tag,
link="info",
with_alt_description=True,
@ -412,7 +412,7 @@ function add_searchtag(ul, value, inputted_list, li_class)
new_li.className = li_class;
const new_span = document.createElement("span");
new_span.className = "tag_object";
new_span.className = "tag_card";
new_span.innerHTML = value;
const new_delbutton = document.createElement("button")
@ -465,11 +465,11 @@ function remove_searchtag(ul, value, inputted_list)
//console.log(lis);
for (const li of lis)
{
const tag_object = li.children[0];
if (! tag_object.classList.contains("tag_object"))
const tag_card = li.children[0];
if (! tag_card.classList.contains("tag_card"))
{continue}
const tagname = tag_object.innerHTML;
const tagname = tag_card.innerHTML;
if (tagname != value)
{continue}

View file

@ -1,7 +1,7 @@
<!--
tag: The Tag object
extra_classes:
Space-separated string, if you want more than "tag_object".
Space-separated string, if you want more than "tag_card".
innertext:
A string to use as the innertext.
Otherwise, will use the name based on the other parameters.
@ -15,7 +15,7 @@
with_alt_description:
True: Include the description in the alt text
-->
{%- macro tag_object(
{%- macro create_tag_card(
tag,
extra_classes="",
innertext=None,
@ -34,7 +34,7 @@
None: None,
}.get(link, link)
-%}
{%- set class = ("tag_object" + " " + extra_classes).strip() -%}
{%- set class = ("tag_card" + " " + extra_classes).strip() -%}
{%- set title = (with_alt_description and tag.description) or None -%}
{%- set innertext = innertext_safe or (innertext or tag.name)|e -%}
{%- set element = "a" if (link or onclick) else "span" -%}

View file

@ -2,7 +2,7 @@
<html>
<head>
{% import "header.html" as header %}
{% import "tag_object.html" as tag_object %}
{% import "tag_card.html" as tag_card %}
{% if specific_tag is none %}
<title>Tags</title>
{% else %}
@ -95,7 +95,7 @@ h2, h3
{% if specific_tag %}
<div id="hierarchy_self" class="panel">
<div id="tag_metadata">
<h2>{{tag_object.tag_object(
<h2>{{tag_card.create_tag_card(
specific_tag,
link="search",
id="name_text",
@ -129,9 +129,9 @@ h2, h3
<ul id="parent_list">
{% for ancestor in specific_tag.get_parents() %}
<li>
{{tag_object.tag_object(ancestor, link="search_musts", innertext="(+)")}}
{{tag_object.tag_object(ancestor, link="search_forbids", innertext="(x)")}}
{{tag_object.tag_object(ancestor, link="info", innertext=ancestor.name, with_alt_description=True)}}
{{tag_card.create_tag_card(ancestor, link="search_musts", innertext="(+)")}}
{{tag_card.create_tag_card(ancestor, link="search_forbids", innertext="(x)")}}
{{tag_card.create_tag_card(ancestor, link="info", innertext=ancestor.name, with_alt_description=True)}}
</li>
{% endfor %}
</ul>
@ -148,9 +148,9 @@ h2, h3
<ul id="tag_list">
{% for (qualified_name, tag) in tags %}
<li>
{{tag_object.tag_object(tag, link="search_musts", innertext="(+)")}}
{{tag_object.tag_object(tag, link="search_forbids", innertext="(x)")}}
{{tag_object.tag_object(tag, link="info", innertext=qualified_name, with_alt_description=True)-}}
{{tag_card.create_tag_card(tag, link="search_musts", innertext="(+)")}}
{{tag_card.create_tag_card(tag, link="search_forbids", innertext="(x)")}}
{{tag_card.create_tag_card(tag, link="info", innertext=qualified_name, with_alt_description=True)-}}
{% if specific_tag or '.' in qualified_name -%}
<button
class="remove_tag_button red_button button_with_confirm"
@ -181,9 +181,9 @@ h2, h3
{% if include_synonyms %}
{% for synonym in tag.get_synonyms()|sort %}
<li>
{{-tag_object.tag_object(tag, link="search_musts", innertext="(+)")}}
{{tag_object.tag_object(tag, link="search_forbids", innertext="(x)")}}
{{tag_object.tag_object(tag, link='info', innertext=qualified_name + '+' + synonym)-}}
{{-tag_card.create_tag_card(tag, link="search_musts", innertext="(+)")}}
{{tag_card.create_tag_card(tag, link="search_forbids", innertext="(x)")}}
{{tag_card.create_tag_card(tag, link='info', innertext=qualified_name + '+' + synonym)-}}
<button
class="remove_tag_button red_button button_with_confirm"
data-holder-class="confirm_holder_remove_synonym"
@ -216,11 +216,11 @@ h2, h3
<ul>
{% for synonym in synonyms %}
<li>
{{tag_object.tag_object(specific_tag, link="search_musts", innertext="(+)")}}
{{tag_card.create_tag_card(specific_tag, link="search_musts", innertext="(+)")}}
{{tag_object.tag_object(specific_tag, link="search_forbids", innertext="(x)")}}
{{tag_card.create_tag_card(specific_tag, link="search_forbids", innertext="(x)")}}
{{tag_object.tag_object(specific_tag, link=none, innertext=synonym)-}}
{{tag_card.create_tag_card(specific_tag, link=none, innertext=synonym)-}}
<button
class="remove_tag_button red_button button_with_confirm"
data-onclick="return remove_specific_synonym_form(event);"
@ -319,10 +319,10 @@ function add_synonym_form(event)
api.tags.add_synonym(SPECIFIC_TAG, syn_name, callback);
}
function tag_object_from_li(li)
function tag_card_from_li(li)
{
const tag_objects = li.getElementsByClassName("tag_object");
return tag_objects[tag_objects.length - 1];
const tag_cards = li.getElementsByClassName("tag_card");
return tag_cards[tag_cards.length - 1];
}
function easybake_form()
@ -349,8 +349,8 @@ function delete_specific_tag_form(event)
{
const delete_button = event.target;
const hierarchy_self = delete_button.closest("#hierarchy_self");
const tag_object = tag_object_from_li(hierarchy_self);
const tag_name = tag_object.innerText;
const tag_card = tag_card_from_li(hierarchy_self);
const tag_name = tag_card.innerText;
return api.tags.delete(tag_name, api.tags.callback_go_to_tags);
}
@ -358,8 +358,8 @@ function delete_tag_form(event)
{
const delete_button = event.target;
const li = delete_button.closest("li");
const tag_object = tag_object_from_li(li);
const tag_name = tag_object.innerText.split(".").pop();
const tag_card = tag_card_from_li(li);
const tag_name = tag_card.innerText.split(".").pop();
return api.tags.delete(tag_name, tag_action_callback);
}
@ -367,8 +367,8 @@ function remove_child_form(event)
{
const delete_button = event.target;
const li = delete_button.closest("li");
const tag_object = tag_object_from_li(li);
const qual_name = tag_object.innerText;
const tag_card = tag_card_from_li(li);
const qual_name = tag_card.innerText;
let tag_name;
let parent_name;
if (qual_name.indexOf(".") != -1)
@ -389,8 +389,8 @@ function remove_specific_synonym_form(event)
{
const delete_button = event.target;
const li = delete_button.closest("li");
const tag_object = tag_object_from_li(li);
const synonym = tag_object.innerText;
const tag_card = tag_card_from_li(li);
const synonym = tag_card.innerText;
return api.tags.remove_synonym(SPECIFIC_TAG, synonym, tag_action_callback);
}
@ -398,8 +398,8 @@ function remove_synonym_form(event)
{
const delete_button = event.target;
const li = delete_button.closest("li");
const tag_object = tag_object_from_li(li);
const parts = tag_object.innerText.split(".").pop().split("+");
const tag_card = tag_card_from_li(li);
const parts = tag_card.innerText.split(".").pop().split("+");
const synonym = parts.pop();
const tag_name = parts.pop();
return api.tags.remove_synonym(tag_name, synonym, tag_action_callback);