327 lines
12 KiB
HTML
327 lines
12 KiB
HTML
{% load static %}
|
|
{% load i18n %}
|
|
{% load l10n %}
|
|
{% load humanize %}
|
|
{% load mastodon %}
|
|
{% 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>{% trans "Mark" %} - {{ item.title }}</strong>
|
|
</header>
|
|
<div>
|
|
<form method="post" action="{% url 'journal:mark' item.uuid %}">
|
|
{% csrf_token %}
|
|
{% if shelf_statuses %}
|
|
<input type="hidden" id="mark-status" name="status" value="{{ shelf_type }}">
|
|
<div class="grid mark-line">
|
|
<div>
|
|
<div role="group">
|
|
{% for k, v in shelf_statuses %}
|
|
{% if v %}
|
|
<button data-value="{{ k }}"
|
|
id="id_status_{{ k }}"
|
|
style="padding-left:0.1em;
|
|
padding-right:0.1em;
|
|
width:25%;
|
|
text-overflow: ellipsis;
|
|
white-space: nowrap;
|
|
overflow: hidden"
|
|
{% if k == "wishlist" or k == "dropped" %} _="on click add .outline to .status-selector then remove .outline from me then set value of #mark-status to '{{ k }}' then add .hidden to .rating-editor then halt" {% else %} _="on click add .outline to .status-selector then remove .outline from me then set value of #mark-status to '{{ k }}' then remove .hidden from .rating-editor then halt" {% endif %}
|
|
{% if shelf_type == k %}class="status-selector"{% else %}class="status-selector outline"{% endif %}>
|
|
{{ v }}
|
|
</button>
|
|
{% endif %}
|
|
{% endfor %}
|
|
</div>
|
|
</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 '{% trans "not rated" %}' 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 '{% trans "not rated" %}' 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 '{% trans "not rated" %}' 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="{% trans "Tips: use >!text!< for spoilers; some instances may not be able to show posts longer than 360 charactors." %}"
|
|
id="id_text">{{ mark.comment_text|default:"" }}</textarea>
|
|
</fieldset>
|
|
</div>
|
|
<div>
|
|
<div class="tag-input">
|
|
<input name="tags"
|
|
type="text"
|
|
placeholder="{% trans "add a tag and press Enter" %}"
|
|
id="tags_input"
|
|
data-initial-value="{{ tags }}">
|
|
</div>
|
|
</div>
|
|
<div class="grid" style="overflow-x:scroll;">
|
|
<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">{% trans "Public" %}</label>
|
|
<input type="radio"
|
|
name="visibility"
|
|
value="1"
|
|
required
|
|
id="id_visibility_1"
|
|
{% if mark.visibility == 1 %}checked{% endif %}>
|
|
<label for="id_visibility_1">{% trans "Followers Only" %}</label>
|
|
<input type="radio"
|
|
name="visibility"
|
|
value="2"
|
|
required
|
|
id="id_visibility_2"
|
|
{% if mark.visibility == 2 %}checked{% endif %}>
|
|
<label for="id_visibility_2">{% trans "Mentioned Only" %}</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 %}>
|
|
{% trans "Repost to timeline" %}
|
|
</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">{% trans "change mark date" %}</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="{% trans "Save" %}">
|
|
</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('{% trans "Sure to delete mark, comment and tags for this item?" %}')">
|
|
{% trans "Delete" %}
|
|
</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>
|