315 lines
11 KiB
HTML
315 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
|
|
_="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 class="add-to-list-modal__body">
|
|
<form method="post" action="{% url 'journal:mark' item.uuid %}">
|
|
{% csrf_token %}
|
|
<div class="grid mark-line">
|
|
<div>
|
|
<fieldset>
|
|
{% for k, v in shelf_types %}
|
|
{% if v %}
|
|
<input type="radio"
|
|
name="status"
|
|
value="{{ k }}"
|
|
required
|
|
id="id_status_{{ k }}"
|
|
{% if k == "wishlist" %} _="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) 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) 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>
|
|
<div>
|
|
<fieldset>
|
|
<textarea name="text"
|
|
rows="5"
|
|
autofocus
|
|
placeholder="提示: 善用 >!文字!< 标记可隐藏剧透; 超过360字可能无法分享到联邦网络实例时间线。"
|
|
id="id_text">{{ mark.comment_text|default:"" }}</textarea>
|
|
</fieldset>
|
|
</div>
|
|
<div class="mark-modal__tag">
|
|
<div class="tag-input">
|
|
<input name="tags" type="text" placeholder="回车增加标签" id="id_tags" 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>
|
|
<label for="id_share_to_mastodon">
|
|
<input role="switch"
|
|
type="checkbox"
|
|
name="share_to_mastodon"
|
|
id="id_share_to_mastodon"
|
|
value="1"
|
|
{% if not request.user.preference.default_no_share %}checked{% endif %}>
|
|
分享到联邦网络
|
|
</label>
|
|
</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.toLowerCase());
|
|
}
|
|
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 }}".split(","),
|
|
allowDuplicateTags: false,
|
|
duplicateTime: 300,
|
|
onTagRemove: function (tag) { },
|
|
});
|
|
})();
|
|
</script>
|