From a5a1af418c5128c1221a8364ce89c4a388c27fef Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Tue, 10 Nov 2020 13:39:37 -0800 Subject: [PATCH 01/11] Adds ui for editing and adding shelves --- bookwyrm/static/css/fonts/icomoon.eot | Bin 7624 -> 7744 bytes bookwyrm/static/css/fonts/icomoon.svg | 1 + bookwyrm/static/css/fonts/icomoon.ttf | Bin 7460 -> 7580 bytes bookwyrm/static/css/fonts/icomoon.woff | Bin 7536 -> 7656 bytes bookwyrm/static/css/icons.css | 13 +++--- bookwyrm/templates/followers.html | 10 +++++ bookwyrm/templates/following.html | 10 +++++ bookwyrm/templates/shelf.html | 45 +++++++++++++++++-- bookwyrm/templates/snippets/user_header.html | 13 ------ bookwyrm/templates/user.html | 15 +++++++ bookwyrm/templates/user_shelves.html | 25 ----------- 11 files changed, 85 insertions(+), 47 deletions(-) delete mode 100644 bookwyrm/templates/user_shelves.html diff --git a/bookwyrm/static/css/fonts/icomoon.eot b/bookwyrm/static/css/fonts/icomoon.eot index 0c2680e2a1b3249a5616c11ef3996d5a26a06522..30ae2cd57334ee225ee478e7d23d10bab788d955 100644 GIT binary patch delta 465 zcmX?MeZYp*L5_i8&O}yo7JKu)CzAzbL?(tL)w6RjFfi-^;)LYf#DdEoE`MfVV3Yy! zbJ7!w3xKo$klz8MInr|~(-xg-ss!>UFfd4pWTYmhNOLSrU|^710+ct)019w$v*-f( zcYu7AjNFonx^@nr8PY&5Lr+eAa$@$U5};K>X|A8Vv4KEphBG;iJjQ<~tvxrR>a~G2U>R@DG*eu3$NTUA#0Tu@40}RSQ zBNPQq)U+9u*hB>tmDpq%MZ}C11x3WH8I8>LGAk2G!SNPuoUSVNg z#sn~jF#*V7asX4j*c5S#*H>3?N@6 zBe$fYs+|L9hExxb-;tA_oS6M7y^VoES_H^<%T25(V9?iQ0$L^=0~AomOUzB3>BR|j zfOHMelD2~U;t~dCpbUd73rL=UnfdbM6h=Fym$xP_VYD{)01EOka4;}2urV+)D7=(- z+4l0*|G)qLgR}to3_$*MFrV@NV{sO->0<6c;}|!~F&&an04d2_cldTZzs*+$Zjkv5 l47bm_PlwTybEM4~l_oEd?wD*K + \ No newline at end of file diff --git a/bookwyrm/static/css/fonts/icomoon.ttf b/bookwyrm/static/css/fonts/icomoon.ttf index 58aeb8fe1d1799f79772a6727cb961dea997a1b4..40d6e886255770541932dbd4b4d4930eca41ff88 100644 GIT binary patch delta 460 zcmZ2tHOIQ1fsuiMft#U$ftkU;KUm+0Ux=LpD6$8L6OwZi3od`S{F#A)Q3lA*Nlz>; z0MY_Leg}}|NYANETXd?a63Cyxz#u7-k(!ty&9O9rfkA2sP~I#9D8RwZq6_5T0rFKc za!V@e+Btw`NCUYHJvsTwj)~cyN`MAR_W%VvauX{G7<8C`mPua$@)hzDb5mz}asCGK zzW^<1E66V{0Xh^2WNSe349v_|CLXY3dc`$~(b_%$C?o)cAO(yJ3NIyIw!OUditGR1 z|Nns^K;kZi?fJL7jqYr0O|mS!sa5zLlX7>53n#WA7D@h8lfm?qNdHL z#3m}JsKh4AC?aO8C@3Ok&1ht1DyV2=X3J=z#{A&l0%6_*yu$w$@Cpm_GA4jIj0r#v zlLMII#ijt{8c?_c!IM67`*?nvuMFHQATBS%?F$>qKr9eFIYi2wQF(HYRL5iiX)ht3 aF0d|TCMgC`95FC3O%{|D-dr!elo0?NN^cSX delta 328 zcmbPZy~L`XfsuiMft#U$ftkU;KUm+0Ux@8GP-G7fCnV=47BH;e^P7QzQ3l9QNlz>; z0MY_Leglx^NYANEGp{!WvKc!V7$jC?q$Z|FvtC}rz#wG+lsC%&3UF|<=m7Z{K)y;w zZb?N|I|tAVsU9G|BPT!EF){m7dK&|Sv+&=F< g9Y#++A!W{}G)cN+a*wnd2T&9gZc3YPNgrYa03B9UjQ{`u diff --git a/bookwyrm/static/css/fonts/icomoon.woff b/bookwyrm/static/css/fonts/icomoon.woff index 2483f599c5e1555a79f55ef2102e0388832c03b5..6cfa9a4da17882e7cb0d51ebd423e00e5de1ad84 100644 GIT binary patch delta 486 zcmexh^}<@D+~3WOfsp|SWM43FgXuXFMYQVKIg)b|3m6y}Gk{__Abk15<_K^S_8;e0bveq z7Tt{8k_w=h50Kvj!gcK&1v&Z2i46V>(l>wt9w40ksYD<*u>xqZi~^7k!8%Mbd5O8H zKrsiPX?BnX67rCc^K`OUU5zKVYIdn0162JAxMgmLE)vu z%eI%dUUB{Z`~N>s1Zcra2B64ws0ic#$Kotv)5YAyB!D`AA+>oQ;~|Oq{|8tYm=7>0 z1C3A=G*Q!LRALhqR8(SE zH;Yb2Zb=1D>;{nE0m4=790fV~$%zd94AKce0XGoN{*>O9n^*y~SQ=;ng8~?9Gs)y7 z=B5J0P5>=$1L2uooWBe5i%Wps34p6(2C|r$FHh!Sv}1aCYqAfcwYdjSh!5y~CI&X3 z?-gE3yli`U>;K>X|AFE_<6klW`PadG#{ZASS;VG`xic^`Fm67^ct}D4q$G3Q;oI^2 zHeVUISwLKd+vnY44 DES+A> diff --git a/bookwyrm/static/css/icons.css b/bookwyrm/static/css/icons.css index dafaca21b..536db5600 100644 --- a/bookwyrm/static/css/icons.css +++ b/bookwyrm/static/css/icons.css @@ -1,10 +1,10 @@ @font-face { font-family: 'icomoon'; - src: url('fonts/icomoon.eot?jhaogg'); - src: url('fonts/icomoon.eot?jhaogg#iefix') format('embedded-opentype'), - url('fonts/icomoon.ttf?jhaogg') format('truetype'), - url('fonts/icomoon.woff?jhaogg') format('woff'), - url('fonts/icomoon.svg?jhaogg#icomoon') format('svg'); + src: url('fonts/icomoon.eot?rd4abb'); + src: url('fonts/icomoon.eot?rd4abb#iefix') format('embedded-opentype'), + url('fonts/icomoon.ttf?rd4abb') format('truetype'), + url('fonts/icomoon.woff?rd4abb') format('woff'), + url('fonts/icomoon.svg?rd4abb#icomoon') format('svg'); font-weight: normal; font-style: normal; font-display: block; @@ -115,3 +115,6 @@ .icon-heart:before { content: "\e9da"; } +.icon-plus:before { + content: "\ea0a"; +} diff --git a/bookwyrm/templates/followers.html b/bookwyrm/templates/followers.html index a5fdfd82a..645e46a17 100644 --- a/bookwyrm/templates/followers.html +++ b/bookwyrm/templates/followers.html @@ -1,6 +1,16 @@ {% extends 'layout.html' %} {% load fr_display %} {% block content %} +
+

