new style
* new style with picocss * djlint * rate distribution * collection item drag to order * discover available for guest * search combine movie tv
This commit is contained in:
parent
cef2e0e617
commit
0ffd47ca96
163 changed files with 8699 additions and 5252 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -23,6 +23,7 @@ tox.ini
|
||||||
# generated css
|
# generated css
|
||||||
/common/static/css/boofilsic.min.css
|
/common/static/css/boofilsic.min.css
|
||||||
/common/static/css/boofilsic.css
|
/common/static/css/boofilsic.css
|
||||||
|
/common/static/scss/neodb.css
|
||||||
|
|
||||||
# debug log file
|
# debug log file
|
||||||
/log
|
/log
|
||||||
|
|
|
@ -10,3 +10,10 @@ repos:
|
||||||
hooks:
|
hooks:
|
||||||
- id: black
|
- id: black
|
||||||
language_version: python3.11
|
language_version: python3.11
|
||||||
|
repos:
|
||||||
|
- repo: https://github.com/Riverside-Healthcare/djLint
|
||||||
|
rev: v1.28.0
|
||||||
|
hooks:
|
||||||
|
- id: djlint-reformat-django
|
||||||
|
- id: djlint-django
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,7 @@ https://docs.djangoproject.com/en/3.0/ref/settings/
|
||||||
|
|
||||||
import os
|
import os
|
||||||
|
|
||||||
|
PROJECT_ROOT = os.path.abspath(os.path.dirname(__name__))
|
||||||
|
|
||||||
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
|
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
|
||||||
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||||
|
@ -52,6 +53,7 @@ INSTALLED_APPS = [
|
||||||
"django_rq",
|
"django_rq",
|
||||||
"django_bleach",
|
"django_bleach",
|
||||||
"tz_detect",
|
"tz_detect",
|
||||||
|
"sass_processor",
|
||||||
"simple_history",
|
"simple_history",
|
||||||
"markdownx",
|
"markdownx",
|
||||||
"polymorphic",
|
"polymorphic",
|
||||||
|
@ -210,6 +212,11 @@ STATIC_URL = "/static/"
|
||||||
STATIC_ROOT = os.path.join(BASE_DIR, "static/")
|
STATIC_ROOT = os.path.join(BASE_DIR, "static/")
|
||||||
|
|
||||||
STATICFILES_STORAGE = "django.contrib.staticfiles.storage.ManifestStaticFilesStorage"
|
STATICFILES_STORAGE = "django.contrib.staticfiles.storage.ManifestStaticFilesStorage"
|
||||||
|
STATICFILES_FINDERS = [
|
||||||
|
"django.contrib.staticfiles.finders.FileSystemFinder",
|
||||||
|
"django.contrib.staticfiles.finders.AppDirectoriesFinder",
|
||||||
|
"sass_processor.finders.CssFinder",
|
||||||
|
]
|
||||||
|
|
||||||
AUTH_USER_MODEL = "users.User"
|
AUTH_USER_MODEL = "users.User"
|
||||||
|
|
||||||
|
@ -221,9 +228,9 @@ SILENCED_SYSTEM_CHECKS = [
|
||||||
MEDIA_URL = "/media/"
|
MEDIA_URL = "/media/"
|
||||||
MEDIA_ROOT = os.path.join(BASE_DIR, "media/")
|
MEDIA_ROOT = os.path.join(BASE_DIR, "media/")
|
||||||
|
|
||||||
PROJECT_ROOT = os.path.abspath(os.path.dirname(__name__))
|
|
||||||
SITE_INFO = {
|
SITE_INFO = {
|
||||||
"site_name": "NiceDB",
|
"site_name": "NiceDB",
|
||||||
|
"site_url": "https://nicedb.org",
|
||||||
"support_link": "https://github.com/doubaniux/boofilsic/issues",
|
"support_link": "https://github.com/doubaniux/boofilsic/issues",
|
||||||
"social_link": "https://donotban.com/@testie",
|
"social_link": "https://donotban.com/@testie",
|
||||||
"donation_link": "https://patreon.com/tertius",
|
"donation_link": "https://patreon.com/tertius",
|
||||||
|
@ -237,6 +244,7 @@ CLIENT_NAME = os.environ.get("APP_NAME", "NiceDB")
|
||||||
SITE_INFO["site_name"] = os.environ.get("APP_NAME", "NiceDB")
|
SITE_INFO["site_name"] = os.environ.get("APP_NAME", "NiceDB")
|
||||||
APP_WEBSITE = os.environ.get("APP_URL", "https://nicedb.org")
|
APP_WEBSITE = os.environ.get("APP_URL", "https://nicedb.org")
|
||||||
REDIRECT_URIS = APP_WEBSITE + "/users/OAuth2_login/"
|
REDIRECT_URIS = APP_WEBSITE + "/users/OAuth2_login/"
|
||||||
|
SITE_INFO["site_url"] = APP_WEBSITE
|
||||||
|
|
||||||
|
|
||||||
# Path to save report related images, ends with slash
|
# Path to save report related images, ends with slash
|
||||||
|
@ -408,3 +416,5 @@ MAINTENANCE_MODE_IGNORE_ADMIN_SITE = True
|
||||||
MAINTENANCE_MODE_IGNORE_SUPERUSER = True
|
MAINTENANCE_MODE_IGNORE_SUPERUSER = True
|
||||||
MAINTENANCE_MODE_IGNORE_ANONYMOUS_USER = True
|
MAINTENANCE_MODE_IGNORE_ANONYMOUS_USER = True
|
||||||
MAINTENANCE_MODE_IGNORE_URLS = (r"^/users/connect/", r"^/users/OAuth2_login/")
|
MAINTENANCE_MODE_IGNORE_URLS = (r"^/users/connect/", r"^/users/OAuth2_login/")
|
||||||
|
|
||||||
|
DISCORD_WEBHOOKS = {}
|
||||||
|
|
|
@ -277,9 +277,9 @@ class MockResponse:
|
||||||
return json.load(StringIO(self.text))
|
return json.load(StringIO(self.text))
|
||||||
|
|
||||||
def html(self):
|
def html(self):
|
||||||
return html.fromstring(
|
return html.fromstring( # may throw exception unexpectedly due to OS bug, see https://github.com/neodb-social/neodb/issues/5
|
||||||
self.text
|
self.text
|
||||||
) # may throw exception unexpectedly due to OS bug, see https://github.com/neodb-social/neodb/issues/5
|
)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def headers(self):
|
def headers(self):
|
||||||
|
|
|
@ -8,6 +8,9 @@ from django.utils import timezone
|
||||||
from django.db.models import Count
|
from django.db.models import Count
|
||||||
|
|
||||||
|
|
||||||
|
MAX_GALLERY_ITEMS = 42
|
||||||
|
|
||||||
|
|
||||||
class Command(BaseCommand):
|
class Command(BaseCommand):
|
||||||
help = "catalog app utilities"
|
help = "catalog app utilities"
|
||||||
|
|
||||||
|
@ -18,9 +21,21 @@ class Command(BaseCommand):
|
||||||
help="generate discover data",
|
help="generate discover data",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def get_popular_item_ids(self, category, days):
|
||||||
|
self.stdout.write(f"Generating popular {category} items for {days} days...")
|
||||||
|
item_ids = [
|
||||||
|
m["item_id"]
|
||||||
|
for m in ShelfMember.objects.filter(query_item_category(category))
|
||||||
|
.filter(created_time__gt=timezone.now() - timedelta(days=days))
|
||||||
|
.values("item_id")
|
||||||
|
.annotate(num=Count("item_id"))
|
||||||
|
.order_by("-num")[:MAX_GALLERY_ITEMS]
|
||||||
|
]
|
||||||
|
return item_ids
|
||||||
|
|
||||||
def handle(self, *args, **options):
|
def handle(self, *args, **options):
|
||||||
if options["update"]:
|
if options["update"]:
|
||||||
cache_key = "public_gallery_list"
|
cache_key = "public_gallery"
|
||||||
gallery_categories = [
|
gallery_categories = [
|
||||||
ItemCategory.Book,
|
ItemCategory.Book,
|
||||||
ItemCategory.Movie,
|
ItemCategory.Movie,
|
||||||
|
@ -31,22 +46,19 @@ class Command(BaseCommand):
|
||||||
]
|
]
|
||||||
gallery_list = []
|
gallery_list = []
|
||||||
for category in gallery_categories:
|
for category in gallery_categories:
|
||||||
item_ids = [
|
days = 14
|
||||||
m["item_id"]
|
item_ids = []
|
||||||
for m in ShelfMember.objects.filter(query_item_category(category))
|
while len(item_ids) < MAX_GALLERY_ITEMS / 2 and days < 150:
|
||||||
.filter(created_time__gt=timezone.now() - timedelta(days=42))
|
item_ids = self.get_popular_item_ids(category, days)
|
||||||
.values("item_id")
|
days *= 3
|
||||||
.annotate(num=Count("item_id"))
|
items = Item.objects.filter(id__in=item_ids)
|
||||||
.order_by("-num")[:100]
|
|
||||||
]
|
|
||||||
gallery_list.append(
|
gallery_list.append(
|
||||||
{
|
{
|
||||||
"name": "popular_" + category.value,
|
"name": "popular_" + category.value,
|
||||||
"title": "热门"
|
"title": "热门"
|
||||||
+ (category.label if category != ItemCategory.Book else "图书"),
|
+ (category.label if category != ItemCategory.Book else "图书"),
|
||||||
"item_ids": item_ids,
|
"items": items,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
cache.set(cache_key, gallery_list, timeout=None)
|
cache.set(cache_key, gallery_list, timeout=None)
|
||||||
|
|
||||||
self.stdout.write(self.style.SUCCESS(f"Done."))
|
self.stdout.write(self.style.SUCCESS(f"Done."))
|
||||||
|
|
|
@ -75,6 +75,16 @@ class Album(Item):
|
||||||
bandcamp_album_id = jsondata.CharField(blank=True, default="", max_length=500)
|
bandcamp_album_id = jsondata.CharField(blank=True, default="", max_length=500)
|
||||||
disc_count = jsondata.IntegerField(_("碟片数"), blank=True, default="", max_length=500)
|
disc_count = jsondata.IntegerField(_("碟片数"), blank=True, default="", max_length=500)
|
||||||
|
|
||||||
|
def get_embed_link(self):
|
||||||
|
for res in self.external_resources.all():
|
||||||
|
if res.id_type == IdType.Bandcamp.value and res.metadata.get(
|
||||||
|
"bandcamp_album_id"
|
||||||
|
):
|
||||||
|
return f"https://bandcamp.com/EmbeddedPlayer/album={res.metadata.get('bandcamp_album_id')}/size=large/bgcol=ffffff/linkcol=19A2CA/artwork=small/transparent=true/"
|
||||||
|
if res.id_type == IdType.Spotify_Album.value:
|
||||||
|
return res.url.replace("open.spotify.com/", "open.spotify.com/embed/")
|
||||||
|
return None
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def lookup_id_type_choices(cls):
|
def lookup_id_type_choices(cls):
|
||||||
id_types = [
|
id_types = [
|
||||||
|
|
|
@ -16,19 +16,22 @@ class SearchResultItem:
|
||||||
self, category, source_site, source_url, title, subtitle, brief, cover_url
|
self, category, source_site, source_url, title, subtitle, brief, cover_url
|
||||||
):
|
):
|
||||||
self.category = category
|
self.category = category
|
||||||
|
self.external_resources = {
|
||||||
|
"all": [{"url": source_url, "site_name": {"label": source_site}}]
|
||||||
|
}
|
||||||
self.source_site = source_site
|
self.source_site = source_site
|
||||||
self.source_url = source_url
|
self.source_url = source_url
|
||||||
self.title = title
|
self.title = title
|
||||||
self.subtitle = subtitle
|
self.subtitle = subtitle
|
||||||
self.brief = brief
|
self.brief = brief
|
||||||
self.cover_url = cover_url
|
self.cover_image_url = cover_url
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def verbose_category_name(self):
|
def verbose_category_name(self):
|
||||||
return self.category.label
|
return self.category.label
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def link(self):
|
def url(self):
|
||||||
return f"/search?q={quote_plus(self.source_url)}"
|
return f"/search?q={quote_plus(self.source_url)}"
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
@ -272,7 +275,7 @@ class ExternalSources:
|
||||||
results = []
|
results = []
|
||||||
if c == "" or c is None:
|
if c == "" or c is None:
|
||||||
c = "all"
|
c = "all"
|
||||||
if c == "all" or c == "movie" or c == "tv":
|
if c == "all" or c == "movietv":
|
||||||
results.extend(TheMovieDatabase.search(q, page))
|
results.extend(TheMovieDatabase.search(q, page))
|
||||||
if c == "all" or c == "book":
|
if c == "all" or c == "book":
|
||||||
results.extend(GoogleBooks.search(q, page))
|
results.extend(GoogleBooks.search(q, page))
|
||||||
|
|
|
@ -236,7 +236,10 @@ class Indexer:
|
||||||
def search(cls, q, page=1, category=None, tag=None, sort=None):
|
def search(cls, q, page=1, category=None, tag=None, sort=None):
|
||||||
f = []
|
f = []
|
||||||
if category:
|
if category:
|
||||||
f.append("category:= " + category)
|
if category == "movietv":
|
||||||
|
f.append("category:= [movie,tv]")
|
||||||
|
else:
|
||||||
|
f.append("category:= " + category)
|
||||||
if tag:
|
if tag:
|
||||||
f.append(f"tags:= '{tag}'")
|
f.append(f"tags:= '{tag}'")
|
||||||
filters = " && ".join(f)
|
filters = " && ".join(f)
|
||||||
|
@ -254,6 +257,7 @@ class Indexer:
|
||||||
|
|
||||||
try:
|
try:
|
||||||
r = cls.instance().collections[INDEX_NAME].documents.search(options)
|
r = cls.instance().collections[INDEX_NAME].documents.search(options)
|
||||||
|
print(r)
|
||||||
results.items = list(
|
results.items = list(
|
||||||
[
|
[
|
||||||
x
|
x
|
||||||
|
|
|
@ -80,6 +80,7 @@ def fetch(request, url, is_refetch: bool = False, site: AbstractSite = None):
|
||||||
"fetch_pending.html",
|
"fetch_pending.html",
|
||||||
{
|
{
|
||||||
"site": site,
|
"site": site,
|
||||||
|
"sites": SiteName.labels,
|
||||||
"job_id": job_id,
|
"job_id": job_id,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
@ -99,6 +100,7 @@ def search(request):
|
||||||
"search_results.html",
|
"search_results.html",
|
||||||
{
|
{
|
||||||
"items": None,
|
"items": None,
|
||||||
|
"sites": SiteName.labels,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -150,7 +152,7 @@ def search(request):
|
||||||
),
|
),
|
||||||
"categories": ["book", "movie", "music", "game"],
|
"categories": ["book", "movie", "music", "game"],
|
||||||
"sites": SiteName.labels,
|
"sites": SiteName.labels,
|
||||||
"hide_category": category is not None,
|
"hide_category": category is not None and category != "movietv",
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -14,8 +14,8 @@ _logger = logging.getLogger(__name__)
|
||||||
class Bandcamp(AbstractSite):
|
class Bandcamp(AbstractSite):
|
||||||
SITE_NAME = SiteName.Bandcamp
|
SITE_NAME = SiteName.Bandcamp
|
||||||
ID_TYPE = IdType.Bandcamp
|
ID_TYPE = IdType.Bandcamp
|
||||||
URL_PATTERNS = [r"https://([a-z0-9\-]+.bandcamp.com/album/[^?#/]+)"]
|
URL_PATTERNS = [r"https://([a-z0-9\-]+.bandcamp.com/album/[^?#/]+).*"]
|
||||||
URL_PATTERN_FALLBACK = r"https://([a-z0-9\-\.]+/album/[^?#/]+)"
|
URL_PATTERN_FALLBACK = r"https://([a-z0-9\-\.]+/album/[^?#/]+).*"
|
||||||
WIKI_PROPERTY_ID = ""
|
WIKI_PROPERTY_ID = ""
|
||||||
DEFAULT_MODEL = Album
|
DEFAULT_MODEL = Album
|
||||||
|
|
||||||
|
|
|
@ -24,7 +24,7 @@ spotify_token_expire_time = time.time()
|
||||||
class Spotify(AbstractSite):
|
class Spotify(AbstractSite):
|
||||||
SITE_NAME = SiteName.Spotify
|
SITE_NAME = SiteName.Spotify
|
||||||
ID_TYPE = IdType.Spotify_Album
|
ID_TYPE = IdType.Spotify_Album
|
||||||
URL_PATTERNS = [r"\w+://open\.spotify\.com/album/([a-zA-Z0-9]+)"]
|
URL_PATTERNS = [r"\w+://open\.spotify\.com/album/([a-zA-Z0-9]+).*"]
|
||||||
WIKI_PROPERTY_ID = "?"
|
WIKI_PROPERTY_ID = "?"
|
||||||
DEFAULT_MODEL = Album
|
DEFAULT_MODEL = Album
|
||||||
|
|
||||||
|
|
57
catalog/static/podcast.js
Normal file
57
catalog/static/podcast.js
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
function create_player(audio) {
|
||||||
|
window.player = new Shikwasa.Player({
|
||||||
|
container: () => document.querySelector('.player'),
|
||||||
|
preload: 'metadata',
|
||||||
|
autoplay: true,
|
||||||
|
themeColor: getComputedStyle(document.documentElement).getPropertyValue('--pico-primary'),
|
||||||
|
fixed: {
|
||||||
|
type: 'fixed',
|
||||||
|
position: 'bottom'
|
||||||
|
},
|
||||||
|
audio: audio
|
||||||
|
});
|
||||||
|
// $('.shk-title').on('click', e=>{
|
||||||
|
// window.location = "#";
|
||||||
|
// });
|
||||||
|
$('.footer').attr('style', 'margin-bottom: 120px !important');
|
||||||
|
}
|
||||||
|
function podcast_init(context) {
|
||||||
|
$('.episode', context).on('click', e=>{
|
||||||
|
e.preventDefault();
|
||||||
|
var ele = e.currentTarget;
|
||||||
|
var album = $(ele).data('album');
|
||||||
|
var artist = $(ele).data('hosts');
|
||||||
|
var title = $(ele).data('title');
|
||||||
|
var cover_url = $(ele).data('cover');
|
||||||
|
var media_url = $(ele).data('media');
|
||||||
|
var position = $(ele).data('position');
|
||||||
|
if (!media_url) return;
|
||||||
|
window.current_item_uuid = $(ele).data('uuid');
|
||||||
|
if (!window.player) {
|
||||||
|
create_player({
|
||||||
|
title: title,
|
||||||
|
cover: cover_url,
|
||||||
|
src: media_url,
|
||||||
|
album: album,
|
||||||
|
artist: artist
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
window.player.update({
|
||||||
|
title: title,
|
||||||
|
cover: cover_url,
|
||||||
|
src: media_url,
|
||||||
|
album: album,
|
||||||
|
artist: artist
|
||||||
|
})
|
||||||
|
}
|
||||||
|
if (position) window.player._initSeek = position;
|
||||||
|
window.player.play()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
$(function() {
|
||||||
|
document.body.addEventListener('htmx:load', function(evt) {
|
||||||
|
podcast_init(evt.detail.elt);
|
||||||
|
});
|
||||||
|
podcast_init(document.body);
|
||||||
|
});
|
121
catalog/templates/_item_card.html
Normal file
121
catalog/templates/_item_card.html
Normal file
|
@ -0,0 +1,121 @@
|
||||||
|
{% load humanize %}
|
||||||
|
{% load i18n %}
|
||||||
|
{% load highlight %}
|
||||||
|
{% if item.get_embed_link %}
|
||||||
|
<div class="item player">
|
||||||
|
<h5>
|
||||||
|
<a href="{{ item.url }}">{{ item.title }}</a>
|
||||||
|
<small>
|
||||||
|
{% if not hide_category %}<span class="category">[{{ item.category.label }}]</span>{% endif %}
|
||||||
|
<span class="site-list">
|
||||||
|
{% for res in item.external_resources.all %}
|
||||||
|
<a href="{{ res.url }}" class="{{ res.site_name }}">{{ res.site_name.label }}</a>
|
||||||
|
{% endfor %}
|
||||||
|
</span>
|
||||||
|
</small>
|
||||||
|
</h5>
|
||||||
|
<iframe src="{{ item.get_embed_link }}"
|
||||||
|
frameborder="0"
|
||||||
|
allowtransparency="true"
|
||||||
|
allow="encrypted-media"
|
||||||
|
style="width: 100%;
|
||||||
|
height: 120px"></iframe>
|
||||||
|
</div>
|
||||||
|
{% else %}
|
||||||
|
<div class="item">
|
||||||
|
<div class="cover">
|
||||||
|
<a href="{{ item.url }}">
|
||||||
|
<img src="{{ item.cover_image_url }}" alt="cover" />
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<hgroup>
|
||||||
|
<h5>
|
||||||
|
<a href="{{ item.url }}">
|
||||||
|
{% if request.GET.q %}
|
||||||
|
{{ item.title | strip_season | highlight:request.GET.q }}
|
||||||
|
{% else %}
|
||||||
|
{{ item.title | strip_season }}
|
||||||
|
{% endif %}
|
||||||
|
</a>
|
||||||
|
<small>
|
||||||
|
{% if item.season_number %}第{{ item.season_number|apnumber }}季{% endif %}
|
||||||
|
{% if item.year %}({{ item.year }}){% endif %}
|
||||||
|
{% if not hide_category %}<span class="category">[{{ item.category.label }}]</span>{% endif %}
|
||||||
|
<span class="site-list">
|
||||||
|
{% for res in item.external_resources.all %}
|
||||||
|
<a href="{{ res.url }}" class="{{ res.site_name }}">{{ res.site_name.label }}</a>
|
||||||
|
{% endfor %}
|
||||||
|
</span>
|
||||||
|
</small>
|
||||||
|
</h5>
|
||||||
|
{% comment %}
|
||||||
|
<span class="site-list">
|
||||||
|
{% for res in item.external_resources.all %}
|
||||||
|
<a href="{{ res.url }}" class="{{ res.site_name }}">{{ res.site_name.label }}</a>
|
||||||
|
{% endfor %}
|
||||||
|
</span>
|
||||||
|
{% endcomment %}
|
||||||
|
<div>
|
||||||
|
<small>
|
||||||
|
{% if item.subtitle %}{{ item.subtitle }}{% endif %}
|
||||||
|
{% if item.orig_title %}
|
||||||
|
{{ item.orig_title }}
|
||||||
|
{% if item.season_number %}Season {{ item.season_number }}{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
</small>
|
||||||
|
</div>
|
||||||
|
</hgroup>
|
||||||
|
<div>
|
||||||
|
<div class="metadata">
|
||||||
|
{% if item.rating %}
|
||||||
|
{{ item.rating | floatformat:1 }}分
|
||||||
|
{% else %}
|
||||||
|
{% endif %}
|
||||||
|
{% include '_people.html' with people=item.author role='' max=2 %}
|
||||||
|
{% include '_people.html' with people=item.translator role='' max=2 %}
|
||||||
|
{% include '_people.html' with people=item.director role='' max=2 %}
|
||||||
|
{% include '_people.html' with people=item.hosts role='' max=2 %}
|
||||||
|
{% include '_people.html' with people=item.artist role='' max=2 %}
|
||||||
|
{% include '_people.html' with people=item.developer role='' max=2 %}
|
||||||
|
{% if item.pub_house %}/ {{ item.pub_house }}{% endif %}
|
||||||
|
{% if item.pub_year %}
|
||||||
|
/ {{ item.pub_year }}{% trans '年' %}
|
||||||
|
{% if item.pub_month %}
|
||||||
|
{{ item.pub_month }}{% trans '月' %}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% if item.release_date %}/ {{ item.release_date }}{% endif %}
|
||||||
|
{% include '_people.html' with people=item.genre role='' max=10 %}
|
||||||
|
{% include '_people.html' with people=item.platform role='' max=10 %}
|
||||||
|
</div>
|
||||||
|
<div class="brief">
|
||||||
|
{% if item.actor %}
|
||||||
|
{% include '_people.html' with people=item.actor role='主演' max=2 %}
|
||||||
|
<br>
|
||||||
|
{% endif %}
|
||||||
|
{% if item.other_title %}
|
||||||
|
{% include '_people.html' with people=item.other_title role='又名' max=2 %}
|
||||||
|
<br>
|
||||||
|
{% endif %}
|
||||||
|
{% if request.GET.q %}
|
||||||
|
{{ item.brief | linebreaksbr | highlight:request.GET.q }}
|
||||||
|
{% else %}
|
||||||
|
{{ item.brief | linebreaksbr }}
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
{% if show_tags %}
|
||||||
|
<div class="tag-list">
|
||||||
|
{% for tag in item.tags %}
|
||||||
|
{% if forloop.counter <= 5 %}
|
||||||
|
<span>
|
||||||
|
<a href="{% url 'catalog:search' %}?tag={{ tag }}">{{ tag }}</a>
|
||||||
|
</span>
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
11
catalog/templates/_people.html
Normal file
11
catalog/templates/_people.html
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
{% if people %}
|
||||||
|
{% if role %}{{ role }}:{% endif %}
|
||||||
|
{% for p in people %}
|
||||||
|
{% if forloop.counter <= max %}
|
||||||
|
{% if not forloop.first %}、{% endif %}
|
||||||
|
<span>{{ p }}</span>
|
||||||
|
{% elif forloop.last %}
|
||||||
|
等
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
|
@ -10,114 +10,120 @@
|
||||||
{% load strip_scheme %}
|
{% load strip_scheme %}
|
||||||
{% load thumb %}
|
{% load thumb %}
|
||||||
{% load duration %}
|
{% load duration %}
|
||||||
|
|
||||||
<!-- class specific details -->
|
<!-- class specific details -->
|
||||||
{% block details %}
|
{% block details %}
|
||||||
<div class="entity-detail__fields">
|
<div>
|
||||||
<div class="entity-detail__rating">
|
{% if item.artist %}
|
||||||
{% if item.rating and item.rating_count >= 5 %}
|
{% trans '艺术家:' %}
|
||||||
<span class="entity-detail__rating-star rating-star" data-rating-score="{{ item.rating | floatformat:"0" }}"></span>
|
{% for artist in item.artist %}
|
||||||
<span class="entity-detail__rating-score"> {{ item.rating | floatformat:1 }} </span>
|
<span {% if forloop.counter > 5 %}style="display: none;"{% endif %}>
|
||||||
<small>({{ item.rating_count }}人评分)</small>
|
<span class="artist">{{ artist }}</span>
|
||||||
{% else %}
|
{% if not forloop.last %}/{% endif %}
|
||||||
<span> {% trans '评分:评分人数不足' %}</span>
|
</span>
|
||||||
{% endif %}
|
{% endfor %}
|
||||||
</div>
|
{% if item.artist|length > 5 %}
|
||||||
<div>{% if item.artist %}{% trans '艺术家:' %}
|
<a href="javascript:void(0);" id="artistMore">{% trans '更多' %}</a>
|
||||||
{% for artist in item.artist %}
|
<script>
|
||||||
<span {% if forloop.counter > 5 %}style="display: none;" {% endif %}>
|
|
||||||
<span class="artist">{{ artist }}</span>
|
|
||||||
{% if not forloop.last %} / {% endif %}
|
|
||||||
</span>
|
|
||||||
{% endfor %}
|
|
||||||
{% if item.artist|length > 5 %}
|
|
||||||
<a href="javascript:void(0);" id="artistMore">{% trans '更多' %}</a>
|
|
||||||
<script>
|
|
||||||
$("#artistMore").on('click', function (e) {
|
$("#artistMore").on('click', function (e) {
|
||||||
$("span.artist:not(:visible)").each(function (e) {
|
$("span.artist:not(:visible)").each(function (e) {
|
||||||
$(this).parent().removeAttr('style');
|
$(this).parent().removeAttr('style');
|
||||||
});
|
});
|
||||||
$(this).remove();
|
$(this).remove();
|
||||||
})
|
})
|
||||||
</script>
|
|
||||||
{% endif %}
|
</script>
|
||||||
{% endif %}</div>
|
{% endif %}
|
||||||
<div>{% if item.company %}{% trans '发行方:' %}
|
{% endif %}
|
||||||
{% for company in item.company %}
|
</div>
|
||||||
<span {% if forloop.counter > 5 %}style="display: none;" {% endif %}>
|
<div>
|
||||||
<span class="company">{{ company }}</span>
|
{% if item.company %}
|
||||||
{% if not forloop.last %} / {% endif %}
|
{% trans '发行方:' %}
|
||||||
</span>
|
{% for company in item.company %}
|
||||||
{% endfor %}
|
<span {% if forloop.counter > 5 %}style="display: none;"{% endif %}>
|
||||||
{% if item.company|length > 5 %}
|
<span class="company">{{ company }}</span>
|
||||||
<a href="javascript:void(0);" id="companyMore">{% trans '更多' %}</a>
|
{% if not forloop.last %}/{% endif %}
|
||||||
<script>
|
</span>
|
||||||
|
{% endfor %}
|
||||||
|
{% if item.company|length > 5 %}
|
||||||
|
<a href="javascript:void(0);" id="companyMore">{% trans '更多' %}</a>
|
||||||
|
<script>
|
||||||
$("#companyMore").on('click', function (e) {
|
$("#companyMore").on('click', function (e) {
|
||||||
$("span.company:not(:visible)").each(function (e) {
|
$("span.company:not(:visible)").each(function (e) {
|
||||||
$(this).parent().removeAttr('style');
|
$(this).parent().removeAttr('style');
|
||||||
});
|
});
|
||||||
$(this).remove();
|
$(this).remove();
|
||||||
})
|
})
|
||||||
</script>
|
|
||||||
{% endif %}
|
</script>
|
||||||
{% endif %}</div>
|
{% endif %}
|
||||||
<div>{% if item.release_date %}
|
{% endif %}
|
||||||
{% trans '发行日期:' %}{{ item.release_date }}
|
</div>
|
||||||
{% endif %}
|
<div>
|
||||||
</div>
|
{% if item.release_date %}
|
||||||
<div>{% if item.duration %}
|
{% trans '发行日期:' %}{{ item.release_date }}
|
||||||
{% trans '时长:' %}{{ item.duration|duration_format:1000 }}
|
{% endif %}
|
||||||
{% endif %}
|
</div>
|
||||||
</div>
|
<div>
|
||||||
<div>{% if item.genre %}
|
{% if item.duration %}
|
||||||
{% trans '流派:' %}
|
{% trans '时长:' %}{{ item.duration|duration_format:1000 }}
|
||||||
{% for genre in item.genre %}
|
{% endif %}
|
||||||
<span>{{ genre }}</span>{% if not forloop.last %} / {% endif %}
|
</div>
|
||||||
{% endfor %}
|
<div>
|
||||||
{% endif %}
|
{% if item.genre %}
|
||||||
</div>
|
{% trans '流派:' %}
|
||||||
<div>{% if item.barcode %}
|
{% for genre in item.genre %}
|
||||||
{% trans '条形码:' %}{{ item.barcode }}
|
<span>{{ genre }}</span>
|
||||||
{% endif %}
|
{% if not forloop.last %}/{% endif %}
|
||||||
</div>
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
<div class="entity-detail__fields">
|
<div>
|
||||||
<div>{% if item.other_title %}
|
{% if item.barcode %}
|
||||||
{% trans '又名:' %}
|
{% trans '条形码:' %}{{ item.barcode }}
|
||||||
{% for t in item.other_title %}
|
{% endif %}
|
||||||
<span>{{ t }}</span>{% if not forloop.last %} / {% endif %}
|
</div>
|
||||||
{% endfor %}
|
<div>
|
||||||
{% endif %}
|
{% if item.other_title %}
|
||||||
</div>
|
{% trans '又名:' %}
|
||||||
<div>{% if item.album_type %}
|
{% for t in item.other_title %}
|
||||||
{% trans '专辑类型:' %}{{ item.album_type }}
|
<span>{{ t }}</span>
|
||||||
{% endif %}
|
{% if not forloop.last %}/{% endif %}
|
||||||
</div>
|
{% endfor %}
|
||||||
<div>{% if item.media %}
|
{% endif %}
|
||||||
{% trans '介质:' %}{{ item.media }}
|
</div>
|
||||||
{% endif %}
|
<div>
|
||||||
</div>
|
{% if item.album_type %}
|
||||||
<div>{% if item.disc_count %}
|
{% trans '专辑类型:' %}{{ item.album_type }}
|
||||||
{% trans '碟片数:' %}{{ item.disc_count }}
|
{% endif %}
|
||||||
{% endif %}
|
</div>
|
||||||
</div>
|
<div>
|
||||||
|
{% if item.media %}
|
||||||
{% if item.last_editor and item.last_editor.preference.show_last_edit %}
|
{% trans '介质:' %}{{ item.media }}
|
||||||
<div>{% trans '最近编辑者:' %}<a href="{% url 'journal:user_profile' item.last_editor.mastodon_username %}">{{ item.last_editor | default:"" }}</a></div>
|
{% endif %}
|
||||||
{% endif %}
|
</div>
|
||||||
|
<div>
|
||||||
<div>
|
{% if item.disc_count %}
|
||||||
{% if user.is_authenticated %}
|
{% trans '碟片数:' %}{{ item.disc_count }}
|
||||||
<a href="{% url 'catalog:edit' item.url_path item.uuid %}">{% trans '编辑' %}{{ item.demonstrative }}</a>
|
{% endif %}
|
||||||
{% endif %}
|
</div>
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
<!-- class specific sidebar -->
|
<!-- class specific sidebar -->
|
||||||
{% block sidebar %}
|
{% block content %}
|
||||||
{% if item.get_embed_link %}
|
{% if item.track_list %}
|
||||||
<iframe src="{{ item.get_embed_link }}" height="320" frameborder="0" allowtransparency="true" allow="encrypted-media"></iframe>
|
<section>
|
||||||
{% endif %}
|
<h5>曲目</h5>
|
||||||
|
<p class="tldr" _="on click toggle .tldr on me">{{ item.track_list | linebreaksbr }}</p>
|
||||||
|
</section>
|
||||||
|
{% endif %}
|
||||||
|
{% if item.get_embed_link %}
|
||||||
|
<section>
|
||||||
|
<h5>播放</h5>
|
||||||
|
<iframe src="{{ item.get_embed_link }}"
|
||||||
|
frameborder="0"
|
||||||
|
allowtransparency="true"
|
||||||
|
allow="encrypted-media"
|
||||||
|
style="width: 100%;
|
||||||
|
height: 50vh"></iframe>
|
||||||
|
</section>
|
||||||
|
{% endif %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
@ -4,133 +4,148 @@
|
||||||
{% load mastodon %}
|
{% load mastodon %}
|
||||||
{% load oauth_token %}
|
{% load oauth_token %}
|
||||||
{% load truncate %}
|
{% load truncate %}
|
||||||
|
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en" class="content-page">
|
||||||
|
<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>{{ site_name }} -
|
||||||
<title>{{ site_name }} - {% if form.instance.id %}{% trans '编辑' %} {{ form.instance.title }} {% else %}{% trans '添加' %}{% endif %}</title>
|
{% if form.instance.id %}
|
||||||
{% include "common_libs.html" with jquery=0 %}
|
{% trans '编辑' %} {{ form.instance.title }}
|
||||||
</head>
|
{% else %}
|
||||||
|
{% trans '添加' %}
|
||||||
<body>
|
{% endif %}
|
||||||
<div id="page-wrapper">
|
</title>
|
||||||
<div id="content-wrapper">
|
{% include "common_libs.html" with jquery=0 v2=1 %}
|
||||||
{% include "partial/_navbar.html" %}
|
<style>
|
||||||
|
aside details {
|
||||||
<section id="content" class="container">
|
margin-bottom: 1rem;
|
||||||
<div class="grid">
|
padding: 1rem;
|
||||||
<div style="float:right;padding-left:16px">
|
border: var(--pico-muted-color) solid 1px;
|
||||||
{% if item %}
|
}
|
||||||
<div class="aside-section-wrapper">
|
aside summary {
|
||||||
{% for res in form.instance.external_resources.all %}
|
cursor: pointer;
|
||||||
<div class="action-panel">
|
font-weight: bold;
|
||||||
<div class="action-panel__label">{% trans '源网站' %}: <a href="{{ res.url }}">{{ res.site_name.label }}</a></div>
|
}
|
||||||
<div class="action-panel__button-group">
|
main>div {
|
||||||
<form method="post" action="{% url 'catalog:refetch' %}">
|
margin-bottom: 4rem;
|
||||||
{% csrf_token %}
|
}
|
||||||
<input type="hidden" name="id" value="{{ res.id }}" >
|
</style>
|
||||||
<input type="hidden" name="url" value="{{ res.url }}" >
|
</head>
|
||||||
<input class="button" type="submit" value="{% trans '重新抓取' %}">
|
<body>
|
||||||
</form>
|
{% include "_header.html" %}
|
||||||
</div>
|
<main>
|
||||||
|
<div class="grid__main">
|
||||||
|
<form action="{{ submit_url }}" method="post" enctype="multipart/form-data">
|
||||||
|
{% csrf_token %}
|
||||||
|
{{ form.media }}
|
||||||
|
{{ form }}
|
||||||
|
<div class="grid">
|
||||||
|
<input type="submit" value="{% trans '保存' %}">
|
||||||
|
<input type="reset" value="{% trans '返回' %}" onclick="history.go(-1);">
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
<aside class="grid__aside">
|
||||||
|
<h5>进阶编辑选项</h5>
|
||||||
|
{% if item %}
|
||||||
|
{% for res in form.instance.external_resources.all %}
|
||||||
|
<details>
|
||||||
|
<summary>
|
||||||
|
{% trans '源网站' %}: <a href="{{ res.url }}">{{ res.site_name.label }}</a>
|
||||||
|
</summary>
|
||||||
|
<div class="grid">
|
||||||
|
<form method="post" action="{% url 'catalog:refetch' %}">
|
||||||
|
{% csrf_token %}
|
||||||
|
<input type="hidden" name="id" value="{{ res.id }}">
|
||||||
|
<input type="hidden" name="url" value="{{ res.url }}">
|
||||||
|
<input class="secondary" type="submit" value="{% trans '重新抓取' %}">
|
||||||
|
</form>
|
||||||
{% if request.user.is_staff %}
|
{% if request.user.is_staff %}
|
||||||
<div class="action-panel__button-group">
|
|
||||||
<form method="post" action="{% url 'catalog:unlink' %}">
|
<form method="post" action="{% url 'catalog:unlink' %}">
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
<input type="hidden" name="id" value="{{ res.id }}" >
|
<input type="hidden" name="id" value="{{ res.id }}">
|
||||||
<input class="button" type="submit" value="{% trans '取消关联' %}">
|
<input class="contrast" type="submit" value="{% trans '取消关联' %}">
|
||||||
</form>
|
</form>
|
||||||
</div>
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
{% endfor %}
|
</details>
|
||||||
</div>
|
{% endfor %}
|
||||||
|
{% if item.class_name == "movie" or item.class_name == "tvshow" %}
|
||||||
{% if item.class_name == "movie" or item.class_name == "tvshow" %}
|
<details>
|
||||||
<div class="aside-section-wrapper">
|
<summary>{% trans '切换分类' %}</summary>
|
||||||
<div class="action-panel">
|
<form method="post"
|
||||||
<div class="action-panel__label">{% trans '切换分类' %} </div>
|
action="{% url 'catalog:recast' item.url_path item.uuid %}"
|
||||||
<div class="action-panel__button-group">
|
onsubmit="return confirm('确认切换吗?');">
|
||||||
<form method="post" action="{% url 'catalog:recast' item.url_path item.uuid %}" onsubmit="return confirm('确认切换吗?');">
|
{% csrf_token %}
|
||||||
{% csrf_token %}
|
{% if item.class_name == "movie" %}
|
||||||
{% if item.class_name == "movie" %}
|
<input type="hidden" value="tvshow" name="class">
|
||||||
<input type="hidden" value="tvshow" name="class">
|
<input class="contrast" type="submit" value="{% trans '更改为剧集' %}">
|
||||||
<input class="button" type="submit" value="{% trans '更改为剧集' %}">
|
|
||||||
{% endif %}
|
|
||||||
{% if item.class_name == "tvshow" %}
|
|
||||||
<input type="hidden" value="movie" name="class">
|
|
||||||
<input class="button" type="submit" value="{% trans '更改为电影' %}">
|
|
||||||
{% endif %}
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
<div class="aside-section-wrapper">
|
|
||||||
<div class="action-panel">
|
|
||||||
{% if item.class_name == "tvseason" %}
|
|
||||||
{% if not item.show or request.user.is_superuser %}
|
|
||||||
<div class="action-panel__label">{% trans '将本季关联到电视剧' %} </div>
|
|
||||||
<div class="action-panel__button-group">
|
|
||||||
<form method="post" action="{% url 'catalog:assign_parent' item.url_path item.uuid %}" onsubmit="return confirm('本操作不可撤销。确认关联吗?');">
|
|
||||||
{% csrf_token %}
|
|
||||||
<input type="url" name="parent_item_url" placeholder="目标条目URL" value="{{ item.show.absolute_url }}" required><br>
|
|
||||||
<input class="button" type="submit" value="{% trans '提交' %}">
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
{% if item.class_name == "tvshow" %}
|
||||||
|
<input type="hidden" value="movie" name="class">
|
||||||
|
<input class="contrast" type="submit" value="{% trans '更改为电影' %}">
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
</form>
|
||||||
{% if item.is_deleted and not request.user.is_superuser %}
|
</details>
|
||||||
<i>条目已被删除</i>
|
|
||||||
{% elif item.merged_to_item and not request.user.is_superuser %}
|
|
||||||
<i>条目已被合并</i>
|
|
||||||
{% elif not item.deletable and not request.user.is_superuser %}
|
|
||||||
<i>条目已被用户标记过</i>
|
|
||||||
{% else %}
|
|
||||||
<div class="action-panel__label">{% trans '合并到另一条目' %} </div>
|
|
||||||
<div class="action-panel__button-group">
|
|
||||||
<form method="post" action="{% url 'catalog:merge' item.url_path item.uuid %}" onsubmit="return confirm('本操作不可撤销。确认合并吗?');">
|
|
||||||
{% csrf_token %}
|
|
||||||
<input type="url" name="new_item_url" placeholder="目标条目URL" value="{{ item.merged_to_item.absolute_url }}" required><br>
|
|
||||||
<input class="button" type="submit" value="{% trans '提交' %}">
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="action-panel__label">{% trans '删除' %} </div>
|
|
||||||
<div class="action-panel__button-group">
|
|
||||||
<form method="post" action="{% url 'catalog:delete' item.url_path item.uuid %}" onsubmit="return confirm('本操作不可撤销。确认删除吗?');">
|
|
||||||
{% csrf_token %}
|
|
||||||
<input class="button" type="submit"
|
|
||||||
{% if item.is_deleted or item.merged_to_item %} disabled {% endif %} value="{% trans '提交' %}">
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
{% if item.class_name == "tvseason" %}
|
||||||
<div class="single-section-wrapper" id="main">
|
{% if not item.show or request.user.is_superuser %}
|
||||||
<form class="entity-form" action="{{ submit_url }}" method="post" enctype="multipart/form-data">
|
<details>
|
||||||
{% csrf_token %}
|
<summary>{% trans '将本季关联到电视剧' %}</summary>
|
||||||
{{ form.media }}
|
<form method="post"
|
||||||
{{ form }}
|
action="{% url 'catalog:assign_parent' item.url_path item.uuid %}"
|
||||||
<hr/>
|
onsubmit="return confirm('本操作不可撤销。确认关联吗?');">
|
||||||
<input class="button" type="submit" value="{% trans '提交' %}">
|
{% csrf_token %}
|
||||||
<a href="{{ item.url | default:'javascript:history.go(-1)' }}" style="float:right;">返回</a>
|
<input type="url"
|
||||||
</form>
|
name="parent_item_url"
|
||||||
</div>
|
placeholder="目标条目URL"
|
||||||
|
value="{{ item.show.absolute_url }}"
|
||||||
</section>
|
required>
|
||||||
</div>
|
<br>
|
||||||
{% include "partial/_footer.html" %}
|
<input class="contrast" type="submit" value="{% trans '提交' %}">
|
||||||
</div>
|
</form>
|
||||||
</body>
|
</details>
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
</html>
|
{% if item.is_deleted and not request.user.is_superuser %}
|
||||||
|
<i>条目已被删除</i>
|
||||||
|
{% elif item.merged_to_item and not request.user.is_superuser %}
|
||||||
|
<i>条目已被合并</i>
|
||||||
|
{% elif not item.deletable and not request.user.is_superuser %}
|
||||||
|
<i>条目已被用户标记过</i>
|
||||||
|
{% else %}
|
||||||
|
<details>
|
||||||
|
<summary>{% trans '合并到另一条目' %}</summary>
|
||||||
|
<form method="post"
|
||||||
|
action="{% url 'catalog:merge' item.url_path item.uuid %}"
|
||||||
|
onsubmit="return confirm('本操作不可撤销。确认合并吗?');">
|
||||||
|
{% csrf_token %}
|
||||||
|
<input type="url"
|
||||||
|
name="new_item_url"
|
||||||
|
placeholder="目标条目URL"
|
||||||
|
value="{{ item.merged_to_item.absolute_url }}"
|
||||||
|
required>
|
||||||
|
<br>
|
||||||
|
<input class="contrast" type="submit" value="{% trans '提交' %}">
|
||||||
|
</form>
|
||||||
|
</details>
|
||||||
|
<details>
|
||||||
|
<summary>{% trans '删除' %}</summary>
|
||||||
|
<form method="post"
|
||||||
|
action="{% url 'catalog:delete' item.url_path item.uuid %}"
|
||||||
|
onsubmit="return confirm('本操作不可撤销。确认删除吗?');">
|
||||||
|
{% csrf_token %}
|
||||||
|
<input class="contrast"
|
||||||
|
type="submit"
|
||||||
|
{% if item.is_deleted or item.merged_to_item %}disabled{% endif %}
|
||||||
|
value="{% trans '提交' %}">
|
||||||
|
</form>
|
||||||
|
</details>
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
</aside>
|
||||||
|
</main>
|
||||||
|
{% include "partial/_footer.html" %}
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
|
@ -1,42 +1,38 @@
|
||||||
{% load static %}
|
{% load static %}
|
||||||
|
{% load sass_tags %}
|
||||||
{% load tz_detect %}
|
{% load tz_detect %}
|
||||||
{% tz_detect %}
|
{% if request.user.is_authenticated %}
|
||||||
{% if sentry_dsn %}
|
{% tz_detect %}
|
||||||
<script src="https://browser.sentry-cdn.com/7.7.0/bundle.min.js"></script>
|
|
||||||
<script>
|
|
||||||
if (window.Sentry) Sentry.init({
|
|
||||||
dsn: "{{ sentry_dsn }}",
|
|
||||||
release: "{{ version_hash }}",
|
|
||||||
environment: "{{ settings_module }}",
|
|
||||||
tracesSampleRate: 1.0,
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if jquery %}
|
{% if jquery %}
|
||||||
<script src="https://cdn.staticfile.org/jquery/3.6.3/jquery.min.js"></script>
|
<script src="https://cdn.staticfile.org/jquery/3.6.3/jquery.min.js"></script>
|
||||||
{% else %}
|
{% else %}
|
||||||
<script src="https://cdn.staticfile.org/cash/8.1.3/cash.min.js"></script>
|
<script src="https://cdn.staticfile.org/cash/8.1.5/cash.min.js"></script>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
if (!$.fn.is_visible) $.fn.is_visible = function () {
|
if (!$.fn.is_visible) $.fn.is_visible = function () {
|
||||||
return this.filter((_, elt) => (elt.offsetWidth || elt.offsetHeight || elt.getClientRects().length)).length > 0;
|
return this.filter((_, elt) => (elt.offsetWidth || elt.offsetHeight || elt.getClientRects().length)).length > 0;
|
||||||
};
|
};
|
||||||
if (!$.fn.submit) $.fn.submit = function () {
|
if (!$.fn.submit) $.fn.submit = function () {
|
||||||
this.each(function () {
|
this.each(function () {
|
||||||
$(this).trigger('submit');
|
$(this).trigger('submit');
|
||||||
this.submit();
|
this.submit();
|
||||||
});
|
});
|
||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/htmx/1.8.5/htmx.min.js"></script>
|
<script src="https://cdn.staticfile.org/htmx/1.9.2/htmx.min.js"></script>
|
||||||
<script src="{% static 'lib/js/hyperscript-0.9.7.min.js' %}"></script>
|
<script src="{% static 'lib/js/hyperscript-0.9.7.min.js' %}"></script>
|
||||||
<script src="{% static 'lib/js/rating-star.js' %}"></script>
|
|
||||||
<link rel="stylesheet" href="{% static 'css/boofilsic.css' %}">
|
|
||||||
<link rel="stylesheet" href="{% static 'lib/css/rating-star.css' %}">
|
|
||||||
<link rel="stylesheet" href="{% static 'lib/css/collection.css' %}">
|
|
||||||
<link rel="search" type="application/opensearchdescription+xml" title="{{ site_name }}" href="{% static 'opensearch.xml' %}">
|
|
||||||
<script src="{% static 'catalog.js' %}"></script>
|
|
||||||
<script src="{% static 'lib/js/tag-input.js' %}"></script>
|
<script src="{% static 'lib/js/tag-input.js' %}"></script>
|
||||||
<link href="{% static 'lib/css/tag-input.css' %}" type="text/css" media="all" rel="stylesheet">
|
<link rel="stylesheet"
|
||||||
<link href="{% static 'fontawesomefree/css/all.min.css' %}" rel="stylesheet" type="text/css">
|
href="https://unpkg.com/@picocss/pico@next/css/pico.min.css" />
|
||||||
|
<link href="{% sass_src 'scss/neodb.scss' %}"
|
||||||
|
rel="stylesheet"
|
||||||
|
type="text/css" />
|
||||||
|
<link href="{% static 'fontawesomefree/css/all.min.css' %}"
|
||||||
|
rel="stylesheet"
|
||||||
|
type="text/css">
|
||||||
|
<link rel="search"
|
||||||
|
type="application/opensearchdescription+xml"
|
||||||
|
title="{{ site_name }}"
|
||||||
|
href="{% static 'opensearch.xml' %}">
|
||||||
|
|
|
@ -6,118 +6,111 @@
|
||||||
{% load truncate %}
|
{% load truncate %}
|
||||||
{% load thumb %}
|
{% load thumb %}
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en" class="classic-page">
|
||||||
|
<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="{{ site_name }} - 联邦宇宙书影音游戏标注平台">
|
||||||
<title>{{ site_name }} - {% trans '发现' %}</title>
|
<meta name="description"
|
||||||
<link rel="alternate" type="application/rss+xml" title="{{ site_name }} - {{ user.mastodon_username }}的评论" href="{{ request.build_absolute_uri }}feed/reviews/">
|
property="og:description"
|
||||||
|
content="{{ site_name }}致力于为联邦宇宙居民提供一个自由、开放、互联的书籍、电影、音乐和游戏收藏评论空间">
|
||||||
{% include "common_libs.html" with jquery=0 %}
|
<meta property="og:type" content="website">
|
||||||
<script src="{% static 'js/mastodon.js' %}" defer></script>
|
<meta property="og:url" content="{{ site_url }}">
|
||||||
<script src="{% static 'js/home.js' %}" defer></script>
|
<meta property="og:image"
|
||||||
|
content="{{ request.scheme }}://{{ request.get_host }}{% static 'img/logo_square.jpg' %}">
|
||||||
|
<meta property="og:site_name" content="{{ site_name }}">
|
||||||
|
<title>{{ site_name }} - {% trans '发现' %}</title>
|
||||||
|
<link rel="alternate"
|
||||||
|
type="application/rss+xml"
|
||||||
|
title="{{ site_name }} - {{ user.mastodon_username }}的评论"
|
||||||
|
href="{{ request.build_absolute_uri }}feed/reviews/">
|
||||||
|
{% include "common_libs.html" with jquery=0 v2=1 %}
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/shikwasa@2.2.1/dist/shikwasa.min.js"></script>
|
||||||
|
<link href="https://cdn.jsdelivr.net/npm/shikwasa@2.2.1/dist/style.min.css"
|
||||||
|
rel="stylesheet"></link>
|
||||||
|
<script src="{% static 'podcast.js' %}"></script>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<div id="page-wrapper">
|
{% include "_header.html" with current="discover" %}
|
||||||
<div id="content-wrapper">
|
<main>
|
||||||
{% include "partial/_navbar.html" with current="discover" %}
|
<div class="grid__main">
|
||||||
|
<div class="sortable">
|
||||||
<section id="content">
|
{% for gallery in gallery_list %}
|
||||||
<div class="grid grid--reverse-order">
|
<section class="entity-sort shelf"
|
||||||
<div class="grid__main grid__main--reverse-order">
|
id="{{ gallery.name }}"
|
||||||
|
{% if not gallery.items %}style="display:none;"{% endif %}>
|
||||||
<div class="main-section-wrapper sortable">
|
<h5>{{ gallery.title }}</h5>
|
||||||
|
<ul class="cards">
|
||||||
{% for gallery in gallery_list %}
|
{% for item in gallery.items %}
|
||||||
<div class="entity-sort" id="{{ gallery.name }}" {% if not gallery.items %}style="display:none;"{% endif %}>
|
<li class="card">
|
||||||
<h5 class="entity-sort__label">
|
<a href="{{ item.url }}" title="{{ item.title }}">
|
||||||
{{ gallery.title }}
|
<img src="{{ item.cover|thumb:'normal' }}"
|
||||||
</h5>
|
alt="{{ item.title }}"
|
||||||
<ul class="entity-sort__entity-list">
|
loading="lazy">
|
||||||
{% for item in gallery.items %}
|
<div class="card-title">{{ item.title }}</div>
|
||||||
<li class="entity-sort__entity">
|
</a>
|
||||||
<a href="{{ item.url }}">
|
</li>
|
||||||
<img src="{{ item.cover_image_url | default:item.cover.url }}" alt="{{ item.title }}" class="entity-sort__entity-img">
|
|
||||||
<div class="entity-sort__entity-name" title="{{ item.title }}"> {{ item.title }}</div>
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
{% empty %}
|
|
||||||
<div>暂无记录</div>
|
|
||||||
{% endfor %}
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
</div>
|
</section>
|
||||||
|
{% endfor %}
|
||||||
{% if user == request.user %}
|
</div>
|
||||||
|
{% if request.user.is_authenticated %}
|
||||||
<div class="entity-sort-control">
|
<div class="entity-sort-control">
|
||||||
<div class="entity-sort-control__button" id="sortEditButton">
|
<div class="entity-sort-control__button" id="sortEditButton">
|
||||||
<span class="entity-sort-control__text" id="sortEditText">
|
<span class="entity-sort-control__text" id="sortEditText">{% trans '编辑布局' %}</span>
|
||||||
{% trans '编辑布局' %}
|
<span class="entity-sort-control__text"
|
||||||
</span>
|
id="sortSaveText"
|
||||||
<span class="entity-sort-control__text" id="sortSaveText" style="display: none;">
|
style="display: none">{% trans '保存' %}</span>
|
||||||
{% trans '保存' %}
|
<span class="icon-edit" id="sortEditIcon">
|
||||||
</span>
|
<i class="fa-solid fa-pencil"></i>
|
||||||
<span class="icon-edit" id="sortEditIcon">
|
</span>
|
||||||
<i class="fa-solid fa-pencil"></i>
|
<span class="icon-save" id="sortSaveIcon" style="display: none;">
|
||||||
</span>
|
<i class="fa-regular fa-floppy-disk"></i>
|
||||||
<span class="icon-save" id="sortSaveIcon" style="display: none;">
|
</span>
|
||||||
<i class="fa-regular fa-floppy-disk"></i>
|
</div>
|
||||||
</span>
|
<div class="entity-sort-control__button"
|
||||||
</div>
|
id="sortExitButton"
|
||||||
<div class="entity-sort-control__button" id="sortExitButton" style="display: none;">
|
style="display: none">
|
||||||
<span class="entity-sort-control__text">
|
<span class="entity-sort-control__text">{% trans '取消' %}</span>
|
||||||
{% trans '取消' %}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="entity-sort-control__button entity-sort-control__button--float-right" id="toggleDisplayButtonTemplate" style="display: none;">
|
|
||||||
<span class="showText" style="display: none;">
|
|
||||||
{% trans '显示' %}
|
|
||||||
</span>
|
|
||||||
<span class="hideText" style="display: none;">
|
|
||||||
{% trans '隐藏' %}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<form action="{% url 'users:set_layout' %}" method="post" id="sortForm">
|
|
||||||
{% csrf_token %}
|
|
||||||
<input type="hidden" name="name" value="discover">
|
|
||||||
<input type="hidden" name="layout">
|
|
||||||
</form>
|
|
||||||
<script src="https://cdn.staticfile.org/html5sortable/0.13.3/html5sortable.min.js" crossorigin="anonymous"></script>
|
|
||||||
<script src="{% static 'js/sort_layout.js' %}"></script>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
{{ layout|json_script:"layout-data" }}
|
|
||||||
<script>
|
|
||||||
const initialLayoutData = JSON.parse(document.getElementById('layout-data').textContent);
|
|
||||||
// initialize sort element visibility and order
|
|
||||||
initialLayoutData.forEach(elem => {
|
|
||||||
// set visiblity
|
|
||||||
$('#' + elem.id).data('visibility', elem.visibility);
|
|
||||||
if (!elem.visibility) {
|
|
||||||
$('#' + elem.id).hide();
|
|
||||||
}
|
|
||||||
// order
|
|
||||||
$('#' + elem.id).appendTo('.main-section-wrapper');
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{% include "partial/_sidebar.html" %}
|
|
||||||
</div>
|
</div>
|
||||||
</section>
|
<div class="entity-sort-control__button entity-sort-control__button--float-right"
|
||||||
|
id="toggleDisplayButtonTemplate"
|
||||||
|
style="display: none">
|
||||||
|
<span class="showText" style="display: none;">{% trans '显示' %}</span>
|
||||||
|
<span class="hideText" style="display: none;">{% trans '隐藏' %}</span>
|
||||||
|
</div>
|
||||||
|
<form action="{% url 'users:set_layout' %}" method="post" id="sortForm">
|
||||||
|
{% csrf_token %}
|
||||||
|
<input type="hidden" name="name" value="discover">
|
||||||
|
<input type="hidden" name="layout">
|
||||||
|
</form>
|
||||||
|
<script src="https://cdn.staticfile.org/html5sortable/0.13.3/html5sortable.min.js"
|
||||||
|
crossorigin="anonymous"></script>
|
||||||
|
<script src="{% static 'js/sort_layout.js' %}"></script>
|
||||||
|
{{ layout|json_script:"layout-data" }}
|
||||||
|
<script>
|
||||||
|
const initialLayoutData = JSON.parse(document.getElementById('layout-data').textContent);
|
||||||
|
// initialize sort element visibility and order
|
||||||
|
initialLayoutData.forEach(elem => {
|
||||||
|
// set visiblity
|
||||||
|
$('#' + elem.id).data('visibility', elem.visibility);
|
||||||
|
if (!elem.visibility) {
|
||||||
|
$('#' + elem.id).hide();
|
||||||
|
}
|
||||||
|
// order
|
||||||
|
$('#' + elem.id).appendTo('.sortable');
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
{% include "partial/_footer.html" %}
|
{% if request.user.is_authenticated %}
|
||||||
</div>
|
{% include "_sidebar.html" with show_progress=1 %}
|
||||||
|
{% else %}
|
||||||
{% if request.user.unread_announcements %}
|
{% include "partial/_sidebar_anonymous.html" %}
|
||||||
{% include "partial/_announcement.html" %}
|
{% endif %}
|
||||||
{% endif %}
|
</main>
|
||||||
|
{% include "partial/_footer.html" %}
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -9,105 +9,153 @@
|
||||||
{% load truncate %}
|
{% load truncate %}
|
||||||
{% load strip_scheme %}
|
{% load strip_scheme %}
|
||||||
{% load thumb %}
|
{% load thumb %}
|
||||||
|
|
||||||
{% block head %}
|
{% block head %}
|
||||||
{% if item.author %}
|
{% if item.author %}
|
||||||
<meta property="og:book:author" content="{% for author in item.author %}{{ author }}{% if not forloop.last %},{% endif %}{% endfor %}">
|
<meta property="og:book:author"
|
||||||
{% endif %}
|
content="{% for author in item.author %}{{ author }}{% if not forloop.last %},{% endif %}{% endfor %}">
|
||||||
{% if item.isbn %}
|
{% endif %}
|
||||||
<meta property="og:book:isbn" content="{{ item.isbn }}">
|
{% if item.isbn %}<meta property="og:book:isbn" content="{{ item.isbn }}">{% endif %}
|
||||||
{% endif %}
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block details %}
|
{% block details %}
|
||||||
<div class="entity-detail__fields">
|
<!-- <div>{% if item.subtitle %}{% trans '副标题:' %}{{ item.subtitle }}{% endif %}</div>
|
||||||
<div class="entity-detail__rating">
|
<div>{% if item.orig_title %}{% trans '原作名:' %}{{ item.orig_title }}{% endif %}</div> -->
|
||||||
{% if item.rating %}
|
<div>
|
||||||
<span class="entity-detail__rating-star rating-star" data-rating-score="{{ item.rating | floatformat:0 }}"></span>
|
{% if item.isbn %}
|
||||||
<span class="entity-detail__rating-score"> {{ item.rating | floatformat:1 }} </span>
|
{% trans 'ISBN:' %}{{ item.isbn }}
|
||||||
<small>({{ item.rating_count }}人评分)</small>
|
{% endif %}
|
||||||
{% else %}
|
</div>
|
||||||
<span> {% trans '评分:评分人数不足' %}</span>
|
<div>
|
||||||
{% endif %}
|
{% if item.author %}
|
||||||
</div>
|
{% trans '作者:' %}
|
||||||
<div>{% if item.subtitle %}{% trans '副标题:' %}{{ item.subtitle }}{% endif %}</div>
|
{% for author in item.author %}
|
||||||
<div>{% if item.isbn %}{% trans 'ISBN:' %}{{ item.isbn }}{% endif %}</div>
|
<span>{{ author }}</span>
|
||||||
<div>{% if item.author %}{% trans '作者:' %}
|
{% if not forloop.last %}/{% endif %}
|
||||||
{% for author in item.author %}
|
{% endfor %}
|
||||||
<span>{{ author }}</span>{% if not forloop.last %} / {% endif %}
|
{% endif %}
|
||||||
{% endfor %}
|
</div>
|
||||||
{% endif %}</div>
|
<div>
|
||||||
<div>{% if item.pub_house %}{% trans '出版社:' %}{{ item.pub_house }}{% endif %}</div>
|
{% if item.translator %}
|
||||||
<div>{% if item.orig_title %}{% trans '原作名:' %}{{ item.orig_title }}{% endif %}</div>
|
{% trans '译者:' %}
|
||||||
<div>{% if item.translator %}{% trans '译者:' %}
|
{% for translator in item.translator %}
|
||||||
{% for translator in item.translator %}
|
<span>{{ translator }}</span>
|
||||||
<span>{{ translator }}</span>{% if not forloop.last %} / {% endif %}
|
{% if not forloop.last %}/{% endif %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% endif %}</div>
|
{% endif %}
|
||||||
<div>{%if item.pub_year %}{% trans '出版时间:' %}{{ item.pub_year }}{% trans '年' %}{% if item.pub_month %}{{ item.pub_month }}{% trans '月' %}{% endif %}{% endif %}</div>
|
</div>
|
||||||
<div>{% if item.series %}{% trans '丛书系列:' %}{{ item.series }}{% endif %}</div>
|
<div>
|
||||||
</div>
|
{% if item.pub_house %}
|
||||||
<div class="entity-detail__fields">
|
{% trans '出版社:' %}{{ item.pub_house }}
|
||||||
<div>{% if item.language %}{% trans '语言:' %}{{ item.language }}{% endif %}</div>
|
{% endif %}
|
||||||
<div>{% if item.binding %}{% trans '装帧:' %}{{ item.binding }}{% endif %}</div>
|
</div>
|
||||||
<div>{% if item.price %}{% trans '定价:' %}{{ item.price }}{% endif %}</div>
|
<div>
|
||||||
<div>{% if item.pages %}{% trans '页数:' %}{{ item.pages }}{% endif %}</div>
|
{% if item.imprint %}
|
||||||
<div>{% if item.imprint %}{% trans '出品方:' %}{{ item.imprint }}{% endif %}</div>
|
{% trans '出品方:' %}{{ item.imprint }}
|
||||||
{% if item.other_info %}
|
{% endif %}
|
||||||
{% for k, v in item.other_info.items %}
|
</div>
|
||||||
<div>
|
<div>
|
||||||
{{ k }}:{{ v | urlize }}
|
{% if item.pub_year %}
|
||||||
</div>
|
{% trans '出版时间:' %}{{ item.pub_year }}{% trans '年' %}
|
||||||
{% endfor %}
|
{% if item.pub_month %}
|
||||||
{% endif %}
|
{{ item.pub_month }}{% trans '月' %}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
{% if item.last_editor and item.last_editor.preference.show_last_edit %}
|
</div>
|
||||||
<div>{% trans '最近编辑者:' %}<a href="{% url 'journal:user_profile' item.last_editor.mastodon_username %}">{{ item.last_editor | default:"" }}</a></div>
|
<div>
|
||||||
{% endif %}
|
{% if item.series %}
|
||||||
|
{% trans '丛书系列:' %}{{ item.series }}
|
||||||
<div>
|
{% endif %}
|
||||||
{% if user.is_authenticated %}
|
</div>
|
||||||
<a href="{% url 'catalog:edit' item.url_path item.uuid %}">{% trans '编辑' %}{{ item.demonstrative }}</a>
|
<div>
|
||||||
{% endif %}
|
{% if item.language %}
|
||||||
</div>
|
{% trans '语言:' %}{{ item.language }}
|
||||||
</div>
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
{% if item.binding %}
|
||||||
|
{% trans '装帧:' %}{{ item.binding }}
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
{% if item.price %}
|
||||||
|
{% trans '定价:' %}{{ item.price }}
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
{% if item.pages %}
|
||||||
|
{% trans '页数:' %}{{ item.pages }}
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
{% if item.other_info %}
|
||||||
|
{% for k, v in item.other_info.items %}<div>{{ k }}:{{ v|urlizetrunc:24 }}</div>{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
{% endblock %}
|
||||||
|
{% block content %}
|
||||||
|
{% if item.contents %}
|
||||||
|
<section>
|
||||||
|
<h5>目录</h5>
|
||||||
|
<p class="tldr" _="on click toggle .tldr on me">{{ item.contents | linebreaksbr }}</p>
|
||||||
|
</section>
|
||||||
|
{% endif %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
|
|
||||||
{% block sidebar %}
|
{% block sidebar %}
|
||||||
{% with related_books=item.get_related_books %}
|
{% with related_books=item.get_related_books %}
|
||||||
{% if related_books.count > 0 %}
|
{% if related_books.count > 0 %}
|
||||||
<div class="aside-section-wrapper">
|
<section>
|
||||||
<div class="action-panel">
|
<h5>{% trans '其它版本' %}</h5>
|
||||||
<div class="action-panel__label">{% trans '其它版本' %}</div>
|
{% for b in related_books %}
|
||||||
<div >
|
<p>
|
||||||
{% for b in related_books %}
|
<a href="{{ b.url }}">{{ b.title }}</a>
|
||||||
<p>
|
<small>({{ b.pub_house | default:'' }} {{ b.pub_year | default:'' }})</small>
|
||||||
<a href="{{ b.url }}">{{ b.title }}</a>
|
{% comment %} {% for res in b.external_resources.all %}
|
||||||
<small>({{ b.pub_house | default:'' }} {{ b.pub_year | default:'' }})</small>
|
<a href="{{ res.url }}">
|
||||||
{% for res in b.external_resources.all %}
|
<span class="source-label source-label__{{ res.site_name }}">{{ res.site_name.label }}</span>
|
||||||
<a href="{{ res.url }}">
|
</a>
|
||||||
<span class="source-label source-label__{{ res.site_name }}">{{ res.site_name.label }}</span>
|
{% endfor %} {% endcomment %}
|
||||||
</a>
|
</p>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</p>
|
</section>
|
||||||
{% endfor %}
|
{% endif %}
|
||||||
</div>
|
{% endwith %}
|
||||||
</div>
|
{% if item.isbn %}
|
||||||
</div>
|
<section>
|
||||||
{% endif %}
|
<div class="action-panel">
|
||||||
{% endwith %}
|
<h5>{% trans '借阅或购买' %}</h5>
|
||||||
|
<div>
|
||||||
{% if item.isbn %}
|
<ul>
|
||||||
<div class="aside-section-wrapper">
|
<li>
|
||||||
<div class="action-panel">
|
<a target="_blank"
|
||||||
<div class="action-panel__label">{% trans '借阅或购买' %}</div>
|
rel="noopener"
|
||||||
<div class="action-panel__button-group">
|
href="https://www.worldcat.org/isbn/{{ item.isbn }}">WorldCat</a>
|
||||||
<a class="action-panel__button" target="_blank" rel="noopener" href="https://www.worldcat.org/isbn/{{ item.isbn }}">{% trans 'WorldCat' %}</a>
|
</li>
|
||||||
<a class="action-panel__button" target="_blank" rel="noopener" href="https://openlibrary.org/search?isbn={{ item.isbn }}">{% trans 'Open Library' %}</a>
|
<li>
|
||||||
</div>
|
<a target="_blank"
|
||||||
</div>
|
rel="noopener"
|
||||||
</div>
|
href="https://openlibrary.org/search?isbn={{ item.isbn }}">Open Library</a>
|
||||||
{% endif %}
|
</li>
|
||||||
|
<li>
|
||||||
|
<a target="_blank"
|
||||||
|
rel="noopener"
|
||||||
|
href="https://library.oapen.org/discover?filtertype_1=isbn&filter_relational_operator_1=equals&filter_1={{ item.isbn }}">
|
||||||
|
OAPEN</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a target="_blank"
|
||||||
|
rel="noopener"
|
||||||
|
href="https://bookshop.org/search?keywords={{ item.isbn }}">Bookshop.org</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a target="_blank"
|
||||||
|
rel="noopener"
|
||||||
|
href="https://www.amazon.com/s?k={{ item.isbn }}">Amazon</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a target="_blank"
|
||||||
|
rel="noopener"
|
||||||
|
href="https://www.duozhuayu.com/search/book/{{ item.isbn }}">多抓鱼</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
{% endif %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
@ -8,17 +8,14 @@
|
||||||
{% load truncate %}
|
{% load truncate %}
|
||||||
{% load strip_scheme %}
|
{% load strip_scheme %}
|
||||||
{% load thumb %}
|
{% load thumb %}
|
||||||
|
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<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">
|
||||||
<script src="https://cdn.staticfile.org/cash/8.1.3/cash.min.js"></script>
|
<script src="https://cdn.staticfile.org/cash/8.1.3/cash.min.js"></script>
|
||||||
{% block head %}
|
{% block head %}{% endblock %}
|
||||||
{% endblock %}
|
<title>{{ site_name }} - {% trans item.category.label %} | {{ item.title }}</title>
|
||||||
<title>{{ site_name }} - {% trans item.category.label %} | {{ item.title }}</title>
|
</head>
|
||||||
</head>
|
<body></body>
|
||||||
<body>
|
|
||||||
</body>
|
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -9,10 +9,10 @@
|
||||||
{% load truncate %}
|
{% load truncate %}
|
||||||
{% load strip_scheme %}
|
{% load strip_scheme %}
|
||||||
{% load thumb %}
|
{% load thumb %}
|
||||||
|
|
||||||
{% block head %}
|
{% block head %}
|
||||||
<script src="https://cdn.jsdelivr.net/npm/shikwasa@2.2.0/dist/shikwasa.min.js"></script>
|
<script src="https://cdn.jsdelivr.net/npm/shikwasa@2.2.1/dist/shikwasa.min.js"></script>
|
||||||
<link href="https://cdn.jsdelivr.net/npm/shikwasa@2.2.0/dist/style.min.css" rel="stylesheet"></link>
|
<link href="https://cdn.jsdelivr.net/npm/shikwasa@2.2.1/dist/style.min.css"
|
||||||
|
rel="stylesheet"></link>
|
||||||
<style>
|
<style>
|
||||||
.shk-player {
|
.shk-player {
|
||||||
font-family: sans-serif;
|
font-family: sans-serif;
|
||||||
|
|
|
@ -8,43 +8,6 @@
|
||||||
{% load truncate %}
|
{% load truncate %}
|
||||||
{% load highlight %}
|
{% load highlight %}
|
||||||
{% load thumb %}
|
{% load thumb %}
|
||||||
|
|
||||||
{% for item in external_items %}
|
{% for item in external_items %}
|
||||||
<li class="entity-list__entity">
|
<article class="item-card external">{% include "_item_card.html" with item=item %}</article>
|
||||||
<div class="entity-list__entity-img-wrapper">
|
{% endfor %}
|
||||||
<a href="{{ item.link }}">
|
|
||||||
{% if item.cover_url %}
|
|
||||||
<img src="{{ item.cover_url }}" alt="" class="entity-list__entity-img">
|
|
||||||
{% endif %}
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
<div class="entity-list__entity-text">
|
|
||||||
<div class="entity-list__entity-title" style="font-style:italic;">
|
|
||||||
<a href="{{ item.link }}" class="entity-list__entity-link">
|
|
||||||
{% if request.GET.q %}
|
|
||||||
{{ item.title | highlight:request.GET.q }}
|
|
||||||
{% else %}
|
|
||||||
{{ item.title }}
|
|
||||||
{% endif %}
|
|
||||||
</a>
|
|
||||||
|
|
||||||
{% if not request.GET.c or not request.GET.c in categories %}
|
|
||||||
<span class="entity-list__entity-category">[{{item.verbose_category_name}}]</span>
|
|
||||||
{% endif %}
|
|
||||||
<a href="{{ item.source_url }}">
|
|
||||||
<span class="source-label source-label__{{ item.source_site }}">{{ item.source_site.label }}</span>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<span class="entity-list__entity-info entity-list__entity-info--full-length">
|
|
||||||
{{item.subtitle}}
|
|
||||||
</span>
|
|
||||||
<p class="entity-list__entity-brief">
|
|
||||||
{{ item.brief }}
|
|
||||||
</p>
|
|
||||||
<div class="tag-collection">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</li>
|
|
||||||
{% endfor %}
|
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
<p>
|
<p>
|
||||||
无法加载条目。部分网站可能删除条目或隐藏条目为仅登录可见,欢迎在本站手工添加这些条目。
|
<i class="fa-solid fa-triangle-exclamation"></i>
|
||||||
</p>
|
无法加载条目,请确认链接正确。
|
||||||
|
部分网站可能删除条目或隐藏条目为仅登录可见,欢迎在本站手工添加这些条目。
|
||||||
|
</p>
|
||||||
|
|
|
@ -9,51 +9,28 @@
|
||||||
{% load highlight %}
|
{% load highlight %}
|
||||||
{% load thumb %}
|
{% load thumb %}
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en" class="classic-page">
|
||||||
|
<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>{{ site_name }} - {% trans '搜索结果' %}</title>
|
<title>{{ site_name }} - {% trans '搜索结果' %}</title>
|
||||||
{% include "common_libs.html" with jquery=0 %}
|
{% include "common_libs.html" with jquery=0 v2=1 %}
|
||||||
</head>
|
</head>
|
||||||
|
<body>
|
||||||
<body>
|
{% include '_header.html' %}
|
||||||
<div id="page-wrapper">
|
<main>
|
||||||
<div id="content-wrapper">
|
<div class="grid__main">
|
||||||
{% include 'partial/_navbar.html' %}
|
<article>
|
||||||
|
<h5>{% trans '正在连线' %}{{ site.SITE_NAME.label }}</h5>
|
||||||
<section id="content">
|
<div hx-get="{% url 'catalog:fetch_refresh' job_id %}"
|
||||||
<div class="grid">
|
hx-trigger="load delay:2s"
|
||||||
<div class="grid__main">
|
hx-swap="outerHTML">
|
||||||
<div class="main-section-wrapper">
|
<i class="fa-solid fa-compact-disc fa-spin loading"></i>
|
||||||
<div>
|
</div>
|
||||||
{% trans '正在连线' %}{{ site.SITE_NAME.label }}
|
</article>
|
||||||
<div hx-get="{% url 'catalog:fetch_refresh' job_id %}" hx-trigger="load delay:2s" hx-swap="outerHTML"></div>
|
</div>
|
||||||
<i class="fas fa-fan fa-spin"></i>
|
{% include "search_sidebar.html" %}
|
||||||
</div>
|
</main>
|
||||||
|
{% include 'partial/_footer.html' %}
|
||||||
</div>
|
</body>
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
{% include "search_sidebar.html" %}
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
</div>
|
|
||||||
{% include 'partial/_footer.html' %}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<script>
|
|
||||||
document.body.addEventListener('htmx:configRequest', (event) => {
|
|
||||||
event.detail.headers['X-CSRFToken'] = '{{ csrf_token }}';
|
|
||||||
})
|
|
||||||
</script>
|
|
||||||
</body>
|
|
||||||
|
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -1 +1,5 @@
|
||||||
<div hx-get="{% url 'catalog:fetch_refresh' job_id %}?retry={{ retry }}" hx-trigger="load delay:{{ delay }}s" hx-swap="outerHTML"></div>
|
<div hx-get="{% url 'catalog:fetch_refresh' job_id %}?retry={{ retry }}"
|
||||||
|
hx-trigger="load delay:{{ delay }}s"
|
||||||
|
hx-swap="outerHTML">
|
||||||
|
<i class="fa-solid fa-compact-disc fa-spin loading"></i>
|
||||||
|
</div>
|
||||||
|
|
|
@ -9,100 +9,75 @@
|
||||||
{% load truncate %}
|
{% load truncate %}
|
||||||
{% load strip_scheme %}
|
{% load strip_scheme %}
|
||||||
{% load thumb %}
|
{% load thumb %}
|
||||||
|
|
||||||
<!-- class specific details -->
|
<!-- class specific details -->
|
||||||
{% block details %}
|
{% block details %}
|
||||||
<div class="entity-detail__fields">
|
<div>
|
||||||
<div class="entity-detail__rating">
|
{% if item.other_title %}
|
||||||
{% if item.rating and item.rating_count >= 5 %}
|
{% trans '别名:' %}
|
||||||
<span class="entity-detail__rating-star rating-star" data-rating-score="{{ item.rating | floatformat:0 }}"></span>
|
{% for other_title in item.other_title %}
|
||||||
<span class="entity-detail__rating-score"> {{ item.rating | floatformat:1 }} </span>
|
<span {% if forloop.counter > 5 %}style="display: none;"{% endif %}>
|
||||||
<small>({{ item.rating_count }}人评分)</small>
|
<span class="other_title">{{ other_title }}</span>
|
||||||
{% else %}
|
{% if not forloop.last %}/{% endif %}
|
||||||
<span> {% trans '评分:评分人数不足' %}</span>
|
</span>
|
||||||
{% endif %}
|
{% endfor %}
|
||||||
</div>
|
{% if item.other_title|length > 5 %}
|
||||||
|
<a href="javascript:void(0);" id="otherTitleMore">{% trans '更多' %}</a>
|
||||||
<div>{% if item.other_title %}{% trans '别名:' %}
|
<script>
|
||||||
{% for other_title in item.other_title %}
|
|
||||||
<span {% if forloop.counter > 5 %}style="display: none;" {% endif %}>
|
|
||||||
<span class="other_title">{{ other_title }}</span>
|
|
||||||
{% if not forloop.last %} / {% endif %}
|
|
||||||
</span>
|
|
||||||
{% endfor %}
|
|
||||||
{% if item.other_title|length > 5 %}
|
|
||||||
<a href="javascript:void(0);" id="otherTitleMore">{% trans '更多' %}</a>
|
|
||||||
<script>
|
|
||||||
$("#otherTitleMore").on('click', function (e) {
|
$("#otherTitleMore").on('click', function (e) {
|
||||||
$("span.other_title:not(:visible)").each(function (e) {
|
$("span.other_title:not(:visible)").each(function (e) {
|
||||||
$(this).parent().removeAttr('style');
|
$(this).parent().removeAttr('style');
|
||||||
});
|
});
|
||||||
$(this).remove();
|
$(this).remove();
|
||||||
})
|
})
|
||||||
</script>
|
|
||||||
{% endif %}
|
</script>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
{% endif %}
|
||||||
|
</div>
|
||||||
<div>
|
<div>
|
||||||
{% if item.genre %}{% trans '类型:' %}
|
{% if item.genre %}
|
||||||
{% for genre in item.genre %}
|
{% trans '类型:' %}
|
||||||
<span>{{ genre }}</span>{% if not forloop.last %} / {% endif %}
|
{% for genre in item.genre %}
|
||||||
{% endfor %}
|
<span>{{ genre }}</span>
|
||||||
{% endif %}
|
{% if not forloop.last %}/{% endif %}
|
||||||
</div>
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
<div>
|
</div>
|
||||||
{% if item.developer %}{% trans '开发商:' %}
|
<div>
|
||||||
{% for developer in item.developer %}
|
{% if item.developer %}
|
||||||
<span>{{ developer }}</span>{% if not forloop.last %} / {% endif %}
|
{% trans '开发商:' %}
|
||||||
{% endfor %}
|
{% for developer in item.developer %}
|
||||||
{% endif %}
|
<span>{{ developer }}</span>
|
||||||
</div>
|
{% if not forloop.last %}/{% endif %}
|
||||||
|
{% endfor %}
|
||||||
<div>
|
{% endif %}
|
||||||
{% if item.publisher %}{% trans '发行商:' %}
|
</div>
|
||||||
{% for publisher in item.publisher %}
|
<div>
|
||||||
<span>{{ publisher }}</span>{% if not forloop.last %} / {% endif %}
|
{% if item.publisher %}
|
||||||
{% endfor %}
|
{% trans '发行商:' %}
|
||||||
{% endif %}
|
{% for publisher in item.publisher %}
|
||||||
</div>
|
<span>{{ publisher }}</span>
|
||||||
|
{% if not forloop.last %}/{% endif %}
|
||||||
<div>{% if item.release_date %}
|
{% endfor %}
|
||||||
{% trans '发行日期:' %}{{ item.release_date }}
|
{% endif %}
|
||||||
{% endif %}
|
</div>
|
||||||
</div>
|
<div>
|
||||||
|
{% if item.release_date %}
|
||||||
<div>{% if item.official_site %}
|
{% trans '发行日期:' %}{{ item.release_date }}
|
||||||
{% trans '官方网站:' %}{{ item.official_site|urlizetrunc:42 }}
|
{% endif %}
|
||||||
{% endif %}
|
</div>
|
||||||
</div>
|
<div>
|
||||||
|
{% if item.official_site %}
|
||||||
</div>
|
{% trans '官方网站:' %}{{ item.official_site|urlizetrunc:24 }}
|
||||||
<div class="entity-detail__fields">
|
{% endif %}
|
||||||
|
</div>
|
||||||
<div>
|
<div>
|
||||||
{% if item.platform %}{% trans '平台:' %}
|
{% if item.platform %}
|
||||||
{% for platform in item.platform %}
|
{% trans '平台:' %}
|
||||||
<span>{{ platform }}</span>{% if not forloop.last %} / {% endif %}
|
{% for platform in item.platform %}
|
||||||
{% endfor %}
|
<span>{{ platform }}</span>
|
||||||
{% endif %}
|
{% if not forloop.last %}/{% endif %}
|
||||||
</div>
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
|
||||||
{% if item.last_editor and item.last_editor.preference.show_last_edit %}
|
|
||||||
<div>{% trans '最近编辑者:' %}<a href="{% url 'journal:user_profile' item.last_editor.mastodon_username %}">{{ item.last_editor | default:"" }}</a></div>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
<div>
|
|
||||||
{% if user.is_authenticated %}
|
|
||||||
<a href="{% url 'catalog:edit' item.url_path item.uuid %}">{% trans '编辑' %}{{ item.demonstrative }}</a>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% endblock %}
|
|
||||||
|
|
||||||
<!-- class specific sidebar -->
|
|
||||||
{% block sidebar %}
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
@ -9,11 +9,7 @@
|
||||||
{% load truncate %}
|
{% load truncate %}
|
||||||
{% load strip_scheme %}
|
{% load strip_scheme %}
|
||||||
{% load thumb %}
|
{% load thumb %}
|
||||||
|
|
||||||
<!-- class specific details -->
|
<!-- class specific details -->
|
||||||
{% block details %}
|
{% block details %}{% endblock %}
|
||||||
{% endblock %}
|
|
||||||
|
|
||||||
<!-- class specific sidebar -->
|
<!-- class specific sidebar -->
|
||||||
{% block sidebar %}
|
{% block sidebar %}{% endblock %}
|
||||||
{% endblock %}
|
|
||||||
|
|
|
@ -9,325 +9,389 @@
|
||||||
{% load strip_scheme %}
|
{% load strip_scheme %}
|
||||||
{% load thumb %}
|
{% load thumb %}
|
||||||
{% load user_actions %}
|
{% load user_actions %}
|
||||||
|
{% load duration %}
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en" id="item-page">
|
||||||
|
<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"
|
||||||
<meta property="og:title" content="{{ site_name }}{% trans item.category.label %} - {{ item.title }}">
|
content="{{ site_name }}{% trans item.category.label %} - {{ item.title }}">
|
||||||
<meta property="og:type" content="{{ item.category }}">
|
<meta property="og:type" content="{{ item.category }}">
|
||||||
<meta property="og:url" content="{{ request.build_absolute_uri }}">
|
<meta property="og:url" content="{{ request.build_absolute_uri }}">
|
||||||
{% if item.has_cover %}
|
{% if item.has_cover %}<meta property="og:image" content="{{ item.cover_image_url }}">{% endif %}
|
||||||
<meta property="og:image" content="{{ item.cover_image_url }}">
|
<meta property="og:site_name" content="{{ site_name }}">
|
||||||
{% endif %}
|
<meta property="og:description" content="{{ item.brief }}">
|
||||||
<meta property="og:site_name" content="{{ site_name }}">
|
{% if item.is_deleted or item.merged_to_item %}<meta name="robots" content="noindex">{% endif %}
|
||||||
<meta property="og:description" content="{{ item.brief }}">
|
<title>{{ site_name }} - {% trans item.category.label %} | {{ item.title }}</title>
|
||||||
{% block head %}
|
{% include "common_libs.html" with jquery=0 v2=1 %}
|
||||||
{% endblock %}
|
{% block head %}{% endblock %}
|
||||||
<title>{{ site_name }} - {% trans item.category.label %} | {{ item.title }}</title>
|
</head>
|
||||||
{% include "common_libs.html" with jquery=0 %}
|
<body>
|
||||||
</head>
|
{% include "_header.html" %}
|
||||||
|
<main class="container-fluid">
|
||||||
<body>
|
<div id="item-title" class="middle">
|
||||||
<div id="page-wrapper">
|
{% if item.is_deleted %}[DELETED]{% endif %}
|
||||||
<div id="content-wrapper">
|
{% if item.merged_to_item %}
|
||||||
{% include "partial/_navbar.html" %}
|
[MERGED TO <a href="{{ item.merged_to_item.url }}">{{ item.merged_to_item.title }}</a>]
|
||||||
|
{% endif %}
|
||||||
<section id="content">
|
<h1>
|
||||||
<div class="grid">
|
{{ item.title }}
|
||||||
<div class="grid__main" id="main">
|
<small>
|
||||||
<div class="main-section-wrapper">
|
{% if item.season_number %}
|
||||||
<div class="entity-detail">
|
{% trans '第' %}{{ item.season_number|apnumber }}{% trans '季' %}
|
||||||
|
|
||||||
<a href="{{ item.cover.url }}" class="entity-detail__img-origin" target="_blank" rel="noopener" title="{% trans '查看原图' %}">
|
|
||||||
<img src="{{ item.cover|thumb:'normal' }}" class="entity-detail__img" alt="{{ item.title }}">
|
|
||||||
</a>
|
|
||||||
|
|
||||||
<div class="entity-detail__info">
|
|
||||||
{% if item.is_deleted %}
|
|
||||||
[DELETED]
|
|
||||||
{% endif %}
|
|
||||||
{% if item.merged_to_item %}
|
|
||||||
[MERGED <a href="{{ item.merged_to_item.url }}">{{ item.merged_to_item.title }}</a>]
|
|
||||||
{% endif %}
|
|
||||||
{% block title %}
|
|
||||||
<h5 class="entity-detail__title">
|
|
||||||
{{ item.title }}
|
|
||||||
|
|
||||||
{% for res in item.external_resources.all %}
|
|
||||||
<a href="{{ res.url }}">
|
|
||||||
<span class="source-label source-label__{{ res.site_name }}">{{ res.site_name.label }}</span>
|
|
||||||
</a>
|
|
||||||
{% endfor %}
|
|
||||||
</h5>
|
|
||||||
{% endblock %}
|
|
||||||
|
|
||||||
{% block details %}
|
|
||||||
<div class="entity-detail__fields">
|
|
||||||
<div class="entity-detail__rating">
|
|
||||||
{% if item.rating %}
|
|
||||||
<span class="entity-detail__rating-star rating-star" data-rating-score="{{ item.rating | floatformat:0 }}"></span>
|
|
||||||
<span class="entity-detail__rating-score"> {{ item.rating | floatformat:1 }} </span>
|
|
||||||
<small>({{ item.rating_count }}人评分)</small>
|
|
||||||
{% else %}
|
|
||||||
<span> {% trans '评分:评分人数不足' %}</span>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
<div>此类数据尚未支持</div>
|
|
||||||
<div>uuid: {{item.uuid}}</div>
|
|
||||||
<div>class: {{item.class_name}}</div>
|
|
||||||
<div>category: {{item.category}}</div>
|
|
||||||
</div>
|
|
||||||
{% endblock %}
|
|
||||||
|
|
||||||
<div class="tag-collection">
|
|
||||||
{% for tag in item.tags %}
|
|
||||||
<span class="tag-collection__tag">
|
|
||||||
<a href="{% url 'catalog:search' %}?tag={{ tag }}">{{ tag }}</a>
|
|
||||||
</span>
|
|
||||||
{% endfor %}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="dividing-line"></div>
|
|
||||||
{% if item.brief %}
|
|
||||||
<div class="entity-desc" id="description">
|
|
||||||
<h5 class="entity-desc__title">{% trans '简介' %}</h5>
|
|
||||||
|
|
||||||
<p class="entity-desc__content">{{ item.brief | linebreaksbr }}</p>
|
|
||||||
<div class="entity-desc__unfold-button entity-desc__unfold-button--hidden">
|
|
||||||
<a href="javascript:void(0);">展开全部</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
{% block content %}
|
|
||||||
{% if item.contents %}
|
|
||||||
<div class="entity-desc" id="contents">
|
|
||||||
<h5 class="entity-desc__title">{% trans '目录' %}</h5>
|
|
||||||
<p class="entity-desc__content">{{ item.contents | linebreaksbr }}</p>
|
|
||||||
<div class="entity-desc__unfold-button entity-desc__unfold-button--hidden">
|
|
||||||
<a href="javascript:void(0);">展开全部</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
{% if item.track_list %}
|
|
||||||
<div class="entity-desc" id="description">
|
|
||||||
<h5 class="entity-desc__title">{% trans '曲目' %}</h5>
|
|
||||||
<p class="entity-desc__content">{{ item.track_list | linebreaksbr }}</p>
|
|
||||||
<div class="entity-desc__unfold-button entity-desc__unfold-button--hidden">
|
|
||||||
<a href="javascript:void(0);">展开全部</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
{% endblock %}
|
|
||||||
|
|
||||||
<div class="entity-marks">
|
|
||||||
<h5 class="entity-marks__title">{% trans '标记' %}</h5>
|
|
||||||
{% if mark_list %}
|
|
||||||
<a href="{% url 'catalog:mark_list' item.url_path item.uuid %}" class="entity-marks__more-link">{% trans '全部标记' %}</a>
|
|
||||||
<a href="{% url 'catalog:mark_list' item.url_path item.uuid 'following' %}" class="entity-marks__more-link">关注的人的标记</a>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
<ul class="entity-marks__mark-list">
|
|
||||||
{% for others_mark in mark_list %}
|
|
||||||
<li class="entity-marks__mark">
|
|
||||||
<a href="{% url 'journal:user_profile' others_mark.owner.mastodon_username %}" class="entity-marks__owner-link">{{ others_mark.owner.username }}</a>
|
|
||||||
|
|
||||||
<span>{{ others_mark.action_label }}</span>
|
|
||||||
|
|
||||||
{% if others_mark.rating %}
|
|
||||||
<span class="entity-marks__rating-star rating-star" data-rating-score="{{ others_mark.rating }}"></span>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
{% if others_mark.visibility > 0 %}
|
|
||||||
<i class="fa-solid fa-lock"></i>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
{% if others_mark.shelfmember.metadata.shared_link %}
|
|
||||||
<a href="{{ others_mark.shelfmember.metadata.shared_link }}" target="_blank" rel="noopener"><span class="entity-marks__mark-time">{{ others_mark.created_time | date }}</span></a>
|
|
||||||
{% else %}
|
|
||||||
<span class="entity-marks__mark-time">{{ others_mark.created_time | date }}</span>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
{% if others_mark.text %}
|
|
||||||
<p class="entity-marks__mark-content">{{ others_mark.comment_html|safe }}
|
|
||||||
<span class="action-bar inline">
|
|
||||||
<span>
|
|
||||||
{% liked_piece others_mark.shelfmember as liked %}
|
|
||||||
{% include 'like_stats.html' with liked=liked piece=others_mark.shelfmember %}
|
|
||||||
</span>
|
|
||||||
</span>
|
|
||||||
</p>
|
|
||||||
{% endif %}
|
|
||||||
</li>
|
|
||||||
{% empty %}
|
|
||||||
|
|
||||||
<div> {% trans '暂无标记' %} </div>
|
|
||||||
|
|
||||||
{% endfor %}
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
<div class="entity-reviews">
|
|
||||||
<h5 class="entity-reviews__title">{% trans '评论' %}</h5>
|
|
||||||
{% if review_list %}
|
|
||||||
<a href="{% url 'catalog:review_list' item.url_path item.uuid %}" class="entity-reviews__more-link">{% trans '全部评论' %}</a>
|
|
||||||
{% endif %}
|
|
||||||
{% if review_list %}
|
|
||||||
<ul class="entity-reviews__review-list">
|
|
||||||
{% for others_review in review_list %}
|
|
||||||
<li class="entity-reviews__review">
|
|
||||||
<a href="{% url 'journal:user_profile' others_review.owner.mastodon_username %}" class="entity-reviews__owner-link">{{ others_review.owner.username }}</a>
|
|
||||||
{% if others_review.visibility > 0 %}
|
|
||||||
<i class="fa-solid fa-lock"></i>
|
|
||||||
{% endif %}
|
|
||||||
<span class="entity-reviews__review-time">{{ others_review.created_time | date }}</span>
|
|
||||||
<span class="entity-reviews__review-title"> <a href="{% url 'journal:review_retrieve' others_review.uuid %}">{{ others_review.title }}</a></span>
|
|
||||||
<span class="action-bar inline">
|
|
||||||
<span>
|
|
||||||
{% liked_piece others_review as liked %}
|
|
||||||
{% include 'like_stats.html' with liked=liked piece=others_review %}
|
|
||||||
</span>
|
|
||||||
</span>
|
|
||||||
<span>{{ others_review.get_plain_content | truncate:100 }}</span>
|
|
||||||
</li>
|
|
||||||
{% endfor %}
|
|
||||||
</ul>
|
|
||||||
{% else %}
|
|
||||||
<div>{% trans '暂无评论' %}</div>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="grid__aside" id="aside">
|
|
||||||
{% block sidebar_review %}
|
|
||||||
{% if user.is_authenticated %}
|
|
||||||
<div class="aside-section-wrapper">
|
|
||||||
{% if mark.shelf_type %}
|
|
||||||
<div class="mark-panel">
|
|
||||||
<span class="mark-panel__status">{% trans '我' %}{% trans mark.shelf_label %}</span>
|
|
||||||
{% if mark.rating %}
|
|
||||||
<span class="mark-panel__rating-star rating-star" data-rating-score="{{ mark.rating | floatformat:'0' }}"></span>
|
|
||||||
{% endif %}
|
|
||||||
{% if mark.visibility > 0 %}
|
|
||||||
<i class="fa-solid fa-lock"></i>
|
|
||||||
{% endif %}
|
|
||||||
<span class="mark-panel__actions">
|
|
||||||
<a href="#" hx-get="{% url 'journal:mark' item.uuid %}" class="edit" hx-target="body" hx-swap="beforeend">{% trans '修改' %}</a>
|
|
||||||
<form id="mark_delete" action="{% url 'journal:mark' item.uuid %}" method="post">
|
|
||||||
{% csrf_token %}
|
|
||||||
<input type="hidden" name="delete" value="1">
|
|
||||||
<a href="javascript:$('#mark_delete').submit()" class="delete">{% trans '删除' %}</a>
|
|
||||||
</form>
|
|
||||||
</span>
|
|
||||||
<div class="mark-panel__clear"></div>
|
|
||||||
|
|
||||||
<div class="mark-panel__time">
|
|
||||||
<!-- <div>
|
|
||||||
{% for log in mark.logs %}
|
|
||||||
{{ log.timestamp|date }} {{ log.action_label }}<br>
|
|
||||||
{% endfor %}
|
|
||||||
</div> -->
|
|
||||||
{% if mark.metadata.shared_link %}
|
|
||||||
<a href="{{ mark.metadata.shared_link }}">{{ mark.created_time|date }}</a>
|
|
||||||
{% else %}
|
|
||||||
{{ mark.created_time|date }}
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{% if mark.text %}
|
|
||||||
<p class="mark-panel__text">{{ mark.comment_html|safe }}</p>
|
|
||||||
{% endif %}
|
|
||||||
<div class="tag-collection">
|
|
||||||
|
|
||||||
{% for tag in mark.tags %}
|
|
||||||
<span class="tag-collection__tag"><a href="{% url 'journal:user_tag_member_list' user.mastodon_username tag %}">{{ tag }}</a></span>
|
|
||||||
{% endfor %}
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% else %}
|
|
||||||
<div class="action-panel" id="addMarkPanel">
|
|
||||||
<div class="action-panel__label">{% trans '标记' %}{% trans item.demonstrative %}</div>
|
|
||||||
<div class="action-panel__button-group">
|
|
||||||
{% for k, v in shelf_types %}
|
|
||||||
{% if v %}
|
|
||||||
<button class="action-panel__button" data-status="{{ k }}" hx-get="{% url 'journal:mark' item.uuid %}?shelf_type={{ k }}" class="edit" hx-target="body" hx-swap="beforeend">{% trans v %}</button>
|
|
||||||
{% endif %}
|
|
||||||
{% endfor %}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="aside-section-wrapper">
|
|
||||||
<div class="review-panel action-panel">
|
|
||||||
{% if review %}
|
|
||||||
<span class="review-panel__label">{% trans '我的评论' %}</span>
|
|
||||||
{% if review.visibility > 0 %}
|
|
||||||
<i class="fa-solid fa-lock"></i>
|
|
||||||
{% endif %}
|
|
||||||
<span class="review-panel__actions">
|
|
||||||
<a href="{% url 'journal:review_edit' item.uuid review.uuid %}">{% trans '编辑' %}</a>
|
|
||||||
<a href="{% url 'journal:review_delete' review.uuid %}?return_url={{ item.url }}">{% trans '删除' %}</a>
|
|
||||||
</span>
|
|
||||||
|
|
||||||
<div class="review-panel__time">{{ review.edited_time }}</div>
|
|
||||||
|
|
||||||
<a href="{% url 'journal:review_retrieve' review.uuid %}" class="review-panel__review-title">
|
|
||||||
{{ review.title }}
|
|
||||||
</a>
|
|
||||||
{% else %}
|
|
||||||
<div class="action-panel__button-group action-panel__button-group--center">
|
|
||||||
<a href="{% url 'journal:review_create' item.uuid %}">
|
|
||||||
<button class="action-panel__button">{% trans '撰写评论' %}</button>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% else %}
|
|
||||||
<div class="aside-section-wrapper">
|
|
||||||
<div class="mark-panel">
|
|
||||||
<span>{% trans '登录后可管理标记和评论' %}</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endblock %}
|
{% if item.year %}({{ item.year }}){% endif %}
|
||||||
|
</small>
|
||||||
{% block sidebar %}
|
</h1>
|
||||||
{% endblock %}
|
<span class="site-list">
|
||||||
|
{% for res in item.external_resources.all %}
|
||||||
{% block sidebar_collection %}
|
<a href="{{ res.url }}" class="{{ res.site_name }}">{{ res.site_name.label }}</a>
|
||||||
<div class="aside-section-wrapper">
|
{% endfor %}
|
||||||
<div class="action-panel">
|
</span>
|
||||||
<div class="action-panel__label">{% trans '相关收藏单' %}</div>
|
</div>
|
||||||
<div >
|
<div id="item-cover" class="left">
|
||||||
{% if collection_list %}
|
<img src="{{ item.cover|thumb:'normal' }}" alt="{{ item.title }}">
|
||||||
{% for c in collection_list %}
|
</div>
|
||||||
<p>
|
{% if request.user.is_authenticated and not mark.shelf_type %}
|
||||||
<a href="{{ c.url }}">{{ c.title }}</a>
|
<div id="item-primary-action" class="right mark">
|
||||||
</p>
|
<div class="item-action">
|
||||||
{% endfor %}
|
{% for k, v in shelf_types %}
|
||||||
{% endif %}
|
{% if v %}
|
||||||
{% if request.user.is_authenticated %}
|
<button class="primary"
|
||||||
<div class="action-panel__button-group action-panel__button-group--center">
|
data-status="{{ k }}"
|
||||||
<button class="action-panel__button add-to-list" hx-get="{% url 'journal:add_to_collection' item.uuid %}" hx-target="body" hx-swap="beforeend">{% trans '添加到收藏单' %}</button>
|
hx-get="{% url 'journal:mark' item.uuid %}?shelf_type={{ k }}&new=1"
|
||||||
</div>
|
hx-target="body"
|
||||||
{% endif %}
|
hx-swap="beforeend">{% trans v %}</button>
|
||||||
</div>
|
{% endif %}
|
||||||
</div>
|
{% endfor %}
|
||||||
</div>
|
|
||||||
{% endblock %}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
{% endif %}
|
||||||
</div>
|
{% if request.user.is_authenticated and mark.shelf_type %}
|
||||||
|
<div id="item-primary-mark" class="right mark">
|
||||||
|
<div class="item-action">
|
||||||
|
<button class="outline edit"
|
||||||
|
hx-get="{% url 'journal:mark' item.uuid %}?new=1"
|
||||||
|
hx-target="body"
|
||||||
|
hx-swap="beforeend">
|
||||||
|
{{ mark.created_time | date }} {% trans mark.action_label %}
|
||||||
|
{% if mark.rating %}
|
||||||
|
<br>
|
||||||
|
{{ mark.rating | rating_star }}
|
||||||
|
<!-- <span style="white-space: nowrap;">
|
||||||
|
<i class="fa-solid fa-star"></i><i class="fa-solid fa-star"></i><i class="fa-solid fa-star"></i><i class="fa-solid fa-star-half-stroke"></i><i class="fa-regular fa-star"></i>
|
||||||
|
</span> -->
|
||||||
|
{% endif %}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="small-only" style="margin-top:2vh;">
|
||||||
|
<a href="#item-sidebar">标签 · 短评 · 评论 · 收藏</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
<div id="item-sidebar" class="right">
|
||||||
|
{% if request.user.is_authenticated %}
|
||||||
|
<section>
|
||||||
|
<h5>
|
||||||
|
我的标签
|
||||||
|
<small>
|
||||||
|
<a href="#"
|
||||||
|
hx-get="{% url 'journal:mark' item.uuid %}?new=1"
|
||||||
|
class="edit"
|
||||||
|
hx-target="body"
|
||||||
|
hx-swap="beforeend">
|
||||||
|
{% if mark.tags %}
|
||||||
|
<i class="fa-solid fa-pen-to-square"></i>
|
||||||
|
{% else %}
|
||||||
|
<i class="fa-regular fa-square-plus"></i>
|
||||||
|
{% endif %}
|
||||||
|
</a>
|
||||||
|
</small>
|
||||||
|
</h5>
|
||||||
|
<div class="tag-list">
|
||||||
|
{% for tag in mark.tags %}
|
||||||
|
<span>
|
||||||
|
<a href="{% url 'journal:user_tag_member_list' request.user.mastodon_username tag %}">{{ tag }}</a>
|
||||||
|
</span>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
<section>
|
||||||
|
<h5>
|
||||||
|
我的短评
|
||||||
|
<small>
|
||||||
|
<a href="#"
|
||||||
|
hx-get="{% url 'journal:mark' item.uuid %}?new=1"
|
||||||
|
class="edit"
|
||||||
|
hx-target="body"
|
||||||
|
hx-swap="beforeend">
|
||||||
|
{% if mark.text %}
|
||||||
|
<i class="fa-solid fa-pen-to-square"></i>
|
||||||
|
{% else %}
|
||||||
|
<i class="fa-regular fa-square-plus"></i>
|
||||||
|
{% endif %}
|
||||||
|
</a>
|
||||||
|
</small>
|
||||||
|
</h5>
|
||||||
|
{% if mark.comment %}
|
||||||
|
<span class="action">
|
||||||
|
<span>
|
||||||
|
{% liked_piece mark.comment as liked %}
|
||||||
|
{% include 'like_stats.html' with liked=liked piece=mark.comment %}
|
||||||
|
</span>
|
||||||
|
<span>
|
||||||
|
<a target="_blank"
|
||||||
|
rel="noopener"
|
||||||
|
{% if mark.comment.metadata.shared_link %} href="{{ mark.comment.metadata.shared_link }}" title="打开联邦网络分享链接" {% else %} class="disabled" {% endif %}><i class="fa-solid {% if mark.comment.visibility > 0 %} fa-lock {% else %} fa-globe {% endif %}"></i></a>
|
||||||
|
</span>
|
||||||
|
<span class="timestamp">{{ mark.comment.created_time|date }}</span>
|
||||||
|
</span>
|
||||||
|
<p>{{ mark.comment.html|safe }}</p>
|
||||||
|
{% else %}
|
||||||
|
<!-- <span class="empty">暂无</span> -->
|
||||||
|
{% endif %}
|
||||||
|
</section>
|
||||||
|
<section>
|
||||||
|
<h5>
|
||||||
|
我的评论
|
||||||
|
<small>
|
||||||
|
{% if review %}
|
||||||
|
<a href="{% url 'journal:review_edit' item.uuid review.uuid %}">
|
||||||
|
<i class="fa-solid fa-pen-to-square"></i>
|
||||||
|
</a>
|
||||||
|
{% else %}
|
||||||
|
<a href="{% url 'journal:review_create' item.uuid %}">
|
||||||
|
<i class="fa-regular fa-square-plus"></i>
|
||||||
|
</a>
|
||||||
|
{% endif %}
|
||||||
|
</small>
|
||||||
|
</h5>
|
||||||
|
{% if review %}
|
||||||
|
<span class="action">
|
||||||
|
<span>
|
||||||
|
{% liked_piece mark.review as liked %}
|
||||||
|
{% include 'like_stats.html' with liked=liked piece=mark.review %}
|
||||||
|
</span>
|
||||||
|
<span>
|
||||||
|
<a target="_blank"
|
||||||
|
rel="noopener"
|
||||||
|
{% if mark.review.metadata.shared_link %} href="{{ mark.review.metadata.shared_link }}" title="打开联邦网络分享链接" {% else %} class="disabled" {% endif %}><i class="fa-solid {% if mark.review.visibility > 0 %} fa-lock {% else %} fa-globe {% endif %}"></i></a>
|
||||||
|
</span>
|
||||||
|
<span class="timestamp">{{ mark.review.created_time|date }}</span>
|
||||||
|
</span>
|
||||||
|
<p>
|
||||||
|
<a href="{% url 'journal:review_retrieve' review.uuid %}">{{ review.title }}</a>
|
||||||
|
</p>
|
||||||
|
{% else %}
|
||||||
|
<!-- <span class="empty">暂无</span> -->
|
||||||
|
{% endif %}
|
||||||
|
</section>
|
||||||
|
<section>
|
||||||
|
<h5>
|
||||||
|
我的收藏单
|
||||||
|
<small>
|
||||||
|
<a href="#"
|
||||||
|
hx-get="{% url 'journal:add_to_collection' item.uuid %}?new=1"
|
||||||
|
class="edit"
|
||||||
|
hx-target="body"
|
||||||
|
hx-swap="beforeend">
|
||||||
|
<i class="fa-regular fa-square-plus"></i>
|
||||||
|
</a>
|
||||||
|
</small>
|
||||||
|
</h5>
|
||||||
|
<div>
|
||||||
|
{% for c in my_collections %}
|
||||||
|
<p>
|
||||||
|
<a href="{{ c.url }}">{{ c.title }}</a>
|
||||||
|
{% if c.visibility > 0 %}<i class="fa-solid fa-lock"></i>{% endif %}
|
||||||
|
</p>
|
||||||
|
{% empty %}
|
||||||
|
<!-- <span class="empty">暂无</span> -->
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
<!--
|
||||||
|
<section>
|
||||||
|
<h5>标记历史</h5>
|
||||||
|
<div>
|
||||||
|
{% for log in mark.logs %}{{ log.timestamp|date }} {{ log.action_label }}<br>{% endfor %}
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
-->
|
||||||
|
{% else %}
|
||||||
|
<section>
|
||||||
|
<p class="empty">
|
||||||
|
<span><a href="{% url 'users:login' %}">登录</a>后可管理标记收藏</span>
|
||||||
|
</p>
|
||||||
|
</section>
|
||||||
|
{% endif %}
|
||||||
|
{% block sidebar %}{% endblock %}
|
||||||
|
{% if collection_list %}
|
||||||
|
<section>
|
||||||
|
<h5>相关收藏单</h5>
|
||||||
|
<div>
|
||||||
|
{% for c in collection_list %}
|
||||||
|
<p>
|
||||||
|
<a href="{{ c.url }}">{{ c.title }}</a>
|
||||||
|
{% if c.visibility > 0 %}<i class="fa-solid fa-lock"></i>{% endif %}
|
||||||
|
</p>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
<div id="item-metadata" class="left">
|
||||||
|
{% block details %}
|
||||||
|
<div>此类数据尚未支持</div>
|
||||||
|
<div>uuid: {{ item.uuid }}</div>
|
||||||
|
<div>class: {{ item.class_name }}</div>
|
||||||
|
<div>category: {{ item.category }}</div>
|
||||||
|
{% endblock %}
|
||||||
|
{% if request.user.is_authenticated %}
|
||||||
|
<div class="item-edit">
|
||||||
|
<span class="action inline">
|
||||||
|
<a href="{% url 'catalog:edit' item.url_path item.uuid %}"
|
||||||
|
title="{% trans '编辑' %}{{ item.demonstrative }}"><i class="fa-solid fa-pen-to-square"></i></a>
|
||||||
|
</span>
|
||||||
|
{% if item.last_editor and item.last_editor.preference.show_last_edit %}
|
||||||
|
<span>
|
||||||
|
{% trans '最近编辑:' %}
|
||||||
|
<a href="{% url 'journal:user_profile' item.last_editor.mastodon_username %}">{{ item.last_editor | default:"" }}</a>
|
||||||
|
</span>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
<div class="rating{% if not item.rating %} unavailable{% endif %}">
|
||||||
|
<div class="display">
|
||||||
|
<div>
|
||||||
|
<hgroup>
|
||||||
|
<h3>
|
||||||
|
{{ item.rating | floatformat:1 }} <small>/ 10</small>
|
||||||
|
</h3>
|
||||||
|
<p>{{ item.rating_count }}人评分</p>
|
||||||
|
</hgroup>
|
||||||
|
</div>
|
||||||
|
<div data-placement="top">
|
||||||
|
<ul class="chart">
|
||||||
|
<li data-tooltip="{{ item.rating_dist.0 }}%" data-placement="left">
|
||||||
|
<span style="height:{{ item.rating_dist.0 }}%"></span>
|
||||||
|
</li>
|
||||||
|
<li data-tooltip="{{ item.rating_dist.1 }}%" data-placement="left">
|
||||||
|
<span style="height:{{ item.rating_dist.1 }}%"></span>
|
||||||
|
</li>
|
||||||
|
<li data-tooltip="{{ item.rating_dist.2 }}%" data-placement="left">
|
||||||
|
<span style="height:{{ item.rating_dist.2 }}%"></span>
|
||||||
|
</li>
|
||||||
|
<li data-tooltip="{{ item.rating_dist.3 }}%" data-placement="left">
|
||||||
|
<span style="height:{{ item.rating_dist.3 }}%"></span>
|
||||||
|
</li>
|
||||||
|
<li data-tooltip="{{ item.rating_dist.4 }}%" data-placement="left">
|
||||||
|
<span style="height:{{ item.rating_dist.4 }}%"></span>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="undisplay">
|
||||||
|
<span>评分人数不足</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="tag-list">
|
||||||
|
{% for tag in item.tags %}
|
||||||
|
<span>
|
||||||
|
<a href="{% url 'catalog:search' %}?tag={{ tag }}">{{ tag }}</a>
|
||||||
|
</span>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
{% block left_sidebar %}{% endblock %}
|
||||||
|
</div>
|
||||||
|
<div id="item-title-more" class="middle">
|
||||||
|
<hgroup>
|
||||||
|
{% if item.subtitle %}<p>{{ item.subtitle }}</p>{% endif %}
|
||||||
|
{% if item.orig_title %}
|
||||||
|
<p>
|
||||||
|
{{ item.orig_title }}
|
||||||
|
<small>
|
||||||
|
{% if item.season_number %}Season {{ item.season_number }}{% endif %}
|
||||||
|
</small>
|
||||||
|
</p>
|
||||||
|
{% endif %}
|
||||||
|
{% if item.author or item.translator %}
|
||||||
|
<p>
|
||||||
|
<i>
|
||||||
|
{% include '_people.html' with people=item.author _role='作者' max=2 %}
|
||||||
|
</i>
|
||||||
|
|
||||||
|
<i>
|
||||||
|
{% include '_people.html' with people=item.translator role='译者' max=2 %}
|
||||||
|
</i>
|
||||||
|
</p>
|
||||||
|
{% endif %}
|
||||||
|
</hgroup>
|
||||||
|
</div>
|
||||||
|
<div id="item-detail" class="middle">
|
||||||
|
<section>
|
||||||
|
<h5>简介</h5>
|
||||||
|
{% if item.brief %}
|
||||||
|
<p class="tldr" _="on click toggle .tldr on me">{{ item.brief | linebreaksbr }}</p>
|
||||||
|
{% else %}
|
||||||
|
<p class="empty">暂缺</p>
|
||||||
|
{% endif %}
|
||||||
|
</section>
|
||||||
|
{% block content %}{% endblock %}
|
||||||
|
<section>
|
||||||
|
<h5>
|
||||||
|
短评
|
||||||
|
{% if request.user.is_authenticated %}
|
||||||
|
<small>
|
||||||
|
| <a href="{% url 'catalog:mark_list' item.url_path item.uuid %}"
|
||||||
|
class="entity-marks__more-link">{% trans '全部标记' %}</a>
|
||||||
|
| <a href="{% url 'catalog:mark_list' item.url_path item.uuid 'following' %}"
|
||||||
|
class="entity-marks__more-link">关注的人的标记</a>
|
||||||
|
</small>
|
||||||
|
{% endif %}
|
||||||
|
</h5>
|
||||||
|
{% if request.user.is_authenticated %}
|
||||||
|
<div>
|
||||||
|
<div hx-get="{% url 'catalog:comments' item.url_path item.uuid %}"
|
||||||
|
hx-trigger="intersect once"
|
||||||
|
hx-swap="outerHTML">
|
||||||
|
<i class="fa-solid fa-compact-disc fa-spin loading"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% else %}
|
||||||
|
<p class="empty">登录后可见</p>
|
||||||
|
{% endif %}
|
||||||
|
</section>
|
||||||
|
<section class="entity-reviews">
|
||||||
|
<h5>
|
||||||
|
{% trans '评论' %}
|
||||||
|
{% comment %}
|
||||||
|
{% if request.user.is_authenticated %}
|
||||||
|
<small>
|
||||||
|
| <a href="{% url 'catalog:review_list' item.url_path item.uuid %}" class="entity-marks__more-link">{% trans '全部评论' %}</a>
|
||||||
|
</small>
|
||||||
|
{% endif %}
|
||||||
|
{% endcomment %}
|
||||||
|
</h5>
|
||||||
|
{% if request.user.is_authenticated %}
|
||||||
|
<div>
|
||||||
|
<div hx-get="{% url 'catalog:reviews' item.url_path item.uuid %}"
|
||||||
|
hx-trigger="intersect once"
|
||||||
|
hx-swap="outerHTML">
|
||||||
|
<i class="fa-solid fa-compact-disc fa-spin loading"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% else %}
|
||||||
|
<p class="empty">登录后可见</p>
|
||||||
|
{% endif %}
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
<div id="item-more" class="middle">
|
||||||
|
<!-- test more content -->
|
||||||
|
</div>
|
||||||
|
<div style="clear: both;display: table;"></div>
|
||||||
|
</main>
|
||||||
{% include "partial/_footer.html" %}
|
{% include "partial/_footer.html" %}
|
||||||
</div>
|
</body>
|
||||||
</body>
|
|
||||||
</html>
|
</html>
|
||||||
|
|
44
catalog/templates/item_comments.html
Normal file
44
catalog/templates/item_comments.html
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
{% load static %}
|
||||||
|
{% load i18n %}
|
||||||
|
{% load l10n %}
|
||||||
|
{% load admin_url %}
|
||||||
|
{% load mastodon %}
|
||||||
|
{% load oauth_token %}
|
||||||
|
{% load truncate %}
|
||||||
|
{% load duration %}
|
||||||
|
{% load user_actions %}
|
||||||
|
{% for comment in comments %}
|
||||||
|
{% if forloop.counter <= 10 %}
|
||||||
|
<section>
|
||||||
|
<span class="action">
|
||||||
|
<span>
|
||||||
|
{% liked_piece comment as liked %}
|
||||||
|
{% include 'like_stats.html' with liked=liked piece=comment %}
|
||||||
|
</span>
|
||||||
|
<span>
|
||||||
|
<a target="_blank"
|
||||||
|
rel="noopener"
|
||||||
|
{% if comment.metadata.shared_link %} href="{{ comment.metadata.shared_link }}" title="打开联邦网络分享链接" {% else %} class="disabled" {% endif %}><i class="fa-solid {% if comment.visibility > 0 %} fa-lock {% else %} fa-globe {% endif %}"></i></a>
|
||||||
|
</span>
|
||||||
|
<span class="timestamp">{{ comment.created_time|date }}</span>
|
||||||
|
</span>
|
||||||
|
<span>
|
||||||
|
{% if comment.rating_grade %}{{ comment.rating_grade|rating_star }}{% endif %}
|
||||||
|
<a href="{% url 'journal:user_profile' comment.owner.mastodon_username %}"
|
||||||
|
class="nickname"
|
||||||
|
title="@{{ comment.owner.mastodon_username }}">{{ comment.owner.display_name }}</a>
|
||||||
|
{{ comment.mark.action_label }}
|
||||||
|
{% if comment.focus_item %}<a href="{{ comment.focus_item.url }}">{{ comment.focus_item.title }}</a>{% endif %}
|
||||||
|
</span>
|
||||||
|
<div>{{ comment.html|safe }}</div>
|
||||||
|
</section>
|
||||||
|
{% else %}
|
||||||
|
<a hx-get="{% url 'catalog:comments' comment.item.url_path comment.item.uuid %}?last={{ comment.created_time|date:'Y-m-d H:i:s.uO'|urlencode }}"
|
||||||
|
hx-trigger="click"
|
||||||
|
hx-swap="outerHTML">
|
||||||
|
<button class="outline">显示更多</button>
|
||||||
|
</a>
|
||||||
|
{% endif %}
|
||||||
|
{% empty %}
|
||||||
|
<div class="empty">{% trans '暂无' %}</div>
|
||||||
|
{% endfor %}
|
|
@ -7,108 +7,78 @@
|
||||||
{% load highlight %}
|
{% load highlight %}
|
||||||
{% load thumb %}
|
{% load thumb %}
|
||||||
{% load user_actions %}
|
{% load user_actions %}
|
||||||
|
{% load duration %}
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en" class="classic-page">
|
||||||
|
<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>{{ site_name }} - {{ item.title }}{% trans '的标记' %}</title>
|
||||||
<title>{{ site_name }} - {{ item.title }}{% trans '的标记' %}</title>
|
{% include "common_libs.html" with jquery=0 v2=1 %}
|
||||||
{% include "common_libs.html" with jquery=0 %}
|
</head>
|
||||||
</head>
|
<body>
|
||||||
|
{% include '_header.html' %}
|
||||||
<body>
|
<main>
|
||||||
<div id="page-wrapper">
|
<div class="grid__main">
|
||||||
<div id="content-wrapper">
|
<h5>
|
||||||
{% include "partial/_navbar.html" %}
|
<a href="{% url 'catalog:retrieve' item.url_path item.uuid %}">{{ item.title }}</a>{% trans ' 的标记' %}
|
||||||
|
</h5>
|
||||||
<section id="content">
|
{% for member in marks %}
|
||||||
<div class="grid">
|
{% with member.mark as mark %}
|
||||||
<div class="grid__main" id="main">
|
<section>
|
||||||
<div class="main-section-wrapper">
|
<div class="action">
|
||||||
<div class="entity-marks">
|
{% if mark.comment %}
|
||||||
<h5 class="entity-marks__title entity-marks__title--stand-alone">
|
<span>
|
||||||
<a href="{% url 'catalog:retrieve' item.url_path item.uuid %}">{{ item.title }}</a>{% trans ' 的标记' %}
|
{% liked_piece mark.comment as liked %}
|
||||||
</h5>
|
{% include 'like_stats.html' with liked=liked piece=mark.comment %}
|
||||||
<ul class="entity-marks__mark-list">
|
</span>
|
||||||
{% for others_mark in marks %}
|
{% endif %}
|
||||||
<li class="entity-marks__mark">
|
<span>
|
||||||
<a href="{% url 'journal:user_profile' others_mark.owner.mastodon_username %}" class="entity-marks__owner-link">{{ others_mark.owner.username }}</a>
|
<a target="_blank"
|
||||||
|
rel="noopener"
|
||||||
<span>{{ others_mark.mark.action_label }}</span>
|
{% if mark.metadata.shared_link %} href="{{ mark.metadata.shared_link }}" title="打开联邦网络分享链接" {% else %} class="disabled" {% endif %}><i class="fa-solid {% if mark.visibility > 0 %} fa-lock {% else %} fa-globe {% endif %}"></i></a>
|
||||||
|
</span>
|
||||||
{% if others_mark.mark.rating %}
|
<span class="timestamp">{{ mark.created_time|date }}</span>
|
||||||
<span class="entity-marks__rating-star rating-star" data-rating-score="{{ others_mark.mark.rating }}"></span>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
{% if others_mark.mark.visibility > 0 %}
|
|
||||||
<i class="fa-solid fa-lock"></i>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
{% if others_mark.metadata.shared_link %}
|
|
||||||
<a href="{{ others_mark.metadata.shared_link }}" target="_blank" rel="noopener"><span class="entity-marks__mark-time">{{ others_mark.mark.created_time|date }}</span></a>
|
|
||||||
{% else %}
|
|
||||||
<span class="entity-marks__mark-time">{{ others_mark.mark.created_time|date }}</span>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
{% if others_mark.mark.text %}
|
|
||||||
<p class="entity-marks__mark-content">{{ others_mark.mark.comment_html|safe }}
|
|
||||||
<span class="action-bar inline">
|
|
||||||
<span>
|
|
||||||
{% liked_piece others_mark as liked %}
|
|
||||||
{% include 'like_stats.html' with liked=liked piece=others_mark %}
|
|
||||||
</span>
|
|
||||||
</span>
|
|
||||||
</p>
|
|
||||||
{% endif %}
|
|
||||||
</li>
|
|
||||||
{% empty %}
|
|
||||||
|
|
||||||
<div> {% trans '暂无标记' %} </div>
|
|
||||||
|
|
||||||
{% endfor %}
|
|
||||||
</ul>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="pagination">
|
<div>
|
||||||
|
<a href="{% url 'journal:user_profile' mark.owner.mastodon_username %}"
|
||||||
{% if marks.pagination.has_prev %}
|
title="@{{ mark.owner.mastodon_username }}">{{ mark.owner.display_name }}</a>
|
||||||
<a href="?page=1"
|
<span>{{ mark.action_label }}</span>
|
||||||
class="pagination__nav-link pagination__nav-link">«</a>
|
{% if mark.rating_grade %}{{ mark.rating_grade|rating_star }}{% endif %}
|
||||||
<a href="?page={{ marks.previous_page_number }}"
|
{% if mark.comment.focus_item %}
|
||||||
class="pagination__nav-link pagination__nav-link--right-margin pagination__nav-link">‹</a>
|
<a href="{{ mark.comment.focus_item.url }}">{{ mark.comment.focus_item.title }}</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% for page in marks.pagination.page_range %}
|
|
||||||
|
|
||||||
{% 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 %}
|
|
||||||
|
|
||||||
{% endfor %}
|
|
||||||
|
|
||||||
{% if marks.pagination.has_next %}
|
|
||||||
<a href="?page={{ marks.next_page_number }}"
|
|
||||||
class="pagination__nav-link pagination__nav-link--left-margin">›</a>
|
|
||||||
<a href="?page={{ marks.pagination.last_page }}"
|
|
||||||
class="pagination__nav-link">»</a>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<div>{{ mark.comment.html|safe }}</div>
|
||||||
</div>
|
</section>
|
||||||
|
{% endwith %}
|
||||||
<div class="grid__aside" id="aside">
|
{% empty %}
|
||||||
{% include "sidebar_item.html" %}
|
<div>{% trans '暂无标记' %}</div>
|
||||||
</div>
|
{% endfor %}
|
||||||
|
<div class="pagination">
|
||||||
|
{% if marks.pagination.has_prev %}
|
||||||
|
<a href="?page=1" class="pagination__nav-link pagination__nav-link">«</a>
|
||||||
|
<a href="?page={{ marks.previous_page_number }}"
|
||||||
|
class="pagination__nav-link pagination__nav-link--right-margin pagination__nav-link">‹</a>
|
||||||
|
{% endif %}
|
||||||
|
{% for page in marks.pagination.page_range %}
|
||||||
|
{% 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 %}
|
||||||
|
{% endfor %}
|
||||||
|
{% if marks.pagination.has_next %}
|
||||||
|
<a href="?page={{ marks.next_page_number }}"
|
||||||
|
class="pagination__nav-link pagination__nav-link--left-margin">›</a>
|
||||||
|
<a href="?page={{ marks.pagination.last_page }}"
|
||||||
|
class="pagination__nav-link">»</a>
|
||||||
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</div>
|
||||||
</div>
|
<div class="grid__aside" id="aside">{% include "sidebar_item.html" %}</div>
|
||||||
|
</main>
|
||||||
{% include "partial/_footer.html" %}
|
{% include "partial/_footer.html" %}
|
||||||
</div>
|
</body>
|
||||||
</body>
|
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -7,94 +7,77 @@
|
||||||
{% load highlight %}
|
{% load highlight %}
|
||||||
{% load thumb %}
|
{% load thumb %}
|
||||||
{% load user_actions %}
|
{% load user_actions %}
|
||||||
|
{% load duration %}
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en" class="classic-page">
|
||||||
|
<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>{{ site_name }} - {{ item.title }}{% trans '的评论' %}</title>
|
||||||
<title>{{ site_name }} - {{ item.title }}{% trans '的评论' %}</title>
|
{% include "common_libs.html" with jquery=0 v2=1 %}
|
||||||
{% include "common_libs.html" with jquery=0 %}
|
</head>
|
||||||
</head>
|
<body>
|
||||||
|
{% include '_header.html' %}
|
||||||
<body>
|
<main>
|
||||||
<div id="page-wrapper">
|
<div class="grid__main">
|
||||||
<div id="content-wrapper">
|
<h5>
|
||||||
{% include "partial/_navbar.html" %}
|
<a href="{% url 'catalog:retrieve' item.url_path item.uuid %}">{{ item.title }}</a>{% trans ' 的评论' %}
|
||||||
<section id="content">
|
</h5>
|
||||||
<div class="grid">
|
{% for review in reviews %}
|
||||||
<div class="grid__main" id="main">
|
<section>
|
||||||
<div class="main-section-wrapper">
|
<div class="action">
|
||||||
<div class="entity-reviews">
|
<span>
|
||||||
<h5 class="entity-reviews__title entity-reviews__title--stand-alone">
|
<a target="_blank"
|
||||||
<a href="{{ item.url }}">{{ item.title }}</a>{% trans ' 的评论' %}
|
rel="noopener"
|
||||||
</h5>
|
{% if review.metadata.shared_link %} href="{{ review.metadata.shared_link }}" title="打开联邦网络分享链接" {% else %} class="disabled" {% endif %}><i class="fa-solid {% if review.visibility > 0 %} fa-lock {% else %} fa-globe {% endif %}"></i></a>
|
||||||
<ul class="entity-reviews__review-list">
|
</span>
|
||||||
|
<span>
|
||||||
{% for review in reviews %}
|
{% liked_piece review as liked %}
|
||||||
<li class="entity-reviews__review entity-reviews__review--wider">
|
{% include 'like_stats.html' with liked=liked piece=review %}
|
||||||
<a href="{% url 'journal:user_profile' review.owner.mastodon_username %}" class="entity-reviews__owner-link">{{ review.owner.username }}</a>
|
</span>
|
||||||
{% if review.visibility > 0 %}
|
<span class="timestamp">{{ review.created_time|date }}</span>
|
||||||
<i class="fa-solid fa-lock"></i>
|
|
||||||
{% endif %}
|
|
||||||
<span class="entity-reviews__review-time">{{ review.created_time | date }}</span>
|
|
||||||
<span class="entity-reviews__review-title"><a href="{% url 'journal:review_retrieve' review.uuid %}">{{ review.title }}</a></span>
|
|
||||||
<span class="action-bar inline">
|
|
||||||
<span>
|
|
||||||
{% liked_piece review as liked %}
|
|
||||||
{% include 'like_stats.html' with liked=liked piece=review %}
|
|
||||||
</span>
|
|
||||||
</span>
|
|
||||||
</li>
|
|
||||||
{% empty %}
|
|
||||||
<div>{% trans '暂无评论' %}</div>
|
|
||||||
{% endfor %}
|
|
||||||
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
<div class="pagination">
|
|
||||||
|
|
||||||
{% if reviews.pagination.has_prev %}
|
|
||||||
<a href="?page=1" class="pagination__nav-link pagination__nav-link">«</a>
|
|
||||||
<a href="?page={{ reviews.previous_page_number }}"
|
|
||||||
class="pagination__nav-link pagination__nav-link--right-margin pagination__nav-link">‹</a>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
{% for page in reviews.pagination.page_range %}
|
|
||||||
|
|
||||||
{% 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 %}
|
|
||||||
|
|
||||||
{% endfor %}
|
|
||||||
|
|
||||||
{% if reviews.pagination.has_next %}
|
|
||||||
<a href="?page={{ reviews.next_page_number }}"
|
|
||||||
class="pagination__nav-link pagination__nav-link--left-margin">›</a>
|
|
||||||
<a href="?page={{ reviews.pagination.last_page }}" class="pagination__nav-link">»</a>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<div>
|
||||||
|
{% if review.rating_grade %}{{ review.rating_grade|rating_star }}{% endif %}
|
||||||
<div class="grid__aside" id="aside">
|
<span>
|
||||||
{% include "sidebar_item.html" %}
|
<a href="{% url 'journal:review_retrieve' review.uuid %}">{{ review.title }}</a>
|
||||||
</div>
|
</span>
|
||||||
</section>
|
-
|
||||||
|
<span>
|
||||||
|
<a href="{% url 'journal:user_profile' review.owner.mastodon_username %}"
|
||||||
|
class="nickname"
|
||||||
|
title="@{{ review.owner.mastodon_username }}">{{ review.owner.display_name }}</a>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div>{{ review.plain_content | truncate:200 }}</div>
|
||||||
|
</section>
|
||||||
|
{% empty %}
|
||||||
|
<div>{% trans '暂无评论' %}</div>
|
||||||
|
{% endfor %}
|
||||||
|
<div class="pagination">
|
||||||
|
{% if reviews.pagination.has_prev %}
|
||||||
|
<a href="?page=1" class="pagination__nav-link pagination__nav-link">«</a>
|
||||||
|
<a href="?page={{ reviews.previous_page_number }}"
|
||||||
|
class="pagination__nav-link pagination__nav-link--right-margin pagination__nav-link">‹</a>
|
||||||
|
{% endif %}
|
||||||
|
{% for page in reviews.pagination.page_range %}
|
||||||
|
{% 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 %}
|
||||||
|
{% endfor %}
|
||||||
|
{% if reviews.pagination.has_next %}
|
||||||
|
<a href="?page={{ reviews.next_page_number }}"
|
||||||
|
class="pagination__nav-link pagination__nav-link--left-margin">›</a>
|
||||||
|
<a href="?page={{ reviews.pagination.last_page }}"
|
||||||
|
class="pagination__nav-link">»</a>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% include "partial/_footer.html" %}
|
<div class="grid__aside" id="aside">{% include "sidebar_item.html" %}</div>
|
||||||
</div>
|
</main>
|
||||||
|
{% include "partial/_footer.html" %}
|
||||||
|
|
||||||
|
|
||||||
<script>
|
|
||||||
|
|
||||||
</script>
|
|
||||||
</body>
|
</body>
|
||||||
|
</html>
|
||||||
|
|
||||||
</html>
|
|
||||||
|
|
49
catalog/templates/item_reviews.html
Normal file
49
catalog/templates/item_reviews.html
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
{% load static %}
|
||||||
|
{% load i18n %}
|
||||||
|
{% load l10n %}
|
||||||
|
{% load admin_url %}
|
||||||
|
{% load mastodon %}
|
||||||
|
{% load oauth_token %}
|
||||||
|
{% load truncate %}
|
||||||
|
{% load duration %}
|
||||||
|
{% load user_actions %}
|
||||||
|
{% for review in reviews %}
|
||||||
|
{% if forloop.counter <= 10 %}
|
||||||
|
<section>
|
||||||
|
<span class="action">
|
||||||
|
<span>
|
||||||
|
{% liked_piece review as liked %}
|
||||||
|
{% include 'like_stats.html' with liked=liked piece=review %}
|
||||||
|
</span>
|
||||||
|
<span>
|
||||||
|
<a target="_blank"
|
||||||
|
rel="noopener"
|
||||||
|
{% if review.metadata.shared_link %} href="{{ review.metadata.shared_link }}" title="打开联邦网络分享链接" {% else %} class="disabled" {% endif %}><i class="fa-solid {% if review.visibility > 0 %} fa-lock {% else %} fa-globe {% endif %}"></i></a>
|
||||||
|
</span>
|
||||||
|
<span class="timestamp">{{ review.created_time|date }}</span>
|
||||||
|
</span>
|
||||||
|
<span>
|
||||||
|
{% if review.rating_grade %}{{ review.rating_grade|rating_star }}{% endif %}
|
||||||
|
<a href="{% url 'journal:user_profile' review.owner.mastodon_username %}"
|
||||||
|
class="nickname"
|
||||||
|
title="@{{ review.owner.mastodon_username }}">{{ review.owner.display_name }}</a>
|
||||||
|
{{ review.mark.action_label | default:"" }}
|
||||||
|
</span>
|
||||||
|
<div>
|
||||||
|
<span>
|
||||||
|
<a href="{% url 'journal:review_retrieve' review.uuid %}">{{ review.title }}</a>
|
||||||
|
</span>
|
||||||
|
-
|
||||||
|
{{ review.plain_content | truncate:200 }}
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
{% else %}
|
||||||
|
<a hx-get="{% url 'catalog:reviews' review.item.url_path review.item.uuid %}?last={{ review.created_time|date:'Y-m-d H:i:s.uO'|urlencode }}"
|
||||||
|
hx-trigger="click"
|
||||||
|
hx-swap="outerHTML">
|
||||||
|
<button class="outline">显示更多</button>
|
||||||
|
</a>
|
||||||
|
{% endif %}
|
||||||
|
{% empty %}
|
||||||
|
<div class="empty">{% trans '暂无' %}</div>
|
||||||
|
{% endfor %}
|
|
@ -9,164 +9,160 @@
|
||||||
{% load truncate %}
|
{% load truncate %}
|
||||||
{% load strip_scheme %}
|
{% load strip_scheme %}
|
||||||
{% load thumb %}
|
{% load thumb %}
|
||||||
|
|
||||||
{% block title %}
|
|
||||||
<h5 class="entity-detail__title">
|
|
||||||
{% if item.season_number %}
|
|
||||||
{{ item.title }} {% trans '第' %}{{ item.season_number|apnumber }}{% trans '季' %} {{ item.orig_title }} Season {{ item.season_number }}
|
|
||||||
<span class="entity-detail__title entity-detail__title--secondary">
|
|
||||||
{% if item.year %}({{ item.year }}){% endif %}
|
|
||||||
</span>
|
|
||||||
{% else %}
|
|
||||||
{{ item.title }} {{ item.orig_title }}
|
|
||||||
<span class="entity-detail__title entity-detail__title--secondary">
|
|
||||||
{% if item.year %}({{ item.year }}){% endif %}
|
|
||||||
</span>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
{% for res in item.external_resources.all %}
|
|
||||||
<a href="{{ res.url }}">
|
|
||||||
<span class="source-label source-label__{{ res.site_name }}">{{ res.site_name.label }}</span>
|
|
||||||
</a>
|
|
||||||
{% endfor %}
|
|
||||||
</h5>
|
|
||||||
{% endblock %}
|
|
||||||
|
|
||||||
<!-- class specific details -->
|
<!-- class specific details -->
|
||||||
{% block details %}
|
{% block details %}
|
||||||
<div class="entity-detail__fields">
|
<div>
|
||||||
<div class="entity-detail__rating">
|
{% if item.imdb %}
|
||||||
{% if item.rating %}
|
{% trans 'IMDb:' %}<a href="https://www.imdb.com/title/{{ item.imdb }}/"
|
||||||
<span class="entity-detail__rating-star rating-star" data-rating-score="{{ item.rating | floatformat:'0' }}"></span>
|
target="_blank"
|
||||||
<span class="entity-detail__rating-score"> {{ item.rating|floatformat:1 }} </span>
|
rel="noopener">{{ item.imdb }}</a>
|
||||||
<small>({{ item.rating_count }}人评分)</small>
|
{% endif %}
|
||||||
{% else %}
|
</div>
|
||||||
<span> {% trans '评分:评分人数不足' %}</span>
|
<div>
|
||||||
{% endif %}
|
{% if item.director %}
|
||||||
</div>
|
{% trans '导演:' %}
|
||||||
<div>{% if item.imdb %}
|
{% for director in item.director %}
|
||||||
{% trans 'IMDb:' %}<a href="https://www.imdb.com/title/{{ item.imdb }}/" target="_blank" rel="noopener">{{ item.imdb }}</a>
|
<span {% if forloop.counter > 5 %}style="display: none;"{% endif %}>
|
||||||
{% endif %}
|
<span class="director">{{ director }}</span>
|
||||||
</div>
|
{% if not forloop.last %}/{% endif %}
|
||||||
<div>{% if item.director %}{% trans '导演:' %}
|
</span>
|
||||||
{% for director in item.director %}
|
{% endfor %}
|
||||||
<span {% if forloop.counter > 5 %}style="display: none;" {% endif %}>
|
{% if item.director|length > 5 %}
|
||||||
<span class="director">{{ director }}</span>
|
<a href="javascript:void(0);" id="directorMore">{% trans '更多' %}</a>
|
||||||
{% if not forloop.last %} / {% endif %}
|
<script>
|
||||||
</span>
|
|
||||||
{% endfor %}
|
|
||||||
{% if item.director|length > 5 %}
|
|
||||||
<a href="javascript:void(0);" id="directorMore">{% trans '更多' %}</a>
|
|
||||||
<script>
|
|
||||||
$("#directorMore").on('click', function (e) {
|
$("#directorMore").on('click', function (e) {
|
||||||
$("span.director:not(:visible)").each(function (e) {
|
$("span.director:not(:visible)").each(function (e) {
|
||||||
$(this).parent().removeAttr('style');
|
$(this).parent().removeAttr('style');
|
||||||
});
|
});
|
||||||
$(this).remove();
|
$(this).remove();
|
||||||
})
|
})
|
||||||
</script>
|
|
||||||
{% endif %}
|
</script>
|
||||||
{% endif %}</div>
|
{% endif %}
|
||||||
<div>{% if item.playwright %}{% trans '编剧:' %}
|
{% endif %}
|
||||||
{% for playwright in item.playwright %}
|
</div>
|
||||||
<span {% if forloop.counter > 5 %}style="display: none;" {% endif %}>
|
<div>
|
||||||
<span class="playwright">{{ playwright }}</span>
|
{% if item.playwright %}
|
||||||
{% if not forloop.last %} / {% endif %}
|
{% trans '编剧:' %}
|
||||||
</span>
|
{% for playwright in item.playwright %}
|
||||||
{% endfor %}
|
<span {% if forloop.counter > 5 %}style="display: none;"{% endif %}>
|
||||||
{% if item.playwright|length > 5 %}
|
<span class="playwright">{{ playwright }}</span>
|
||||||
<a href="javascript:void(0);" id="playwrightMore">{% trans '更多' %}</a>
|
{% if not forloop.last %}/{% endif %}
|
||||||
<script>
|
</span>
|
||||||
|
{% endfor %}
|
||||||
|
{% if item.playwright|length > 5 %}
|
||||||
|
<a href="javascript:void(0);" id="playwrightMore">{% trans '更多' %}</a>
|
||||||
|
<script>
|
||||||
$("#playwrightMore").on('click', function (e) {
|
$("#playwrightMore").on('click', function (e) {
|
||||||
$("span.playwright:not(:visible)").each(function (e) {
|
$("span.playwright:not(:visible)").each(function (e) {
|
||||||
$(this).parent().removeAttr('style');
|
$(this).parent().removeAttr('style');
|
||||||
});
|
});
|
||||||
$(this).remove();
|
$(this).remove();
|
||||||
})
|
})
|
||||||
</script>
|
|
||||||
{% endif %}
|
|
||||||
{% endif %}</div>
|
|
||||||
<div>{% if item.actor %}{% trans '主演:' %}
|
|
||||||
{% for actor in item.actor %}
|
|
||||||
<span {% if forloop.counter > 5 %}style="display: none;"{% endif %}>
|
|
||||||
<span class="actor">{{ actor }}</span>
|
|
||||||
{% if not forloop.last %} / {% endif %}
|
|
||||||
</span>
|
|
||||||
{% endfor %}
|
|
||||||
|
|
||||||
{% if item.actor|length > 5 %}
|
</script>
|
||||||
<a href="javascript:void(0);" id="actorMore">{% trans '更多' %}</a>
|
{% endif %}
|
||||||
<script>
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
{% if item.actor %}
|
||||||
|
{% trans '主演:' %}
|
||||||
|
{% for actor in item.actor %}
|
||||||
|
<span {% if forloop.counter > 5 %}style="display: none;"{% endif %}>
|
||||||
|
<span class="actor">{{ actor }}</span>
|
||||||
|
{% if not forloop.last %}/{% endif %}
|
||||||
|
</span>
|
||||||
|
{% endfor %}
|
||||||
|
{% if item.actor|length > 5 %}
|
||||||
|
<a href="javascript:void(0);" id="actorMore">{% trans '更多' %}</a>
|
||||||
|
<script>
|
||||||
$("#actorMore").on('click', function(e) {
|
$("#actorMore").on('click', function(e) {
|
||||||
$("span.actor:not(:visible)").each(function(e){
|
$("span.actor:not(:visible)").each(function(e){
|
||||||
$(this).parent().removeAttr('style');
|
$(this).parent().removeAttr('style');
|
||||||
});
|
});
|
||||||
$(this).remove();
|
$(this).remove();
|
||||||
})
|
})
|
||||||
</script>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
{% endif %}</div>
|
</script>
|
||||||
<div>{% if item.genre %}{% trans '类型:' %}
|
{% endif %}
|
||||||
{% for genre in item.genre %}
|
{% endif %}
|
||||||
<span>{{ genre }}</span>{% if not forloop.last %} / {% endif %}
|
</div>
|
||||||
{% endfor %}
|
<div>
|
||||||
{% endif %}</div>
|
{% if item.genre %}
|
||||||
<div>{% if item.area %}{% trans '制片国家/地区:' %}
|
{% trans '类型:' %}
|
||||||
{% for area in item.area %}
|
{% for genre in item.genre %}
|
||||||
<span>{{ area }}</span>{% if not forloop.last %} / {% endif %}
|
<span>{{ genre }}</span>
|
||||||
{% endfor %}
|
{% if not forloop.last %}/{% endif %}
|
||||||
{% endif %}</div>
|
{% endfor %}
|
||||||
<div>{% if item.language %}{% trans '语言:' %}
|
{% endif %}
|
||||||
{% for language in item.language %}
|
</div>
|
||||||
<span>{{ language }}</span>{% if not forloop.last %} / {% endif %}
|
<div>
|
||||||
{% endfor %}
|
{% if item.area %}
|
||||||
{% endif %}</div>
|
{% trans '制片国家/地区:' %}
|
||||||
|
{% for area in item.area %}
|
||||||
</div>
|
<span>{{ area }}</span>
|
||||||
<div class="entity-detail__fields">
|
{% if not forloop.last %}/{% endif %}
|
||||||
<div>{% if item.duration %}{% trans '片长:' %}{{ item.duration }}{% endif %}</div>
|
{% endfor %}
|
||||||
<div>{% if item.season_count %}{% trans '季数:' %}{{ item.season_count }}{% endif %}</div>
|
{% endif %}
|
||||||
<div>{% if item.episode_count %}{% trans '集数:' %}{{ item.episode_count }}{% endif %}</div>
|
</div>
|
||||||
<div>{% if item.single_episode_length %}{% trans '单集长度:' %}{{ item.single_episode_length }}{% endif %}</div>
|
<div>
|
||||||
|
{% if item.language %}
|
||||||
<div>{% if item.showtime %}{% trans '上映时间:' %}
|
{% trans '语言:' %}
|
||||||
{% for showtime in item.showtime %}
|
{% for language in item.language %}
|
||||||
{% for time, region in showtime.items %}
|
<span>{{ language }}</span>
|
||||||
<span>{{ time }}{% if region != '' %}({{ region }}){% endif %}</span>
|
{% if not forloop.last %}/{% endif %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% if not forloop.last %} / {% endif %}
|
{% endif %}
|
||||||
{% endfor %}
|
</div>
|
||||||
{% endif %}</div>
|
<div>
|
||||||
<div>{% if item.other_title %}{% trans '又名:' %}
|
{% if item.duration %}
|
||||||
{% for t in item.other_title %}
|
{% trans '片长:' %}{{ item.duration }}
|
||||||
<span>{{ t }}</span>{% if not forloop.last %} / {% endif %}
|
{% endif %}
|
||||||
{% endfor %}
|
</div>
|
||||||
{% endif %}</div>
|
<div>
|
||||||
<div>{% if item.site %}{% trans '网站:' %}
|
{% if item.season_count %}
|
||||||
<a href="{{ item.site }}" target="_blank" rel="noopener">{{ item.site|strip_scheme }}</a>
|
{% trans '季数:' %}{{ item.season_count }}
|
||||||
{% endif %}</div>
|
{% endif %}
|
||||||
{% if item.other_info %}
|
</div>
|
||||||
{% for k, v in item.other_info.items %}
|
<div>
|
||||||
<div>
|
{% if item.episode_count %}
|
||||||
{{ k }}:{{ v | urlize }}
|
{% trans '集数:' %}{{ item.episode_count }}
|
||||||
</div>
|
{% endif %}
|
||||||
{% endfor %}
|
</div>
|
||||||
{% endif %}
|
<div>
|
||||||
|
{% if item.single_episode_length %}
|
||||||
|
{% trans '单集长度:' %}{{ item.single_episode_length }}
|
||||||
{% if item.last_editor and item.last_editor.preference.show_last_edit %}
|
{% endif %}
|
||||||
<div>{% trans '最近编辑者:' %}<a href="{% url 'journal:user_profile' item.last_editor.mastodon_username %}">{{ item.last_editor | default:"" }}</a></div>
|
</div>
|
||||||
{% endif %}
|
<div>
|
||||||
|
{% if item.showtime %}
|
||||||
<div>
|
{% trans '上映时间:' %}
|
||||||
{% if user.is_authenticated %}
|
{% for showtime in item.showtime %}
|
||||||
<a href="{% url 'catalog:edit' item.url_path item.uuid %}">{% trans '编辑' %}{{ item.demonstrative }}</a>
|
{% for time, region in showtime.items %}
|
||||||
{% endif %}
|
<span>{{ time }}
|
||||||
</div>
|
{% if region != '' %}({{ region }}){% endif %}
|
||||||
</div>
|
</span>
|
||||||
{% endblock %}
|
{% endfor %}
|
||||||
|
{% if not forloop.last %}/{% endif %}
|
||||||
<!-- class specific sidebar -->
|
{% endfor %}
|
||||||
{% block sidebar %}
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
{% if item.other_title %}
|
||||||
|
{% trans '又名:' %}
|
||||||
|
{% for t in item.other_title %}
|
||||||
|
<span>{{ t }}</span>
|
||||||
|
{% if not forloop.last %}/{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
{% if item.site %}
|
||||||
|
{% trans '网站:' %}
|
||||||
|
<a href="{{ item.site }}" target="_blank" rel="noopener">{{ item.site|strip_scheme }}</a>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
{% if item.other_info %}
|
||||||
|
{% for k, v in item.other_info.items %}<div>{{ k }}:{{ v|urlizetrunc:24 }}</div>{% endfor %}
|
||||||
|
{% endif %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
@ -9,138 +9,121 @@
|
||||||
{% load truncate %}
|
{% load truncate %}
|
||||||
{% load strip_scheme %}
|
{% load strip_scheme %}
|
||||||
{% load thumb %}
|
{% load thumb %}
|
||||||
|
|
||||||
<!-- class specific details -->
|
<!-- class specific details -->
|
||||||
{% block details %}
|
{% block details %}
|
||||||
<div class="entity-detail__fields">
|
<div>
|
||||||
<div class="entity-detail__rating">
|
{% if item.other_title %}
|
||||||
{% if item.rating and item.rating_count >= 5 %}
|
{% trans '别名:' %}
|
||||||
<span class="entity-detail__rating-star rating-star" data-rating-score="{{ item.rating | floatformat:0 }}"></span>
|
{% for other_title in item.other_title %}
|
||||||
<span class="entity-detail__rating-score"> {{ item.rating | floatformat:1 }} </span>
|
<span {% if forloop.counter > 5 %}style="display: none;"{% endif %}>
|
||||||
<small>({{ item.rating_count }}人评分)</small>
|
<span class="other_title">{{ other_title }}</span>
|
||||||
{% else %}
|
{% if not forloop.last %}/{% endif %}
|
||||||
<span> {% trans '评分:评分人数不足' %}</span>
|
</span>
|
||||||
{% endif %}
|
{% endfor %}
|
||||||
</div>
|
{% if item.other_title|length > 5 %}
|
||||||
|
<a href="javascript:void(0);" id="otherTitleMore">{% trans '更多' %}</a>
|
||||||
<div>{% if item.other_title %}{% trans '别名:' %}
|
<script>
|
||||||
{% for other_title in item.other_title %}
|
|
||||||
<span {% if forloop.counter > 5 %}style="display: none;" {% endif %}>
|
|
||||||
<span class="other_title">{{ other_title }}</span>
|
|
||||||
{% if not forloop.last %} / {% endif %}
|
|
||||||
</span>
|
|
||||||
{% endfor %}
|
|
||||||
{% if item.other_title|length > 5 %}
|
|
||||||
<a href="javascript:void(0);" id="otherTitleMore">{% trans '更多' %}</a>
|
|
||||||
<script>
|
|
||||||
$("#otherTitleMore").on('click', function (e) {
|
$("#otherTitleMore").on('click', function (e) {
|
||||||
$("span.other_title:not(:visible)").each(function (e) {
|
$("span.other_title:not(:visible)").each(function (e) {
|
||||||
$(this).parent().removeAttr('style');
|
$(this).parent().removeAttr('style');
|
||||||
});
|
});
|
||||||
$(this).remove();
|
$(this).remove();
|
||||||
})
|
})
|
||||||
</script>
|
|
||||||
{% endif %}
|
</script>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
{% endif %}
|
||||||
|
</div>
|
||||||
<div>
|
<div>
|
||||||
{% if item.genre %}{% trans '类型:' %}
|
{% if item.genre %}
|
||||||
{% for genre in item.genre %}
|
{% trans '类型:' %}
|
||||||
<span>{{ genre }}</span>{% if not forloop.last %} / {% endif %}
|
{% for genre in item.genre %}
|
||||||
{% endfor %}
|
<span>{{ genre }}</span>
|
||||||
{% endif %}
|
{% if not forloop.last %}/{% endif %}
|
||||||
</div>
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
<div>
|
</div>
|
||||||
{% if item.director %}{% trans '导演:' %}
|
<div>
|
||||||
{% for director in item.director %}
|
{% if item.director %}
|
||||||
<span>{{ director }}</span>{% if not forloop.last %} / {% endif %}
|
{% trans '导演:' %}
|
||||||
{% endfor %}
|
{% for director in item.director %}
|
||||||
{% endif %}
|
<span>{{ director }}</span>
|
||||||
</div>
|
{% if not forloop.last %}/{% endif %}
|
||||||
|
{% endfor %}
|
||||||
<div>
|
{% endif %}
|
||||||
{% if item.playwright %}{% trans '编剧:' %}
|
</div>
|
||||||
{% for playwright in item.playwright %}
|
<div>
|
||||||
<span>{{ playwright }}</span>{% if not forloop.last %} / {% endif %}
|
{% if item.playwright %}
|
||||||
{% endfor %}
|
{% trans '编剧:' %}
|
||||||
{% endif %}
|
{% for playwright in item.playwright %}
|
||||||
</div>
|
<span>{{ playwright }}</span>
|
||||||
|
{% if not forloop.last %}/{% endif %}
|
||||||
<div>
|
{% endfor %}
|
||||||
{% if item.actor %}{% trans '主演:' %}
|
{% endif %}
|
||||||
{% for actor in item.actor %}
|
</div>
|
||||||
<span>{{ actor }}</span>{% if not forloop.last %} / {% endif %}
|
<div>
|
||||||
{% endfor %}
|
{% if item.actor %}
|
||||||
{% endif %}
|
{% trans '主演:' %}
|
||||||
</div>
|
{% for actor in item.actor %}
|
||||||
|
<span>{{ actor }}</span>
|
||||||
<div>
|
{% if not forloop.last %}/{% endif %}
|
||||||
{% if item.choreographer %}{% trans '编舞:' %}
|
{% endfor %}
|
||||||
{% for choreographer in item.choreographer %}
|
{% endif %}
|
||||||
<span>{{ choreographer }}</span>{% if not forloop.last %} / {% endif %}
|
</div>
|
||||||
{% endfor %}
|
<div>
|
||||||
{% endif %}
|
{% if item.choreographer %}
|
||||||
</div>
|
{% trans '编舞:' %}
|
||||||
|
{% for choreographer in item.choreographer %}
|
||||||
<div>
|
<span>{{ choreographer }}</span>
|
||||||
{% if item.composer %}{% trans '作曲:' %}
|
{% if not forloop.last %}/{% endif %}
|
||||||
{% for composer in item.composer %}
|
{% endfor %}
|
||||||
<span>{{ composer }}</span>{% if not forloop.last %} / {% endif %}
|
{% endif %}
|
||||||
{% endfor %}
|
</div>
|
||||||
{% endif %}
|
<div>
|
||||||
</div>
|
{% if item.composer %}
|
||||||
</div>
|
{% trans '作曲:' %}
|
||||||
<div class="entity-detail__fields">
|
{% for composer in item.composer %}
|
||||||
|
<span>{{ composer }}</span>
|
||||||
<div>
|
{% if not forloop.last %}/{% endif %}
|
||||||
{% if item.troupe %}{% trans '剧团:' %}
|
{% endfor %}
|
||||||
{% for troupe in item.troupe %}
|
{% endif %}
|
||||||
<span>{{ troupe }}</span>{% if not forloop.last %} / {% endif %}
|
</div>
|
||||||
{% endfor %}
|
<div>
|
||||||
{% endif %}
|
{% if item.troupe %}
|
||||||
</div>
|
{% trans '剧团:' %}
|
||||||
|
{% for troupe in item.troupe %}
|
||||||
<div>
|
<span>{{ troupe }}</span>
|
||||||
{% if item.theatre %}{% trans '剧场:' %}
|
{% if not forloop.last %}/{% endif %}
|
||||||
{% for theatre in item.theatre %}
|
{% endfor %}
|
||||||
<span>{{ theatre }}</span>{% if not forloop.last %} / {% endif %}
|
{% endif %}
|
||||||
{% endfor %}
|
</div>
|
||||||
{% endif %}
|
<div>
|
||||||
</div>
|
{% if item.theatre %}
|
||||||
|
{% trans '剧场:' %}
|
||||||
<div>
|
{% for theatre in item.theatre %}
|
||||||
{% if item.opening_date %}{% trans '演出日期:' %}
|
<span>{{ theatre }}</span>
|
||||||
<span>{{ item.opening_date }}</span>
|
{% if not forloop.last %}/{% endif %}
|
||||||
{% endif %}
|
{% endfor %}
|
||||||
</div>
|
{% endif %}
|
||||||
|
</div>
|
||||||
<div>
|
<div>
|
||||||
{% if item.version %}{% trans '版本:' %}
|
{% if item.opening_date %}
|
||||||
{% for version in item.version %}
|
{% trans '演出日期:' %}
|
||||||
<span>{{ version }}</span>{% if not forloop.last %} / {% endif %}
|
<span>{{ item.opening_date }}</span>
|
||||||
{% endfor %}
|
{% endif %}
|
||||||
{% endif %}
|
</div>
|
||||||
</div>
|
<div>
|
||||||
|
{% if item.version %}
|
||||||
<div>{% if item.official_site %}
|
{% trans '版本:' %}
|
||||||
{% trans '官方网站:' %}{{ item.official_site|urlizetrunc:42 }}
|
{% for version in item.version %}
|
||||||
{% endif %}
|
<span>{{ version }}</span>
|
||||||
</div>
|
{% if not forloop.last %}/{% endif %}
|
||||||
|
{% endfor %}
|
||||||
{% if item.last_editor and item.last_editor.preference.show_last_edit %}
|
{% endif %}
|
||||||
<div>{% trans '最近编辑者:' %}<a href="{% url 'journal:user_profile' item.last_editor.mastodon_username %}">{{ item.last_editor | default:"" }}</a></div>
|
</div>
|
||||||
{% endif %}
|
<div>
|
||||||
|
{% if item.official_site %}
|
||||||
<div>
|
{% trans '官方网站:' %}{{ item.official_site|urlizetrunc:24 }}
|
||||||
{% if user.is_authenticated %}
|
{% endif %}
|
||||||
<a href="{% url 'catalog:edit' item.url_path item.uuid %}">{% trans '编辑' %}{{ item.demonstrative }}</a>
|
</div>
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% endblock %}
|
|
||||||
|
|
||||||
<!-- class specific sidebar -->
|
|
||||||
{% block sidebar %}
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
@ -9,99 +9,67 @@
|
||||||
{% load truncate %}
|
{% load truncate %}
|
||||||
{% load strip_scheme %}
|
{% load strip_scheme %}
|
||||||
{% load thumb %}
|
{% load thumb %}
|
||||||
|
|
||||||
{% block head %}
|
{% block head %}
|
||||||
<script src=" https://cdn.jsdelivr.net/npm/shikwasa@2.2.0/dist/shikwasa.min.js "></script>
|
<script src="https://cdn.jsdelivr.net/npm/shikwasa@2.2.1/dist/shikwasa.min.js"></script>
|
||||||
<link href=" https://cdn.jsdelivr.net/npm/shikwasa@2.2.0/dist/style.min.css " rel="stylesheet"></link>
|
<link href="https://cdn.jsdelivr.net/npm/shikwasa@2.2.1/dist/style.min.css"
|
||||||
|
rel="stylesheet"></link>
|
||||||
|
<script src="{% static 'podcast.js' %}"></script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
<!-- class specific details -->
|
|
||||||
{% block details %}
|
{% block details %}
|
||||||
<style type="text/css">
|
<div>
|
||||||
.entity-detail .entity-detail__img {
|
{% if item.genre %}
|
||||||
height: unset !important;
|
{% trans '类型:' %}
|
||||||
}
|
{% for genre in item.genre %}
|
||||||
</style>
|
<span>{{ genre }}</span>
|
||||||
<div class="entity-detail__fields">
|
{% if not forloop.last %}/{% endif %}
|
||||||
<div class="entity-detail__rating">
|
{% endfor %}
|
||||||
{% if item.rating and item.rating_count >= 5 %}
|
{% endif %}
|
||||||
<span class="entity-detail__rating-star rating-star" data-rating-score="{{ item.rating | floatformat:0 }}"></span>
|
</div>
|
||||||
<span class="entity-detail__rating-score"> {{ item.rating | floatformat:1 }} </span>
|
<div>
|
||||||
<small>({{ item.rating_count }}人评分)</small>
|
{% if item.official_site %}
|
||||||
{% else %}
|
{% trans '网站:' %}{{ item.official_site|urlizetrunc:24 }}
|
||||||
<span> {% trans '评分:评分人数不足' %}</span>
|
{% endif %}
|
||||||
{% endif %}
|
</div>
|
||||||
</div>
|
<div>
|
||||||
|
{% if item.hosts %}
|
||||||
<div>
|
{% trans '主播:' %}
|
||||||
{% if item.genre %}{% trans '类型:' %}
|
{% for host in item.hosts %}
|
||||||
{% for genre in item.genre %}
|
<span {% if forloop.counter > 5 %}style="display: none;"{% endif %}>
|
||||||
<span>{{ genre }}</span>{% if not forloop.last %} / {% endif %}
|
<span class="other_title">{{ host }}</span>
|
||||||
{% endfor %}
|
{% if not forloop.last %}/{% endif %}
|
||||||
{% endif %}
|
</span>
|
||||||
</div>
|
{% endfor %}
|
||||||
|
{% if item.hosts|length > 5 %}
|
||||||
<div>{% if item.official_site %}
|
<a href="javascript:void(0);" id="otherTitleMore">{% trans '更多' %}</a>
|
||||||
{% trans '网站:' %}{{ item.official_site|urlizetrunc:42 }}
|
<script>
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
<div class="entity-detail__fields">
|
|
||||||
|
|
||||||
<div>{% if item.hosts %}{% trans '主播:' %}
|
|
||||||
{% for host in item.hosts %}
|
|
||||||
<span {% if forloop.counter > 5 %}style="display: none;" {% endif %}>
|
|
||||||
<span class="other_title">{{ host }}</span>
|
|
||||||
{% if not forloop.last %} / {% endif %}
|
|
||||||
</span>
|
|
||||||
{% endfor %}
|
|
||||||
{% if item.hosts|length > 5 %}
|
|
||||||
<a href="javascript:void(0);" id="otherTitleMore">{% trans '更多' %}</a>
|
|
||||||
<script>
|
|
||||||
$("#otherTitleMore").on('click', function (e) {
|
$("#otherTitleMore").on('click', function (e) {
|
||||||
$("span.other_title:not(:visible)").each(function (e) {
|
$("span.other_title:not(:visible)").each(function (e) {
|
||||||
$(this).parent().removeAttr('style');
|
$(this).parent().removeAttr('style');
|
||||||
});
|
});
|
||||||
$(this).remove();
|
$(this).remove();
|
||||||
})
|
})
|
||||||
</script>
|
|
||||||
{% endif %}
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{% if item.last_editor and item.last_editor.preference.show_last_edit %}
|
</script>
|
||||||
<div>{% trans '最近编辑者:' %}<a href="{% url 'journal:user_profile' item.last_editor.mastodon_username %}">{{ item.last_editor | default:"" }}</a></div>
|
{% endif %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
<div>
|
|
||||||
{% if user.is_authenticated %}
|
|
||||||
<a href="{% url 'catalog:edit' item.url_path item.uuid %}">{% trans '编辑' %}{{ item.demonstrative }}</a>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% endblock %}
|
|
||||||
|
|
||||||
|
|
||||||
{% block content %}
|
|
||||||
<div class="entity-desc" id="episodes">
|
|
||||||
<h5 class="entity-desc__title">{% trans '近期节目' %}</h5>
|
|
||||||
<br>
|
|
||||||
<div hx-get="{% url 'catalog:episode_data' item.uuid %}" hx-trigger="load" hx-swap="outerHTML"></div>
|
|
||||||
</div>
|
|
||||||
{% endblock %}
|
|
||||||
|
|
||||||
<!-- class specific sidebar -->
|
|
||||||
{% block sidebar %}
|
|
||||||
<div class="aside-section-wrapper">
|
|
||||||
<div class="action-panel" id="episodes">
|
|
||||||
<div class="action-panel__button-group action-panel__button-group--center">
|
|
||||||
<button href="#" class="podlove-subscribe-button-primary action-panel__button">{% trans '用播客应用订阅' %}</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
{% endblock %}
|
||||||
|
{% block content %}
|
||||||
<script>
|
<section class="entity-desc" id="episodes">
|
||||||
|
<h5 class="entity-desc__title">{% trans '近期节目' %}</h5>
|
||||||
|
<div hx-get="{% url 'catalog:episode_data' item.uuid %}"
|
||||||
|
hx-trigger="load"
|
||||||
|
hx-swap="outerHTML"></div>
|
||||||
|
</section>
|
||||||
|
{% endblock %}
|
||||||
|
<!-- class specific sidebar -->
|
||||||
|
{% block left_sidebar %}
|
||||||
|
<section>
|
||||||
|
<center>
|
||||||
|
<button href="#" class="podlove-subscribe-button-primary outline">{% trans '用播客应用订阅' %}</button>
|
||||||
|
</center>
|
||||||
|
</section>
|
||||||
|
<script>
|
||||||
window.podcastData = {
|
window.podcastData = {
|
||||||
"title": "{{ item.title | escapejs }}",
|
"title": "{{ item.title | escapejs }}",
|
||||||
"subtitle": "",
|
"subtitle": "",
|
||||||
|
@ -123,6 +91,12 @@ $(()=>{
|
||||||
if (position) window.player._initSeek = position;
|
if (position) window.player._initSeek = position;
|
||||||
{% endif %}
|
{% endif %}
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
<script class="podlove-subscribe-button" src="https://cdn.podlove.org/subscribe-button/javascripts/app.js" data-json-data="podcastData" data-buttonid="primary" data-language="en" data-hide="true" data-color="#1190C0"></script>
|
<script class="podlove-subscribe-button"
|
||||||
|
src="https://cdn.podlove.org/subscribe-button/javascripts/app.js"
|
||||||
|
data-json-data="podcastData"
|
||||||
|
data-buttonid="primary"
|
||||||
|
data-language="en"
|
||||||
|
data-hide="true"
|
||||||
|
data-color="#1190C0"></script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
@ -3,44 +3,39 @@
|
||||||
{% load l10n %}
|
{% load l10n %}
|
||||||
{% load humanize %}
|
{% load humanize %}
|
||||||
{% for ep in episodes %}
|
{% for ep in episodes %}
|
||||||
<details>
|
<p>
|
||||||
<summary>
|
<h6 class="entity-desc__title">
|
||||||
<h6 class="entity-desc__title">
|
<a data-media="{{ ep.media_url }}"
|
||||||
<a
|
data-cover="{{ ep.cover_url|default:item.cover.url }}"
|
||||||
data-media="{{ ep.media_url }}"
|
class="episode gg-play-button-o"
|
||||||
data-cover="{{ ep.cover_url|default:item.cover.url }}"
|
href="{{ ep.url }}"
|
||||||
class="episode gg-play-button-o"
|
data-uuid="{{ ep.uuid }}"
|
||||||
href="{{ep.url}}"
|
data-title="{{ ep.title }}"
|
||||||
data-uuid="{{ep.uuid}}"
|
data-album="{{ item.title }}"
|
||||||
data-title="{{ ep.title }}"
|
data-hosts="{{ item.hosts|join:' / ' }}"
|
||||||
data-album = "{{ item.title }}"
|
style="top:4px;
|
||||||
data-hosts = "{{ item.hosts|join:' / ' }}"
|
margin-right: 8px"></a>
|
||||||
style="top:4px;margin-right: 8px;">
|
|
||||||
</a>
|
{% if request.user.is_authenticated %}
|
||||||
{{ ep.title }}
|
<a style="margin-right: 10px"
|
||||||
<small style="color:lightgrey;">{{ ep.pub_date|date }}</small>
|
title="评论单集"
|
||||||
</h6>
|
href="#"
|
||||||
</summary>
|
hx-get="{% url 'journal:comment' item.uuid ep.uuid %}"
|
||||||
<p> {{ ep.brief | linebreaksbr }} </p>
|
hx-target="body"
|
||||||
</details>
|
hx-swap="beforeend"><i class="fa-regular fa-comment-dots"></i></a>
|
||||||
<div style="margin-bottom: 8px;margin-left: 32px;">
|
{% endif %}
|
||||||
{% if request.user.is_authenticated %}
|
<a title="打开源网站" target="_blank" rel="noopener" href="{{ ep.link }}"><i class="fa-solid fa-link"></i></a>
|
||||||
<a class="icon" style="margin-right: 10px;" title="评论单集" href="#" hx-get="{% url 'journal:comment' item.uuid ep.uuid %}" hx-target="body" hx-swap="beforeend">
|
{{ ep.title }}
|
||||||
<i class="fa-regular fa-comment-dots"></i>
|
<small style="color:lightgrey;">{{ ep.pub_date|date }}</small>
|
||||||
</a>
|
</h6>
|
||||||
{% endif %}
|
<small class="tldr-2 muted" _="on click toggle .tldr-2">{{ ep.brief | linebreaksbr }}</small>
|
||||||
<!-- <a class="icon" title="详细介绍" href="{{ep.link}}">
|
</p>
|
||||||
<i class="fa-solid fa-circle-info"></i>
|
{% if forloop.last %}
|
||||||
</a> -->
|
<button class="outline"
|
||||||
<a class="icon" title="打开源网站" target="_blank" rel="noopener" href="{{ep.link}}">
|
hx-get="{% url 'catalog:episode_data' item.uuid %}?last={{ ep.pub_date|date:'Y-m-d H:i:s.uO'|urlencode }}"
|
||||||
<i class="fa-solid fa-arrow-up-right-from-square"></i>
|
hx-trigger="click"
|
||||||
</a>
|
hx-swap="outerHTML">显示更多</button>
|
||||||
</div>
|
{% endif %}
|
||||||
|
|
||||||
{% if forloop.last %}
|
|
||||||
<button hx-get="{% url 'catalog:episode_data' item.uuid %}?last={{ ep.pub_date|date:'Y-m-d H:i:s.uO'|urlencode }}" hx-trigger="click" hx-swap="outerHTML">显示更多</button>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
{% empty %}
|
{% empty %}
|
||||||
<div>{% trans '目前没有更多内容了' %}</div>
|
<div>{% trans '目前没有更多内容了' %}</div>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
|
@ -9,15 +9,18 @@
|
||||||
{% load truncate %}
|
{% load truncate %}
|
||||||
{% load strip_scheme %}
|
{% load strip_scheme %}
|
||||||
{% load thumb %}
|
{% load thumb %}
|
||||||
|
|
||||||
{% block head %}
|
{% block head %}
|
||||||
<meta http-equiv="refresh" content="0;url={{ item.program.absolute_url }}?focus={{ item.uuid }}{% if request.GET.position %}&position={{ request.GET.position }}{% endif %}" />
|
<meta http-equiv="refresh"
|
||||||
<meta property="og:image" content="{{ item.cover_url | default:item.program.cover_image_url }}">
|
content="0;url={{ item.program.absolute_url }}?focus={{ item.uuid }}{% if request.GET.position %}&position={{ request.GET.position }}{% endif %}" />
|
||||||
<meta property="twitter:image" content="{{ item.cover_url | default:item.program.cover_image_url }}">
|
<meta property="og:image"
|
||||||
{% if item.media_url %}
|
content="{{ item.cover_url | default:item.program.cover_image_url }}">
|
||||||
<meta property="twitter:card" content="player">
|
<meta property="twitter:image"
|
||||||
<meta property="twitter:player" content="{{ item.program.absolute_url }}/embed?focus={{ item.uuid }}{% if request.GET.position %}&position={{ request.GET.position }}{% endif %}" />
|
content="{{ item.cover_url | default:item.program.cover_image_url }}">
|
||||||
<meta property="twitter:player:width" content="300">
|
{% if item.media_url %}
|
||||||
<meta property="twitter:player:height" content="120">
|
<meta property="twitter:card" content="player">
|
||||||
{% endif %}
|
<meta property="twitter:player"
|
||||||
|
content="{{ item.program.absolute_url }}/embed?focus={{ item.uuid }}{% if request.GET.position %}&position={{ request.GET.position }}{% endif %}" />
|
||||||
|
<meta property="twitter:player:width" content="300">
|
||||||
|
<meta property="twitter:player:height" content="120">
|
||||||
|
{% endif %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
@ -9,94 +9,70 @@
|
||||||
{% load highlight %}
|
{% load highlight %}
|
||||||
{% load thumb %}
|
{% load thumb %}
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en" class="classic-page">
|
||||||
|
<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>{{ site_name }} - {% trans '搜索结果' %}</title>
|
<title>{{ site_name }} - {% trans '搜索结果' %}</title>
|
||||||
{% include "common_libs.html" with jquery=0 %}
|
{% include "common_libs.html" with jquery=0 v2=1 %}
|
||||||
</head>
|
</head>
|
||||||
|
<body>
|
||||||
<body>
|
{% include '_header.html' %}
|
||||||
<div id="page-wrapper">
|
<main>
|
||||||
<div id="content-wrapper">
|
<div class="grid__main">
|
||||||
{% include 'partial/_navbar.html' %}
|
<div class="main-section-wrapper">
|
||||||
|
<div class="entity-list">
|
||||||
<section id="content">
|
{% if request.GET.q %}
|
||||||
<div class="grid">
|
<h5>“{{ request.GET.q }}” {% trans '的搜索结果' %}</h5>
|
||||||
<div class="grid__main">
|
{% endif %}
|
||||||
<div class="main-section-wrapper">
|
{% if request.GET.tag %}
|
||||||
|
<h5>{% trans '含有标签' %} “{{ request.GET.tag }}” {% trans '的结果' %}</h5>
|
||||||
<div class="entity-list">
|
{% endif %}
|
||||||
{% if request.GET.q %}
|
<ul class="item-card-list">
|
||||||
<h5 class="entity-list__title">“{{ request.GET.q }}” {% trans '的搜索结果' %}</h5>
|
{% for item in items %}
|
||||||
{% endif %}
|
{% with "list_item_"|add:item.class_name|add:".html" as template %}
|
||||||
|
{% include template with show_tags=1 %}
|
||||||
{% if request.GET.tag %}
|
{% endwith %}
|
||||||
<h5 class="entity-list__title">{% trans '含有标签' %} “{{ request.GET.tag }}” {% trans '的结果' %}</h5>
|
{% empty %}
|
||||||
{% endif %}
|
<li class="empty">{% trans '无站内条目匹配' %}</li>
|
||||||
|
{% endfor %}
|
||||||
<ul class="entity-list__entities">
|
{% if request.GET.q and user.is_authenticated %}
|
||||||
{% for item in items %}
|
<li hx-get="{% url 'catalog:external_search' %}?q={{ request.GET.q }}&c={{ request.GET.c }}&page={% if pagination.current_page %}{{ pagination.current_page }}{% else %}1{% endif %}"
|
||||||
{% with "list_item_"|add:item.class_name|add:".html" as template %}
|
hx-trigger="load"
|
||||||
{% include template %}
|
hx-swap="outerHTML">
|
||||||
{% endwith %}
|
{% trans '正在实时搜索站外条目' %}
|
||||||
{% empty %}
|
<span><i class="fa-solid fa-compact-disc fa-spin loading"></i></span>
|
||||||
<li class="entity-list__entity">
|
</li>
|
||||||
{% trans '无站内条目匹配' %}
|
{% endif %}
|
||||||
</li>
|
</ul>
|
||||||
{% endfor %}
|
</div>
|
||||||
{% if request.GET.q and user.is_authenticated %}
|
<div class="pagination">
|
||||||
<li class="entity-list__entity" hx-get="{% url 'catalog:external_search' %}?q={{ request.GET.q }}&c={{ request.GET.c }}&page={% if pagination.current_page %}{{ pagination.current_page }}{% else %}1{% endif %}" hx-trigger="load" hx-swap="outerHTML">
|
{% if pagination.has_prev %}
|
||||||
{% trans '正在实时搜索站外条目' %}
|
<a href="?page=1&{% if request.GET.q %}q={{ request.GET.q }}{% elif request.GET.tag %}tag={{ request.GET.tag }}{% endif %}{% if request.GET.c %}&c={{ request.GET.c }}{% endif %}"
|
||||||
<span><i class="fas fa-fan fa-spin"></i></span>
|
class="pagination__nav-link pagination__nav-link">«</a>
|
||||||
</li>
|
<a href="?page={{ pagination.previous_page }}&{% if request.GET.q %}q={{ request.GET.q }}{% elif request.GET.tag %}tag={{ request.GET.tag }}{% endif %}{% if request.GET.c %}&c={{ request.GET.c }}{% endif %}"
|
||||||
{% endif %}
|
class="pagination__nav-link pagination__nav-link--right-margin pagination__nav-link">‹</a>
|
||||||
</ul>
|
{% endif %}
|
||||||
</div>
|
{% for page in pagination.page_range %}
|
||||||
<div class="pagination" >
|
{% if page == pagination.current_page %}
|
||||||
|
<a href="?page={{ page }}&{% if request.GET.q %}q={{ request.GET.q }}{% elif request.GET.tag %}tag={{ request.GET.tag }}{% endif %}{% if request.GET.c %}&c={{ request.GET.c }}{% endif %}"
|
||||||
{% if pagination.has_prev %}
|
class="pagination__page-link pagination__page-link--current">{{ page }}</a>
|
||||||
<a href="?page=1&{% if request.GET.q %}q={{ request.GET.q }}{% elif request.GET.tag %}tag={{ request.GET.tag }}{% endif %}{% if request.GET.c %}&c={{ request.GET.c }}{% endif %}" class="pagination__nav-link pagination__nav-link">«</a>
|
{% else %}
|
||||||
<a href="?page={{ pagination.previous_page }}&{% if request.GET.q %}q={{ request.GET.q }}{% elif request.GET.tag %}tag={{ request.GET.tag }}{% endif %}{% if request.GET.c %}&c={{ request.GET.c }}{% endif %}" class="pagination__nav-link pagination__nav-link--right-margin pagination__nav-link">‹</a>
|
<a href="?page={{ page }}&{% if request.GET.q %}q={{ request.GET.q }}{% elif request.GET.tag %}tag={{ request.GET.tag }}{% endif %}{% if request.GET.c %}&c={{ request.GET.c }}{% endif %}"
|
||||||
{% endif %}
|
class="pagination__page-link">{{ page }}</a>
|
||||||
|
{% endif %}
|
||||||
{% for page in pagination.page_range %}
|
{% endfor %}
|
||||||
|
{% if pagination.has_next %}
|
||||||
{% if page == pagination.current_page %}
|
<a href="?page={{ pagination.next_page }}&{% if request.GET.q %}q={{ request.GET.q }}{% elif request.GET.tag %}tag={{ request.GET.tag }}{% endif %}{% if request.GET.c %}&c={{ request.GET.c }}{% endif %}"
|
||||||
<a href="?page={{ page }}&{% if request.GET.q %}q={{ request.GET.q }}{% elif request.GET.tag %}tag={{ request.GET.tag }}{% endif %}{% if request.GET.c %}&c={{ request.GET.c }}{% endif %}" class="pagination__page-link pagination__page-link--current">{{ page }}</a>
|
class="pagination__nav-link pagination__nav-link--left-margin">›</a>
|
||||||
{% else %}
|
<a href="?page={{ pagination.last_page }}&{% if request.GET.q %}q={{ request.GET.q }}{% elif request.GET.tag %}tag={{ request.GET.tag }}{% endif %}{% if request.GET.c %}&c={{ request.GET.c }}{% endif %}"
|
||||||
<a href="?page={{ page }}&{% if request.GET.q %}q={{ request.GET.q }}{% elif request.GET.tag %}tag={{ request.GET.tag }}{% endif %}{% if request.GET.c %}&c={{ request.GET.c }}{% endif %}" class="pagination__page-link">{{ page }}</a>
|
class="pagination__nav-link">»</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
</div>
|
||||||
{% endfor %}
|
|
||||||
|
|
||||||
{% if pagination.has_next %}
|
|
||||||
<a href="?page={{ pagination.next_page }}&{% if request.GET.q %}q={{ request.GET.q }}{% elif request.GET.tag %}tag={{ request.GET.tag }}{% endif %}{% if request.GET.c %}&c={{ request.GET.c }}{% endif %}" class="pagination__nav-link pagination__nav-link--left-margin">›</a>
|
|
||||||
<a href="?page={{ pagination.last_page }}&{% if request.GET.q %}q={{ request.GET.q }}{% elif request.GET.tag %}tag={{ request.GET.tag }}{% endif %}{% if request.GET.c %}&c={{ request.GET.c }}{% endif %}" class="pagination__nav-link">»</a>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{% include "search_sidebar.html" %}
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
</div>
|
</div>
|
||||||
{% include 'partial/_footer.html' %}
|
</div>
|
||||||
</div>
|
{% include "search_sidebar.html" %}
|
||||||
|
</main>
|
||||||
|
{% include 'partial/_footer.html' %}
|
||||||
|
</body>
|
||||||
<script>
|
|
||||||
document.body.addEventListener('htmx:configRequest', (event) => {
|
|
||||||
event.detail.headers['X-CSRFToken'] = '{{ csrf_token }}';
|
|
||||||
})
|
|
||||||
</script>
|
|
||||||
</body>
|
|
||||||
|
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -1,46 +1,42 @@
|
||||||
{% load static %}
|
{% load static %}
|
||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
{% load l10n %}
|
{% load l10n %}
|
||||||
|
<style>
|
||||||
<div class="grid__aside">
|
.add-entity-entries__button {
|
||||||
<div class="aside-section-wrapper">
|
margin: 4px;
|
||||||
|
}
|
||||||
<div class="add-entity-entries">
|
</style>
|
||||||
<div class="add-entity-entries__entry">
|
<aside class="grid__aside bottom">
|
||||||
<div class="add-entity-entries__label">
|
<article>
|
||||||
{% trans '没有想要的结果?' %}
|
<div class="add-entity-entries__label">{% trans '没有想要的结果?' %}</div>
|
||||||
</div>
|
<p>
|
||||||
<p>
|
如果在
|
||||||
如果在
|
{% for site in sites %}
|
||||||
{% for site in sites %}
|
{{ site }}
|
||||||
{{ site }}
|
{% if not forloop.last %}/{% endif %}
|
||||||
{% if not forloop.last %}/{% endif %}
|
{% endfor %}
|
||||||
{% endfor %}
|
找到了条目,可以在搜索栏中输入完整链接提交。
|
||||||
找到了条目,可以在搜索栏中输入完整链接提交。
|
</p>
|
||||||
</p>
|
<p>当然也可以手工创建条目:</p>
|
||||||
<p>
|
<ul>
|
||||||
当然也可以手工创建条目。
|
<li>
|
||||||
</p>
|
<a href="{% url 'catalog:create' 'Edition' %}">{% trans '添加书' %}</a>
|
||||||
<a href="{% url 'catalog:create' 'Edition' %}">
|
</li>
|
||||||
<button class="add-entity-entries__button">{% trans '添加书' %}</button>
|
<li>
|
||||||
</a>
|
<a href="{% url 'catalog:create' 'Movie' %}">{% trans '添加电影' %}</a>
|
||||||
<a href="{% url 'catalog:create' 'Movie' %}">
|
</li>
|
||||||
<button class="add-entity-entries__button">{% trans '添加电影' %}</button>
|
<li>
|
||||||
</a>
|
<a href="{% url 'catalog:create' 'TVShow' %}">{% trans '添加剧集' %}</a>
|
||||||
<a href="{% url 'catalog:create' 'TVShow' %}">
|
</li>
|
||||||
<button class="add-entity-entries__button">{% trans '添加剧集' %}</button>
|
<li>
|
||||||
</a>
|
<a href="{% url 'catalog:create' 'Podcast' %}">{% trans '添加播客' %}</a>
|
||||||
<a href="{% url 'catalog:create' 'Podcast' %}">
|
</li>
|
||||||
<button class="add-entity-entries__button">{% trans '添加播客' %}</button>
|
<li>
|
||||||
</a>
|
<a href="{% url 'catalog:create' 'Album' %}">{% trans '添加专辑' %}</a>
|
||||||
<a href="{% url 'catalog:create' 'Album' %}">
|
</li>
|
||||||
<button class="add-entity-entries__button">{% trans '添加专辑' %}</button>
|
<li>
|
||||||
</a>
|
<a href="{% url 'catalog:create' 'Game' %}">{% trans '添加游戏' %}</a>
|
||||||
<a href="{% url 'catalog:create' 'Game' %}">
|
</li>
|
||||||
<button class="add-entity-entries__button">{% trans '添加游戏' %}</button>
|
</ul>
|
||||||
</a>
|
</article>
|
||||||
</div>
|
</aside>
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
|
@ -2,30 +2,26 @@
|
||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
{% load truncate %}
|
{% load truncate %}
|
||||||
{% load thumb %}
|
{% load thumb %}
|
||||||
<div class="aside-section-wrapper">
|
<article class="item">
|
||||||
<div class="entity-card">
|
<div>
|
||||||
<div class="entity-card__img-wrapper">
|
<a href="{% url 'catalog:retrieve' item.url_path item.uuid %}">
|
||||||
<a href="{% url 'catalog:retrieve' item.url_path item.uuid %}"><img src="{{ item.cover|thumb:'normal' }}" alt="" class="entity-card__img"></a>
|
<img src="{{ item.cover|thumb:'normal' }}" alt="" class="entity-card__img">
|
||||||
</div>
|
</a>
|
||||||
<div class="entity-card__info-wrapper">
|
</div>
|
||||||
<h5 class="entity-card__title"><a href="{% url 'catalog:retrieve' item.url_path item.uuid %}">{{ item.title }}</a>
|
<footer>
|
||||||
{% for res in item.external_resources.all %}
|
<h4>
|
||||||
|
<a href="{% url 'catalog:retrieve' item.url_path item.uuid %}">{{ item.title }}</a>
|
||||||
|
{% for res in item.external_resources.all %}
|
||||||
<a href="{{ res.url }}">
|
<a href="{{ res.url }}">
|
||||||
<span class="source-label source-label__{{ res.site_name }}">{{ res.site_name.label }}</span>
|
<span class="source-label source-label__{{ res.site_name }}">{{ res.site_name.label }}</span>
|
||||||
</a>
|
</a>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</h5>
|
</h4>
|
||||||
|
{% if item.isbn %}<div>ISBN: {{ item.isbn }}</div>{% endif %}
|
||||||
{% if item.isbn %}
|
<div>
|
||||||
<div>ISBN: {{ item.isbn }}</div>
|
{% if item.pub_house %}
|
||||||
{% endif %}
|
{% trans '出版社:' %}{{ item.pub_house }}
|
||||||
|
|
||||||
<div>{% if item.pub_house %}{% trans '出版社:' %}{{ item.pub_house }}{% endif %}</div>
|
|
||||||
{% if item.rating %}
|
|
||||||
{% trans '评分: ' %}<span class="entity-card__rating-star rating-star" data-rating-score="{{ item.rating | floatformat:0 }}"></span>
|
|
||||||
<span class="entity-card__rating-score rating-score">{{ item.rating | floatformat:1 }}</span>
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
|
</footer>
|
||||||
</div>
|
</article>
|
||||||
</div>
|
|
||||||
|
|
|
@ -9,178 +9,201 @@
|
||||||
{% load truncate %}
|
{% load truncate %}
|
||||||
{% load strip_scheme %}
|
{% load strip_scheme %}
|
||||||
{% load thumb %}
|
{% load thumb %}
|
||||||
|
|
||||||
{% block title %}
|
{% block title %}
|
||||||
<h5 class="entity-detail__title">
|
<h5 class="entity-detail__title">
|
||||||
{% if item.season_number %}
|
{% if item.season_number %}
|
||||||
{{ item.title }} {{ item.orig_title }} Season {{ item.season_number }}
|
{{ item.title }} {{ item.orig_title }} Season {{ item.season_number }}
|
||||||
<span class="entity-detail__title entity-detail__title--secondary">
|
<span class="entity-detail__title entity-detail__title--secondary">
|
||||||
{% if item.year %}({{ item.year }}){% endif %}
|
{% if item.year %}({{ item.year }}){% endif %}
|
||||||
</span>
|
</span>
|
||||||
{% else %}
|
{% else %}
|
||||||
{{ item.title }} {{ item.orig_title }}
|
{{ item.title }} {{ item.orig_title }}
|
||||||
<span class="entity-detail__title entity-detail__title--secondary">
|
<span class="entity-detail__title entity-detail__title--secondary">
|
||||||
{% if item.year %}({{ item.year }}){% endif %}
|
{% if item.year %}({{ item.year }}){% endif %}
|
||||||
</span>
|
</span>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
{% for res in item.external_resources.all %}
|
||||||
{% for res in item.external_resources.all %}
|
<a href="{{ res.url }}">
|
||||||
<a href="{{ res.url }}">
|
<span class="source-label source-label__{{ res.site_name }}">{{ res.site_name.label }}</span>
|
||||||
<span class="source-label source-label__{{ res.site_name }}">{{ res.site_name.label }}</span>
|
</a>
|
||||||
</a>
|
{% endfor %}
|
||||||
{% endfor %}
|
</h5>
|
||||||
</h5>
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
<!-- class specific details -->
|
<!-- class specific details -->
|
||||||
{% block details %}
|
{% block details %}
|
||||||
<div class="entity-detail__fields">
|
<div>
|
||||||
<div class="entity-detail__rating">
|
{% if item.imdb %}
|
||||||
{% if item.rating and item.rating_count >= 5 %}
|
{% trans 'IMDb:' %}<a href="https://www.imdb.com/title/{{ item.imdb }}/"
|
||||||
<span class="entity-detail__rating-star rating-star" data-rating-score="{{ item.rating | floatformat:"0" }}"></span>
|
target="_blank"
|
||||||
<span class="entity-detail__rating-score"> {{ item.rating | floatformat:1 }} </span>
|
rel="noopener">{{ item.imdb }}</a>
|
||||||
<small>({{ item.rating_count }}人评分)</small>
|
{% endif %}
|
||||||
{% else %}
|
</div>
|
||||||
<span> {% trans '评分:评分人数不足' %}</span>
|
<div>
|
||||||
{% endif %}
|
{% if item.director %}
|
||||||
</div>
|
{% trans '导演:' %}
|
||||||
<div>{% if item.imdb %}
|
{% for director in item.director %}
|
||||||
{% trans 'IMDb:' %}<a href="https://www.imdb.com/title/{{ item.imdb }}/" target="_blank" rel="noopener">{{ item.imdb }}</a>
|
<span {% if forloop.counter > 5 %}style="display: none;"{% endif %}>
|
||||||
{% endif %}
|
<span class="director">{{ director }}</span>
|
||||||
</div>
|
{% if not forloop.last %}/{% endif %}
|
||||||
<div>{% if item.director %}{% trans '导演:' %}
|
</span>
|
||||||
{% for director in item.director %}
|
{% endfor %}
|
||||||
<span {% if forloop.counter > 5 %}style="display: none;" {% endif %}>
|
{% if item.director|length > 5 %}
|
||||||
<span class="director">{{ director }}</span>
|
<a href="javascript:void(0);" id="directorMore">{% trans '更多' %}</a>
|
||||||
{% if not forloop.last %} / {% endif %}
|
<script>
|
||||||
</span>
|
|
||||||
{% endfor %}
|
|
||||||
{% if item.director|length > 5 %}
|
|
||||||
<a href="javascript:void(0);" id="directorMore">{% trans '更多' %}</a>
|
|
||||||
<script>
|
|
||||||
$("#directorMore").on('click', function (e) {
|
$("#directorMore").on('click', function (e) {
|
||||||
$("span.director:not(:visible)").each(function (e) {
|
$("span.director:not(:visible)").each(function (e) {
|
||||||
$(this).parent().removeAttr('style');
|
$(this).parent().removeAttr('style');
|
||||||
});
|
});
|
||||||
$(this).remove();
|
$(this).remove();
|
||||||
})
|
})
|
||||||
</script>
|
|
||||||
{% endif %}
|
</script>
|
||||||
{% endif %}</div>
|
{% endif %}
|
||||||
<div>{% if item.playwright %}{% trans '编剧:' %}
|
{% endif %}
|
||||||
{% for playwright in item.playwright %}
|
</div>
|
||||||
<span {% if forloop.counter > 5 %}style="display: none;" {% endif %}>
|
<div>
|
||||||
<span class="playwright">{{ playwright }}</span>
|
{% if item.playwright %}
|
||||||
{% if not forloop.last %} / {% endif %}
|
{% trans '编剧:' %}
|
||||||
</span>
|
{% for playwright in item.playwright %}
|
||||||
{% endfor %}
|
<span {% if forloop.counter > 5 %}style="display: none;"{% endif %}>
|
||||||
{% if item.playwright|length > 5 %}
|
<span class="playwright">{{ playwright }}</span>
|
||||||
<a href="javascript:void(0);" id="playwrightMore">{% trans '更多' %}</a>
|
{% if not forloop.last %}/{% endif %}
|
||||||
<script>
|
</span>
|
||||||
|
{% endfor %}
|
||||||
|
{% if item.playwright|length > 5 %}
|
||||||
|
<a href="javascript:void(0);" id="playwrightMore">{% trans '更多' %}</a>
|
||||||
|
<script>
|
||||||
$("#playwrightMore").on('click', function (e) {
|
$("#playwrightMore").on('click', function (e) {
|
||||||
$("span.playwright:not(:visible)").each(function (e) {
|
$("span.playwright:not(:visible)").each(function (e) {
|
||||||
$(this).parent().removeAttr('style');
|
$(this).parent().removeAttr('style');
|
||||||
});
|
});
|
||||||
$(this).remove();
|
$(this).remove();
|
||||||
})
|
})
|
||||||
</script>
|
|
||||||
{% endif %}
|
|
||||||
{% endif %}</div>
|
|
||||||
<div>{% if item.actor %}{% trans '主演:' %}
|
|
||||||
{% for actor in item.actor %}
|
|
||||||
<span {% if forloop.counter > 5 %}style="display: none;"{% endif %}>
|
|
||||||
<span class="actor">{{ actor }}</span>
|
|
||||||
{% if not forloop.last %} / {% endif %}
|
|
||||||
</span>
|
|
||||||
{% endfor %}
|
|
||||||
|
|
||||||
{% if item.actor|length > 5 %}
|
</script>
|
||||||
<a href="javascript:void(0);" id="actorMore">{% trans '更多' %}</a>
|
{% endif %}
|
||||||
<script>
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
{% if item.actor %}
|
||||||
|
{% trans '主演:' %}
|
||||||
|
{% for actor in item.actor %}
|
||||||
|
<span {% if forloop.counter > 5 %}style="display: none;"{% endif %}>
|
||||||
|
<span class="actor">{{ actor }}</span>
|
||||||
|
{% if not forloop.last %}/{% endif %}
|
||||||
|
</span>
|
||||||
|
{% endfor %}
|
||||||
|
{% if item.actor|length > 5 %}
|
||||||
|
<a href="javascript:void(0);" id="actorMore">{% trans '更多' %}</a>
|
||||||
|
<script>
|
||||||
$("#actorMore").on('click', function(e) {
|
$("#actorMore").on('click', function(e) {
|
||||||
$("span.actor:not(:visible)").each(function(e){
|
$("span.actor:not(:visible)").each(function(e){
|
||||||
$(this).parent().removeAttr('style');
|
$(this).parent().removeAttr('style');
|
||||||
});
|
});
|
||||||
$(this).remove();
|
$(this).remove();
|
||||||
})
|
})
|
||||||
</script>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
{% endif %}</div>
|
|
||||||
<div>{% if item.genre %}{% trans '类型:' %}
|
|
||||||
{% for genre in item.genre %}
|
|
||||||
<span>{{ genre }}</span>{% if not forloop.last %} / {% endif %}
|
|
||||||
{% endfor %}
|
|
||||||
{% endif %}</div>
|
|
||||||
<div>{% if item.area %}{% trans '制片国家/地区:' %}
|
|
||||||
{% for area in item.area %}
|
|
||||||
<span>{{ area }}</span>{% if not forloop.last %} / {% endif %}
|
|
||||||
{% endfor %}
|
|
||||||
{% endif %}</div>
|
|
||||||
<div>{% if item.language %}{% trans '语言:' %}
|
|
||||||
{% for language in item.language %}
|
|
||||||
<span>{{ language }}</span>{% if not forloop.last %} / {% endif %}
|
|
||||||
{% endfor %}
|
|
||||||
{% endif %}</div>
|
|
||||||
|
|
||||||
|
</script>
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
{% if item.genre %}
|
||||||
|
{% trans '类型:' %}
|
||||||
|
{% for genre in item.genre %}
|
||||||
|
<span>{{ genre }}</span>
|
||||||
|
{% if not forloop.last %}/{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
{% if item.area %}
|
||||||
|
{% trans '制片国家/地区:' %}
|
||||||
|
{% for area in item.area %}
|
||||||
|
<span>{{ area }}</span>
|
||||||
|
{% if not forloop.last %}/{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
{% if item.language %}
|
||||||
|
{% trans '语言:' %}
|
||||||
|
{% for language in item.language %}
|
||||||
|
<span>{{ language }}</span>
|
||||||
|
{% if not forloop.last %}/{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
{% if item.season_number %}
|
||||||
|
{% trans '本季序号:' %}{{ item.season_number }}
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
{% if item.episode_count %}
|
||||||
|
{% trans '本季集数:' %}{{ item.episode_count }}
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
<div></div>
|
||||||
|
<div>
|
||||||
|
{% if item.show %}
|
||||||
|
{% trans '所属剧集:' %}<a href="{{ item.show.url }}">{{ item.show.title }}
|
||||||
|
{% endif %}
|
||||||
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="entity-detail__fields">
|
<div>
|
||||||
<div>{% if item.season_number %}{% trans '本季序号:' %}{{ item.season_number }}{% endif %}</div>
|
{% if item.season_count %}
|
||||||
<div>{% if item.episode_count %}{% trans '本季集数:' %}{{ item.episode_count }}{% endif %}</div>
|
{% trans '总季数:' %}{{ item.season_count }}
|
||||||
<div> </div>
|
{% endif %}
|
||||||
<div>{% if item.show %}{% trans '所属剧集:' %}<a href="{{ item.show.url }}">{{ item.show.title }}{% endif %}</a></div>
|
</div>
|
||||||
<div>{% if item.season_count %}{% trans '总季数:' %}{{ item.season_count }}{% endif %}</div>
|
<div>
|
||||||
<div>{% if item.single_episode_length %}{% trans '单集长度:' %}{{ item.single_episode_length }}{% endif %}</div>
|
{% if item.single_episode_length %}
|
||||||
{% with item.all_seasons as seasons %}
|
{% trans '单集长度:' %}{{ item.single_episode_length }}
|
||||||
{% if seasons %}
|
{% endif %}
|
||||||
<div>
|
</div>
|
||||||
{% trans '本剧所有季:' %}
|
{% with item.all_seasons as seasons %}
|
||||||
{% for s in seasons %}
|
{% if seasons %}
|
||||||
<span>
|
<div>
|
||||||
<a href="{{ s.url }}">{{ s.season_number }}</a>
|
{% trans '本剧所有季:' %}
|
||||||
</span>
|
{% for s in seasons %}
|
||||||
|
<span>
|
||||||
|
<a href="{{ s.url }}">{{ s.season_number }}</a>
|
||||||
|
</span>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
{% endwith %}
|
||||||
|
<div>
|
||||||
|
{% if item.showtime %}
|
||||||
|
{% trans '上映时间:' %}
|
||||||
|
{% for showtime in item.showtime %}
|
||||||
|
{% for time, region in showtime.items %}
|
||||||
|
<span>{{ time }}
|
||||||
|
{% if region != '' %}({{ region }}){% endif %}
|
||||||
|
</span>
|
||||||
|
{% endfor %}
|
||||||
|
{% if not forloop.last %}/{% endif %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</div>
|
{% endif %}
|
||||||
{% endif %}
|
|
||||||
{% endwith %}
|
|
||||||
|
|
||||||
<div>{% if item.showtime %}{% trans '上映时间:' %}
|
|
||||||
{% for showtime in item.showtime %}
|
|
||||||
{% for time, region in showtime.items %}
|
|
||||||
<span>{{ time }}{% if region != '' %}({{ region }}){% endif %}</span>
|
|
||||||
{% endfor %}
|
|
||||||
{% if not forloop.last %} / {% endif %}
|
|
||||||
{% endfor %}
|
|
||||||
{% endif %}</div>
|
|
||||||
<div>{% if item.other_title %}{% trans '又名:' %}
|
|
||||||
{% for t in item.other_title %}
|
|
||||||
<span>{{ t }}</span>{% if not forloop.last %} / {% endif %}
|
|
||||||
{% endfor %}
|
|
||||||
{% endif %}</div>
|
|
||||||
<div>{% if item.site %}{% trans '网站:' %}
|
|
||||||
<a href="{{ item.site }}" target="_blank" rel="noopener">{{ item.site|strip_scheme }}</a>
|
|
||||||
{% endif %}</div>
|
|
||||||
{% if item.other_info %}
|
|
||||||
{% for k, v in item.other_info.items %}
|
|
||||||
<div>
|
|
||||||
{{ k }}:{{ v | urlize }}
|
|
||||||
</div>
|
|
||||||
{% endfor %}
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
|
|
||||||
{% if item.last_editor and item.last_editor.preference.show_last_edit %}
|
|
||||||
<div>{% trans '最近编辑者:' %}<a href="{% url 'journal:user_profile' item.last_editor.mastodon_username %}">{{ item.last_editor | default:"" }}</a></div>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
<div>
|
|
||||||
{% if user.is_authenticated %}
|
|
||||||
<a href="{% url 'catalog:edit' item.url_path item.uuid %}">{% trans '编辑' %}{{ item.demonstrative }}</a>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
<div>
|
||||||
|
{% if item.other_title %}
|
||||||
|
{% trans '又名:' %}
|
||||||
|
{% for t in item.other_title %}
|
||||||
|
<span>{{ t }}</span>
|
||||||
|
{% if not forloop.last %}/{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
{% if item.site %}
|
||||||
|
{% trans '网站:' %}
|
||||||
|
<a href="{{ item.site }}" target="_blank" rel="noopener">{{ item.site|strip_scheme }}</a>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
{% if item.other_info %}
|
||||||
|
{% for k, v in item.other_info.items %}<div>{{ k }}:{{ v|urlizetrunc:24 }}</div>{% endfor %}
|
||||||
|
{% endif %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
<!-- class specific sidebar -->
|
<!-- class specific sidebar -->
|
||||||
{% block sidebar %}
|
{% block sidebar %}{% endblock %}
|
||||||
{% endblock %}
|
|
||||||
|
|
|
@ -9,179 +9,167 @@
|
||||||
{% load truncate %}
|
{% load truncate %}
|
||||||
{% load strip_scheme %}
|
{% load strip_scheme %}
|
||||||
{% load thumb %}
|
{% load thumb %}
|
||||||
|
|
||||||
{% block title %}
|
|
||||||
<h5 class="entity-detail__title">
|
|
||||||
{% if item.season_number %}
|
|
||||||
{{ item.title }} {% trans '第' %}{{ item.season_number|apnumber }}{% trans '季' %} {{ item.orig_title }} Season {{ item.season_number }}
|
|
||||||
<span class="entity-detail__title entity-detail__title--secondary">
|
|
||||||
{% if item.year %}({{ item.year }}){% endif %}
|
|
||||||
</span>
|
|
||||||
{% else %}
|
|
||||||
{{ item.title }} {{ item.orig_title }}
|
|
||||||
<span class="entity-detail__title entity-detail__title--secondary">
|
|
||||||
{% if item.year %}({{ item.year }}){% endif %}
|
|
||||||
</span>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
{% for res in item.external_resources.all %}
|
|
||||||
<a href="{{ res.url }}">
|
|
||||||
<span class="source-label source-label__{{ res.site_name }}">{{ res.site_name.label }}</span>
|
|
||||||
</a>
|
|
||||||
{% endfor %}
|
|
||||||
</h5>
|
|
||||||
{% endblock %}
|
|
||||||
|
|
||||||
<!-- class specific details -->
|
<!-- class specific details -->
|
||||||
{% block details %}
|
{% block details %}
|
||||||
<div class="entity-detail__fields">
|
<div>
|
||||||
<div class="entity-detail__rating">
|
{% if item.imdb %}
|
||||||
{% if item.rating and item.rating_count >= 5 %}
|
{% trans 'IMDb:' %}<a href="https://www.imdb.com/title/{{ item.imdb }}/"
|
||||||
<span class="entity-detail__rating-star rating-star" data-rating-score="{{ item.rating | floatformat:0 }}"></span>
|
target="_blank"
|
||||||
<span class="entity-detail__rating-score"> {{ item.rating | floatformat:1 }} </span>
|
rel="noopener">{{ item.imdb }}</a>
|
||||||
<small>({{ item.rating_count }}人评分)</small>
|
{% endif %}
|
||||||
{% else %}
|
</div>
|
||||||
<span> {% trans '评分:评分人数不足' %}</span>
|
<div>
|
||||||
{% endif %}
|
{% if item.director %}
|
||||||
</div>
|
{% trans '导演:' %}
|
||||||
<div>{% if item.imdb %}
|
{% for director in item.director %}
|
||||||
{% trans 'IMDb:' %}<a href="https://www.imdb.com/title/{{ item.imdb }}/" target="_blank" rel="noopener">{{ item.imdb }}</a>
|
<span {% if forloop.counter > 5 %}style="display: none;"{% endif %}>
|
||||||
{% endif %}
|
<span class="director">{{ director }}</span>
|
||||||
</div>
|
{% if not forloop.last %}/{% endif %}
|
||||||
<div>{% if item.director %}{% trans '导演:' %}
|
</span>
|
||||||
{% for director in item.director %}
|
{% endfor %}
|
||||||
<span {% if forloop.counter > 5 %}style="display: none;" {% endif %}>
|
{% if item.director|length > 5 %}
|
||||||
<span class="director">{{ director }}</span>
|
<a href="javascript:void(0);" id="directorMore">{% trans '更多' %}</a>
|
||||||
{% if not forloop.last %} / {% endif %}
|
<script>
|
||||||
</span>
|
|
||||||
{% endfor %}
|
|
||||||
{% if item.director|length > 5 %}
|
|
||||||
<a href="javascript:void(0);" id="directorMore">{% trans '更多' %}</a>
|
|
||||||
<script>
|
|
||||||
$("#directorMore").on('click', function (e) {
|
$("#directorMore").on('click', function (e) {
|
||||||
$("span.director:not(:visible)").each(function (e) {
|
$("span.director:not(:visible)").each(function (e) {
|
||||||
$(this).parent().removeAttr('style');
|
$(this).parent().removeAttr('style');
|
||||||
});
|
});
|
||||||
$(this).remove();
|
$(this).remove();
|
||||||
})
|
})
|
||||||
</script>
|
|
||||||
{% endif %}
|
</script>
|
||||||
{% endif %}</div>
|
{% endif %}
|
||||||
<div>{% if item.playwright %}{% trans '编剧:' %}
|
{% endif %}
|
||||||
{% for playwright in item.playwright %}
|
</div>
|
||||||
<span {% if forloop.counter > 5 %}style="display: none;" {% endif %}>
|
<div>
|
||||||
<span class="playwright">{{ playwright }}</span>
|
{% if item.playwright %}
|
||||||
{% if not forloop.last %} / {% endif %}
|
{% trans '编剧:' %}
|
||||||
</span>
|
{% for playwright in item.playwright %}
|
||||||
{% endfor %}
|
<span {% if forloop.counter > 5 %}style="display: none;"{% endif %}>
|
||||||
{% if item.playwright|length > 5 %}
|
<span class="playwright">{{ playwright }}</span>
|
||||||
<a href="javascript:void(0);" id="playwrightMore">{% trans '更多' %}</a>
|
{% if not forloop.last %}/{% endif %}
|
||||||
<script>
|
</span>
|
||||||
|
{% endfor %}
|
||||||
|
{% if item.playwright|length > 5 %}
|
||||||
|
<a href="javascript:void(0);" id="playwrightMore">{% trans '更多' %}</a>
|
||||||
|
<script>
|
||||||
$("#playwrightMore").on('click', function (e) {
|
$("#playwrightMore").on('click', function (e) {
|
||||||
$("span.playwright:not(:visible)").each(function (e) {
|
$("span.playwright:not(:visible)").each(function (e) {
|
||||||
$(this).parent().removeAttr('style');
|
$(this).parent().removeAttr('style');
|
||||||
});
|
});
|
||||||
$(this).remove();
|
$(this).remove();
|
||||||
})
|
})
|
||||||
</script>
|
|
||||||
{% endif %}
|
|
||||||
{% endif %}</div>
|
|
||||||
<div>{% if item.actor %}{% trans '主演:' %}
|
|
||||||
{% for actor in item.actor %}
|
|
||||||
<span {% if forloop.counter > 5 %}style="display: none;"{% endif %}>
|
|
||||||
<span class="actor">{{ actor }}</span>
|
|
||||||
{% if not forloop.last %} / {% endif %}
|
|
||||||
</span>
|
|
||||||
{% endfor %}
|
|
||||||
|
|
||||||
{% if item.actor|length > 5 %}
|
</script>
|
||||||
<a href="javascript:void(0);" id="actorMore">{% trans '更多' %}</a>
|
{% endif %}
|
||||||
<script>
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
{% if item.actor %}
|
||||||
|
{% trans '主演:' %}
|
||||||
|
{% for actor in item.actor %}
|
||||||
|
<span {% if forloop.counter > 5 %}style="display: none;"{% endif %}>
|
||||||
|
<span class="actor">{{ actor }}</span>
|
||||||
|
{% if not forloop.last %}/{% endif %}
|
||||||
|
</span>
|
||||||
|
{% endfor %}
|
||||||
|
{% if item.actor|length > 5 %}
|
||||||
|
<a href="javascript:void(0);" id="actorMore">{% trans '更多' %}</a>
|
||||||
|
<script>
|
||||||
$("#actorMore").on('click', function(e) {
|
$("#actorMore").on('click', function(e) {
|
||||||
$("span.actor:not(:visible)").each(function(e){
|
$("span.actor:not(:visible)").each(function(e){
|
||||||
$(this).parent().removeAttr('style');
|
$(this).parent().removeAttr('style');
|
||||||
});
|
});
|
||||||
$(this).remove();
|
$(this).remove();
|
||||||
})
|
})
|
||||||
</script>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
{% endif %}</div>
|
</script>
|
||||||
<div>{% if item.genre %}{% trans '类型:' %}
|
{% endif %}
|
||||||
{% for genre in item.genre %}
|
{% endif %}
|
||||||
<span>{{ genre }}</span>{% if not forloop.last %} / {% endif %}
|
</div>
|
||||||
{% endfor %}
|
<div>
|
||||||
{% endif %}</div>
|
{% if item.genre %}
|
||||||
<div>{% if item.area %}{% trans '制片国家/地区:' %}
|
{% trans '类型:' %}
|
||||||
{% for area in item.area %}
|
{% for genre in item.genre %}
|
||||||
<span>{{ area }}</span>{% if not forloop.last %} / {% endif %}
|
<span>{{ genre }}</span>
|
||||||
{% endfor %}
|
{% if not forloop.last %}/{% endif %}
|
||||||
{% endif %}</div>
|
{% endfor %}
|
||||||
<div>{% if item.language %}{% trans '语言:' %}
|
{% endif %}
|
||||||
{% for language in item.language %}
|
</div>
|
||||||
<span>{{ language }}</span>{% if not forloop.last %} / {% endif %}
|
<div>
|
||||||
{% endfor %}
|
{% if item.area %}
|
||||||
{% endif %}</div>
|
{% trans '制片国家/地区:' %}
|
||||||
|
{% for area in item.area %}
|
||||||
</div>
|
<span>{{ area }}</span>
|
||||||
<div class="entity-detail__fields">
|
{% if not forloop.last %}/{% endif %}
|
||||||
<div>{% if item.season_count %}{% trans '季数:' %}{{ item.season_count }}{% endif %}</div>
|
{% endfor %}
|
||||||
<div>{% if item.episode_count %}{% trans '集数:' %}{{ item.episode_count }}{% endif %}</div>
|
{% endif %}
|
||||||
<div>{% if item.single_episode_length %}{% trans '单集长度:' %}{{ item.single_episode_length }}{% endif %}</div>
|
</div>
|
||||||
|
<div>
|
||||||
{% with item.all_seasons as seasons %}
|
{% if item.language %}
|
||||||
{% if seasons %}
|
{% trans '语言:' %}
|
||||||
<div>
|
{% for language in item.language %}
|
||||||
{% trans '本剧所有季:' %}
|
<span>{{ language }}</span>
|
||||||
{% for s in seasons %}
|
{% if not forloop.last %}/{% endif %}
|
||||||
<span>
|
{% endfor %}
|
||||||
<a href="{{ s.url }}">{{ s.season_number }}</a>
|
{% endif %}
|
||||||
</span>
|
</div>
|
||||||
{% endfor %}
|
<div>
|
||||||
</div>
|
{% if item.season_count %}
|
||||||
{% endif %}
|
{% trans '季数:' %}{{ item.season_count }}
|
||||||
{% endwith %}
|
{% endif %}
|
||||||
|
</div>
|
||||||
<div>{% if item.showtime %}{% trans '播出时间:' %}
|
<div>
|
||||||
{% for showtime in item.showtime %}
|
{% if item.episode_count %}
|
||||||
{% for time, region in showtime.items %}
|
{% trans '集数:' %}{{ item.episode_count }}
|
||||||
<span>{{ time }}{% if region != '' %}({{ region }}){% endif %}</span>
|
{% endif %}
|
||||||
{% endfor %}
|
</div>
|
||||||
{% if not forloop.last %} / {% endif %}
|
<div>
|
||||||
{% endfor %}
|
{% if item.single_episode_length %}
|
||||||
{% endif %}</div>
|
{% trans '单集长度:' %}{{ item.single_episode_length }}
|
||||||
<div>{% if item.other_title %}{% trans '又名:' %}
|
{% endif %}
|
||||||
{% for t in item.other_title %}
|
</div>
|
||||||
<span>{{ t }}</span>{% if not forloop.last %} / {% endif %}
|
{% with item.all_seasons as seasons %}
|
||||||
{% endfor %}
|
{% if seasons %}
|
||||||
{% endif %}</div>
|
<div>
|
||||||
<div>{% if item.site %}{% trans '网站:' %}
|
{% trans '本剧所有季:' %}
|
||||||
<a href="{{ item.site }}" target="_blank" rel="noopener">{{ item.site|strip_scheme }}</a>
|
{% for s in seasons %}
|
||||||
{% endif %}</div>
|
<span>
|
||||||
{% if item.other_info %}
|
<a href="{{ s.url }}">{{ s.season_number }}</a>
|
||||||
{% for k, v in item.other_info.items %}
|
</span>
|
||||||
<div>
|
{% endfor %}
|
||||||
{{ k }}:{{ v | urlize }}
|
</div>
|
||||||
</div>
|
{% endif %}
|
||||||
{% endfor %}
|
{% endwith %}
|
||||||
{% endif %}
|
<div>
|
||||||
|
{% if item.showtime %}
|
||||||
|
{% trans '播出时间:' %}
|
||||||
{% if item.last_editor and item.last_editor.preference.show_last_edit %}
|
{% for showtime in item.showtime %}
|
||||||
<div>{% trans '最近编辑者:' %}<a href="{% url 'journal:user_profile' item.last_editor.mastodon_username %}">{{ item.last_editor | default:"" }}</a></div>
|
{% for time, region in showtime.items %}
|
||||||
{% endif %}
|
<span>{{ time }}
|
||||||
|
{% if region != '' %}({{ region }}){% endif %}
|
||||||
<div>
|
</span>
|
||||||
{% if user.is_authenticated %}
|
{% endfor %}
|
||||||
<a href="{% url 'catalog:edit' item.url_path item.uuid %}">{% trans '编辑' %}{{ item.demonstrative }}</a>
|
{% if not forloop.last %}/{% endif %}
|
||||||
{% endif %}
|
{% endfor %}
|
||||||
{% if user.is_staff %}
|
{% endif %}
|
||||||
/<a href="{% url 'catalog:delete' item.url_path item.uuid %}"> {% trans '删除' %}</a>
|
</div>
|
||||||
{% endif %}
|
<div>
|
||||||
</div>
|
{% if item.other_title %}
|
||||||
</div>
|
{% trans '又名:' %}
|
||||||
{% endblock %}
|
{% for t in item.other_title %}
|
||||||
|
<span>{{ t }}</span>
|
||||||
<!-- class specific sidebar -->
|
{% if not forloop.last %}/{% endif %}
|
||||||
{% block sidebar %}
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
{% if item.site %}
|
||||||
|
{% trans '网站:' %}
|
||||||
|
<a href="{{ item.site }}" target="_blank" rel="noopener">{{ item.site|strip_scheme }}</a>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
{% if item.other_info %}
|
||||||
|
{% for k, v in item.other_info.items %}<div>{{ k }}:{{ v|urlizetrunc:24 }}</div>{% endfor %}
|
||||||
|
{% endif %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
@ -9,11 +9,7 @@
|
||||||
{% load truncate %}
|
{% load truncate %}
|
||||||
{% load strip_scheme %}
|
{% load strip_scheme %}
|
||||||
{% load thumb %}
|
{% load thumb %}
|
||||||
|
|
||||||
<!-- class specific details -->
|
<!-- class specific details -->
|
||||||
{% block details %}
|
{% block details %}{% endblock %}
|
||||||
{% endblock %}
|
|
||||||
|
|
||||||
<!-- class specific sidebar -->
|
<!-- class specific sidebar -->
|
||||||
{% block sidebar %}
|
{% block sidebar %}{% endblock %}
|
||||||
{% endblock %}
|
|
||||||
|
|
|
@ -72,10 +72,24 @@ urlpatterns = [
|
||||||
recast,
|
recast,
|
||||||
name="recast",
|
name="recast",
|
||||||
),
|
),
|
||||||
|
re_path(
|
||||||
|
r"^(?P<item_path>"
|
||||||
|
+ _get_all_url_paths()
|
||||||
|
+ ")/(?P<item_uuid>[A-Za-z0-9]{21,22})/comments",
|
||||||
|
comments,
|
||||||
|
name="comments",
|
||||||
|
),
|
||||||
re_path(
|
re_path(
|
||||||
r"^(?P<item_path>"
|
r"^(?P<item_path>"
|
||||||
+ _get_all_url_paths()
|
+ _get_all_url_paths()
|
||||||
+ ")/(?P<item_uuid>[A-Za-z0-9]{21,22})/reviews",
|
+ ")/(?P<item_uuid>[A-Za-z0-9]{21,22})/reviews",
|
||||||
|
reviews,
|
||||||
|
name="reviews",
|
||||||
|
),
|
||||||
|
re_path(
|
||||||
|
r"^(?P<item_path>"
|
||||||
|
+ _get_all_url_paths()
|
||||||
|
+ ")/(?P<item_uuid>[A-Za-z0-9]{21,22})/review_list",
|
||||||
review_list,
|
review_list,
|
||||||
name="review_list",
|
name="review_list",
|
||||||
),
|
),
|
||||||
|
|
136
catalog/views.py
136
catalog/views.py
|
@ -11,7 +11,7 @@ from django.core.paginator import Paginator
|
||||||
from catalog.common.models import ExternalResource, IdealIdTypes
|
from catalog.common.models import ExternalResource, IdealIdTypes
|
||||||
from .models import *
|
from .models import *
|
||||||
from django.views.decorators.clickjacking import xframe_options_exempt
|
from django.views.decorators.clickjacking import xframe_options_exempt
|
||||||
from journal.models import Mark, ShelfMember, Review, query_item_category
|
from journal.models import Mark, ShelfMember, Review, Comment, query_item_category
|
||||||
from journal.models import (
|
from journal.models import (
|
||||||
query_visible,
|
query_visible,
|
||||||
query_following,
|
query_following,
|
||||||
|
@ -85,32 +85,28 @@ def retrieve(request, item_path, item_uuid):
|
||||||
)
|
)
|
||||||
mark = None
|
mark = None
|
||||||
review = None
|
review = None
|
||||||
mark_list = None
|
my_collections = []
|
||||||
review_list = None
|
|
||||||
collection_list = []
|
collection_list = []
|
||||||
shelf_types = [(n[1], n[2]) for n in iter(ShelfTypeNames) if n[0] == item.category]
|
shelf_types = [(n[1], n[2]) for n in iter(ShelfTypeNames) if n[0] == item.category]
|
||||||
if request.user.is_authenticated:
|
if request.user.is_authenticated:
|
||||||
visible = query_visible(request.user)
|
visible = query_visible(request.user)
|
||||||
mark = Mark(request.user, item)
|
mark = Mark(request.user, item)
|
||||||
review = mark.review
|
review = mark.review
|
||||||
|
my_collections = item.collections.all().filter(owner=request.user)
|
||||||
collection_list = (
|
collection_list = (
|
||||||
item.collections.all()
|
item.collections.all()
|
||||||
|
.exclude(owner=request.user)
|
||||||
.filter(visible)
|
.filter(visible)
|
||||||
.annotate(like_counts=Count("likes"))
|
.annotate(like_counts=Count("likes"))
|
||||||
.order_by("-like_counts")
|
.order_by("-like_counts")
|
||||||
)
|
)
|
||||||
mark_query = (
|
else:
|
||||||
ShelfMember.objects.filter(item=item)
|
collection_list = (
|
||||||
.filter(visible)
|
item.collections.all()
|
||||||
.order_by("-created_time")
|
.filter(visibility=0)
|
||||||
|
.annotate(like_counts=Count("likes"))
|
||||||
|
.order_by("-like_counts")
|
||||||
)
|
)
|
||||||
mark_list = [member.mark for member in mark_query[:NUM_REVIEWS_ON_ITEM_PAGE]]
|
|
||||||
review_list = (
|
|
||||||
Review.objects.filter(item=item)
|
|
||||||
.filter(visible)
|
|
||||||
.order_by("-created_time")[:NUM_REVIEWS_ON_ITEM_PAGE]
|
|
||||||
)
|
|
||||||
|
|
||||||
return render(
|
return render(
|
||||||
request,
|
request,
|
||||||
item.class_name + ".html",
|
item.class_name + ".html",
|
||||||
|
@ -119,8 +115,7 @@ def retrieve(request, item_path, item_uuid):
|
||||||
"focus_item": focus_item,
|
"focus_item": focus_item,
|
||||||
"mark": mark,
|
"mark": mark,
|
||||||
"review": review,
|
"review": review,
|
||||||
"mark_list": mark_list,
|
"my_collections": my_collections,
|
||||||
"review_list": review_list,
|
|
||||||
"collection_list": collection_list,
|
"collection_list": collection_list,
|
||||||
"shelf_types": shelf_types,
|
"shelf_types": shelf_types,
|
||||||
},
|
},
|
||||||
|
@ -273,7 +268,7 @@ def episode_data(request, item_uuid):
|
||||||
if request.GET.get("last"):
|
if request.GET.get("last"):
|
||||||
qs = qs.filter(pub_date__lt=request.GET.get("last"))
|
qs = qs.filter(pub_date__lt=request.GET.get("last"))
|
||||||
return render(
|
return render(
|
||||||
request, "podcast_episode_data.html", {"item": item, "episodes": qs[:10]}
|
request, "podcast_episode_data.html", {"item": item, "episodes": qs[:5]}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -326,27 +321,62 @@ def review_list(request, item_path, item_uuid):
|
||||||
|
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
|
def comments(request, item_path, item_uuid):
|
||||||
|
item = get_object_or_404(Item, uid=get_uuid_or_404(item_uuid))
|
||||||
|
if not item:
|
||||||
|
raise Http404()
|
||||||
|
queryset = Comment.objects.filter(item=item).order_by("-created_time")
|
||||||
|
queryset = queryset.filter(query_visible(request.user))
|
||||||
|
before_time = request.GET.get("last")
|
||||||
|
if before_time:
|
||||||
|
queryset = queryset.filter(created_time__lte=before_time)
|
||||||
|
return render(
|
||||||
|
request,
|
||||||
|
"item_comments.html",
|
||||||
|
{
|
||||||
|
"comments": queryset[:11],
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@login_required
|
||||||
|
def reviews(request, item_path, item_uuid):
|
||||||
|
item = get_object_or_404(Item, uid=get_uuid_or_404(item_uuid))
|
||||||
|
if not item:
|
||||||
|
raise Http404()
|
||||||
|
queryset = Review.objects.filter(item=item).order_by("-created_time")
|
||||||
|
queryset = queryset.filter(query_visible(request.user))
|
||||||
|
before_time = request.GET.get("last")
|
||||||
|
if before_time:
|
||||||
|
queryset = queryset.filter(created_time__lte=before_time)
|
||||||
|
return render(
|
||||||
|
request,
|
||||||
|
"item_reviews.html",
|
||||||
|
{
|
||||||
|
"reviews": queryset[:11],
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def discover(request):
|
def discover(request):
|
||||||
if request.method != "GET":
|
if request.method != "GET":
|
||||||
raise BadRequest()
|
raise BadRequest()
|
||||||
user = request.user
|
user = request.user
|
||||||
if user.is_authenticated:
|
if user.is_authenticated:
|
||||||
layout = user.get_preference().discover_layout
|
layout = user.get_preference().discover_layout
|
||||||
top_tags = user.tag_manager.all_tags[:10]
|
|
||||||
else:
|
else:
|
||||||
layout = []
|
layout = []
|
||||||
top_tags = []
|
|
||||||
|
|
||||||
cache_key = "public_gallery_list"
|
cache_key = "public_gallery"
|
||||||
gallery_list = cache.get(cache_key, [])
|
gallery_list = cache.get(cache_key, [])
|
||||||
|
|
||||||
for gallery in gallery_list:
|
# for gallery in gallery_list:
|
||||||
ids = (
|
# ids = (
|
||||||
random.sample(gallery["item_ids"], 10)
|
# random.sample(gallery["item_ids"], 10)
|
||||||
if len(gallery["item_ids"]) > 10
|
# if len(gallery["item_ids"]) > 10
|
||||||
else gallery["item_ids"]
|
# else gallery["item_ids"]
|
||||||
)
|
# )
|
||||||
gallery["items"] = Item.objects.filter(id__in=ids)
|
# gallery["items"] = Item.objects.filter(id__in=ids)
|
||||||
|
|
||||||
if user.is_authenticated:
|
if user.is_authenticated:
|
||||||
podcast_ids = [
|
podcast_ids = [
|
||||||
|
@ -355,41 +385,39 @@ def discover(request):
|
||||||
ShelfType.PROGRESS, ItemCategory.Podcast
|
ShelfType.PROGRESS, ItemCategory.Podcast
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
episodes = PodcastEpisode.objects.filter(program_id__in=podcast_ids).order_by(
|
recent_podcast_episodes = PodcastEpisode.objects.filter(
|
||||||
"-pub_date"
|
program_id__in=podcast_ids
|
||||||
)[:5]
|
).order_by("-pub_date")[:10]
|
||||||
gallery_list.insert(
|
books_in_progress = Edition.objects.filter(
|
||||||
0,
|
id__in=[
|
||||||
{
|
p.item_id
|
||||||
"name": "my_recent_podcasts",
|
for p in user.shelf_manager.get_members(
|
||||||
"title": "在听播客的近期更新",
|
ShelfType.PROGRESS, ItemCategory.Book
|
||||||
"items": episodes,
|
).order_by("-created_time")[:10]
|
||||||
},
|
]
|
||||||
)
|
)
|
||||||
# books = Edition.objects.filter(
|
tvshows_in_progress = Item.objects.filter(
|
||||||
# id__in=[
|
id__in=[
|
||||||
# p.item_id
|
p.item_id
|
||||||
# for p in user.shelf_manager.get_members(
|
for p in user.shelf_manager.get_members(
|
||||||
# ShelfType.PROGRESS, ItemCategory.Book
|
ShelfType.PROGRESS, ItemCategory.TV
|
||||||
# ).order_by("-created_time")[:10]
|
).order_by("-created_time")[:10]
|
||||||
# ]
|
]
|
||||||
# )
|
)
|
||||||
# gallery_list.insert(
|
else:
|
||||||
# 0,
|
recent_podcast_episodes = []
|
||||||
# {
|
books_in_progress = []
|
||||||
# "name": "my_books_inprogress",
|
tvshows_in_progress = []
|
||||||
# "title": "正在读的书",
|
|
||||||
# "items": books,
|
|
||||||
# },
|
|
||||||
# )
|
|
||||||
|
|
||||||
return render(
|
return render(
|
||||||
request,
|
request,
|
||||||
"discover.html",
|
"discover.html",
|
||||||
{
|
{
|
||||||
"user": user,
|
"user": user,
|
||||||
"top_tags": top_tags,
|
|
||||||
"gallery_list": gallery_list,
|
"gallery_list": gallery_list,
|
||||||
|
"recent_podcast_episodes": recent_podcast_episodes,
|
||||||
|
"books_in_progress": books_in_progress,
|
||||||
|
"tvshows_in_progress": tvshows_in_progress,
|
||||||
"layout": layout,
|
"layout": layout,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
|
@ -26,6 +26,5 @@
|
||||||
|
|
||||||
.wday, .month {
|
.wday, .month {
|
||||||
font-variant: small-caps;
|
font-variant: small-caps;
|
||||||
color: #222222;
|
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
}
|
}
|
||||||
|
|
|
@ -180,8 +180,8 @@ div.jsoneditor-menu {
|
||||||
}
|
}
|
||||||
|
|
||||||
.donut {
|
.donut {
|
||||||
margin-left: 20%;
|
margin-left: 10%;
|
||||||
width: 60%;
|
width: 80%;
|
||||||
aspect-ratio : 1 / 1;
|
aspect-ratio : 1 / 1;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
@ -198,7 +198,7 @@ div.jsoneditor-menu {
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
progress {
|
/* progress {
|
||||||
border-radius: 7px;
|
border-radius: 7px;
|
||||||
width: 80%;
|
width: 80%;
|
||||||
height: 10px;
|
height: 10px;
|
||||||
|
@ -209,7 +209,7 @@ progress {
|
||||||
}
|
}
|
||||||
::-webkit-progress-value {
|
::-webkit-progress-value {
|
||||||
background-color: #00a1cc;
|
background-color: #00a1cc;
|
||||||
}
|
} */
|
||||||
|
|
||||||
.markdownx-editor {
|
.markdownx-editor {
|
||||||
font-family: monospace;
|
font-family: monospace;
|
||||||
|
@ -266,6 +266,6 @@ summary::-webkit-details-marker {
|
||||||
transform: rotate(360deg);
|
transform: rotate(360deg);
|
||||||
}
|
}
|
||||||
|
|
||||||
.fa-lock, .fa-spin {
|
.action-bar .fa-lock, .fa-spin {
|
||||||
color: lightgray;
|
color: lightgray;
|
||||||
}
|
}
|
||||||
|
|
|
@ -167,7 +167,7 @@
|
||||||
|
|
||||||
// Fixed size with width= 721 and height = 110
|
// Fixed size with width= 721 and height = 110
|
||||||
var wire_html =
|
var wire_html =
|
||||||
'<svg width="721" height="110">' +
|
'<svg width="700" height="100">' +
|
||||||
'<g transform="translate(0, 20)">' +
|
'<g transform="translate(0, 20)">' +
|
||||||
loop_html +
|
loop_html +
|
||||||
'</g>' + '"Your browser does not support inline SVG."' +
|
'</g>' + '"Your browser does not support inline SVG."' +
|
||||||
|
|
15
common/static/sass/_common.sass
Normal file
15
common/static/sass/_common.sass
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
|
||||||
|
@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
|
48
common/static/scss/_card.scss
Normal file
48
common/static/scss/_card.scss
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
div.item {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns:
|
||||||
|
calc(4rem * var(--pico-line-height)) auto;
|
||||||
|
column-gap: var(--pico-block-spacing-horizontal);
|
||||||
|
align-items: top;
|
||||||
|
justify-content: left;
|
||||||
|
word-break: break-all;
|
||||||
|
|
||||||
|
&.player {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
hgroup {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
h5 small,
|
||||||
|
hgroup span {
|
||||||
|
font-weight: 400;
|
||||||
|
font-size: 80%;
|
||||||
|
color: var(--pico-muted-color);
|
||||||
|
|
||||||
|
&.category {
|
||||||
|
opacity: 0.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.metadata {
|
||||||
|
display: -webkit-box;
|
||||||
|
-webkit-line-clamp: 1;
|
||||||
|
-webkit-box-orient: vertical;
|
||||||
|
overflow: hidden;
|
||||||
|
font-size: 80%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.brief {
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
word-wrap: break-word;
|
||||||
|
overflow: hidden;
|
||||||
|
-webkit-line-clamp: 4;
|
||||||
|
display: -webkit-box;
|
||||||
|
-webkit-box-orient: vertical;
|
||||||
|
font-size: 80%;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
25
common/static/scss/_collection.scss
Normal file
25
common/static/scss/_collection.scss
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
#collection-page {
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
main>article>header {
|
||||||
|
display: flex;
|
||||||
|
flex-flow: column nowrap;
|
||||||
|
|
||||||
|
#collection-cover {
|
||||||
|
img {
|
||||||
|
height: 20vw;
|
||||||
|
}
|
||||||
|
|
||||||
|
height: unset !important;
|
||||||
|
order: -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#collection-feature {
|
||||||
|
order: 99;
|
||||||
|
|
||||||
|
.donut {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
95
common/static/scss/_common.scss
Normal file
95
common/static/scss/_common.scss
Normal file
|
@ -0,0 +1,95 @@
|
||||||
|
body {
|
||||||
|
--pico-block-spacing-vertical: var(--pico-block-spacing-horizontal);
|
||||||
|
}
|
||||||
|
|
||||||
|
article.item-card {
|
||||||
|
padding: calc(var(--pico-block-spacing-horizontal));
|
||||||
|
margin-bottom: calc(var(--pico-block-spacing-vertical) / 2);
|
||||||
|
|
||||||
|
header,
|
||||||
|
footer {
|
||||||
|
padding: calc(var(--pico-block-spacing-horizontal) / 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
section {
|
||||||
|
margin-bottom: calc(var(--pico-spacing) / 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
article.item-card.external h5 {
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
|
||||||
|
details {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
section section {
|
||||||
|
margin-bottom: var(--pico-spacing) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.empty {
|
||||||
|
font-style: italic;
|
||||||
|
font-size: 80%;
|
||||||
|
color: var(--pico-muted-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.oneline {
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
overflow: hidden;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.handler {
|
||||||
|
color: var(--pico-muted-color);
|
||||||
|
word-break: break-all;
|
||||||
|
opacity: 0.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.loading {
|
||||||
|
color: var(--pico-muted-color);
|
||||||
|
opacity: 0.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.action {
|
||||||
|
width: max-content;
|
||||||
|
float: right;
|
||||||
|
|
||||||
|
&.inline {
|
||||||
|
float: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
>span {
|
||||||
|
padding-left: calc(var(--pico-spacing)/2);
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
cursor: pointer;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
a.hidden {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
a.disabled,
|
||||||
|
.timestamp {
|
||||||
|
cursor: unset;
|
||||||
|
color: var(--pico-muted-color);
|
||||||
|
opacity: 0.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
a:not(:hover) {
|
||||||
|
color: var(--pico-muted-color);
|
||||||
|
opacity: 0.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
a.activated:not(:hover) {
|
||||||
|
color: var(--pico-primary);
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
form img {
|
||||||
|
max-height: 20vh;
|
||||||
|
}
|
103
common/static/scss/_dialog.scss
Normal file
103
common/static/scss/_dialog.scss
Normal file
|
@ -0,0 +1,103 @@
|
||||||
|
dialog {
|
||||||
|
header {
|
||||||
|
margin-bottom: 16px;
|
||||||
|
padding: 8px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
&>article {
|
||||||
|
/* Animate when opening */
|
||||||
|
animation-name: zoomIn;
|
||||||
|
animation-duration: 150ms;
|
||||||
|
animation-timing-function: ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.closing {
|
||||||
|
/* Animate when closing */
|
||||||
|
animation-name: fadeOut;
|
||||||
|
animation-duration: 150ms;
|
||||||
|
animation-timing-function: ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.closing>article {
|
||||||
|
/* Aniate when closing */
|
||||||
|
animation-name: zoomOut;
|
||||||
|
animation-duration: 150ms;
|
||||||
|
animation-timing-function: ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes fadeIn {
|
||||||
|
0% {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes fadeOut {
|
||||||
|
0% {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes zoomIn {
|
||||||
|
0% {
|
||||||
|
transform: scale(0.9);
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
transform: scale(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes zoomOut {
|
||||||
|
0% {
|
||||||
|
transform: scale(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
transform: scale(0.9);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.grid>div {
|
||||||
|
min-width: max-content;
|
||||||
|
}
|
||||||
|
|
||||||
|
.grid>div:nth-child(2) fieldset {
|
||||||
|
float: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.grid>div:nth-child(2) fieldset {
|
||||||
|
float: unset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fieldset {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
article {
|
||||||
|
padding-bottom: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type="date"] {
|
||||||
|
margin: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tag-input {
|
||||||
|
margin-bottom: var(--pico-spacing);
|
||||||
|
}
|
||||||
|
|
||||||
|
.rating-editor {
|
||||||
|
font-size: 120%;
|
||||||
|
padding-bottom: 1em;
|
||||||
|
}
|
||||||
|
}
|
63
common/static/scss/_feed.scss
Normal file
63
common/static/scss/_feed.scss
Normal file
|
@ -0,0 +1,63 @@
|
||||||
|
.feed-page {
|
||||||
|
.feed {
|
||||||
|
.avatar {
|
||||||
|
height: calc(1rem * var(--pico-line-height) + var(--pico-nav-link-spacing-vertical) * 4 - 8px);
|
||||||
|
width: calc(1rem * var(--pico-line-height) + var(--pico-nav-link-spacing-vertical) * 4 - 8px);
|
||||||
|
|
||||||
|
img {
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
section {
|
||||||
|
margin-bottom: 2vh;
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: auto 1fr;
|
||||||
|
grid-template-rows: auto;
|
||||||
|
grid-column-gap: 1em;
|
||||||
|
grid-row-gap: 0px;
|
||||||
|
// align-items: center;
|
||||||
|
// justify-content: left;
|
||||||
|
|
||||||
|
.nickname a {
|
||||||
|
word-break: break-all;
|
||||||
|
}
|
||||||
|
|
||||||
|
.time {
|
||||||
|
width: max-content;
|
||||||
|
float: right;
|
||||||
|
color: var(--pico-muted-color);
|
||||||
|
opacity: 0.5;
|
||||||
|
margin-left: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rating-star {
|
||||||
|
margin: 0 0.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rating-star,
|
||||||
|
.rating-star>* {
|
||||||
|
color: var(--pico-primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
article {
|
||||||
|
padding: calc(var(--pico-block-spacing-horizontal) / 2);
|
||||||
|
|
||||||
|
footer {
|
||||||
|
padding: calc(var(--pico-block-spacing-horizontal) / 2);
|
||||||
|
margin-left: calc(var(--pico-block-spacing-horizontal) * -0.5);
|
||||||
|
margin-right: calc(var(--pico-block-spacing-horizontal) * -0.5);
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
margin-right: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.spacing {
|
||||||
|
margin-bottom: var(--pico-block-spacing-horizontal);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
120
common/static/scss/_gallery.scss
Normal file
120
common/static/scss/_gallery.scss
Normal file
|
@ -0,0 +1,120 @@
|
||||||
|
.calendar_view {
|
||||||
|
overflow-x: scroll;
|
||||||
|
|
||||||
|
svg {
|
||||||
|
height: 108px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.shelf {
|
||||||
|
max-width: 1400px;
|
||||||
|
padding: 0;
|
||||||
|
|
||||||
|
* {
|
||||||
|
box-sizing: border-box;
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cards {
|
||||||
|
display: grid;
|
||||||
|
grid-auto-columns: 100%;
|
||||||
|
grid-column-gap: var(--pico-block-spacing-horizontal);
|
||||||
|
grid-auto-flow: column;
|
||||||
|
padding: var(--pico-nav-link-spacing-vertical) 0px;
|
||||||
|
list-style: none;
|
||||||
|
overflow-x: scroll;
|
||||||
|
scroll-snap-type: x mandatory;
|
||||||
|
|
||||||
|
&::-webkit-scrollbar {
|
||||||
|
height: var(--pico-nav-link-spacing-vertical);
|
||||||
|
}
|
||||||
|
|
||||||
|
&::-webkit-scrollbar-thumb,
|
||||||
|
&::-webkit-scrollbar-track {
|
||||||
|
border-radius: 92px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&::-webkit-scrollbar-thumb {
|
||||||
|
background: var(--pico-range-active-border-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
&::-webkit-scrollbar-track {
|
||||||
|
background: var(--pico-range-border-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.card {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
padding: 0px;
|
||||||
|
// border-radius: 5px;
|
||||||
|
scroll-snap-align: start;
|
||||||
|
transition: all 0.2s;
|
||||||
|
text-align: center;
|
||||||
|
vertical-align: middle;
|
||||||
|
|
||||||
|
a {
|
||||||
|
margin-top: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
img {
|
||||||
|
background: var(--pico-background-color);
|
||||||
|
// border-radius: 5px;
|
||||||
|
width: 100%;
|
||||||
|
min-height: 3rem;
|
||||||
|
vertical-align: middle;
|
||||||
|
margin: auto;
|
||||||
|
font-size: 80%;
|
||||||
|
border: 2px solid transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
a:hover img {
|
||||||
|
border: 2px solid var(--pico-primary-hover);
|
||||||
|
}
|
||||||
|
|
||||||
|
a>div {
|
||||||
|
font-size: 80%;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
word-wrap: break-word;
|
||||||
|
overflow: hidden;
|
||||||
|
-webkit-line-clamp: 2;
|
||||||
|
display: -webkit-box;
|
||||||
|
-webkit-box-orient: vertical;
|
||||||
|
min-height: 2.5rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 200px) {
|
||||||
|
.cards {
|
||||||
|
grid-auto-columns: calc(25% - var(--pico-block-spacing-horizontal));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 500px) {
|
||||||
|
.cards {
|
||||||
|
grid-auto-columns: calc(20% - var(--pico-block-spacing-horizontal));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 769px) {
|
||||||
|
.cards {
|
||||||
|
grid-auto-columns: calc(calc(100% / 6) - var(--pico-block-spacing-horizontal));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 1281px) {
|
||||||
|
.cards {
|
||||||
|
grid-auto-columns: calc(calc(100% / 8) - var(--pico-block-spacing-horizontal));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 769px) {
|
||||||
|
.sidebar .shelf .cards {
|
||||||
|
grid-auto-columns: calc(34% - var(--pico-spacing)) !important;
|
||||||
|
gap: var(--pico-spacing) !important;
|
||||||
|
}
|
||||||
|
}
|
220
common/static/scss/_header.scss
Normal file
220
common/static/scss/_header.scss
Normal file
|
@ -0,0 +1,220 @@
|
||||||
|
body>header {
|
||||||
|
padding: 0px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-logo {
|
||||||
|
margin-left: 8px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-dropdown {
|
||||||
|
margin-right: 8px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-dropdown ul li a {
|
||||||
|
padding: var(--pico-form-element-spacing-vertical) var(--pico-form-element-spacing-horizontal) !important
|
||||||
|
}
|
||||||
|
|
||||||
|
nav form {
|
||||||
|
margin-bottom: 0px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
nav summary {
|
||||||
|
border: 0px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
nav ul {
|
||||||
|
min-width: -webkit-max-content;
|
||||||
|
min-width: -moz-max-content;
|
||||||
|
}
|
||||||
|
|
||||||
|
nav ul li a.current {
|
||||||
|
font-weight: bold;
|
||||||
|
color: var(--pico-primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-search,
|
||||||
|
.nav-search li {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-search select {
|
||||||
|
max-width: max-content;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-search input[type="submit"] {
|
||||||
|
background-color: var(--pico-secondary-background);
|
||||||
|
border-color: var(--pico-secondary-background);
|
||||||
|
padding-left: calc(var(--pico-nav-link-spacing-horizontal)*2);
|
||||||
|
padding-right: calc(var(--pico-nav-link-spacing-horizontal)*2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-logo img {
|
||||||
|
max-height: 56px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.unhide {
|
||||||
|
display: unset !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-dropdown summary {
|
||||||
|
padding-top: 0px !important;
|
||||||
|
padding-bottom: 0px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-dropdown summary::after {
|
||||||
|
height: calc(1rem * var(--pico-line-height, 1.5) + 8px) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.avatar {
|
||||||
|
line-height: 0;
|
||||||
|
/* remove line-height */
|
||||||
|
display: inline-block;
|
||||||
|
/* circle wraps image */
|
||||||
|
border: 4px solid lightgray;
|
||||||
|
border-radius: 50%;
|
||||||
|
/* relative value */
|
||||||
|
transition: linear 0.25s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.avatar img {
|
||||||
|
border-radius: 50%;
|
||||||
|
height: calc(1rem * var(--pico-line-height) + var(--pico-nav-link-spacing-vertical) * 2 - 8px);
|
||||||
|
width: calc(1rem * var(--pico-line-height) + var(--pico-nav-link-spacing-vertical) * 2 - 8px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.avatar:hover {
|
||||||
|
transition: ease-out 0.2s;
|
||||||
|
border: 4px solid var(--pico-primary);
|
||||||
|
-webkit-transition: ease-out 0.2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 1200px) {
|
||||||
|
:root {
|
||||||
|
--pico-font-size: 80%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 769px) {
|
||||||
|
.small-only {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
:root {
|
||||||
|
--pico-font-size: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.large-only {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
body>header {
|
||||||
|
position: sticky;
|
||||||
|
top: 0px;
|
||||||
|
background: var(--pico-background-color);
|
||||||
|
z-index: 999;
|
||||||
|
box-shadow: var(--pico-box-shadow);
|
||||||
|
}
|
||||||
|
|
||||||
|
nav {
|
||||||
|
display: flex;
|
||||||
|
flex-flow: row wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-logo img {
|
||||||
|
max-height: 28px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-search {
|
||||||
|
order: 999;
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-search li {
|
||||||
|
padding: 0px;
|
||||||
|
padding-bottom: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-search input[type="submit"] {
|
||||||
|
padding-left: calc(var(--pico-nav-link-spacing-horizontal)*1);
|
||||||
|
padding-right: calc(var(--pico-nav-link-spacing-horizontal)*1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-dropdown::after {
|
||||||
|
flex-basis: 100%;
|
||||||
|
width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-dropdown {
|
||||||
|
margin-right: 0 !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Dark color scheme (Auto) */
|
||||||
|
/* Automatically enabled if user has Dark mode enabled */
|
||||||
|
@media only screen and (prefers-color-scheme: dark) {
|
||||||
|
.nav-logo img {
|
||||||
|
filter: brightness(100%) grayscale(100%) invert(40%);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Dark color scheme (Forced) */
|
||||||
|
/* Enabled if forced with data-theme="dark" */
|
||||||
|
.nav-logo img [data-theme="dark"] {
|
||||||
|
filter: brightness(100%) grayscale(100%) invert(40%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.tldr {
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: " ... [点击展开]";
|
||||||
|
display: -webkit-box;
|
||||||
|
-webkit-line-clamp: 10;
|
||||||
|
-webkit-box-orient: vertical;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tldr-2 {
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: " ... [点击展开]";
|
||||||
|
display: -webkit-box;
|
||||||
|
-webkit-line-clamp: 2;
|
||||||
|
-webkit-box-orient: vertical;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hidden {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.invisible {
|
||||||
|
visibility: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
a:not(:hover) {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
body>footer {
|
||||||
|
padding-top: 0.4em !important;
|
||||||
|
text-align: center;
|
||||||
|
margin-bottom: 4px !important;
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
.footer__border {
|
||||||
|
width: 100%;
|
||||||
|
padding-top: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer__link {
|
||||||
|
margin: 0 12px;
|
||||||
|
white-space: nowrap;
|
||||||
|
min-width: 15vw;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 769px) {
|
||||||
|
clear: both;
|
||||||
|
position: absolute !important;
|
||||||
|
left: 50%;
|
||||||
|
transform: translateX(-50%);
|
||||||
|
}
|
||||||
|
}
|
165
common/static/scss/_item.scss
Normal file
165
common/static/scss/_item.scss
Normal file
|
@ -0,0 +1,165 @@
|
||||||
|
#item-page {
|
||||||
|
a:not(:hover) {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.muted {
|
||||||
|
color: var(--pico-muted-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.muted a:not(:hover) {
|
||||||
|
color: var(--pico-muted-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.muted .fa-lock {
|
||||||
|
filter: brightness(50%) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
a>button {
|
||||||
|
padding: 2px 8px;
|
||||||
|
font-size: 75%;
|
||||||
|
}
|
||||||
|
|
||||||
|
main>div {
|
||||||
|
margin: 2vw;
|
||||||
|
}
|
||||||
|
|
||||||
|
main>div>section {
|
||||||
|
margin-bottom: 2vw;
|
||||||
|
}
|
||||||
|
|
||||||
|
#item-title {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#item-title-more {
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#item-title h1 {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 small {
|
||||||
|
font-size: 80%;
|
||||||
|
margin-left: 0.5vw;
|
||||||
|
font-weight: 400;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#item-cover {
|
||||||
|
align-items: stretch;
|
||||||
|
}
|
||||||
|
|
||||||
|
#item-cover img {
|
||||||
|
transition: transform 0.2s ease-in-out;
|
||||||
|
filter: drop-shadow(0 0.2rem 0.8rem rgba(0, 0, 0, 0.2));
|
||||||
|
max-width: 80%;
|
||||||
|
max-height: 50vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
.item-edit,
|
||||||
|
.item-edit a {
|
||||||
|
color: var(--pico-muted-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.item-action {
|
||||||
|
display: flex;
|
||||||
|
flex-flow: row wrap;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
margin-top: 5%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.item-action button {
|
||||||
|
margin-left: 4px;
|
||||||
|
margin-right: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mark {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
#item-cover {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
main {
|
||||||
|
padding-top: 1vh !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 769px) {
|
||||||
|
#item-title h1 {
|
||||||
|
display: inline;
|
||||||
|
}
|
||||||
|
|
||||||
|
.middle {
|
||||||
|
margin: auto;
|
||||||
|
width: 50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.left {
|
||||||
|
float: left;
|
||||||
|
clear: left;
|
||||||
|
width: 22%;
|
||||||
|
margin-left: 0;
|
||||||
|
margin-right: 3%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.right {
|
||||||
|
float: right;
|
||||||
|
clear: right;
|
||||||
|
width: 22%;
|
||||||
|
margin-left: 3%;
|
||||||
|
margin-right: 0%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
main {
|
||||||
|
display: flex;
|
||||||
|
flex-flow: column nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
#item-title {
|
||||||
|
order: -5;
|
||||||
|
display: flex;
|
||||||
|
flex-flow: column nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
#item-title .site-list {
|
||||||
|
order: -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#item-title-more {
|
||||||
|
order: -4;
|
||||||
|
}
|
||||||
|
|
||||||
|
#item-cover {
|
||||||
|
order: -3;
|
||||||
|
}
|
||||||
|
|
||||||
|
#item-primary-action {
|
||||||
|
order: -2;
|
||||||
|
}
|
||||||
|
|
||||||
|
#item-primary-mark {
|
||||||
|
order: -2;
|
||||||
|
}
|
||||||
|
|
||||||
|
#item-metadata {
|
||||||
|
order: -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#item-sidebar {
|
||||||
|
order: 99;
|
||||||
|
}
|
||||||
|
|
||||||
|
#item-cover img {
|
||||||
|
max-width: 60vw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
144
common/static/scss/_layout.scss
Normal file
144
common/static/scss/_layout.scss
Normal file
|
@ -0,0 +1,144 @@
|
||||||
|
.classic-page,
|
||||||
|
.feed-page {
|
||||||
|
main {
|
||||||
|
width: 100vw;
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 64% 32%;
|
||||||
|
grid-template-areas: "main aside";
|
||||||
|
gap: 4%;
|
||||||
|
padding: calc(3*var(--pico-spacing));
|
||||||
|
|
||||||
|
.grid__main {
|
||||||
|
grid-area: main;
|
||||||
|
}
|
||||||
|
|
||||||
|
.grid__aside {
|
||||||
|
grid-area: aside;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
main {
|
||||||
|
display: flex;
|
||||||
|
flex-flow: column nowrap;
|
||||||
|
padding: 0;
|
||||||
|
gap: 0;
|
||||||
|
|
||||||
|
.grid__main {
|
||||||
|
order: -1;
|
||||||
|
margin: var(--pico-spacing);
|
||||||
|
}
|
||||||
|
|
||||||
|
.grid__aside {
|
||||||
|
order: -2;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul {
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
aside.bottom {
|
||||||
|
order: 2 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.content-page {
|
||||||
|
article {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
main {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: auto 25%;
|
||||||
|
grid-template-areas: "main aside";
|
||||||
|
gap: calc(3*var(--pico-spacing));
|
||||||
|
padding: calc(3*var(--pico-spacing));
|
||||||
|
|
||||||
|
&>div {
|
||||||
|
grid-area: main;
|
||||||
|
}
|
||||||
|
|
||||||
|
&>aside {
|
||||||
|
grid-area: aside;
|
||||||
|
|
||||||
|
article>div {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.owner-info {
|
||||||
|
height: max-content;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
gap: var(--pico-spacing);
|
||||||
|
|
||||||
|
.owner {
|
||||||
|
.avatar {
|
||||||
|
width: calc(2rem * var(--pico-line-height));
|
||||||
|
height: calc(2rem * var(--pico-line-height));
|
||||||
|
|
||||||
|
img {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.info {
|
||||||
|
width: 70%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.more {
|
||||||
|
width: 20%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
main {
|
||||||
|
display: flex;
|
||||||
|
max-width: 100%;
|
||||||
|
flex-flow: column nowrap;
|
||||||
|
padding: 0;
|
||||||
|
gap: 0;
|
||||||
|
|
||||||
|
>div {
|
||||||
|
order: 1;
|
||||||
|
// margin: var(--pico-spacing);
|
||||||
|
}
|
||||||
|
|
||||||
|
>aside {
|
||||||
|
order: 2;
|
||||||
|
|
||||||
|
article.item {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 25% auto;
|
||||||
|
grid-template-areas: "main aside";
|
||||||
|
margin: calc(var(--pico-spacing)/2);
|
||||||
|
padding: 0;
|
||||||
|
border: var(--pico-border-width) solid var(--pico-card-border-color);
|
||||||
|
|
||||||
|
>* {
|
||||||
|
margin: 0;
|
||||||
|
border: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
>div {
|
||||||
|
margin-left: var(--pico-spacing);
|
||||||
|
background-color: var(--pico-card-sectioning-background-color);
|
||||||
|
align-items: center;
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ul {
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
1028
common/static/scss/_legacy.sass
Normal file
1028
common/static/scss/_legacy.sass
Normal file
File diff suppressed because it is too large
Load diff
191
common/static/scss/_legacy2.scss
Normal file
191
common/static/scss/_legacy2.scss
Normal file
|
@ -0,0 +1,191 @@
|
||||||
|
/*** django-jsoneditor ***/
|
||||||
|
div.jsoneditor {
|
||||||
|
border-color: #ccc !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.jsoneditor-menu {
|
||||||
|
background-color: #606c76 !important;
|
||||||
|
border-color: #606c76 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/***** MODAL DIALOG ****/
|
||||||
|
#modal {
|
||||||
|
/* Underlay covers entire screen. */
|
||||||
|
position: fixed;
|
||||||
|
top: 0px;
|
||||||
|
bottom: 0px;
|
||||||
|
left: 0px;
|
||||||
|
right: 0px;
|
||||||
|
background-color: rgba(0, 0, 0, 0.5);
|
||||||
|
z-index: 1000;
|
||||||
|
|
||||||
|
/* Flexbox centers the .modal-content vertically and horizontally */
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
/* Animate when opening */
|
||||||
|
animation-name: fadeIn;
|
||||||
|
animation-duration: 150ms;
|
||||||
|
animation-timing-function: ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
#modal>.modal-underlay {
|
||||||
|
/* underlay takes up the entire viewport. This is only
|
||||||
|
required if you want to click to dismiss the popup */
|
||||||
|
position: absolute;
|
||||||
|
z-index: -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#modal>.modal-content {
|
||||||
|
/* Position visible dialog near the top of the window */
|
||||||
|
margin-top: 10vh;
|
||||||
|
|
||||||
|
/* Sizing for visible dialog */
|
||||||
|
width: 80%;
|
||||||
|
max-width: 600px;
|
||||||
|
|
||||||
|
/* Display properties for visible dialog*/
|
||||||
|
background-color: #f7f7f7;
|
||||||
|
padding: 20px 20px 10px 20px;
|
||||||
|
color: #606c76;
|
||||||
|
|
||||||
|
/* Animate when opening */
|
||||||
|
animation-name: zoomIn;
|
||||||
|
animation-duration: 150ms;
|
||||||
|
animation-timing-function: ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
#modal.closing {
|
||||||
|
/* Animate when closing */
|
||||||
|
animation-name: fadeOut;
|
||||||
|
animation-duration: 150ms;
|
||||||
|
animation-timing-function: ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
#modal.closing>.modal-content {
|
||||||
|
/* Aniate when closing */
|
||||||
|
animation-name: zoomOut;
|
||||||
|
animation-duration: 150ms;
|
||||||
|
animation-timing-function: ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes fadeIn {
|
||||||
|
0% {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes fadeOut {
|
||||||
|
0% {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes zoomIn {
|
||||||
|
0% {
|
||||||
|
transform: scale(0.9);
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
transform: scale(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes zoomOut {
|
||||||
|
0% {
|
||||||
|
transform: scale(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
transform: scale(0.9);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#modal .add-to-list-modal__head {
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#modal .add-to-list-modal__head::after {
|
||||||
|
content: ' ';
|
||||||
|
clear: both;
|
||||||
|
display: table;
|
||||||
|
}
|
||||||
|
|
||||||
|
#modal .add-to-list-modal__title {
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 1.2em;
|
||||||
|
float: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
#modal .add-to-list-modal__close-button {
|
||||||
|
float: right;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
#modal .add-to-list-modal__confirm-button {
|
||||||
|
float: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
#modal li,
|
||||||
|
#modal ul,
|
||||||
|
#modal label {
|
||||||
|
display: inline;
|
||||||
|
}
|
||||||
|
|
||||||
|
.donut {
|
||||||
|
margin-left: 10%;
|
||||||
|
width: 80%;
|
||||||
|
aspect-ratio: 1 / 1;
|
||||||
|
border-radius: 50%;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.donut .hole {
|
||||||
|
width: 80%;
|
||||||
|
aspect-ratio: 1 / 1;
|
||||||
|
border-radius: 50%;
|
||||||
|
background: #f7f7f7;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
input:invalid#position {
|
||||||
|
border: red dashed 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gg-play-button-o {
|
||||||
|
box-sizing: border-box;
|
||||||
|
position: relative;
|
||||||
|
display: inline-block;
|
||||||
|
transform: scale(var(--ggs, 1));
|
||||||
|
width: 22px;
|
||||||
|
height: 22px;
|
||||||
|
border: 2px solid;
|
||||||
|
border-radius: 20px
|
||||||
|
}
|
||||||
|
|
||||||
|
.gg-play-button-o::before {
|
||||||
|
content: "";
|
||||||
|
display: inline-block;
|
||||||
|
box-sizing: border-box;
|
||||||
|
position: absolute;
|
||||||
|
width: 0;
|
||||||
|
height: 10px;
|
||||||
|
border-top: 5px solid transparent;
|
||||||
|
border-bottom: 5px solid transparent;
|
||||||
|
border-left: 6px solid;
|
||||||
|
top: 4px;
|
||||||
|
left: 7px
|
||||||
|
}
|
72
common/static/scss/_login.scss
Normal file
72
common/static/scss/_login.scss
Normal file
|
@ -0,0 +1,72 @@
|
||||||
|
.login-page {
|
||||||
|
input:invalid {
|
||||||
|
border: var(--pico-primary) dashed 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
mark {
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.autoComplete_wrapper>ul {
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.autoComplete_wrapper>ul li {
|
||||||
|
list-style: none;
|
||||||
|
padding: 0 var(--pico-spacing);
|
||||||
|
}
|
||||||
|
|
||||||
|
.autoComplete_wrapper>ul>li:hover {
|
||||||
|
cursor: pointer;
|
||||||
|
background-color: var(--pico-text-selection-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.autoComplete_wrapper>ul>li[aria-selected="true"] {
|
||||||
|
background-color: var(--pico-text-selection-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
article {
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
min-width: max-content;
|
||||||
|
width: 50%;
|
||||||
|
height: max-content;
|
||||||
|
|
||||||
|
p {
|
||||||
|
max-width: 50vw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
header img {
|
||||||
|
padding: 10%;
|
||||||
|
}
|
||||||
|
|
||||||
|
html,
|
||||||
|
body {
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
article {
|
||||||
|
width: 96%;
|
||||||
|
|
||||||
|
p {
|
||||||
|
max-width: 96vw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
body>footer {
|
||||||
|
color: lightgrey;
|
||||||
|
text-align: center;
|
||||||
|
bottom: 0px;
|
||||||
|
position: fixed;
|
||||||
|
width: 100%;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
}
|
68
common/static/scss/_mark.scss
Normal file
68
common/static/scss/_mark.scss
Normal file
|
@ -0,0 +1,68 @@
|
||||||
|
#mark_date {
|
||||||
|
width: unset !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tag-input {
|
||||||
|
display: -webkit-box;
|
||||||
|
display: -ms-flexbox;
|
||||||
|
display: flex;
|
||||||
|
-webkit-box-pack: start;
|
||||||
|
-ms-flex-pack: start;
|
||||||
|
justify-content: flex-start;
|
||||||
|
-ms-flex-wrap: wrap;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
border-bottom: 0.1rem solid #ccc;
|
||||||
|
padding-bottom: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tag-input__tag {
|
||||||
|
position: relative;
|
||||||
|
display: block;
|
||||||
|
float: left;
|
||||||
|
color: white;
|
||||||
|
background: #d5d5d5;
|
||||||
|
padding: 5px 20px 5px 6px;
|
||||||
|
margin: 4px;
|
||||||
|
border-radius: .4rem;
|
||||||
|
line-height: 1em;
|
||||||
|
-webkit-transition: all 0.2s ease-in-out;
|
||||||
|
transition: all 0.2s ease-in-out;
|
||||||
|
height: min-content;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tag-input__tag.tag-input__tag--highlight {
|
||||||
|
color: white;
|
||||||
|
background: #00a1cc;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tag-input__close {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
width: 14px;
|
||||||
|
height: 100%;
|
||||||
|
cursor: pointer;
|
||||||
|
border-radius: 0 2px 2px 0;
|
||||||
|
-webkit-transition: background 0.2s;
|
||||||
|
transition: background 0.2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tag-input__close:after {
|
||||||
|
position: absolute;
|
||||||
|
content: "×";
|
||||||
|
top: 5px;
|
||||||
|
left: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tag-input__close:hover {
|
||||||
|
color: #606c76;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tag-input input {
|
||||||
|
border: 0;
|
||||||
|
margin: 4px;
|
||||||
|
padding: 3px 7px 3px 0;
|
||||||
|
width: auto;
|
||||||
|
outline: none;
|
||||||
|
height: unset;
|
||||||
|
}
|
31
common/static/scss/_markdown.scss
Normal file
31
common/static/scss/_markdown.scss
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
.spoiler {
|
||||||
|
background: grey;
|
||||||
|
filter: blur(2px);
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
&.revealed {
|
||||||
|
background: unset;
|
||||||
|
filter: unset;
|
||||||
|
color: inherit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.markdown-content {
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
font-size: 1.5rem
|
||||||
|
}
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
font-size: 1.25rem
|
||||||
|
}
|
||||||
|
|
||||||
|
h3 {
|
||||||
|
font-size: 1.1rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.markdownx-editor {
|
||||||
|
font-family: monospace;
|
||||||
|
}
|
133
common/static/scss/_rating.scss
Normal file
133
common/static/scss/_rating.scss
Normal file
|
@ -0,0 +1,133 @@
|
||||||
|
.rating {
|
||||||
|
margin-top: 2vh;
|
||||||
|
margin-bottom: 2vh;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rating * {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rating h3 small {
|
||||||
|
font-weight: 200;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rating .display {
|
||||||
|
display: flex;
|
||||||
|
flex: row;
|
||||||
|
vertical-align: bottom;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rating .display div {
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rating .display div:nth-child(1) {
|
||||||
|
width: max-content;
|
||||||
|
padding-right: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rating .display div:nth-child(2) {
|
||||||
|
flex-grow: 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rating .chart {
|
||||||
|
flex-grow: 100;
|
||||||
|
display: table;
|
||||||
|
table-layout: fixed;
|
||||||
|
height: max-content;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rating .chart li {
|
||||||
|
position: relative;
|
||||||
|
display: table-cell;
|
||||||
|
vertical-align: bottom;
|
||||||
|
height: 6vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rating .chart span {
|
||||||
|
margin: 2%;
|
||||||
|
display: block;
|
||||||
|
background: var(--pico-muted-color);
|
||||||
|
border-radius: 0.5vh 0.5vh 0 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rating .undisplay {
|
||||||
|
position: absolute;
|
||||||
|
display: none;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
inset: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rating.unavailable .undisplay {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rating.unavailable .display {
|
||||||
|
filter: blur(0.5vh);
|
||||||
|
}
|
||||||
|
|
||||||
|
.rating.unavailable .chart li:nth-child(1) span {
|
||||||
|
height: 10% !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rating.unavailable .chart li:nth-child(2) span {
|
||||||
|
height: 20% !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rating.unavailable .chart li:nth-child(3) span {
|
||||||
|
height: 30% !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rating.unavailable .chart li:nth-child(4) span {
|
||||||
|
height: 40% !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rating.unavailable .chart li:nth-child(5) span {
|
||||||
|
height: 50% !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Rating Star with Font Awesome
|
||||||
|
.rating-star {
|
||||||
|
position: relative;
|
||||||
|
vertical-align: middle;
|
||||||
|
font-family: FontAwesome;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rating-star:before {
|
||||||
|
content: "\f006 \f006 \f006 \f006 \f006";
|
||||||
|
text-underline-offset: 0.125em;
|
||||||
|
line-height: 1;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rating-star>div {
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rating-star>div:before {
|
||||||
|
content: "\f005 \f005 \f005 \f005 \f005";
|
||||||
|
text-underline-offset: 0.125em;
|
||||||
|
line-height: 1;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rating-star .yellow {
|
||||||
|
color: #F68127;
|
||||||
|
text-shadow: 0 0 1px #FFE205, 0 0 2px #FFE205, 0 0 6px #EDD205;
|
||||||
|
// color: #FFE205;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rating-editor {
|
||||||
|
cursor: pointer !important;
|
||||||
|
border: none !important;
|
||||||
|
}
|
84
common/static/scss/_sidebar.scss
Normal file
84
common/static/scss/_sidebar.scss
Normal file
|
@ -0,0 +1,84 @@
|
||||||
|
.sidebar {
|
||||||
|
article {
|
||||||
|
padding: calc(var(--pico-block-spacing-horizontal));
|
||||||
|
}
|
||||||
|
|
||||||
|
details {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
hgroup {
|
||||||
|
margin: 0;
|
||||||
|
margin-right: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
section.announcement {
|
||||||
|
p {
|
||||||
|
font-size: 80%;
|
||||||
|
}
|
||||||
|
|
||||||
|
// details[open]>summary {
|
||||||
|
// margin: 0;
|
||||||
|
// }
|
||||||
|
|
||||||
|
details {
|
||||||
|
margin-bottom: var(--pico-spacing);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
section.profile {
|
||||||
|
summary>div {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: auto 1fr;
|
||||||
|
grid-template-rows: auto;
|
||||||
|
grid-column-gap: 0.5em;
|
||||||
|
grid-row-gap: 0px;
|
||||||
|
// align-items: center;
|
||||||
|
// justify-content: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
summary::after {
|
||||||
|
position: relative;
|
||||||
|
bottom: calc(2rem * var(--pico-line-height));
|
||||||
|
}
|
||||||
|
|
||||||
|
a:hover {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.avatar {
|
||||||
|
height: calc(1rem * var(--pico-line-height) + var(--pico-nav-link-spacing-vertical) * 4);
|
||||||
|
width: calc(1rem * var(--pico-line-height) + var(--pico-nav-link-spacing-vertical) * 4);
|
||||||
|
|
||||||
|
img {
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.nickname {
|
||||||
|
word-break: break-all;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.relation {
|
||||||
|
width: max-content;
|
||||||
|
float: right;
|
||||||
|
color: var(--pico-muted-color);
|
||||||
|
opacity: 0.5;
|
||||||
|
margin-left: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
|
||||||
|
section,
|
||||||
|
article,
|
||||||
|
details {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
115
common/static/scss/_sitelabel.scss
Normal file
115
common/static/scss/_sitelabel.scss
Normal file
|
@ -0,0 +1,115 @@
|
||||||
|
.site-list {
|
||||||
|
a {
|
||||||
|
display: inline;
|
||||||
|
background: transparent;
|
||||||
|
padding: calc(var(--pico-spacing)/8);
|
||||||
|
border-radius: calc(var(--pico-spacing)/4);
|
||||||
|
border-style: solid;
|
||||||
|
border-width: 1px;
|
||||||
|
font-size: 80%;
|
||||||
|
margin: 3px;
|
||||||
|
// padding: 1px 3px;
|
||||||
|
// padding-top: 2px;
|
||||||
|
font-weight: lighter;
|
||||||
|
word-break: keep-all;
|
||||||
|
opacity: 1;
|
||||||
|
font-weight: 400;
|
||||||
|
text-decoration: none;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.douban {
|
||||||
|
border: none;
|
||||||
|
color: white;
|
||||||
|
background-color: #319840;
|
||||||
|
}
|
||||||
|
|
||||||
|
.spotify {
|
||||||
|
background-color: #1ed760;
|
||||||
|
color: black;
|
||||||
|
border: none;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.imdb {
|
||||||
|
background-color: #F5C518;
|
||||||
|
color: #121212;
|
||||||
|
border: none;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.igdb {
|
||||||
|
background-color: #323A44;
|
||||||
|
color: #DFE1E2;
|
||||||
|
border: none;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.steam {
|
||||||
|
background: linear-gradient(30deg, #1387b8, #111d2e);
|
||||||
|
color: white;
|
||||||
|
border: none;
|
||||||
|
// font-weight: 600
|
||||||
|
// padding-top: 2px
|
||||||
|
}
|
||||||
|
|
||||||
|
.bangumi {
|
||||||
|
background: #F09199;
|
||||||
|
color: #FCFCFC;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.goodreads {
|
||||||
|
background: #F4F1EA;
|
||||||
|
color: #372213;
|
||||||
|
font-weight: lighter;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bookstw {
|
||||||
|
background: #7FBA19;
|
||||||
|
color: white;
|
||||||
|
font-weight: lighter;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tmdb {
|
||||||
|
background: linear-gradient(90deg, #91CCA3, #1FB4E2);
|
||||||
|
color: white;
|
||||||
|
border: none;
|
||||||
|
font-weight: lighter;
|
||||||
|
padding-top: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.googlebooks {
|
||||||
|
color: white;
|
||||||
|
background-color: #4285F4;
|
||||||
|
border-color: #4285F4;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rss {
|
||||||
|
color: white;
|
||||||
|
background-color: #E1A02F;
|
||||||
|
border-color: #E1A02F;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bandcamp {
|
||||||
|
color: white;
|
||||||
|
background-color: #28A0C1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// .bandcamp {
|
||||||
|
// color: white
|
||||||
|
// background-color: #28A0C1
|
||||||
|
// // transform: skewX(-30deg)
|
||||||
|
// display: inline-block
|
||||||
|
// }
|
||||||
|
// .bandcamp span
|
||||||
|
// // transform: skewX(30deg)
|
||||||
|
// display: inline-block
|
||||||
|
// margin: 0 4px
|
||||||
|
|
||||||
|
.discogs {
|
||||||
|
color: white;
|
||||||
|
background-color: #262626;
|
||||||
|
border-color: #262626;
|
||||||
|
}
|
||||||
|
}
|
20
common/static/scss/_tag.scss
Normal file
20
common/static/scss/_tag.scss
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
.tag-list {
|
||||||
|
// margin-bottom: var(--pico-spacing);
|
||||||
|
|
||||||
|
span {
|
||||||
|
// margin: 3px;
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: white;
|
||||||
|
background: var(--pico-muted-color);
|
||||||
|
padding: calc(var(--pico-spacing)/4);
|
||||||
|
border-radius: calc(var(--pico-spacing)/4);
|
||||||
|
line-height: 1.2em;
|
||||||
|
font-size: 80%;
|
||||||
|
margin: 3px !important;
|
||||||
|
text-decoration: none;
|
||||||
|
white-space: nowrap;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
18
common/static/scss/neodb.scss
Normal file
18
common/static/scss/neodb.scss
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
@import '_header.scss';
|
||||||
|
@import '_dialog.scss';
|
||||||
|
@import '_rating.scss';
|
||||||
|
@import '_mark.scss';
|
||||||
|
@import '_item.scss';
|
||||||
|
@import '_layout.scss';
|
||||||
|
@import '_sitelabel.scss';
|
||||||
|
@import '_tag.scss';
|
||||||
|
@import '_markdown.scss';
|
||||||
|
@import '_legacy.sass';
|
||||||
|
@import '_legacy2.scss';
|
||||||
|
@import '_collection.scss';
|
||||||
|
@import '_feed.scss';
|
||||||
|
@import '_card.scss';
|
||||||
|
@import '_gallery.scss';
|
||||||
|
@import '_sidebar.scss';
|
||||||
|
@import '_common.scss';
|
||||||
|
@import '_login.scss';
|
|
@ -8,33 +8,23 @@
|
||||||
{% load thumb %}
|
{% load thumb %}
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<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">
|
<title>{{ site_name }} - {% trans '无效请求' %}</title>
|
||||||
<title>{{ site_name }} - {% trans '无效请求' %}</title>
|
{% include "common_libs.html" with jquery=0 v2=1 %}
|
||||||
{% include "common_libs.html" with jquery=0 %}
|
</head>
|
||||||
<link rel="stylesheet" href="{% static 'css/boofilsic_box.css' %}">
|
<body>
|
||||||
</head>
|
{% include "_header.html" %}
|
||||||
|
<main class="container">
|
||||||
<body>
|
<article class="error">
|
||||||
<div id="page-wrapper">
|
<header>
|
||||||
<div id="content-wrapper">
|
<h3>🤦🏻 无效的请求</h3>
|
||||||
{% include "partial/_navbar.html" %}
|
</header>
|
||||||
<div class="box">
|
{{ exception }}
|
||||||
<a href="{% url 'common:home' %}">
|
您可能提交了无效的数据,或者相关内容已被作者删除。如果您确信这是我们的错误,请通过页面底部的链接联系我们。
|
||||||
<img src="{% static 'img/logo.svg' %}" alt="logo" class="logo">
|
</article>
|
||||||
</a>
|
</main>
|
||||||
<div class="main-msg">
|
|
||||||
无效的请求
|
|
||||||
</div>
|
|
||||||
<div class="sec-msg">
|
|
||||||
{{ exception }}
|
|
||||||
您可能提交了无效的数据,或者相关内容已被作者删除。如果您确信这是我们的错误,欢迎通过页面底部的链接联系。
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% include "partial/_footer.html" %}
|
{% include "partial/_footer.html" %}
|
||||||
</div>
|
</body>
|
||||||
</body>
|
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -8,32 +8,23 @@
|
||||||
{% load thumb %}
|
{% load thumb %}
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<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">
|
<title>{{ site_name }} - {% trans '权限不符' %}</title>
|
||||||
<title>{{ site_name }} - {% trans '权限不符' %}</title>
|
{% include "common_libs.html" with jquery=0 v2=1 %}
|
||||||
{% include "common_libs.html" with jquery=0 %}
|
</head>
|
||||||
<link rel="stylesheet" href="{% static 'css/boofilsic_box.css' %}">
|
<body>
|
||||||
</head>
|
{% include "_header.html" %}
|
||||||
|
<main class="container">
|
||||||
<body>
|
<article class="error">
|
||||||
<div id="page-wrapper">
|
<header>
|
||||||
<div id="content-wrapper">
|
<h3>🤦🏻 权限不符</h3>
|
||||||
{% include "partial/_navbar.html" %}
|
</header>
|
||||||
<div class="box">
|
{{ exception }}
|
||||||
<a href="{% url 'common:home' %}">
|
您可能访问了错误的网址,或者相关内容已被作者删除。如果您确信这是我们的错误,请通过页面底部的链接联系我们。
|
||||||
<img src="{% static 'img/logo.svg' %}" alt="logo" class="logo">
|
</article>
|
||||||
</a>
|
</main>
|
||||||
<div class="main-msg">
|
|
||||||
权限不符
|
|
||||||
</div>
|
|
||||||
<div class="sec-msg">
|
|
||||||
您可能访问了错误的网址,或者相关内容已被作者隐藏。如果您确信这是我们的错误,欢迎通过页面底部的链接联系。
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% include "partial/_footer.html" %}
|
{% include "partial/_footer.html" %}
|
||||||
</div>
|
</body>
|
||||||
</body>
|
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -8,32 +8,22 @@
|
||||||
{% load thumb %}
|
{% load thumb %}
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<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">
|
<title>{{ site_name }} - {% trans '未找到' %}</title>
|
||||||
<title>{{ site_name }} - {% trans '未找到' %}</title>
|
{% include "common_libs.html" with jquery=0 v2=1 %}
|
||||||
{% include "common_libs.html" with jquery=0 %}
|
</head>
|
||||||
<link rel="stylesheet" href="{% static 'css/boofilsic_box.css' %}">
|
<body>
|
||||||
</head>
|
{% include "_header.html" %}
|
||||||
|
<main class="container">
|
||||||
<body>
|
<article class="error">
|
||||||
<div id="page-wrapper">
|
<header>
|
||||||
<div id="content-wrapper">
|
<h3>🤦🏻 条目未找到</h3>
|
||||||
{% include "partial/_navbar.html" %}
|
</header>
|
||||||
<div class="box">
|
您可能输入了一个无效的网址,或者相关内容已被作者删除。如果您确信这是我们的错误,请通过页面底部的链接联系我们。
|
||||||
<a href="{% url 'common:home' %}">
|
</article>
|
||||||
<img src="{% static 'img/logo.svg' %}" alt="logo" class="logo">
|
</main>
|
||||||
</a>
|
|
||||||
<div class="main-msg">
|
|
||||||
请求条目未找到
|
|
||||||
</div>
|
|
||||||
<div class="sec-msg">
|
|
||||||
您可能输入了一个无效的网址,或者相关内容已被作者删除。如果您确信这是我们的错误,欢迎通过页面底部的链接联系。
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% include "partial/_footer.html" %}
|
{% include "partial/_footer.html" %}
|
||||||
</div>
|
</body>
|
||||||
</body>
|
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -8,32 +8,22 @@
|
||||||
{% load thumb %}
|
{% load thumb %}
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<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">
|
<title>{{ site_name }} - {% trans '系统错误' %}</title>
|
||||||
<title>{{ site_name }} - {% trans '系统错误' %}</title>
|
{% include "common_libs.html" with jquery=0 v2=1 %}
|
||||||
{% include "common_libs.html" with jquery=0 %}
|
</head>
|
||||||
<link rel="stylesheet" href="{% static 'css/boofilsic_box.css' %}">
|
<body>
|
||||||
</head>
|
{% include "_header.html" %}
|
||||||
|
<main class="container">
|
||||||
<body>
|
<article class="error">
|
||||||
<div id="page-wrapper">
|
<header>
|
||||||
<div id="content-wrapper">
|
<h3>🤦🏻 系统内部错误</h3>
|
||||||
{% include "partial/_navbar.html" %}
|
</header>
|
||||||
<div class="box">
|
发生了一个内部错误,如果这个错误多次出现,后台会记录并会由人工处理。如果您有紧急情况或任何疑问,请通过页面底部的链接联系我们。
|
||||||
<a href="{% url 'common:home' %}">
|
</article>
|
||||||
<img src="{% static 'img/logo.svg' %}" alt="logo" class="logo">
|
</main>
|
||||||
</a>
|
|
||||||
<div class="main-msg">
|
|
||||||
系统内部错误
|
|
||||||
</div>
|
|
||||||
<div class="sec-msg">
|
|
||||||
发生了一个内部错误,如果这个错误多次出现,后台会记录并会由人工处理。如果您有紧急情况或疑问,欢迎通过页面底部的链接联系。
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% include "partial/_footer.html" %}
|
{% include "partial/_footer.html" %}
|
||||||
</div>
|
</body>
|
||||||
</body>
|
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -1,22 +1,25 @@
|
||||||
<html>
|
<!DOCTYPE html>
|
||||||
<head>
|
<html lang="en">
|
||||||
<meta charset="UTF-8">
|
<head>
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta charset="UTF-8">
|
||||||
<title>☃ NeoDB 升级中...</title>
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
</head>
|
<title>☃ NeoDB 升级中...</title>
|
||||||
<body>
|
</head>
|
||||||
<div class="pl">
|
<body>
|
||||||
<div class="pl__outer-ring"></div>
|
<div class="pl">
|
||||||
<div class="pl__inner-ring"><center>NeoDB 升级中...</center></div>
|
<div class="pl__outer-ring"></div>
|
||||||
<div class="pl__track-cover"></div>
|
<div class="pl__inner-ring">
|
||||||
<div class="pl__ball">
|
<center>NeoDB 升级中...</center>
|
||||||
<div class="pl__ball-texture"></div>
|
</div>
|
||||||
<div class="pl__ball-outer-shadow"></div>
|
<div class="pl__track-cover"></div>
|
||||||
<div class="pl__ball-inner-shadow"></div>
|
<div class="pl__ball">
|
||||||
<div class="pl__ball-side-shadows"></div>
|
<div class="pl__ball-texture"></div>
|
||||||
</div>
|
<div class="pl__ball-outer-shadow"></div>
|
||||||
</div>
|
<div class="pl__ball-inner-shadow"></div>
|
||||||
<style>
|
<div class="pl__ball-side-shadows"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<style>
|
||||||
* {
|
* {
|
||||||
border: 0;
|
border: 0;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
|
@ -205,7 +208,7 @@ center {
|
||||||
transform: rotate(360deg);
|
transform: rotate(360deg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
<!-- CSS from https://jonkantner.com -->
|
<!-- CSS from https://jonkantner.com -->
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
103
common/templates/_header.html
Normal file
103
common/templates/_header.html
Normal file
|
@ -0,0 +1,103 @@
|
||||||
|
{% load admin_url %}
|
||||||
|
{% load static %}
|
||||||
|
{% load i18n %}
|
||||||
|
<header class="container-fluid">
|
||||||
|
<nav>
|
||||||
|
<ul class="nav-logo">
|
||||||
|
<a href="{% url 'common:home' %}">
|
||||||
|
<img src="{% static 'img/logo.svg' %}" alt="" />
|
||||||
|
</a>
|
||||||
|
</ul>
|
||||||
|
<ul class="nav-search">
|
||||||
|
<li>
|
||||||
|
<form role="search" method="get" action="{% url 'catalog:search' %}">
|
||||||
|
<input type="search"
|
||||||
|
name="q"
|
||||||
|
placeholder="搜索标题、创作者、ISBN、链接(如 https://movie.douban.com/subject/1297880/ )"
|
||||||
|
class="search"
|
||||||
|
value="{{ request.GET.q|default:'' }}" />
|
||||||
|
<select name="c">
|
||||||
|
<option value="all">全部</option>
|
||||||
|
<option {% if request.GET.c and request.GET.c == 'book' or '/book/' in request.path %}selected{% endif %}
|
||||||
|
value="book">书籍</option>
|
||||||
|
<option {% if request.GET.c and request.GET.c == 'movietv' or '/movie/' in request.path or '/tv/' in request.path %}selected{% endif %}
|
||||||
|
value="movietv">影视</option>
|
||||||
|
<option {% if request.GET.c and request.GET.c == 'podcast' or '/podcast/' in request.path %}selected{% endif %}
|
||||||
|
value="podcast">播客</option>
|
||||||
|
<option {% if request.GET.c and request.GET.c == 'music' or '/album/' in request.path %}selected{% endif %}
|
||||||
|
value="music">音乐</option>
|
||||||
|
<option {% if request.GET.c and request.GET.c == 'game' or '/game/' in request.path %}selected{% endif %}
|
||||||
|
value="game">游戏</option>
|
||||||
|
</select>
|
||||||
|
<input type="submit" value="" class="fa-solid" />
|
||||||
|
</form>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<ul>
|
||||||
|
<li class="small-only">
|
||||||
|
<a _="on click toggle .unhide on .nav-search">搜索</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a class="{% if current == 'discover' %}current{% endif %}"
|
||||||
|
href="{% url 'catalog:discover' %}">发现</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a class="{% if current == 'timeline' %}current{% endif %}"
|
||||||
|
href="{% url 'social:feed' %}">动态</a>
|
||||||
|
</li>
|
||||||
|
<li class="large-only">
|
||||||
|
<a class="{% if current == 'home' %}current{% endif %}"
|
||||||
|
href="{% url 'common:me' %}">个人</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<ul class="nav-dropdown">
|
||||||
|
<li>
|
||||||
|
<details class="dropdown">
|
||||||
|
<summary aria-haspopup="listbox">
|
||||||
|
<span class="avatar">
|
||||||
|
<img alt=""
|
||||||
|
src="{% if request.user.is_authenticated %}{{ request.user.mastodon_account.avatar }}{% else %}data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw=={% endif %}" />
|
||||||
|
</span>
|
||||||
|
</summary>
|
||||||
|
<ul role="listbox" style="min-width:-webkit-max-content;" dir="rtl">
|
||||||
|
{% if request.user.is_authenticated %}
|
||||||
|
<li class="small-only">
|
||||||
|
<a class="{% if current == 'home' %}current{% endif %}"
|
||||||
|
href="{% url 'common:me' %}">个人主页</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="{% url 'users:data' %}">数据</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="{% url 'users:preferences' %}">设置</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="{% url 'users:logout' %}">登出</a>
|
||||||
|
</li>
|
||||||
|
{% if request.user.is_superuser %}
|
||||||
|
<li>
|
||||||
|
<a href="{% admin_url %}">后台</a>
|
||||||
|
</li>
|
||||||
|
{% endif %}
|
||||||
|
{% else %}
|
||||||
|
<li>
|
||||||
|
<a href="{% url 'users:login' %}?next={{ request.path }}">登录</a>
|
||||||
|
</li>
|
||||||
|
{% endif %}
|
||||||
|
</ul>
|
||||||
|
</details>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</nav>
|
||||||
|
</header>
|
||||||
|
{% if messages %}
|
||||||
|
<div class="main-section-wrapper"
|
||||||
|
style="margin-bottom: 10px;
|
||||||
|
text-align:center">
|
||||||
|
<ul class="messages">
|
||||||
|
{% for message in messages %}
|
||||||
|
<li {% if message.tags %}class="{{ message.tags }}"{% endif %}>{{ message }}</li>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
215
common/templates/_sidebar.html
Normal file
215
common/templates/_sidebar.html
Normal file
|
@ -0,0 +1,215 @@
|
||||||
|
{% load static %}
|
||||||
|
{% load i18n %}
|
||||||
|
{% load admin_url %}
|
||||||
|
{% load mastodon %}
|
||||||
|
{% load oauth_token %}
|
||||||
|
{% load truncate %}
|
||||||
|
{% load thumb %}
|
||||||
|
{% load collection %}
|
||||||
|
{% load bleach_tags %}
|
||||||
|
<aside class="grid__aside sidebar">
|
||||||
|
{% if request.user.unread_announcements %}
|
||||||
|
<section class="announcement">
|
||||||
|
<article>
|
||||||
|
<h5>
|
||||||
|
未读公告
|
||||||
|
<small> | <a href="{% url 'management:list' %}">全部</a> </small>
|
||||||
|
</h5>
|
||||||
|
{% for ann in request.user.unread_announcements %}
|
||||||
|
<details open>
|
||||||
|
<summary>
|
||||||
|
{{ ann.title }}
|
||||||
|
<small>(<a href="{% url 'management:retrieve' ann.pk %}">{{ ann.created_time|date }}</a>)</small>
|
||||||
|
</summary>
|
||||||
|
<div class="tldr" _="on click toggle .tldr on me">{{ ann.get_html_content | safe }}</div>
|
||||||
|
</details>
|
||||||
|
{% endfor %}
|
||||||
|
<form action="{% url 'users:mark_announcements_read' %}" method="post">
|
||||||
|
{% csrf_token %}
|
||||||
|
<input type="submit" class="secondary outline" value="{% trans '全部标为已读' %}">
|
||||||
|
</form>
|
||||||
|
</article>
|
||||||
|
</section>
|
||||||
|
{% endif %}
|
||||||
|
{% if show_profile %}
|
||||||
|
<section class="profile">
|
||||||
|
<article>
|
||||||
|
<details class="auto-collapse" open>
|
||||||
|
<summary>
|
||||||
|
<div>
|
||||||
|
<div class="avatar">
|
||||||
|
<a href="{% url 'journal:user_profile' user.mastodon_username %}">
|
||||||
|
<img src="{{ user.mastodon_account.avatar }}" alt="">
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<hgroup>
|
||||||
|
<h6 class="nickname">{{ user.display_name }}</h6>
|
||||||
|
<div>
|
||||||
|
<a href="{{ user.mastodon_account.url }}" target="_blank" rel="noopener">
|
||||||
|
<span class="handler">@{{ user.mastodon_username }}</span>
|
||||||
|
</a>
|
||||||
|
{% current_user_relationship user as relationship %}
|
||||||
|
{% if relationship %}<span>{{ relationship }}</span>{% endif %}
|
||||||
|
</div>
|
||||||
|
</hgroup>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</summary>
|
||||||
|
<p class="user-profile__bio mast-brief">{{ user.mastodon_account.note|bleach:"a,p,span,br" }}</p>
|
||||||
|
{% if request.user != user %}
|
||||||
|
<span class="action">
|
||||||
|
<small>
|
||||||
|
<a href="{% url 'users:report' %}?user_id={{ user.id }}"
|
||||||
|
class="user-profile__report-link">{% trans '投诉用户' %}</a>
|
||||||
|
</small>
|
||||||
|
</span>
|
||||||
|
{% endif %}
|
||||||
|
</details>
|
||||||
|
</article>
|
||||||
|
</section>
|
||||||
|
{% endif %}
|
||||||
|
{% if show_progress %}
|
||||||
|
<section>
|
||||||
|
<article>
|
||||||
|
<details {% if user.featured_collections.all %}open{% endif %}>
|
||||||
|
<summary>{% trans '当前目标' %}</summary>
|
||||||
|
{% for featured_collection in user.featured_collections.all %}
|
||||||
|
{% user_visibility_of featured_collection as visible %}
|
||||||
|
{% if visible %}
|
||||||
|
{% user_stats_of collection=featured_collection user=user as stats %}
|
||||||
|
<div>
|
||||||
|
<a href="{{ featured_collection.collection.url }}">{{ featured_collection.collection.title }}</a> <small>{{ stats.complete }} / {{ stats.total }}</small>
|
||||||
|
<br>
|
||||||
|
<progress value="{{ stats.percentage }}" max="100" />
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
{% empty %}
|
||||||
|
{% if request.user == user %}
|
||||||
|
<div class="empty">将自己或他人的收藏单设为目标,这里就会显示进度</div>
|
||||||
|
{% else %}
|
||||||
|
<div class="empty">暂未设置目标</div>
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
</details>
|
||||||
|
</article>
|
||||||
|
</section>
|
||||||
|
{% endif %}
|
||||||
|
{% if recent_podcast_episodes %}
|
||||||
|
<section>
|
||||||
|
<article>
|
||||||
|
<details class="auto-collapse" open>
|
||||||
|
<summary>{% trans '在听播客的近期单集' %}</summary>
|
||||||
|
<div class="shelf">
|
||||||
|
<ul class="cards">
|
||||||
|
{% for item in recent_podcast_episodes %}
|
||||||
|
<li class="card">
|
||||||
|
<a class="episode"
|
||||||
|
data-uuid="{{ item.uuid }}"
|
||||||
|
data-media="{{ item.media_url }}"
|
||||||
|
data-cover="{{ item.cover_url|default:item.program.cover.url }}"
|
||||||
|
data-title="{{ item.title }}"
|
||||||
|
data-album="{{ item.program.title }}"
|
||||||
|
data-hosts="{{ item.program.hosts|join:' / ' }}"
|
||||||
|
data-position="0"
|
||||||
|
href="{{ item.url }}"
|
||||||
|
title="{{ item.title }}">
|
||||||
|
<img src="{{ item.cover_image_url | default:item.cover.url }}"
|
||||||
|
alt="{{ item.title }}"
|
||||||
|
loading="lazy">
|
||||||
|
<div class="card-title">
|
||||||
|
<i class="fa-solid fa-circle-play"></i> {{ item.title }}
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</details>
|
||||||
|
</article>
|
||||||
|
</section>
|
||||||
|
{% endif %}
|
||||||
|
{% if books_in_progress %}
|
||||||
|
<section>
|
||||||
|
<article>
|
||||||
|
<details class="auto-collapse" open>
|
||||||
|
<summary>{% trans '在读的书' %}</summary>
|
||||||
|
<div class="shelf">
|
||||||
|
<ul class="cards">
|
||||||
|
{% for item in books_in_progress %}
|
||||||
|
<li class="card">
|
||||||
|
<a href="{{ item.url }}" title="{{ item.title }}">
|
||||||
|
<img src="{{ item.cover|thumb:'normal' }}"
|
||||||
|
alt="{{ item.title }}"
|
||||||
|
loading="lazy">
|
||||||
|
<div class="card-title">{{ item.title }}</div>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</details>
|
||||||
|
</article>
|
||||||
|
</section>
|
||||||
|
{% endif %}
|
||||||
|
{% if tvshows_in_progress %}
|
||||||
|
<section>
|
||||||
|
<article>
|
||||||
|
<details class="auto-collapse" open>
|
||||||
|
<summary>{% trans '在看的剧集' %}</summary>
|
||||||
|
<div class="shelf">
|
||||||
|
<ul class="cards">
|
||||||
|
{% for item in tvshows_in_progress %}
|
||||||
|
<li class="card">
|
||||||
|
<a href="{{ item.url }}" title="{{ item.title }}">
|
||||||
|
<img src="{{ item.cover|thumb:'normal' }}"
|
||||||
|
alt="{{ item.title }}"
|
||||||
|
loading="lazy">
|
||||||
|
<div class="card-title">{{ item.title }}</div>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</details>
|
||||||
|
</article>
|
||||||
|
</section>
|
||||||
|
{% endif %}
|
||||||
|
{% if top_tags %}
|
||||||
|
<section>
|
||||||
|
<article>
|
||||||
|
<details {% if top_tags %}class="auto-collapse" open{% endif %}>
|
||||||
|
<summary>{% trans '常用标签' %}</summary>
|
||||||
|
<div class="tag-list">
|
||||||
|
{% for t in top_tags %}
|
||||||
|
<span>
|
||||||
|
<a href="{% url 'journal:user_tag_member_list' user.mastodon_username t %}">{{ t }}</a>
|
||||||
|
</span>
|
||||||
|
{% empty %}
|
||||||
|
<div class="empty">暂无可见标签</div>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
<small>
|
||||||
|
{% if top_tags %}
|
||||||
|
<a href="{% url 'journal:user_tag_list' user.mastodon_username %}">...{% trans '全部' %}</a>
|
||||||
|
{% endif %}
|
||||||
|
</small>
|
||||||
|
</details>
|
||||||
|
</article>
|
||||||
|
</section>
|
||||||
|
{% endif %}
|
||||||
|
</aside>
|
||||||
|
<script>
|
||||||
|
$(function () {
|
||||||
|
function _sidebar_auto_collapse(mm){
|
||||||
|
if (mm.matches) {
|
||||||
|
$('.auto-collapse').removeAttr('open')
|
||||||
|
} else {
|
||||||
|
$('.auto-collapse').attr('open', '')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var mm = window.matchMedia("(max-width: 768px)")
|
||||||
|
mm.addListener(_sidebar_auto_collapse);
|
||||||
|
_sidebar_auto_collapse(mm);
|
||||||
|
});
|
||||||
|
</script>
|
|
@ -1,24 +1,28 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html>
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/swagger-ui/4.15.5/swagger-ui.min.css" integrity="sha512-JArlzA682ixxKlWoGxYQxF+vHv527K1/NMnGbMxZERWr/16D7ZlPZUdq9+n5cA3TM030G57bSXYdN706FU9doQ==" crossorigin="anonymous" referrerpolicy="no-referrer" />
|
<link rel="stylesheet"
|
||||||
<title>{{ api.title }} API Documentation</title>
|
href="https://cdnjs.cloudflare.com/ajax/libs/swagger-ui/4.15.5/swagger-ui.min.css"
|
||||||
{% include "common_libs.html" with jquery=0 %}
|
integrity="sha512-JArlzA682ixxKlWoGxYQxF+vHv527K1/NMnGbMxZERWr/16D7ZlPZUdq9+n5cA3TM030G57bSXYdN706FU9doQ=="
|
||||||
<style type="text/css">
|
crossorigin="anonymous"
|
||||||
|
referrerpolicy="no-referrer" />
|
||||||
|
<title>{{ api.title }} API Documentation</title>
|
||||||
|
{% include "common_libs.html" with jquery=0 v2=1 %}
|
||||||
|
<style type="text/css">
|
||||||
.information-container {
|
.information-container {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="content-wrapper">
|
{% include "_header.html" %}
|
||||||
{% include "partial/_navbar.html" %}
|
<div id="swagger-ui" class="container"></div>
|
||||||
|
{% include "partial/_footer.html" %}
|
||||||
<div id="swagger-ui">
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/swagger-ui/4.15.5/swagger-ui-bundle.min.js"
|
||||||
</div>
|
integrity="sha512-8FFvTCXo6KgUt72SMpgMgMHoHnNUOPxndku0/mc+B98qIeEfZ6dpPDYJv6a1TRWHoEZeMQAKQzcwSmQixM9v2w=="
|
||||||
|
crossorigin="anonymous"
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/swagger-ui/4.15.5/swagger-ui-bundle.min.js" integrity="sha512-8FFvTCXo6KgUt72SMpgMgMHoHnNUOPxndku0/mc+B98qIeEfZ6dpPDYJv6a1TRWHoEZeMQAKQzcwSmQixM9v2w==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
|
referrerpolicy="no-referrer"></script>
|
||||||
<script>
|
<script>
|
||||||
const ui = SwaggerUIBundle({
|
const ui = SwaggerUIBundle({
|
||||||
url: '{{ openapi_json_url }}',
|
url: '{{ openapi_json_url }}',
|
||||||
dom_id: '#swagger-ui',
|
dom_id: '#swagger-ui',
|
||||||
|
@ -27,15 +31,14 @@
|
||||||
SwaggerUIBundle.SwaggerUIStandalonePreset
|
SwaggerUIBundle.SwaggerUIStandalonePreset
|
||||||
],
|
],
|
||||||
layout: "BaseLayout",
|
layout: "BaseLayout",
|
||||||
{% if api.csrf and csrf_token %}
|
{% if api.csrf and csrf_token %}
|
||||||
requestInterceptor: (req) => {
|
requestInterceptor: (req) => {
|
||||||
req.headers['X-CSRFToken'] = "{{csrf_token}}"
|
req.headers['X-CSRFToken'] = "{{csrf_token}}"
|
||||||
return req;
|
return req;
|
||||||
},
|
},
|
||||||
{% endif %}
|
{% endif %}
|
||||||
deepLinking: true
|
deepLinking: true
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
</div>
|
</body>
|
||||||
</body>
|
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -1,32 +1,29 @@
|
||||||
{% load i18n %}
|
|
||||||
{% load static %}
|
{% load static %}
|
||||||
|
{% load i18n %}
|
||||||
|
{% load l10n %}
|
||||||
|
{% load admin_url %}
|
||||||
|
{% load mastodon %}
|
||||||
|
{% load oauth_token %}
|
||||||
|
{% load truncate %}
|
||||||
|
{% load thumb %}
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<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="5;url={% if url %}{{url}}{% else %}{% url 'common:home' %}{% endif %}">
|
<title>{{ site_name }} - {% trans '错误' %}</title>
|
||||||
<link rel="stylesheet" href="https://cdn.staticfile.org/milligram/1.4.1/milligram.min.css">
|
{% include "common_libs.html" with jquery=0 v2=1 %}
|
||||||
<link rel="stylesheet" href="{% static 'css/boofilsic_edit.css' %}">
|
</head>
|
||||||
<link rel="stylesheet" href="{% static 'css/boofilsic_box.css' %}">
|
<body>
|
||||||
<title>{% trans '错误' %}</title>
|
{% include "_header.html" %}
|
||||||
</head>
|
<main class="container">
|
||||||
<body>
|
<article class="error">
|
||||||
<div class="box">
|
<header>
|
||||||
|
<h3>🙅🏻 {{ msg }}</h3>
|
||||||
<a href="{% url 'common:home' %}">
|
</header>
|
||||||
<img src="{% static 'img/logo.svg' %}" alt="logo" class="logo">
|
{{ secondary_msg|default:"" }}
|
||||||
</a>
|
</article>
|
||||||
<div class="main-msg">
|
</main>
|
||||||
{{ msg }}
|
{% include "partial/_footer.html" %}
|
||||||
</div>
|
</body>
|
||||||
<div class="sec-msg">
|
</html>
|
||||||
{% if secondary_msg %}
|
|
||||||
{{ secondary_msg }}
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
|
|
|
@ -6,41 +6,39 @@
|
||||||
{% load truncate %}
|
{% load truncate %}
|
||||||
{% load thumb %}
|
{% load thumb %}
|
||||||
<div id="modals">
|
<div id="modals">
|
||||||
<style>
|
<style>
|
||||||
.bottom-link {
|
.bottom-link {
|
||||||
margin-top: 30px; text-align: center; margin-bottom: 5px;
|
margin-top: 30px; text-align: center; margin-bottom: 5px;
|
||||||
}
|
}
|
||||||
.bottom-link a {
|
.bottom-link a {
|
||||||
color: #ccc;
|
color: #ccc;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
<div class="announcement-modal modal">
|
<div class="announcement-modal modal">
|
||||||
<div class="announcement-modal__head">
|
<div class="announcement-modal__head">
|
||||||
<h4 class="announcement-modal__title">{% trans '公告' %}</h4>
|
<h4 class="announcement-modal__title">{% trans '公告' %}</h4>
|
||||||
<span class="announcement-modal__close-button modal-close">
|
<span class="announcement-modal__close-button modal-close">
|
||||||
<i class="fa-solid fa-xmark"></i>
|
<i class="fa-solid fa-xmark"></i>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
|
||||||
<div class="announcement-modal__body">
|
|
||||||
<ul>
|
|
||||||
{% for ann in request.user.unread_announcements %}
|
|
||||||
<li class="announcement">
|
|
||||||
<a href="{% url 'management:retrieve' ann.pk %}">
|
|
||||||
<h5 class="announcement__title">{{ ann.title }}</h5>
|
|
||||||
</a>
|
|
||||||
<span class="announcement__datetime">{{ ann.created_time }}</span>
|
|
||||||
<p class="announcement__content">{{ ann.get_plain_content | truncate:200 }}</p>
|
|
||||||
</li>
|
|
||||||
{% if not forloop.last %}
|
|
||||||
<div class="dividing-line" style="border-top-style: dashed;"></div>
|
|
||||||
{% endif %}
|
|
||||||
{% endfor %}
|
|
||||||
</ul>
|
|
||||||
<div class="bottom-link">
|
|
||||||
<a href="{% url 'management:list' %}">{% trans '查看全部公告' %}</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
<div class="announcement-modal__body">
|
||||||
|
<ul>
|
||||||
|
{% for ann in request.user.unread_announcements %}
|
||||||
|
<li class="announcement">
|
||||||
|
<a href="{% url 'management:retrieve' ann.pk %}">
|
||||||
|
<h5 class="announcement__title">{{ ann.title }}</h5>
|
||||||
|
</a>
|
||||||
|
<span class="announcement__datetime">{{ ann.created_time }}</span>
|
||||||
|
<p class="announcement__content">{{ ann.get_plain_content | truncate:200 }}</p>
|
||||||
|
</li>
|
||||||
|
{% if not forloop.last %}<div class="dividing-line" style="border-top-style: dashed;"></div>{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
<div class="bottom-link">
|
||||||
|
<a href="{% url 'management:list' %}">{% trans '查看全部公告' %}</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="bg-mask"></div>
|
<div class="bg-mask"></div>
|
||||||
<script>
|
<script>
|
||||||
|
|
|
@ -1,23 +1,34 @@
|
||||||
<footer class="footer">
|
<footer class="footer">
|
||||||
<div class="grid">
|
<div class="grid">
|
||||||
<div class="footer__border">
|
<div class="footer__border">
|
||||||
{% if social_link %}
|
{% if social_link %}
|
||||||
<a class="footer__link" target="_blank" rel="noopener" href="{{ social_link }}">关注我们</a>
|
<a class="footer__link"
|
||||||
{% endif %}
|
target="_blank"
|
||||||
{% if support_link %}
|
rel="noopener"
|
||||||
<a class="footer__link" target="_blank" rel="noopener" href="{{ support_link }}">问题反馈</a>
|
href="{{ social_link }}">关注我们</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<a class="footer__link" target="_blank" rel="noopener" href="https://github.com/neodb-social">源代码</a>
|
{% if support_link %}
|
||||||
{% if donation_link %}
|
<a class="footer__link"
|
||||||
<a class="footer__link" target="_blank" rel="noopener" href="{{ donation_link }}">捐助本站</a>
|
target="_blank"
|
||||||
{% endif %}
|
rel="noopener"
|
||||||
<a class="footer__link" href="/announcement/">公告栏</a>
|
href="{{ support_link }}">问题反馈</a>
|
||||||
<a class="footer__link" href="/api-doc/">API</a>
|
{% endif %}
|
||||||
</div>
|
<a class="footer__link"
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener"
|
||||||
|
href="https://github.com/neodb-social">源代码</a>
|
||||||
|
{% if donation_link %}
|
||||||
|
<a class="footer__link"
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener"
|
||||||
|
href="{{ donation_link }}">捐助本站</a>
|
||||||
|
{% endif %}
|
||||||
|
<a class="footer__link" href="{% url 'management:list' %}">公告栏</a>
|
||||||
|
<a class="footer__link" href="{% url 'common:api_doc' %}">API</a>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
<div class="player">
|
<div class="player"></div>
|
||||||
</div>
|
|
||||||
<script>
|
<script>
|
||||||
document.body.addEventListener('htmx:configRequest', (event) => {
|
document.body.addEventListener('htmx:configRequest', (event) => {
|
||||||
event.detail.headers['X-CSRFToken'] = '{{ csrf_token }}';
|
event.detail.headers['X-CSRFToken'] = '{{ csrf_token }}';
|
||||||
|
|
|
@ -2,64 +2,96 @@
|
||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
{% load admin_url %}
|
{% load admin_url %}
|
||||||
<form method="get" action="{% url 'catalog:search' %}">
|
<form method="get" action="{% url 'catalog:search' %}">
|
||||||
<section id="navbar">
|
<section id="navbar">
|
||||||
<nav class="navbar">
|
<nav class="navbar">
|
||||||
<div class="grid">
|
<div class="grid">
|
||||||
<div class="navbar__wrapper">
|
<div class="navbar__wrapper">
|
||||||
<a href="{% url 'common:home' %}" class="navbar__logo">
|
<a href="{% url 'common:home' %}" class="navbar__logo">
|
||||||
<img src="{% static 'img/logo.svg' %}" alt="" class="navbar__logo-img">
|
<img src="{% static 'img/logo.svg' %}" alt="" class="navbar__logo-img">
|
||||||
</a>
|
</a>
|
||||||
<div class="navbar__search-box">
|
<div class="navbar__search-box">
|
||||||
<!-- <input type="search" name="q" id="searchInput" required="true" value="{% for v in request.GET.values %}{{ v }}{% endfor %}" -->
|
<!-- <input type="search"
|
||||||
<input type="search" name="q" id="searchInput" required="true" value="{% if request.GET.q %}{{ request.GET.q }}{% endif %}"
|
name="q"
|
||||||
placeholder="搜索书影音游戏播客,或输入站外条目链接如 https://movie.douban.com/subject/1297880/ 支持站点列表见页底公告栏">
|
id="searchInput"
|
||||||
<select class="navbar__search-dropdown" id="searchCategory" name="c">
|
required="true"
|
||||||
<option value="all" {% if request.GET.c and request.GET.c == 'all' or not request.GET.c %}selected{% endif %}>{% trans '任意' %}</option>
|
value="{% for v in request.GET.values %}{{ v }}{% endfor %}"
|
||||||
<option value="book" {% if request.GET.c and request.GET.c == 'book' or '/book/' in request.path %}selected{% endif %}>{% trans '书籍' %}</option>
|
-->
|
||||||
<option value="movie" {% if request.GET.c and request.GET.c == 'movie' or '/movie/' in request.path %}selected{% endif %}>{% trans '电影' %}</option>
|
<input type="search"
|
||||||
<option value="tv" {% if request.GET.c and request.GET.c == 'tv' or '/tv/' in request.path %}selected{% endif %}>{% trans '剧集' %}</option>
|
name="q"
|
||||||
<option value="podcast" {% if request.GET.c and request.GET.c == 'podcast' or '/podcast/' in request.path %}selected{% endif %}>{% trans '播客' %}</option>
|
id="searchInput"
|
||||||
<option value="music" {% if request.GET.c and request.GET.c == 'music' or '/album/' in request.path %}selected{% endif %}>{% trans '音乐' %}</option>
|
required="true"
|
||||||
<option value="game" {% if request.GET.c and request.GET.c == 'game' or '/game/' in request.path %}selected{% endif %}>{% trans '游戏' %}</option>
|
value="{% if request.GET.q %}{{ request.GET.q }}{% endif %}"
|
||||||
|
placeholder="搜索书影音游戏播客,或输入站外条目链接如 https://movie.douban.com/subject/1297880/ 支持站点列表见页底公告栏">
|
||||||
</select>
|
<select class="navbar__search-dropdown" id="searchCategory" name="c">
|
||||||
|
<option value="all"
|
||||||
|
{% if request.GET.c and request.GET.c == 'all' or not request.GET.c %}selected{% endif %}>
|
||||||
|
{% trans '任意' %}
|
||||||
|
</option>
|
||||||
|
<option value="book"
|
||||||
|
{% if request.GET.c and request.GET.c == 'book' or '/book/' in request.path %}selected{% endif %}>
|
||||||
|
{% trans '书籍' %}
|
||||||
|
</option>
|
||||||
|
<option value="movie"
|
||||||
|
{% if request.GET.c and request.GET.c == 'movie' or '/movie/' in request.path %}selected{% endif %}>
|
||||||
|
{% trans '电影' %}
|
||||||
|
</option>
|
||||||
|
<option value="tv"
|
||||||
|
{% if request.GET.c and request.GET.c == 'tv' or '/tv/' in request.path %}selected{% endif %}>
|
||||||
|
{% trans '剧集' %}
|
||||||
|
</option>
|
||||||
|
<option value="podcast"
|
||||||
|
{% if request.GET.c and request.GET.c == 'podcast' or '/podcast/' in request.path %}selected{% endif %}>
|
||||||
|
{% trans '播客' %}
|
||||||
|
</option>
|
||||||
|
<option value="music"
|
||||||
|
{% if request.GET.c and request.GET.c == 'music' or '/album/' in request.path %}selected{% endif %}>
|
||||||
|
{% trans '音乐' %}
|
||||||
|
</option>
|
||||||
|
<option value="game"
|
||||||
|
{% if request.GET.c and request.GET.c == 'game' or '/game/' in request.path %}selected{% endif %}>
|
||||||
|
{% trans '游戏' %}
|
||||||
|
</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<ul class="navbar__link-list">
|
||||||
|
{% if request.user.is_authenticated %}
|
||||||
|
<a class="navbar__link {% if current == 'discover' %}current{% endif %}"
|
||||||
|
href="{% url 'catalog:discover' %}">{% trans '发现' %}</a>
|
||||||
|
<a class="navbar__link {% if current == 'timeline' %}current{% endif %}"
|
||||||
|
href="{% url 'social:feed' %}">{% trans '动态' %}</a>
|
||||||
|
<a class="navbar__link {% if current == 'home' %}current{% endif %}"
|
||||||
|
href="{% url 'journal:user_profile' request.user.mastodon_username %}">{% trans '个人主页' %}</a>
|
||||||
|
<div class="navbar__link dropdown">
|
||||||
|
<a class="dropbtn"><i class="fa-solid fa-gear" title="{% trans '更多' %}"></i></a>
|
||||||
|
<div class="dropdown-content">
|
||||||
|
<a class="navbar__link {% if current == 'data' %}current{% endif %}"
|
||||||
|
href="{% url 'users:data' %}">{% trans '数据' %}</a>
|
||||||
|
<a class="navbar__link {% if current == 'preferences' %}current{% endif %}"
|
||||||
|
href="{% url 'users:preferences' %}">{% trans '设置' %}</a>
|
||||||
|
<a class="navbar__link" id="logoutLink" href="{% url 'users:logout' %}">{% trans '登出' %}</a>
|
||||||
|
{% if request.user.is_superuser %}
|
||||||
|
<a class="navbar__link" href="{% admin_url %}">{% trans '后台' %}</a>
|
||||||
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
<ul class="navbar__link-list">
|
</div>
|
||||||
|
{% else %}
|
||||||
{% if request.user.is_authenticated %}
|
<a class="navbar__link"
|
||||||
|
href="{% url 'users:login' %}?next={{ request.path }}">{% trans '登录' %}</a>
|
||||||
<a class="navbar__link {% if current == 'discover' %}current{% endif %}" href="{% url 'catalog:discover' %}">{% trans '发现' %}</a>
|
{% endif %}
|
||||||
<a class="navbar__link {% if current == 'timeline' %}current{% endif %}" href="{% url 'social:feed' %}">{% trans '动态' %}</a>
|
</ul>
|
||||||
<a class="navbar__link {% if current == 'home' %}current{% endif %}" href="{% url 'journal:user_profile' request.user.mastodon_username %}">{% trans '个人主页' %}</a>
|
|
||||||
<div class="navbar__link dropdown">
|
|
||||||
<a class="dropbtn"><i class="fa-solid fa-gear" title="{% trans '更多' %}"></i></a>
|
|
||||||
<div class="dropdown-content">
|
|
||||||
<a class="navbar__link {% if current == 'data' %}current{% endif %}" href="{% url 'users:data' %}">{% trans '数据' %}</a>
|
|
||||||
<a class="navbar__link {% if current == 'preferences' %}current{% endif %}" href="{% url 'users:preferences' %}">{% trans '设置' %}</a>
|
|
||||||
<a class="navbar__link" id="logoutLink" href="{% url 'users:logout' %}">{% trans '登出' %}</a>
|
|
||||||
{% if request.user.is_superuser %}
|
|
||||||
<a class="navbar__link" href="{% admin_url %}">{% trans '后台' %}</a>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{% else %}
|
|
||||||
<a class="navbar__link" href="{% url 'users:login' %}?next={{ request.path }}">{% trans '登录' %}</a>
|
|
||||||
{% endif %}
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
</section>
|
</section>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
{% if messages %}
|
{% if messages %}
|
||||||
<div class="main-section-wrapper" style="margin-bottom: 10px; text-align:center;">
|
<div class="main-section-wrapper"
|
||||||
|
style="margin-bottom: 10px;
|
||||||
|
text-align:center">
|
||||||
<ul class="messages">
|
<ul class="messages">
|
||||||
{% for message in messages %}
|
{% for message in messages %}
|
||||||
<li{% if message.tags %} class="{{ message.tags }}"{% endif %}>{{ message }}</li>
|
<li {% if message.tags %}class="{{ message.tags }}"{% endif %}>{{ message }}</li>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
|
@ -7,148 +7,136 @@
|
||||||
{% load thumb %}
|
{% load thumb %}
|
||||||
{% load collection %}
|
{% load collection %}
|
||||||
{% load bleach_tags %}
|
{% load bleach_tags %}
|
||||||
|
|
||||||
<div class="grid__aside grid__aside--reverse-order grid__aside--tablet-column">
|
<div class="grid__aside grid__aside--reverse-order grid__aside--tablet-column">
|
||||||
<div class="aside-section-wrapper aside-section-wrapper--no-margin">
|
<div class="aside-section-wrapper aside-section-wrapper--no-margin">
|
||||||
<div class="user-profile" id="userInfoCard">
|
<div class="user-profile" id="userInfoCard">
|
||||||
<div class="user-profile__header">
|
<div class="user-profile__header">
|
||||||
<!-- <img src="" class="user-profile__avatar mast-avatar" alt="{{ user.username }}"> -->
|
<!-- <img src=""
|
||||||
<img src="{{ user.mastodon_account.avatar }}" class="user-profile__avatar mast-avatar">
|
class="user-profile__avatar mast-avatar"
|
||||||
<a href="{% url 'journal:user_profile' user.mastodon_username %}">
|
alt="{{ user.username }}"> -->
|
||||||
<h5 class="user-profile__username mast-displayname">{{ user.mastodon_account.display_name }}</h5>
|
<img src="{{ user.mastodon_account.avatar }}"
|
||||||
</a>
|
class="user-profile__avatar mast-avatar"
|
||||||
<!-- {{ user.id }} -->
|
alt="">
|
||||||
</div>
|
<a href="{% url 'journal:user_profile' user.mastodon_username %}">
|
||||||
<p><a class="user-profile__link mast-acct" target="_blank" rel="me noopener" href="{{ user.mastodon_account.url }}">@{{ user.username }}@{{ user.mastodon_site }}</a>
|
<h5 class="user-profile__username mast-displayname">{{ user.mastodon_account.display_name }}</h5>
|
||||||
{% current_user_relationship user as relationship %}
|
</a>
|
||||||
{% if relationship %}
|
<!-- {{ user.id }} -->
|
||||||
<a class="user-profile__report-link">
|
</div>
|
||||||
{{ relationship }}
|
<p>
|
||||||
</a>
|
<a class="user-profile__link mast-acct"
|
||||||
{% endif %}
|
target="_blank"
|
||||||
</p>
|
rel="me noopener"
|
||||||
<div class="relation-dropdown">
|
href="{{ user.mastodon_account.url }}">@{{ user.username }}@{{ user.mastodon_site }}</a>
|
||||||
<div class="relation-dropdown__body">
|
{% current_user_relationship user as relationship %}
|
||||||
<p class="user-profile__bio mast-brief">{{ user.mastodon_account.note|bleach:"a,p,span,br" }}</p>
|
{% if relationship %}<a class="user-profile__report-link">{{ relationship }}</a>{% endif %}
|
||||||
{% if request.user != user %}
|
</p>
|
||||||
<a href="{% url 'users:report' %}?user_id={{ user.id }}"
|
<div class="relation-dropdown">
|
||||||
class="user-profile__report-link">{% trans '投诉用户' %}</a>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="relation-dropdown">
|
|
||||||
<div class="relation-dropdown__button">
|
|
||||||
<span class="icon-arrow">
|
|
||||||
<i class="fas fa-angle-down"></i>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
{% if user.featured_collections.all %}
|
|
||||||
<div class="relation-dropdown__body">
|
<div class="relation-dropdown__body">
|
||||||
<div class="aside-section-wrapper aside-section-wrapper--transparent aside-section-wrapper--collapse">
|
<p class="user-profile__bio mast-brief">{{ user.mastodon_account.note|bleach:"a,p,span,br" }}</p>
|
||||||
<div class="user-relation">
|
{% if request.user != user %}
|
||||||
<h5 class="user-relation__label">
|
<a href="{% url 'users:report' %}?user_id={{ user.id }}"
|
||||||
{% trans '当前目标' %}
|
class="user-profile__report-link">{% trans '投诉用户' %}</a>
|
||||||
</h5>
|
{% endif %}
|
||||||
{% for featured_collection in user.featured_collections.all %}
|
|
||||||
{% user_visibility_of featured_collection as visible %}
|
|
||||||
{% if visible %}
|
|
||||||
{% user_progress_of collection=featured_collection user=user as progress %}
|
|
||||||
<div class="tag-collection" style="margin-left: 10%;">
|
|
||||||
<a href="{{ featured_collection.collection.url }}">{{ featured_collection.collection.title }}</a><br>
|
|
||||||
已完成{{ progress }}% <br>
|
|
||||||
<progress value="{{ progress }}" max="100">
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
{% endfor %}
|
|
||||||
<br>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
</div>
|
||||||
|
|
||||||
{% if user == request.user %}
|
|
||||||
<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.mastodon_username %}"
|
|
||||||
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.mastodon_username %}"
|
|
||||||
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>
|
|
||||||
|
|
||||||
{% if top_tags %}
|
|
||||||
<div class="user-relation">
|
|
||||||
<h5 class="user-relation__label">
|
|
||||||
{% trans '常用标签' %}
|
|
||||||
</h5>
|
|
||||||
<a href="{% url 'journal:user_tag_list' user.mastodon_username %}">{% trans '更多' %}</a>
|
|
||||||
<div class="tag-collection" style="margin-left: 0;">
|
|
||||||
{% for t in top_tags %}
|
|
||||||
<span class="tag-collection__tag">
|
|
||||||
<a href="/users/{{ user.mastodon_username }}/tags/{{ t }}/">{{ t }}</a>
|
|
||||||
</span>
|
|
||||||
{% endfor %}
|
|
||||||
<div class="clearfix"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="relation-dropdown">
|
||||||
|
<div class="relation-dropdown__button">
|
||||||
|
<span class="icon-arrow">
|
||||||
|
<i class="fas fa-angle-down"></i>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
{% if user.featured_collections.all %}
|
||||||
|
<div class="relation-dropdown__body">
|
||||||
|
<div class="aside-section-wrapper aside-section-wrapper--transparent aside-section-wrapper--collapse">
|
||||||
|
<div class="user-relation">
|
||||||
|
<h5 class="user-relation__label">{% trans '当前目标' %}</h5>
|
||||||
|
{% for featured_collection in user.featured_collections.all %}
|
||||||
|
{% user_visibility_of featured_collection as visible %}
|
||||||
|
{% if visible %}
|
||||||
|
{% user_progress_of collection=featured_collection user=user as progress %}
|
||||||
|
<div class="tag-collection" style="margin-left: 10%;">
|
||||||
|
<a href="{{ featured_collection.collection.url }}">{{ featured_collection.collection.title }}</a>
|
||||||
|
<br>
|
||||||
|
已完成{{ progress }}%
|
||||||
|
<br>
|
||||||
|
<progress value="{{ progress }}" max="100" />
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
<br>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
{% if user == request.user %}
|
||||||
|
<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.mastodon_username %}"
|
||||||
|
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.mastodon_username %}"
|
||||||
|
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>
|
||||||
|
{% if top_tags %}
|
||||||
|
<div class="user-relation">
|
||||||
|
<h5 class="user-relation__label">{% trans '常用标签' %}</h5>
|
||||||
|
<a href="{% url 'journal:user_tag_list' user.mastodon_username %}">{% trans '更多' %}</a>
|
||||||
|
<div class="tag-collection" style="margin-left: 0;">
|
||||||
|
{% for t in top_tags %}
|
||||||
|
<span class="tag-collection__tag">
|
||||||
|
<a href="{% url 'journal:user_tag_member_list' user.mastodon_username t %}">{{ t }}</a>
|
||||||
|
</span>
|
||||||
|
{% endfor %}
|
||||||
|
<div class="clearfix"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{% if user == request.user %}
|
{% if user == request.user %}
|
||||||
<div id="oauth2Token" hidden="true">{{ request.user.mastodon_token }}</div>
|
<div id="oauth2Token" hidden="true">{{ request.user.mastodon_token }}</div>
|
||||||
<div id="mastodonURI" hidden="true">{{ request.user.mastodon_site }}</div>
|
<div id="mastodonURI" hidden="true">{{ request.user.mastodon_site }}</div>
|
||||||
<div id="userMastodonID" hidden="true">{{ user.mastodon_id }}</div>
|
<div id="userMastodonID" hidden="true">{{ user.mastodon_id }}</div>
|
||||||
<div id="userPageURL" hidden="true">{% url 'journal:user_profile' 0 %}</div>
|
<div id="userPageURL" hidden="true">{% url 'journal:user_profile' 0 %}</div>
|
||||||
|
<div id="spinner" hidden>
|
||||||
<div id="spinner" hidden>
|
|
||||||
<div class="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>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
28
common/templates/partial/_sidebar_anonymous.html
Normal file
28
common/templates/partial/_sidebar_anonymous.html
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
{% load static %}
|
||||||
|
{% load i18n %}
|
||||||
|
{% load admin_url %}
|
||||||
|
{% load mastodon %}
|
||||||
|
{% load oauth_token %}
|
||||||
|
{% load truncate %}
|
||||||
|
{% load thumb %}
|
||||||
|
{% load collection %}
|
||||||
|
{% load bleach_tags %}
|
||||||
|
<div class="grid__aside grid__aside--reverse-order">
|
||||||
|
<section>
|
||||||
|
<article>
|
||||||
|
<h3>欢迎 🙋🏻♀️ 🙋🏻 🙋🏻♂️</h3>
|
||||||
|
<p>
|
||||||
|
<i class="fa-solid fa-puzzle-piece"></i> {{ site_name }}致力于提供一个涵盖书籍、影视、音乐、游戏、播客的自由开放互联的收藏评论空间。 你可以在这里记录你的收藏和想法,以及发现新的内容和朋友。
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<i class="fa-solid fa-globe"></i> 登录{{ site_name }}需要一个联邦网络(Fediverse,也被称为长毛象)实例账号,如果你还没有账号,可以<a href="https://joinmastodon.org/zh/servers" target="_blank">到这里注册</a>。
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<i class="fa-solid fa-circle-question"></i> 如果有任何问题或建议,欢迎通过<a href="https://mastodon.social/@neodb">联邦网络</a>或<a href="https://discord.gg/uprvcH8gqD">Discord</a>和我们联系。
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<i class="fa-solid fa-door-open"></i> <a href="/users/login/">点击这里</a>登录。
|
||||||
|
</p>
|
||||||
|
</article>
|
||||||
|
</section>
|
||||||
|
</div>
|
|
@ -9,23 +9,25 @@
|
||||||
margin-left: 1%;
|
margin-left: 1%;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
<div class="widget-value-key-input" name='{{ widget.name }}'{% include "django/forms/widgets/attrs.html" %}>
|
<div class="widget-value-key-input"
|
||||||
{% if widget.value != None %}
|
name='{{ widget.name }}'
|
||||||
|
{% include "django/forms/widgets/attrs.html" %}>
|
||||||
|
{% if widget.value != None %}
|
||||||
{% for pair in widget.value %}
|
{% for pair in widget.value %}
|
||||||
|
{% for k, v in pair.items %}
|
||||||
{% for k, v in pair.items %}
|
<input type="text" value="{{ k }}">
|
||||||
<input type="text" value="{{ k }}"><input type="text" value="{{ v }}">
|
<input type="text" value="{{ v }}">
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
{% endif %}
|
|
||||||
</div>
|
</div>
|
||||||
<input type="text" class="widget-value-key-input-data" hidden name="{{ widget.name }}">
|
<input type="text"
|
||||||
|
class="widget-value-key-input-data"
|
||||||
|
hidden
|
||||||
|
name="{{ widget.name }}">
|
||||||
<script>
|
<script>
|
||||||
keyValueInput(
|
keyValueInput(
|
||||||
$(".widget-value-key-input[name='{{ widget.name }}']"),
|
$(".widget-value-key-input[name='{{ widget.name }}']"),
|
||||||
$(".widget-value-key-input-data[name='{{ widget.name }}']")
|
$(".widget-value-key-input-data[name='{{ widget.name }}']")
|
||||||
);
|
);
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -1,5 +1,11 @@
|
||||||
<input type="{{ widget.type }}" name="{{ widget.name }}"{% include "django/forms/widgets/attrs.html" %}>
|
<input type="{{ widget.type }}"
|
||||||
<img src="{{ widget.value|default_if_none:''|stringformat:'s' }}" alt="" id="previewImage" style="margin:10px 0; max-width:500px;">
|
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">
|
||||||
<script>
|
<script>
|
||||||
$("input[type='file'][name='{{ widget.name }}']").on("change", function () {
|
$("input[type='file'][name='{{ widget.name }}']").on("change", function () {
|
||||||
if (this.files && this.files[0]) {
|
if (this.files && this.files[0]) {
|
||||||
|
|
|
@ -1,8 +1,12 @@
|
||||||
<select name="{{ widget.name }}"
|
<select name="{{ widget.name }}"
|
||||||
{% include "django/forms/widgets/attrs.html" %}>{% for group_name, group_choices, group_index in widget.optgroups %}{% if group_name %}
|
{% include "django/forms/widgets/attrs.html" %}>
|
||||||
<optgroup label="{{ group_name }}">{% endif %}{% for option in group_choices %}
|
{% for group_name, group_choices, group_index in widget.optgroups %}
|
||||||
{% include option.template_name with widget=option %}{% endfor %}{% if group_name %}
|
{% if group_name %}<optgroup label="{{ group_name }}">{% endif %}
|
||||||
</optgroup>{% endif %}{% endfor %}
|
{% for option in group_choices %}
|
||||||
|
{% include option.template_name with widget=option %}
|
||||||
|
{% endfor %}
|
||||||
|
{% if group_name %}</optgroup>{% endif %}
|
||||||
|
{% endfor %}
|
||||||
</select>
|
</select>
|
||||||
<script>
|
<script>
|
||||||
$('select[name="{{ widget.name }}"]').multipleSelect({
|
$('select[name="{{ widget.name }}"]').multipleSelect({
|
||||||
|
@ -13,4 +17,4 @@
|
||||||
minimumCountSelected: 50,
|
minimumCountSelected: 50,
|
||||||
filter: true,
|
filter: true,
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -1,17 +1,14 @@
|
||||||
<div class="tag-input">
|
<div class="tag-input">
|
||||||
<input type="text" name="{{ widget.name }}" {% include "django/forms/widgets/attrs.html" %}>
|
<input type="text"
|
||||||
|
name="{{ widget.name }}"
|
||||||
|
{% include "django/forms/widgets/attrs.html" %}>
|
||||||
</div>
|
</div>
|
||||||
<script>
|
<script>
|
||||||
new inputTags({
|
new inputTags({
|
||||||
container: document.getElementsByClassName("tag-input")[0],
|
container: document.getElementsByClassName("tag-input")[0],
|
||||||
tags : [{% for tag in widget.value %}"{{ tag }}",{% endfor %}],
|
tags : [{% for tag in widget.value %}"{{ tag }}",{% endfor %}],
|
||||||
allowDuplicateTags : false,
|
allowDuplicateTags : false,
|
||||||
duplicateTime: 300,
|
duplicateTime: 300,
|
||||||
onTagRemove : function (tag) {},
|
onTagRemove : function (tag) {},
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
from django import template
|
from django import template
|
||||||
from django.template.defaultfilters import stringfilter
|
from django.template.defaultfilters import stringfilter
|
||||||
from django.utils.text import Truncator
|
from django.utils.text import Truncator
|
||||||
|
from django.utils.safestring import mark_safe
|
||||||
|
|
||||||
register = template.Library()
|
register = template.Library()
|
||||||
|
|
||||||
|
@ -14,3 +15,19 @@ def duration_format(value, unit):
|
||||||
s = duration % 60
|
s = duration % 60
|
||||||
return f"{h}:{m:02}:{s:02}" if h else f"{m}:{s:02}"
|
return f"{h}:{m:02}:{s:02}" if h else f"{m}:{s:02}"
|
||||||
# return (f"{h}小时 " if h else "") + (f"{m}分钟" if m else "")
|
# return (f"{h}小时 " if h else "") + (f"{m}分钟" if m else "")
|
||||||
|
|
||||||
|
|
||||||
|
@register.filter(is_safe=True)
|
||||||
|
@stringfilter
|
||||||
|
def rating_star(value):
|
||||||
|
try:
|
||||||
|
v = float(value or 0)
|
||||||
|
except ValueError:
|
||||||
|
v = 0
|
||||||
|
pct = round(10 * v)
|
||||||
|
if pct > 100:
|
||||||
|
pct = 100
|
||||||
|
elif pct < 0:
|
||||||
|
pct = 0
|
||||||
|
html = f'<span class="rating-star" data-rating="{v}"><div style="width:{pct}%;"></div></span>'
|
||||||
|
return mark_safe(html)
|
||||||
|
|
|
@ -2,7 +2,7 @@ from django import template
|
||||||
from django.utils.safestring import mark_safe
|
from django.utils.safestring import mark_safe
|
||||||
from django.template.defaultfilters import stringfilter
|
from django.template.defaultfilters import stringfilter
|
||||||
from opencc import OpenCC
|
from opencc import OpenCC
|
||||||
|
import re
|
||||||
|
|
||||||
cc = OpenCC("t2s")
|
cc = OpenCC("t2s")
|
||||||
register = template.Library()
|
register = template.Library()
|
||||||
|
@ -23,7 +23,7 @@ def highlight(text, search):
|
||||||
m = None
|
m = None
|
||||||
for w in words:
|
for w in words:
|
||||||
if otext[i : i + len(w)] == w:
|
if otext[i : i + len(w)] == w:
|
||||||
m = f'<span class="highlight">{text[i:i+len(w)]}</span>'
|
m = f"<mark>{text[i:i+len(w)]}</mark>"
|
||||||
i += len(w)
|
i += len(w)
|
||||||
break
|
break
|
||||||
if not m:
|
if not m:
|
||||||
|
@ -31,3 +31,9 @@ def highlight(text, search):
|
||||||
i += 1
|
i += 1
|
||||||
rtext += m
|
rtext += m
|
||||||
return mark_safe(rtext)
|
return mark_safe(rtext)
|
||||||
|
|
||||||
|
|
||||||
|
@register.filter
|
||||||
|
@stringfilter
|
||||||
|
def strip_season(text):
|
||||||
|
return re.sub(r"\s*第\s*\d+\s*季$", "", text)
|
||||||
|
|
|
@ -4,6 +4,7 @@ from .views import *
|
||||||
app_name = "common"
|
app_name = "common"
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path("", home),
|
path("", home),
|
||||||
path("api-doc/", api_doc),
|
path("api-doc/", api_doc, name="api_doc"),
|
||||||
path("home/", home, name="home"),
|
path("home/", home, name="home"),
|
||||||
|
path("me/", me, name="me"),
|
||||||
]
|
]
|
||||||
|
|
|
@ -6,14 +6,23 @@ from .api import api
|
||||||
|
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
|
def me(request):
|
||||||
|
return redirect(
|
||||||
|
reverse("journal:user_profile", args=[request.user.mastodon_username])
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def home(request):
|
def home(request):
|
||||||
home = request.user.get_preference().classic_homepage
|
if request.user.is_authenticated:
|
||||||
if home == 1:
|
home = request.user.get_preference().classic_homepage
|
||||||
return redirect(
|
if home == 1:
|
||||||
reverse("journal:user_profile", args=[request.user.mastodon_username])
|
return redirect(
|
||||||
)
|
reverse("journal:user_profile", args=[request.user.mastodon_username])
|
||||||
elif home == 2:
|
)
|
||||||
return redirect(reverse("social:feed"))
|
elif home == 2:
|
||||||
|
return redirect(reverse("social:feed"))
|
||||||
|
else:
|
||||||
|
return redirect(reverse("catalog:discover"))
|
||||||
else:
|
else:
|
||||||
return redirect(reverse("catalog:discover"))
|
return redirect(reverse("catalog:discover"))
|
||||||
|
|
||||||
|
|
|
@ -47,6 +47,7 @@ Build static assets
|
||||||
```
|
```
|
||||||
python3 manage.py sass common/static/sass/boofilsic.sass common/static/css/boofilsic.min.css -t compressed
|
python3 manage.py sass common/static/sass/boofilsic.sass common/static/css/boofilsic.min.css -t compressed
|
||||||
python3 manage.py sass common/static/sass/boofilsic.sass common/static/css/boofilsic.css
|
python3 manage.py sass common/static/sass/boofilsic.sass common/static/css/boofilsic.css
|
||||||
|
python3 manage.py compilescss
|
||||||
python3 manage.py collectstatic
|
python3 manage.py collectstatic
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
|
@ -156,12 +156,6 @@ class Content(Piece):
|
||||||
metadata = models.JSONField(default=dict)
|
metadata = models.JSONField(default=dict)
|
||||||
item = models.ForeignKey(Item, on_delete=models.PROTECT)
|
item = models.ForeignKey(Item, on_delete=models.PROTECT)
|
||||||
|
|
||||||
@cached_property
|
|
||||||
def mark(self):
|
|
||||||
m = Mark(self.owner, self.item)
|
|
||||||
m.review = self
|
|
||||||
return m
|
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return f"{self.uuid}@{self.item}"
|
return f"{self.uuid}@{self.item}"
|
||||||
|
|
||||||
|
@ -221,6 +215,16 @@ class Comment(Content):
|
||||||
def html(self):
|
def html(self):
|
||||||
return render_text(self.text)
|
return render_text(self.text)
|
||||||
|
|
||||||
|
@cached_property
|
||||||
|
def rating_grade(self):
|
||||||
|
return Rating.get_item_rating_by_user(self.item, self.owner)
|
||||||
|
|
||||||
|
@cached_property
|
||||||
|
def mark(self):
|
||||||
|
m = Mark(self.owner, self.item)
|
||||||
|
m.comment = self
|
||||||
|
return m
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def item_url(self):
|
def item_url(self):
|
||||||
if self.focus_item:
|
if self.focus_item:
|
||||||
|
@ -259,6 +263,19 @@ class Review(Content):
|
||||||
def html_content(self):
|
def html_content(self):
|
||||||
return render_md(self.body)
|
return render_md(self.body)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def plain_content(self):
|
||||||
|
html = render_md(self.body)
|
||||||
|
return _RE_HTML_TAG.sub(
|
||||||
|
" ", _RE_SPOILER_TAG.sub("***", html.replace("\n", " "))
|
||||||
|
)
|
||||||
|
|
||||||
|
@cached_property
|
||||||
|
def mark(self):
|
||||||
|
m = Mark(self.owner, self.item)
|
||||||
|
m.review = self
|
||||||
|
return m
|
||||||
|
|
||||||
@cached_property
|
@cached_property
|
||||||
def rating_grade(self):
|
def rating_grade(self):
|
||||||
return Rating.get_item_rating_by_user(self.item, self.owner)
|
return Rating.get_item_rating_by_user(self.item, self.owner)
|
||||||
|
@ -291,6 +308,9 @@ class Review(Content):
|
||||||
return review
|
return review
|
||||||
|
|
||||||
|
|
||||||
|
MIN_RATING_COUNT = 5
|
||||||
|
|
||||||
|
|
||||||
class Rating(Content):
|
class Rating(Content):
|
||||||
class Meta:
|
class Meta:
|
||||||
unique_together = [["owner", "item"]]
|
unique_together = [["owner", "item"]]
|
||||||
|
@ -304,7 +324,7 @@ class Rating(Content):
|
||||||
stat = Rating.objects.filter(item=item, grade__isnull=False).aggregate(
|
stat = Rating.objects.filter(item=item, grade__isnull=False).aggregate(
|
||||||
average=Avg("grade"), count=Count("item")
|
average=Avg("grade"), count=Count("item")
|
||||||
)
|
)
|
||||||
return round(stat["average"], 1) if stat["count"] >= 5 else None
|
return round(stat["average"], 1) if stat["count"] >= MIN_RATING_COUNT else None
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_rating_count_for_item(item):
|
def get_rating_count_for_item(item):
|
||||||
|
@ -337,9 +357,34 @@ class Rating(Content):
|
||||||
rating = Rating.objects.filter(owner=user, item=item).first()
|
rating = Rating.objects.filter(owner=user, item=item).first()
|
||||||
return rating.grade if rating else None
|
return rating.grade if rating else None
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get_rating_distribution_for_item(item):
|
||||||
|
stat = (
|
||||||
|
Rating.objects.filter(item=item, grade__isnull=False)
|
||||||
|
.values("grade")
|
||||||
|
.annotate(count=Count("grade"))
|
||||||
|
.order_by("grade")
|
||||||
|
)
|
||||||
|
g = [0] * 11
|
||||||
|
t = 0
|
||||||
|
for s in stat:
|
||||||
|
g[s["grade"]] = s["count"]
|
||||||
|
t += s["count"]
|
||||||
|
if t < MIN_RATING_COUNT:
|
||||||
|
return [0] * 5
|
||||||
|
r = [
|
||||||
|
100 * (g[1] + g[2]) // t,
|
||||||
|
100 * (g[3] + g[4]) // t,
|
||||||
|
100 * (g[5] + g[6]) // t,
|
||||||
|
100 * (g[7] + g[8]) // t,
|
||||||
|
100 * (g[9] + g[10]) // t,
|
||||||
|
]
|
||||||
|
return r
|
||||||
|
|
||||||
|
|
||||||
Item.rating = property(Rating.get_rating_for_item)
|
Item.rating = property(Rating.get_rating_for_item)
|
||||||
Item.rating_count = property(Rating.get_rating_count_for_item)
|
Item.rating_count = property(Rating.get_rating_count_for_item)
|
||||||
|
Item.rating_dist = property(Rating.get_rating_distribution_for_item)
|
||||||
|
|
||||||
|
|
||||||
class Reply(Piece):
|
class Reply(Piece):
|
||||||
|
@ -440,6 +485,17 @@ class List(Piece):
|
||||||
)
|
)
|
||||||
member.delete()
|
member.delete()
|
||||||
|
|
||||||
|
def update_member_order(self, ordered_member_ids):
|
||||||
|
members = self.ordered_members
|
||||||
|
for m in self.members.all():
|
||||||
|
try:
|
||||||
|
i = ordered_member_ids.index(m.id)
|
||||||
|
if m.position != i + 1:
|
||||||
|
m.position = i + 1
|
||||||
|
m.save()
|
||||||
|
except ValueError:
|
||||||
|
pass
|
||||||
|
|
||||||
def move_up_item(self, item):
|
def move_up_item(self, item):
|
||||||
members = self.ordered_members
|
members = self.ordered_members
|
||||||
member = self.get_member_for_item(item)
|
member = self.get_member_for_item(item)
|
||||||
|
@ -674,8 +730,11 @@ class ShelfManager:
|
||||||
def get_shelf(self, shelf_type):
|
def get_shelf(self, shelf_type):
|
||||||
return self.shelf_list[shelf_type]
|
return self.shelf_list[shelf_type]
|
||||||
|
|
||||||
def get_members(self, shelf_type, item_category):
|
def get_members(self, shelf_type, item_category=None):
|
||||||
return self.shelf_list[shelf_type].get_members_in_category(item_category)
|
if item_category:
|
||||||
|
return self.shelf_list[shelf_type].get_members_in_category(item_category)
|
||||||
|
else:
|
||||||
|
return self.shelf_list[shelf_type].members.all()
|
||||||
|
|
||||||
# def get_items_on_shelf(self, item_category, shelf_type):
|
# def get_items_on_shelf(self, item_category, shelf_type):
|
||||||
# shelf = (
|
# shelf = (
|
||||||
|
@ -748,6 +807,7 @@ class CollectionMember(ListMember):
|
||||||
|
|
||||||
|
|
||||||
_RE_HTML_TAG = re.compile(r"<[^>]*>")
|
_RE_HTML_TAG = re.compile(r"<[^>]*>")
|
||||||
|
_RE_SPOILER_TAG = re.compile(r'<(div|span)\sclass="spoiler">.*</(div|span)>')
|
||||||
|
|
||||||
|
|
||||||
class Collection(List):
|
class Collection(List):
|
||||||
|
@ -781,8 +841,9 @@ class Collection(List):
|
||||||
html = render_md(self.brief)
|
html = render_md(self.brief)
|
||||||
return _RE_HTML_TAG.sub(" ", html)
|
return _RE_HTML_TAG.sub(" ", html)
|
||||||
|
|
||||||
def is_featured_by_user(self, user):
|
def featured_by_user_since(self, user):
|
||||||
return self.featured_by_users.all().filter(id=user.id).exists()
|
f = FeaturedCollection.objects.filter(target=self, owner=user).first()
|
||||||
|
return f.created_time if f else None
|
||||||
|
|
||||||
def get_stats_for_user(self, user):
|
def get_stats_for_user(self, user):
|
||||||
items = list(self.members.all().values_list("item_id", flat=True))
|
items = list(self.members.all().values_list("item_id", flat=True))
|
||||||
|
@ -881,13 +942,15 @@ class TagManager:
|
||||||
return sorted(list(map(lambda t: t["title"], tags)))
|
return sorted(list(map(lambda t: t["title"], tags)))
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def all_tags_for_user(user):
|
def all_tags_for_user(user, public_only=False):
|
||||||
tags = (
|
tags = (
|
||||||
user.tag_set.all()
|
user.tag_set.all()
|
||||||
.values("title")
|
.values("title")
|
||||||
.annotate(frequency=Count("members__id"))
|
.annotate(frequency=Count("members__id"))
|
||||||
.order_by("-frequency")
|
.order_by("-frequency")
|
||||||
)
|
)
|
||||||
|
if public_only:
|
||||||
|
tags = tags.filter(visibility=0)
|
||||||
return list(map(lambda t: t["title"], tags))
|
return list(map(lambda t: t["title"], tags))
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
@ -935,6 +998,10 @@ class TagManager:
|
||||||
def all_tags(self):
|
def all_tags(self):
|
||||||
return TagManager.all_tags_for_user(self.owner)
|
return TagManager.all_tags_for_user(self.owner)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def public_tags(self):
|
||||||
|
return TagManager.all_tags_for_user(self.owner, public_only=True)
|
||||||
|
|
||||||
def add_item_tags(self, item, tags, visibility=0):
|
def add_item_tags(self, item, tags, visibility=0):
|
||||||
for tag in tags:
|
for tag in tags:
|
||||||
TagManager.add_tag_by_user(item, tag, self.owner, visibility)
|
TagManager.add_tag_by_user(item, tag, self.owner, visibility)
|
||||||
|
@ -1021,6 +1088,10 @@ class Mark:
|
||||||
def rating(self):
|
def rating(self):
|
||||||
return Rating.get_item_rating_by_user(self.item, self.owner)
|
return Rating.get_item_rating_by_user(self.item, self.owner)
|
||||||
|
|
||||||
|
@cached_property
|
||||||
|
def rating_grade(self):
|
||||||
|
return Rating.get_item_rating_by_user(self.item, self.owner)
|
||||||
|
|
||||||
@cached_property
|
@cached_property
|
||||||
def comment(self):
|
def comment(self):
|
||||||
return Comment.objects.filter(
|
return Comment.objects.filter(
|
||||||
|
@ -1059,7 +1130,8 @@ class Mark:
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
share_as_new_post = shelf_type != self.shelf_type
|
share_as_new_post = shelf_type != self.shelf_type
|
||||||
if shelf_type != self.shelf_type or visibility != self.visibility:
|
original_visibility = self.visibility
|
||||||
|
if shelf_type != self.shelf_type or visibility != original_visibility:
|
||||||
self.shelfmember = self.owner.shelf_manager.move_item(
|
self.shelfmember = self.owner.shelf_manager.move_item(
|
||||||
self.item, shelf_type, visibility=visibility, metadata=metadata
|
self.item, shelf_type, visibility=visibility, metadata=metadata
|
||||||
)
|
)
|
||||||
|
@ -1082,11 +1154,11 @@ class Mark:
|
||||||
metadata=self.metadata,
|
metadata=self.metadata,
|
||||||
timestamp=created_time,
|
timestamp=created_time,
|
||||||
)
|
)
|
||||||
if comment_text != self.text or visibility != self.visibility:
|
if comment_text != self.text or visibility != original_visibility:
|
||||||
self.comment = Comment.comment_item_by_user(
|
self.comment = Comment.comment_item_by_user(
|
||||||
self.item, self.owner, comment_text, visibility
|
self.item, self.owner, comment_text, visibility
|
||||||
)
|
)
|
||||||
if rating_grade != self.rating or visibility != self.visibility:
|
if rating_grade != self.rating or visibility != original_visibility:
|
||||||
Rating.rate_item_by_user(self.item, self.owner, rating_grade, visibility)
|
Rating.rate_item_by_user(self.item, self.owner, rating_grade, visibility)
|
||||||
self.rating = rating_grade
|
self.rating = rating_grade
|
||||||
if share:
|
if share:
|
||||||
|
@ -1120,7 +1192,7 @@ class Mark:
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def reset_visibility_for_user(user: User, visibility: int):
|
def reset_journal_visibility_for_user(user: User, visibility: int):
|
||||||
ShelfMember.objects.filter(owner=user).update(visibility=visibility)
|
ShelfMember.objects.filter(owner=user).update(visibility=visibility)
|
||||||
Comment.objects.filter(owner=user).update(visibility=visibility)
|
Comment.objects.filter(owner=user).update(visibility=visibility)
|
||||||
Rating.objects.filter(owner=user).update(visibility=visibility)
|
Rating.objects.filter(owner=user).update(visibility=visibility)
|
||||||
|
|
|
@ -37,7 +37,7 @@ def _spolier(s):
|
||||||
r = l[1].split("!<", 1)
|
r = l[1].split("!<", 1)
|
||||||
return (
|
return (
|
||||||
escape(l[0])
|
escape(l[0])
|
||||||
+ '<span class="spoiler">'
|
+ '<span class="spoiler" _="on click toggle .revealed on me">'
|
||||||
+ escape(r[0])
|
+ escape(r[0])
|
||||||
+ "</span>"
|
+ "</span>"
|
||||||
+ (_spolier(r[1]) if len(r) == 2 else "")
|
+ (_spolier(r[1]) if len(r) == 2 else "")
|
||||||
|
|
17
journal/templates/_feature_stats.html
Normal file
17
journal/templates/_feature_stats.html
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
<form style="display:none"
|
||||||
|
action="{% if featured %}{% url 'journal:collection_remove_featured' collection.uuid %}{% else %}{% url 'journal:collection_add_featured' collection.uuid %}{% endif %}"
|
||||||
|
method="post"
|
||||||
|
id="feature-form">
|
||||||
|
{% csrf_token %}
|
||||||
|
</form>
|
||||||
|
{% if featured %}
|
||||||
|
<a class="activated"
|
||||||
|
title="停止追踪目标"
|
||||||
|
onclick="if (confirm('停止这个目标吗?')) $('#feature-form').submit();">
|
||||||
|
<i class="fa-solid fa-circle-dot"></i>
|
||||||
|
</a>
|
||||||
|
{% else %}
|
||||||
|
<a title="设为目标" onclick="$('#feature-form').submit()">
|
||||||
|
<i class="fa-regular fa-circle-dot"></i>
|
||||||
|
</a>
|
||||||
|
{% endif %}
|
|
@ -8,22 +8,27 @@
|
||||||
{% load truncate %}
|
{% load truncate %}
|
||||||
{% load highlight %}
|
{% load highlight %}
|
||||||
{% load thumb %}
|
{% load thumb %}
|
||||||
|
<div id="modal"
|
||||||
<div id="modal" _="on closeModal add .closing then wait for animationend then remove me">
|
_="on closeModal add .closing then wait for animationend then remove me">
|
||||||
<div class="modal-underlay" _="on click trigger closeModal"></div>
|
<div class="modal-underlay" _="on click trigger closeModal"></div>
|
||||||
<div class="modal-content">
|
<div class="modal-content">
|
||||||
<div class="add-to-list-modal__head">
|
<div class="add-to-list-modal__head">
|
||||||
<span class="add-to-list-modal__title">{% trans '添加到收藏单' %}</span>
|
<span class="add-to-list-modal__title">{% trans '添加到收藏单' %}</span>
|
||||||
<span class="add-to-list-modal__close-button modal-close" _="on click trigger closeModal">
|
<span class="add-to-list-modal__close-button modal-close"
|
||||||
|
_="on click trigger closeModal">
|
||||||
<i class="fa-solid fa-xmark"></i>
|
<i class="fa-solid fa-xmark"></i>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="add-to-list-modal__body">
|
<div class="add-to-list-modal__body">
|
||||||
<form action="{% url 'journal:add_to_collection' item.uuid %}" method="post">
|
<form action="{% url 'journal:add_to_collection' item.uuid %}"
|
||||||
|
method="post">
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
<select name="collection_id">
|
<select name="collection_id">
|
||||||
{% for collection in collections %}
|
{% for collection in collections %}
|
||||||
<option value="{{ collection.id }}">{{ collection.title }}{% if collection.visibility > 0 %}🔒{% endif %}</option>
|
<option value="{{ collection.id }}">
|
||||||
|
{{ collection.title }}
|
||||||
|
{% if collection.visibility > 0 %}🔒{% endif %}
|
||||||
|
</option>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
<option value="0">新建收藏单</option>
|
<option value="0">新建收藏单</option>
|
||||||
</select>
|
</select>
|
||||||
|
@ -31,7 +36,7 @@
|
||||||
<textarea type="text" name="note" placeholder="条目备注"></textarea>
|
<textarea type="text" name="note" placeholder="条目备注"></textarea>
|
||||||
</div>
|
</div>
|
||||||
<div class="add-to-list-modal__confirm-button">
|
<div class="add-to-list-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>
|
||||||
|
|
|
@ -1 +1,18 @@
|
||||||
{{ calendar_data|json_script:"calendar_data" }}
|
{{ calendar_data|json_script:"calendar_data" }}
|
||||||
|
<script>
|
||||||
|
$(".calendar_view").calendar_yearview_blocks({
|
||||||
|
data: $("#calendar_data").text(),
|
||||||
|
start_monday: false,
|
||||||
|
always_show_tooltip: false,
|
||||||
|
month_names: ['一月', '二月', '三月', '四月', '五月', '六月', '七月', '八月', '九月', '十月', '十一月', '十二月'],
|
||||||
|
day_names: ['', '', ''],
|
||||||
|
colors: {
|
||||||
|
'default': getComputedStyle(document.documentElement).getPropertyValue('--pico-form-element-background-color'),
|
||||||
|
'book': '#B4D2A5',
|
||||||
|
'movie': '#7CBDFE',
|
||||||
|
'music': '#FEA36D',
|
||||||
|
'game': '#C5A290',
|
||||||
|
'other': '#9D6AB0'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
|
@ -9,187 +9,130 @@
|
||||||
{% load thumb %}
|
{% load thumb %}
|
||||||
{% load collection %}
|
{% load collection %}
|
||||||
{% load user_actions %}
|
{% load user_actions %}
|
||||||
|
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en" class="content-page">
|
||||||
|
<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"
|
||||||
<meta property="og:title" content="{{ site_name }} {% trans '收藏单' %} - {{ collection.title }}">
|
content="{{ site_name }}{% trans '收藏单' %} - {{ collection.title }}">
|
||||||
<meta property="og:description" content="{{ collection.description }}">
|
<meta property="og:description" content="{{ collection.description }}">
|
||||||
<meta property="og:type" content="article">
|
<meta property="og:type" content="article">
|
||||||
<meta property="og:article:author" content="{{ collection.owner.username }}">
|
<meta property="og:article:author"
|
||||||
<meta property="og:url" content="{{ request.build_absolute_uri }}">
|
content="{{ collection.owner.username }}">
|
||||||
<meta property="og:image" content="{{ collection.cover|thumb:'normal' }}">
|
<meta property="og:url" content="{{ request.build_absolute_uri }}">
|
||||||
|
<meta property="og:image" content="{{ collection.cover|thumb:'normal' }}">
|
||||||
<title>{{ site_name }} {% trans '收藏单' %} - {{ collection.title }}</title>
|
<title>{{ site_name }} {% trans '收藏单' %} - {{ collection.title }}</title>
|
||||||
|
{% include "common_libs.html" with jquery=0 v2=1 %}
|
||||||
{% include "common_libs.html" with jquery=0 %}
|
</head>
|
||||||
</head>
|
<body>
|
||||||
|
{% include "_header.html" %}
|
||||||
<body>
|
<main>
|
||||||
<div id="page-wrapper">
|
<div class="grid__main">
|
||||||
<div id="content-wrapper">
|
<article>
|
||||||
{% include "partial/_navbar.html" %}
|
<header>
|
||||||
|
<hgroup>
|
||||||
<section id="content">
|
<h3>
|
||||||
<div class="grid">
|
<div class="action">
|
||||||
<div class="grid__main" id="main">
|
{% if request.user.is_authenticated %}
|
||||||
<div class="main-section-wrapper">
|
|
||||||
<div class="review-head">
|
|
||||||
<h5 class="review-head__title">
|
|
||||||
{{ collection.title }}
|
|
||||||
</h5>
|
|
||||||
{% if collection.visibility > 0 %}
|
|
||||||
<i class="fa-solid fa-lock"></i>
|
|
||||||
{% endif %}
|
|
||||||
<div class="review-head__body">
|
|
||||||
<div class="review-head__info">
|
|
||||||
|
|
||||||
<a href="{% url 'journal:user_profile' collection.owner.mastodon_username %}" class="review-head__owner-link">{{ collection.owner.mastodon_username }}</a>
|
|
||||||
|
|
||||||
|
|
||||||
<span class="review-head__time">{{ collection.edited_time }}</span>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
<div class="action-bar">
|
|
||||||
<span>
|
<span>
|
||||||
{% liked_piece collection as liked %}
|
{% liked_piece collection as liked %}
|
||||||
{% include 'like_stats.html' with liked=liked piece=collection %}
|
{% include 'like_stats.html' with liked=liked piece=collection label='关注' icon='fa-bookmark' %}
|
||||||
</span>
|
</span>
|
||||||
{% if request.user == collection.owner %}
|
<span>{% include '_feature_stats.html' with featured=featured_since %}</span>
|
||||||
<span>
|
<span>
|
||||||
<a class="review-head__action-link" href="{% url 'journal:collection_edit' collection.uuid %}">{% trans '编辑' %}</a>
|
<a href="#"
|
||||||
<a class="review-head__action-link" href="{% url 'journal:collection_delete' collection.uuid %}">{% trans '删除' %}</a>
|
hx-get="{% url 'journal:collection_share' collection.uuid %}"
|
||||||
|
hx-target="body"
|
||||||
|
hx-swap="beforeend"
|
||||||
|
title="分享到联邦网络"><i class="fa-solid fa-share-nodes"></i></a>
|
||||||
</span>
|
</span>
|
||||||
{% elif editable %}
|
{% endif %}
|
||||||
<span class="review-head__time">可协作整理</span>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<!-- <div class="dividing-line"></div> --> <!-- <div class="entity-card__img-wrapper" style="text-align: center;"> <img src="{{ collection.cover|thumb:'normal' }}" alt="" class="entity-card__img"> </div> -->
|
|
||||||
<div class="markdown-content">
|
|
||||||
{{ collection.html | safe }}
|
|
||||||
</div>
|
</div>
|
||||||
|
{{ collection.title }}
|
||||||
|
{% if collection.visibility > 0 %}<small><i class="fa-solid fa-lock"></i></small>{% endif %}
|
||||||
|
</h3>
|
||||||
|
</hgroup>
|
||||||
|
<div class="owner-info">
|
||||||
|
<div class="owner">
|
||||||
|
<span class="avatar">
|
||||||
|
<img src="{{ collection.owner.mastodon_account.avatar }}"
|
||||||
|
alt="{{ collection.owner.username }}">
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="entity-list" hx-get="{% url 'journal:collection_retrieve_items' collection.uuid %}" hx-trigger="load">
|
<div class="info">
|
||||||
</div>
|
<p>
|
||||||
</div>
|
<a href="{% url 'journal:user_profile' collection.owner.mastodon_username %}">{{ collection.owner.mastodon_account.display_name }}</a>
|
||||||
</div>
|
<span class="handler">@{{ collection.owner.mastodon_username }}</span>
|
||||||
<div class="grid__aside" id="aside">
|
</p>
|
||||||
<div class="aside-section-wrapper">
|
<p>
|
||||||
<div class="entity-card">
|
{% for cat, count in collection.get_summary.items %}
|
||||||
<div class="entity-card__img-wrapper">
|
{% if count %}<span>{{ count }} {{ cat|prural_items }}</span> {% endif %}
|
||||||
<a href="{{ collection.url }}">
|
{% endfor %}
|
||||||
<img src="{{ collection.cover|thumb:'normal' }}" alt="" class="entity-card__img">
|
</p>
|
||||||
</a>
|
{% if featured_since %}
|
||||||
</div>
|
|
||||||
<div class="entity-card__info-wrapper">
|
|
||||||
<h5 class="entity-card__title">
|
|
||||||
<a href="{{ collection.url }}">
|
|
||||||
{{ collection.title }}
|
|
||||||
</a>
|
|
||||||
</h5>
|
|
||||||
<p>
|
<p>
|
||||||
{% for cat, count in collection.get_summary.items %}
|
<progress value="{{ stats.percentage }}"
|
||||||
{% if count %}
|
max="100"
|
||||||
{{count}}{{cat|prural_items}}
|
title="{{ stats.percentage }}%" />
|
||||||
{% endif %}
|
|
||||||
{% endfor %}
|
|
||||||
</p>
|
</p>
|
||||||
|
{% endif %}
|
||||||
|
<div class="markdown-content">{{ collection.html | safe }}</div>
|
||||||
|
</div>
|
||||||
|
<div class="more">
|
||||||
|
<div style="text-align: center;">
|
||||||
|
<img src="{{ collection.cover|thumb:'normal' }}" alt="">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</header>
|
||||||
{% if is_featured %}
|
{% comment %}
|
||||||
<div class="aside-section-wrapper">
|
{% if featured_since %}
|
||||||
<div class="action-panel">
|
<section style="min-width:10vw;">
|
||||||
<div class="donut" style="background: conic-gradient(#7CBDFE 0deg {{ stats.complete_deg }}deg, #B4D2A5 {{ stats.complete_deg }}deg {{ stats.complete_deg|add:stats.progress_deg }}deg, #ccc {{ stats.complete_deg|add:stats.progress_deg }}deg 1deg );"><div class="hole"><div class="text">
|
<div class="donut" style="background: conic-gradient(#7CBDFE 0deg {{ stats.complete_deg }}deg, #B4D2A5 {{ stats.complete_deg }}deg {{ stats.complete_deg|add:stats.progress_deg }}deg, #ccc {{ stats.complete_deg|add:stats.progress_deg }}deg 1deg );"><div class="hole"><div class="text">
|
||||||
{% if stats.progress %}
|
{% if stats.progress %}
|
||||||
{{ stats.progress }} 进行中<br>
|
{{ stats.progress }} 进行中<br>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if stats.complete %}
|
{% if stats.complete %}
|
||||||
{{ stats.complete }} 已完成
|
{{ stats.complete }} 已完成
|
||||||
{% elif not stats.progress %}
|
{% elif not stats.progress %}
|
||||||
尚未开始
|
尚未开始
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div></div></div>
|
</div></div></div>
|
||||||
</div>
|
<div style="margin:8px; color:lightgray" class="muted">
|
||||||
|
开始于{{ featured_since|date }}
|
||||||
<div class="action-panel" style="margin-bottom: 0;">
|
<a class="muted" href="#" title="停止" onclick="if (confirm('停止这个目标吗?')) $('#stop-featured').submit();"><i class="fa-solid fa-ban"></i></a>
|
||||||
<div class="action-panel__button-group action-panel__button-group--center">
|
<form action="{% url 'journal:collection_remove_featured' collection.uuid %}" method="post" id="stop-featured">
|
||||||
<form action="{% url 'journal:collection_remove_featured' collection.uuid %}" method="post">
|
{% csrf_token %}
|
||||||
{% csrf_token %}
|
</form>
|
||||||
<button class="action-panel__button" title="点击取消目标设置">{% trans '当前进度' %} {{ stats.percentage }}%</button>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
</section>
|
||||||
|
{% endif %}
|
||||||
{% if available_as_featured %}
|
{% endcomment %}
|
||||||
<div class="aside-section-wrapper">
|
<section>
|
||||||
<div class="action-panel">
|
<div class="entity-list"
|
||||||
<div class="action-panel__button-group action-panel__button-group--center">
|
hx-get="{% url 'journal:collection_retrieve_items' collection.uuid %}"
|
||||||
<form action="{% url 'journal:collection_add_featured' collection.uuid %}" method="post">
|
hx-trigger="load"></div>
|
||||||
{% csrf_token %}
|
</section>
|
||||||
<button class="action-panel__button">{% trans '设为目标' %}</button>
|
<footer>
|
||||||
</form>
|
<div class="action">
|
||||||
</div>
|
{% if request.user == collection.owner %}
|
||||||
</div>
|
<span>
|
||||||
|
<a href="{% url 'journal:collection_edit' collection.uuid %}">{% trans '编辑' %}</a>
|
||||||
|
</span>
|
||||||
|
<span>
|
||||||
|
<a href="{% url 'journal:collection_delete' collection.uuid %}">{% trans '删除' %}</a>
|
||||||
|
</span>
|
||||||
|
{% elif editable %}
|
||||||
|
<a href="{% url 'journal:collection_edit' collection.uuid %}">{% trans '协助整理' %}</a>
|
||||||
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
<span>创建于 {{ collection.created_time | date }}</span>
|
||||||
|
</footer>
|
||||||
{% if not is_featured and request.user.is_authenticated and request.user != collection.owner %}
|
</article>
|
||||||
<div class="aside-section-wrapper">
|
</div>
|
||||||
<div class="action-panel">
|
{% include "_sidebar.html" with user=collection.owner show_profile=1 %}
|
||||||
<div class="action-panel__button-group action-panel__button-group--center">
|
</main>
|
||||||
{% if following %}
|
|
||||||
<form action="{% url 'journal:unlike' collection.uuid %}?back=1" method="post">
|
|
||||||
{% csrf_token %}
|
|
||||||
<button class="action-panel__button">{% trans '取消关注' %}</button>
|
|
||||||
</form>
|
|
||||||
{% else %}
|
|
||||||
<form action="{% url 'journal:like' collection.uuid %}?back=1" method="post">
|
|
||||||
{% csrf_token %}
|
|
||||||
<button class="action-panel__button">{% trans '关注' %}</button>
|
|
||||||
</form>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
{% if request.user.is_authenticated %}
|
|
||||||
<div class="aside-section-wrapper">
|
|
||||||
<div class="action-panel">
|
|
||||||
<div class="action-panel__button-group action-panel__button-group--center">
|
|
||||||
<form>
|
|
||||||
<button class="action-panel__button add-to-list" hx-get="{% url 'journal:collection_share' collection.uuid %}" hx-target="body" hx-swap="beforeend">{% trans '分享到联邦网络' %}</button>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
</div>
|
|
||||||
{% include "partial/_footer.html" %}
|
{% include "partial/_footer.html" %}
|
||||||
</div>
|
</body>
|
||||||
|
|
||||||
|
|
||||||
<script>
|
|
||||||
$(".markdownx textarea").hide();
|
|
||||||
</script>
|
|
||||||
<script>
|
|
||||||
document.body.addEventListener('htmx:configRequest', (event) => {
|
|
||||||
event.detail.headers['X-CSRFToken'] = '{{ csrf_token }}';
|
|
||||||
})
|
|
||||||
</script>
|
|
||||||
</body>
|
|
||||||
|
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -5,47 +5,56 @@
|
||||||
{% load oauth_token %}
|
{% load oauth_token %}
|
||||||
{% load truncate %}
|
{% load truncate %}
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en" class="content-page">
|
||||||
|
<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>{{ site_name }} - 编辑收藏单 - {{ title }}</title>
|
||||||
<title>{{ site_name }} - 编辑收藏单 - {{ title }}</title>
|
{% include "common_libs.html" with jquery=0 v2=1 %}
|
||||||
{% include "common_libs.html" with jquery=0 %}
|
<script src="https://cdn.staticfile.org/html5sortable/0.13.3/html5sortable.min.js"
|
||||||
<style type="text/css">
|
crossorigin="anonymous"></script>
|
||||||
#id_collaborative li, #id_visibility li {display: inline-block !important;}
|
<style type="text/css">
|
||||||
</style>
|
#id_collaborative li, #id_visibility li {display: inline-block !important;}
|
||||||
</head>
|
.grid__main details {
|
||||||
|
margin: 2rem 0;
|
||||||
<body>
|
}
|
||||||
<div id="page-wrapper">
|
</style>
|
||||||
{% include "partial/_navbar.html" %}
|
</head>
|
||||||
<div id="content-wrapper">
|
<body>
|
||||||
<section id="content" class="container">
|
{% include "_header.html" %}
|
||||||
<div class="grid">
|
<main>
|
||||||
<div class="single-section-wrapper" id="main">
|
<div class="grid__main">
|
||||||
<form class="entity-form markdown-content" method="post" enctype="multipart/form-data">
|
<h4>
|
||||||
{% csrf_token %}
|
|
||||||
{{ form }}
|
|
||||||
<input class="button" type="submit" value="{% trans '提交' %}">
|
|
||||||
</form>
|
|
||||||
{{ form.media }}
|
|
||||||
</div>
|
|
||||||
{% if collection %}
|
{% if collection %}
|
||||||
<div class="dividing-line"></div>
|
编辑 <a href="{{ collection.url }}">{{ collection.title }}</a>
|
||||||
<div class="single-section-wrapper">
|
{% else %}
|
||||||
<div id="collection_items" class="entity-list" hx-get="{% url 'journal:collection_retrieve_items' collection.uuid %}?edit=1" hx-trigger="load"></div>
|
创建收藏单
|
||||||
</div>
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</h4>
|
||||||
</section>
|
<hr>
|
||||||
</div>
|
<details {% if not collection %}open{% endif %}>
|
||||||
|
<summary>标题和描述</summary>
|
||||||
|
<form class="entity-form markdown-content"
|
||||||
|
method="post"
|
||||||
|
enctype="multipart/form-data">
|
||||||
|
{% csrf_token %}
|
||||||
|
{{ form }}
|
||||||
|
<input class="button" type="submit" value="{% trans '保存' %}">
|
||||||
|
</form>
|
||||||
|
{{ form.media }}
|
||||||
|
</details>
|
||||||
|
{% if collection %}
|
||||||
|
<hr>
|
||||||
|
<details open>
|
||||||
|
<summary>条目</summary>
|
||||||
|
<div id="collection_items"
|
||||||
|
hx-get="{% url 'journal:collection_retrieve_items' collection.uuid %}?edit=1"
|
||||||
|
hx-trigger="load"></div>
|
||||||
|
</details>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
{% include "_sidebar.html" with user=collection.owner show_profile=1 fold_profile=1 %}
|
||||||
|
</main>
|
||||||
{% include "partial/_footer.html" %}
|
{% include "partial/_footer.html" %}
|
||||||
</div>
|
</body>
|
||||||
<script>
|
|
||||||
document.body.addEventListener('htmx:configRequest', (event) => {
|
|
||||||
event.detail.headers['X-CSRFToken'] = '{{ csrf_token }}';
|
|
||||||
})
|
|
||||||
</script>
|
|
||||||
</body>
|
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -1,27 +1,57 @@
|
||||||
{% load thumb %}
|
{% load thumb %}
|
||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
{% load l10n %}
|
{% load l10n %}
|
||||||
<ul class="entity-list__entities">
|
<div class="item-list sortable">
|
||||||
{% for member in collection.ordered_members %}
|
{% for member in collection.ordered_members %}
|
||||||
{% with "list_item_"|add:member.item.class_name|add:".html" as template %}
|
{% with "list_item_"|add:member.item.class_name|add:".html" as template %}
|
||||||
{% include template with item=member.item mark=None collection_member=member %}
|
{% include template with item=member.item mark=None collection_member=member %}
|
||||||
{% endwith %}
|
{% endwith %}
|
||||||
{% empty %}
|
{% empty %}
|
||||||
暂无条目
|
暂无条目
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% if collection_edit %}
|
</div>
|
||||||
<li>
|
{% if collection_edit %}
|
||||||
<form class="entity-form" hx-target=".entity-list" hx-post="{% url 'journal:collection_append_item' collection.uuid %}" method="POST">
|
<form class="entity-form"
|
||||||
{% csrf_token %}
|
hx-target="#collection_items"
|
||||||
<input type="url" name="url" placeholder="{{ request.scheme }}://{{ request.get_host }}/item/abcd123" style="min-width:24rem" required>
|
hx-post="{% url 'journal:collection_append_item' collection.uuid %}"
|
||||||
<input type="text" name="comment" placeholder="{% trans '备注' %}" style="min-width:24rem">
|
method="post">
|
||||||
<input class="button" type="submit" value="{% trans '添加' %}" >
|
{% csrf_token %}
|
||||||
</form>
|
<input type="url"
|
||||||
</li>
|
name="url"
|
||||||
{% endif %}
|
placeholder="{{ request.scheme }}://{{ request.get_host }}/item/abcd123"
|
||||||
</ul>
|
style="min-width:24rem"
|
||||||
{% if msg %}
|
required>
|
||||||
<script type="text/javascript">
|
<input type="text"
|
||||||
alert("{{ msg|escapejs }}");
|
name="comment"
|
||||||
</script>
|
placeholder="{% trans '备注' %}"
|
||||||
{% endif %}
|
style="min-width:24rem">
|
||||||
|
<input class="button" type="submit" value="{% trans '添加站内条目到收藏夹' %}">
|
||||||
|
</form>
|
||||||
|
<script>
|
||||||
|
$(function () {
|
||||||
|
sortable('.sortable', {
|
||||||
|
forcePlaceholderSize: true,
|
||||||
|
placeholderClass: 'entity-sort--placeholder',
|
||||||
|
hoverClass: 'entity-sort--hover'
|
||||||
|
});
|
||||||
|
});
|
||||||
|
function update_member_order() {
|
||||||
|
var member_ids = [];
|
||||||
|
$('.sortable>.item-card').each(function () {
|
||||||
|
member_ids.push($(this).data('member-id'));
|
||||||
|
});
|
||||||
|
$('#member_ids').val(member_ids.join(','));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<form class="entity-form"
|
||||||
|
hx-target="#collection_items"
|
||||||
|
hx-post="{% url 'journal:collection_update_member_order' collection.uuid %}"
|
||||||
|
onsubmit="return update_member_order()"
|
||||||
|
method="post">
|
||||||
|
{% csrf_token %}
|
||||||
|
<input type="hidden" name="member_ids" id="member_ids" required>
|
||||||
|
<input type="submit" class="secondary" value="拖拽修改条目顺序后点击这里保存">
|
||||||
|
</form>
|
||||||
|
{% endif %}
|
||||||
|
{% if msg %}<script type="text/javascript">alert("{{ msg|escapejs }}");</script>{% endif %}
|
||||||
|
|
|
@ -8,43 +8,66 @@
|
||||||
{% load truncate %}
|
{% load truncate %}
|
||||||
{% load highlight %}
|
{% load highlight %}
|
||||||
{% load thumb %}
|
{% load thumb %}
|
||||||
|
<div id="modal"
|
||||||
<div id="modal" _="on closeModal add .closing then wait for animationend then remove me">
|
_="on closeModal add .closing then wait for animationend then remove me">
|
||||||
<div class="modal-underlay" _="on click trigger closeModal"></div>
|
<div class="modal-underlay" _="on click trigger closeModal"></div>
|
||||||
<div class="modal-content">
|
<div class="modal-content">
|
||||||
<div class="add-to-list-modal__head">
|
<div class="add-to-list-modal__head">
|
||||||
<span class="add-to-list-modal__title">{% trans '分享收藏单' %} - {{ collection.title }}</span>
|
<span class="add-to-list-modal__title">{% trans '分享收藏单' %} - {{ collection.title }}</span>
|
||||||
<span class="add-to-list-modal__close-button modal-close" _="on click trigger closeModal">
|
<span class="add-to-list-modal__close-button modal-close"
|
||||||
<i class="fa-solid fa-xmark"></i>
|
_="on click trigger closeModal">
|
||||||
</span>
|
<i class="fa-solid fa-xmark"></i>
|
||||||
</div>
|
</span>
|
||||||
<div class="add-to-list-modal__body">
|
|
||||||
<form action="{% url 'journal:collection_share' collection.uuid %}" method="post">
|
|
||||||
{% csrf_token %}
|
|
||||||
<div>
|
|
||||||
<label for="id_visibility_0">分享可见性(不同于收藏单本身的权限):</label>
|
|
||||||
<ul id="id_visibility">
|
|
||||||
<li><label for="id_visibility_0"><input type="radio" name="visibility" value="0" required="" id="id_visibility_0" {% if collection.visibility == 0 %}checked{% endif %}>
|
|
||||||
公开</label>
|
|
||||||
|
|
||||||
</li>
|
|
||||||
<li><label for="id_visibility_1"><input type="radio" name="visibility" value="1" required="" id="id_visibility_1" {% if collection.visibility == 1 %}checked{% endif %}>
|
|
||||||
仅关注者</label>
|
|
||||||
|
|
||||||
</li>
|
|
||||||
<li><label for="id_visibility_2"><input type="radio" name="visibility" value="2" required="" id="id_visibility_2" {% if collection.visibility == 2 %}checked{% endif %}>
|
|
||||||
仅自己</label>
|
|
||||||
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<textarea type="text" name="comment" placeholder="分享附言"></textarea>
|
|
||||||
</div>
|
|
||||||
<div class="add-to-list-modal__confirm-button">
|
|
||||||
<input type="submit" class="button float-right" value="{% trans '提交' %}">
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
<div class="add-to-list-modal__body">
|
||||||
|
<form action="{% url 'journal:collection_share' collection.uuid %}"
|
||||||
|
method="post">
|
||||||
|
{% csrf_token %}
|
||||||
|
<div>
|
||||||
|
<label for="id_visibility_0">分享可见性(不同于收藏单本身的权限):</label>
|
||||||
|
<ul id="id_visibility">
|
||||||
|
<li>
|
||||||
|
<label for="id_visibility_0">
|
||||||
|
<input type="radio"
|
||||||
|
name="visibility"
|
||||||
|
value="0"
|
||||||
|
required=""
|
||||||
|
id="id_visibility_0"
|
||||||
|
{% if collection.visibility == 0 %}checked{% endif %}>
|
||||||
|
公开
|
||||||
|
</label>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<label for="id_visibility_1">
|
||||||
|
<input type="radio"
|
||||||
|
name="visibility"
|
||||||
|
value="1"
|
||||||
|
required=""
|
||||||
|
id="id_visibility_1"
|
||||||
|
{% if collection.visibility == 1 %}checked{% endif %}>
|
||||||
|
仅关注者
|
||||||
|
</label>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<label for="id_visibility_2">
|
||||||
|
<input type="radio"
|
||||||
|
name="visibility"
|
||||||
|
value="2"
|
||||||
|
required=""
|
||||||
|
id="id_visibility_2"
|
||||||
|
{% if collection.visibility == 2 %}checked{% endif %}>
|
||||||
|
仅自己
|
||||||
|
</label>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<textarea type="text" name="comment" placeholder="分享附言"></textarea>
|
||||||
|
</div>
|
||||||
|
<div class="add-to-list-modal__confirm-button">
|
||||||
|
<input type="submit" class="button float-right" value="{% trans '提交' %}">
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue