add item to list from detail page

This commit is contained in:
Your Name 2022-01-16 00:51:32 -05:00
parent 2a371648d0
commit 267e329d3f
14 changed files with 286 additions and 22 deletions

View file

@ -1,9 +1,12 @@
{% load static %}
{% load i18n %}
{% load l10n %}
{% load humanize %}
{% load admin_url %}
{% load mastodon %}
{% load oauth_token %}
{% load truncate %}
{% load strip_scheme %}
{% load thumb %}
<!DOCTYPE html>
<html lang="en">
@ -26,10 +29,13 @@
<title>{{ site_name }} - {% trans '书籍详情' %} | {{ book.title }}</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="https://unpkg.com/hyperscript.org@0.9.3"></script>
<script src="https://unpkg.com/htmx.org@1.6.1"></script>
<script src="{% static 'lib/js/rating-star.js' %}"></script>
<script src="{% static 'js/detail.js' %}"></script>
<link rel="stylesheet" href="{% static 'css/boofilsic.min.css' %}">
<link rel="stylesheet" href="{% static 'lib/css/rating-star.css' %}">
<link rel="stylesheet" href="{% static 'lib/css/neo.css' %}">
</head>
<body>
@ -323,6 +329,9 @@
<a href="{% url 'collection:retrieve' c.id %}">{{ c.title }}</a>
</p>
{% endfor %}
<div class="action-panel__button-group action-panel__button-group--center">
<button class="action-panel__button add-to-list" hx-get="{% url 'collection:add_to_list' 'book' book.id %}" hx-target="body" hx-swap="beforeend">{% trans '添加到收藏单' %}</button>
</div>
</div>
</div>
</div>
@ -338,7 +347,6 @@
<div id="modals">
<div class="mark-modal modal">
<div class="mark-modal__head">
{% if not mark %}
<style>
.mark-modal__title::after {
@ -355,12 +363,12 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20">
<polygon
points="20 2.61 17.39 0 10 7.39 2.61 0 0 2.61 7.39 10 0 17.39 2.61 20 10 12.61 17.39 20 20 17.39 12.61 10 20 2.61">
</polygon>
</svg>
</polygon>
</svg>
</span>
</span>
</span>
</div>
<div class="mark-modal__body">
</div>
<div class="mark-modal__body">
<form action="{% url 'books:create_update_mark' %}" method="post">
{{ mark_form.media }}
{% csrf_token %}

View file

@ -35,9 +35,12 @@ class Collection(UserOwnedEntity):
html = markdown(self.description)
return RE_HTML_TAG.sub(' ', html)
def has_item(self, item):
return len(list(filter(lambda i: i.item == item, self.collectionitem_list))) > 0
def append_item(self, item, comment=""):
cl = self.collectionitem_list
if item is None or len(list(filter(lambda i: i.item == item, cl))) > 0:
if item is None or self.has_item(item):
return None
else:
i = CollectionItem(collection=self, position=cl[-1].position + 1 if len(cl) else 1, comment=comment)

View file

@ -0,0 +1,44 @@
{% load static %}
{% load i18n %}
{% load l10n %}
{% load humanize %}
{% load admin_url %}
{% load mastodon %}
{% load oauth_token %}
{% load truncate %}
{% load highlight %}
{% load thumb %}
<div id="modal" _="on closeModal add .closing then wait for animationend then remove me">
<div class="modal-underlay" _="on click trigger closeModal"></div>
<div class="modal-content">
<div class="add-to-list-modal__head">
<span class="add-to-list-modal__title">{% trans '添加到收藏单' %}</span>
<span class="add-to-list-modal__close-button modal-close" _="on click trigger closeModal">
<span class="icon-cross">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20">
<polygon
points="20 2.61 17.39 0 10 7.39 2.61 0 0 2.61 7.39 10 0 17.39 2.61 20 10 12.61 17.39 20 20 17.39 12.61 10 20 2.61">
</polygon>
</svg>
</span>
</span>
</div>
<div class="add-to-list-modal__body">
<form action="/collections/add_to_list/{{ type }}/{{ id }}/" method="post">
{% csrf_token %}
<select name="collection_id">
{% for collection in collections %}
<option value="{{ collection.id }}">{{ collection.title }}{% if collection.visibility > 0 %}🔒{% endif %}</option>
{% endfor %}
</select>
<div>
<textarea type="text" name="comment" placeholder="条目备注"></textarea>
</div>
<div class="add-to-list-modal__confirm-button">
<input type="submit" class="button float-right" value="{% trans '提交' %}">
</div>
</form>
</div>
</div>
</div>

View file

@ -17,5 +17,7 @@ urlpatterns = [
path('<int:id>/move_up_item/<int:item_id>', move_up_item, name='move_up_item'),
path('<int:id>/move_down_item/<int:item_id>', move_down_item, name='move_down_item'),
path('with/<str:type>/<int:id>/', list_with, name='list_with'),
path('add_to_list/<str:type>/<int:id>/', add_to_list, name='add_to_list'),
# TODO: tag
]

View file

@ -343,3 +343,38 @@ def move_down_item(request, id, item_id):
@login_required
def list_with(request, type, id):
pass
def get_entity_by_type_id(type, id):
mapping = {
'movie': Movie,
'book': Book,
'game': Game,
'album': Album,
'song': Song,
}
cls = mapping.get(type)
if cls is not None:
return cls.objects.get(id=id)
return None
@login_required
def add_to_list(request, type, id):
item = get_entity_by_type_id(type, id)
if request.method == 'GET':
queryset = Collection.objects.filter(owner=request.user)
return render(
request,
'add_to_list.html',
{
'type': type,
'id': id,
'item': item,
'collections': queryset,
}
)
else:
collection = Collection.objects.filter(owner=request.user, id=request.POST.get('collection_id')).first()
collection.append_item(item, request.POST.get('comment'))
return HttpResponseRedirect(request.META.get('HTTP_REFERER'))

View file

@ -1058,8 +1058,46 @@ select::placeholder {
word-break: break-all;
}
.add-to-list-modal {
z-index: 2;
display: none;
position: fixed;
width: 500px;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background-color: #f7f7f7;
padding: 20px 20px 10px 20px;
color: #606c76;
}
.add-to-list-modal .add-to-list-modal__head {
margin-bottom: 20px;
}
.add-to-list-modal .add-to-list-modal__head::after {
content: ' ';
clear: both;
display: table;
}
.add-to-list-modal .add-to-list-modal__title {
font-weight: bold;
font-size: 1.2em;
float: left;
}
.add-to-list-modal .add-to-list-modal__close-button {
float: right;
cursor: pointer;
}
.add-to-list-modal .add-to-list-modal__confirm-button {
float: right;
}
@media (max-width: 575.98px) {
.mark-modal, .confirm-modal, .announcement-modal {
.mark-modal, .confirm-modal, .announcement-modal .add-to-list-modal {
width: 100%;
}
}
@ -1164,10 +1202,6 @@ select::placeholder {
width: 100%;
}
.tools-section-wrapper input, .tools-section-wrapperl select {
width: unset;
}
.entity-list .entity-list__title {
margin-bottom: 20px;
}
@ -2433,3 +2467,7 @@ select::placeholder {
.tag-input input {
flex-grow: 1;
}
.tools-section-wrapper input, .tools-section-wrapper select {
width: unset;
}

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,110 @@
/***** MODAL DIALOG ****/
#modal {
/* Underlay covers entire screen. */
position: fixed;
top:0px;
bottom: 0px;
left:0px;
right:0px;
background-color:rgba(0,0,0,0.5);
z-index:1000;
/* Flexbox centers the .modal-content vertically and horizontally */
display:flex;
flex-direction:column;
align-items:center;
/* Animate when opening */
animation-name: fadeIn;
animation-duration:150ms;
animation-timing-function: ease;
}
#modal > .modal-underlay {
/* underlay takes up the entire viewport. This is only
required if you want to click to dismiss the popup */
position: absolute;
z-index: -1;
top:0px;
bottom:0px;
left: 0px;
right: 0px;
}
#modal > .modal-content {
/* Position visible dialog near the top of the window */
margin-top:10vh;
/* Sizing for visible dialog */
width:80%;
max-width:600px;
/* Display properties for visible dialog*/
background-color: #f7f7f7;
padding: 20px 20px 10px 20px;
color: #606c76;
/* Animate when opening */
animation-name:zoomIn;
animation-duration:150ms;
animation-timing-function: ease;
}
#modal.closing {
/* Animate when closing */
animation-name: fadeOut;
animation-duration:150ms;
animation-timing-function: ease;
}
#modal.closing > .modal-content {
/* Aniate when closing */
animation-name: zoomOut;
animation-duration:150ms;
animation-timing-function: ease;
}
@keyframes fadeIn {
0% {opacity: 0;}
100% {opacity: 1;}
}
@keyframes fadeOut {
0% {opacity: 1;}
100% {opacity: 0;}
}
@keyframes zoomIn {
0% {transform: scale(0.9);}
100% {transform: scale(1);}
}
@keyframes zoomOut {
0% {transform: scale(1);}
100% {transform: scale(0.9);}
}
#modal .add-to-list-modal__head {
margin-bottom: 20px;
}
#modal .add-to-list-modal__head::after {
content: ' ';
clear: both;
display: table;
}
#modal .add-to-list-modal__title {
font-weight: bold;
font-size: 1.2em;
float: left;
}
#modal .add-to-list-modal__close-button {
float: right;
cursor: pointer;
}
#modal .add-to-list-modal__confirm-button {
float: right;
}

