notification
This commit is contained in:
parent
05821eaac1
commit
15a7b55642
31 changed files with 379 additions and 47 deletions
|
@ -66,6 +66,12 @@
|
||||||
// margin-right: 4px;
|
// margin-right: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
blockquote {
|
||||||
|
padding-top: 0;
|
||||||
|
padding-bottom: 0;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
.spacing {
|
.spacing {
|
||||||
margin-bottom: calc(var(--pico-block-spacing-horizontal)/2);
|
margin-bottom: calc(var(--pico-block-spacing-horizontal)/2);
|
||||||
}
|
}
|
||||||
|
|
|
@ -78,6 +78,9 @@
|
||||||
</summary>
|
</summary>
|
||||||
<ul role="listbox" style="min-width:-webkit-max-content;" dir="rtl">
|
<ul role="listbox" style="min-width:-webkit-max-content;" dir="rtl">
|
||||||
{% if request.user.is_authenticated %}
|
{% if request.user.is_authenticated %}
|
||||||
|
<li>
|
||||||
|
<a href="{% url 'social:notification' %}">通知</a>
|
||||||
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<a href="{% url 'users:data' %}">数据</a>
|
<a href="{% url 'users:data' %}">数据</a>
|
||||||
</li>
|
</li>
|
||||||
|
|
|
@ -178,6 +178,11 @@ class Piece(PolymorphicModel, UserOwnedObjectMixin):
|
||||||
obj = None
|
obj = None
|
||||||
return obj
|
return obj
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_by_post_id(cls, post_id: int):
|
||||||
|
pp = PiecePost.objects.filter(post_id=post_id).first()
|
||||||
|
return pp.piece if pp else None
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def update_by_ap_object(cls, owner, item, obj, post_id, visibility):
|
def update_by_ap_object(cls, owner, item, obj, post_id, visibility):
|
||||||
raise NotImplementedError("subclass must implement this")
|
raise NotImplementedError("subclass must implement this")
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
{% load i18n %}
|
||||||
<section class="replies" hx-target="this" hx-swap="outerHTML">
|
<section class="replies" hx-target="this" hx-swap="outerHTML">
|
||||||
{% for post in replies %}
|
{% for post in replies %}
|
||||||
<div>
|
<div>
|
||||||
|
@ -35,49 +36,51 @@
|
||||||
<div id="replies_{{ post.pk }}"></div>
|
<div id="replies_{{ post.pk }}"></div>
|
||||||
</div>
|
</div>
|
||||||
{% empty %}
|
{% empty %}
|
||||||
<div class="empty">暂无回应</div>
|
<div class="empty">{% trans 'nothing so far.' %}</div>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
<form class="reply"
|
{% if post %}
|
||||||
role="group"
|
<form class="reply"
|
||||||
hx-post="{% url 'journal:post_reply' post.pk %}"
|
role="group"
|
||||||
hx-trigger="submit once">
|
hx-post="{% url 'journal:post_reply' post.pk %}"
|
||||||
<input name="content" type="text" placeholder="Type your reply" />
|
hx-trigger="submit once">
|
||||||
<details class="dropdown">
|
<input name="content" type="text" placeholder="Type your reply" />
|
||||||
<summary>
|
<details class="dropdown">
|
||||||
<i class="fa-solid fa-users-gear"></i>
|
<summary>
|
||||||
</summary>
|
<i class="fa-solid fa-users-gear"></i>
|
||||||
<ul>
|
</summary>
|
||||||
<li>
|
<ul>
|
||||||
<label>
|
<li>
|
||||||
<input type="radio"
|
<label>
|
||||||
name="visibility"
|
<input type="radio"
|
||||||
value="{{ request.user.preference.post_public_mode }}"
|
name="visibility"
|
||||||
{% if post.visibility <= 1 or post.visibility == 4 %}checked{% endif %} />
|
value="{{ request.user.preference.post_public_mode }}"
|
||||||
<i class="fa-solid fa-globe"></i>
|
{% if post.visibility <= 1 or post.visibility == 4 %}checked{% endif %} />
|
||||||
</label>
|
<i class="fa-solid fa-globe"></i>
|
||||||
</li>
|
</label>
|
||||||
<li>
|
</li>
|
||||||
<label>
|
<li>
|
||||||
<input type="radio"
|
<label>
|
||||||
name="visibility"
|
<input type="radio"
|
||||||
value="2"
|
name="visibility"
|
||||||
{% if post.visibility == 2 %}checked{% endif %} />
|
value="2"
|
||||||
<i class="fa-solid fa-lock"></i>
|
{% if post.visibility == 2 %}checked{% endif %} />
|
||||||
</label>
|
<i class="fa-solid fa-lock"></i>
|
||||||
</li>
|
</label>
|
||||||
<li>
|
</li>
|
||||||
<label>
|
<li>
|
||||||
<input type="radio"
|
<label>
|
||||||
name="visibility"
|
<input type="radio"
|
||||||
value="3"
|
name="visibility"
|
||||||
{% if post.visibility == 3 %}checked{% endif %} />
|
value="3"
|
||||||
<i class="fa-solid fa-at"></i>
|
{% if post.visibility == 3 %}checked{% endif %} />
|
||||||
</label>
|
<i class="fa-solid fa-at"></i>
|
||||||
</li>
|
</label>
|
||||||
</ul>
|
</li>
|
||||||
</details>
|
</ul>
|
||||||
<button class="secondary">
|
</details>
|
||||||
<i class="fa-regular fa-paper-plane"></i>
|
<button class="secondary">
|
||||||
</button>
|
<i class="fa-regular fa-paper-plane"></i>
|
||||||
</form>
|
</button>
|
||||||
|
</form>
|
||||||
|
{% endif %}
|
||||||
</section>
|
</section>
|
||||||
|
|
1
social/templates/event/announcement.html
Normal file
1
social/templates/event/announcement.html
Normal file
|
@ -0,0 +1 @@
|
||||||
|
unsupported notification: announcement
|
5
social/templates/event/boosted.html
Normal file
5
social/templates/event/boosted.html
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
{% load bleach_tags %}
|
||||||
|
boosted your post
|
||||||
|
<blockquote class="tldr" _="on click toggle .tldr on me">
|
||||||
|
{{ event.post.content|bleach:"a,p,span,br,div,img"|default:"<br>" }}
|
||||||
|
</blockquote>
|
1
social/templates/event/boosted_collection.html
Normal file
1
social/templates/event/boosted_collection.html
Normal file
|
@ -0,0 +1 @@
|
||||||
|
boosted your collection <a href="{{ event.piece.url }}">{{ event.piece.title }}</a>
|
8
social/templates/event/boosted_comment.html
Normal file
8
social/templates/event/boosted_comment.html
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
{% load duration %}
|
||||||
|
boost your comment on <a href="{{ event.item.url }}">{{ event.item.display_title }}</a>
|
||||||
|
<blockquote class="tldr" _="on click toggle .tldr on me">
|
||||||
|
<span>
|
||||||
|
{% if event.piece.rating_grade %}{{ event.piece.rating_grade|rating_star }}{% endif %}
|
||||||
|
</span>
|
||||||
|
{{ event.piece.html|safe }}
|
||||||
|
</blockquote>
|
1
social/templates/event/boosted_review.html
Normal file
1
social/templates/event/boosted_review.html
Normal file
|
@ -0,0 +1 @@
|
||||||
|
boosted your review <a href="{{ event.piece.url }}">{{ event.piece.title }}</a> on <a href="{{ event.item.url }}">{{ event.item.display_title }}</a>
|
8
social/templates/event/boosted_shelfmember.html
Normal file
8
social/templates/event/boosted_shelfmember.html
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
{% load duration %}
|
||||||
|
boosted your mark on <a href="{{ event.item.url }}">{{ event.item.display_title }}</a>
|
||||||
|
<blockquote class="tldr" _="on click toggle .tldr on me">
|
||||||
|
<span>
|
||||||
|
{% if event.piece.mark.rating_grade %}{{ event.piece.mark.rating_grade|rating_star }}{% endif %}
|
||||||
|
</span>
|
||||||
|
{{ event.piece.mark.comment.html|safe }}
|
||||||
|
</blockquote>
|
12
social/templates/event/follow_requested.html
Normal file
12
social/templates/event/follow_requested.html
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
{% load bleach_tags %}
|
||||||
|
requested to follow you
|
||||||
|
<blockquote class="tldr" _="on click toggle .tldr on me">
|
||||||
|
<span class="action">{% include 'users/profile_actions.html' with show_home=1 identity=event.identity %}</span>
|
||||||
|
<div>
|
||||||
|
<code class="{{ event.identity.id }}_handler"
|
||||||
|
style="cursor:pointer"
|
||||||
|
onmouseleave="$(this).removeAttr('data-tooltip')"
|
||||||
|
onclick="navigator.clipboard.writeText(this.innerText);$(this).data('tooltip','copied');">@{{ event.identity.full_handle }}</code>
|
||||||
|
</div>
|
||||||
|
{{ event.identity.summary|bleach:"a,p,span,br"|default:"<br>" }}
|
||||||
|
</blockquote>
|
12
social/templates/event/followed.html
Normal file
12
social/templates/event/followed.html
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
{% load bleach_tags %}
|
||||||
|
followed you
|
||||||
|
<blockquote class="tldr" _="on click toggle .tldr on me">
|
||||||
|
<span class="action">{% include 'users/profile_actions.html' with show_home=1 identity=event.identity %}</span>
|
||||||
|
<div>
|
||||||
|
<code class="{{ event.identity.id }}_handler"
|
||||||
|
style="cursor:pointer"
|
||||||
|
onmouseleave="$(this).removeAttr('data-tooltip')"
|
||||||
|
onclick="navigator.clipboard.writeText(this.innerText);$(this).data('tooltip','copied');">@{{ event.identity.full_handle }}</code>
|
||||||
|
</div>
|
||||||
|
{{ event.identity.summary|bleach:"a,p,span,br"|default:"<br>" }}
|
||||||
|
</blockquote>
|
1
social/templates/event/identity_created.html
Normal file
1
social/templates/event/identity_created.html
Normal file
|
@ -0,0 +1 @@
|
||||||
|
joined {{ site_name }}
|
5
social/templates/event/liked.html
Normal file
5
social/templates/event/liked.html
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
{% load bleach_tags %}
|
||||||
|
liked your post
|
||||||
|
<blockquote class="tldr" _="on click toggle .tldr on me">
|
||||||
|
{{ event.post.content|bleach:"a,p,span,br,div,img"|default:"<br>" }}
|
||||||
|
</blockquote>
|
1
social/templates/event/liked_collection.html
Normal file
1
social/templates/event/liked_collection.html
Normal file
|
@ -0,0 +1 @@
|
||||||
|
liked your collection <a href="{{ event.piece.url }}">{{ event.piece.title }}</a>
|
8
social/templates/event/liked_comment.html
Normal file
8
social/templates/event/liked_comment.html
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
{% load duration %}
|
||||||
|
liked your comment on <a href="{{ event.item.url }}">{{ event.item.display_title }}</a>
|
||||||
|
<blockquote class="tldr" _="on click toggle .tldr on me">
|
||||||
|
<span>
|
||||||
|
{% if event.piece.rating_grade %}{{ event.piece.rating_grade|rating_star }}{% endif %}
|
||||||
|
</span>
|
||||||
|
{{ event.piece.html|safe }}
|
||||||
|
</blockquote>
|
1
social/templates/event/liked_review.html
Normal file
1
social/templates/event/liked_review.html
Normal file
|
@ -0,0 +1 @@
|
||||||
|
liked your review <a href="{{ event.piece.url }}">{{ event.piece.title }}</a> on <a href="{{ event.item.url }}">{{ event.item.display_title }}</a>
|
8
social/templates/event/liked_shelfmember.html
Normal file
8
social/templates/event/liked_shelfmember.html
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
{% load duration %}
|
||||||
|
liked your mark on <a href="{{ event.item.url }}">{{ event.item.display_title }}</a>
|
||||||
|
<blockquote class="tldr" _="on click toggle .tldr on me">
|
||||||
|
<span>
|
||||||
|
{% if event.piece.mark.rating_grade %}{{ event.piece.mark.rating_grade|rating_star }}{% endif %}
|
||||||
|
</span>
|
||||||
|
{{ event.piece.mark.comment.html|safe }}
|
||||||
|
</blockquote>
|
6
social/templates/event/mentioned.html
Normal file
6
social/templates/event/mentioned.html
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
{% load bleach_tags %}
|
||||||
|
mentioned you
|
||||||
|
<blockquote class="tldr" _="on click toggle .tldr on me">
|
||||||
|
{{ event.post.content|bleach:"a,p,span,br,div,img"|default:"<br>" }}
|
||||||
|
</blockquote>
|
||||||
|
{% include "events/_post.html" with post=event.reply %}
|
2
social/templates/event/mentioned_collection.html
Normal file
2
social/templates/event/mentioned_collection.html
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
replied to your collection <a href="{{ event.piece.url }}">{{ event.piece.title }}</a>
|
||||||
|
{% include "events/_post.html" with post=event.reply %}
|
9
social/templates/event/mentioned_comment.html
Normal file
9
social/templates/event/mentioned_comment.html
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
{% load duration %}
|
||||||
|
replied to your comment on <a href="{{ event.item.url }}">{{ event.item.display_title }}</a>
|
||||||
|
<blockquote class="tldr" _="on click toggle .tldr on me">
|
||||||
|
<span>
|
||||||
|
{% if event.piece.rating_grade %}{{ event.piece.rating_grade|rating_star }}{% endif %}
|
||||||
|
</span>
|
||||||
|
{{ event.piece.html|safe }}
|
||||||
|
</blockquote>
|
||||||
|
{% include "events/_post.html" with post=event.reply %}
|
2
social/templates/event/mentioned_review.html
Normal file
2
social/templates/event/mentioned_review.html
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
replied to your review <a href="{{ event.piece.url }}">{{ event.piece.title }}</a> on <a href="{{ event.item.url }}">{{ event.item.display_title }}</a>
|
||||||
|
{% include "events/_post.html" with post=event.reply %}
|
9
social/templates/event/mentioned_shelfmember.html
Normal file
9
social/templates/event/mentioned_shelfmember.html
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
{% load duration %}
|
||||||
|
replied to your mark on <a href="{{ event.item.url }}">{{ event.item.display_title }}</a>
|
||||||
|
<blockquote class="tldr" _="on click toggle .tldr on me">
|
||||||
|
<span>
|
||||||
|
{% if event.piece.mark.rating_grade %}{{ event.piece.mark.rating_grade|rating_star }}{% endif %}
|
||||||
|
</span>
|
||||||
|
{{ event.piece.mark.comment.html|safe }}
|
||||||
|
</blockquote>
|
||||||
|
{% include "events/_post.html" with post=event.reply %}
|
1
social/templates/event/post.html
Normal file
1
social/templates/event/post.html
Normal file
|
@ -0,0 +1 @@
|
||||||
|
unsupported notification: post
|
51
social/templates/events.html
Normal file
51
social/templates/events.html
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
{% load static %}
|
||||||
|
{% load i18n %}
|
||||||
|
{% load l10n %}
|
||||||
|
{% load humanize %}
|
||||||
|
{% load admin_url %}
|
||||||
|
{% load mastodon %}
|
||||||
|
{% load oauth_token %}
|
||||||
|
{% load truncate %}
|
||||||
|
{% load thumb %}
|
||||||
|
{% load prettydate %}
|
||||||
|
{% load user_actions %}
|
||||||
|
{% load duration %}
|
||||||
|
{% for event in events %}
|
||||||
|
<section class="activity">
|
||||||
|
<div class="avatar">
|
||||||
|
<img src="{{ event.identity.avatar }}" alt="cover" />
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<div>
|
||||||
|
<span class="time">
|
||||||
|
<span>{{ event.created|naturaltime }}</span>
|
||||||
|
</span>
|
||||||
|
<div>
|
||||||
|
<span>
|
||||||
|
<a href="{{ event.identity.url }}"
|
||||||
|
class="nickname"
|
||||||
|
title="@{{ event.identity.full_handle }}">{{ event.identity.display_name }}</a>
|
||||||
|
</span>
|
||||||
|
{% with "event/"|add:event.template|add:".html" as template %}
|
||||||
|
{% include template %}
|
||||||
|
{% endwith %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
{% if forloop.last %}
|
||||||
|
<div class="htmx-indicator"
|
||||||
|
style="margin-left: 60px"
|
||||||
|
hx-get="{% url 'social:events' %}?last={{ event.created|date:'Y-m-d H:i:s.uO'|urlencode }}"
|
||||||
|
hx-trigger="revealed"
|
||||||
|
hx-swap="outerHTML">
|
||||||
|
<i class="fa-solid fa-compact-disc fa-spin loading"></i>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
{% empty %}
|
||||||
|
{% if request.GET.last %}
|
||||||
|
<div class="empty">{% trans 'nothing more.' %}</div>
|
||||||
|
{% else %}
|
||||||
|
<div class="empty">{% trans 'nothing so far.' %}</div>
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
17
social/templates/events/_post.html
Normal file
17
social/templates/events/_post.html
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
<div>
|
||||||
|
<span class="action">
|
||||||
|
{% include "action_reply_post.html" %}
|
||||||
|
{% include "action_like_post.html" %}
|
||||||
|
{% include "action_boost_post.html" %}
|
||||||
|
{% include "action_open_post.html" %}
|
||||||
|
</span>
|
||||||
|
{% if post.summary %}
|
||||||
|
<details>
|
||||||
|
<summary>{{ post.summary }}</summary>
|
||||||
|
{{ post.safe_content_local }}
|
||||||
|
</details>
|
||||||
|
{% else %}
|
||||||
|
{{ post.safe_content_local }}
|
||||||
|
{% endif %}
|
||||||
|
<div id="replies_{{ post.pk }}"></div>
|
||||||
|
</div>
|
38
social/templates/notification.html
Normal file
38
social/templates/notification.html
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
{% load static %}
|
||||||
|
{% load i18n %}
|
||||||
|
{% load l10n %}
|
||||||
|
{% load admin_url %}
|
||||||
|
{% load mastodon %}
|
||||||
|
{% load oauth_token %}
|
||||||
|
{% load truncate %}
|
||||||
|
{% load thumb %}
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="zh" class="feed-page">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>{{ site_name }} - {% trans 'Notification' %}</title>
|
||||||
|
{% include "common_libs.html" %}
|
||||||
|
<script src="{{ cdn_url }}/npm/shikwasa@2.2.1/dist/shikwasa.min.js"></script>
|
||||||
|
<link href="{{ cdn_url }}/npm/shikwasa@2.2.1/dist/style.min.css"
|
||||||
|
rel="stylesheet"></link>
|
||||||
|
<script src="{% static 'js/podcast.js' %}"></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
{% include "_header.html" with current="timeline" %}
|
||||||
|
<main>
|
||||||
|
<div class="grid__main">
|
||||||
|
<h5>{% trans 'Notification' %}</h5>
|
||||||
|
<div class="feed">
|
||||||
|
<div hx-get="{% url 'social:events' %}"
|
||||||
|
hx-trigger="intersect once delay:0.1s"
|
||||||
|
hx-swap="outerHTML">
|
||||||
|
<i class="fa-solid fa-compact-disc fa-spin loading"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% include "_sidebar.html" with show_progress=1 identity=request.user.identity %}
|
||||||
|
</main>
|
||||||
|
{% include "_footer.html" %}
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -6,4 +6,6 @@ app_name = "social"
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path("", feed, name="feed"),
|
path("", feed, name="feed"),
|
||||||
path("data", data, name="data"),
|
path("data", data, name="data"),
|
||||||
|
path("notification", notification, name="notification"),
|
||||||
|
path("events", events, name="events"),
|
||||||
]
|
]
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
from django.contrib.auth.decorators import login_required
|
from django.contrib.auth.decorators import login_required
|
||||||
from django.core.exceptions import BadRequest
|
|
||||||
from django.shortcuts import redirect, render
|
from django.shortcuts import redirect, render
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
from django.utils.translation import gettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
|
@ -9,11 +8,10 @@ from django.views.decorators.http import require_http_methods
|
||||||
|
|
||||||
from catalog.models import *
|
from catalog.models import *
|
||||||
from journal.models import *
|
from journal.models import *
|
||||||
|
from takahe.utils import Takahe
|
||||||
|
|
||||||
from .models import *
|
from .models import *
|
||||||
|
|
||||||
_logger = logging.getLogger(__name__)
|
|
||||||
|
|
||||||
PAGE_SIZE = 10
|
PAGE_SIZE = 10
|
||||||
|
|
||||||
|
|
||||||
|
@ -71,3 +69,84 @@ def data(request):
|
||||||
)[:PAGE_SIZE],
|
)[:PAGE_SIZE],
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@require_http_methods(["GET"])
|
||||||
|
@login_required
|
||||||
|
def notification(request):
|
||||||
|
if not request.user.registration_complete:
|
||||||
|
return redirect(reverse("users:register"))
|
||||||
|
user = request.user
|
||||||
|
podcast_ids = [
|
||||||
|
p.item_id
|
||||||
|
for p in user.shelf_manager.get_latest_members(
|
||||||
|
ShelfType.PROGRESS, ItemCategory.Podcast
|
||||||
|
)
|
||||||
|
]
|
||||||
|
recent_podcast_episodes = PodcastEpisode.objects.filter(
|
||||||
|
program_id__in=podcast_ids
|
||||||
|
).order_by("-pub_date")[:10]
|
||||||
|
books_in_progress = Edition.objects.filter(
|
||||||
|
id__in=[
|
||||||
|
p.item_id
|
||||||
|
for p in user.shelf_manager.get_latest_members(
|
||||||
|
ShelfType.PROGRESS, ItemCategory.Book
|
||||||
|
)[:10]
|
||||||
|
]
|
||||||
|
)
|
||||||
|
tvshows_in_progress = Item.objects.filter(
|
||||||
|
id__in=[
|
||||||
|
p.item_id
|
||||||
|
for p in user.shelf_manager.get_latest_members(
|
||||||
|
ShelfType.PROGRESS, ItemCategory.TV
|
||||||
|
)[:10]
|
||||||
|
]
|
||||||
|
)
|
||||||
|
return render(
|
||||||
|
request,
|
||||||
|
"notification.html",
|
||||||
|
{
|
||||||
|
"recent_podcast_episodes": recent_podcast_episodes,
|
||||||
|
"books_in_progress": books_in_progress,
|
||||||
|
"tvshows_in_progress": tvshows_in_progress,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class NotificationEvent:
|
||||||
|
def __init__(self, tle) -> None:
|
||||||
|
self.event = tle
|
||||||
|
self.type = tle.type
|
||||||
|
self.template = tle.type
|
||||||
|
self.created = tle.created
|
||||||
|
self.identity = (
|
||||||
|
APIdentity.objects.filter(pk=tle.subject_identity.pk).first()
|
||||||
|
if tle.subject_identity
|
||||||
|
else None
|
||||||
|
)
|
||||||
|
self.post = tle.subject_post
|
||||||
|
if self.type == "mentioned":
|
||||||
|
# for reply, self.post is the original post
|
||||||
|
self.reply = self.post
|
||||||
|
self.replies = [self.post]
|
||||||
|
self.post = self.post.in_reply_to_post() if self.post else None
|
||||||
|
self.piece = Piece.get_by_post_id(self.post.id) if self.post else None
|
||||||
|
self.item = getattr(self.piece, "item") if hasattr(self.piece, "item") else None
|
||||||
|
if self.piece and self.template in ["liked", "boost", "mentioned"]:
|
||||||
|
cls = self.piece.__class__.__name__.lower()
|
||||||
|
self.template += "_" + cls
|
||||||
|
|
||||||
|
|
||||||
|
@login_required
|
||||||
|
@require_http_methods(["GET"])
|
||||||
|
def events(request):
|
||||||
|
es = Takahe.get_events(request.user.identity.pk)
|
||||||
|
last = request.GET.get("last")
|
||||||
|
if last:
|
||||||
|
es = es.filter(created__lt=last)
|
||||||
|
nes = [NotificationEvent(e) for e in es[:PAGE_SIZE]]
|
||||||
|
return render(
|
||||||
|
request,
|
||||||
|
"events.html",
|
||||||
|
{"events": nes},
|
||||||
|
)
|
||||||
|
|
|
@ -942,3 +942,27 @@ class Takahe:
|
||||||
.exclude(seen=user)
|
.exclude(seen=user)
|
||||||
):
|
):
|
||||||
a.seen.add(user)
|
a.seen.add(user)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get_events(identity_id: int):
|
||||||
|
return (
|
||||||
|
TimelineEvent.objects.select_related(
|
||||||
|
"subject_post",
|
||||||
|
"subject_post__author",
|
||||||
|
"subject_post__author__domain",
|
||||||
|
"subject_identity",
|
||||||
|
"subject_identity__domain",
|
||||||
|
"subject_post_interaction",
|
||||||
|
"subject_post_interaction__identity",
|
||||||
|
"subject_post_interaction__identity__domain",
|
||||||
|
)
|
||||||
|
.prefetch_related(
|
||||||
|
"subject_post__attachments",
|
||||||
|
"subject_post__mentions",
|
||||||
|
"subject_post__emojis",
|
||||||
|
)
|
||||||
|
.filter(identity=identity_id)
|
||||||
|
.exclude(type="post", subject_identity__isnull=True)
|
||||||
|
.exclude(subject_identity_id=identity_id)
|
||||||
|
.order_by("-created")
|
||||||
|
)
|
||||||
|
|
|
@ -31,10 +31,13 @@ _RESERVED_USERNAMES = [
|
||||||
"__",
|
"__",
|
||||||
"admin",
|
"admin",
|
||||||
"administrator",
|
"administrator",
|
||||||
|
"service",
|
||||||
|
"support",
|
||||||
"system",
|
"system",
|
||||||
"user",
|
"user",
|
||||||
"users",
|
"users",
|
||||||
"api",
|
"api",
|
||||||
|
"bot",
|
||||||
"me",
|
"me",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue