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. - 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). - 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. - 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? - 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. - Overall, more dynamism with cards and tag objects and updating page without requiring refresh.
- Serve RSS/Atom forms of search results. - Serve RSS/Atom forms of search results.

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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