+ {% if is_self %}Your + {% else %} + {% include 'snippets/username.html' with user=user possessive=True %} + {% endif %} + followers +

+
+ {% include 'snippets/user_header.html' with user=user %}
diff --git a/bookwyrm/templates/following.html b/bookwyrm/templates/following.html index c3bf976ab..2cca91273 100644 --- a/bookwyrm/templates/following.html +++ b/bookwyrm/templates/following.html @@ -1,6 +1,16 @@ {% extends 'layout.html' %} {% load fr_display %} {% block content %} +
+

+ Users following + {% if is_self %}you + {% else %} + {% include 'snippets/username.html' with user=user %} + {% endif %} +

+
+ {% include 'snippets/user_header.html' with user=user %}
diff --git a/bookwyrm/templates/shelf.html b/bookwyrm/templates/shelf.html index 8e6cc9f88..660d400c9 100644 --- a/bookwyrm/templates/shelf.html +++ b/bookwyrm/templates/shelf.html @@ -1,20 +1,57 @@ {% extends 'layout.html' %} {% load fr_display %} {% block content %} + +
+
+

+ {% if is_self %}Your + {% else %} + {% include 'snippets/username.html' with user=user possessive=True %} + {% endif %} + shelves +

+
+ {% if is_self %} + + {% endif %} +
+ {% include 'snippets/user_header.html' with user=user %}
-
+
+
+
+

{{ shelf.name }}

+
+ {% if is_self %} + + {% endif %} +
+
{% include 'snippets/shelf.html' with shelf=shelf ratings=ratings %} diff --git a/bookwyrm/templates/snippets/user_header.html b/bookwyrm/templates/snippets/user_header.html index bb892757f..d9ca71b24 100644 --- a/bookwyrm/templates/snippets/user_header.html +++ b/bookwyrm/templates/snippets/user_header.html @@ -1,19 +1,6 @@ {% load humanize %} {% load fr_display %}
-
-

User Profile

- {% if is_self %} - - {% endif %} -
-
diff --git a/bookwyrm/templates/user.html b/bookwyrm/templates/user.html index b6d808c86..ba9fcc94b 100644 --- a/bookwyrm/templates/user.html +++ b/bookwyrm/templates/user.html @@ -1,6 +1,21 @@ {% extends 'layout.html' %} {% block content %} +
+
+

User profile

+
+ {% if is_self %} + + {% endif %} +
+ {% include 'snippets/user_header.html' with user=user %}
diff --git a/bookwyrm/templates/user_shelves.html b/bookwyrm/templates/user_shelves.html deleted file mode 100644 index acda58ca0..000000000 --- a/bookwyrm/templates/user_shelves.html +++ /dev/null @@ -1,25 +0,0 @@ -{% extends 'layout.html' %} -{% load fr_display %} -{% block content %} -{% include 'snippets/user_header.html' with user=user %} - -
-
- -

{{ shelf.name }}

-
- -{% for shelf in shelves %} -
- {% include 'snippets/shelf.html' with shelf=shelf ratings=ratings %} -
-{% endfor %} - -{% endblock %} - From ab0f9230c72a23ae4fdaa7654bc0067f151165b4 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Tue, 10 Nov 2020 13:39:58 -0800 Subject: [PATCH 02/11] Adds privacy setting to shelves --- bookwyrm/migrations/0009_shelf_privacy.py | 18 ++++++++++++++++++ bookwyrm/models/shelf.py | 7 ++++++- 2 files changed, 24 insertions(+), 1 deletion(-) create mode 100644 bookwyrm/migrations/0009_shelf_privacy.py diff --git a/bookwyrm/migrations/0009_shelf_privacy.py b/bookwyrm/migrations/0009_shelf_privacy.py new file mode 100644 index 000000000..8232c2edc --- /dev/null +++ b/bookwyrm/migrations/0009_shelf_privacy.py @@ -0,0 +1,18 @@ +# Generated by Django 3.0.7 on 2020-11-10 20:53 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('bookwyrm', '0008_work_default_edition'), + ] + + operations = [ + migrations.AddField( + model_name='shelf', + name='privacy', + field=models.CharField(choices=[('public', 'Public'), ('unlisted', 'Unlisted'), ('followers', 'Followers'), ('direct', 'Direct')], default='public', max_length=255), + ), + ] diff --git a/bookwyrm/models/shelf.py b/bookwyrm/models/shelf.py index cd82198c9..dafc8ff59 100644 --- a/bookwyrm/models/shelf.py +++ b/bookwyrm/models/shelf.py @@ -2,7 +2,7 @@ from django.db import models from bookwyrm import activitypub -from .base_model import BookWyrmModel, OrderedCollectionMixin +from .base_model import BookWyrmModel, OrderedCollectionMixin, PrivacyLevels class Shelf(OrderedCollectionMixin, BookWyrmModel): @@ -11,6 +11,11 @@ class Shelf(OrderedCollectionMixin, BookWyrmModel): identifier = models.CharField(max_length=100) user = models.ForeignKey('User', on_delete=models.PROTECT) editable = models.BooleanField(default=True) + privacy = models.CharField( + max_length=255, + default='public', + choices=PrivacyLevels.choices + ) books = models.ManyToManyField( 'Edition', symmetrical=False, From c3fe8e041ab40ad9ba94165741fce38ab8b9fbe8 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Tue, 10 Nov 2020 14:07:12 -0800 Subject: [PATCH 03/11] Disentangles user pages --- bookwyrm/views.py | 54 ++++++++++++++++++++++++++--------------------- 1 file changed, 30 insertions(+), 24 deletions(-) diff --git a/bookwyrm/views.py b/bookwyrm/views.py index 679464914..d4f483aaf 100644 --- a/bookwyrm/views.py +++ b/bookwyrm/views.py @@ -311,8 +311,9 @@ def notifications_page(request): notifications.update(read=True) return TemplateResponse(request, 'notifications.html', data) + @csrf_exempt -def user_page(request, username, subpage=None, shelf=None): +def user_page(request, username): ''' profile page for a user ''' try: user = get_user_from_username(username) @@ -329,19 +330,6 @@ def user_page(request, username, subpage=None, shelf=None): 'user': user, 'is_self': request.user.id == user.id, } - if subpage == 'followers': - data['followers'] = user.followers.all() - return TemplateResponse(request, 'followers.html', data) - if subpage == 'following': - data['following'] = user.following.all() - return TemplateResponse(request, 'following.html', data) - if subpage == 'shelves': - data['shelves'] = user.shelf_set.all() - if shelf: - data['shelf'] = user.shelf_set.get(identifier=shelf) - else: - data['shelf'] = user.shelf_set.first() - return TemplateResponse(request, 'shelf.html', data) data['shelf_count'] = user.shelf_set.count() shelves = [] @@ -376,7 +364,13 @@ def followers_page(request, username): if is_api_request(request): return JsonResponse(user.to_followers_activity(**request.GET)) - return user_page(request, username, subpage='followers') + data = { + 'title': '%s: followers' % user.name, + 'user': user, + 'is_self': request.user.id == user.id, + 'followers': user.followers.all(), + } + return TemplateResponse(request, 'followers.html', data) @csrf_exempt @@ -393,16 +387,19 @@ def following_page(request, username): if is_api_request(request): return JsonResponse(user.to_following_activity(**request.GET)) - return user_page(request, username, subpage='following') + data = { + 'title': '%s: following' % user.name, + 'user': user, + 'is_self': request.user.id == user.id, + 'following': user.following.all(), + } + return TemplateResponse(request, 'following.html', data) @csrf_exempt def user_shelves_page(request, username): ''' list of followers ''' - if request.method != 'GET': - return HttpResponseBadRequest() - - return user_page(request, username, subpage='shelves') + return shelf_page(request, username, None) @csrf_exempt @@ -629,10 +626,19 @@ def shelf_page(request, username, shelf_identifier): except models.User.DoesNotExist: return HttpResponseNotFound() - shelf = models.Shelf.objects.get(user=user, identifier=shelf_identifier) - if is_api_request(request): + shelf = models.Shelf.objects.get(user=user, identifier=shelf_identifier) return JsonResponse(shelf.to_activity(**request.GET)) - return user_page( - request, username, subpage='shelves', shelf=shelf_identifier) + data = { + 'title': user.name, + 'user': user, + 'is_self': request.user.id == user.id, + } + + data['shelves'] = user.shelf_set.all() + if shelf: + data['shelf'] = user.shelf_set.get(identifier=shelf) + else: + data['shelf'] = user.shelf_set.first() + return TemplateResponse(request, 'shelf.html', data) From 408ca6609c0a1fafc02feb4f216d87def1d4df16 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Tue, 10 Nov 2020 14:52:04 -0800 Subject: [PATCH 04/11] Let users create shelves --- bookwyrm/forms.py | 5 +++ bookwyrm/models/shelf.py | 10 ++++++ bookwyrm/templates/shelf.html | 59 ++++++++++++++++++++++++++--------- bookwyrm/urls.py | 1 + bookwyrm/view_actions.py | 11 +++++++ bookwyrm/views.py | 15 +++++---- 6 files changed, 80 insertions(+), 21 deletions(-) diff --git a/bookwyrm/forms.py b/bookwyrm/forms.py index dbe3cb887..29c6b6de7 100644 --- a/bookwyrm/forms.py +++ b/bookwyrm/forms.py @@ -159,3 +159,8 @@ class CreateInviteForm(CustomForm): choices=[(i, "%d uses" % (i,)) for i in [1, 5, 10, 25, 50, 100]] + [(None, 'Unlimited')]) } + +class ShelfForm(CustomForm): + class Meta: + model = models.Shelf + fields = ['user', 'name', 'privacy'] diff --git a/bookwyrm/models/shelf.py b/bookwyrm/models/shelf.py index dafc8ff59..59e5f8413 100644 --- a/bookwyrm/models/shelf.py +++ b/bookwyrm/models/shelf.py @@ -1,4 +1,5 @@ ''' puttin' books on shelves ''' +import re from django.db import models from bookwyrm import activitypub @@ -23,6 +24,15 @@ class Shelf(OrderedCollectionMixin, BookWyrmModel): through_fields=('shelf', 'book') ) + def save(self, *args, **kwargs): + ''' set the identifier ''' + saved = super().save(*args, **kwargs) + if not self.identifier: + slug = re.sub(r'[^\w]', '', self.name) + self.identifier = '%s-%d' % (slug, self.id) + return super().save(*args, **kwargs) + return saved + @property def collection_queryset(self): ''' list of books for this shelf, overrides OrderedCollectionMixin ''' diff --git a/bookwyrm/templates/shelf.html b/bookwyrm/templates/shelf.html index 660d400c9..f6b0972a5 100644 --- a/bookwyrm/templates/shelf.html +++ b/bookwyrm/templates/shelf.html @@ -12,32 +12,61 @@ shelves
+
+ +{% include 'snippets/user_header.html' with user=user %} + +
+
+
+ +
+
+ {% if is_self %} {% endif %}
-{% include 'snippets/user_header.html' with user=user %} + +