Merge pull request #636 from mouse-reeve/follow-block-button

Cleans up display of follow/block/unfollow/unblock buttons
This commit is contained in:
Mouse Reeve 2021-02-23 13:38:02 -08:00 committed by GitHub
commit fdbd3688f4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
16 changed files with 63 additions and 64 deletions

View file

@ -112,6 +112,16 @@ class User(OrderedCollectionPageMixin, AbstractUser):
activity_serializer = activitypub.Person activity_serializer = activitypub.Person
@classmethod
def viewer_aware_objects(cls, viewer):
''' the user queryset filtered for the context of the logged in user '''
queryset = cls.objects.filter(is_active=True)
if viewer.is_authenticated:
queryset = queryset.exclude(
blocks=viewer
)
return queryset
def to_outbox(self, filter_type=None, **kwargs): def to_outbox(self, filter_type=None, **kwargs):
''' an ordered collection of statuses ''' ''' an ordered collection of statuses '''
if filter_type: if filter_type:

View file

@ -42,26 +42,10 @@
<h3 class="title is-6 mb-1">Add cover</h3> <h3 class="title is-6 mb-1">Add cover</h3>
<form name="add-cover" method="POST" action="/upload-cover/{{ book.id }}" enctype="multipart/form-data"> <form name="add-cover" method="POST" action="/upload-cover/{{ book.id }}" enctype="multipart/form-data">
{% csrf_token %} {% csrf_token %}
<div class="field has-addons"> <label class="label">
<div class="control"> <input type="file" name="cover" accept="image/*" enctype="multipart/form-data" id="id_cover" required>
<div class="file is-small mb-1"> </label>
<label class="file-label"> <button class="button is-small is-primary" type="submit">Add</button>
<input class="file-input" type="file" name="cover" accept="image/*" enctype="multipart/form-data" id="id_cover" required>
<span class="file-cta">
<span class="file-icon">
<i class="fas fa-upload"></i>
</span>
<span class="file-label">
Choose file...
</span>
</span>
</label>
</div>
</div>
<div class="control">
<button class="button is-small is-primary" type="submit">Add</button>
</div>
</div>
</form> </form>
</div> </div>
{% endif %} {% endif %}

View file

@ -62,7 +62,7 @@
<div class="column is-narrow"> <div class="column is-narrow">
<div class="block"> <div class="block">
<h2 class="title is-4">Cover</h2> <h2 class="title is-4">Cover</h2>
<p>{{ form.cover }} </p> <p>{{ form.cover }}</p>
{% for error in form.cover.errors %} {% for error in form.cover.errors %}
<p class="help is-danger">{{ error | escape }}</p> <p class="help is-danger">{{ error | escape }}</p>
{% endfor %} {% endfor %}

View file

@ -5,20 +5,29 @@
Follow request already sent. Follow request already sent.
</div> </div>
{% elif user in request.user.blocks.all %}
{% include 'snippets/block_button.html' %}
{% else %} {% else %}
<form action="/follow/" method="POST" class="interaction follow-{{ user.id }} {% if request.user in user.followers.all %}hidden{%endif %}" data-id="follow-{{ user.id }}"> <div class="field has-addons">
{% csrf_token %} <div class="control">
<input type="hidden" name="user" value="{{ user.username }}"> <form action="/follow/" method="POST" class="interaction follow-{{ user.id }} {% if request.user in user.followers.all %}hidden{%endif %}" data-id="follow-{{ user.id }}">
{% if user.manually_approves_followers %} {% csrf_token %}
<button class="button is-small is-link" type="submit">Send follow request</button> <input type="hidden" name="user" value="{{ user.username }}">
{% else %} {% if user.manually_approves_followers %}
<button class="button is-small is-link" type="submit">Follow</button> <button class="button is-small is-link" type="submit">Send follow request</button>
{% endif %} {% else %}
</form> <button class="button is-small is-link" type="submit">Follow</button>
<form action="/unfollow/" method="POST" class="interaction follow-{{ user.id }} {% if not request.user in user.followers.all %}hidden{%endif %}" data-id="follow-{{ user.id }}"> {% endif %}
{% csrf_token %} </form>
<input type="hidden" name="user" value="{{ user.username }}"> <form action="/unfollow/" method="POST" class="interaction follow-{{ user.id }} {% if not request.user in user.followers.all %}hidden{%endif %}" data-id="follow-{{ user.id }}">
<button class="button is-small is-danger is-light" type="submit">Unfollow</button> {% csrf_token %}
</form> <input type="hidden" name="user" value="{{ user.username }}">
<button class="button is-small is-danger is-light" type="submit">Unfollow</button>
</form>
</div>
<div class="control">
{% include 'snippets/user_options.html' with user=user class="is-small" %}
</div>
</div>
{% endif %} {% endif %}