View file

@ -115,10 +115,12 @@
&__content
word-break: break-all
.add-to-list-modal
@include modal
// Small devices (landscape phones, 576px and up)
@media (max-width: $small-devices)
.mark-modal, .confirm-modal, .announcement-modal
.mark-modal, .confirm-modal, .announcement-modal .add-to-list-modal
width: 100%
// Medium devices (tablets, 768px and up)
@media (max-width: $medium-devices)

View file

@ -50,4 +50,7 @@
.tippy-content
.tag-input input
flex-grow: 1
flex-grow: 1
.tools-section-wrapper input, .tools-section-wrapper select
width: unset

View file

@ -24,11 +24,13 @@
<title>{{ site_name }} - {% trans '游戏详情' %} | {{ game.title }}</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="https://unpkg.com/hyperscript.org@0.9.3"></script>
<script src="https://unpkg.com/htmx.org@1.6.1"></script>
<script src="{% static 'lib/js/rating-star.js' %}"></script>
<script src="{% static 'js/detail.js' %}"></script>
<link rel="stylesheet" href="{% static 'css/boofilsic.css' %}">
<link rel="stylesheet" href="{% static 'lib/css/rating-star.css' %}">
<link rel="stylesheet" href="{% static 'lib/css/neo.css' %}">
</head>
<body>
@ -327,6 +329,9 @@
<a href="{% url 'collection:retrieve' c.id %}">{{ c.title }}</a>
</p>
{% endfor %}
<div class="action-panel__button-group action-panel__button-group--center">
<button class="action-panel__button add-to-list" hx-get="{% url 'collection:add_to_list' 'game' game.id %}" hx-target="body" hx-swap="beforeend">{% trans '添加到收藏单' %}</button>
</div>
</div>
</div>
</div>

