mirror of
https://github.com/bookwyrm-social/bookwyrm.git
synced 2024-12-01 22:11:16 +00:00
Add status type filters
This commit is contained in:
parent
8a6f78cfff
commit
a0093a8a2e
6 changed files with 100 additions and 3 deletions
|
@ -174,6 +174,29 @@ class UserGroupForm(CustomForm):
|
||||||
fields = ["groups"]
|
fields = ["groups"]
|
||||||
|
|
||||||
|
|
||||||
|
class CheckboxSelectMultipleHorizontal(widgets.CheckboxSelectMultiple):
|
||||||
|
template_name = "widgets/checkbox_select_horizontal.html"
|
||||||
|
option_template_name = "widgets/checkbox_select_horizontal_option.html"
|
||||||
|
|
||||||
|
|
||||||
|
class FeedStatusTypes(CustomForm):
|
||||||
|
class Meta:
|
||||||
|
model = models.User
|
||||||
|
fields = ["feed_status_types"]
|
||||||
|
help_texts = {f: None for f in fields}
|
||||||
|
labels = {"feed_status_types": ""}
|
||||||
|
widgets = {
|
||||||
|
"feed_status_types": CheckboxSelectMultipleHorizontal(
|
||||||
|
choices=[
|
||||||
|
("review", _("Reviews")),
|
||||||
|
("comment", _("Comments")),
|
||||||
|
("quotation", _("Quotations")),
|
||||||
|
("everything", _("Everything else")),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
class CoverForm(CustomForm):
|
class CoverForm(CustomForm):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = models.Book
|
model = models.Book
|
||||||
|
|
|
@ -4,7 +4,7 @@ from urllib.parse import urlparse
|
||||||
|
|
||||||
from django.apps import apps
|
from django.apps import apps
|
||||||
from django.contrib.auth.models import AbstractUser, Group
|
from django.contrib.auth.models import AbstractUser, Group
|
||||||
from django.contrib.postgres.fields import CICharField
|
from django.contrib.postgres.fields import ArrayField, CICharField
|
||||||
from django.core.validators import MinValueValidator
|
from django.core.validators import MinValueValidator
|
||||||
from django.dispatch import receiver
|
from django.dispatch import receiver
|
||||||
from django.db import models, transaction
|
from django.db import models, transaction
|
||||||
|
@ -128,6 +128,13 @@ class User(OrderedCollectionPageMixin, AbstractUser):
|
||||||
show_suggested_users = models.BooleanField(default=True)
|
show_suggested_users = models.BooleanField(default=True)
|
||||||
discoverable = fields.BooleanField(default=False)
|
discoverable = fields.BooleanField(default=False)
|
||||||
|
|
||||||
|
# feed options
|
||||||
|
feed_status_types = ArrayField(
|
||||||
|
models.CharField(max_length=10, blank=False),
|
||||||
|
size=8,
|
||||||
|
default=list(["review", "comment", "quotation", "everything"]),
|
||||||
|
)
|
||||||
|
|
||||||
preferred_timezone = models.CharField(
|
preferred_timezone = models.CharField(
|
||||||
choices=[(str(tz), str(tz)) for tz in pytz.all_timezones],
|
choices=[(str(tz), str(tz)) for tz in pytz.all_timezones],
|
||||||
default=str(pytz.utc),
|
default=str(pytz.utc),
|
||||||
|
|
|
@ -16,6 +16,27 @@
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<details class="mb-5" {% if settings_saved %}open{% endif %}>
|
||||||
|
<summary>
|
||||||
|
<span class="has-text-weight-bold">What to display?</span>
|
||||||
|
{% if settings_saved %}
|
||||||
|
<span class="tag is-success is-light ml-2">Saved!</span>
|
||||||
|
{% endif %}
|
||||||
|
</summary>
|
||||||
|
<form class="level" method="post" action="/{{ tab.key }}">
|
||||||
|
{% csrf_token %}
|
||||||
|
<div class="level-left">
|
||||||
|
{{ feed_status_types_form }}
|
||||||
|
</div>
|
||||||
|
<div class="level-right">
|
||||||
|
<button class="button is-small is-primary is-outlined" type="submit">
|
||||||
|
Submit
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</details>
|
||||||
|
|
||||||
{# announcements and system messages #}
|
{# announcements and system messages #}
|
||||||
{% if not activities.number > 1 %}
|
{% if not activities.number > 1 %}
|
||||||
<a href="{{ request.path }}" class="transition-y is-hidden notification is-primary is-block" data-poll-wrapper>
|
<a href="{{ request.path }}" class="transition-y is-hidden notification is-primary is-block" data-poll-wrapper>
|
||||||
|
|
11
bookwyrm/templates/widgets/checkbox_select_horizontal.html
Normal file
11
bookwyrm/templates/widgets/checkbox_select_horizontal.html
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
{% with id=widget.attrs.id %}
|
||||||
|
<div{% if id %} id="{{ id }}"{% endif %} class="field">
|
||||||
|
<div class="control">
|
||||||
|
{% for group, options, index in widget.optgroups %}
|
||||||
|
{% for option in options %}
|
||||||
|
{% include option.template_name with widget=option %}
|
||||||
|
{% endfor %}
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endwith %}
|
|
@ -0,0 +1,4 @@
|
||||||
|
<label{% if widget.attrs.id %} for="{{ widget.attrs.id }}"{% endif %}>
|
||||||
|
{% include "django/forms/widgets/input.html" %}
|
||||||
|
{{ widget.label }}
|
||||||
|
</label>
|
|
@ -11,6 +11,7 @@ from django.views import View
|
||||||
|
|
||||||
from bookwyrm import activitystreams, forms, models
|
from bookwyrm import activitystreams, forms, models
|
||||||
from bookwyrm.activitypub import ActivitypubResponse
|
from bookwyrm.activitypub import ActivitypubResponse
|
||||||
|
from bookwyrm.models import User
|
||||||
from bookwyrm.settings import PAGE_LENGTH, STREAMS
|
from bookwyrm.settings import PAGE_LENGTH, STREAMS
|
||||||
from bookwyrm.suggested_users import suggested_users
|
from bookwyrm.suggested_users import suggested_users
|
||||||
from .helpers import get_user_from_username
|
from .helpers import get_user_from_username
|
||||||
|
@ -22,7 +23,16 @@ from .helpers import is_api_request, is_bookwyrm_request
|
||||||
class Feed(View):
|
class Feed(View):
|
||||||
"""activity stream"""
|
"""activity stream"""
|
||||||
|
|
||||||
def get(self, request, tab):
|
def post(self, request, tab):
|
||||||
|
settings_saved = False
|
||||||
|
form = forms.FeedStatusTypes(request.POST, instance=request.user)
|
||||||
|
if form.is_valid():
|
||||||
|
form.save()
|
||||||
|
settings_saved = True
|
||||||
|
|
||||||
|
return self.get(request, tab, settings_saved)
|
||||||
|
|
||||||
|
def get(self, request, tab, settings_saved=False):
|
||||||
"""user's homepage with activity feed"""
|
"""user's homepage with activity feed"""
|
||||||
tab = [s for s in STREAMS if s["key"] == tab]
|
tab = [s for s in STREAMS if s["key"] == tab]
|
||||||
tab = tab[0] if tab else STREAMS[0]
|
tab = tab[0] if tab else STREAMS[0]
|
||||||
|
@ -30,7 +40,11 @@ class Feed(View):
|
||||||
activities = activitystreams.streams[tab["key"]].get_activity_stream(
|
activities = activitystreams.streams[tab["key"]].get_activity_stream(
|
||||||
request.user
|
request.user
|
||||||
)
|
)
|
||||||
paginated = Paginator(activities, PAGE_LENGTH)
|
filtered_activities = filter_stream_by_status_type(
|
||||||
|
activities,
|
||||||
|
allowed_types=request.user.feed_status_types,
|
||||||
|
)
|
||||||
|
paginated = Paginator(filtered_activities, PAGE_LENGTH)
|
||||||
|
|
||||||
suggestions = suggested_users.get_suggestions(request.user)
|
suggestions = suggested_users.get_suggestions(request.user)
|
||||||
|
|
||||||
|
@ -43,6 +57,10 @@ class Feed(View):
|
||||||
"tab": tab,
|
"tab": tab,
|
||||||
"streams": STREAMS,
|
"streams": STREAMS,
|
||||||
"goal_form": forms.GoalForm(),
|
"goal_form": forms.GoalForm(),
|
||||||
|
"feed_status_types_form": forms.FeedStatusTypes(
|
||||||
|
instance=request.user,
|
||||||
|
),
|
||||||
|
"settings_saved": settings_saved,
|
||||||
"path": f"/{tab['key']}",
|
"path": f"/{tab['key']}",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -230,3 +248,16 @@ def get_suggested_books(user, max_books=5):
|
||||||
suggested_books.append(shelf_preview)
|
suggested_books.append(shelf_preview)
|
||||||
book_count += len(shelf_preview["books"])
|
book_count += len(shelf_preview["books"])
|
||||||
return suggested_books
|
return suggested_books
|
||||||
|
|
||||||
|
|
||||||
|
def filter_stream_by_status_type(activities, allowed_types=[]):
|
||||||
|
if "review" not in allowed_types:
|
||||||
|
activities = activities.filter(Q(review__isnull=True))
|
||||||
|
if "comment" not in allowed_types:
|
||||||
|
activities = activities.filter(Q(comment__isnull=True))
|
||||||
|
if "quotation" not in allowed_types:
|
||||||
|
activities = activities.filter(Q(quotation__isnull=True))
|
||||||
|
if "everything" not in allowed_types:
|
||||||
|
activities = activities.filter(Q(generatednote__isnull=True))
|
||||||
|
|
||||||
|
return activities
|
||||||
|
|
Loading…
Reference in a new issue