restructure css

This commit is contained in:
doubaniux 2020-07-03 15:36:23 +08:00
parent 1a69142d67
commit 265e922517
68 changed files with 5367 additions and 1750 deletions

4
.gitignore vendored
View file

@ -18,8 +18,8 @@ migrations/
*.sqlite3 *.sqlite3
# deployed media and static files # deployed media and static files
media/ /media/
static/ /static/
# log file # log file
log log

View file

@ -86,7 +86,7 @@ if DEBUG:
'NAME': 'test', 'NAME': 'test',
'USER': 'donotban', 'USER': 'donotban',
'PASSWORD': 'donotbansilvousplait', 'PASSWORD': 'donotbansilvousplait',
'HOST': '192.168.238.194', 'HOST': '172.18.99.149',
'OPTIONS': { 'OPTIONS': {
'client_encoding': 'UTF8', 'client_encoding': 'UTF8',
# 'isolation_level': psycopg2.extensions.ISOLATION_LEVEL_DEFAULT, # 'isolation_level': psycopg2.extensions.ISOLATION_LEVEL_DEFAULT,
@ -174,8 +174,8 @@ AUTH_USER_MODEL = 'users.User'
MEDIA_URL = '/media/' MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media/') MEDIA_ROOT = os.path.join(BASE_DIR, 'media/')
CLIENT_ID = 'kEbwT9Je5HsadfNs5Mw6Asht456YlQl54t4sj2_4' CLIENT_ID = 'kEbwT9Je5HHg4FoLx4nb0tNaIrPNs5Mw6AYlQlsj2_4'
CLIENT_SECRET = 'xwmEvlmudLCkBmvdzGf8msdfgsdfggs5di9xnDqeVLrcKSg' CLIENT_SECRET = 'xwmEvlmudLCkBmvdzGf8m41Ug5o5di9xnDqeVLrcKSg'
# Path to save report related images, ends without slash # Path to save report related images, ends without slash
REPORT_MEDIA_PATH_ROOT = 'report/' REPORT_MEDIA_PATH_ROOT = 'report/'
@ -190,7 +190,6 @@ MASTODON_DOMAIN_NAME = 'donotban.com'
MASTODON_TIMEOUT = 30 MASTODON_TIMEOUT = 30
# Emoji code in mastodon # Emoji code in mastodon
# note the white spaces
STAR_SOLID = ':star_solid:' STAR_SOLID = ':star_solid:'
STAR_HALF = ':star_half:' STAR_HALF = ':star_half:'
STAR_EMPTY = ':star_empty:' STAR_EMPTY = ':star_empty:'
@ -205,5 +204,9 @@ LOGIN_URL = '/users/login/'
# Admin site root url # Admin site root url
ADMIN_URL = 'lpLuTqX72Bt2hLfxxRYKeTZdE59Y2hLfpLuTqX72Btx9sXuljYK4tYEmjrHd' ADMIN_URL = 'lpLuTqX72Bt2hLfxxRYKeTZdE59Y2hLfpLuTqX72Btx9sXuljYK4tYEmjrHd'
# Luminati proxy settings
LUMINATI_USERNAME = '***REMOVED***'
LUMINATI_PASSWORD = '***REMOVED***'
# https://django-debug-toolbar.readthedocs.io/en/latest/ # https://django-debug-toolbar.readthedocs.io/en/latest/
# maybe benchmarking before deployment # maybe benchmarking before deployment

View file

@ -5,6 +5,7 @@ from django.utils.translation import gettext_lazy as _
from .models import Book, BookMark, BookReview from .models import Book, BookMark, BookReview
from common.models import MarkStatusEnum from common.models import MarkStatusEnum
from common.forms import RadioBooleanField, RatingValidator from common.forms import RadioBooleanField, RatingValidator
from common.forms import PreviewImageInput
def BookMarkStatusTranslator(status): def BookMarkStatusTranslator(status):
@ -59,13 +60,13 @@ class BookForm(forms.ModelForm):
'brief': _("简介"), 'brief': _("简介"),
'other_info': _("其他信息"), 'other_info': _("其他信息"),
} }
from common.forms import ImageInput
widgets = { widgets = {
'author': forms.TextInput(attrs={'placeholder': _("多个作者使用英文逗号分隔")}), 'author': forms.TextInput(attrs={'placeholder': _("多个作者使用英文逗号分隔")}),
'translator': forms.TextInput(attrs={'placeholder': _("多个译者使用英文逗号分隔")}), 'translator': forms.TextInput(attrs={'placeholder': _("多个译者使用英文逗号分隔")}),
'other_info': KeyValueInput(), 'other_info': KeyValueInput(),
# 'cover': forms.FileInput(), # 'cover': forms.FileInput(),
'cover': ImageInput(), 'cover': PreviewImageInput(),
} }
def clean_isbn(self): def clean_isbn(self):
@ -108,7 +109,7 @@ class BookMarkForm(forms.ModelForm):
'text': _("短评"), 'text': _("短评"),
} }
widgets = { widgets = {
'book': forms.Select(attrs={"hidden": ""}), 'book': forms.TextInput(attrs={"hidden": ""}),
'text': forms.Textarea(attrs={"placeholder": _("最多只能写500字哦~")}), 'text': forms.Textarea(attrs={"placeholder": _("最多只能写500字哦~")}),
} }
@ -141,7 +142,7 @@ class BookReviewForm(forms.ModelForm):
'share_to_mastodon': _("分享到长毛象") 'share_to_mastodon': _("分享到长毛象")
} }
widgets = { widgets = {
'book': forms.Select(attrs={"hidden": ""}), 'book': forms.TextInput(attrs={"hidden": ""}),
} }

View file

@ -9,38 +9,23 @@
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<!-- <meta name="viewport" content="width=device-width, initial-scale=1.0"> --> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{% trans 'Nicedb - ' %}{{ title }}</title> <title>{% trans 'Nicedb - ' %}{{ title }}</title>
<script src="https://cdn.staticfile.org/jquery/3.5.0/jquery.min.js"></script> <script src="https://cdn.staticfile.org/jquery/3.5.0/jquery.min.js"></script>
<script src="{% static 'js/create_update.js' %}"></script> <!-- <link rel="stylesheet" href="{% static 'lib/css/milligram.css' %}"> -->
<link rel="stylesheet" href="{% static 'lib/css/milligram.css' %}"> <!-- <link rel="stylesheet" href="{% static 'css/boofilsic_edit.css' %}"> -->
<link rel="stylesheet" href="{% static 'css/boofilsic_edit.css' %}"> <link rel="stylesheet" href="{% static 'css/boofilsic.css' %}">
</head> </head>
<body> <body>
<div id="page-wrapper"> <div id="page-wrapper">
<div id="content-wrapper"> <div id="content-wrapper">
<section id="navbar" class="navbar"> {% include "partial/_navbar.html" %}
<div class="container">
<nav class="clearfix">
<a href="{% url 'common:home' %}">
<img src="{% static 'img/logo.svg' %}" alt="" class="logo">
</a>
<h4 class="nav-title">{{ title }}</h4>
<a class="nav-link" id="logoutLink" href="{% url 'users:logout' %}">{% trans '登出' %}</a>
<a class="nav-link" href="{% url 'common:home' %}">{% trans '主页' %}</a>
{% if user.is_staff %}
<a class="nav-link" href="{% admin_url %}">{% trans '后台' %}</a>
{% endif %}
</nav>
</div>
</section>
<section id="content" class="container"> <section id="content" class="container">
<div class="row"> <div class="grid">
<div id="main"> <div class="single-section-wrapper" id="main">
<form action="{{ submit_url }}" method="post" enctype="multipart/form-data"> <form class="entity-form" action="{{ submit_url }}" method="post" enctype="multipart/form-data">
{% csrf_token %} {% csrf_token %}
{{ form }} {{ form }}
<input class="button" type="submit" value="{% trans '提交' %}"> <input class="button" type="submit" value="{% trans '提交' %}">
@ -49,11 +34,7 @@
</section> </section>
</div> </div>
<footer class="container"> {% include "partial/_footer.html" %}
<a href="https://donotban.com/@whitiewhite">去长毛象向作者提意见</a>
<a href="https://github.com/doubaniux/boofilsic/issues">报告错误</a>
<a href="https://github.com/doubaniux/boofilsic" id="githubLink">Github</a>
</footer>
</div> </div>
@ -72,6 +53,10 @@
location.href = "{% url 'common:search' %}" + "?q=" + q; location.href = "{% url 'common:search' %}" + "?q=" + q;
} }
}); });
// mark required
$("#content input[required]").each(function () {
$(this).prev().prepend("*");
})
</script> </script>
</body> </body>

View file

@ -9,44 +9,34 @@
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<!-- <meta name="viewport" content="width=device-width, initial-scale=1.0"> --> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{% trans 'Nicedb - ' %}{{ title }}</title> <title>{% trans 'Nicedb - ' %}{{ title }}</title>
<script src="https://cdn.staticfile.org/jquery/3.5.0/jquery.min.js"></script> <script src="https://cdn.staticfile.org/jquery/3.5.0/jquery.min.js"></script>
<script src="{% static 'js/create_update_review.js' %}"></script> <script src="{% static 'js/create_update_review.js' %}"></script>
<script src="{% static 'lib/js/rating-star.js' %}"></script> <script src="{% static 'lib/js/rating-star.js' %}"></script>
<link rel="stylesheet" href="{% static 'lib/css/rating-star.css' %}"> <link rel="stylesheet" href="{% static 'lib/css/rating-star.css' %}">
<link rel="stylesheet" href="{% static 'lib/css/milligram.css' %}"> <link rel="stylesheet" href="{% static 'css/boofilsic.css' %}">
<link rel="stylesheet" href="{% static 'css/boofilsic_edit.css' %}"> <!-- <link rel="stylesheet" href="{% static 'css/boofilsic_edit.css' %}"> -->
<!-- <link rel="stylesheet" href="{% static 'lib/css/milligram.css' %}"> -->
</head> </head>
<body> <body>
<div id="page-wrapper"> <div id="page-wrapper">
<div id="content-wrapper"> <div id="content-wrapper">
<section id="navbar" class="navbar"> {% include "partial/_navbar.html" %}
<div class="container">
<nav class="clearfix">
<a href="{% url 'common:home' %}">
<img src="{% static 'img/logo.svg' %}" alt="" class="logo">
</a>
<h4 class="nav-title">{{ title }}</h4>
<a class="nav-link" id="logoutLink" href="{% url 'users:logout' %}">{% trans '登出' %}</a>
<a class="nav-link" href="{% url 'common:home' %}">{% trans '主页' %}</a>
{% if user.is_staff %}
<a class="nav-link" href="{% admin_url %}">{% trans '后台' %}</a>
{% endif %}
</nav>
</div>
</section>
<section id="content" class="container"> <section id="content">
<div class="row"> <div class="grid">
<div id="main"> <div class="single-section-wrapper">
<div class="item-card clearfix"> <div class="entity-card entity-card--horizontal">
<img src="{{ book.cover.url }}" alt="" class="item-image float-left"> <div class="entity-card__img-wrapper">
<div class="item-info float-left"> <a href="{% url 'books:retrieve' book.id %}">
<img src="{{ book.cover.url }}" alt="" class="item-image float-left">
</a>
</div>
<div class="entity-card__info-wrapper entity-card__info-wrapper--horizontal">
<div class="item-title"><a href="{% url 'books:retrieve' book.id %}">{{ book.title }}</a></div> <h5 class="entity-card__title"><a href="{% url 'books:retrieve' book.id %}">{{ book.title }}</a></h5>
<div>{% if book.isbn %}{% trans 'ISBN' %}{{ book.isbn }}{% endif %}</div> <div>{% if book.isbn %}{% trans 'ISBN' %}{{ book.isbn }}{% endif %}</div>
<div>{% if book.author %}{% trans '作者:' %} <div>{% if book.author %}{% trans '作者:' %}
{% for author in book.author %} {% for author in book.author %}
@ -57,35 +47,38 @@
<div>{%if book.pub_year %}{% trans '出版时间:' %}{{ book.pub_year }}{% trans '年' %}{% if book.pub_month %}{{ book.pub_month }}{% trans '月' %}{% endif %}{% endif %}</div> <div>{%if book.pub_year %}{% trans '出版时间:' %}{{ book.pub_year }}{% trans '年' %}{% if book.pub_month %}{{ book.pub_month }}{% trans '月' %}{% endif %}{% endif %}</div>
{% if book.rating %} {% if book.rating %}
<span class="rating-star" data-rating-score="{{ book.rating | floatformat:"0" }}"> </span> {% trans '评分:' %}<span class="entity-card__rating-star rating-star" data-rating-score="{{ book.rating | floatformat:"0" }}"> </span>
<span class="rating-score"> {{ book.rating }} </span> <span class="entity-card__rating-score rating-score"> {{ book.rating }} </span>
{% endif %} {% endif %}
</div> </div>
</div> </div>
<div class="dividing-line"></div>
<div class="review">
<form action="{{ submit_url }}" method="post"> <form action="{{ submit_url }}" method="post" class="review-form">
{% csrf_token %} {% csrf_token %}
{{ form.book }} {{ form.book }}
{{ form.title.label }}{{ form.title }} <div>
{{ form.title.label }}
</div>
{{ form.title }}
<div class="clearfix"> <div class="clearfix">
<span class="float-left"> <span class="float-left">
{{ form.content.label }} {{ form.content.label }}
</span> </span>
<span class="float-right"> <span class="float-right">
<span class="preview-button">{% trans '预览' %}</span> <span class="review-form__preview-button">{% trans '预览' %}</span>
</span> </span>
</div> </div>
<div id="rawContent"> <div id="rawContent">
{{ form.content }} {{ form.content }}
</div> </div>
<div class="fyi">{% trans '不知道什么是Markdown可以参考' %}<a target="_blank" href="https://www.markdownguide.org/">{% trans '这里' %}</a></div> <div class="review-form__fyi">{% trans '不知道什么是Markdown可以参考' %}<a target="_blank" href="https://www.markdownguide.org/">{% trans '这里' %}</a></div>
<div class="option clearfix"> <div class="review-form__option">
<div class="selection float-left"> <div class="review-form__visibility-radio">
{{ form.is_private.label }}{{ form.is_private }} {{ form.is_private.label }}{{ form.is_private }}
</div> </div>
<div class="float-right"> <div class="review-form__share-checkbox">
{{ form.share_to_mastodon }}{{ form.share_to_mastodon.label }} {{ form.share_to_mastodon }}{{ form.share_to_mastodon.label }}
</div> </div>
</div> </div>
@ -94,16 +87,13 @@
</div> </div>
{{ form.media }} {{ form.media }}
</form> </form>
</div>
</div> </div>
</div>
</section> </section>
</div> </div>
<footer class="container"> {% include "partial/_footer.html" %}
<a href="https://donotban.com/@whitiewhite">去长毛象向作者提意见</a>
<a href="https://github.com/doubaniux/boofilsic/issues">报告错误</a>
<a href="https://github.com/doubaniux/boofilsic" id="githubLink">Github</a>
</footer>
</div> </div>
{% comment %} {% comment %}

View file

@ -9,64 +9,57 @@
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<!-- <meta name="viewport" content="width=device-width, initial-scale=1.0"> --> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{% trans 'Nicedb - 删除图书' %}</title> <title>{% trans 'Nicedb - 删除图书' %}</title>
<script src="https://cdn.staticfile.org/jquery/3.5.0/jquery.min.js"></script> <script src="https://cdn.staticfile.org/jquery/3.5.0/jquery.min.js"></script>
<script src="{% static 'lib/js/rating-star.js' %}"></script> <script src="{% static 'lib/js/rating-star.js' %}"></script>
<script src="{% static 'js/rating-star-readonly.js' %}"></script> <script src="{% static 'js/rating-star-readonly.js' %}"></script>
<link rel="stylesheet" href="{% static 'lib/css/rating-star.css' %}"> <link rel="stylesheet" href="{% static 'lib/css/rating-star.css' %}">
<link rel="stylesheet" href="{% static 'lib/css/milligram.css' %}"> <!-- <link rel="stylesheet" href="{% static 'lib/css/milligram.css' %}"> -->
<link rel="stylesheet" href="{% static 'css/boofilsic_edit.css' %}"> <!-- <link rel="stylesheet" href="{% static 'css/boofilsic_edit.css' %}"> -->
<link rel="stylesheet" href="{% static 'css/boofilsic.css' %}">
</head> </head>
<body> <body>
<div id="page-wrapper"> <div id="page-wrapper">
<div id="content-wrapper"> <div id="content-wrapper">
<section id="navbar" class="navbar"> {% include "partial/_navbar.html" %}
<div class="container">
<nav class="clearfix">
<a href="{% url 'common:home' %}">
<img src="{% static 'img/logo.svg' %}" alt="" class="logo">
</a>
<h4 class="nav-title">{% trans '删除图书' %}</h4>
<a class="nav-link" id="logoutLink" href="{% url 'users:logout' %}">{% trans '登出' %}</a>
<a class="nav-link" href="{% url 'common:home' %}">{% trans '主页' %}</a>
{% if user.is_staff %}
<a class="nav-link" href="{% admin_url %}">{% trans '后台' %}</a>
{% endif %}
</nav>
</div>
</section>
<section id="content" class="container"> <section id="content">
<div class="row"> <div class="grid">
<div id="main"> <div class="single-section-wrapper" id="main">
<h4 class="prompt">{% trans '确认删除这本书吗?相关评论和标记将一并删除。' %}</h4> <h5>{% trans '确认删除这本书吗?相关评论和标记将一并删除。' %}</h5>
<div class="item-card"> <div class="entity-card entity-card--horizontal">
<div class="clearfix"> <div class="entity-card__img-wrapper">
<img src="{{ book.cover.url }}" alt="" class="item-image float-left"> <a href="{% url 'books:retrieve' book.id %}">
<div class="item-info float-left"> <img src="{{ book.cover.url }}" alt="" class="item-image float-left">
<a href="{% url 'books:retrieve' book.id %}"> </a>
<h5 class="item-title"> </div>
{{ book.title }} <div class="entity-card__info-wrapper entity-card__info-wrapper--horizontal">
</h5> <a href="{% url 'books:retrieve' book.id %}">
</a> <h5 class="entity-card__title">
{% if book.rating %} {{ book.title }}
{% trans '评分:' %} </h5>
<span class="rating-star" data-rating-score="{{ book.rating | floatformat:"0" }}"> </a>
</span> {% if book.rating %}
<span class="rating-score">{{ book.rating }} </span> {% trans '评分:' %}<span class="entity-card__rating-star rating-star" data-rating-score="{{ book.rating | floatformat:"0" }}">
{% else %} </span>
<span>{% trans '评分:暂无评分' %}</span> <span class="entity-card__rating-score">{{ book.rating }}</span>
{% endif %} {% else %}
<div>{% trans '最近编辑者:' %}{{ book.last_editor | default:"" }}</div> <span>{% trans '评分:暂无评分' %}</span>
<div>{% trans '上次编辑时间:' %}{{ book.edited_time }}</div> {% endif %}
</div>
{% if book.last_editor %}
<a href="{% url 'users:home' book.last_editor.id %}">
<div>{% trans '最近编辑者:' %}{{ book.last_editor | default:"" }}</div>
</a>
{% endif %}
<div>{% trans '上次编辑时间:' %}{{ book.edited_time }}</div>
</div> </div>
<div class="dividing-line"></div>
</div> </div>
<div class="dividing-line"></div>
<div class="clearfix"> <div class="clearfix">
<form action="{% url 'books:delete' book.id %}" method="post" class="float-right"> <form action="{% url 'books:delete' book.id %}" method="post" class="float-right">
{% csrf_token %} {% csrf_token %}
@ -75,14 +68,11 @@
<button onclick="history.back()" class="button button-clear float-right">{% trans '返回' %}</button> <button onclick="history.back()" class="button button-clear float-right">{% trans '返回' %}</button>
</div> </div>
</div> </div>
</div>
</section> </section>
</div> </div>
<footer class="container"> {% include "partial/_footer.html" %}
<a href="https://donotban.com/@whitiewhite">去长毛象向作者提意见</a>
<a href="https://github.com/doubaniux/boofilsic/issues">报告错误</a>
<a href="https://github.com/doubaniux/boofilsic" id="githubLink">Github</a>
</footer>
</div> </div>

View file

@ -9,90 +9,96 @@
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<!-- <meta name="viewport" content="width=device-width, initial-scale=1.0"> --> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{% trans 'Nicedb - 删除评论' %}</title> <title>{% trans 'Nicedb - 删除评论' %}</title>
<script src="https://cdn.staticfile.org/jquery/3.5.0/jquery.min.js"></script> <script src="https://cdn.staticfile.org/jquery/3.5.0/jquery.min.js"></script>
<link rel="stylesheet" href="{% static 'lib/css/rating-star.css' %}"> <link rel="stylesheet" href="{% static 'lib/css/rating-star.css' %}">
<link rel="stylesheet" href="{% static 'lib/css/milligram.css' %}"> <link rel="stylesheet" href="{% static 'css/boofilsic.css' %}">
<link rel="stylesheet" href="{% static 'css/boofilsic_edit.css' %}"> <!-- <link rel="stylesheet" href="{% static 'lib/css/milligram.css' %}"> -->
<!-- <link rel="stylesheet" href="{% static 'css/boofilsic_edit.css' %}"> -->
</head> </head>
<body> <body>
<div id="page-wrapper"> <div id="page-wrapper">
<div id="content-wrapper"> <div id="content-wrapper">
<section id="navbar" class="navbar"> {% include "partial/_navbar.html" %}
<div class="container">
<nav class="clearfix"> <section id="content">
<a href="{% url 'common:home' %}"> <div class="grid">
<img src="{% static 'img/logo.svg' %}" alt="" class="logo"> <div class="single-section-wrapper" id="main">
</a> <h5>{% trans '确认删除这篇评论吗?' %}</h5>
<h4 class="nav-title">{% trans '删除评论' %}</h4>
<a class="nav-link" id="logoutLink" href="{% url 'users:logout' %}">{% trans '登出' %}</a> <div class="dividing-line"></div>
<a class="nav-link" href="{% url 'common:home' %}">{% trans '主页' %}</a>
{% if user.is_staff %}
<a class="nav-link" href="{% admin_url %}">{% trans '后台' %}</a> <div class="review-head">
{% endif %}
</nav> <h5 class="review-head__title">
</div> {{ review.title }}
</section> </h5>
{% if review.is_private %}
<section id="content" class="container"> <span class="icon-lock"><svg xmlns="http://www.w3.org/2000/svg"
<div class="row"> viewBox="0 0 20 20"><svg xmlns="http://www.w3.org/2000/svg"
<div id="main"> viewBox="0 0 20 20">
<h4 class="prompt">{% trans '确认删除这篇评论吗?' %}</h4> <path
d="M17,8.48h-.73V6.27a6.27,6.27,0,1,0-12.53,0V8.48H3a.67.67,0,0,0-.67.67V19.33A.67.67,0,0,0,3,20H17a.67.67,0,0,0,.67-.67V9.15A.67.67,0,0,0,17,8.48ZM6.42,6.27h0a3.57,3.57,0,0,1,7.14,0h0V8.48H6.42Z" />
<div class="item-card"> </svg></span>
<div class="review"> {% endif %}
<div class="review-head clearfix">
<div class="mark-label float-left"> <div class="review-head__body">
<h4> <div class="review-head__info">
{{ review.title }}
{% if review.is_private %} <a href="{% url 'users:home' review.owner.id %}"
<span class="icon-lock"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><path d="M17,8.48h-.73V6.27a6.27,6.27,0,1,0-12.53,0V8.48H3a.67.67,0,0,0-.67.67V19.33A.67.67,0,0,0,3,20H17a.67.67,0,0,0,.67-.67V9.15A.67.67,0,0,0,17,8.48ZM6.42,6.27h0a3.57,3.57,0,0,1,7.14,0h0V8.48H6.42Z"/></svg></span> class="review-head__owner-link">{{ review.owner.username }}</a>
{% endif %}
</h4> {% if mark %}
<a href="" class="mark-owner-name">{{ review.owner.username }}</a>
{% if mark.rating %}
<span class="mark-time">{{ review.edited_time }}</span> <span class="review-head__rating-star rating-star"
data-rating-score="{{ mark.rating | floatformat:"0" }}"></span>
{% endif %}
{% endif %}
<span class="review-head__time">{{ review.edited_time }}</span>
</div> </div>
</div> </div>
<!-- <div class="dividing-line"></div> -->
<div id="rawContent" class="delete-preview">
{{ form.content }}
</div>
{{ form.media }}
</div>
<!-- <div class="dividing-line"></div> -->
</div> </div>
<div id="rawContent" class="delete-preview">
{{ form.content }}
</div>
{{ form.media }}
<div class="dividing-line"></div>
<div class="clearfix"> <div class="clearfix">
<form action="{% url 'books:delete_review' review.id %}" method="post" class="float-right"> <form action="{% url 'books:delete_review' review.id %}" method="post" class="float-right">
{% csrf_token %} {% csrf_token %}
<input class="button" type="submit" value="{% trans '确认' %}"> <input class="button" type="submit" value="{% trans '确认' %}">
</form> </form>
<button onclick="history.back()" class="button button-clear float-right">{% trans '返回' %}</button> <button onclick="history.back()"
class="button button-clear float-right">{% trans '返回' %}</button>
</div> </div>
</div> </div>
</div>
</section> </section>
</div> </div>
<footer class="container"> {% include "partial/_footer.html" %}
<a href="https://donotban.com/@whitiewhite">去长毛象向作者提意见</a>
<a href="https://github.com/doubaniux/boofilsic/issues">报告错误</a>
<a href="https://github.com/doubaniux/boofilsic" id="githubLink">Github</a>
</footer>
</div> </div>
{% comment %} {% comment %}
<div id="oauth2Token" hidden="true">{% oauth_token %}</div> <div id="oauth2Token" hidden="true">{% oauth_token %}</div>
<div id="mastodonURI" hidden="true">{% mastodon %}</div> <div id="mastodonURI" hidden="true">{% mastodon %}</div>
<!--current user mastodon id--> <!--current user mastodon id-->
<div id="userMastodonID" hidden="true">{{ user.mastodon_id }}</div> <div id="userMastodonID" hidden="true">{{ user.mastodon_id }}</div>
{% endcomment %} {% endcomment %}
<script> <script>
$("#searchInput").on('keyup', function (e) { $("#searchInput").on('keyup', function (e) {
if (e.keyCode === 13) { if (e.keyCode === 13) {
@ -107,4 +113,4 @@
</body> </body>
</html> </html>

View file

@ -9,314 +9,325 @@
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<!-- <meta name="viewport" content="width=device-width, initial-scale=1.0"> --> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta property="og:title" content="NiceDB书 - {{ book.title }}">
<meta property="og:type" content="book">
{% if book.author %}
<meta property="og:book:author" content="{% for author in book.author %}{{ author }}{% if not forloop.last %},{% endif %}{% endfor %}">
{% endif %}
{% if book.isbn %}
<meta property="og:book:isbn" content="{{ book.isbn }}">
{% endif %}
<meta property="og:url" content="{{ request.build_absolute_uri }}">
<meta property="og:image" content="{{ request.scheme }}://{{ request.get_host }}{{ book.cover.url }}">
<title>{% trans 'Nicedb - 书籍详情' %} | {{ book.title }}</title> <title>{% trans 'Nicedb - 书籍详情' %} | {{ book.title }}</title>
<script src="https://cdn.staticfile.org/jquery/3.5.0/jquery.min.js"></script> <script src="https://cdn.staticfile.org/jquery/3.5.0/jquery.min.js"></script>
<script src="{% static 'lib/js/rating-star.js' %}"></script> <script src="{% static 'lib/js/rating-star.js' %}"></script>
<script src="{% static 'js/detail.js' %}"></script> <script src="{% static 'js/detail.js' %}"></script>
<link rel="stylesheet" href="{% static 'css/boofilsic_browse.css' %}"> <!-- <link rel="stylesheet" href="{% static 'css/boofilsic_browse.css' %}"> -->
<link rel="stylesheet" href="{% static 'css/boofilsic_modal.css' %}"> <!-- <link rel="stylesheet" href="{% static 'css/boofilsic_modal.css' %}"> -->
<!-- <link rel="stylesheet" href="{% static 'lib/css/milligram.css' %}"> -->
<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/rating-star.css' %}">
<link rel="stylesheet" href="{% static 'lib/css/milligram.css' %}">
</head> </head>
<body> <body>
<div id="page-wrapper"> <div id="page-wrapper">
<div id="content-wrapper"> <div id="content-wrapper">
<section id="navbar" class="navbar"> {% include "partial/_navbar.html" %}
<div class="container">
<nav class="clearfix">
<a href="{% url 'common:home' %}">
<img src="{% static 'img/logo.svg' %}" alt="" class="logo">
</a>
<input type="search" class="search-box" name="q" id="searchInput" required="true" placeholder="{% trans '搜索书影音,多个关键字以空格分割' %}">
<a class="nav-link" id="logoutLink" href="{% url 'users:logout' %}">{% trans '登出' %}</a>
<a class="nav-link" href="{% url 'common:home' %}">{% trans '主页' %}</a>
{% if user.is_staff %}
<a class="nav-link" href="{% admin_url %}">{% trans '后台' %}</a>
{% endif %}
</nav>
</div>
</section>
<section id="content" class="container"> <section id="content">
<div class="row"> <div class="grid">
<div id="main"> <div class="grid__main" id="main">
<div class="clearfix"> <div class="main-section-wrapper">
<div class="float-left"> <div class="entity-detail">
<img src="{{ book.cover.url }}" class="display-image" alt="">
</div>
<div class="display-info">
<h5 class="display-title">
{{ book.title }}
</h5>
<div class="display-info-detail">
<div>{% if book.isbn %}{% trans 'ISBN' %}{{ book.isbn }}{% endif %}</div>
<div>{% if book.author %}{% trans '作者:' %}
{% for author in book.author %}
<span>{{ author }}</span>
{% endfor %}
{% endif %}</div>
<div>{% if book.pub_house %}{% trans '出版社:' %}{{ book.pub_house }}{% endif %}</div>
<div>{% if book.subtitle %}{% trans '副标题:' %}{{ book.subtitle }}{% endif %}</div>
<div>{% if book.translator %}{% trans '译者:' %}
{% for translator in book.translator %}
<span>{{ translator }}</span>
{% endfor %}
{% endif %}</div>
<div>{% if book.orig_title %}{% trans '原作名:' %}{{ book.orig_title }}{% endif %}</div>
<div>{% if book.language %}{% trans '语言:' %}{{ book.language }}{% endif %}</div>
<div>{%if book.pub_year %}{% trans '出版时间:' %}{{ book.pub_year }}{% trans '年' %}{% if book.pub_month %}{{ book.pub_month }}{% trans '月' %}{% endif %}{% endif %}</div>
</div>
<div class="display-info-detail">
{% if book.rating %}
<span class="rating-star" data-rating-score="{{ book.rating | floatformat:"0" }}">
</span> <img src="{{ book.cover.url }}" class="entity-detail__img" alt="{{ book.title }}">
<span class="rating-score"> {{ book.rating }} </span>
{% else %} <div class="entity-detail__info">
<span> {% trans '评分:暂无评分' %}</span> <h5 class="entity-detail__title">
{% endif %} {{ book.title }}
<div>{% if book.binding %}{% trans '装帧:' %}{{ book.binding }}{% endif %}</div> </h5>
<div>{% if book.price %}{% trans '定价:' %}{{ book.price }}{% endif %}</div>
<div>{% if book.pages %}{% trans '页数:' %}{{ book.pages }}{% endif %}</div>
{% if book.other_info %}
{% for k, v in book.other_info.items %}
<div>
{{k}}{{v}}
</div>
{% endfor %}
{% endif %}
{% comment %} <div class="entity-detail__fields">
{% url 'users:home' book.last_editor %} <div class="entity-detail__rating">
{% endcomment %} {% if book.rating %}
<span class="entity-detail__rating-star rating-star" data-rating-score="{{ book.rating | floatformat:"0" }}"></span>
<span class="entity-detail__rating-score"> {{ book.rating }} </span>
{% else %}
<span> {% trans '评分:暂无评分' %}</span>
{% endif %}
</div>
<div>{% if book.isbn %}{% trans 'ISBN' %}{{ book.isbn }}{% endif %}</div>
<div>{% if book.author %}{% trans '作者:' %}
{% for author in book.author %}
<span>{{ author }}</span>
{% endfor %}
{% endif %}</div>
<div>{% if book.pub_house %}{% trans '出版社:' %}{{ book.pub_house }}{% endif %}</div>
<div>{% if book.subtitle %}{% trans '副标题:' %}{{ book.subtitle }}{% endif %}</div>
<div>{% if book.translator %}{% trans '译者:' %}
{% for translator in book.translator %}
<span>{{ translator }}</span>
{% endfor %}
{% endif %}</div>
<div>{% if book.orig_title %}{% trans '原作名:' %}{{ book.orig_title }}{% endif %}</div>
<div>{% if book.language %}{% trans '语言:' %}{{ book.language }}{% endif %}</div>
<div>{%if book.pub_year %}{% trans '出版时间:' %}{{ book.pub_year }}{% trans '年' %}{% if book.pub_month %}{{ book.pub_month }}{% trans '月' %}{% endif %}{% endif %}</div>
</div>
<div class="entity-detail__fields">
<div>{% if book.binding %}{% trans '装帧:' %}{{ book.binding }}{% endif %}</div>
<div>{% if book.price %}{% trans '定价:' %}{{ book.price }}{% endif %}</div>
<div>{% if book.pages %}{% trans '页数:' %}{{ book.pages }}{% endif %}</div>
{% if book.other_info %}
{% for k, v in book.other_info.items %}
<div>
{{k}}{{v}}
</div>
{% endfor %}
{% endif %}
<div>{% trans '最近编辑者:' %}<a href="{% url 'users:home' book.last_editor.id %}">{{ book.last_editor | default:"" }}</a></div>
<div>
<a href="{% url 'books:update' book.id %}">{% trans '编辑这本书' %}</a>
{% if user.is_staff %}
<a href="{% url 'books:delete' book.id %}" class="delete"> / {% trans '删除' %}</a>
{% endif %}
</div>
</div>
{% if book.last_editor %}
<div>{% trans '最近编辑者:' %}<a href="{% url 'users:home' book.last_editor.id %}">{{ book.last_editor | default:"" }}</a></div>
{% endif %}
<div>
<a href="{% url 'books:update' book.id %}">{% trans '编辑这本书' %}</a>
{% if user.is_staff %}
<a href="{% url 'books:delete' book.id %}"> / {% trans '删除' %}</a>
{% endif %}
</div>
</div>
</div>
</div> </div>
</div> <div class="dividing-line"></div>
<div class="dividing-line"></div> <div class="entity-desc">
<div class="set"> <h5 class="entity-desc__title">{% trans '简介' %}</h5>
<h5 class="set-title">{% trans '简介' %}</h5>
{% if book.brief %}
{% if book.brief %} <p class="entity-desc__content">{{ book.brief | linebreaksbr }}</p>
<p class="set-content">{{ book.brief | linebreaksbr }}</p> {% else %}
{% else %} <div>{% trans '暂无简介' %}</div>
<p class="set-empty">{% trans '暂无简介' %}</p> {% endif %}
{% endif %}
</div>
</div> <div class="entity-marks">
<div class="set"> <h5 class="entity-marks__title">{% trans '这本书的标记' %}</h5>
<h5 class="set-title">{% trans '这本书的标记' %}</h5> {% if mark_list_more %}
{% if mark_list_more %} <a href="{% url 'books:retrieve_mark_list' book.id %}" class="entity-marks__more-link">{% trans '更多' %}</a>
<a href="{% url 'books:retrieve_mark_list' book.id %}" class="more-link">{% trans '更多' %}</a> {% endif %}
{% endif %} {% if mark_list %}
{% if mark_list %} <ul class="entity-marks__mark-list">
{% for others_mark in mark_list %} {% for others_mark in mark_list %}
<div class="mark"> <li class="entity-marks__mark">
<div class="mark-label"> <a href="{% url 'users:home' others_mark.owner.id %}" class="entity-marks__owner-link">{{ others_mark.owner.username }}</a>
<a href="{% url 'users:home' others_mark.owner.id %}" class="mark-owner-name">{{ others_mark.owner.username }}</a>
<span>{{ others_mark.get_status_display }}</span> <span>{{ others_mark.get_status_display }}</span>
{% if others_mark.rating %} {% if others_mark.rating %}
<span class="rating-star" data-rating-score="{{ others_mark.rating | floatformat:"0" }}"></span> <span class="entity-marks__rating-star rating-star" data-rating-score="{{ others_mark.rating | floatformat:"0" }}"></span>
{% endif %} {% endif %}
{% if others_mark.is_private %} {% if others_mark.is_private %}
<span class="icon-lock"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><path d="M17,8.48h-.73V6.27a6.27,6.27,0,1,0-12.53,0V8.48H3a.67.67,0,0,0-.67.67V19.33A.67.67,0,0,0,3,20H17a.67.67,0,0,0,.67-.67V9.15A.67.67,0,0,0,17,8.48ZM6.42,6.27h0a3.57,3.57,0,0,1,7.14,0h0V8.48H6.42Z"/></svg></span> <span class="icon-lock"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><path d="M17,8.48h-.73V6.27a6.27,6.27,0,1,0-12.53,0V8.48H3a.67.67,0,0,0-.67.67V19.33A.67.67,0,0,0,3,20H17a.67.67,0,0,0,.67-.67V9.15A.67.67,0,0,0,17,8.48ZM6.42,6.27h0a3.57,3.57,0,0,1,7.14,0h0V8.48H6.42Z"/></svg></span>
{% endif %} {% endif %}
<span class="mark-time">{{ others_mark.edited_time }}</span> <span class="entity-marks__mark-time">{{ others_mark.edited_time }}</span>
</div> {% if others_mark.text %}
<p class="entity-marks__mark-content">{{ others_mark.text }}</p>
{% if others_mark.text %} {% endif %}
<p class="mark-text">{{ others_mark.text }}</p> </li>
{% endfor %}
</ul>
{% else %}
<div>{% trans '暂无标记' %}</div>
{% endif %} {% endif %}
</div> </div>
{% endfor %} <div class="entity-reviews">
{% else %} <h5 class="entity-reviews__title">{% trans '这本书的评论' %}</h5>
<p class="set-empty">{% trans '暂无标记' %}</p> {% if review_list_more %}
{% endif %} <a href="{% url 'books:retrieve_review_list' book.id %}" class="entity-reviews__more-link">{% trans '更多' %}</a>
</div> {% endif %}
<div class="set"> {% if review_list %}
<h5 class="set-title">{% trans '这本书的评论' %}</h5> <ul class="entity-reviews__review-list">
{% if review_list_more %} {% for others_review in review_list %}
<a href="{% url 'books:retrieve_review_list' book.id %}" class="more-link">{% trans '更多' %}</a> <li class="entity-reviews__review">
{% endif %} <a href="{% url 'users:home' others_review.owner.id %}" class="entity-reviews__owner-link">{{ others_review.owner.username }}</a>
{% if review_list %}
{% for others_review in review_list %}
<div class="mark">
<div class="mark-label">
<a href="{% url 'users:home' others_review.owner.id %}" class="mark-owner-name">{{ others_review.owner.username }}</a>
{% if others_review.is_private %} {% if others_review.is_private %}
<span class="icon-lock"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><path d="M17,8.48h-.73V6.27a6.27,6.27,0,1,0-12.53,0V8.48H3a.67.67,0,0,0-.67.67V19.33A.67.67,0,0,0,3,20H17a.67.67,0,0,0,.67-.67V9.15A.67.67,0,0,0,17,8.48ZM6.42,6.27h0a3.57,3.57,0,0,1,7.14,0h0V8.48H6.42Z"/></svg></span> <span class="icon-lock"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><path d="M17,8.48h-.73V6.27a6.27,6.27,0,1,0-12.53,0V8.48H3a.67.67,0,0,0-.67.67V19.33A.67.67,0,0,0,3,20H17a.67.67,0,0,0,.67-.67V9.15A.67.67,0,0,0,17,8.48ZM6.42,6.27h0a3.57,3.57,0,0,1,7.14,0h0V8.48H6.42Z"/></svg></span>
{% endif %} {% endif %}
<span class="mark-time">{{ others_review.edited_time }}</span> <span class="entity-reviews__review-time">{{ others_review.edited_time }}</span>
<span class="review-title"> <a href="{% url 'books:retrieve_review' others_review.id %}">{{ others_review.title }}</a></span> <span class="entity-reviews__review-title"> <a href="{% url 'books:retrieve_review' others_review.id %}">{{ others_review.title }}</a></span>
</div> </li>
{% endfor %}
</ul>
{% else %}
<div>{% trans '暂无评论' %}</div>
{% endif %}
</div> </div>
{% endfor %}
{% else %}
<p class="set-empty">{% trans '暂无评论' %}</p>
{% endif %}
</div> </div>
</div> </div>
<div id="aside"> <div class="grid__aside" id="aside">
<div class="aside-card" id="asideMark"> <div class="aside-section-wrapper">
{% if mark %} {% if mark %}
<div class="mark"> <div class="mark-panel">
<div class="clearfix">
<span class="mark-status-label float-left">{% trans '我' %}{{ mark.get_status_display }}</span> <span class="mark-panel__status">{% trans '我' %}{{ mark.get_status_display }}</span>
{% if mark.status == status_enum.DO.value or mark.status == status_enum.COLLECT.value%} {% if mark.status == status_enum.DO.value or mark.status == status_enum.COLLECT.value%}
{% if mark.rating %} {% if mark.rating %}
<span class="rating-star" data-rating-score="{{ mark.rating | floatformat:"0" }}"></span> <span class="mark-panel__rating-star rating-star" data-rating-score="{{ mark.rating | floatformat:"0" }}"></span>
{% endif %}
{% endif %} {% endif %}
{% if mark.is_private %} {% endif %}
<span class="icon-lock"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><path d="M17,8.48h-.73V6.27a6.27,6.27,0,1,0-12.53,0V8.48H3a.67.67,0,0,0-.67.67V19.33A.67.67,0,0,0,3,20H17a.67.67,0,0,0,.67-.67V9.15A.67.67,0,0,0,17,8.48ZM6.42,6.27h0a3.57,3.57,0,0,1,7.14,0h0V8.48H6.42Z"/></svg></span> {% if mark.is_private %}
{% endif %} <span class="icon-lock"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><path d="M17,8.48h-.73V6.27a6.27,6.27,0,1,0-12.53,0V8.48H3a.67.67,0,0,0-.67.67V19.33A.67.67,0,0,0,3,20H17a.67.67,0,0,0,.67-.67V9.15A.67.67,0,0,0,17,8.48ZM6.42,6.27h0a3.57,3.57,0,0,1,7.14,0h0V8.48H6.42Z"/></svg></span>
<span class="float-right"> {% endif %}
<a href="" class="edit">{% trans '修改' %}</a> <span class="mark-panel__actions">
<form action="{% url 'books:delete_mark' mark.id %}" method="post"> <a href="" class="edit">{% trans '修改' %}</a>
{% csrf_token %} <form action="{% url 'books:delete_mark' mark.id %}" method="post">
<a href="">{% trans '删除' %}</a> {% csrf_token %}
</form> <a href="" class="delete">{% trans '删除' %}</a>
</span> </form>
</div> </span>
<div class="clearfix"> <div class="mark-panel__clear"></div>
<span class="mark-time float-left">{{ mark.edited_time }}</span>
</div> <div class="mark-panel__time">{{ mark.edited_time }}</div>
{% if mark.text %} {% if mark.text %}
<p class="mark-text">{{ mark.text }}</p> <p class="mark-panel__text">{{ mark.text }}</p>
{% endif %} {% endif %}
</div> </div>
{% else %} {% else %}
<div class="mark"> <div class="action-panel" id="addMarkPanel">
<div class="clearfix"> <div class="action-panel__label">{% trans '标记这本书' %}</div>
<span class="mark-status-label float-left">{% trans '标记这本书' %}</span> <div class="action-panel__button-group">
</div> <button class="action-panel__button" data-status="{{ status_enum.WISH.value }}">{% trans '想读' %}</button>
<div class="button-group"> <button class="action-panel__button" data-status="{{ status_enum.DO.value }}">{% trans '在读' %}</button>
<a href="" class="button" id="wishButton" data-status="{{ status_enum.WISH.value }}">{% trans '想读' %}</a> <button class="action-panel__button" data-status="{{ status_enum.COLLECT.value }}">{% trans '读过' %}</button>
<a href="" class="button" data-status="{{ status_enum.DO.value }}">{% trans '在读' %}</a>
<a href="" class="button" data-status="{{ status_enum.COLLECT.value }}">{% trans '读过' %}</a>
</div> </div>
</div> </div>
{% endif %} {% endif %}
</div> </div>
<div class="aside-card" id="asideReview"> <div class="aside-section-wrapper">
{% if review %} {% if review %}
<div class="review"> <div class="review-panel">
<div class="clearfix">
<span class="review-label float-left">{% trans '我的评论' %}</span> <span class="review-panel__label">{% trans '我的评论' %}</span>
{% if review.is_private %} {% if review.is_private %}
<span class="icon-lock"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><path d="M17,8.48h-.73V6.27a6.27,6.27,0,1,0-12.53,0V8.48H3a.67.67,0,0,0-.67.67V19.33A.67.67,0,0,0,3,20H17a.67.67,0,0,0,.67-.67V9.15A.67.67,0,0,0,17,8.48ZM6.42,6.27h0a3.57,3.57,0,0,1,7.14,0h0V8.48H6.42Z"/></svg></span> <span class="icon-lock"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><path d="M17,8.48h-.73V6.27a6.27,6.27,0,1,0-12.53,0V8.48H3a.67.67,0,0,0-.67.67V19.33A.67.67,0,0,0,3,20H17a.67.67,0,0,0,.67-.67V9.15A.67.67,0,0,0,17,8.48ZM6.42,6.27h0a3.57,3.57,0,0,1,7.14,0h0V8.48H6.42Z"/></svg></span>
{% endif %} {% endif %}
<span class="float-right"> <span class="review-panel__actions">
<a href="{% url 'books:update_review' review.id %}">{% trans '编辑' %}</a> <a href="{% url 'books:update_review' review.id %}">{% trans '编辑' %}</a>
<a href="{% url 'books:delete_review' review.id %}">{% trans '删除' %}</a> <a href="{% url 'books:delete_review' review.id %}">{% trans '删除' %}</a>
</span> </span>
</div> <div class="review-panel__time">{{ review.edited_time }}</div>
<div class="clearfix">
<span class="review-time float-left">{{ review.edited_time }}</span> <a href="{% url 'books:retrieve_review' review.id %}" class="review-panel__review-title">
</div>
<a href="{% url 'books:retrieve_review' review.id %}" class="review-title">
{{ review.title }} {{ review.title }}
</a> </a>
</div> </div>
{% else %} {% else %}
<div class="clearfix">
<span class="review-label float-left">{% trans '我的评论' %}</span> <div class="action-panel">
</div> <div class="action-panel__label">{% trans '我的评论' %}</div>
<a href="{% url 'books:create_review' book.id %}" class="button">{% trans '去写评论' %}</a> <div class="action-panel__button-group action-panel__button-group--center">
<a href="{% url 'books:create_review' book.id %}">
<button class="action-panel__button">{% trans '去写评论' %}</button>
</a>
</div>
</div>
{% endif %} {% endif %}
</div> </div>
</div> </div>
</div>
</section> </section>
</div> </div>
<footer class="container"> {% include "partial/_footer.html" %}
<a href="https://donotban.com/@whitiewhite">去长毛象向作者提意见</a>
<a href="https://github.com/doubaniux/boofilsic/issues">报告错误</a>
<a href="https://github.com/doubaniux/boofilsic" id="githubLink">Github</a>
</footer>
</div> </div>
<div id="modals"> <div id="modals">
<div class="modal mark-modal"> <div class="mark-modal modal">
<div class="modal-head clearfix"> <div class="mark-modal__head">
{% if not mark %} {% if not mark %}
<style> <style>
.modal-title::after { .mark-modal__title::after {
content: "{% trans '这本书' %}"; content: "{% trans '这本书' %}";
} }
</style> </style>
<span class="modal-title float-left"></span> <span class="mark-modal__title"></span>
{% else %} {% else %}
<span class="modal-title float-left">{% trans '我的标记' %}</span> <span class="mark-modal__title">{% trans '我的标记' %}</span>
{% endif %} {% endif %}
<span class="modal-close float-right"> <span class="mark-modal__close-button modal-close">
<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"/></svg> <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> </span>
</div> </div>
<div class="modal-body"> <div class="mark-modal__body">
<form action="{% url 'books:create_update_mark' %}" method="post"> <form action="{% url 'books:create_update_mark' %}" method="post">
{% csrf_token %} {% csrf_token %}
{{ mark_form.id }} {{ mark_form.id }}
{{ mark_form.book }} {{ mark_form.book }}
{% if mark.rating %} {% if mark.rating %}
{% endif %} {% endif %}
<div class="clearfix">
<div class="rating-star-edit float-left"></div> <div class="mark-modal__rating-star rating-star-edit"></div>
<div id="statusSelection" class="modal-selection float-right" {% if not mark %}hidden{% endif %}>
{{ mark_form.status }}
</div>
</div>
{{ mark_form.rating }} {{ mark_form.rating }}
<div id="statusSelection" class="mark-modal__status-radio" {% if not mark %}hidden{% endif %}>
{{ mark_form.status }}
</div>
<div class="mark-modal__clear"></div>
{{ mark_form.text }} {{ mark_form.text }}
<div class="modal-option clearfix">
<div class="modal-selection float-left"> <div class="mark-modal__option">
<div class="mark-modal__visibility-radio">
<span>{{ mark_form.is_private.label }}:</span> <span>{{ mark_form.is_private.label }}:</span>
{{ mark_form.is_private }} {{ mark_form.is_private }}
</div> </div>
<div class="modal-checkbox float-right"> <div class="mark-modal__share-checkbox">
{{ mark_form.share_to_mastodon }}{{ mark_form.share_to_mastodon.label }} {{ mark_form.share_to_mastodon }}{{ mark_form.share_to_mastodon.label }}
</div> </div>
</div> </div>
<div class="clearfix modal-button"> <div class="mark-modal__confirm-button">
<input type="submit" class="button float-right" value="{% trans '提交' %}"> <input type="submit" class="button float-right" value="{% trans '提交' %}">
</div> </div>
</form> </form>
</div> </div>
</div> </div>
<div class="modal confirm-modal"> <div class="confirm-modal modal">
<div class="modal-head clearfix"> <div class="confirm-modal__head">
<span class="modal-title float-left">{% trans '确定要删除你的标记吗?' %}</span> <span class="confirm-modal__title">{% trans '确定要删除你的标记吗?' %}</span>
<span class="modal-close float-right"> <span class="confirm-modal__close-button modal-close">
<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"/></svg> <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> </span>
</div> </div>
<div class="modal-body"> <div class="confirm-modal__body">
<div class="clearfix modal-button"> <div class="confirm-modal__confirm-button">
<input type="submit" class="button float-right" value="{% trans '确认' %}"> <input type="submit" class="button float-right" value="{% trans '确认' %}">
</div> </div>
</div> </div>

View file

@ -10,197 +10,227 @@
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<!-- <meta name="viewport" content="width=device-width, initial-scale=1.0"> --> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{% trans 'Nicedb - ' %}</title> <title>{% trans 'Nicedb - ' %}{{ user.username }}{{ list_title }}</title>
<script src="https://cdn.staticfile.org/jquery/3.5.0/jquery.min.js"></script> <script src="https://cdn.staticfile.org/jquery/3.5.0/jquery.min.js"></script>
<script src="{% static 'lib/js/rating-star.js' %}"></script> <script src="{% static 'lib/js/rating-star.js' %}"></script>
<script src="{% static 'js/rating-star-readonly.js' %}"></script> <script src="{% static 'js/rating-star-readonly.js' %}"></script>
<script src="{% static 'js/mastodon.js' %}"></script> <script src="{% static 'js/mastodon.js' %}"></script>
<script src="{% static 'js/home.js' %}"></script> <script src="{% static 'js/home.js' %}"></script>
<link rel="stylesheet" href="{% static 'css/boofilsic_browse.css' %}">
<link rel="stylesheet" href="{% static 'lib/css/rating-star.css' %}"> <link rel="stylesheet" href="{% static 'lib/css/rating-star.css' %}">
<link rel="stylesheet" href="{% static 'lib/css/milligram.css' %}"> <link rel="stylesheet" href="{% static 'css/boofilsic.css' %}">
<!-- <link rel="stylesheet" href="{% static 'css/boofilsic_browse.css' %}"> -->
<!-- <link rel="stylesheet" href="{% static 'lib/css/milligram.css' %}"> -->
</head> </head>
<body> <body>
<div id="page-wrapper"> <div id="page-wrapper">
<div id="content-wrapper"> <div id="content-wrapper">
<section id="navbar" class="navbar"> {% include "partial/_navbar.html" %}
<div class="container">
<nav class="clearfix">
<a href="{% url 'common:home' %}">
<img src="{% static 'img/logo.svg' %}" alt="" class="logo">
</a>
<input type="search" class="search-box" name="q"
value="{% if request.GET.q %}{{ request.GET.q }}{% endif %}" id="searchInput" required="true" placeholder="{% trans '搜索书影音,多个关键字以空格分割' %}">
<a class="nav-link" id="logoutLink" href="{% url 'users:logout' %}">{% trans '登出' %}</a>
<a class="nav-link" href="{% url 'common:home' %}">{% trans '主页' %}</a>
{% if request.user.is_staff %}
<a class="nav-link" href="{% admin_url %}">{% trans '后台' %}</a>
{% endif %}
</nav>
</div>
</section>
<section id="content" class="container"> <section id="content" class="container">
<div class="row"> <div class="grid grid--reverse-order">
<div id="main"> <div class="grid__main grid__main--reverse-order">
<div class="set"> <div class="main-section-wrapper">
<h5 class="set-title"> <div class="entity-list">
{{ user.username }}{{ list_title }}
</h5>
</div>
<ul class="result-items">
{% for mark in marks %}
<li class="result-item clearfix">
<a href="{% url 'books:retrieve' mark.book.id %}">
<img src="{{ mark.book.cover.url }}" alt="" class="result-book-cover">
</a>
<div class="result-info">
<a href="{% url 'books:retrieve' mark.book.id %}" class="result-item-title"> <div class="set">
{{ mark.book.title }} <h5 class="entity-list__title">
</a> {{ user.username }}{{ list_title }}
{% if mark.book.rating %} </h5>
<div class="rating-star" data-rating-score="{{ mark.book.rating | floatformat:"0" }}"></div>
<span class="rating-score">
{{ mark.book.rating }}
</span>
{% else %}
<span class="rating-empty"> {% trans '暂无评分' %}</span>
{% endif %}
<span class="result-book-info">
{% if mark.book.pub_year %}
{{ mark.book.pub_year }}{% trans '年' %} /
{% if mark.book.pub_month %}
{{ mark.book.pub_month }}{% trans '月' %} /
{% endif %}
{% endif %}
{% if mark.book.author %}
{% trans '作者' %}
{% for author in mark.book.author %}
{{ author }}{% if not forloop.last %},{% endif %}
{% endfor %}/
{% endif %}
{% if mark.book.translator %}
{% trans '译者' %}
{% for translator in mark.book.translator %}
{{ translator }}{% if not forloop.last %},{% endif %}
{% endfor %}/
{% endif %}
{% if mark.book.orig_title %}
&nbsp;{% trans '原名' %}
{{ mark.book.orig_title }}
{% endif %}
</span>
<p class="result-item-brief">
{{ mark.book.brief | truncate:170 }}
</p>
</div> </div>
</li> <ul class="entity-list__entities">
{% empty %}
{% trans '无结果' %} {% for mark in marks %}
{% endfor %}
<li class="entity-list__entity">
</ul> <div class="entity-list__entity-img-wrapper">
<div class="pagination" > <a href="{% url 'books:retrieve' mark.book.id %}">
<img src="{{ mark.book.cover.url }}" alt="" class="entity-list__entity-img">
</a>
</div>
<div class="entity-list__entity-text">
<div class="entity-list__entity-title">
<a href="{% url 'books:retrieve' mark.book.id %}" class="entity-list__entity-link">
{{ mark.book.title }}
</a>
</div>
{% comment %}
<!-- {% if mark.book.rating %}
<div class="rating-star entity-list__rating-star" data-rating-score="{{ mark.book.rating | floatformat:"0" }}"></div>
<span class="entity-list__rating-score rating-score">
{{ mark.book.rating }}
</span>
{% else %}
<div class="entity-list__rating entity-list__rating--empty"> {% trans '暂无评分' %}</div>
{% endif %} -->
{% endcomment %}
<span class="entity-list__entity-info entity-list__entity-info--full-length">
{% if mark.book.pub_year %}
{{ mark.book.pub_year }}{% trans '年' %} /
{% if mark.book.pub_month %}
{{ mark.book.pub_month }}{% trans '月' %} /
{% endif %}
{% endif %}
{% if mark.book.author %}
{% trans '作者' %}
{% for author in mark.book.author %}
{{ author }}{% if not forloop.last %},{% endif %}
{% endfor %}/
{% endif %}
{% if mark.book.translator %}
{% trans '译者' %}
{% for translator in mark.book.translator %}
{{ translator }}{% if not forloop.last %},{% endif %}
{% endfor %}/
{% endif %}
{% if mark.book.orig_title %}
&nbsp;{% trans '原名' %}
{{ mark.book.orig_title }}
{% endif %}
</span>
<p class="entity-list__entity-brief">
{{ mark.book.brief | truncate:170 }}
</p>
<div class="entity-marks" style="margin-bottom: 0;">
<ul class="entity-marks__mark-list">
<li class="entity-marks__mark">
{% if mark.rating %}
<span class="entity-marks__rating-star rating-star"
data-rating-score="{{ mark.rating | floatformat:"0" }}" style="left: -4px;"></span>
{% endif %}
{% if mark.is_private %}
<span class="icon-lock"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><svg
xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20">
<path
d="M17,8.48h-.73V6.27a6.27,6.27,0,1,0-12.53,0V8.48H3a.67.67,0,0,0-.67.67V19.33A.67.67,0,0,0,3,20H17a.67.67,0,0,0,.67-.67V9.15A.67.67,0,0,0,17,8.48ZM6.42,6.27h0a3.57,3.57,0,0,1,7.14,0h0V8.48H6.42Z" />
</svg></span>
{% endif %}
<span class="entity-marks__mark-time">{{ mark.edited_time }}</span>
{% if mark.text %}
<p class="entity-marks__mark-content">{{ mark.text }}</p>
{% endif %}
</li>
</ul>
</div>
</div>
</li>
{% empty %}
<div>{% trans '无结果' %}</div>
{% endfor %}
<!-- user mark -->
</ul>
</div>
<div class="pagination">
<a {% if marks.pagination.has_prev %}
{% if marks.has_previous %} <a href="?page=1" class="pagination__nav-link pagination__nav-link">&laquo;</a>
href="?page=1" <a href="?page={{ marks.previous_page_number }}"
{% else %} class="pagination__nav-link pagination__nav-link--right-margin pagination__nav-link">&lsaquo;</a>
disabled {% endif %}
{% endif %}>
<button {% if not marks.has_previous %}disabled{% endif %} class="button button-clear">{% trans "首页" %}</button> {% for page in marks.pagination.page_range %}
</a>&nbsp;&nbsp;
{% if page == marks.pagination.current_page %}
<a <a href="?page={{ page }}" class="pagination__page-link pagination__page-link--current">{{ page }}</a>
{% if marks.has_previous %} {% else %}
href="?page={{ marks.previous_page_number }}" <a href="?page={{ page }}" class="pagination__page-link">{{ page }}</a>
{% else %} {% endif %}
disabled
{% endif %}> {% endfor %}
<button {% if not marks.has_previous %}disabled{% endif %} class="button button-clear">{% trans "上一页" %}</button>
</a>&nbsp;&nbsp; {% if marks.pagination.has_next %}
<a href="?page={{ marks.next_page_number }}"
<span class="page-index"> class="pagination__nav-link pagination__nav-link--left-margin">&rsaquo;</a>
{% trans "第" %}{% if request.GET.page %}{{ request.GET.page }}{% else %}1{% endif %}{% trans "页" %} <a href="?page={{ marks.pagination.last_page }}" class="pagination__nav-link">&raquo;</a>
</span> {% endif %}
&nbsp;&nbsp;<a </div>
{% if marks.has_next %} </div>
href="?page={{ marks.next_page_number }}"
{% else %}
disabled
{% endif %}
>
<button {% if not marks.has_next %}disabled{% endif %} class="button button-clear">{% trans "下一页" %}</button>
</a>
&nbsp;&nbsp;<a
{% if marks.has_next %}
href="?page={{ marks.paginator.num_pages }}"
{% else %}
disabled
{% endif %}>
<button {% if not marks.has_next %}disabled{% endif %} class="button button-clear">{% trans "末页" %}</button>
</a>
</div>
</div> </div>
<div id="aside"> <div class="grid__aside grid__aside--reverse-order grid__aside--tablet-column">
<div class="aside-card mast-user" id="userInfoCard"> <div class="aside-section-wrapper aside-section-wrapper--no-margin">
<div class="clearfix"> <div class="user-profile" id="userInfoCard">
<img src="" class="info-avatar mast-avatar" alt="{{ user.username }}"> <div class="user-profile__header">
<a href="{% url 'users:home' user.id %}"> <!-- <img src="" class="user-profile__avatar mast-avatar" alt="{{ user.username }}"> -->
<h5 class="info-name mast-displayname"></h5> <img src="" class="user-profile__avatar mast-avatar">
</a> <a href="{% url 'users:home' user.id %}">
<h5 class="user-profile__username mast-displayname"></h5>
</a>
</div>
<p class="user-profile__bio mast-brief"></p>
<!-- <a href="#" class="follow">{% trans '关注TA' %}</a> -->
{% if request.user != user %}
<a href="{% url 'users:report' %}?user_id={{ user.id }}"
class="user-profile__report-link">{% trans '举报用户' %}</a>
{% endif %}
</div> </div>
<p class="info-brief mast-brief"></p>
<!-- <a href="#" class="follow">{% trans '关注TA' %}</a> -->
{% if request.user != user %}
<a href="{% url 'users:report' %}?user_id={{ user.id }}" class="report">{% trans '举报用户' %}</a>
{% endif %}
</div> </div>
<div class="relation-card" id="userRelationCard">
<h5 class="relation-label"> <div class="relation-dropdown">
{% trans '关注的人' %} <div class="relation-dropdown__button">
</h5> <span class="icon-arrow">
<a href="{% url 'users:following' user.id %}" class="more-link mast-following-more">{% trans '更多' %}</a> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 10 10">
<ul class="row mast-following relation-user-list"> <path d="M8.12,3.29,5,6.42,1.86,3.29H.45L5,7.84,9.55,3.29Z" />
<li class="column column-25 relation-user"> </svg>
<img src="" alt="" class="relation-avatar"> </span>
<a class="relation-name"></a> </div>
</li> <div class="relation-dropdown__body">
</ul> <div class="aside-section-wrapper aside-section-wrapper--transparent aside-section-wrapper--collapse">
<h5 class="relation-label">
{% trans '被他们关注' %} <div class="user-relation" id="followings">
</h5> <h5 class="user-relation__label">
<a href="{% url 'users:followers' user.id %}" class="more-link mast-followers-more">{% trans '更多' %}</a> {% trans '关注的人' %}
<ul class="row mast-followers relation-user-list"> </h5>
<li class="column column-25 relation-user"> <a href="{% url 'users:following' user.id %}"
<img src="" alt="" class="relation-avatar"> class="user-relation__more-link mast-following-more">{% trans '更多' %}</a>
<a class="relation-name"></a> <ul class="user-relation__related-user-list mast-following">
</li> <li class="user-relation__related-user">
</ul> <a>
<img src="" alt="" class="user-relation__related-user-avatar">
<div class="user-relation__related-user-name mast-displayname">
</div>
</a>
</li>
</ul>
</div>
<div class="user-relation" id="followers">
<h5 class="user-relation__label">
{% trans '被他们关注' %}
</h5>
<a href="{% url 'users:followers' user.id %}"
class="user-relation__more-link mast-followers-more">{% trans '更多' %}</a>
<ul class="user-relation__related-user-list mast-followers">
<li class="user-relation__related-user">
<a>
<img src="" alt="" class="user-relation__related-user-avatar">
<div class="user-relation__related-user-name mast-displayname">
</div>
</a>
</li>
</ul>
</div>
</div>
</div>
</div> </div>
</div> </div>
</div>
</section> </section>
</div> </div>
<footer class="container"> {% include "partial/_footer.html" %}
<a href="https://donotban.com/@whitiewhite">去长毛象向作者提意见</a>
<a href="https://github.com/doubaniux/boofilsic/issues">报告错误</a>
<a href="https://github.com/doubaniux/boofilsic" id="githubLink">Github</a>
</footer>
</div> </div>
@ -209,22 +239,22 @@
<!--current user mastodon id--> <!--current user mastodon id-->
<div id="userMastodonID" hidden="true">{{ user.mastodon_id }}</div> <div id="userMastodonID" hidden="true">{{ user.mastodon_id }}</div>
<div id="userPageURL" hidden="true">{% url 'users:home' 0 %}?is_mastodon_id=true</div> <div id="userPageURL" hidden="true">{% url 'users:home' 0 %}?is_mastodon_id=true</div>
<div class="spinner" id="spinner" hidden> <div id="spinner" hidden>
<div class="lds-spinner"> <div class="spinner">
<div></div> <div></div>
<div></div> <div></div>
<div></div> <div></div>
<div></div> <div></div>
<div></div> <div></div>
<div></div> <div></div>
<div></div> <div></div>
<div></div> <div></div>
<div></div> <div></div>
<div></div> <div></div>
<div></div> <div></div>
<div></div> <div></div>
</div> </div>
</div> </div>
<script> <script>
$("#searchInput").on('keyup', function (e) { $("#searchInput").on('keyup', function (e) {
if (e.keyCode === 13) { if (e.keyCode === 13) {

View file

@ -10,140 +10,122 @@
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<!-- <meta name="viewport" content="width=device-width, initial-scale=1.0"> --> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{% trans 'Nicedb - 搜索结果' %}</title> <title>{% trans 'Nicedb - ' %}{{ book.title }}{% trans '的标记' %}</title>
<script src="https://cdn.staticfile.org/jquery/3.5.0/jquery.min.js"></script> <script src="https://cdn.staticfile.org/jquery/3.5.0/jquery.min.js"></script>
<script src="{% static 'lib/js/rating-star.js' %}"></script> <script src="{% static 'lib/js/rating-star.js' %}"></script>
<script src="{% static 'js/rating-star-readonly.js' %}"></script> <script src="{% static 'js/rating-star-readonly.js' %}"></script>
<link rel="stylesheet" href="{% static 'css/boofilsic_browse.css' %}"> <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/rating-star.css' %}">
<link rel="stylesheet" href="{% static 'lib/css/milligram.css' %}"> <!-- <link rel="stylesheet" href="{% static 'css/boofilsic_browse.css' %}"> -->
<!-- <link rel="stylesheet" href="{% static 'lib/css/milligram.css' %}"> -->
</head> </head>
<body> <body>
<div id="page-wrapper"> <div id="page-wrapper">
<div id="content-wrapper"> <div id="content-wrapper">
<section id="navbar" class="navbar"> {% include "partial/_navbar.html" %}
<div class="container">
<nav class="clearfix">
<a href="{% url 'common:home' %}">
<img src="{% static 'img/logo.svg' %}" alt="" class="logo">
</a>
<input type="search" class="search-box" name="q"
value="{% if request.GET.q %}{{ request.GET.q }}{% endif %}" id="searchInput" required="true" placeholder="{% trans '搜索书影音,多个关键字以空格分割' %}">
<a class="nav-link" id="logoutLink" href="{% url 'users:logout' %}">{% trans '登出' %}</a>
<a class="nav-link" href="{% url 'common:home' %}">{% trans '主页' %}</a>
{% if user.is_staff %}
<a class="nav-link" href="{% admin_url %}">{% trans '后台' %}</a>
{% endif %}
</nav>
</div>
</section>
<section id="content" class="container"> <section id="content">
<div class="row"> <div class="grid">
<div id="main"> <div class="grid__main" id="main">
<h5 class="list-head"> <div class="main-section-wrapper">
<a href="{% url 'books:retrieve' book.id %}">{{ book.title }}</a>{% trans ' 的标记' %} <div class="entity-marks">
</h5> <h5 class="entity-marks__title entity-marks__title--stand-alone">
<ul class="result-items set"> <a href="{% url 'books:retrieve' book.id %}">{{ book.title }}</a>{% trans ' 的标记' %}
</h5>
<ul class="entity-marks__mark-list">
{% for mark in marks %}
<li class="entity-marks__mark entity-marks__mark--wider">
<a href="{% url 'users:home' mark.owner.id %}"
class="entity-marks__owner-link">{{ mark.owner.username }}</a>
<span>{{ mark.get_status_display }}</span>
{% if mark.rating %}
<span class="entity-marks__rating-star rating-star"
data-rating-score="{{ mark.rating | floatformat:"0" }}"></span>
{% endif %}
{% if mark.is_private %}
<span class="icon-lock"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><svg
xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20">
<path
d="M17,8.48h-.73V6.27a6.27,6.27,0,1,0-12.53,0V8.48H3a.67.67,0,0,0-.67.67V19.33A.67.67,0,0,0,3,20H17a.67.67,0,0,0,.67-.67V9.15A.67.67,0,0,0,17,8.48ZM6.42,6.27h0a3.57,3.57,0,0,1,7.14,0h0V8.48H6.42Z" />
</svg></span>
{% endif %}
<span class="entity-marks__mark-time">{{ mark.edited_time }}</span>
{% if mark.text %}
<p class="entity-marks__mark-content">{{ mark.text }}</p>
{% endif %}
</li>
{% for mark in marks %} {% empty %}
<div>
<div class="list-item"> {% trans '无结果' %}
<div class="list-label"> </div>
<a href="{% url 'users:home' mark.owner.id %}" class="list-owner-name">{{ mark.owner.username }}</a> {% endfor %}
<span>{{ mark.get_status_display }}</span>
{% if mark.rating %} </ul>
<span class="rating-star" data-rating-score="{{ mark.rating | floatformat:"0" }}"></span>
{% endif %}
{% if mark.is_private %}
<span class="icon-lock"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><path d="M17,8.48h-.73V6.27a6.27,6.27,0,1,0-12.53,0V8.48H3a.67.67,0,0,0-.67.67V19.33A.67.67,0,0,0,3,20H17a.67.67,0,0,0,.67-.67V9.15A.67.67,0,0,0,17,8.48ZM6.42,6.27h0a3.57,3.57,0,0,1,7.14,0h0V8.48H6.42Z"/></svg></span>
{% endif %}
<span class="item-time">{{ mark.edited_time }}</span>
</div>
{% if mark.text %}
<p class="mark-text">{{ mark.text }}</p>
{% endif %}
</div> </div>
{% empty %} <div class="pagination">
{% trans '无结果' %}
{% endfor %}
</ul>
<div class="pagination" >
<a {% if marks.pagination.has_prev %}
{% if marks.has_previous %} <a href="?page=1"
href="?page=1" class="pagination__nav-link pagination__nav-link">&laquo;</a>
{% else %} <a href="?page={{ marks.previous_page_number }}"
disabled class="pagination__nav-link pagination__nav-link--right-margin pagination__nav-link">&lsaquo;</a>
{% endif %}>
<button {% if not marks.has_previous %}disabled{% endif %} class="button button-clear">{% trans "首页" %}</button>
</a>&nbsp;&nbsp;
<a
{% if marks.has_previous %}
href="?page={{ marks.previous_page_number }}"
{% else %}
disabled
{% endif %}>
<button {% if not marks.has_previous %}disabled{% endif %} class="button button-clear">{% trans "上一页" %}</button>
</a>&nbsp;&nbsp;
<span class="page-index">
{% trans "第" %}{% if request.GET.page %}{{ request.GET.page }}{% else %}1{% endif %}{% trans "页" %}
</span>
&nbsp;&nbsp;<a
{% if marks.has_next %}
href="?page={{ marks.next_page_number }}"
{% else %}
disabled
{% endif %}
>
<button {% if not marks.has_next %}disabled{% endif %} class="button button-clear">{% trans "下一页" %}</button>
</a>
&nbsp;&nbsp;<a
{% if marks.has_next %}
href="?page={{ marks.paginator.num_pages }}"
{% else %}
disabled
{% endif %}>
<button {% if not marks.has_next %}disabled{% endif %} class="button button-clear">{% trans "末页" %}</button>
</a>
</div>
</div>
<div id="aside">
<div class="aside-card">
<div class="aside-item">
<a href="{% url 'books:retrieve' book.id %}"><img src="{{ book.cover.url }}" alt="" class="item-image"></a>
<h5 class="item-title"><a href="{% url 'books:retrieve' book.id %}">{{ book.title }}</a></h5>
{% if book.isbn %}
<div>ISBN: {{ book.isbn }}</div>
{% endif %} {% endif %}
<div>{% if book.pub_house %}{% trans '出版社:' %}{{ book.pub_house }}{% endif %}</div> {% for page in marks.pagination.page_range %}
{% if book.rating %}
{% trans '评分: ' %}<span class="rating-star" data-rating-score="{{ book.rating | floatformat:"0" }}"></span> {% if page == marks.pagination.current_page %}
<a href="?page={{ page }}"
class="pagination__page-link pagination__page-link--current">{{ page }}</a>
{% else %}
<a href="?page={{ page }}"
class="pagination__page-link">{{ page }}</a>
{% endif %} {% endif %}
{% endfor %}
{% if marks.pagination.has_next %}
<a href="?page={{ marks.next_page_number }}"
class="pagination__nav-link pagination__nav-link--left-margin">&rsaquo;</a>
<a href="?page={{ marks.pagination.last_page }}"
class="pagination__nav-link">&raquo;</a>
{% endif %}
</div> </div>
</div> </div>
</div> </div>
<div class="grid__aside" id="aside">
<div class="aside-section-wrapper">
<div class="entity-card">
<div class="entity-card__img-wrapper">
<a href="{% url 'books:retrieve' book.id %}"><img src="{{ book.cover.url }}" alt="" class="entity-card__img"></a>
</div>
<div class="entity-card__info-wrapper">
<h5 class="entity-card__title"><a href="{% url 'books:retrieve' book.id %}">{{ book.title }}</a></h5>
{% if book.isbn %}
<div>ISBN: {{ book.isbn }}</div>
{% endif %}
<div>{% if book.pub_house %}{% trans '出版社:' %}{{ book.pub_house }}{% endif %}</div>
{% if book.rating %}
{% trans '评分: ' %}<span class="entity-card__rating-star rating-star" data-rating-score="{{ book.rating | floatformat:"0" }}"></span>
<span class="entity-card__rating-score rating-score">{{ book.rating }}</span>
{% endif %}
</div>
</div>
</div>
</div>
</div>
</section> </section>
</div> </div>
<footer class="container"> {% include "partial/_footer.html" %}
<a href="https://donotban.com/@whitiewhite">去长毛象向作者提意见</a>
<a href="https://github.com/doubaniux/boofilsic/issues">报告错误</a>
<a href="https://github.com/doubaniux/boofilsic" id="githubLink">Github</a>
</footer>
</div> </div>
@ -161,16 +143,7 @@
if (q) if (q)
location.href = "{% url 'common:search' %}" + "?q=" + q; location.href = "{% url 'common:search' %}" + "?q=" + q;
} }
}); });
ratingLabels = $("#aside .rating-star");
$(ratingLabels).each( function(index, value) {
let ratingScore = $(this).data("rating-score") / 2;
$(this).starRating({
initialRating: ratingScore,
readOnly: true,
starSize: 15,
});
});
</script> </script>
</body> </body>

View file

@ -9,105 +9,103 @@
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<!-- <meta name="viewport" content="width=device-width, initial-scale=1.0"> --> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{% trans 'Nicedb - 查看评论' %}</title> <meta property="og:title" content="NiceDB书评 - {{ review.title }}">
<meta property="og:type" content="article">
<meta property="og:article:author" content="{{ review.owner.username }}">
<meta property="og:url" content="{{ request.build_absolute_uri }}">
<meta property="og:image" content="{{ request.scheme }}://{{ request.get_host }}{% static 'img/logo_square.svg' %}">
<title>{% trans 'Nicedb - 评论详情' %}</title>
<script src="https://cdn.staticfile.org/jquery/3.5.0/jquery.min.js"></script> <script src="https://cdn.staticfile.org/jquery/3.5.0/jquery.min.js"></script>
<script src="{% static 'lib/js/rating-star.js' %}"></script> <script src="{% static 'lib/js/rating-star.js' %}"></script>
<script src="{% static 'js/rating-star-readonly.js' %}"></script>
<link rel="stylesheet" href="{% static 'lib/css/rating-star.css' %}"> <link rel="stylesheet" href="{% static 'lib/css/rating-star.css' %}">
<link rel="stylesheet" href="{% static 'lib/css/milligram.css' %}"> <!-- <link rel="stylesheet" href="{% static 'lib/css/milligram.css' %}"> -->
<link rel="stylesheet" href="{% static 'css/boofilsic_browse.css' %}"> <!-- <link rel="stylesheet" href="{% static 'css/boofilsic_browse.css' %}"> -->
<link rel="stylesheet" href="{% static 'css/boofilsic.css' %}">
</head> </head>
<body> <body>
<div id="page-wrapper"> <div id="page-wrapper">
<div id="content-wrapper"> <div id="content-wrapper">
<section id="navbar" class="navbar"> {% include "partial/_navbar.html" %}
<div class="container">
<nav class="clearfix">
<a href="{% url 'common:home' %}">
<img src="{% static 'img/logo.svg' %}" alt="" class="logo">
</a>
<input type="search" class="search-box" name="q" id="searchInput" required="true" placeholder="{% trans '搜索书影音,多个关键字以空格分割' %}">
<a class="nav-link" id="logoutLink" href="{% url 'users:logout' %}">{% trans '登出' %}</a>
<a class="nav-link" href="{% url 'common:home' %}">{% trans '主页' %}</a>
{% if user.is_staff %}
<a class="nav-link" href="{% admin_url %}">{% trans '后台' %}</a>
{% endif %}
</nav>
</div>
</section>
<section id="content" class="container"> <section id="content">
<div class="row"> <div class="grid">
<div id="main"> <div class="grid__main" id="main">
<div class="main-section-wrapper">
<div class="review-head">
<div class="review"> <h5 class="review-head__title">
<div class="review-head clearfix"> {{ review.title }}
<div class="mark-label float-left"> </h5>
<h4> {% if review.is_private %}
{{ review.title }} <span class="icon-lock"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><svg
{% if review.is_private %} xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20">
<span class="icon-lock"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><path d="M17,8.48h-.73V6.27a6.27,6.27,0,1,0-12.53,0V8.48H3a.67.67,0,0,0-.67.67V19.33A.67.67,0,0,0,3,20H17a.67.67,0,0,0,.67-.67V9.15A.67.67,0,0,0,17,8.48ZM6.42,6.27h0a3.57,3.57,0,0,1,7.14,0h0V8.48H6.42Z"/></svg></span> <path
{% endif %} d="M17,8.48h-.73V6.27a6.27,6.27,0,1,0-12.53,0V8.48H3a.67.67,0,0,0-.67.67V19.33A.67.67,0,0,0,3,20H17a.67.67,0,0,0,.67-.67V9.15A.67.67,0,0,0,17,8.48ZM6.42,6.27h0a3.57,3.57,0,0,1,7.14,0h0V8.48H6.42Z" />
</h4> </svg></span>
<a href="{% url 'users:home' review.owner.id %}" class="mark-owner-name">{{ review.owner.username }}</a>
{% if mark %}
{% if mark.rating %}
<span class="rating-star" data-rating-score="{{ mark.rating | floatformat:"0" }}"></span>
{% endif %}
{% endif %}
<span class="mark-time">{{ review.edited_time }}</span>
</div>
{% if request.user == review.owner %}
<div class="edit float-right"><a href="{% url 'books:update_review' review.id %}">{% trans '编辑' %}</a></div>
<div class="edit float-right"><a href="{% url 'books:delete_review' review.id %}">{% trans '删除' %}</a></div>
{% endif %} {% endif %}
<div class="review-head__body">
<div class="review-head__info">
<a href="{% url 'users:home' review.owner.id %}" class="review-head__owner-link">{{ review.owner.username }}</a>
{% if mark %}
{% if mark.rating %}
<span class="review-head__rating-star rating-star" data-rating-score="{{ mark.rating | floatformat:"0" }}"></span>
{% endif %}
{% endif %}
<span class="review-head__time">{{ review.edited_time }}</span>
</div>
<div class="review-head__actions">
{% if request.user == review.owner %}
<a class="review-head__action-link" href="{% url 'books:update_review' review.id %}">{% trans '编辑' %}</a>
<a class="review-head__action-link" href="{% url 'books:delete_review' review.id %}">{% trans '删除' %}</a>
{% endif %}
</div>
</div>
<!-- <div class="dividing-line"></div> -->
<div id="rawContent">
{{ form.content }}
</div>
{{ form.media }}
</div> </div>
<div class="dividing-line"></div> </div>
<div id="rawContent">
{{ form.content }} </div>
<div class="grid__aside" id="aside">
<div class="aside-section-wrapper">
<div class="entity-card">
<div class="entity-card__img-wrapper">
<a href="{% url 'books:retrieve' book.id %}"><img src="{{ book.cover.url }}" alt=""
class="entity-card__img"></a>
</div>
<div class="entity-card__info-wrapper">
<h5 class="entity-card__title"><a href="{% url 'books:retrieve' book.id %}">{{ book.title }}</a></h5>
{% if book.isbn %}
<div>ISBN: {{ book.isbn }}</div>
{% endif %}
<div>{% if book.pub_house %}{% trans '出版社:' %}{{ book.pub_house }}{% endif %}</div>
{% if book.rating %}
{% trans '评分: ' %}<span class="entity-card__rating-star rating-star"
data-rating-score="{{ book.rating | floatformat:"0" }}"></span>
<span class="entity-card__rating-score rating-score">{{ book.rating }}</span>
{% endif %}
</div>
</div> </div>
{{ form.media }}
</div> </div>
</div> </div>
<div id="aside"> </div>
<div class="aside-card">
<div class="aside-item">
<a href="{% url 'books:retrieve' book.id %}"><img src="{{ book.cover.url }}" alt="" class="item-image"></a>
<h5 class="item-title"><a href="{% url 'books:retrieve' book.id %}">{{ book.title }}</a></h5>
{% if book.isbn %}
<div>ISBN: {{ book.isbn }}</div>
{% endif %}
<div>{% if book.author %}{% trans '作者:' %}
{% for author in book.author %}
<span>{{ author }}</span>
{% endfor %}
{% endif %}</div>
<div>{% if book.pub_house %}{% trans '出版社:' %}{{ book.pub_house }}{% endif %}</div>
<div>{%if book.pub_year %}{% trans '出版时间:' %}{{ book.pub_year }}{% trans '年' %}{% if book.pub_month %}{{ book.pub_month }}{% trans '月' %}{% endif %}{% endif %}</div>
{% if book.rating %}
{% trans '评分: ' %}<span class="rating-star" data-rating-score="{{ book.rating | floatformat:"0" }}"></span>
{% endif %}
</div>
</div>
</div>
</section> </section>
</div> </div>
<footer class="container"> {% include "partial/_footer.html" %}
<a href="https://donotban.com/@whitiewhite">去长毛象向作者提意见</a>
<a href="https://github.com/doubaniux/boofilsic/issues">报告错误</a>
<a href="https://github.com/doubaniux/boofilsic" id="githubLink">Github</a>
</footer>
</div> </div>
@ -126,15 +124,7 @@
location.href = "{% url 'common:search' %}" + "?q=" + q; location.href = "{% url 'common:search' %}" + "?q=" + q;
} }
}); });
ratingLabels = $("#aside .rating-star");
$(ratingLabels).each( function(index, value) {
let ratingScore = $(this).data("rating-score") / 2;
$(this).starRating({
initialRating: ratingScore,
readOnly: true,
starSize: 15,
});
});
$(".markdownx textarea").hide(); $(".markdownx textarea").hide();
</script> </script>
</body> </body>

View file

@ -10,135 +10,109 @@
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<!-- <meta name="viewport" content="width=device-width, initial-scale=1.0"> --> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{% trans 'Nicedb - 搜索结果' %}</title> <title>{% trans 'Nicedb - ' %}{{ book.title }}{% trans '的评论' %}</title>
<script src="https://cdn.staticfile.org/jquery/3.5.0/jquery.min.js"></script> <script src="https://cdn.staticfile.org/jquery/3.5.0/jquery.min.js"></script>
<script src="{% static 'lib/js/rating-star.js' %}"></script> <script src="{% static 'lib/js/rating-star.js' %}"></script>
<script src="{% static 'js/rating-star-readonly.js' %}"></script> <script src="{% static 'js/rating-star-readonly.js' %}"></script>
<link rel="stylesheet" href="{% static 'css/boofilsic_browse.css' %}">
<link rel="stylesheet" href="{% static 'lib/css/rating-star.css' %}"> <link rel="stylesheet" href="{% static 'lib/css/rating-star.css' %}">
<link rel="stylesheet" href="{% static 'lib/css/milligram.css' %}"> <link rel="stylesheet" href="{% static 'css/boofilsic.css' %}">
<!-- <link rel="stylesheet" href="{% static 'css/boofilsic_browse.css' %}"> -->
<!-- <link rel="stylesheet" href="{% static 'lib/css/milligram.css' %}"> -->
</head> </head>
<body> <body>
<div id="page-wrapper"> <div id="page-wrapper">
<div id="content-wrapper"> <div id="content-wrapper">
<section id="navbar" class="navbar"> {% include "partial/_navbar.html" %}
<div class="container">
<nav class="clearfix">
<a href="{% url 'common:home' %}">
<img src="{% static 'img/logo.svg' %}" alt="" class="logo">
</a>
<input type="search" class="search-box" name="q"
value="{% if request.GET.q %}{{ request.GET.q }}{% endif %}" id="searchInput" required="true" placeholder="{% trans '搜索书影音,多个关键字以空格分割' %}">
<a class="nav-link" id="logoutLink" href="{% url 'users:logout' %}">{% trans '登出' %}</a>
<a class="nav-link" href="{% url 'common:home' %}">{% trans '主页' %}</a>
{% if user.is_staff %}
<a class="nav-link" href="{% admin_url %}">{% trans '后台' %}</a>
{% endif %}
</nav>
</div>
</section>
<section id="content" class="container"> <section id="content">
<div class="row"> <div class="grid">
<div id="main"> <div class="grid__main" id="main">
<h5 class="list-head"> <div class="main-section-wrapper">
<a href="{% url 'books:retrieve' book.id %}">{{ book.title }}</a>{% trans ' 的评论' %} <div class="entity-reviews">
</h5> <h5 class="entity-reviews__title entity-reviews__title--stand-alone">
<ul class="result-items set"> <a href="{% url 'books:retrieve' book.id %}">{{ book.title }}</a>{% trans ' 的评论' %}
</h5>
{% for review in reviews %} <ul class="entity-reviews__review-list">
<div class="list-item"> {% for review in reviews %}
<div class="item-label">
<a href="{% url 'users:home' review.owner.id %}" class="item-owner-name">{{ review.owner.username }}</a> <li class="entity-reviews__review entity-reviews__review--wider">
{% if review.is_private %}
<span class="icon-lock"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><path d="M17,8.48h-.73V6.27a6.27,6.27,0,1,0-12.53,0V8.48H3a.67.67,0,0,0-.67.67V19.33A.67.67,0,0,0,3,20H17a.67.67,0,0,0,.67-.67V9.15A.67.67,0,0,0,17,8.48ZM6.42,6.27h0a3.57,3.57,0,0,1,7.14,0h0V8.48H6.42Z"/></svg></span> <a href="{% url 'users:home' review.owner.id %}" class="entity-reviews__owner-link">{{ review.owner.username }}</a>
{% endif %} {% if review.is_private %}
<span class="item-time">{{ review.edited_time }}</span> <span class="icon-lock"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><path d="M17,8.48h-.73V6.27a6.27,6.27,0,1,0-12.53,0V8.48H3a.67.67,0,0,0-.67.67V19.33A.67.67,0,0,0,3,20H17a.67.67,0,0,0,.67-.67V9.15A.67.67,0,0,0,17,8.48ZM6.42,6.27h0a3.57,3.57,0,0,1,7.14,0h0V8.48H6.42Z"/></svg></span>
</div> {% endif %}
<span class="entity-reviews__review-time">{{ review.edited_time }}</span>
<a href="{% url 'books:retrieve_review' review.id %}" class="review-title">{{ review.title }}</a>
<span href="{% url 'books:retrieve_review' review.id %}" class="entity-reviews__review-title"><a href="{% url 'books:retrieve_review' review.id %}">{{ review.title }}</a></span>
</li>
{% empty %}
<div>{% trans '无结果' %}</div>
{% endfor %}
</ul>
</div> </div>
{% empty %} <div class="pagination">
{% trans '无结果' %}
{% endfor %}
</ul>
<div class="pagination" >
<a {% if reviews.pagination.has_prev %}
{% if reviews.has_previous %} <a href="?page=1" class="pagination__nav-link pagination__nav-link">&laquo;</a>
href="?page=1" <a href="?page={{ reviews.previous_page_number }}"
{% else %} class="pagination__nav-link pagination__nav-link--right-margin pagination__nav-link">&lsaquo;</a>
disabled
{% endif %}>
<button {% if not reviews.has_previous %}disabled{% endif %} class="button button-clear">{% trans "首页" %}</button>
</a>&nbsp;&nbsp;
<a
{% if reviews.has_previous %}
href="?page={{ reviews.previous_page_number }}"
{% else %}
disabled
{% endif %}>
<button {% if not reviews.has_previous %}disabled{% endif %} class="button button-clear">{% trans "上一页" %}</button>
</a>&nbsp;&nbsp;
<span class="page-index">
{% trans "第" %}{% if request.GET.page %}{{ request.GET.page }}{% else %}1{% endif %}{% trans "页" %}
</span>
&nbsp;&nbsp;<a
{% if reviews.has_next %}
href="?page={{ reviews.next_page_number }}"
{% else %}
disabled
{% endif %}
>
<button {% if not reviews.has_next %}disabled{% endif %} class="button button-clear">{% trans "下一页" %}</button>
</a>
&nbsp;&nbsp;<a
{% if reviews.has_next %}
href="?page={{ reviews.paginator.num_pages }}"
{% else %}
disabled
{% endif %}>
<button {% if not reviews.has_next %}disabled{% endif %} class="button button-clear">{% trans "末页" %}</button>
</a>
</div>
</div>
<div id="aside">
<div class="aside-card">
<div class="aside-item">
<a href="{% url 'books:retrieve' book.id %}"><img src="{{ book.cover.url }}" alt="" class="item-image"></a>
<h5 class="item-title"><a href="{% url 'books:retrieve' book.id %}">{{ book.title }}</a></h5>
{% if book.isbn %}
<div>ISBN: {{ book.isbn }}</div>
{% endif %} {% endif %}
<div>{% if book.pub_house %}{% trans '出版社:' %}{{ book.pub_house }}{% endif %}</div> {% for page in reviews.pagination.page_range %}
{% if book.rating %}
{% trans '评分: ' %}<span class="rating-star" data-rating-score="{{ book.rating | floatformat:"0" }}"></span> {% if page == reviews.pagination.current_page %}
<a href="?page={{ page }}" class="pagination__page-link pagination__page-link--current">{{ page }}</a>
{% else %}
<a href="?page={{ page }}" class="pagination__page-link">{{ page }}</a>
{% endif %} {% endif %}
{% endfor %}
{% if reviews.pagination.has_next %}
<a href="?page={{ reviews.next_page_number }}"
class="pagination__nav-link pagination__nav-link--left-margin">&rsaquo;</a>
<a href="?page={{ reviews.pagination.last_page }}" class="pagination__nav-link">&raquo;</a>
{% endif %}
</div> </div>
</div> </div>
</div> </div>
<div class="grid__aside" id="aside">
<div class="aside-section-wrapper">
<div class="entity-card">
<div class="entity-card__img-wrapper">
<a href="{% url 'books:retrieve' book.id %}"><img src="{{ book.cover.url }}" alt=""
class="entity-card__img"></a>
</div>
<div class="entity-card__info-wrapper">
<h5 class="entity-card__title"><a href="{% url 'books:retrieve' book.id %}">{{ book.title }}</a></h5>
{% if book.isbn %}
<div>ISBN: {{ book.isbn }}</div>
{% endif %}
<div>{% if book.pub_house %}{% trans '出版社:' %}{{ book.pub_house }}{% endif %}</div>
{% if book.rating %}
{% trans '评分: ' %}<span class="entity-card__rating-star rating-star"
data-rating-score="{{ book.rating | floatformat:"0" }}"></span>
<span class="entity-card__rating-score rating-score">{{ book.rating }}</span>
{% endif %}
</div>
</div>
</div>
</div>
</div>
</section> </section>
</div> </div>
<footer class="container"> {% include "partial/_footer.html" %}
<a href="https://donotban.com/@whitiewhite">去长毛象向作者提意见</a>
<a href="https://github.com/doubaniux/boofilsic/issues">报告错误</a>
<a href="https://github.com/doubaniux/boofilsic" id="githubLink">Github</a>
</footer>
</div> </div>
@ -157,15 +131,6 @@
location.href = "{% url 'common:search' %}" + "?q=" + q; location.href = "{% url 'common:search' %}" + "?q=" + q;
} }
}); });
ratingLabels = $("#aside .rating-star");
$(ratingLabels).each( function(index, value) {
let ratingScore = $(this).data("rating-score") / 2;
$(this).starRating({
initialRating: ratingScore,
readOnly: true,
starSize: 15,
});
});
</script> </script>
</body> </body>

View file

@ -9,54 +9,49 @@
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<!-- <meta name="viewport" content="width=device-width, initial-scale=1.0"> --> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{% trans 'Nicedb - 主页' %}</title> <title>{% trans 'Nicedb - 主页' %}</title>
<script src="https://cdn.staticfile.org/jquery/3.5.0/jquery.min.js"></script> <script src="https://cdn.staticfile.org/jquery/3.5.0/jquery.min.js"></script>
<script src="{% static 'js/scrape.js' %}"></script> <script src="{% static 'js/scrape.js' %}"></script>
<link rel="stylesheet" href="{% static 'css/boofilsic_browse.css' %}"> <link rel="stylesheet" href="{% static 'css/boofilsic.css' %}">
<link rel="stylesheet" href="{% static 'lib/css/milligram.css' %}"> <!-- <link rel="stylesheet" href="{% static 'css/boofilsic_browse.css' %}"> -->
<!-- <link rel="stylesheet" href="{% static 'lib/css/milligram.css' %}"> -->
</head> </head>
<body> <body>
<style> <style>
#scrapeForm label{ #scrape {
font-size: small !important; overflow: auto;
} }
textarea { #scrape iframe {
width: 100%;
}
#scrape textarea {
height: 200px; height: 200px;
resize: vertical;
}
#scrape iframe {
height: 500px;
} }
</style> </style>
<div id="page-wrapper"> <div id="page-wrapper">
<div id="content-wrapper"> <div id="content-wrapper">
<section id="navbar" class="navbar"> {% include "partial/_navbar.html" %}
<div class="container">
<nav class="clearfix"> <section id="content">
<a href="{% url 'common:home' %}"> <div class="grid grid--reverse-order">
<img src="{% static 'img/logo.svg' %}" alt="" class="logo"> <div class="grid__main grid__main--reverse-order" id="main">
</a> <div class="main-section-wrapper">
<input type="search" class="search-box" name="q" <div id="scrape">
value="{% if request.GET.q %}{{ request.GET.q }}{% endif %}" id="searchInput" required="true" placeholder="{% trans '搜索书影音,多个关键字以空格分割' %}"> <h5>
<a class="nav-link" id="logoutLink" href="{% url 'users:logout' %}">{% trans '登出' %}</a> {% trans '根据豆瓣内容填写下方表单' %}
<a class="nav-link" href="{% url 'common:home' %}">{% trans '主页' %}</a> </h5>
{% if request.user.is_staff %} <iframe id='test' sandbox="allow-same-origin allow-scripts allow-popups allow-forms" src="https://search.douban.com/book/subject_search{% if q %}?search_text={{ q }}{% endif %}" frameborder="0"></iframe>
<a class="nav-link" href="{% admin_url %}">{% trans '后台' %}</a> <div class="dividing-line"></div>
{% endif %} <div id="parser">
</nav> <label style="font-size: small;">{% trans '解析器:' %}</label>
</div> <textarea name="parser" id="" cols="30" rows="40" placeholder="复制信息粘贴至此自动解析,例:
</section>
<section id="content" class="container">
<div class="row">
<div id="main">
<div class="set">
{% trans '根据豆瓣内容填写下方表单' %}
</div>
<iframe id='test' sandbox="allow-same-origin allow-scripts allow-popups allow-forms" src="https://search.douban.com/book/subject_search{% if q %}?search_text={{ q }}{% endif %}" frameborder="0"></iframe>
<div class="dividing-line"></div>
<div id="parser">
<label style="font-size: small;">{% trans '解析器:' %}</label>
<textarea name="parser" id="" cols="30" rows="40" placeholder="复制信息粘贴至此自动解析,例:
作者: [法] 雨果 作者: [法] 雨果
出版社: 人民文学出版社 出版社: 人民文学出版社
原作名: Les Misérables 原作名: Les Misérables
@ -67,42 +62,38 @@
装帧: 精装 装帧: 精装
丛书: 名著名译丛书 丛书: 名著名译丛书
ISBN: 9787020104345 ISBN: 9787020104345
"></textarea> "></textarea>
</div> </div>
<div class="dividing-line"></div> <div class="dividing-line"></div>
<div id="scrapeForm"> <div id="scrapeForm">
<form action="{% url 'books:create' %}" method="POST" enctype="multipart/form-data"> <form action="{% url 'books:create' %}" method="POST" enctype="multipart/form-data">
{% csrf_token %} {% csrf_token %}
{{ form }} {{ form }}
</form> </form>
<a href="{% url 'books:scrape' %}" class="button add-button submit">{% trans '剽取!' %}</a> <a href="{% url 'books:scrape' %}" class="button add-button submit">{% trans '剽取!' %}</a>
</div>
</div>
</div> </div>
</div> </div>
<div id="aside"> <div class="grid__aside grid__aside--reverse-order" id="aside">
<div class="aside-card"> <div class="aside-section-wrapper aside-section-wrapper--singular">
<div class="add-nav"> <h5>
<div class="set"> {% trans '复制详情页链接' %}
{% trans '或者复制详情页链接' %} </h5>
</div> <form action="{% url 'books:click_to_scrape' %}" method="post">
<form action="{% url 'books:click_to_scrape' %}" method="post"> {% csrf_token %}
{% csrf_token %} <input type="text" name="url" required placeholder="https://book.douban.com/subject/1000000/">
<input type="text" name="url" required placeholder="https://book.douban.com/subject/1000000/"> <input type="submit" class="button add-button" value="{% trans '一键取剽取!' %}">
<input type="submit" class="button add-button" value="{% trans '一键取剽取!' %}"> </form>
</form>
</div>
</div> </div>
</div> </div>
</div>
</section> </section>
</div> </div>
<footer class="container"> {% include "partial/_footer.html" %}
<a href="https://donotban.com/@whitiewhite">去长毛象向作者提意见</a>
<a href="https://github.com/doubaniux/boofilsic/issues">报告错误</a>
<a href="https://github.com/doubaniux/boofilsic" id="githubLink">Github</a>
</footer>
</div> </div>
<script> <script>

View file

@ -10,6 +10,8 @@ from django.core.files.uploadedfile import SimpleUploadedFile
from common.mastodon import mastodon_request_included from common.mastodon import mastodon_request_included
from common.mastodon.api import check_visibility, post_toot, TootVisibilityEnum from common.mastodon.api import check_visibility, post_toot, TootVisibilityEnum
from common.mastodon.utils import rating_to_emoji from common.mastodon.utils import rating_to_emoji
from common.utils import PageLinksGenerator
from common.views import PAGE_LINK_NUMBER
from .models import * from .models import *
from .forms import * from .forms import *
from .forms import BookMarkStatusTranslator from .forms import BookMarkStatusTranslator
@ -247,6 +249,7 @@ def retrieve_mark_list(request, book_id):
paginator = Paginator(queryset, MARK_PER_PAGE) paginator = Paginator(queryset, MARK_PER_PAGE)
page_number = request.GET.get('page', default=1) page_number = request.GET.get('page', default=1)
marks = paginator.get_page(page_number) marks = paginator.get_page(page_number)
marks.pagination = PageLinksGenerator(PAGE_LINK_NUMBER, page_number, paginator.num_pages)
for m in marks: for m in marks:
m.get_status_display = BookMarkStatusTranslator(m.status) m.get_status_display = BookMarkStatusTranslator(m.status)
return render( return render(
@ -430,6 +433,7 @@ def retrieve_review_list(request, book_id):
paginator = Paginator(queryset, REVIEW_PER_PAGE) paginator = Paginator(queryset, REVIEW_PER_PAGE)
page_number = request.GET.get('page', default=1) page_number = request.GET.get('page', default=1)
reviews = paginator.get_page(page_number) reviews = paginator.get_page(page_number)
reviews.pagination = PageLinksGenerator(PAGE_LINK_NUMBER, page_number, paginator.num_pages)
return render( return render(
request, request,
'books/review_list.html', 'books/review_list.html',

View file

@ -59,7 +59,7 @@ class RatingValidator:
) )
class ImageInput(forms.FileInput): class PreviewImageInput(forms.FileInput):
template_name = 'widgets/image.html' template_name = 'widgets/image.html'
def format_value(self, value): def format_value(self, value):
""" """

File diff suppressed because it is too large Load diff

View file

@ -4,7 +4,7 @@
--primary: #00a1cc; --primary: #00a1cc;
--secondary: #606c76; --secondary: #606c76;
--light: #ccc; --light: #ccc;
--bright: rgb(250, 250, 250); --bright: rgb(247, 247, 247);
} }
html { html {

View file

@ -4,7 +4,7 @@
--primary: #00a1cc; --primary: #00a1cc;
--secondary: #606c76; --secondary: #606c76;
--light: #ccc; --light: #ccc;
--bright: rgb(250, 250, 250); --bright: rgb(247, 247, 247);
} }
html { html {

View file

@ -1,89 +0,0 @@
.bg-mask {
background-color: black;
z-index: 1;
filter: opacity(20%);
position: fixed;
width: 100%;
height: 100%;
left: 0;
top: 0;
display: none;
}
.modal {
z-index: 2;
display: none;
position: fixed;
width: 500px;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background-color: var(--bright);
/* border: solid 2px var(--light); */
padding: 20px 20px 0px 20px;
color: var(--secondary);
}
.modal-head {
/* border-bottom: 1px solid var(--light); */
padding-bottom: 30px;
}
.modal-head .modal-title {
font-weight: bold;
}
.modal-head .modal-close svg {
height: 10px;
cursor: pointer;
fill: var(--light);
}
.modal-body form {
margin: 0;
}
.modal-body, .modal-body label {
font-size: small;
font-weight: normal;
}
.modal-body .modal-selection ul {
list-style-type: none;
display: inline;
}
.modal-body .modal-selection ul li, .modal-body .modal-selection ul label {
display: inline;
}
.modal-body .modal-selection ul li {
position: relative;
top: 1px;
}
.modal-body .modal-checkbox {
position: relative;
top: 1px;
}
.modal-body .modal-option {
}
.modal-body .modal-button {
margin: 15px 0 15px 0;
padding: 0;
}
.modal-body textarea {
height: 160px;
margin-top: 5px;
margin-bottom: 5px;
resize: vertical;
}
.modal-body input[type="checkbox"], .modal-body input[type="radio"] {
position: relative;
top: 2px;
}

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 30 30"><title>logo</title><path d="M2.46,18h.32l.55,1,.18.38h0a5.66,5.66,0,0,1,0-.6V18h.29v1.75H3.45l-.54-1-.18-.38h0c0,.19,0,.4,0,.59v.77h-.3Z" style="fill:#606c76"/><path d="M5.45,18h.31v1.75H5.45Z" style="fill:#606c76"/><path d="M7.34,18.88a.82.82,0,0,1,.8-.91.67.67,0,0,1,.5.22l-.16.2a.47.47,0,0,0-.34-.15c-.28,0-.48.24-.48.63s.18.64.48.64a.49.49,0,0,0,.37-.18l.17.2a.73.73,0,0,1-.56.25A.8.8,0,0,1,7.34,18.88Z" style="fill:#606c76"/><path d="M10.2,18h1.05v.26h-.74v.45h.63V19h-.63v.52h.77v.26H10.2Z" style="fill:#606c76"/><path d="M12.86,18h.47a.78.78,0,0,1,.85.87.78.78,0,0,1-.84.88h-.48Zm.45,1.5c.35,0,.55-.2.55-.63s-.2-.62-.55-.62h-.14V19.5Z" style="fill:#606c76"/><path d="M15.76,18h.56c.36,0,.62.11.62.43a.39.39,0,0,1-.24.38h0a.41.41,0,0,1,.34.42c0,.35-.29.51-.67.51h-.61Zm.53.72c.25,0,.35-.09.35-.24s-.11-.24-.34-.24h-.23v.48Zm0,.79c.26,0,.4-.09.4-.29s-.14-.26-.4-.26h-.26v.55Z" style="fill:#606c76"/><path d="M18.53,19.57a.2.2,0,1,1,.4,0,.2.2,0,1,1-.4,0Z" style="fill:#606c76"/><path d="M20.46,18.87c0-.57.31-.9.77-.9s.77.34.77.9-.32.91-.77.91S20.46,19.43,20.46,18.87Zm1.22,0c0-.39-.18-.63-.45-.63s-.45.24-.45.63.17.64.45.64S21.68,19.26,21.68,18.87Z" style="fill:#606c76"/><path d="M23.58,18h.59c.36,0,.64.13.64.52s-.28.55-.64.55h-.28v.68h-.31Zm.56.82c.24,0,.37-.1.37-.3s-.13-.27-.37-.27h-.25v.57Zm0,.16.23-.18.54.95h-.35Z" style="fill:#606c76"/><path d="M26.3,18.88a.83.83,0,0,1,.83-.91.72.72,0,0,1,.52.22l-.16.2a.5.5,0,0,0-.36-.15c-.31,0-.51.24-.51.63s.18.64.53.64a.44.44,0,0,0,.25-.07v-.38h-.33V18.8h.61v.77a.8.8,0,0,1-.56.21A.81.81,0,0,1,26.3,18.88Z" style="fill:#606c76"/><path d="M6.06,17H6l-3.61-.76a.18.18,0,0,1-.14-.18V10.78a.16.16,0,0,1,.07-.14.19.19,0,0,1,.15,0l3.6.76a.18.18,0,0,1,.14.18v5.27a.18.18,0,0,1-.06.14A.19.19,0,0,1,6.06,17ZM2.64,15.91l3.24.68V11.68L2.64,11Z" style="fill:#00a1cc"/><path d="M6.06,17A.15.15,0,0,1,6,17a.19.19,0,0,1-.07-.14V11.54A.18.18,0,0,1,6,11.36l3.6-.76a.2.2,0,0,1,.15,0,.19.19,0,0,1,.07.14v5.27a.18.18,0,0,1-.15.18L6.1,17Zm.18-5.31v4.91l3.24-.68V11Zm3.43,4.37Z" style="fill:#00a1cc"/><path d="M24.69,17a3.4,3.4,0,1,1,3.4-3.4A3.41,3.41,0,0,1,24.69,17Zm0-6.44a3,3,0,1,0,3,3A3,3,0,0,0,24.69,10.58Z" style="fill:#00a1cc"/><path d="M24.69,14.93A1.31,1.31,0,1,1,26,13.62,1.31,1.31,0,0,1,24.69,14.93Zm0-2.26a1,1,0,1,0,.95.95A.95.95,0,0,0,24.69,12.67Z" style="fill:#00a1cc"/><path d="M17.73,16H11.42a.18.18,0,0,1-.18-.18V11.39a.18.18,0,0,1,.18-.18h6.31a.18.18,0,0,1,.18.18v4.46A.18.18,0,0,1,17.73,16Zm-6.13-.36h6v-4.1h-6Z" style="fill:#00a1cc"/><path d="M19.94,16l-.08,0L17.65,14.9a.18.18,0,0,1-.1-.16V12.5a.18.18,0,0,1,.1-.16l2.21-1.11a.17.17,0,0,1,.17,0,.19.19,0,0,1,.09.15v4.46A.19.19,0,0,1,20,16Zm-2-1.4,1.85.92V11.69l-1.85.92Z" style="fill:#00a1cc"/></svg>

After

Width:  |  Height:  |  Size: 2.7 KiB

View file

@ -1,23 +0,0 @@
$(document).ready( function() {
// assume there is only one input[file] on page
// $("input[type='file']").each(function() {
// $(this).after('<img src="#" alt="" id="previewImage" style="margin:10px 0; max-width:500px;"/>');
// })
// mark required
$("input[required]").each(function() {
$(this).prev().prepend("*");
})
// preview uploaded pic
$("input[type='file']").change(function() {
if (this.files && this.files[0]) {
var reader = new FileReader();
reader.onload = function (e) {
$('#previewImage').attr('src', e.target.result);
}
reader.readAsDataURL(this.files[0]);
}
});
});

View file

@ -1,20 +1,21 @@
$(document).ready( function() { $(document).ready( function() {
$(".markdownx-preview").hide();
$(".markdownx textarea").attr("placeholder", "拖拽图片至编辑框即可插入哦~"); $(".markdownx textarea").attr("placeholder", "拖拽图片至编辑框即可插入哦~");
$(".preview-button").click(function() { $(".review-form__preview-button").click(function() {
if ($(".markdownx-preview").is(":visible")) { if ($(".markdownx-preview").is(":visible")) {
$(".preview-button").text("预览"); $(".review-form__preview-button").text("预览");
$(".markdownx-preview").hide(); $(".markdownx-preview").hide();
$(".markdownx textarea").show(); $(".markdownx textarea").show();
} else { } else {
$(".preview-button").text("编辑"); $(".review-form__preview-button").text("编辑");
$(".markdownx-preview").show(); $(".markdownx-preview").show();
$(".markdownx textarea").hide(); $(".markdownx textarea").hide();
} }
}); });
let ratingLabels = $("#main .rating-star"); let ratingLabels = $(".rating-star");
$(ratingLabels).each( function(index, value) { $(ratingLabels).each( function(index, value) {
let ratingScore = $(this).data("rating-score") / 2; let ratingScore = $(this).data("rating-score") / 2;
$(this).starRating({ $(this).starRating({

View file

@ -7,12 +7,12 @@ $(document).ready( function() {
}); });
// pop up new rating modal // pop up new rating modal
$("#aside .mark .button-group .button").each(function() { $("#addMarkPanel button").each(function() {
$(this).click(function(e) { $(this).click(function(e) {
e.preventDefault(); e.preventDefault();
let title = $(this).text().trim(); let title = $(this).text().trim();
$(".mark-modal .modal-title").text(title); $(".mark-modal__title").text(title);
$(".mark-modal .modal-body textarea").val(""); $(".mark-modal__body textarea").val("");
let status = $(this).data('status') let status = $(this).data('status')
$("input[name='status'][value='"+status+"']").prop("checked", true) $("input[name='status'][value='"+status+"']").prop("checked", true)
$(".bg-mask").show(); $(".bg-mask").show();
@ -30,10 +30,10 @@ $(document).ready( function() {
}) })
// pop up modify mark modal // pop up modify mark modal
$(".mark a.edit").click(function(e) { $(".mark-panel a.edit").click(function(e) {
e.preventDefault(); e.preventDefault();
let title = $(".mark-status-label").text().trim(); let title = $(".mark-panel__status").text().trim();
$(".mark-modal .modal-title").text(title); $(".mark-modal__title").text(title);
$(".bg-mask").show(); $(".bg-mask").show();
$(".mark-modal").show(); $(".mark-modal").show();
}); });
@ -77,10 +77,10 @@ $(document).ready( function() {
// hide rating star when select wish // hide rating star when select wish
const WISH_CODE = 1; const WISH_CODE = 1;
if ($(".modal-selection input[type='radio']:checked").val() == WISH_CODE) { if ($("#statusSelection input[type='radio']:checked").val() == WISH_CODE) {
$(".mark-modal .rating-star-edit").hide(); $(".mark-modal .rating-star-edit").hide();
} }
$(".modal-selection#statusSelection input[type='radio']").click(function() { $("#statusSelection input[type='radio']").click(function() {
if ($(this).val() == WISH_CODE) { if ($(this).val() == WISH_CODE) {
$(".mark-modal .rating-star-edit").hide(); $(".mark-modal .rating-star-edit").hide();
} else { } else {
@ -90,16 +90,16 @@ $(document).ready( function() {
}); });
// show confirm modal // show confirm modal
$(".mark form a").click(function(e) { $(".mark-panel a.delete").click(function(e) {
e.preventDefault(); e.preventDefault();
$(".modal.confirm-modal").show(); $(".confirm-modal").show();
$(".bg-mask").show(); $(".bg-mask").show();
}); });
// confirm modal // confirm modal
$(".confirm-modal input[type='submit']").click(function(e) { $(".confirm-modal input[type='submit']").click(function(e) {
e.preventDefault(); e.preventDefault();
$(".mark form").submit(); $(".mark-panel form").submit();
}); });
}); });

View file

@ -8,8 +8,8 @@ $(document).ready( function() {
let followersSpinner = $("#spinner").clone().removeAttr("hidden"); let followersSpinner = $("#spinner").clone().removeAttr("hidden");
let followingSpinner = $("#spinner").clone().removeAttr("hidden"); let followingSpinner = $("#spinner").clone().removeAttr("hidden");
$("#userInfoCard").append(userInfoSpinner); $("#userInfoCard").append(userInfoSpinner);
$("#userRelationCard h5:first").append(followingSpinner); $("#followings h5").after(followingSpinner);
$("#userRelationCard h5:last").append(followersSpinner); $("#followers h5").after(followersSpinner);
$(".mast-following-more").hide(); $(".mast-following-more").hide();
$(".mast-followers-more").hide(); $(".mast-followers-more").hide();
@ -20,13 +20,13 @@ $(document).ready( function() {
function(userData) { function(userData) {
let userName; let userName;
if (userData.display_name) { if (userData.display_name) {
userName = translateEmojis(userData.display_name, userData.emojis); userName = translateEmojis(userData.display_name, userData.emojis, true);
} else { } else {
userName = userData.username; userName = userData.username;
} }
$(".mast-user .mast-avatar").attr("src", userData.avatar); $("#userInfoCard .mast-avatar").attr("src", userData.avatar);
$(".mast-user .mast-displayname").html(userName); $("#userInfoCard .mast-displayname").html(userName);
$(".mast-user .mast-brief").text($(userData.note).text()); $("#userInfoCard .mast-brief").text($(userData.note).text());
$(userInfoSpinner).remove(); $(userInfoSpinner).remove();
} }
); );
@ -38,6 +38,8 @@ $(document).ready( function() {
function(userList, request) { function(userList, request) {
if (userList.length == 0) { if (userList.length == 0) {
$(".mast-followers").hide(); $(".mast-followers").hide();
$(".mast-followers").before("<div>暂无</div>");
} else { } else {
if (userList.length > 4){ if (userList.length > 4){
userList = userList.slice(0, 4); userList = userList.slice(0, 4);
@ -49,9 +51,9 @@ $(document).ready( function() {
temp = $(template).clone(); temp = $(template).clone();
temp.find("img").attr("src", data.avatar); temp.find("img").attr("src", data.avatar);
if (data.display_name) { if (data.display_name) {
temp.find("a").html(translateEmojis(data.display_name, data.emojis)); temp.find(".mast-displayname").html(translateEmojis(data.display_name, data.emojis));
} else { } else {
temp.find("a").text(data.username); temp.find(".mast-displayname").text(data.username);
} }
let url = $("#userPageURL").text().replace('0', data.id); let url = $("#userPageURL").text().replace('0', data.id);
temp.find("a").attr('href', url); temp.find("a").attr('href', url);
@ -69,6 +71,7 @@ $(document).ready( function() {
function(userList, request) { function(userList, request) {
if (userList.length == 0) { if (userList.length == 0) {
$(".mast-following").hide(); $(".mast-following").hide();
$(".mast-following").before("<div>暂无</div>");
} else { } else {
if (userList.length > 4){ if (userList.length > 4){
userList = userList.slice(0, 4); userList = userList.slice(0, 4);
@ -80,9 +83,9 @@ $(document).ready( function() {
temp = $(template).clone() temp = $(template).clone()
temp.find("img").attr("src", data.avatar); temp.find("img").attr("src", data.avatar);
if (data.display_name) { if (data.display_name) {
temp.find("a").html(translateEmojis(data.display_name, data.emojis)); temp.find(".mast-displayname").html(translateEmojis(data.display_name, data.emojis));
} else { } else {
temp.find("a").text(data.username); temp.find(".mast-displayname").text(data.username);
} }
let url = $("#userPageURL").text().replace('0', data.id); let url = $("#userPageURL").text().replace('0', data.id);
temp.find("a").attr('href', url); temp.find("a").attr('href', url);

View file

@ -142,11 +142,18 @@ function getEmojiDict(emoji_list) {
return dict; return dict;
} }
function translateEmojis(text, emoji_list) { function translateEmojis(text, emoji_list, large) {
let dict = getEmojiDict(emoji_list); let dict = getEmojiDict(emoji_list);
let regex = /:(.*?):/g; let regex = /:(.*?):/g;
let translation = text.replace(regex, function (match) { let translation = null
return "<img src=" + dict[match] + " class=emoji alt=" + match + ">"; if (large) {
}); translation = text.replace(regex, function (match) {
return "<img src=" + dict[match] + " class=emoji--large alt=" + match + ">";
});
} else {
translation = text.replace(regex, function (match) {
return "<img src=" + dict[match] + " class=emoji alt=" + match + ">";
});
}
return translation; return translation;
} }

View file

@ -0,0 +1,285 @@
$aside-section-padding: 28px 25px 12px 25px
$aside-section-padding-mobile: 24px 25px 10px 25px
.aside-section-wrapper
display: flex
flex: 1
flex-direction: column
// align-items: center
width: 100%
padding: $aside-section-padding
background-color: $color-bright
margin-bottom: 30px
&--transparent
background-color: unset
&--collapse
padding: unset
.add-entity-entries
& &__entry
margin-bottom: 10px
& &__label
font-size: 1.2em
margin-bottom: 8px
& &__button
.action-panel
margin-bottom: 20px
& &__label
// font-size: 1.2em
font-weight: bold
margin-bottom: 12px
& &__button-group
display: flex
justify-content: space-between
&--center
justify-content: center
& &__button
line-height: unset
height: unset
padding: 4px 15px
margin: 0 5px
// width: 100%
.mark-panel
margin-bottom: 20px
& &__status
font-weight: bold
& &__rating-star
position: relative
top: 2px
& &__actions
float: right
& form
display: inline
& &__time
color: $color-light
margin-bottom: 10px
& &__content
& &__clear
@include clear
.review-panel
& &__label
font-weight: bold
& &__actions
float: right
& &__time
color: $color-light
margin-bottom: 10px
& &__review-title
display: block
margin-bottom: 15px
font-weight: bold
& &__clear
@include clear
.user-profile
& &__header
display: flex
align-items: flex-start
margin-bottom: 15px
& &__avatar
width: 72px
& &__username
font-size: large
margin-left: 10px
margin-bottom: 0
& &__bio
& &__report-link
color: $color-light
.user-relation
& &__label
display: inline-block
font-size: large
margin-bottom: 10px
& &__more-link
margin-left: 5px
& &__related-user-list
display: flex
justify-content: flex-start
& &__related-user
flex-basis: 25%
padding: 0px 3px
text-align: center
display: inline-block
& > a
&:hover
color: $color-secondary
& &__related-user-avatar
width: 48px
& &__related-user-name
color: inherit
overflow: hidden
text-overflow: ellipsis
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
.report-panel
& &__label
display: inline-block
margin-bottom: 10px
& &__report-list
& &__report
margin: 2px 0
& &__user-link
margin: 0 2px
& &__all-link
margin-left: 5px
.relation-dropdown
& &__button
display: none
.entity-card
display: flex
margin-bottom: 10px
flex-direction: column
&--horizontal
flex-direction: row
& &__img
height: 150px
& &__rating-star
position: relative
top: 4px
left: -3px
& &__rating-score
position: relative
top: 1px
margin-left: 2px
& &__title
margin-bottom: 10px
margin-top: 5px
& &__info-wrapper
&--horizontal
margin-left: 20px
& &__img-wrapper
flex-basis: 100px
// Small devices (landscape phones, 576px and up)
@media (max-width: $small-devices)
.add-entity-entries
display: block !important
& &__button
width: 100%
.aside-section-wrapper
&:first-child
margin-right: 0 !important
margin-bottom: 0 !important
&--singular:first-child
margin-bottom: 20px !important
// &--no-padding
// padding: $aside-section-padding-mobile !important
// margin-top: 0 !important
.action-panel
flex-direction: column !important
.entity-card
&--horizontal
flex-direction: column !important
// flex-direction: column !important
& &__info-wrapper
margin-left: 10px !important
&--horizontal
margin-left: 0 !important
// Medium devices (tablets, 768px and up)
@media (max-width: $medium-devices)
pass
// Large devices (desktops, 992px and up)
@media (max-width: $large-devices)
.add-entity-entries
display: flex
justify-content: space-around
.aside-section-wrapper
padding: $aside-section-padding-mobile
margin-top: 20px
// &:not(:first-child)
&:not(:last-child)
margin-right: 20px
&--collapse
padding: $aside-section-padding-mobile !important
margin-top: 0
margin-bottom: 0
&:first-child
margin-right: 0
&--no-margin
margin: 0
.action-panel
flex-direction: row
& &__button-group
justify-content: space-evenly
.relation-dropdown
margin-bottom: 20px
& &__button
padding-bottom: 10px
background-color: $color-bright
width: 100%
display: flex
justify-content: center
align-items: center
& &__button > .icon-arrow
transition: transform 0.3s
& &__button:hover > .icon-arrow
transform: rotate(-180deg)
& &__button:hover + &__body
max-height: 500px
transition: max-height 0.6s ease-in
& &__body
background-color: $color-bright
max-height: 0
transition: max-height 0.6s ease-out
overflow: hidden
.entity-card
flex-direction: row
& &__info-wrapper
margin-left: 30px
// Extra large devices (large desktops, 1200px and up)
@media (max-width: $x-large-devices)
pass

View file

@ -0,0 +1,12 @@
// Blockquote
//
blockquote
border-left: .3rem solid $color-quaternary
margin-left: 0
margin-right: 0
padding: 1rem 1.5rem
*:last-child
margin-bottom: 0

View file

@ -0,0 +1,76 @@
// Button
//
.button,
button,
input[type='button'],
input[type='reset'],
input[type='submit']
background-color: $color-primary
border: .1rem solid $color-primary
border-radius: .4rem
color: $color-initial
cursor: pointer
display: inline-block
font-size: 1.1rem
font-weight: 700
height: 3.4rem
letter-spacing: .1rem
line-height: 3.4rem
padding: 0 2.8rem
// width: 100%
text-align: center
text-decoration: none
text-transform: uppercase
white-space: nowrap
&:focus,
&:hover
background-color: $color-secondary
border-color: $color-secondary
color: $color-initial
outline: 0
&[disabled]
cursor: default
opacity: .5
&:focus,
&:hover
background-color: $color-primary
border-color: $color-primary
&.button-outline
background-color: transparent
color: $color-primary
&:focus,
&:hover
background-color: transparent
border-color: $color-secondary
color: $color-secondary
&[disabled]
&:focus,
&:hover
border-color: inherit
color: $color-primary
&.button-clear
background-color: transparent
border-color: transparent
color: $color-primary
&:focus,
&:hover
background-color: transparent
border-color: transparent
color: $color-secondary
&[disabled]
&:focus,
&:hover
color: $color-primary

View file

@ -0,0 +1,22 @@
// Code
//
code
background: $color-tertiary
border-radius: .4rem
font-size: 86%
margin: 0 .2rem
padding: .2rem .5rem
white-space: nowrap
pre
background: $color-tertiary
border-left: .3rem solid $color-primary
overflow-y: hidden
& > code
border-radius: 0
display: block
padding: 1rem 1.5rem
white-space: pre

View file

@ -0,0 +1,13 @@
// Color
//
$color-initial: #fff !default
$color-primary: #00a1cc !default
$color-secondary: #606c76 !default
$color-tertiary: #fff !default
$color-quaternary: #d5d5d5 !default
$color-quinary: #e5e5e5 !default
$color-light: #ccc
$color-bright: rgb(247, 247, 247)

View file

@ -0,0 +1,8 @@
// Divider
//
hr
border: 0
border-top: .1rem solid $color-tertiary
margin: 3.0rem 0

View file

@ -0,0 +1,42 @@
// these 2 id selectors are to make footer stay at the bottom
#page-wrapper
position: relative
min-height: 100vh
z-index: 0
#content-wrapper
padding-bottom: 160px
// min-height: 100vh;
.footer
padding-top: 0.4em !important
text-align: center
margin-bottom: 4px !important
position: absolute !important
left: 50%
transform: translateX(-50%)
bottom: 0
width: 100%
&__border
// width: 100%
padding-top: 4px;
border-top: $color-bright solid 2px
&__link
margin: 0 12px
// Small devices (landscape phones, 576px and up)
@media (max-width: $small-devices)
#content-wrapper
padding-bottom: 120px
// Medium devices (tablets, 768px and up)
@media (max-width: $medium-devices)
pass
// Large devices (desktops, 992px and up)
@media (max-width: $large-devices)
pass
// Extra large devices (large desktops, 1200px and up)
@media (max-width: $x-large-devices)
pass

View file

@ -0,0 +1,39 @@
// Form
//
select
background: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" height="14" viewBox="0 0 29 14" width="29"><path fill="#d1d1d1" d="M9.37727 3.625l5.08154 6.93523L19.54036 3.625"/></svg>') center right no-repeat
padding-right: 3.0rem
&:focus
background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" height="14" viewBox="0 0 29 14" width="29"><path fill="#9b4dca" d="M9.37727 3.625l5.08154 6.93523L19.54036 3.625"/></svg>')
textarea
min-height: 6.5rem
width: 100%
input, select
width: 100%
label,
legend
display: block
// font-size: 1.6rem
// font-weight: 700
margin-bottom: .5rem
fieldset
border-width: 0
padding: 0
input[type='checkbox'],
input[type='radio']
display: inline
.label-inline
display: inline-block
font-weight: normal
margin-left: .5rem

View file

@ -0,0 +1,107 @@
// Base
//
// Set box-sizing globally to handle padding and border widths
\:root
font-size: 10px
*,
*:after,
*:before
box-sizing: inherit
// The base font-size is set at 62.5% for having the convenience
// of sizing rems in a way that is similar to using px: 1.6rem = 16px
html
box-sizing: border-box
// font-size: 62.5%
height: 100%
// Default body styles
body
color: $color-secondary
font-family: 'Roboto', 'Helvetica Neue', 'Helvetica', 'Arial', 'Microsoft YaHei Light', sans-serif
font-size: 1.3rem
font-weight: 300
letter-spacing: .05rem
line-height: 1.6
margin: 0
height: 100%
textarea
font-family: 'Roboto', 'Helvetica Neue', 'Helvetica', 'Arial', 'Microsoft YaHei Light', sans-serif
// default link styles
a
color: $color-primary
text-decoration: none
&:active,
&:hover,
&:hover:visited
color: $color-secondary
&:visited
// color: $color-primary
li
list-style: none
// clear the "x" button inside the search input box
input[type=text]::-ms-clear,
input[type=text]::-ms-reveal
display: none
width : 0
height: 0
input[type="search"]::-webkit-search-decoration,
input[type="search"]::-webkit-search-cancel-button,
input[type="search"]::-webkit-search-results-button,
input[type="search"]::-webkit-search-results-decoration
display: none;
input[type='email'],
input[type='number'],
input[type='password'],
input[type='search'],
input[type='tel'],
input[type='text'],
input[type='url'],
textarea,
select
appearance: none // Removes awkward default styles on some inputs for iOS
background-color: transparent
border: .1rem solid $color-light
border-radius: .4rem
box-shadow: none
box-sizing: inherit // Forced to replace inherit values of the normalize.css
padding: .6rem 1.0rem // The .6rem vertically centers text on FF, ignored by Webkit
&:focus
border-color: $color-primary
outline: 0
&::placeholder
color: $color-light
::selection
color: white
background-color: $color-primary
// Mixins
@mixin clear
content: ' '
clear: both
display: table
// Breakpoints
// Small devices (landscape phones, 576px and up)
$small-devices: 575.98px
// Medium devices (tablets, 768px and up)
$medium-devices: 767.98px
// Large devices (desktops, 992px and up)
$large-devices: 991.98px
// Extra large devices (large desktops, 1200px and up)
$x-large-devices: 1199.98px

View file

@ -0,0 +1,66 @@
// Grid
//
@mixin container
margin: 0 auto
position: relative
max-width: 110rem
padding: 0 2.0rem;
width: 100%
.grid
@include container
$main-width: 70%
$aside-width: 96% - $main-width
& &__main
width: $main-width
float: left
position: relative
& &__aside
width: $aside-width
// background-color: $color-bright
float: right
position: relative
display: flex
flex-direction: column
justify-content: space-around
&::after
@include clear
// Small devices (landscape phones, 576px and up)
@media (max-width: $small-devices)
.grid
& &__aside
flex-direction: column !important
// Medium devices (tablets, 768px and up)
@media (max-width: $medium-devices)
pass
// Large devices (desktops, 992px and up)
@media (max-width: $large-devices)
.grid
& &__main
width: 100%
float: none
& &__aside
width: 100%
float: none
flex-direction: row
&--tablet-column
flex-direction: column
&--reverse-order
transform: scaleY(-1)
& &__main--reverse-order
transform: scaleY(-1)
& &__aside--reverse-order
transform: scaleY(-1)
// Extra large devices (large desktops, 1200px and up)
@media (max-width: $x-large-devices)
pass

View file

@ -0,0 +1,51 @@
.icon-lock svg
fill: $color-light
height: 12px
position: relative
top: 1px
margin-left: 3px
.icon-cross svg
fill: $color-light
height: 10px
position: relative
.icon-arrow svg
fill: $color-secondary
height: 15px
position: relative
top: 3px
.spinner
display: inline-block
position: relative
left: 50%
transform: translateX(-50%) scale(0.4)
width: 80px
height: 80px
& div
transform-origin: 40px 40px
animation: spinner 1.2s linear infinite
&::after
content: " ";
display: block;
position: absolute;
top: 3px;
left: 37px;
width: 6px;
height: 18px;
border-radius: 20%;
background: $color-secondary
@for $i from 1 through 12
&:nth-child(#{$i})
transform: rotate(($i - 1) * 30deg)
animation-delay: (12 - $i) * -0.1s
@keyframes spinner
0%
opacity: 1
100%
opacity: 0

View file

@ -0,0 +1,19 @@
// Image
//
img
max-width: 100%
object-fit: contain
&.emoji
height: 14px
box-sizing: border-box
object-fit: contain
position: relative
top: 3px
&--large
height: 20px
position: relative
top: 2px

View file

@ -0,0 +1,22 @@
// List
//
dl,
ol,
ul
list-style: none
margin-top: 0
padding-left: 0
dl,
ol,
ul
// font-size: 90%
// margin: 1.5rem 0 1.5rem 3.0rem
ol
list-style: decimal inside
ul
list-style: circle inside

View file

@ -0,0 +1,385 @@
$main-section-padding: 32px 48px 32px 36px
$main-section-padding-mobile: 32px 28px 28px 28px
$section-title-margin: 20px
$sub-sections-between-margin: 28px
$sub-section-title-margin: 8px
.main-section-wrapper
padding: $main-section-padding
background-color: $color-bright
// for search result etc
.entity-list
& &__title
// font-size: large
margin-bottom: $section-title-margin
& &__entities
& &__entity
display: flex
margin-bottom: 36px
&::after
@include clear
& &__entity-img
// float: left
object-fit: contain
// height: 150px
$width: 100px
min-width: $width
max-width: $width
& &__entity-text
margin-left: 20px
overflow: hidden
// float: left
& &__entity-link
font-size: 1.2em
& &__entity-title
display: block
& &__entity-info
max-width: 76%
white-space: nowrap
overflow: hidden
display: inline-block
text-overflow: ellipsis
position: relative
top: 0.52em
&--full-length
max-width: 100%
& &__entity-brief
margin-top: 8px
display: -webkit-box
-webkit-box-orient: vertical
-webkit-line-clamp: 4
overflow: hidden
$rating-info-gap-width: 5px
& &__rating
display: inline-block
margin: 0
& &__rating--empty
// width: $empty-rating-width
margin-right: $rating-info-gap-width
& &__rating-score
margin-right: $rating-info-gap-width
position: relative
top: 1px
& &__rating-star
display: inline
position: relative
top: 0.3em
left: -0.3em
// detail page
.entity-detail
& &__img
height: 210px;
object-fit: contain;
float: left;
max-width: 150px;
& &__info
float: left
margin-left: 20px
overflow: hidden
text-overflow: ellipsis
width: 70%
& &__title
font-weight: bold
& &__fields
display: inline-block
vertical-align: top
width: 48%
& div, & span
margin: 1px 0
& &__rating
position: relative
top: -5px
& &__rating-star
position: relative
left: -4px
top: 3px
& &__rating-score
font-weight: bold
&::after
@include clear
$mark-review-padding: 3px 0
$mark-review-padding-wider: 6px 0
// includes title and description of an entity
// sub section
.entity-desc
margin-bottom: $sub-sections-between-margin
& &__title
margin-bottom: $sub-section-title-margin
& &__content
& &__empty
// includes marks of an entity
// sub section
.entity-marks
margin-bottom: $sub-sections-between-margin
& &__title
margin-bottom: $sub-section-title-margin
& > a
margin-right: 5px
&--stand-alone
margin-bottom: $section-title-margin
& &__more-link
margin-left: 5px
& &__mark-list
& &__mark
margin: 0
padding: $mark-review-padding
border-bottom: 1px dashed $color-quinary
&:last-child
border: none
&--wider
padding: $mark-review-padding-wider
& &__mark-content
margin-bottom: 0
& &__mark-time
color: $color-light
margin-left: 2px
& &__owner-link
& &__rating-star
position: relative
top: 4px
& &__empty
// includes reviews of an entity
// sub section
.entity-reviews
// when used alone
&:first-child
margin-bottom: $sub-sections-between-margin
& &__title
margin-bottom: $sub-section-title-margin
& > a
margin-right: 5px
&--stand-alone
margin-bottom: $section-title-margin
& &__more-link
margin-left: 5px
& &__review-list
& &__review
margin: 0
padding: $mark-review-padding
border-bottom: 1px dashed $color-quinary
&:last-child
border: none
&--wider
padding: $mark-review-padding-wider
& &__review-time
color: $color-light
margin-left: 2px
& &__review-title
& &__owner-link
& &__empty
.dividing-line
height: 0
width: 100%
margin: 40px 0 24px 0
border-top: solid 1px $color-light
// on home page
.entity-sort
margin-bottom: 30px
& &__label
font-size: large
display: inline-block
margin-bottom: $section-title-margin
& &__more-link
margin-left: 5px
& &__entity-list
display: flex
justify-content: flex-start
// padding-left: 24px
flex-wrap: wrap
& &__entity
padding: 0 10px
flex-basis: 20%
text-align: center
display: inline-block
color: $color-secondary
&:hover
color: $color-primary
& > a
color: inherit
& &__entity-img
height: 110px
& &__entity-name
text-overflow: ellipsis
overflow: hidden
display: -webkit-box
-webkit-box-orient: vertical
-webkit-line-clamp: 2
& &__empty
// follower/following list page
.related-user-list
& &__title
margin-bottom: $section-title-margin
& &__user
display: flex
justify-content: flex-start
margin-bottom: 20px
& &__user-info
margin-left: 15px
overflow: auto
& &__user-name
& &__user-bio
& &__user-avatar
max-height: 72px
// review detail page
.review-head
& &__title
display: inline-block
font-weight: bold
& &__body
margin-bottom: 10px
&::after
@include clear
& &__info
float: left
& &__owner-link
color: $color-light
&:hover
color: $color-primary
& &__time
color: $color-light
& &__rating-star
position: relative
top: 3px
left: -1px
& &__actions
float: right
& &__action-link
&:not(:first-child)
margin-left: 5px
// Small devices (landscape phones, 576px and up)
@media (max-width: $small-devices)
.entity-list
& &__entity
flex-direction: column
margin-bottom: 30px
& &__entity-text
margin-left: 0
& &__entity-img-wrapper
margin-bottom: 8px
& &__entity-info
max-width: unset
& &__rating--empty + &__entity-info
max-width: 70%
.entity-detail
flex-direction: column
& &__title
margin-bottom: 5px
& &__info
margin-left: 0
float: none
display: flex
flex-direction: column
width: 100%
& &__img
margin-bottom: 24px
float: none
height: unset
max-width: 170px;
& &__fields
width: unset
.entity-marks
& &__mark-list
& &__mark
& &__rating-star
& &__rating-star + &__mark-time
// display: block
.dividing-line
margin-top: 24px
.entity-sort
& &__entity
flex-basis: 50%
// margin-left: 10px
// margin-right: 10px
& &__entity-img
height: 130px
.review-head
& &__info
float: unset
& &__actions
float: unset
// Medium devices (tablets, 768px and up)
@media (max-width: $medium-devices)
pass
// Large devices (desktops, 992px and up)
@media (max-width: $large-devices)
.main-section-wrapper
padding: $main-section-padding-mobile
.entity-detail
display: flex
& &__info
// display: flex
// Extra large devices (large desktops, 1200px and up)
@media (max-width: $x-large-devices)
pass

View file

@ -0,0 +1,108 @@
.bg-mask
background-color: black
z-index: 1
filter: opacity(20%)
position: fixed
width: 100%
height: 100%
left: 0
top: 0
display: none
@mixin modal
z-index: 2
display: none
position: fixed
width: 500px
top: 50%
left: 50%
transform: translate(-50%, -50%)
background-color: $color-bright
padding: 20px 20px 10px 20px
color: $color-secondary
& &__head
margin-bottom: 30px
&::after
@include clear
& &__title
font-weight: bold
font-size: 1.2em
float: left
& &__close-button
float: right
& &__body
& &__confirm-button
float: right
.mark-modal
@include modal
& input[type="radio"]
margin-right: 0
& &__rating-star
display: inline
float: left
position: relative
left: -3px
& &__status-radio
float: right
& ul
margin-bottom: 0
& li, & label
display: inline
& input[type="radio"]
position: relative
top: 1px
& &__clear
@include clear
& &__content-input, & form textarea
height: 200px
width: 100%
margin-top: 5px
margin-bottom: 5px
resize: vertical
& &__option
margin-bottom: 24px
&::after
@include clear
& &__visibility-radio
float: left
& ul, & li, & label
display: inline
& label
font-size: normal
& input[type="radio"]
position: relative
top: 2px
& &__share-checkbox
float: right
& input[type="checkbox"]
position: relative
top: 2px
.confirm-modal
@include modal
// Small devices (landscape phones, 576px and up)
@media (max-width: $small-devices)
.mark-modal, .confirm-modal
width: 100%
// Medium devices (tablets, 768px and up)
@media (max-width: $medium-devices)
pass
// Large devices (desktops, 992px and up)
@media (max-width: $large-devices)
pass
// Extra large devices (large desktops, 1200px and up)
@media (max-width: $x-large-devices)
pass

View file

@ -0,0 +1,101 @@
.navbar
background-color: $color-bright
box-sizing: border-box
padding: 10px 0
margin-bottom: 50px
border-bottom: $color-light 0.5px solid
& &__wrapper
display: flex
justify-content: space-between
align-items: center
position: relative
& &__logo
flex-basis: 100px
& &__logo-link
display: inline-block
& &__link-list
margin: 0
display: flex
justify-content: space-around
& &__link
margin: 9px
color: $color-secondary
&:active,
&:hover,
&:hover:visited
color: $color-primary
&:visited
color: $color-secondary
& &__search-box
margin: 0 12% 0 15px
height: 32px
flex: 1
background-color: white !important
& &__dropdown-btn
display: none
padding: 0
margin: 0
border: none
background-color: transparent
color: $color-primary
&:focus,
&:hover
background-color: transparent
color: $color-secondary
// Small devices (landscape phones, 576px and up)
@media (max-width: $small-devices)
.navbar
padding: 2px 0
& &__wrapper
display: block
& &__logo-img
width: 72px
margin-right: 10px
position: relative
top: 7px
// dropdown
& &__link-list
// display: block
margin-top: 7px
max-height: 0
transition: max-height 0.6s ease-out
overflow: hidden;
& &__dropdown-btn
display: block
position: absolute
right: 5px
top: 3px
transform: scale(0.7)
&:hover + .navbar__link-list
max-height: 500px
transition: max-height 0.6s ease-in
& &__search-box
margin: 0
width: 46vw
height: 26px
padding: 4px 6px
// Medium devices (tablets, 768px and up)
@media (max-width: $medium-devices)
pass
// Large devices (desktops, 992px and up)
@media (max-width: $large-devices)
.navbar
margin-bottom: 20px
// Extra large devices (large desktops, 1200px and up)
@media (max-width: $x-large-devices)
pass

View file

@ -0,0 +1,61 @@
.pagination
// position: absolute
// bottom: 30px
// left: 50%
// transform: translateX(-50%)
text-align: center
width: 100%
& &__page-link
font-weight: normal
margin: 0 5px
&--current
font-weight: bold
font-size: 1.2em
// text-decoration: underline
color: $color-secondary
& &__nav-link
font-size: 1.4em
margin: 0 2px
$nav-link-edge-margin-width: 18px
&--right-margin
margin-right: $nav-link-edge-margin-width
&--left-margin
margin-left: $nav-link-edge-margin-width
&--hidden
display: none
// Small devices (landscape phones, 576px and up)
@media (max-width: $small-devices)
.pagination
& &__page-link
margin: 0 3px
& &__nav-link
font-size: 1.4em
margin: 0 2px
$nav-link-edge-margin-width: 10px
&--right-margin
margin-right: $nav-link-edge-margin-width
&--left-margin
margin-left: $nav-link-edge-margin-width
// Medium devices (tablets, 768px and up)
@media (max-width: $medium-devices)
pass
// Large devices (desktops, 992px and up)
@media (max-width: $large-devices)
pass
// Extra large devices (large desktops, 1200px and up)
@media (max-width: $x-large-devices)
pass

View file

@ -0,0 +1,67 @@
$single-section-padding: 32px 36px
$single-section-padding-mobile: 32px 28px
.single-section-wrapper
padding: $single-section-padding
background-color: $color-bright
overflow: auto
.entity-form, .review-form
overflow: auto
& > input[type='email'],
& > input[type='number'],
& > input[type='password'],
& > input[type='search'],
& > input[type='tel'],
& > input[type='text'],
& > input[type='url'],
& textarea
width: 100%
& img
display: block
.review-form
& &__preview-button
color: $color-primary
font-weight: bold
cursor: pointer
& &__fyi
color: $color-light
& &__main-content, & textarea
margin-bottom: 5px
resize: vertical
height: 400px
& &__option
margin-top: 24px
margin-bottom: 10px
&::after
@include clear
& &__visibility-radio
float: left
& ul, & li, & label
display: inline
& label
font-size: normal
& input[type="radio"]
position: relative
top: 2px
& &__share-checkbox
float: right
& input[type="checkbox"]
position: relative
top: 2px
// Small devices (landscape phones, 576px and up)
@media (max-width: $small-devices)
.review-form
& &__visibility-radio
float: unset
& &__share-checkbox
float: unset
position: relative
left: -3px

View file

@ -0,0 +1,27 @@
// Spacing
//
.button,
button,
dd,
dt,
li
margin-bottom: 1.0rem
fieldset,
input,
select,
textarea
margin-bottom: 1.5rem
blockquote,
dl,
figure,
form,
ol,
p,
pre,
table,
ul
margin-bottom: 1rem

View file

@ -0,0 +1,19 @@
// Table
//
table
border-spacing: 0
width: 100%
td,
th
border-bottom: .1rem solid $color-quinary
padding: 1.2rem 1.5rem
text-align: left
&:first-child
padding-left: 0
&:last-child
padding-right: 0

View file

@ -0,0 +1,48 @@
// Typography
//
b,
strong
font-weight: bold
p
margin-top: 0
h1,
h2,
h3,
h4,
h5,
h6
font-weight: 300
letter-spacing: -.1rem
margin-bottom: 2.0rem
margin-top: 0
h1
font-size: 4.6rem
line-height: 1.2
h2
font-size: 3.6rem
line-height: 1.25
h3
font-size: 2.8rem
line-height: 1.3
h4
font-size: 2.2rem
letter-spacing: -.08rem
line-height: 1.35
h5
font-size: 1.8rem
letter-spacing: -.05rem
line-height: 1.5
h6
font-size: 1.6rem
letter-spacing: 0
line-height: 1.4

View file

@ -0,0 +1,21 @@
// Utility
//
// Clear a float with .clearfix
.clearfix
&:after
clear: both
content: ' ' // The space content is one way to avoid an Opera bug.
display: table
// Float either direction
.float-left
float: left
.float-right
float: right
.highlight
font-weight: bold

View file

@ -0,0 +1,5 @@
.markdownx-preview > p
min-height: 100px
.rating-star .jq-star
cursor: unset !important

View file

@ -0,0 +1,33 @@
// Sass Modules
//
// milligram
@import Color
// @import Blockquote
@import Button
// @import Code
// @import Divider
@import Form
@import List
@import Spacing
// @import Table
@import Typography
@import Image
@import Utility
// boofilsic components
@import Global
@import Navbar
@import Grid
@import Pagination
@import Footer
@import Icon
@import Modal
// boofilsic modules
@import MainSection
@import AsideSection
@import SingleSection
@import Vendor

View file

@ -4,7 +4,7 @@
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<!-- <meta name="viewport" content="width=device-width, initial-scale=1.0"> --> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="refresh" content="3;url={% url 'common:home' %}"> <meta http-equiv="refresh" content="3;url={% url 'common:home' %}">
<link rel="stylesheet" href="{% static 'lib/css/milligram.css' %}"> <link rel="stylesheet" href="{% static 'lib/css/milligram.css' %}">
<link rel="stylesheet" href="{% static 'css/boofilsic_edit.css' %}"> <link rel="stylesheet" href="{% static 'css/boofilsic_edit.css' %}">
@ -13,17 +13,19 @@
</head> </head>
<body> <body>
<div class="box"> <div class="box">
<a href="{% url 'common:home' %}">
<img src="{% static 'img/logo.svg' %}" alt="logo" class="logo"> <a href="{% url 'common:home' %}">
</a> <img src="{% static 'img/logo.svg' %}" alt="logo" class="logo">
<div class="main-msg"> </a>
{{ msg }} <div class="main-msg">
</div> {{ msg }}
<div class="sec-msg"> </div>
{% if secondary_msg %} <div class="sec-msg">
{{ secondary_msg }} {% if secondary_msg %}
{% endif %} {{ secondary_msg }}
</div> {% endif %}
</div>
</div> </div>
</body> </body>

View file

@ -9,192 +9,235 @@
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<!-- <meta name="viewport" content="width=device-width, initial-scale=1.0"> --> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{% trans 'Nicedb - 主页' %}</title> <title>{% trans 'Nicedb - 主页' %}</title>
<script src="https://cdn.staticfile.org/jquery/3.5.0/jquery.min.js"></script> <script src="https://cdn.staticfile.org/jquery/3.5.0/jquery.min.js"></script>
<script src="{% static 'js/mastodon.js' %}"></script> <script src="{% static 'js/mastodon.js' %}"></script>
<script src="{% static 'js/home.js' %}"></script> <script src="{% static 'js/home.js' %}"></script>
<link rel="stylesheet" href="{% static 'css/boofilsic_browse.css' %}"> <!-- <link rel="stylesheet" href="{% static 'css/boofilsic_browse.css' %}"> -->
<link rel="stylesheet" href="{% static 'lib/css/milligram.css' %}"> <!-- <link rel="stylesheet" href="{% static 'lib/css/milligram.css' %}"> -->
<link rel="stylesheet" href="{% static 'css/boofilsic.css' %}">
</head> </head>
<body> <body>
<div id="page-wrapper"> <div id="page-wrapper">
<div id="content-wrapper"> <div id="content-wrapper">
<section id="navbar" class="navbar"> {% include "partial/_navbar.html" %}
<div class="container">
<nav class="clearfix"> <section id="content">
<a href="{% url 'common:home' %}"> <div class="grid grid--reverse-order">
<img src="{% static 'img/logo.svg' %}" alt="" class="logo"> <div class="grid__main grid__main--reverse-order">
</a>
<input type="search" class="search-box" name="q" id="searchInput" required="true" placeholder="{% trans '搜索书影音,多个关键字以空格分割' %}"> <div class="main-section-wrapper">
<a class="nav-link" id="logoutLink" href="{% url 'users:logout' %}">{% trans '登出' %}</a>
<a class="nav-link" href="{% url 'common:home' %}">{% trans '主页' %}</a> <div class="entity-sort" id="bookWish">
{% if request.user.is_staff %} <h5 class="entity-sort__label">
<a class="nav-link" href="{% admin_url %}">{% trans '后台' %}</a> {% trans '想读的书' %}
{% endif %} </h5>
</nav> {% if wish_books_more %}
</div> <a href="{% url 'users:book_list' user.id 'wish' %}"
</section> class="entity-sort__more-link">{% trans '更多' %}</a>
{% endif %}
<section id="content" class="container">
<div class="row"> <ul class="entity-sort__entity-list">
<div id="main"> {% for wish_book_mark in wish_book_marks %}
<li class="entity-sort__entity">
<div class="set" id="bookWish">
<h5 class="set-title"> <a href="{% url 'books:retrieve' wish_book_mark.book.id %}">
{% trans '想读的书' %} <img src="{{ wish_book_mark.book.cover.url }}"
</h5> alt="{{wish_book_mark.book.title}}" class="entity-sort__entity-img">
{% if wish_books_more %} <div class="entity-sort__entity-name" title="wish_book_mark.book.title">
<a href="{% url 'users:book_list' user.id 'wish' %}" class="more-link">{% trans '更多' %}</a> {{ wish_book_mark.book.title }}</div>
{% endif %} </a>
</li>
<ul class="row set-item-list"> {% empty %}
{% for wish_book_mark in wish_book_marks %} <div>暂无记录</div>
<li class="column column-20 set-item"> {% endfor %}
</ul>
<a href="{% url 'books:retrieve' wish_book_mark.book.id %}" >
<img src="{{ wish_book_mark.book.cover.url }}" alt="" class="set-item-image">
<span class="set-item-title">{{ wish_book_mark.book.title | truncate:15 }}</span>
</a>
</li>
{% empty %}
<p class="set-empty">暂无记录</p>
{% endfor %}
</ul>
</div>
<div class="set" id="bookDo">
<h5 class="set-title">
{% trans '在读的书' %}
</h5>
{% if do_books_more %}
<a href="{% url 'users:book_list' user.id 'do' %}" class="more-link">{% trans '更多' %}</a>
{% endif %}
<ul class="row set-item-list">
{% for do_book_mark in do_book_marks %}
<li class="column column-20 set-item">
<a href="{% url 'books:retrieve' do_book_mark.book.id %}" >
<img src="{{ do_book_mark.book.cover.url }}" alt="" class="set-item-image">
<span class="set-item-title">{{ do_book_mark.book.title | truncate:15 }}</span>
</a>
</li>
{% empty %}
<p class="set-empty">暂无记录</p>
{% endfor %}
</ul>
</div>
<div class="set" id="bookCollect">
<h5 class="set-title">
{% trans '读过的书' %}
</h5>
{% if collect_books_more %}
<a href="{% url 'users:book_list' user.id 'collect' %}" class="more-link">{% trans '更多' %}</a>
{% endif %}
<ul class="row set-item-list">
{% for collect_book_mark in collect_book_marks %}
<li class="column column-20 set-item">
<a href="{% url 'books:retrieve' collect_book_mark.book.id %}" >
<img src="{{ collect_book_mark.book.cover.url }}" alt="" class="set-item-image">
<span class="set-item-title">{{ collect_book_mark.book.title | truncate:15 }}</span>
</a>
</li>
{% empty %}
<p class="set-empty">暂无记录</p>
{% endfor %}
</ul>
</div>
</div>
<div id="aside">
<div class="aside-card mast-user" id="userInfoCard">
<div class="clearfix">
<img src="" class="info-avatar mast-avatar" alt="{{ user.username }}">
<a href="{% url 'users:home' user.id %}">
<h5 class="info-name mast-displayname"></h5>
</a>
</div> </div>
<p class="info-brief mast-brief"></p>
<!-- <a href="#" class="follow">{% trans '关注TA' %}</a> --> <div class="entity-sort" id="bookWish">
<h5 class="entity-sort__label">
{% if request.user != user %} {% trans '在读的书' %}
<a href="{% url 'users:report' %}?user_id={{ user.id }}" class="report">{% trans '举报用户' %}</a> </h5>
{% endif %} {% if do_books_more %}
<a href="{% url 'users:book_list' user.id 'do' %}"
class="entity-sort__more-link">{% trans '更多' %}</a>
{% endif %}
<ul class="entity-sort__entity-list">
{% for do_book_mark in do_book_marks %}
<li class="entity-sort__entity">
<a href="{% url 'books:retrieve' do_book_mark.book.id %}">
<img src="{{ do_book_mark.book.cover.url }}"
alt="{{do_book_mark.book.title}}" class="entity-sort__entity-img">
<div class="entity-sort__entity-name" title="{{do_book_mark.book.title}}">
{{ do_book_mark.book.title }}</div>
</a>
</li>
{% empty %}
<div>暂无记录</div>
{% endfor %}
</ul>
</div>
<div class="entity-sort" id="bookCollect">
<h5 class="entity-sort__label">
{% trans '读过的书' %}
</h5>
{% if collect_books_more %}
<a href="{% url 'users:book_list' user.id 'collect' %}"
class="entity-sort__more-link">{% trans '更多' %}</a>
{% endif %}
<ul class="entity-sort__entity-list">
{% for collect_book_mark in collect_book_marks %}
<li class="entity-sort__entity">
<a href="{% url 'books:retrieve' collect_book_mark.book.id %}">
<img src="{{ collect_book_mark.book.cover.url }}"
alt="{{collect_book_mark.book.title}}" class="entity-sort__entity-img">
<span class="entity-sort__entity-name"
title="{{collect_book_mark.book.title}}">{{ collect_book_mark.book.title }}</span>
</a>
</li>
{% empty %}
<div>暂无记录</div>
{% endfor %}
</ul>
</div>
</div> </div>
<div class="relation-card" id="userRelationCard">
<h5 class="relation-label">
{% trans '关注的人' %}
</h5>
<a href="{% url 'users:following' user.id %}" class="more-link mast-following-more">{% trans '更多' %}</a>
<ul class="row mast-following relation-user-list">
<li class="column column-25 relation-user">
<img src="" alt="" class="relation-avatar">
<a class="relation-name"></a>
</li>
</ul>
<h5 class="relation-label">
{% trans '被他们关注' %}
</h5>
<a href="{% url 'users:followers' user.id %}" class="more-link mast-followers-more">{% trans '更多' %}</a>
<ul class="row mast-followers relation-user-list">
<li class="column column-25 relation-user">
<img src="" alt="" class="relation-avatar">
<a class="relation-name"></a>
</li>
</ul>
</div>
{% if request.user.is_staff %}
<div class="report-card" id="reportMessageCard">
<h5 class="report-label">{% trans '举报信息' %}</h5>
<ul class="report-list">
{% for report in reports %}
<li class="report-message">
<a href="" class="report-user-link">{{ report.submit_user }}</a>{% trans '举报了' %}<a href="">{{ report.reported_user }}</a>
</li>
{% endfor %}
</ul>
<a href="{% url 'users:manage_report' %}">全部举报</a>
</div>
{% endif %}
</div> </div>
<div class="grid__aside grid__aside--reverse-order grid__aside--tablet-column">
<div class="aside-section-wrapper aside-section-wrapper--no-margin">
<div class="user-profile" id="userInfoCard">
<div class="user-profile__header">
<!-- <img src="" class="user-profile__avatar mast-avatar" alt="{{ user.username }}"> -->
<img src="" class="user-profile__avatar mast-avatar">
<a href="{% url 'users:home' user.id %}">
<h5 class="user-profile__username mast-displayname"></h5>
</a>
</div>
<p class="user-profile__bio mast-brief"></p>
<!-- <a href="#" class="follow">{% trans '关注TA' %}</a> -->
{% if request.user != user %}
<a href="{% url 'users:report' %}?user_id={{ user.id }}"
class="user-profile__report-link">{% trans '举报用户' %}</a>
{% endif %}
</div>
</div>
<div class="relation-dropdown">
<div class="relation-dropdown__button">
<span class="icon-arrow">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 10 10">
<path d="M8.12,3.29,5,6.42,1.86,3.29H.45L5,7.84,9.55,3.29Z" />
</svg>
</span>
</div>
<div class="relation-dropdown__body">
<div
class="aside-section-wrapper aside-section-wrapper--transparent aside-section-wrapper--collapse">
<div class="user-relation" id="followings">
<h5 class="user-relation__label">
{% trans '关注的人' %}
</h5>
<a href="{% url 'users:following' user.id %}"
class="user-relation__more-link mast-following-more">{% trans '更多' %}</a>
<ul class="user-relation__related-user-list mast-following">
<li class="user-relation__related-user">
<a>
<img src="" alt="" class="user-relation__related-user-avatar">
<div class="user-relation__related-user-name mast-displayname">
</div>
</a>
</li>
</ul>
</div>
<div class="user-relation" id="followers">
<h5 class="user-relation__label">
{% trans '被他们关注' %}
</h5>
<a href="{% url 'users:followers' user.id %}"
class="user-relation__more-link mast-followers-more">{% trans '更多' %}</a>
<ul class="user-relation__related-user-list mast-followers">
<li class="user-relation__related-user">
<a>
<img src="" alt="" class="user-relation__related-user-avatar">
<div class="user-relation__related-user-name mast-displayname">
</div>
</a>
</li>
</ul>
</div>
</div>
<div
class="aside-section-wrapper aside-section-wrapper--transparent aside-section-wrapper--collapse">
{% if request.user.is_staff and request.user == user%}
<div class="report-panel">
<h5 class="report-panel__label">{% trans '举报信息' %}</h5>
<a class="report-panel__all-link"
href="{% url 'users:manage_report' %}">全部举报</a>
<ul class="report-panel__report-list">
{% for report in reports %}
<li class="report-panel__report">
<a href="{% url 'users:home' report.submit_user.id %}"
class="report-panel__user-link">{{ report.submit_user }}</a>{% trans '举报了' %}<a
href="{% url 'users:home' report.reported_user.id %}"
class="report-panel__user-link">{{ report.reported_user }}</a>
</li>
{% empty %}
<div>{% trans '暂无新举报' %}</div>
{% endfor %}
</ul>
</div>
{% endif %}
</div>
</div>
</div>
</div>
</div>
</section> </section>
</div> </div>
<footer class="container"> {% include "partial/_footer.html" %}
<a href="https://donotban.com/@whitiewhite">去长毛象向作者提意见</a>
<a href="https://github.com/doubaniux/boofilsic/issues">报告错误</a>
<a href="https://github.com/doubaniux/boofilsic" id="githubLink">Github</a>
</footer>
</div> </div>
<div id="oauth2Token" hidden="true">{% oauth_token %}</div> <div id="oauth2Token" hidden="true">{% oauth_token %}</div>
<div id="mastodonURI" hidden="true">{% mastodon %}</div> <div id="mastodonURI" hidden="true">{% mastodon %}</div>
<!--current user mastodon id--> <!--current user mastodon id-->
<div id="userMastodonID" hidden="true">{{ user.mastodon_id }}</div> <div id="userMastodonID" hidden="true">{{ user.mastodon_id }}</div>
<div id="userPageURL" hidden="true">{% url 'users:home' 0 %}?is_mastodon_id=true</div> <div id="userPageURL" hidden="true">{% url 'users:home' 0 %}?is_mastodon_id=true</div>
<div class="spinner" id="spinner" hidden>
<div class="lds-spinner"> <div id="spinner" hidden>
<div></div> <div class="spinner">
<div></div> <div></div>
<div></div> <div></div>
<div></div> <div></div>
<div></div> <div></div>
<div></div> <div></div>
<div></div> <div></div>
<div></div> <div></div>
<div></div> <div></div>
<div></div> <div></div>
<div></div> <div></div>
<div></div> <div></div>
<div></div>
</div> </div>
</div> </div>
<script> <script>
$("#searchInput").on('keyup', function (e) { $("#searchInput").on('keyup', function (e) {
if (e.keyCode === 13) { if (e.keyCode === 13) {
@ -207,4 +250,4 @@
</body> </body>
</html> </html>

View file

@ -10,172 +10,155 @@
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<!-- <meta name="viewport" content="width=device-width, initial-scale=1.0"> --> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{% trans 'Nicedb - 搜索结果' %}</title> <title>{% trans 'Nicedb - 搜索结果' %}</title>
<script src="https://cdn.staticfile.org/jquery/3.5.0/jquery.min.js"></script> <script src="https://cdn.staticfile.org/jquery/3.5.0/jquery.min.js"></script>
<script src="{% static 'lib/js/rating-star.js' %}"></script> <script src="{% static 'lib/js/rating-star.js' %}"></script>
<script src="{% static 'js/rating-star-readonly.js' %}"></script> <script src="{% static 'js/rating-star-readonly.js' %}"></script>
<link rel="stylesheet" href="{% static 'css/boofilsic_browse.css' %}"> <link rel="stylesheet" href="{% static 'css/boofilsic.css' %}">
<!-- <link rel="stylesheet" href="{% static 'css/boofilsic_browse.css' %}"> -->
<link rel="stylesheet" href="{% static 'lib/css/rating-star.css' %}"> <link rel="stylesheet" href="{% static 'lib/css/rating-star.css' %}">
<link rel="stylesheet" href="{% static 'lib/css/milligram.css' %}"> <!-- <link rel="stylesheet" href="{% static 'lib/css/milligram.css' %}"> -->
</head> </head>
<body> <body>
<div id="page-wrapper"> <div id="page-wrapper">
<div id="content-wrapper"> <div id="content-wrapper">
<section id="navbar" class="navbar"> {% include 'partial/_navbar.html' %}
<div class="container">
<nav class="clearfix"> <section id="content">
<a href="{% url 'common:home' %}"> <div class="grid">
<img src="{% static 'img/logo.svg' %}" alt="" class="logo"> <div class="grid__main">
</a> <div class="main-section-wrapper">
<input type="search" class="search-box" name="q"
value="{% if request.GET.q %}{{ request.GET.q }}{% endif %}" id="searchInput" required="true" placeholder="{% trans '搜索书影音,多个关键字以空格分割' %}"> <div class="entity-list">
<a class="nav-link" id="logoutLink" href="{% url 'users:logout' %}">{% trans '登出' %}</a> {% if request.GET.q %}
<a class="nav-link" href="{% url 'common:home' %}">{% trans '主页' %}</a> <h5 class="entity-list__title">“{{ request.GET.q }}”{% trans '的搜索结果' %}</h5>
{% if user.is_staff %} {% endif %}
<a class="nav-link" href="{% admin_url %}">{% trans '后台' %}</a> <ul class="entity-list__entities">
{% endif %}
</nav> {% for book in items %}
<li class="entity-list__entity">
<div class="entity-list__entity-img-wrapper">
<a href="{% url 'books:retrieve' book.id %}">
<img src="{{ book.cover.url }}" alt="" class="entity-list__entity-img">
</a>
</div>
<div class="entity-list__entity-text">
<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>
</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 %}
{{ author }}{% if not forloop.last %},{% endif %}
{% endfor %}/
{% endif %}
{% if book.translator %}
{% trans '译者' %}
{% for translator in book.translator %}
{{ translator }}{% if not forloop.last %},{% endif %}
{% endfor %}/
{% endif %}
{% if book.orig_title %}
&nbsp;{% trans '原名' %}
{{ book.orig_title }}
{% endif %}
</span>
<p class="entity-list__entity-brief">
{{ book.brief }}
</p>
</div>
</li>
{% empty %}
{% trans '无结果' %}
{% endfor %}
</ul>
</div>
<div class="pagination" >
{% if items.pagination.has_prev %}
<a href="?page=1&q={% if request.GET.q %}{{ request.GET.q }}{% endif %}" class="pagination__nav-link pagination__nav-link">&laquo;</a>
<a href="?page={{ items.previous_page_number }}&q={% if request.GET.q %}{{ request.GET.q }}{% endif %}" class="pagination__nav-link pagination__nav-link--right-margin pagination__nav-link">&lsaquo;</a>
{% endif %}
{% for page in items.pagination.page_range %}
{% if page == items.pagination.current_page %}
<a href="?page={{ page }}&q={% if request.GET.q %}{{ request.GET.q }}{% endif %}" class="pagination__page-link pagination__page-link--current">{{ page }}</a>
{% else %}
<a href="?page={{ page }}&q={% if request.GET.q %}{{ request.GET.q }}{% endif %}" class="pagination__page-link">{{ page }}</a>
{% endif %}
{% endfor %}
{% if items.pagination.has_next %}
<a href="?page={{ items.next_page_number }}&q={% if request.GET.q %}{{ request.GET.q }}{% endif %}" class="pagination__nav-link pagination__nav-link--left-margin">&rsaquo;</a>
<a href="?page={{ items.pagination.last_page }}&q={% if request.GET.q %}{{ request.GET.q }}{% endif %}" class="pagination__nav-link">&raquo;</a>
{% endif %}
</div>
</div>
</div>
<div class="grid__aside">
<div class="aside-section-wrapper">
<div class="add-entity-entries">
<div class="add-entity-entries__entry">
<div class="add-entity-entries__label">
没有想要的结果?
</div>
<a href="{% url 'books:create' %}">
<button class="add-entity-entries__button">添加一个条目</button>
</a>
</div>
<div class="add-entity-entries__entry">
<div class="add-entity-entries__label">
或者(≖ ◡ ≖)✧
</div>
<a href="{% url 'books:scrape' %}{% if request.GET.q %}?q={{ request.GET.q }}{% endif %}">
<button class="add-entity-entries__button">从表瓣剽取数据</button>
</a>
</div>
</div>
</div>
</div>
</div> </div>
</section> </section>
<section id="content" class="container">
<div class="row">
<div id="main">
{% if request.GET.q %}
<div class="set">
<h5 class="set-title">
“{{ request.GET.q }}” {% trans '的搜索结果' %}
</h5>
</div>
{% endif %}
<ul class="result-items">
{% for book in items %}
<li class="result-item clearfix">
<a href="{% url 'books:retrieve' book.id %}">
<img src="{{ book.cover.url }}" alt="" class="result-book-cover">
</a>
<div class="result-info">
<a href="{% url 'books:retrieve' book.id %}" class="result-item-title">
{% if request.GET.q %}
{{ book.title | highlight:request.GET.q }}
{% else %}
{{ book.title }}
{% endif %}
</a>
{% if book.rating %}
<div class="rating-star" data-rating-score="{{ book.rating | floatformat:"0" }}"></div>
<span class="rating-score">
{{ book.rating }}
</span>
{% else %}
<span class="rating-empty"> {% trans '暂无评分' %}</span>
{% endif %}
<span class="result-book-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 %}
{{ author }}{% if not forloop.last %},{% endif %}
{% endfor %}/
{% endif %}
{% if book.translator %}
{% trans '译者' %}
{% for translator in book.translator %}
{{ translator }}{% if not forloop.last %},{% endif %}
{% endfor %}/
{% endif %}
{% if book.orig_title %}
&nbsp;{% trans '原名' %}
{{ book.orig_title }}
{% endif %}
</span>
<p class="result-item-brief">
{{ book.brief | truncate:170 }}
</p>
</div>
</li>
{% empty %}
{% trans '无结果' %}
{% endfor %}
</ul>
<div class="pagination" >
<a
{% if items.has_previous %}
href="?page=1&q={% if request.GET.q %}{{ request.GET.q }}{% endif %}"
{%else %}
disabled
{% endif %}>
<button {% if not items.has_previous %}disabled{% endif %} class="button button-clear">{% trans "首页" %}</button>
</a>&nbsp;&nbsp;
<a
{% if items.has_previous %}
href="?page={{ items.previous_page_number }}&q={% if request.GET.q %}{{ request.GET.q }}{% endif %}"
{%else %}
disabled
{% endif %}>
<button {% if not items.has_previous %}disabled{% endif %} class="button button-clear">{% trans "上一页" %}</button>
</a>&nbsp;&nbsp;
<span class="page-index">
{% trans "第" %}{% if request.GET.page %}{{ request.GET.page }}{% else %}1{% endif %}{% trans "页" %}
</span>
&nbsp;&nbsp;<a
{% if items.has_next %}
href="?page={{ items.next_page_number }}&q={% if request.GET.q %}{{ request.GET.q }}{% endif %}"
{% else %}
disabled
{% endif %}
>
<button {% if not items.has_next %}disabled{% endif %} class="button button-clear">{% trans "下一页" %}</button>
</a>
&nbsp;&nbsp;<a
{% if items.has_next %}
href="?page={{ items.paginator.num_pages }}&q={% if request.GET.q %}{{ request.GET.q }}{% endif %}"
{%else %}
disabled
{% endif %}>
<button {% if not items.has_next %}disabled{% endif %} class="button button-clear">{% trans "末页" %}</button>
</a>
</div>
</div>
<div id="aside">
<div class="aside-card">
<div class="add-nav">
<div>{% trans '没有想要的结果?' %}</div>
<a href="{% url 'books:create' %}" class="button add-button">{% trans '添加一个条目' %}</a>
<div>{% trans '或者' %}</div>
<a href="{% url 'books:scrape' %}{% if request.GET.q %}?q={{ request.GET.q }}{% endif %}" class="button add-button">{% trans '从表瓣剽取数据d(≖ ◡ ≖)✧' %}</a>
</div>
</div>
</div>
</section>
</div> </div>
<footer class="container"> {% include 'partial/_footer.html' %}
<a href="https://donotban.com/@whitiewhite">去长毛象向作者提意见</a>
<a href="https://github.com/doubaniux/boofilsic/issues">报告错误</a>
<a href="https://github.com/doubaniux/boofilsic" id="githubLink">Github</a>
</footer>
</div> </div>

View file

@ -0,0 +1,9 @@
<footer class="footer">
<div class="grid">
<div class="footer__border">
<a class="footer__link" target="_blank" href="https://donotban.com/@whitiewhite">作者长毛象</a>
<a class="footer__link" target="_blank" href="https://github.com/doubaniux/boofilsic/issues">报告错误</a>
<a class="footer__link" target="_blank" href="https://github.com/doubaniux/boofilsic" id="githubLink">Github</a>
</div>
</div>
</footer>

View file

@ -0,0 +1,28 @@
{% load static %}
{% load i18n %}
{% load admin_url %}
<section id="navbar">
<nav class="navbar">
<div class="grid">
<div class="navbar__wrapper">
<a href="{% url 'common:home' %}" class="navbar__logo">
<img src="{% static 'img/logo.svg' %}" alt="" class="navbar__logo-img">
</a>
<input type="search" class="navbar__search-box" name="q" id="searchInput" required="true"
placeholder="搜索书影音,多个关键字以空格分割">
<button class="navbar__dropdown-btn">• • •</button>
<ul class="navbar__link-list">
<a class="navbar__link" id="logoutLink" href="{% url 'users:logout' %}">{% trans '登出' %}</a>
<a class="navbar__link" href="{% url 'common:home' %}">{% trans '主页' %}</a>
{% if user.is_staff %}
<a class="navbar__link" href="{% admin_url %}">{% trans '后台' %}</a>
{% endif %}
</ul>
</div>
</div>
</nav>
</section>

View file

@ -1,2 +1,15 @@
<input type="{{ widget.type }}" name="{{ widget.name }}"{% include "django/forms/widgets/attrs.html" %}> <input type="{{ widget.type }}" name="{{ widget.name }}"{% include "django/forms/widgets/attrs.html" %}>
<img src="{{ widget.value|default_if_none:''|stringformat:'s' }}" alt="" id="previewImage" style="margin:10px 0; max-width:500px;"> <img src="{{ widget.value|default_if_none:''|stringformat:'s' }}" alt="" id="previewImage" style="margin:10px 0; max-width:500px;">
<script>
$("input[type='file'][name='{{ widget.name }}']").change(function () {
if (this.files && this.files[0]) {
var reader = new FileReader();
reader.onload = function (e) {
$('#previewImage').attr('src', e.target.result);
}
reader.readAsDataURL(this.files[0]);
}
});
</script>

57
common/utils.py Normal file
View file

@ -0,0 +1,57 @@
class PageLinksGenerator:
# TODO inherit django paginator
"""
Calculate the pages for multiple links pagination.
length -- the number of page links in pagination
"""
def __init__(self, length, current_page, total_pages):
current_page = int(current_page)
self.current_page = current_page
self.start_page = None
self.end_page = None
self.page_range = None
self.has_prev = None
self.has_next = None
start_page = current_page - length // 2
end_page = current_page + length // 2
# decision is based on the start page and the end page
# both sides overflow
if (start_page < 1 and end_page > total_pages)\
or length >= total_pages:
self.start_page = 1
self.end_page = total_pages
self.has_prev = False
self.has_next = False
elif start_page < 1 and not end_page > total_pages:
self.start_page = 1
# this won't overflow because the total pages are more than the length
self.end_page = end_page - (start_page - 1)
self.has_prev = False
if end_page == total_pages:
self.has_next = False
else:
self.has_next = True
elif not start_page < 1 and end_page > total_pages:
self.end_page = total_pages
self.start_page = start_page - (end_page - total_pages)
self.has_next = False
if start_page == 1:
self.has_prev = False
else:
self.has_prev = True
# both sides do not overflow
elif not start_page < 1 and not end_page > total_pages:
self.start_page = start_page
self.end_page = end_page
self.has_prev = True
self.has_next = True
self.first_page = 1
self.last_page = total_pages
self.page_range = range(self.start_page, self.end_page + 1)
# assert self.has_prev is not None and self.has_next is not None

View file

@ -2,6 +2,7 @@ from django.shortcuts import render
from django.contrib.auth.decorators import login_required from django.contrib.auth.decorators import login_required
from books.models import Book from books.models import Book
from common.models import MarkStatusEnum from common.models import MarkStatusEnum
from common.utils import PageLinksGenerator
from users.models import Report, User from users.models import Report, User
from django.core.paginator import Paginator from django.core.paginator import Paginator
from django.db.models import Q from django.db.models import Q
@ -14,6 +15,9 @@ BOOKS_PER_SET = 5
# how many items are showed in one search result page # how many items are showed in one search result page
ITEMS_PER_PAGE = 20 ITEMS_PER_PAGE = 20
# how many pages links in the pagination
PAGE_LINK_NUMBER = 7
@login_required @login_required
def home(request): def home(request):
@ -66,6 +70,7 @@ def search(request):
paginator = Paginator(queryset, ITEMS_PER_PAGE) paginator = Paginator(queryset, ITEMS_PER_PAGE)
page_number = request.GET.get('page', default=1) page_number = request.GET.get('page', default=1)
items = paginator.get_page(page_number) items = paginator.get_page(page_number)
items.pagination = PageLinksGenerator(PAGE_LINK_NUMBER, page_number, paginator.num_pages)
return render( return render(
request, request,

View file

View file

@ -1,7 +1,7 @@
from django import forms from django import forms
from .models import Report from .models import Report
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from common.forms import PreviewImageInput
class ReportForm(forms.ModelForm): class ReportForm(forms.ModelForm):
class Meta: class Meta:
@ -13,6 +13,8 @@ class ReportForm(forms.ModelForm):
] ]
widgets = { widgets = {
'message': forms.Textarea(attrs={'placeholder': _("详情")}), 'message': forms.Textarea(attrs={'placeholder': _("详情")}),
'image': PreviewImageInput()
# 'reported_user': forms.TextInput(),
} }
labels = { labels = {
'reported_user': _("举报的用户"), 'reported_user': _("举报的用户"),

View file

@ -11,29 +11,29 @@ $(document).ready( function() {
let followingSpinner = $("#spinner").clone().removeAttr("hidden"); let followingSpinner = $("#spinner").clone().removeAttr("hidden");
let mainSpinner = $("#spinner").clone().removeAttr("hidden"); let mainSpinner = $("#spinner").clone().removeAttr("hidden");
$("#main .user:first").hide(); $(".mast-user:first").hide();
$("#main").append(mainSpinner); $(".mast-user-list").append(mainSpinner);
$("#userInfoCard").append(userInfoSpinner); $("#userInfoCard").append(userInfoSpinner);
$("#userRelationCard h5:first").append(followingSpinner); $("#followings h5").after(followingSpinner);
$("#userRelationCard h5:last").append(followersSpinner); $("#followers h5").after(followersSpinner);
$(".mast-following-more").hide(); $(".mast-following-more").hide();
$(".mast-followers-more").hide(); $(".mast-followers-more").hide();
getUserInfo( getUserInfo(
id, id,
mast_uri, mast_uri,
token, token,
function(userData) { function (userData) {
let userName; let userName;
if (userData.display_name) { if (userData.display_name) {
userName = translateEmojis(userData.display_name, userData.emojis); userName = translateEmojis(userData.display_name, userData.emojis, true);
} else { } else {
userName = userData.username; userName = userData.username;
} }
$(".mast-user .mast-avatar").attr("src", userData.avatar); $("#userInfoCard .mast-avatar").attr("src", userData.avatar);
$(".mast-user .mast-displayname").html(userName); $("#userInfoCard .mast-displayname").html(userName);
$(".mast-user .mast-brief").text($(userData.note).text()); $("#userInfoCard .mast-brief").text($(userData.note).text());
$(userInfoSpinner).remove(); $(userInfoSpinner).remove();
} }
); );
@ -46,6 +46,7 @@ $(document).ready( function() {
let subUserList = null; let subUserList = null;
if (userList.length == 0) { if (userList.length == 0) {
$(".mast-followers").hide(); $(".mast-followers").hide();
$(".mast-followers").before("<div>暂无</div>");
} else { } else {
if (userList.length > 4){ if (userList.length > 4){
subUserList = userList.slice(0, 4); subUserList = userList.slice(0, 4);
@ -57,9 +58,9 @@ $(document).ready( function() {
temp = $(template).clone(); temp = $(template).clone();
temp.find("img").attr("src", data.avatar); temp.find("img").attr("src", data.avatar);
if (data.display_name) { if (data.display_name) {
temp.find("a").html(translateEmojis(data.display_name, data.emojis)); temp.find(".mast-displayname").html(translateEmojis(data.display_name, data.emojis));
} else { } else {
temp.find("a").text(data.username); temp.find(".mast-displayname").text(data.username);
} }
let url = $("#userPageURL").text().replace('0', data.id); let url = $("#userPageURL").text().replace('0', data.id);
temp.find("a").attr('href', url); temp.find("a").attr('href', url);
@ -68,20 +69,20 @@ $(document).ready( function() {
} }
$(followersSpinner).remove(); $(followersSpinner).remove();
// main // main
let template = $("#main .user").clone().show(); let template = $(".mast-user").clone().show();
userList.forEach(data => { userList.forEach(data => {
temp = $(template).clone(); temp = $(template).clone();
temp.find(".avatar").attr("src", data.avatar); temp.find("img").attr("src", data.avatar);
if (data.display_name) { if (data.display_name) {
temp.find(".user-name").html(translateEmojis(data.display_name, data.emojis)); temp.find(".mast-displayname").html(translateEmojis(data.display_name, data.emojis));
} else { } else {
temp.find(".user-name").text(data.username); temp.find(".mast-displayname").text(data.username);
} }
let url = $("#userPageURL").text().replace('0', data.id); let url = $("#userPageURL").text().replace('0', data.id);
temp.find("a").attr('href', url); temp.find("a").attr('href', url);
temp.find(".user-brief").text(data.note.replace(/(<([^>]+)>)/ig,"")); temp.find(".mast-brief").text(data.note.replace(/(<([^>]+)>)/ig,""));
$("#main .user:last").after(temp); $(".mast-user:last").after(temp);
}); });
mainSpinner.hide(); mainSpinner.hide();
@ -99,30 +100,31 @@ $(document).ready( function() {
mast_uri, mast_uri,
token, token,
function(userList, request) { function(userList, request) {
// aside
if (userList.length == 0) { if (userList.length == 0) {
$("#aside .mast-following").hide(); $(".mast-following").hide();
$(".mast-following").before("<div>暂无</div>");
} else { } else {
if (userList.length > 4){ if (userList.length > 4){
userList = userList.slice(0, 4); userList = userList.slice(0, 4);
$("#aside .mast-following-more").show(); $(".mast-following-more").show();
} }
let template = $("#aside .mast-following li").clone(); let template = $(".mast-following li").clone();
$("#aside .mast-following").html(""); $(".mast-following").html("");
userList.forEach(data => { userList.forEach(data => {
temp = $(template).clone() temp = $(template).clone()
temp.find("img").attr("src", data.avatar); temp.find("img").attr("src", data.avatar);
if (data.display_name) { if (data.display_name) {
temp.find("a").html(translateEmojis(data.display_name, data.emojis)); temp.find(".mast-displayname").html(translateEmojis(data.display_name, data.emojis));
} else { } else {
temp.find("a").text(data.username); temp.find(".mast-displayname").text(data.username);
} }
let url = $("#userPageURL").text().replace('0', data.id); let url = $("#userPageURL").text().replace('0', data.id);
temp.find("a").attr('href', url); temp.find("a").attr('href', url);
$("#aside .mast-following").append(temp); $(".mast-following").append(temp);
}); });
} }
$(followingSpinner).remove(); $(followingSpinner).remove();
} }
); );
@ -149,7 +151,7 @@ $(document).ready( function() {
mainSpinner.hide(); mainSpinner.hide();
return; return;
} }
let template = $("#main .user:first").clone().show(); let template = $(".mast-user:first").clone().show();
let newUrlFlag = false; let newUrlFlag = false;
request.getResponseHeader('link').split(',').forEach(link => { request.getResponseHeader('link').split(',').forEach(link => {
if (link.includes('next')) { if (link.includes('next')) {
@ -163,16 +165,17 @@ $(document).ready( function() {
} }
userList.forEach(data => { userList.forEach(data => {
temp = $(template).clone() temp = $(template).clone()
temp.find(".avatar").attr("src", data.avatar); temp.find("img").attr("src", data.avatar);
if (data.display_name) { if (data.display_name) {
temp.find(".user-name").html(translateEmojis(data.display_name, data.emojis)); temp.find(".mast-displayname").html(translateEmojis(data.display_name, data.emojis));
} else { } else {
temp.find(".user-name").text(data.username); temp.find(".mast-displayname").text(data.username);
} }
let url = $("#userPageURL").text().replace('0', data.id); let url = $("#userPageURL").text().replace('0', data.id);
temp.find("a").attr('href', url); temp.find("a").attr('href', url);
temp.find(".user-brief").text($(data.note).text()); temp.find(".mast-brief").text($(data.note).text());
$("#main .user:last").after(temp); // console.log($(temp).html())
$(".mast-user:last").after(temp);
}); });
mainSpinner.hide(); mainSpinner.hide();
// release lock // release lock

View file

@ -11,29 +11,29 @@ $(document).ready( function() {
let followingSpinner = $("#spinner").clone().removeAttr("hidden"); let followingSpinner = $("#spinner").clone().removeAttr("hidden");
let mainSpinner = $("#spinner").clone().removeAttr("hidden"); let mainSpinner = $("#spinner").clone().removeAttr("hidden");
$("#main .user:first").hide(); $(".mast-user:first").hide();
$("#main").append(mainSpinner); $(".mast-user-list").append(mainSpinner);
$("#userInfoCard").append(userInfoSpinner); $("#userInfoCard").append(userInfoSpinner);
$("#userRelationCard h5:first").append(followingSpinner); $("#followings h5").after(followingSpinner);
$("#userRelationCard h5:last").append(followersSpinner); $("#followers h5").after(followersSpinner);
$(".mast-following-more").hide(); $(".mast-following-more").hide();
$(".mast-followers-more").hide(); $(".mast-followers-more").hide();
getUserInfo( getUserInfo(
id, id,
mast_uri, mast_uri,
token, token,
function(userData) { function (userData) {
let userName; let userName;
if (userData.display_name) { if (userData.display_name) {
userName = translateEmojis(userData.display_name, userData.emojis); userName = translateEmojis(userData.display_name, userData.emojis, true);
} else { } else {
userName = userData.username; userName = userData.username;
} }
$(".mast-user .mast-avatar").attr("src", userData.avatar); $("#userInfoCard .mast-avatar").attr("src", userData.avatar);
$(".mast-user .mast-displayname").html(userName); $("#userInfoCard .mast-displayname").html(userName);
$(".mast-user .mast-brief").text($(userData.note).text()); $("#userInfoCard .mast-brief").text($(userData.note).text());
$(userInfoSpinner).remove(); $(userInfoSpinner).remove();
} }
); );
@ -42,11 +42,12 @@ $(document).ready( function() {
id, id,
mast_uri, mast_uri,
token, token,
function(userList, request) { function (userList, request) {
if (userList.length == 0) { if (userList.length == 0) {
$(".mast-followers").hide(); $(".mast-followers").hide();
$(".mast-followers").before("<div>暂无</div>");
} else { } else {
if (userList.length > 4){ if (userList.length > 4) {
userList = userList.slice(0, 4); userList = userList.slice(0, 4);
$(".mast-followers-more").show(); $(".mast-followers-more").show();
} }
@ -56,9 +57,9 @@ $(document).ready( function() {
temp = $(template).clone(); temp = $(template).clone();
temp.find("img").attr("src", data.avatar); temp.find("img").attr("src", data.avatar);
if (data.display_name) { if (data.display_name) {
temp.find("a").html(translateEmojis(data.display_name, data.emojis)); temp.find(".mast-displayname").html(translateEmojis(data.display_name, data.emojis));
} else { } else {
temp.find("a").text(data.username); temp.find(".mast-displayname").text(data.username);
} }
let url = $("#userPageURL").text().replace('0', data.id); let url = $("#userPageURL").text().replace('0', data.id);
temp.find("a").attr('href', url); temp.find("a").attr('href', url);
@ -77,43 +78,44 @@ $(document).ready( function() {
// aside // aside
let subUserList = null; let subUserList = null;
if (userList.length == 0) { if (userList.length == 0) {
$("#aside .mast-following").hide(); $(".mast-following").hide();
$(".mast-following").before("<div>暂无</div>");
} else { } else {
if (userList.length > 4){ if (userList.length > 4){
subUserList = userList.slice(0, 4); subUserList = userList.slice(0, 4);
$("#aside .mast-following-more").show(); $(".mast-following-more").show();
} }
let template = $("#aside .mast-following li").clone(); let template = $(".mast-following li").clone();
$("#aside .mast-following").html(""); $(".mast-following").html("");
subUserList.forEach(data => { subUserList.forEach(data => {
temp = $(template).clone() temp = $(template).clone()
temp.find("img").attr("src", data.avatar); temp.find("img").attr("src", data.avatar);
if (data.display_name) { if (data.display_name) {
temp.find("a").html(translateEmojis(data.display_name, data.emojis)); temp.find(".mast-displayname").html(translateEmojis(data.display_name, data.emojis));
} else { } else {
temp.find("a").text(data.username); temp.find(".mast-displayname").text(data.username);
} }
let url = $("#userPageURL").text().replace('0', data.id); let url = $("#userPageURL").text().replace('0', data.id);
temp.find("a").attr('href', url); temp.find("a").attr('href', url);
$("#aside .mast-following").append(temp); $(".mast-following").append(temp);
}); });
} }
$(followingSpinner).remove(); $(followingSpinner).remove();
// main // main
let template = $("#main .user").clone().show(); let template = $(".mast-user").clone().show();
userList.forEach(data => { userList.forEach(data => {
temp = $(template).clone() temp = $(template).clone()
temp.find(".avatar").attr("src", data.avatar); temp.find("img").attr("src", data.avatar);
if (data.display_name) { if (data.display_name) {
temp.find(".user-name").html(translateEmojis(data.display_name, data.emojis)); temp.find(".mast-displayname").html(translateEmojis(data.display_name, data.emojis));
} else { } else {
temp.find(".user-name").text(data.username); temp.find(".mast-displayname").text(data.username);
} }
let url = $("#userPageURL").text().replace('0', data.id); let url = $("#userPageURL").text().replace('0', data.id);
temp.find("a").attr('href', url); temp.find("a").attr('href', url);
temp.find(".user-brief").text(data.note.replace(/(<([^>]+)>)/ig,"")); temp.find(".mast-brief").text(data.note.replace(/(<([^>]+)>)/ig,""));
$("#main .user:last").after(temp); $(".mast-user:last").after(temp);
}); });
mainSpinner.hide(); mainSpinner.hide();
@ -149,7 +151,7 @@ $(document).ready( function() {
mainSpinner.hide(); mainSpinner.hide();
return; return;
} }
let template = $("#main .user:first").clone().show(); let template = $(".mast-user:first").clone().show();
let newUrlFlag = false; let newUrlFlag = false;
request.getResponseHeader('link').split(',').forEach(link => { request.getResponseHeader('link').split(',').forEach(link => {
if (link.includes('next')) { if (link.includes('next')) {
@ -161,23 +163,25 @@ $(document).ready( function() {
if (!newUrlFlag) { if (!newUrlFlag) {
nextUrl = null; nextUrl = null;
} }
// console.log(userList.length)
userList.forEach(data => { userList.forEach(data => {
temp = $(template).clone() temp = $(template).clone()
temp.find(".avatar").attr("src", data.avatar); temp.find("img").attr("src", data.avatar);
if (data.display_name) { if (data.display_name) {
temp.find(".user-name").html(translateEmojis(data.display_name, data.emojis)); temp.find(".mast-displayname").html(translateEmojis(data.display_name, data.emojis));
} else { } else {
temp.find(".user-name").text(data.username); temp.find(".mast-displayname").text(data.username);
} }
let url = $("#userPageURL").text().replace('0', data.id); let url = $("#userPageURL").text().replace('0', data.id);
temp.find("a").attr('href', url); temp.find("a").attr('href', url);
temp.find(".user-brief").text($(data.note).text()); temp.find(".mast-brief").text($(data.note).text());
$("#main .user:last").after(temp); // console.log($(temp).html())
$(".mast-user:last").after(temp);
}); });
mainSpinner.hide(); mainSpinner.hide();
// release lock
// console.log(userList[userList.length-1].username) // console.log(userList[userList.length-1].username)
// console.log(nextUrl) // console.log(nextUrl)
// release lock
requesting = false; requesting = false;
}, },
}); });

View file

@ -1,157 +0,0 @@
{% load static %}
{% load i18n %}
{% load admin_url %}
{% load mastodon %}
{% load oauth_token %}
{% load truncate %}
{% load highlight %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<!-- <meta name="viewport" content="width=device-width, initial-scale=1.0"> -->
{% if is_followers_page %}
<title>{% trans 'Nicedb - 被他们关注' %}</title>
{% else %}
<title>{% trans 'Nicedb - 关注的人' %}</title>
{% endif %}
<script src="https://cdn.staticfile.org/jquery/3.5.0/jquery.min.js"></script>
<script src="{% static 'js/mastodon.js' %}"></script>
{% if is_followers_page %}
<script src="{% static 'js/followers_list.js' %}"></script>
{% else %}
<script src="{% static 'js/following_list.js' %}"></script>
{% endif %}
<link rel="stylesheet" href="{% static 'css/boofilsic_browse.css' %}">
<link rel="stylesheet" href="{% static 'lib/css/milligram.css' %}">
</head>
<body>
<div id="page-wrapper">
<div id="content-wrapper">
<section id="navbar" class="navbar">
<div class="container">
<nav class="clearfix">
<a href="{% url 'common:home' %}">
<img src="{% static 'img/logo.svg' %}" alt="" class="logo">
</a>
<input type="search" class="search-box" name="q"
value="{% if request.GET.q %}{{ request.GET.q }}{% endif %}" id="searchInput" required="true" placeholder="{% trans '搜索书影音,多个关键字以空格分割' %}">
<a class="nav-link" id="logoutLink" href="{% url 'users:logout' %}">{% trans '登出' %}</a>
<a class="nav-link" href="{% url 'common:home' %}">{% trans '主页' %}</a>
{% if request.user.is_staff %}
<a class="nav-link" href="{% admin_url %}">{% trans '后台' %}</a>
{% endif %}
</nav>
</div>
</section>
<section id="content" class="container">
<div class="row">
<div id="main">
<div class="set">
<h5 class="set-title">
{% if is_followers_page %}
{% trans ' 被他们关注' %}
{% else %}
{% trans '关注的人' %}
{% endif %}
</h5>
<div class="user clearfix">
<img src="" alt="" class="avatar float-left">
<div class="user-info float-left">
<a href="">
<div class="user-name"></div>
</a>
<p class="user-brief"></p>
</div>
</div>
</div>
</div>
<div id="aside">
<div class="aside-card mast-user" id="userInfoCard">
<div class="clearfix">
<img src="" class="info-avatar mast-avatar" alt="{{ user.username }}">
<a href="{% url 'users:home' user.id %}">
<h5 class="info-name mast-displayname"></h5>
</a>
</div>
<p class="info-brief mast-brief"></p>
<!-- <a href="#" class="follow">{% trans '关注TA' %}</a> -->
{% if request.user != user %}
<a href="{% url 'users:report' %}?user_id={{ user.id }}" class="report">{% trans '举报用户' %}</a>
{% endif %}
</div>
<div class="relation-card" id="userRelationCard">
<h5 class="relation-label">
{% trans '关注的人' %}
</h5>
<a href="{% url 'users:following' user.id %}" class="more-link mast-following-more">{% trans '更多' %}</a>
<ul class="row mast-following relation-user-list">
<li class="column column-25 relation-user">
<img src="" alt="" class="relation-avatar">
<a class="relation-name"></a>
</li>
</ul>
<h5 class="relation-label">
{% trans '被他们关注' %}
</h5>
<a href="{% url 'users:followers' user.id %}" class="more-link mast-followers-more">{% trans '更多' %}</a>
<ul class="row mast-followers relation-user-list">
<li class="column column-25 relation-user">
<img src="" alt="" class="relation-avatar">
<a class="relation-name"></a>
</li>
</ul>
</div>
</div>
</section>
</div>
<footer class="container">
<a href="https://donotban.com/@whitiewhite">去长毛象向作者提意见</a>
<a href="https://github.com/doubaniux/boofilsic/issues">报告错误</a>
<a href="https://github.com/doubaniux/boofilsic" id="githubLink">Github</a>
</footer>
</div>
<div id="oauth2Token" hidden="true">{% oauth_token %}</div>
<div id="mastodonURI" hidden="true">{% mastodon %}</div>
<!--current user mastodon id-->
<div id="userMastodonID" hidden="true">{{ user.mastodon_id }}</div>
<div id="userPageURL" hidden="true">{% url 'users:home' 0 %}?is_mastodon_id=true</div>
<div class="spinner" id="spinner" hidden>
<div class="lds-spinner">
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
</div>
</div>
<script>
$("#searchInput").on('keyup', function (e) {
if (e.keyCode === 13) {
let q = $(this).val();
if (q)
location.href = "{% url 'common:search' %}" + "?q=" + q;
}
});
</script>
</body>
</html>

View file

@ -5,7 +5,7 @@
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<!-- <meta name="viewport" content="width=device-width, initial-scale=1.0"> --> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="{% static 'lib/css/milligram.css' %}"> <link rel="stylesheet" href="{% static 'lib/css/milligram.css' %}">
<link rel="stylesheet" href="{% static 'css/boofilsic_edit.css' %}"> <link rel="stylesheet" href="{% static 'css/boofilsic_edit.css' %}">
<link rel="stylesheet" href="{% static 'css/boofilsic_box.css' %}"> <link rel="stylesheet" href="{% static 'css/boofilsic_box.css' %}">
@ -13,7 +13,8 @@
</head> </head>
<body> <body>
<div id="loginBox" class="box"> <div id="loginBox" class="box">
<img src="{% static 'img/logo.svg' %}" class="logo" alt="boofilsic logo"> <img src="{% static 'img/logo.svg' %}" class="logo" alt="boofilsic logo">
<div id="loginButton"> <div id="loginButton">
@ -25,6 +26,7 @@
{% endif %} {% endif %}
</div> </div>
</div> </div>
</body> </body>
</html> </html>

View file

@ -9,37 +9,23 @@
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<!-- <meta name="viewport" content="width=device-width, initial-scale=1.0"> --> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{% trans 'Nicedb - 管理举报' %}</title> <title>{% trans 'Nicedb - 管理举报' %}</title>
<script src="https://cdn.staticfile.org/jquery/3.5.0/jquery.min.js"></script> <script src="https://cdn.staticfile.org/jquery/3.5.0/jquery.min.js"></script>
<script src="{% static 'js/create_update.js' %}"></script> <script src="{% static 'js/create_update.js' %}"></script>
<link rel="stylesheet" href="{% static 'lib/css/milligram.css' %}"> <link rel="stylesheet" href="{% static 'css/boofilsic.css' %}">
<link rel="stylesheet" href="{% static 'css/boofilsic_edit.css' %}"> <!-- <link rel="stylesheet" href="{% static 'lib/css/milligram.css' %}"> -->
<!-- <link rel="stylesheet" href="{% static 'css/boofilsic_edit.css' %}"> -->
</head> </head>
<body> <body>
<div id="page-wrapper"> <div id="page-wrapper">
<div id="content-wrapper"> <div id="content-wrapper">
<section id="navbar" class="navbar"> {% include "partial/_navbar.html" %}
<div class="container">
<nav class="clearfix">
<a href="{% url 'common:home' %}">
<img src="{% static 'img/logo.svg' %}" alt="" class="logo">
</a>
<h4 class="nav-title">{% trans '举报信息' %}</h4>
<a class="nav-link" id="logoutLink" href="{% url 'users:logout' %}">{% trans '登出' %}</a>
<a class="nav-link" href="{% url 'common:home' %}">{% trans '主页' %}</a>
{% if user.is_staff %}
<a class="nav-link" href="{% admin_url %}">{% trans '后台' %}</a>
{% endif %}
</nav>
</div>
</section>
<section id="content" class="container"> <section id="content">
<div class="row"> <div class="grid">
<div id="main"> <div class="single-section-wrapper" id="main">
{% for report in reports %} {% for report in reports %}
<div class="report"> <div class="report">
@ -57,14 +43,11 @@
{% endfor %} {% endfor %}
</div> </div>
</div>
</section> </section>
</div> </div>
<footer class="container"> {% include "partial/_footer.html" %}
<a href="https://donotban.com/@whitiewhite">去长毛象向作者提意见</a>
<a href="https://github.com/doubaniux/boofilsic/issues">报告错误</a>
<a href="https://github.com/doubaniux/boofilsic" id="githubLink">Github</a>
</footer>
</div> </div>

View file

@ -5,7 +5,7 @@
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<!-- <meta name="viewport" content="width=device-width, initial-scale=1.0"> --> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="{% static 'lib/css/milligram.css' %}"> <link rel="stylesheet" href="{% static 'lib/css/milligram.css' %}">
<link rel="stylesheet" href="{% static 'css/boofilsic_edit.css' %}"> <link rel="stylesheet" href="{% static 'css/boofilsic_edit.css' %}">
<link rel="stylesheet" href="{% static 'css/boofilsic_box.css' %}"> <link rel="stylesheet" href="{% static 'css/boofilsic_box.css' %}">
@ -23,11 +23,10 @@
里瓣书影音继承了长毛象的用户关系比如您在里瓣屏蔽了某人那您将不会在书影音的公共区域看到TA的痕迹。 里瓣书影音继承了长毛象的用户关系比如您在里瓣屏蔽了某人那您将不会在书影音的公共区域看到TA的痕迹。
这里仍是一片处女地,丰富的内容需要大家共同创造! 这里仍是一片处女地,丰富的内容需要大家共同创造!
请注意虽然您可以随意发表任何言论,但试图添加垃圾数据到公共数据领域(如添加不存在的乱码的书籍)将会受到制裁! 请注意虽然您可以随意发表任何言论,但试图添加垃圾数据到公共数据领域(如添加不存在的乱码的书籍)将会受到制裁!
本站使用了Cookie请理解 BTW欧盟惯例本站使用了Cookie请理解
</p> </p>
<p> <p>
此外里瓣书影音现处于“公开阿尔法测试”阶段,您的数据存在丢失的可能,现阶段将不对用户数据负责,请您理解风险后再决定继续使用! 此外里瓣书影音现处于“公开阿尔法测试”阶段,您的数据存在丢失的可能
</p>
<form action="{% url 'users:register' %}" method="post"> <form action="{% url 'users:register' %}" method="post">
{% csrf_token %} {% csrf_token %}

View file

@ -0,0 +1,172 @@
{% load static %}
{% load i18n %}
{% load admin_url %}
{% load mastodon %}
{% load oauth_token %}
{% load highlight %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
{% if is_followers_page %}
<title>{% trans 'Nicedb - 被他们关注' %}</title>
{% else %}
<title>{% trans 'Nicedb - 关注的人' %}</title>
{% endif %}
<script src="https://cdn.staticfile.org/jquery/3.5.0/jquery.min.js"></script>
<script src="{% static 'js/mastodon.js' %}"></script>
{% if is_followers_page %}
<script src="{% static 'js/followers_list.js' %}"></script>
{% else %}
<script src="{% static 'js/following_list.js' %}"></script>
{% endif %}
<!-- <link rel="stylesheet" href="{% static 'css/boofilsic_browse.css' %}"> -->
<!-- <link rel="stylesheet" href="{% static 'lib/css/milligram.css' %}"> -->
<link rel="stylesheet" href="{% static 'css/boofilsic.css' %}">
</head>
<body>
<div id="page-wrapper">
<div id="content-wrapper">
{% include 'partial/_navbar.html' %}
<section id="content">
<div class="grid grid--reverse-order">
<div class="grid__main grid__main--reverse-order">
<div class="main-section-wrapper">
<div class="related-user-list mast-user-list">
<h5 class="related-user-list__title">
{% if is_followers_page %}
{% trans ' 被他们关注' %}
{% else %}
{% trans '关注的人' %}
{% endif %}
</h5>
<div class="related-user-list__user mast-user">
<img src="" alt="" class="related-user-list__user-avatar">
<div class="related-user-list__user-info">
<a href="">
<div class="related-user-list__user-name mast-displayname"></div>
</a>
<p class="related-user-list__user-bio mast-brief"></p>
</div>
</div>
</div>
</div>
</div>
<div class="grid__aside grid__aside--reverse-order grid__aside--tablet-column">
<div class="aside-section-wrapper aside-section-wrapper--no-margin">
<div class="user-profile" id="userInfoCard">
<div class="user-profile__header">
<!-- <img src="" class="user-profile__avatar mast-avatar" alt="{{ user.username }}"> -->
<img src="" class="user-profile__avatar mast-avatar">
<a href="{% url 'users:home' user.id %}">
<h5 class="user-profile__username mast-displayname"></h5>
</a>
</div>
<p class="user-profile__bio mast-brief"></p>
<!-- <a href="#" class="follow">{% trans '关注TA' %}</a> -->
{% if request.user != user %}
<a href="{% url 'users:report' %}?user_id={{ user.id }}"
class="user-profile__report-link">{% trans '举报用户' %}</a>
{% endif %}
</div>
</div>
<div class="relation-dropdown">
<div class="relation-dropdown__button">
<span class="icon-arrow">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 10 10">
<path d="M8.12,3.29,5,6.42,1.86,3.29H.45L5,7.84,9.55,3.29Z" />
</svg>
</span>
</div>
<div class="relation-dropdown__body">
<div class="aside-section-wrapper aside-section-wrapper--transparent aside-section-wrapper--collapse">
<div class="user-relation" id="followings">
<h5 class="user-relation__label">
{% trans '关注的人' %}
</h5>
<a href="{% url 'users:following' user.id %}"
class="user-relation__more-link mast-following-more">{% trans '更多' %}</a>
<ul class="user-relation__related-user-list mast-following">
<li class="user-relation__related-user">
<a>
<img src="" alt="" class="user-relation__related-user-avatar">
<div class="user-relation__related-user-name mast-displayname"></div>
</a>
</li>
</ul>
</div>
<div class="user-relation" id="followers">
<h5 class="user-relation__label">
{% trans '被他们关注' %}
</h5>
<a href="{% url 'users:followers' user.id %}"
class="user-relation__more-link mast-followers-more">{% trans '更多' %}</a>
<ul class="user-relation__related-user-list mast-followers">
<li class="user-relation__related-user">
<a>
<img src="" alt="" class="user-relation__related-user-avatar">
<div class="user-relation__related-user-name mast-displayname"></div>
</a>
</li>
</ul>
</div>
</div>
</div>
</div>
</div>
</div>
</section>
</div>
{% include 'partial/_footer.html' %}
</div>
<div id="oauth2Token" hidden="true">{% oauth_token %}</div>
<div id="mastodonURI" hidden="true">{% mastodon %}</div>
<!--current user mastodon id-->
<div id="userMastodonID" hidden="true">{{ user.mastodon_id }}</div>
<div id="userPageURL" hidden="true">{% url 'users:home' 0 %}?is_mastodon_id=true</div>
<div id="spinner" hidden>
<div class="spinner">
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
</div>
</div>
<script>
$("#searchInput").on('keyup', function (e) {
if (e.keyCode === 13) {
let q = $(this).val();
if (q)
location.href = "{% url 'common:search' %}" + "?q=" + q;
}
});
</script>
</body>
</html>

View file

@ -9,51 +9,34 @@
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<!-- <meta name="viewport" content="width=device-width, initial-scale=1.0"> --> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{% trans 'Nicedb - 举报用户' %}</title> <title>{% trans 'Nicedb - 举报用户' %}</title>
<script src="https://cdn.staticfile.org/jquery/3.5.0/jquery.min.js"></script> <script src="https://cdn.staticfile.org/jquery/3.5.0/jquery.min.js"></script>
<script src="{% static 'js/create_update.js' %}"></script> <script src="{% static 'js/create_update.js' %}"></script>
<link rel="stylesheet" href="{% static 'lib/css/milligram.css' %}"> <link rel="stylesheet" href="{% static 'css/boofilsic.css' %}">
<link rel="stylesheet" href="{% static 'css/boofilsic_edit.css' %}"> <!-- <link rel="stylesheet" href="{% static 'css/boofilsic_edit.css' %}">
<link rel="stylesheet" href="{% static 'lib/css/milligram.css' %}"> -->
</head> </head>
<body> <body>
<div id="page-wrapper"> <div id="page-wrapper">
<div id="content-wrapper"> <div id="content-wrapper">
<section id="navbar" class="navbar"> {% include "partial/_navbar.html" %}
<div class="container">
<nav class="clearfix">
<a href="{% url 'common:home' %}">
<img src="{% static 'img/logo.svg' %}" alt="" class="logo">
</a>
<h4 class="nav-title">{% trans '举报用户' %}</h4>
<a class="nav-link" id="logoutLink" href="{% url 'users:logout' %}">{% trans '登出' %}</a>
<a class="nav-link" href="{% url 'common:home' %}">{% trans '主页' %}</a>
{% if user.is_staff %}
<a class="nav-link" href="{% admin_url %}">{% trans '后台' %}</a>
{% endif %}
</nav>
</div>
</section>
<section id="content" class="container"> <section id="content">
<div class="row"> <div class="grid">
<div id="main"> <div class="single-section-wrapper" id="main">
<form action="{% url 'users:report' %}" method="post" enctype="multipart/form-data"> <form action="{% url 'users:report' %}" method="post" enctype="multipart/form-data">
{% csrf_token %} {% csrf_token %}
{{ form }} {{ form }}
<input class="button" type="submit" value="{% trans '提交' %}"> <input class="button" type="submit" value="{% trans '提交' %}">
</form> </form>
</div> </div>
</div>
</section> </section>
</div> </div>
<footer class="container"> {% include "partial/_footer.html" %}
<a href="https://donotban.com/@whitiewhite">去长毛象向作者提意见</a>
<a href="https://github.com/doubaniux/boofilsic/issues">报告错误</a>
<a href="https://github.com/doubaniux/boofilsic" id="githubLink">Github</a>
</footer>
</div> </div>
@ -72,6 +55,18 @@
location.href = "{% url 'common:search' %}" + "?q=" + q; location.href = "{% url 'common:search' %}" + "?q=" + q;
} }
}); });
// preview uploaded pic
$("input[type='file']").change(function () {
if (this.files && this.files[0]) {
var reader = new FileReader();
reader.onload = function (e) {
$('#previewImage').attr('src', e.target.result);
}
reader.readAsDataURL(this.files[0]);
}
});
</script> </script>
</body> </body>

View file

@ -11,8 +11,9 @@ from .forms import ReportForm
from common.mastodon.auth import * from common.mastodon.auth import *
from common.mastodon.api import * from common.mastodon.api import *
from common.mastodon import mastodon_request_included from common.mastodon import mastodon_request_included
from common.views import BOOKS_PER_SET, ITEMS_PER_PAGE from common.views import BOOKS_PER_SET, ITEMS_PER_PAGE, PAGE_LINK_NUMBER
from common.models import MarkStatusEnum from common.models import MarkStatusEnum
from common.utils import PageLinksGenerator
from books.models import * from books.models import *
from boofilsic.settings import MASTODON_DOMAIN_NAME, CLIENT_ID, CLIENT_SECRET from boofilsic.settings import MASTODON_DOMAIN_NAME, CLIENT_ID, CLIENT_SECRET
from books.forms import BookMarkStatusTranslator from books.forms import BookMarkStatusTranslator
@ -182,7 +183,7 @@ def home(request, id):
@mastodon_request_included @mastodon_request_included
@login_required @login_required
def followers(request, id): def followers(request, id):
if request.method == 'GET': if request.method == 'GET':
try: try:
user = User.objects.get(pk=id) user = User.objects.get(pk=id)
@ -211,7 +212,7 @@ def followers(request, id):
) )
return render( return render(
request, request,
'users/list.html', 'users/relation_list.html',
{ {
'user': user, 'user': user,
'is_followers_page': True, 'is_followers_page': True,
@ -252,7 +253,7 @@ def following(request, id):
) )
return render( return render(
request, request,
'users/list.html', 'users/relation_list.html',
{ {
'user': user, 'user': user,
'page_type': 'followers', 'page_type': 'followers',
@ -299,6 +300,7 @@ def book_list(request, id, status):
paginator = Paginator(queryset, ITEMS_PER_PAGE) paginator = Paginator(queryset, ITEMS_PER_PAGE)
page_number = request.GET.get('page', default=1) page_number = request.GET.get('page', default=1)
marks = paginator.get_page(page_number) marks = paginator.get_page(page_number)
marks.pagination = PageLinksGenerator(PAGE_LINK_NUMBER, page_number, paginator.num_pages)
list_title = str(BookMarkStatusTranslator(MarkStatusEnum[status.upper()])) + str(_("的书")) list_title = str(BookMarkStatusTranslator(MarkStatusEnum[status.upper()])) + str(_("的书"))
return render( return render(
request, request,
@ -353,6 +355,7 @@ def manage_report(request):
if request.method == 'GET': if request.method == 'GET':
reports = Report.objects.all() reports = Report.objects.all()
for r in reports.filter(is_read=False): for r in reports.filter(is_read=False):
r.is_read = True
r.save() r.save()
return render( return render(
request, request,