View file

@ -37,10 +37,13 @@
{% endif %}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="https://unpkg.com/hyperscript.org@0.9.3"></script>
<script src="https://unpkg.com/htmx.org@1.6.1"></script>
<script src="{% static 'lib/js/rating-star.js' %}"></script>
<script src="{% static 'js/detail.js' %}"></script>
<link rel="stylesheet" href="{% static 'css/boofilsic.css' %}">
<link rel="stylesheet" href="{% static 'lib/css/rating-star.css' %}">
<link rel="stylesheet" href="{% static 'lib/css/neo.css' %}">
</head>
<body>
@ -423,6 +426,9 @@
<a href="{% url 'collection:retrieve' c.id %}">{{ c.title }}</a>
</p>
{% endfor %}
<div class="action-panel__button-group action-panel__button-group--center">
<button class="action-panel__button add-to-list" hx-get="{% url 'collection:add_to_list' 'movie' movie.id %}" hx-target="body" hx-swap="beforeend">{% trans '添加到收藏单' %}</button>
</div>
</div>
</div>
</div>

View file

@ -6,6 +6,7 @@
{% load mastodon %}
{% load oauth_token %}
{% load truncate %}
{% load strip_scheme %}
{% load thumb %}
<!DOCTYPE html>
<html lang="en">
@ -23,11 +24,13 @@
<title>{{ site_name }} - {% trans '音乐详情' %} | {{ album.title }}</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="https://unpkg.com/hyperscript.org@0.9.3"></script>
<script src="https://unpkg.com/htmx.org@1.6.1"></script>
<script src="{% static 'lib/js/rating-star.js' %}"></script>
<script src="{% static 'js/detail.js' %}"></script>
<link rel="stylesheet" href="{% static 'css/boofilsic.css' %}">
<link rel="stylesheet" href="{% static 'lib/css/rating-star.css' %}">
<link rel="stylesheet" href="{% static 'lib/css/neo.css' %}">
</head>
<body>
@ -361,6 +364,9 @@
<a href="{% url 'collection:retrieve' c.id %}">{{ c.title }}</a>
</p>
{% endfor %}
<div class="action-panel__button-group action-panel__button-group--center">
<button class="action-panel__button add-to-list" hx-get="{% url 'collection:add_to_list' 'album' album.id %}" hx-target="body" hx-swap="beforeend">{% trans '添加到收藏单' %}</button>
</div>
</div>
</div>
</div>

View file

@ -6,6 +6,7 @@
{% load mastodon %}
{% load oauth_token %}
{% load truncate %}
{% load strip_scheme %}
{% load thumb %}
<!DOCTYPE html>
<html lang="en">
@ -23,11 +24,13 @@
<title>{{ site_name }} - {% trans '音乐详情' %} | {{ song.title }}</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="https://unpkg.com/hyperscript.org@0.9.3"></script>
<script src="https://unpkg.com/htmx.org@1.6.1"></script>
<script src="{% static 'lib/js/rating-star.js' %}"></script>
<script src="{% static 'js/detail.js' %}"></script>
<link rel="stylesheet" href="{% static 'css/boofilsic.css' %}">
<link rel="stylesheet" href="{% static 'lib/css/rating-star.css' %}">
<link rel="stylesheet" href="{% static 'lib/css/neo.css' %}">
</head>
<body>
@ -307,6 +310,9 @@
<a href="{% url 'collection:retrieve' c.id %}">{{ c.title }}</a>
</p>
{% endfor %}
<div class="action-panel__button-group action-panel__button-group--center">
<button class="action-panel__button add-to-list" hx-get="{% url 'collection:add_to_list' 'song' song.id %}" hx-target="body" hx-swap="beforeend">{% trans '添加到收藏单' %}</button>
</div>
</div>
</div>
</div>