lib.itmens/journal/templates/mark.html
2024-04-03 23:34:19 -04:00

323 lines
11 KiB
HTML

{% load static %}
{% load i18n %}
{% load l10n %}
{% load humanize %}
{% load admin_url %}
{% load mastodon %}
{% load oauth_token %}
{% load truncate %}
{% load highlight %}
{% load thumb %}
{% load duration %}
<dialog open
class="mark-editor"
_="on close_dialog add .closing then wait for animationend then remove me">
<article>
<header>
<link to="#"
aria-label="Close"
class="close"
_="on click trigger close_dialog" />
<strong>标记 {{ item.title }}</strong>
</header>
<div>
<form method="post" action="{% url 'journal:mark' item.uuid %}">
{% csrf_token %}
{% if shelf_actions %}
<div class="grid mark-line">
<div>
<fieldset>
{% for k, v in shelf_actions %}
{% if v %}
<input type="radio"
name="status"
value="{{ k }}"
required
id="id_status_{{ k }}"
{% if k == "wishlist" or k == "dropped" %} _="on click add .hidden to .rating-editor" {% else %} _="on click remove .hidden from .rating-editor" {% endif %}
{% if shelf_type == k %}checked=""{% endif %}>
<label for="id_status_{{ k }}">{{ v }}</label>
{% endif %}
{% endfor %}
</fieldset>
</div>
<div>
<span class="rating-editor {% if shelf_type == 'wishlist' %}hidden{% endif %}" _="on mousemove(currentTarget, offsetX) set current_value to Math.round((10 * offsetX) / currentTarget.offsetWidth) if current_value <=10 then set star_div to the
<div/>
in me set star_div.style.width to (current_value * 10) + '%' set @data-tooltip to current_value or '未评分' add .yellow to star_div end on click(currentTarget, offsetX) set current_value to Math.round((10 * offsetX) / currentTarget.offsetWidth) if current_value <=10 then set star_div to the
<div/>
in me set star_input to the
<input/>
in me set star_div.style.width to (current_value * 10) + '%' set @data-tooltip to current_value or '未评分' set star_input.value to current_value end on mouseleave(currentTarget) set star_div to the
<div/>
in me set star_input to the
<input/>
in me set current_value to star_input.value set star_div.style.width to (current_value * 10) + '%' set @data-tooltip to current_value or '未评分' end">
{{ mark.rating_grade|rating_star }}
<input type="hidden"
name="rating_grade"
id="id_rating"
value="{{ mark.rating_grade | default:0 }}">
</span>
</div>
</div>
{% endif %}
<div>
<fieldset>
<textarea name="text"
rows="5"
autofocus
placeholder="提示: 善用 &gt;!文字!&lt; 标记可隐藏剧透; 超过360字可能无法分享到联邦宇宙实例时间轴。"
id="id_text">{{ mark.comment_text|default:"" }}</textarea>
</fieldset>
</div>
<div>
<div class="tag-input">
<input name="tags"
type="text"
placeholder="回车增加标签"
id="tags_input"
data-initial-value="{{ tags }}">
</div>
</div>
<div class="grid">
<div>
<fieldset>
<input type="radio"
name="visibility"
value="0"
required
id="id_visibility_0"
{% if mark.visibility == 0 %}checked{% endif %}>
<label for="id_visibility_0">公开</label>
<input type="radio"
name="visibility"
value="1"
required
id="id_visibility_1"
{% if mark.visibility == 1 %}checked{% endif %}>
<label for="id_visibility_1">仅关注者</label>
<input type="radio"
name="visibility"
value="2"
required
id="id_visibility_2"
{% if mark.visibility == 2 %}checked{% endif %}>
<label for="id_visibility_2">仅自己</label>
</fieldset>
</div>
<div>
<fieldset>
{% if request.user.mastodon_acct %}
<label for="id_share_to_mastodon">
<input role="switch"
type="checkbox"
name="share_to_mastodon"
id="id_share_to_mastodon"
value="1"
{% if request.user.preference.mastodon_default_repost %}checked{% endif %}>
转发到<em data-tooltip="@{{ request.user.mastodon_acct }}">主ID</em>时间轴
</label>
{% endif %}
</fieldset>
</div>
</div>
<div class="grid">
<div>
<div>
<input role="switch"
_="on click toggle .invisible on #mark_date "
type="checkbox"
name="mark_anotherday"
value="1"
id="mark_anotherday">
<label for="mark_anotherday">更改日期:</label>
<input class="invisible"
type="date"
name="mark_date"
id="mark_date"
min="1900-01-01"
max="{{ date_today }}"
value="{{ date_today }}">
</div>
</div>
<div>
<fieldset>
<input type="submit" value="保存">
</fieldset>
</div>
</div>
</form>
<div>
{% if mark.id %}
<form id="mark_delete"
action="{% url 'journal:mark' mark.item.uuid %}"
method="post">
{% csrf_token %}
<input type="hidden" name="delete" value="1">
<a>
<button class="secondary" onclick="return confirm('确认删除这条标记、短评和标签?')">删除标记</button>
</a>
</form>
{% endif %}
</div>
</div>
</article>
</dialog>
<script>
function inputTags(configs) {
let tagsContainer = configs.container,
input = configs.container.querySelector('input')
let _privateMethods = {
init: function (configs) {
// this.inspectConfigProperties(configs);
let self = this,
input_hidden = document.createElement('input');
let name = input.getAttribute('name'),
id = input.getAttribute('id');
input.removeAttribute('name');
// input.removeAttribute('id');
input_hidden.setAttribute('type', 'hidden');
// input_hidden.setAttribute('id', id);
input_hidden.setAttribute('name', name);
input.parentNode.insertBefore(input_hidden, input);
this.input_hidden = input_hidden
tagsContainer.addEventListener('click', function () {
input.focus();
});
if (configs.tags) {
for (let i = 0; i < configs.tags.length; i++) {
if (configs.tags[i]) {
this.create(configs.tags[i]);
}
}
}
input.addEventListener("focusout", function () {
let tag_txt = this.value.trim(),
tag_exists = false;
if (self.tags_array) {
tag_exists = Boolean(self.tags_array.indexOf(tag_txt) + 1);
}
if (tag_txt && tag_exists && !configs.allowDuplicateTags) {
self.showDuplicate(tag_txt);
}
else if (tag_txt && tag_exists && configs.allowDuplicateTags) {
self.create(tag_txt);
}
else if (tag_txt && !tag_exists) {
self.create(tag_txt);
}
this.value = "";
});
input.addEventListener('keydown', function (ev) {
if (ev.keyCode === 13 || ev.keyCode === 188 ||
(ev.keyCode === 32 && configs.allowDuplicateTags)) { // enter || comma || space
let event = new Event('focusout');
input.dispatchEvent(event);
ev.preventDefault();
}
else if (event.which === 8 && !input.value) { // backspace
let tag_nodes = document.querySelectorAll('.tag-input__tag');
if (tag_nodes.length > 0) {
input.addEventListener('keyup', function (event) {
if (event.which === 8) {
let node_to_del = tag_nodes[tag_nodes.length - 1];
node_to_del.remove();
self.update();
}
});
}
ev.preventDefault();
}
});
},
create: function (tag_txt) {
let tag_nodes = document.querySelectorAll('.tag-input__tag');
if (!configs.maxTags || tag_nodes.length < configs.maxTags) {
let self = this,
span_tag = document.createElement('span'),
input_hidden_field = self.input_hidden;
span_tag.setAttribute('class', 'tag-input__tag');
span_tag.innerText = tag_txt;
let span_tag_close = document.createElement('span');
span_tag_close.setAttribute('class', 'tag-input__close');
span_tag.appendChild(span_tag_close);
tagsContainer.insertBefore(span_tag, input_hidden_field);
span_tag.childNodes[1].addEventListener('click', function () {
self.remove(this);
});
this.update();
}
},
update: function () {
let tags = document.getElementsByClassName('tag-input__tag'),
tags_arr = [];
for (let i = 0; i < tags.length; i++) {
tags_arr.push(tags[i].textContent);
}
this.tags_array = tags_arr;
this.input_hidden.setAttribute('value', tags_arr.join());
},
remove: function (tag) {
configs.onTagRemove(tag.parentNode.textContent);
tag.parentNode.remove();
this.update();
},
showDuplicate: function (tag_value) {
let tags = document.getElementsByClassName('tag-input__tag');
for (let i = 0; i < tags.length; i++) {
if (tags[i].textContent === tag_value) {
tags[i].classList.add("tag-input__tag--highlight");
window.setTimeout(function () {
tags[i].classList.remove("tag-input__tag--highlight");
}, configs.duplicateTime);
}
}
}
}
_privateMethods.init(configs);
// return false;
}
(function () {
new inputTags({
container: document.getElementsByClassName("tag-input")[0],
tags: $("#tags_input").data("initial-value").split(","),
allowDuplicateTags: false,
duplicateTime: 300,
onTagRemove: function (tag) { },
});
})();
</script>