View file

@ -43,14 +43,7 @@
</div> </div>
</div> </div>
{% if not is_self and request.user.is_authenticated %} {% if not is_self and request.user.is_authenticated %}
<div class="field has-addons"> {% include 'snippets/follow_button.html' with user=user %}
<div class="control">
{% include 'snippets/follow_button.html' with user=user %}
</div>
<div class="control">
{% include 'snippets/user_options.html' with user=user class="is-small" %}
</div>
</div>
{% endif %} {% endif %}
{% if is_self and user.follower_requests.all %} {% if is_self and user.follower_requests.all %}

View file

@ -56,12 +56,14 @@ class ViewsHelpers(TestCase):
def test_get_user_from_username(self): def test_get_user_from_username(self):
''' works for either localname or username ''' ''' works for either localname or username '''
self.assertEqual( self.assertEqual(
views.helpers.get_user_from_username('mouse'), self.local_user) views.helpers.get_user_from_username(
self.local_user, 'mouse'), self.local_user)
self.assertEqual( self.assertEqual(
views.helpers.get_user_from_username( views.helpers.get_user_from_username(
'mouse@local.com'), self.local_user) self.local_user, 'mouse@local.com'), self.local_user)
with self.assertRaises(models.User.DoesNotExist): with self.assertRaises(models.User.DoesNotExist):
views.helpers.get_user_from_username('mojfse@example.com') views.helpers.get_user_from_username(
self.local_user, 'mojfse@example.com')
def test_is_api_request(self): def test_is_api_request(self):

View file

@ -41,6 +41,7 @@ class RssFeedView(TestCase):
''' load an rss feed ''' ''' load an rss feed '''
view = rss_feed.RssFeed() view = rss_feed.RssFeed()
request = self.factory.get('/user/rss_user/rss') request = self.factory.get('/user/rss_user/rss')
request.user = self.user
with patch("bookwyrm.models.SiteSettings.objects.get") as site: with patch("bookwyrm.models.SiteSettings.objects.get") as site:
site.return_value = self.site site.return_value = self.site
result = view(request, username=self.user.username) result = view(request, username=self.user.username)

View file

@ -65,7 +65,7 @@ class DirectMessage(View):
user = None user = None
if username: if username:
try: try:
user = get_user_from_username(username) user = get_user_from_username(request.user, username)
except models.User.DoesNotExist: except models.User.DoesNotExist:
pass pass
if user: if user:
@ -91,7 +91,7 @@ class Status(View):
def get(self, request, username, status_id): def get(self, request, username, status_id):
''' display a particular status (and replies, etc) ''' ''' display a particular status (and replies, etc) '''
try: try:
user = get_user_from_username(username) user = get_user_from_username(request.user, username)
status = models.Status.objects.select_subclasses().get( status = models.Status.objects.select_subclasses().get(
id=status_id, deleted=False) id=status_id, deleted=False)
except ValueError: except ValueError:

View file

@ -13,7 +13,7 @@ def follow(request):
''' follow another user, here or abroad ''' ''' follow another user, here or abroad '''
username = request.POST['user'] username = request.POST['user']
try: try:
to_follow = get_user_from_username(username) to_follow = get_user_from_username(request.user, username)
except models.User.DoesNotExist: except models.User.DoesNotExist:
return HttpResponseBadRequest() return HttpResponseBadRequest()
@ -33,7 +33,7 @@ def unfollow(request):
''' unfollow a user ''' ''' unfollow a user '''
username = request.POST['user'] username = request.POST['user']
try: try:
to_unfollow = get_user_from_username(username) to_unfollow = get_user_from_username(request.user, username)
except models.User.DoesNotExist: except models.User.DoesNotExist:
return HttpResponseBadRequest() return HttpResponseBadRequest()
@ -52,7 +52,7 @@ def accept_follow_request(request):
''' a user accepts a follow request ''' ''' a user accepts a follow request '''
username = request.POST['user'] username = request.POST['user']
try: try:
requester = get_user_from_username(username) requester = get_user_from_username(request.user, username)
except models.User.DoesNotExist: except models.User.DoesNotExist:
return HttpResponseBadRequest() return HttpResponseBadRequest()
@ -75,7 +75,7 @@ def delete_follow_request(request):
''' a user rejects a follow request ''' ''' a user rejects a follow request '''
username = request.POST['user'] username = request.POST['user']
try: try:
requester = get_user_from_username(username) requester = get_user_from_username(request.user, username)
except models.User.DoesNotExist: except models.User.DoesNotExist:
return HttpResponseBadRequest() return HttpResponseBadRequest()

View file

@ -18,7 +18,7 @@ class Goal(View):
''' track books for the year ''' ''' track books for the year '''
def get(self, request, username, year): def get(self, request, username, year):
''' reading goal page ''' ''' reading goal page '''
user = get_user_from_username(username) user = get_user_from_username(request.user, username)
year = int(year) year = int(year)
goal = models.AnnualGoal.objects.filter( goal = models.AnnualGoal.objects.filter(
year=year, user=user year=year, user=user
@ -42,7 +42,7 @@ class Goal(View):
def post(self, request, username, year): def post(self, request, username, year):
''' update or create an annual goal ''' ''' update or create an annual goal '''
user = get_user_from_username(username) user = get_user_from_username(request.user, username)
if user != request.user: if user != request.user:
return HttpResponseNotFound() return HttpResponseNotFound()

View file

@ -9,13 +9,13 @@ from bookwyrm.status import create_generated_note
from bookwyrm.utils import regex from bookwyrm.utils import regex
def get_user_from_username(username): def get_user_from_username(viewer, username):
''' helper function to resolve a localname or a username to a user ''' ''' helper function to resolve a localname or a username to a user '''
# raises DoesNotExist if user is now found # raises DoesNotExist if user is now found
try: try:
return models.User.objects.get(localname=username) return models.User.viewer_aware_objects(viewer).get(localname=username)
except models.User.DoesNotExist: except models.User.DoesNotExist:
return models.User.objects.get(username=username) return models.User.viewer_aware_objects(viewer).get(username=username)
def is_api_request(request): def is_api_request(request):

View file

@ -65,7 +65,7 @@ class UserLists(View):
page = int(request.GET.get('page', 1)) page = int(request.GET.get('page', 1))
except ValueError: except ValueError:
page = 1 page = 1
user = get_user_from_username(username) user = get_user_from_username(request.user, username)
lists = models.List.objects.filter(user=user).all() lists = models.List.objects.filter(user=user).all()
lists = privacy_filter( lists = privacy_filter(
request.user, lists, ['public', 'followers', 'unlisted']) request.user, lists, ['public', 'followers', 'unlisted'])

View file

@ -11,7 +11,7 @@ class RssFeed(Feed):
def get_object(self, request, username): def get_object(self, request, username):
''' the user who's posts get serialized ''' ''' the user who's posts get serialized '''
return get_user_from_username(username) return get_user_from_username(request.user, username)
def link(self, obj): def link(self, obj):

View file

@ -33,7 +33,7 @@ class Search(View):
handle_remote_webfinger(query) handle_remote_webfinger(query)
# do a user search # do a user search
user_results = models.User.objects.annotate( user_results = models.User.viewer_aware_objects(request.user).annotate(
similarity=Greatest( similarity=Greatest(
TrigramSimilarity('username', query), TrigramSimilarity('username', query),
TrigramSimilarity('localname', query), TrigramSimilarity('localname', query),

View file

@ -19,7 +19,7 @@ class Shelf(View):
def get(self, request, username, shelf_identifier): def get(self, request, username, shelf_identifier):
''' display a shelf ''' ''' display a shelf '''
try: try:
user = get_user_from_username(username) user = get_user_from_username(request.user, username)
except models.User.DoesNotExist: except models.User.DoesNotExist:
return HttpResponseNotFound() return HttpResponseNotFound()

View file

@ -26,7 +26,7 @@ class User(View):
def get(self, request, username): def get(self, request, username):
''' profile page for a user ''' ''' profile page for a user '''
try: try:
user = get_user_from_username(username) user = get_user_from_username(request.user, username)
except models.User.DoesNotExist: except models.User.DoesNotExist:
return HttpResponseNotFound() return HttpResponseNotFound()
@ -96,7 +96,7 @@ class Followers(View):
def get(self, request, username): def get(self, request, username):
''' list of followers ''' ''' list of followers '''
try: try:
user = get_user_from_username(username) user = get_user_from_username(request.user, username)
except models.User.DoesNotExist: except models.User.DoesNotExist:
return HttpResponseNotFound() return HttpResponseNotFound()
@ -121,7 +121,7 @@ class Following(View):
def get(self, request, username): def get(self, request, username):
''' list of followers ''' ''' list of followers '''
try: try:
user = get_user_from_username(username) user = get_user_from_username(request.user, username)
except models.User.DoesNotExist: except models.User.DoesNotExist:
return HttpResponseNotFound() return HttpResponseNotFound()