mark history: do not change actual mark when deleting history; refine some visual
This commit is contained in:
parent
6a571105b3
commit
a2523fae1c
8 changed files with 123 additions and 168 deletions
25
catalog/templates/_item_user_mark_history.html
Normal file
25
catalog/templates/_item_user_mark_history.html
Normal file
|
@ -0,0 +1,25 @@
|
|||
<ul>
|
||||
{% for log in mark.logs %}
|
||||
<li>
|
||||
{{ log.timestamp|date }}
|
||||
{{ log.action_label }}
|
||||
<span class="action inline">
|
||||
<a hx-post="{% url 'journal:mark_log' mark.item.uuid log.id %}?delete=1"
|
||||
hx-target="#log-list">
|
||||
<i class="fa-solid fa-square-xmark"></i>
|
||||
</a>
|
||||
</span>
|
||||
</li>
|
||||
{% empty %}
|
||||
<li _="init transition #mark-history opacity to 0 then remove #mark-history">无标记历史</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
<div class="action inline">
|
||||
<ul>
|
||||
<button class="secondary outline"
|
||||
hx-post="{% url 'journal:mark_log' mark.item.uuid 0 %}?delete=1"
|
||||
hx-target="#log-list"
|
||||
hx-confirm="确定清除所有标记历史吗?">清除所有标记历史</button>
|
||||
</ul>
|
||||
<p>清除标记历史不会删除或改变现有标记</p>
|
||||
</div>
|
|
@ -4,24 +4,28 @@
|
|||
我的标签
|
||||
{% if not mark.tags %}
|
||||
<small>
|
||||
<a href="#"
|
||||
hx-get="{% url 'journal:mark' item.uuid %}"
|
||||
class="item-mark-icon"
|
||||
hx-target="body"
|
||||
hx-swap="beforeend">
|
||||
<i class="fa-regular fa-square-plus"></i>
|
||||
</a>
|
||||
<span class="action inline">
|
||||
<a href="#"
|
||||
hx-get="{% url 'journal:mark' item.uuid %}"
|
||||
class="item-mark-icon"
|
||||
hx-target="body"
|
||||
hx-swap="beforeend">
|
||||
<i class="fa-regular fa-square-plus"></i>
|
||||
</a>
|
||||
</span>
|
||||
</small>
|
||||
{% endif %}
|
||||
</h5>
|
||||
<span class="action">
|
||||
<span>
|
||||
<a href="#"
|
||||
hx-get="{% url 'journal:mark' item.uuid %}"
|
||||
hx-target="body"
|
||||
hx-swap="beforeend"><i class="fa-solid fa-pen-to-square"></i></a>
|
||||
{% if mark.tags %}
|
||||
<span class="action">
|
||||
<span>
|
||||
<a href="#"
|
||||
hx-get="{% url 'journal:mark' item.uuid %}"
|
||||
hx-target="body"
|
||||
hx-swap="beforeend"><i class="fa-solid fa-pen-to-square"></i></a>
|
||||
</span>
|
||||
</span>
|
||||
</span>
|
||||
{% endif %}
|
||||
<div class="tag-list">
|
||||
{% for tag in mark.tags %}
|
||||
<span>
|
||||
|
@ -35,13 +39,15 @@
|
|||
我的短评
|
||||
{% if not mark.comment %}
|
||||
<small>
|
||||
<a href="#"
|
||||
hx-get="{% url 'journal:mark' item.uuid %}"
|
||||
class="item-mark-icon"
|
||||
hx-target="body"
|
||||
hx-swap="beforeend">
|
||||
<i class="fa-regular fa-square-plus"></i>
|
||||
</a>
|
||||
<span class="action inline">
|
||||
<a href="#"
|
||||
hx-get="{% url 'journal:mark' item.uuid %}"
|
||||
class="item-mark-icon"
|
||||
hx-target="body"
|
||||
hx-swap="beforeend">
|
||||
<i class="fa-regular fa-square-plus"></i>
|
||||
</a>
|
||||
</span>
|
||||
</small>
|
||||
{% endif %}
|
||||
</h5>
|
||||
|
@ -97,10 +103,12 @@
|
|||
我的评论
|
||||
{% if not review %}
|
||||
<small>
|
||||
<a href="{% url 'journal:review_create' item.uuid %}"
|
||||
class="item-mark-icon">
|
||||
<i class="fa-regular fa-square-plus"></i>
|
||||
</a>
|
||||
<span class="action inline">
|
||||
<a href="{% url 'journal:review_create' item.uuid %}"
|
||||
class="item-mark-icon">
|
||||
<i class="fa-regular fa-square-plus"></i>
|
||||
</a>
|
||||
</span>
|
||||
</small>
|
||||
{% endif %}
|
||||
</h5>
|
||||
|
@ -119,7 +127,7 @@
|
|||
<span>
|
||||
<a target="_blank"
|
||||
rel="noopener"
|
||||
{% if mark.review.metadata.shared_link %} href="{{ mark.review.metadata.shared_link }}" title="打<EFBFBD><EFBFBD><EFBFBD>联邦网<EFBFBD><EFBFBD><EFBFBD>分享链接" {% else %} class="disabled" {% endif %}><i class="fa-solid {% if mark.review.visibility > 0 %} fa-lock {% else %} fa-globe {% endif %}"></i></a>
|
||||
{% if mark.review.metadata.shared_link %} href="{{ mark.review.metadata.shared_link }}" title="打开联邦宇宙分享链接" {% else %} class="disabled" {% endif %}><i class="fa-solid {% if mark.review.visibility > 0 %} fa-lock {% else %} fa-globe {% endif %}"></i></a>
|
||||
</span>
|
||||
<span class="timestamp">{{ mark.review.created_time|date }}</span>
|
||||
</span>
|
||||
|
@ -134,13 +142,15 @@
|
|||
<h5>
|
||||
我的收藏单
|
||||
<small>
|
||||
<a href="#"
|
||||
hx-get="{% url 'journal:add_to_collection' item.uuid %}"
|
||||
class="edit"
|
||||
hx-target="body"
|
||||
hx-swap="beforeend">
|
||||
<i class="fa-regular fa-square-plus"></i>
|
||||
</a>
|
||||
<span class="action inline">
|
||||
<a href="#"
|
||||
hx-get="{% url 'journal:add_to_collection' item.uuid %}"
|
||||
class="edit"
|
||||
hx-target="body"
|
||||
hx-swap="beforeend">
|
||||
<i class="fa-regular fa-square-plus"></i>
|
||||
</a>
|
||||
</span>
|
||||
</small>
|
||||
</h5>
|
||||
<div>
|
||||
|
@ -154,85 +164,17 @@
|
|||
{% endfor %}
|
||||
</div>
|
||||
</section>
|
||||
<section>
|
||||
<h5>
|
||||
标记历史
|
||||
{% if mark.logs %}
|
||||
{% if mark.logs %}
|
||||
<section id="mark-history">
|
||||
<h5>
|
||||
标记历史
|
||||
<small>
|
||||
<a href="#" onclick="toggleEditing()" id="edit">编辑</a>
|
||||
<span class="action inline">
|
||||
<a href="#"
|
||||
_="on click toggle .hide-action on #log-list then toggle .activated"><i class="fa-solid fa-pen-to-square"></i></a>
|
||||
</span>
|
||||
</small>
|
||||
{% endif %}
|
||||
</h5>
|
||||
{% if mark.logs %}
|
||||
<ul class="log-list">
|
||||
{% for log in mark.logs %}
|
||||
<li>
|
||||
<form id="mark_log_delete_{{ log.id }}"
|
||||
action="{% url 'journal:mark_log' item.uuid log.id %}"
|
||||
method="post">
|
||||
{% csrf_token %}
|
||||
<div class="log-info-container">
|
||||
<span class="log-info">{{ log.timestamp|date }}</span>
|
||||
<span class="log-info">{{ log.action_label }}</span>
|
||||
<input type="hidden" name="delete" value="1">
|
||||
<input type="hidden" name="log_id" id="{{ log.id }}">
|
||||
<span class="hidden-command log-info" style="display:none">
|
||||
<a href="javascript:void(0)"
|
||||
onclick="deleteLog('{{ log.id }}')"
|
||||
class="item-mark-icon">
|
||||
<i class="fa-solid fa-square-xmark"></i>
|
||||
</a>
|
||||
</span>
|
||||
</div>
|
||||
</form>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
<div class="log-command">
|
||||
<span class="action hidden-command " style="display:none">
|
||||
<form id="mark_delete"
|
||||
action="{% url 'journal:mark' mark.item.uuid %}"
|
||||
method="post">
|
||||
{% csrf_token %}
|
||||
<input type="hidden" name="delete" value="1">
|
||||
<input type="hidden" name="silence" value="True">
|
||||
<a href="#" onclick="deleteAllLog(event)">清空标记历史</a>
|
||||
</form>
|
||||
</span>
|
||||
</div>
|
||||
{% else %}
|
||||
<span class="empty">暂无</span>
|
||||
{% endif %}
|
||||
</section>
|
||||
<script>
|
||||
function toggleEditing() {
|
||||
var buttons = document.getElementsByClassName("hidden-command");
|
||||
var toggle = document.getElementById("edit");
|
||||
|
||||
for (var i = 0; i < buttons.length; i++) {
|
||||
var button = buttons[i];
|
||||
if (button.style.display === "none") {
|
||||
button.style.display = "block";
|
||||
toggle.innerHTML = "取消编辑";
|
||||
} else {
|
||||
button.style.display = "none";
|
||||
toggle.innerHTML = "编辑";
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
function deleteAllLog(event) {
|
||||
event.preventDefault(); // Prevent the default link behavior
|
||||
|
||||
const confirmation = confirm('确认清空标记历史?当前标记也会一并删除');
|
||||
if (confirmation) {
|
||||
const form = document.getElementById('mark_delete');
|
||||
form.submit(); // Submit the form
|
||||
}
|
||||
};
|
||||
|
||||
function deleteLog(logId) {
|
||||
const form = document.getElementById(`mark_log_delete_${logId}`);
|
||||
form.submit(); // Submit the form
|
||||
}
|
||||
</script>
|
||||
</h5>
|
||||
<div id="log-list" class="hide-action">{% include '_item_user_mark_history.html' %}</div>
|
||||
</section>
|
||||
{% endif %}
|
||||
|
|
|
@ -141,6 +141,12 @@ details {
|
|||
}
|
||||
}
|
||||
|
||||
.hide-action {
|
||||
.action {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
form img {
|
||||
max-height: 20vh;
|
||||
}
|
||||
|
|
|
@ -13,50 +13,36 @@
|
|||
|
||||
// make log list like a timeline list
|
||||
// source: https://dev.to/peterc/how-to-create-joined-bulletpoint-lists-with-css-bbc-news-style-1eem
|
||||
ul.log-list {
|
||||
#log-list ul {
|
||||
|
||||
li {
|
||||
list-style: disc;
|
||||
list-style: none;
|
||||
padding-bottom: 1rem;
|
||||
border-left: 1px solid var(--pico-range-active-border-color);
|
||||
position: relative;
|
||||
margin: 0;
|
||||
padding-bottom: 0.5em;
|
||||
padding-left: 0.8em;
|
||||
padding-left: 0.75em;
|
||||
margin-left: 1em;
|
||||
margin-bottom: 0;
|
||||
|
||||
// The actual line being placed before each list item, tweak width and color as appropriate
|
||||
&:before {
|
||||
background-color: var(--pico-color);
|
||||
width: 2px;
|
||||
content: '';
|
||||
content: "";
|
||||
width: 0.5em;
|
||||
height: 0.5em;
|
||||
border: 1px solid var(--pico-range-active-border-color);
|
||||
background: var(--pico-background-color);
|
||||
border-radius: 50%;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: -0.75em;
|
||||
left: -0.275em;
|
||||
top: 0.5em;
|
||||
}
|
||||
|
||||
// Start the line further down on the first list item
|
||||
&:first-child:before {
|
||||
top: 15px;
|
||||
}
|
||||
|
||||
// Stop the line short on the final list item
|
||||
&:last-child:before {
|
||||
height: 15px;
|
||||
}
|
||||
|
||||
// Hide the line when there's only one item
|
||||
&:only-child:before {
|
||||
content: none;
|
||||
&:last-child {
|
||||
padding-bottom: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.log-info {
|
||||
margin-right: 0.5em;
|
||||
}
|
||||
|
||||
.log-info-container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.mark-line {
|
||||
|
|
|
@ -1238,23 +1238,16 @@ class Mark:
|
|||
self.shelfmember.save()
|
||||
|
||||
def delete(self, silence=False):
|
||||
self.logs.delete() # When deleting a mark, all logs of the mark are deleted first.
|
||||
# self.logs.delete() # When deleting a mark, all logs of the mark are deleted first.
|
||||
self.update(None, None, None, 0, silence=silence)
|
||||
|
||||
def delete_log(self, log_id):
|
||||
ShelfLogEntry.objects.filter(
|
||||
owner=self.owner, item=self.item, id=log_id
|
||||
).delete()
|
||||
last_log = (
|
||||
ShelfLogEntry.objects.exclude(shelf_type=None)
|
||||
.filter(owner=self.owner, item=self.item)
|
||||
.order_by("id")
|
||||
.last()
|
||||
)
|
||||
if not last_log:
|
||||
self.update(None, None, None, 0, silence=True)
|
||||
else:
|
||||
self.update(last_log.shelf_type, None, None, 0, silence=True)
|
||||
|
||||
def delete_all_logs(self):
|
||||
self.logs.delete()
|
||||
|
||||
@property
|
||||
def logs(self):
|
||||
|
|
|
@ -105,14 +105,14 @@ class ShelfTest(TestCase):
|
|||
first_log = log.first()
|
||||
Mark(user, book1).delete_log(first_log.id)
|
||||
self.assertEqual(log.count(), 4)
|
||||
# test delete mark -> leave one log: 移除标记
|
||||
Mark(user, book1).delete()
|
||||
self.assertEqual(log.count(), 1)
|
||||
# test delete all logs
|
||||
shelf_manager.move_item(book1, ShelfType.PROGRESS)
|
||||
self.assertEqual(log.count(), 2)
|
||||
Mark(user, book1).delete(silence=True)
|
||||
self.assertEqual(log.count(), 0)
|
||||
# # test delete mark -> leave one log: 移除标记
|
||||
# Mark(user, book1).delete()
|
||||
# self.assertEqual(log.count(), 1)
|
||||
# # test delete all logs
|
||||
# shelf_manager.move_item(book1, ShelfType.PROGRESS)
|
||||
# self.assertEqual(log.count(), 2)
|
||||
# Mark(user, book1).delete(silence=True)
|
||||
# self.assertEqual(log.count(), 0)
|
||||
|
||||
|
||||
class TagTest(TestCase):
|
||||
|
|
|
@ -22,7 +22,7 @@ urlpatterns = [
|
|||
path("unlike/<str:piece_uuid>", unlike, name="unlike"),
|
||||
path("mark/<str:item_uuid>", mark, name="mark"),
|
||||
path("comment/<str:item_uuid>", comment, name="comment"),
|
||||
path("mark_log/<str:item_uuid>/<str:log_id>", mark_log, name="mark_log"),
|
||||
path("mark_log/<str:item_uuid>/<int:log_id>", mark_log, name="mark_log"),
|
||||
path(
|
||||
"add_to_collection/<str:item_uuid>", add_to_collection, name="add_to_collection"
|
||||
),
|
||||
|
|
|
@ -268,9 +268,12 @@ def mark_log(request, item_uuid, log_id):
|
|||
item = get_object_or_404(Item, uid=get_uuid_or_404(item_uuid))
|
||||
mark = Mark(request.user, item)
|
||||
if request.method == "POST":
|
||||
if request.POST.get("delete", default=False):
|
||||
mark.delete_log(log_id)
|
||||
return HttpResponseRedirect(request.META.get("HTTP_REFERER"))
|
||||
if request.GET.get("delete", default=False):
|
||||
if log_id:
|
||||
mark.delete_log(log_id)
|
||||
else:
|
||||
mark.delete_all_logs()
|
||||
return render(request, "_item_user_mark_history.html", {"mark": mark})
|
||||
raise BadRequest()
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue