more detail in collection view

This commit is contained in:
Your Name 2022-01-17 14:08:30 -05:00
parent 7d4b0eb07a
commit 5d5ddccf71
13 changed files with 513 additions and 68 deletions

View file

@ -25,6 +25,7 @@
<script src="{% static 'js/rating-star-readonly.js' %}"></script>
<link rel="stylesheet" href="{% static 'lib/css/rating-star.css' %}">
<link rel="stylesheet" href="{% static 'css/boofilsic.min.css' %}">
<link rel="stylesheet" href="{% static 'lib/css/neo.css' %}">
<script src="https://unpkg.com/htmx.org@1.6.1"></script>
</head>

View file

@ -1,5 +1,5 @@
<form hx-post="{% url 'collection:update_item_comment' collection.id item.id %}">
<input name="comment" value="{{ item.comment }}">
<form hx-post="{% url 'collection:update_item_comment' collection.id collectionitem.id %}">
<input name="comment" value="{{ collectionitem.comment }}">
<input type="submit" style="width:unset;" value="修改">
<button style="width:unset;" hx-get="{% url 'collection:show_item_comment' collection.id item.id %}">取消</button>
<button style="width:unset;" hx-get="{% url 'collection:show_item_comment' collection.id collectionitem.id %}">取消</button>
</form>

View file

@ -2,62 +2,9 @@
{% load i18n %}
{% load l10n %}
<ul class="entity-list__entities">
{% for item in collection.collectionitem_list %}
{% if item.item is not None %}
<li class="entity-list__entity">
<div class="entity-list__entity-img-wrapper">
<a href="{{ item.item.get_absolute_url }}">
<img src="{{ item.item.cover|thumb:'normal' }}" alt="" class="entity-list__entity-img">
</a>
</div>
<div class="entity-list__entity-text">
{% if editable %}
<div style="float:right">
{% if not forloop.first %}
<a hx-target=".entity-list" hx-post="{% url 'collection:move_up_item' form.instance.id item.id %}"></a>
{% endif %}
{% if not forloop.last %}
<a hx-target=".entity-list" hx-post="{% url 'collection:move_down_item' form.instance.id item.id %}"></a>
{% endif %}
<a hx-target=".entity-list" hx-post="{% url 'collection:delete_item' form.instance.id item.id %}"></a>
</div>
{% endif %}
<div class="entity-list__entity-title">
<a href="{{ item.item.get_absolute_url }}" style="font-size:16px">{{ item.item.title }}</a>
<span class="entity-list__entity-category">[{{item.item.verbose_category_name}}]</span>
<a href="{{ item.item.source_url }}">
<span class="source-label source-label__{{ item.item.source_site }}">{{ item.item.get_source_site_display }}</span>
</a>
</div>
<span class="entity-list__entity-info entity-list__entity-info--full-length">
<p class="entity-list__entity-brief" style="white-space: normal;">
{{ item.item.brief }}
</p>
</span>
<div class="tag-collection">
{% for tag_dict in item.item.tag_list %}
{% for k, v in tag_dict.items %}
{% if k == 'content' %}
<span class="tag-collection__tag">
<a href="{% url 'common:search' %}?tag={{ v }}">{{ v }}</a>
</span>
{% endif %}
{% endfor %}
{% endfor %}
</div>
<div class="clearfix"></div>
<div class="dividing-line dividing-line--dashed"></div>
<div class="entity-marks" style="margin-bottom: 0;">
<ul class="entity-marks__mark-list">
<li class="entity-marks__mark">
<p class="entity-marks__mark-content" hx-target="this" hx-swap="innerHTML">
{% include "show_item_comment.html" %}
</p>
</li>
</ul>
</div>
</div>
</li>
{% for collectionitem in collection.collectionitem_list %}
{% if collectionitem.item is not None %}
{% include "partial/list_item.html" with item=collectionitem.item %}
{% endif %}
{% empty %}
{% endfor %}

View file

@ -1,4 +1,4 @@
{{ item.comment }}
{{ collectionitem.comment }}
{% if editable %}
<a hx-get="{% url 'collection:update_item_comment' collection.id item.id %}"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" style="cursor:pointer;fill:#ccc;height:12px;vertical-align:text-bottom;"><g><path d="M19,20H5a1,1,0,0,0,0,2H19a1,1,0,0,0,0-2Z"/><path d="M5,18h.09l4.17-.38a2,2,0,0,0,1.21-.57l9-9a1.92,1.92,0,0,0-.07-2.71h0L16.66,2.6A2,2,0,0,0,14,2.53l-9,9a2,2,0,0,0-.57,1.21L4,16.91a1,1,0,0,0,.29.8A1,1,0,0,0,5,18ZM15.27,4,18,6.73,16,8.68,13.32,6Zm-8.9,8.91L12,7.32l2.7,2.7-5.6,5.6-3,.28Z"/></g></svg></a>
<a class="action-icon" hx-get="{% url 'collection:update_item_comment' collection.id collectionitem.id %}"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><g><path d="M19,20H5a1,1,0,0,0,0,2H19a1,1,0,0,0,0-2Z"/><path d="M5,18h.09l4.17-.38a2,2,0,0,0,1.21-.57l9-9a1.92,1.92,0,0,0-.07-2.71h0L16.66,2.6A2,2,0,0,0,14,2.53l-9,9a2,2,0,0,0-.57,1.21L4,16.91a1,1,0,0,0,.29.8A1,1,0,0,0,5,18ZM15.27,4,18,6.73,16,8.68,13.32,6Zm-8.9,8.91L12,7.32l2.7,2.7-5.6,5.6-3,.28Z"/></g></svg></a>
{% endif %}

View file

@ -342,7 +342,7 @@ def show_item_comment(request, id, item_id):
collection = get_object_or_404(Collection, pk=id)
item = CollectionItem.objects.get(id=item_id)
editable = collection.is_editable_by(request.user)
return render(request, 'show_item_comment.html', {'collection': collection, 'item': item, 'editable': editable})
return render(request, 'show_item_comment.html', {'collection': collection, 'collectionitem': item, 'editable': editable})
@login_required
def update_item_comment(request, id, item_id):
@ -354,9 +354,9 @@ def update_item_comment(request, id, item_id):
if request.method == 'POST':
item.comment = request.POST.get('comment', default='')
item.save()
return render(request, 'show_item_comment.html', {'collection': collection, 'item': item, 'editable': True})
return render(request, 'show_item_comment.html', {'collection': collection, 'collectionitem': item, 'editable': True})
else:
return render(request, 'edit_item_comment.html', {'collection': collection, 'item': item})
return render(request, 'edit_item_comment.html', {'collection': collection, 'collectionitem': item})
return retrieve_entity_list(request, id)
return HttpResponseBadRequest()

View file

@ -13,7 +13,7 @@ from django.conf import settings
RE_HTML_TAG = re.compile(r"<[^>]*>")
MAX_TOP_TAGS = 5
# abstract base classes
###################################
@ -119,6 +119,10 @@ class Entity(models.Model):
"""
raise NotImplementedError("Subclass should implement this method.")
@property
def top_tags(self):
return self.get_tags_manager().values('content').annotate(tag_frequency=Count('content')).order_by('-tag_frequency')[:MAX_TOP_TAGS]
def get_marks_manager(self):
"""
Normally this won't be used.

View file

@ -1,5 +1,5 @@
$(document).ready( function() {
let render = function() {
let ratingLabels = $(".rating-star");
$(ratingLabels).each( function(index, value) {
let ratingScore = $(this).data("rating-score") / 2;
@ -8,5 +8,9 @@ $(document).ready( function() {
readOnly: true
});
});
};
document.body.addEventListener('htmx:load', function(evt) {
render();
});
render();
});

View file

@ -1,3 +1,19 @@
.collection-item-position-edit {
float: right;
}
.collection-item-position-edit a {
cursor: pointer;
color: #ccc;
}
.action-icon svg {
cursor: pointer;
fill: #ccc;
height: 12px;
vertical-align: text-bottom;
}
/***** MODAL DIALOG ****/
#modal {
/* Underlay covers entire screen. */
@ -25,7 +41,9 @@
required if you want to click to dismiss the popup */
position: absolute;
z-index: -1;
top:0px;
.collection_list_position_edittop:0px;
bottom:0px;
left: 0px;
right: 0px;

View file

@ -0,0 +1,9 @@
{% if item.category_name|lower == 'book' %}
{% include "partial/list_item_book.html" with book=item %}
{% elif item.category_name|lower == 'movie' %}
{% include "partial/list_item_movie.html" with movie=item %}
{% elif item.category_name|lower == 'game' %}
{% include "partial/list_item_game.html" with game=item %}
{% elif item.category_name|lower == 'album' or item.category_name|lower == 'song' %}
{% include "partial/list_item_music.html" with music=item %}
{% endif %}

View file

@ -0,0 +1,117 @@
{% load thumb %}
{% load highlight %}
{% load i18n %}
{% load l10n %}
<li class="entity-list__entity">
<div class="entity-list__entity-img-wrapper">
<a href="{% url 'books:retrieve' book.id %}">
<img src="{{ book.cover|thumb:'normal' }}" alt="" class="entity-list__entity-img">
</a>
</div>
<div class="entity-list__entity-text">
{% if editable %}
<div class="collection-item-position-edit">
{% if not forloop.first %}
<a hx-target=".entity-list" hx-post="{% url 'collection:move_up_item' form.instance.id collectionitem.id %}"></a>
{% endif %}
{% if not forloop.last %}
<a hx-target=".entity-list" hx-post="{% url 'collection:move_down_item' form.instance.id collectionitem.id %}"></a>
{% endif %}
<a hx-target=".entity-list" hx-post="{% url 'collection:delete_item' form.instance.id collectionitem.id %}"></a>
</div>
{% endif %}
<div class="entity-list__entity-title">
<a href="{% url 'books:retrieve' book.id %}" class="entity-list__entity-link">
{% if request.GET.q %}
{{ book.title | highlight:request.GET.q }}
{% else %}
{{ book.title }}
{% endif %}
</a>
{% if not request.GET.c or not request.GET.c in categories %}
<span class="entity-list__entity-category">[{{book.verbose_category_name}}]</span>
{% endif %}
<a href="{{ book.source_url }}">
<span class="source-label source-label__{{ book.source_site }}">{{ book.get_source_site_display }}</span>
</a>
</div>
{% if book.rating %}
<div class="rating-star entity-list__rating-star" data-rating-score="{{ book.rating | floatformat:"0" }}"></div>
<span class="entity-list__rating-score rating-score">{{ book.rating }}</span>
{% else %}
<div class="entity-list__rating entity-list__rating--empty"> {% trans '暂无评分' %}</div>
{% endif %}
<span class="entity-list__entity-info">
{% if book.pub_year %}
{{ book.pub_year }}{% trans '年' %}
{% if book.pub_month %}
{{book.pub_month }}{% trans '月' %}
{% endif %}/
{% endif %}
{% if book.author %}
{% trans '作者' %}:
{% for author in book.author %}
{% if request.GET.q %}
{{ author | highlight:request.GET.q }}
{% else %}
{{ author }}
{% endif %}
{% if not forloop.last %},{% endif %}
{% endfor %}/
{% endif %}
{% if book.translator %}
{% trans '译者' %}:
{% for translator in book.translator %}
{% if request.GET.q %}
{{ translator | highlight:request.GET.q }}
{% else %}
{{ translator }}
{% endif %}
{% if not forloop.last %},{% endif %}
{% endfor %}/
{% endif %}
{% if book.orig_title %}
{% trans '原名' %}:
{% if request.GET.q %}
{{ book.orig_title | highlight:request.GET.q }}
{% else %}
{{ book.orig_title }}
{% endif %}
{% endif %}
</span>
<p class="entity-list__entity-brief">
{{ book.brief }}
</p>
<div class="tag-collection">
{% for tag_dict in book.top_tags %}
<span class="tag-collection__tag">
<a href="{% url 'common:search' %}?tag={{ tag_dict.content }}">{{ tag_dict.content }}</a>
</span>
{% endfor %}
</div>
{% if collectionitem %}
<div class="clearfix"></div>
<div class="dividing-line dividing-line--dashed"></div>
<div class="entity-marks" style="margin-bottom: 0;">
<ul class="entity-marks__mark-list">
<li class="entity-marks__mark">
<p class="entity-marks__mark-content" hx-target="this" hx-swap="innerHTML">
{% include "show_item_comment.html" %}
</p>
</li>
</ul>
</div>
{% endif %}
</div>
</li>

View file

@ -0,0 +1,102 @@
{% load thumb %}
{% load highlight %}
{% load i18n %}
{% load l10n %}
<li class="entity-list__entity">
<div class="entity-list__entity-img-wrapper">
<a href="{% url 'games:retrieve' game.id %}">
<img src="{{ game.cover|thumb:'normal' }}" alt="" class="entity-list__entity-img">
</a>
</div>
<div class="entity-list__entity-text">
{% if editable %}
<div class="collection-item-position-edit">
{% if not forloop.first %}
<a hx-target=".entity-list" hx-post="{% url 'collection:move_up_item' form.instance.id collectionitem.id %}"></a>
{% endif %}
{% if not forloop.last %}
<a hx-target=".entity-list" hx-post="{% url 'collection:move_down_item' form.instance.id collectionitem.id %}"></a>
{% endif %}
<a hx-target=".entity-list" hx-post="{% url 'collection:delete_item' form.instance.id collectionitem.id %}"></a>
</div>
{% endif %}
<div class="entity-list__entity-title">
<a href="{% url 'games:retrieve' game.id %}" class="entity-list__entity-link">
{% if request.GET.q %}
{{ game.title | highlight:request.GET.q }}
{% else %}
{{ game.title }}
{% endif %}
</a>
{% if not request.GET.c or not request.GET.c in categories %}
<span class="entity-list__entity-category">[{{item.verbose_category_name}}]</span>
{% endif %}
<a href="{{ game.source_url }}">
<span class="source-label source-label__{{ game.source_site }}">{{ game.get_source_site_display }}</span>
</a>
</div>
{% if game.rating %}
<div class="rating-star entity-list__rating-star" data-rating-score="{{ game.rating | floatformat:"0" }}"></div>
<span class="entity-list__rating-score rating-score">{{ game.rating }}</span>
{% else %}
<div class="entity-list__rating entity-list__rating--empty"> {% trans '暂无评分' %}</div>
{% endif %}
<span class="entity-list__entity-info entity-list__entity-info--full-length">
{% if game.other_title %}{% trans '别名' %}:
{% for other_title in game.other_title %}
{{ other_title }}{% if not forloop.last %} {% endif %}
{% endfor %}/
{% endif %}
{% if game.developer %}{% trans '开发商' %}:
{% for developer in game.developer %}
{{ developer }}{% if not forloop.last %} {% endif %}
{% endfor %}/
{% endif %}
{% if game.genre %}{% trans '类型' %}:
{% for genre in game.genre %}
{{ genre }}{% if not forloop.last %} {% endif %}
{% endfor %}/
{% endif %}
{% if game.platform %}{% trans '平台' %}:
{% for platform in game.platform %}
{{ platform }}{% if not forloop.last %} {% endif %}
{% endfor %}
{% endif %}
</span>
<p class="entity-list__entity-brief">
{{ game.brief }}
</p>
<div class="tag-collection">
{% for tag_dict in game.top_tags %}
<span class="tag-collection__tag">
<a href="{% url 'common:search' %}?tag={{ tag_dict.content }}">{{ tag_dict.content }}</a>
</span>
{% endfor %}
</div>
{% if collectionitem %}
<div class="clearfix"></div>
<div class="dividing-line dividing-line--dashed"></div>
<div class="entity-marks" style="margin-bottom: 0;">
<ul class="entity-marks__mark-list">
<li class="entity-marks__mark">
<p class="entity-marks__mark-content" hx-target="this" hx-swap="innerHTML">
{% include "show_item_comment.html" %}
</p>
</li>
</ul>
</div>
{% endif %}
</div>
</li>

View file

@ -0,0 +1,116 @@
{% load thumb %}
{% load highlight %}
{% load i18n %}
{% load l10n %}
{% load humanize %}
<li class="entity-list__entity">
<div class="entity-list__entity-img-wrapper">
<a href="{% url 'movies:retrieve' movie.id %}">
<img src="{{ movie.cover|thumb:'normal' }}" alt="" class="entity-list__entity-img">
</a>
</div>
<div class="entity-list__entity-text">
{% if editable %}
<div class="collection-item-position-edit">
{% if not forloop.first %}
<a hx-target=".entity-list" hx-post="{% url 'collection:move_up_item' form.instance.id collectionitem.id %}"></a>
{% endif %}
{% if not forloop.last %}
<a hx-target=".entity-list" hx-post="{% url 'collection:move_down_item' form.instance.id collectionitem.id %}"></a>
{% endif %}
<a hx-target=".entity-list" hx-post="{% url 'collection:delete_item' form.instance.id collectionitem.id %}"></a>
</div>
{% endif %}
<div class="entity-list__entity-title">
<a href="{% url 'movies:retrieve' movie.id %}" class="entity-list__entity-link">
{% if movie.season %}
{% if request.GET.q %}
{{ movie.title | highlight:request.GET.q }} {% trans '第' %}{{ movie.season|apnumber }}{% trans '季' %}
{{ movie.orig_title | highlight:request.GET.q }} Season {{ movie.season }}
{% if movie.year %}({{ movie.year }}){% endif %}
{% else %}
{{ movie.title }} {% trans '第' %}{{ movie.season|apnumber }}{% trans '季' %}
{{ movie.orig_title }} Season {{ movie.season }}
{% if movie.year %}({{ movie.year }}){% endif %}
{% endif %}
{% else %}
{% if request.GET.q %}
{{ movie.title | highlight:request.GET.q }} {{ movie.orig_title | highlight:request.GET.q }}
{% if movie.year %}({{ movie.year }}){% endif %}
{% else %}
{{ movie.title }} {{ movie.orig_title }}
{% if movie.year %}({{ movie.year }}){% endif %}
{% endif %}
{% endif %}
</a>
{% if not request.GET.c or not request.GET.c in categories %}
<span class="entity-list__entity-category">[{{movie.verbose_category_name}}]</span>
{% endif %}
<a href="{{ movie.source_url }}">
<span class="source-label source-label__{{ movie.source_site }}">{{ movie.get_source_site_display }}</span>
</a>
</div>
{% if movie.rating %}
<div class="rating-star entity-list__rating-star" data-rating-score="{{ movie.rating | floatformat:"0" }}"></div>
<span class="entity-list__rating-score rating-score">{{ movie.rating }}</span>
{% else %}
<div class="entity-list__rating entity-list__rating--empty"> {% trans '暂无评分' %}</div>
{% endif %}
<span class="entity-list__entity-info ">
{% if movie.director %}{% trans '导演' %}:
{% for director in movie.director %}
{{ director }}{% if not forloop.last %} {% endif %}
{% endfor %}/
{% endif %}
{% if movie.genre %}{% trans '类型' %}:
{% for genre in movie.get_genre_display %}
{{ genre }}{% if not forloop.last %} {% endif %}
{% endfor %}/
{% endif %}
</span>
<span class="entity-list__entity-info entity-list__entity-info--full-length">
{% if movie.actor %}{% trans '主演' %}:
{% for actor in movie.actor %}
<span {% if forloop.counter > 5 %}style="display: none;" {% endif %}>{{ actor }}</span>
{% if forloop.counter <= 5 %}
{% if not forloop.counter == 5 and not forloop.last %} {% endif %}
{% endif %}
{% endfor %}
{% endif %}
</span>
<p class="entity-list__entity-brief">
{{ movie.brief }}
</p>
<div class="tag-collection">
{% for tag_dict in movie.top_tags %}
<span class="tag-collection__tag">
<a href="{% url 'common:search' %}?tag={{ tag_dict.content }}">{{ tag_dict.content }}</a>
</span>
{% endfor %}
</div>
{% if collectionitem %}
<div class="clearfix"></div>
<div class="dividing-line dividing-line--dashed"></div>
<div class="entity-marks" style="margin-bottom: 0;">
<ul class="entity-marks__mark-list">
<li class="entity-marks__mark">
<p class="entity-marks__mark-content" hx-target="this" hx-swap="innerHTML">
{% include "show_item_comment.html" %}
</p>
</li>
</ul>
</div>
{% endif %}
</div>
</li>

View file

@ -0,0 +1,127 @@
{% load thumb %}
{% load highlight %}
{% load i18n %}
{% load l10n %}
<li class="entity-list__entity">
<div class="entity-list__entity-img-wrapper">
{% if music.category_name|lower == 'album' %}
<a href="{% url 'music:retrieve_album' music.id %}">
<img src="{{ music.cover|thumb:'normal' }}" alt="" class="entity-list__entity-img">
</a>
{% elif music.category_name|lower == 'song' %}
<a href="{% url 'music:retrieve_song' music.id %}">
<img src="{{ music.cover|thumb:'normal' }}" alt="" class="entity-list__entity-img">
</a>
{% endif %}
</div>
<div class="entity-list__entity-text">
{% if editable %}
<div class="collection-item-position-edit">
{% if not forloop.first %}
<a hx-target=".entity-list" hx-post="{% url 'collection:move_up_item' form.instance.id collectionitem.id %}"></a>
{% endif %}
{% if not forloop.last %}
<a hx-target=".entity-list" hx-post="{% url 'collection:move_down_item' form.instance.id collectionitem.id %}"></a>
{% endif %}
<a hx-target=".entity-list" hx-post="{% url 'collection:delete_item' form.instance.id collectionitem.id %}"></a>
</div>
{% endif %}
<div class="entity-list__entity-title">
{% if music.category_name|lower == 'album' %}
<a href="{% url 'music:retrieve_album' music.id %}" class="entity-list__entity-link">
{% if request.GET.q %}
{{ music.title | highlight:request.GET.q }}
{% else %}
{{ music.title }}
{% endif %}
</a>
{% elif music.category_name|lower == 'song' %}
<a href="{% url 'music:retrieve_song' music.id %}" class="entity-list__entity-link">
{% if request.GET.q %}
{{ music.title | highlight:request.GET.q }}
{% else %}
{{ music.title }}
{% endif %}
</a>
{% endif %}
{% if not request.GET.c or not request.GET.c in categories %}
<span class="entity-list__entity-category">[{{music.verbose_category_name}}]</span>
{% endif %}
<a href="{{ music.source_url }}">
<span class="source-label source-label__{{ music.source_site }}">{{ music.get_source_site_display }}</span>
</a>
</div>
{% if music.rating %}
<div class="rating-star entity-list__rating-star" data-rating-score="{{ music.rating | floatformat:"0" }}"></div>
<span class="entity-list__rating-score rating-score">{{ music.rating }}</span>
{% else %}
<div class="entity-list__rating entity-list__rating--empty"> {% trans '暂无评分' %}</div>
{% endif %}
<span class="entity-list__entity-info ">
{% if music.artist %}{% trans '艺术家' %}:
{% for artist in music.artist %}
<span>{{ artist }}</span>
{% if not forloop.last %} {% endif %}
{% endfor %}
{% endif %}
{% if music.genre %}/ {% trans '流派' %}:
{{ music.genre }}
{% endif %}
{% if music.release_date %}/ {% trans '发行日期' %}:
{{ music.release_date }}
{% endif %}
</span>
<span class="entity-list__entity-info entity-list__entity-info--full-length">
</span>
{% if music.brief %}
<p class="entity-list__entity-brief">
{{ music.brief }}
</p>
{% elif music.category_name|lower == 'album' %}
<p class="entity-list__entity-brief">
{% trans '曲目:' %}{{ music.track_list }}
</p>
{% else %}
<!-- song -->
<p class="entity-list__entity-brief">
{% trans '所属专辑:' %}{{ music.album }}
</p>
{% endif %}
<div class="tag-collection">
{% for tag_dict in music.top_tags %}
<span class="tag-collection__tag">
<a href="{% url 'common:search' %}?tag={{ tag_dict.content }}">{{ tag_dict.content }}</a>
</span>
{% endfor %}
</div>
{% if collectionitem %}
<div class="clearfix"></div>
<div class="dividing-line dividing-line--dashed"></div>
<div class="entity-marks" style="margin-bottom: 0;">
<ul class="entity-marks__mark-list">
<li class="entity-marks__mark">
<p class="entity-marks__mark-content" hx-target="this" hx-swap="innerHTML">
{% include "show_item_comment.html" %}
</p>
</li>
</ul>
</div>
{% endif %}
</div>
</li>