diff --git a/bookwyrm/static/js/shared.js b/bookwyrm/static/js/shared.js
index 55a5c1b2..8bac038b 100644
--- a/bookwyrm/static/js/shared.js
+++ b/bookwyrm/static/js/shared.js
@@ -31,8 +31,29 @@ window.onload = function() {
// hidden submit button in a form
document.querySelectorAll('.hidden-form input')
.forEach(t => t.onchange = revealForm);
+
+ // polling
+ document.querySelectorAll('[data-poll]')
+ .forEach(t => setInterval(function () { polling(t) }, 10000));
};
+
+function polling(el) {
+ // poll the endpoint
+ fetch('/api/updates/' + el.getAttribute('data-poll'), {
+ method : "GET",
+ }).then(response => response.json())
+ .then(data => updateCountElement(el, data));
+}
+function updateCountElement(el, data) {
+ const count = data[el.getAttribute('data-poll')];
+ if (count) {
+ removeClass(el, 'hidden');
+ el.innerHTML = count;
+ }
+}
+
+
function revealForm(e) {
var hidden = e.currentTarget.closest('.hidden-form').getElementsByClassName('hidden')[0];
if (hidden) {
diff --git a/bookwyrm/templates/layout.html b/bookwyrm/templates/layout.html
index 30c8bf7a..f3e37861 100644
--- a/bookwyrm/templates/layout.html
+++ b/bookwyrm/templates/layout.html
@@ -113,9 +113,9 @@
Notifications
- {% if request.user|notification_count %}
- {{ request.user | notification_count }}
- {% endif %}
+
+ {{ request.user | notification_count }}
+
diff --git a/bookwyrm/urls.py b/bookwyrm/urls.py
index f014d44d..ab134b1c 100644
--- a/bookwyrm/urls.py
+++ b/bookwyrm/urls.py
@@ -31,14 +31,15 @@ urlpatterns = [
re_path(r'^inbox/?$', incoming.shared_inbox),
re_path(r'%s/inbox/?$' % local_user_path, incoming.inbox),
re_path(r'%s/outbox/?$' % local_user_path, views.Outbox.as_view()),
-
- # .well-known endpoints
re_path(r'^.well-known/webfinger/?$', wellknown.webfinger),
re_path(r'^.well-known/nodeinfo/?$', wellknown.nodeinfo_pointer),
re_path(r'^nodeinfo/2\.0/?$', wellknown.nodeinfo),
re_path(r'^api/v1/instance/?$', wellknown.instance_info),
re_path(r'^api/v1/instance/peers/?$', wellknown.peers),
+ # polling updates
+ re_path('^api/updates/notifications/?$', views.Updates.as_view()),
+
# authentication
re_path(r'^login/?$', views.Login.as_view()),
re_path(r'^register/?$', views.Register.as_view()),
diff --git a/bookwyrm/views/__init__.py b/bookwyrm/views/__init__.py
index e1ffeda4..d37851aa 100644
--- a/bookwyrm/views/__init__.py
+++ b/bookwyrm/views/__init__.py
@@ -23,4 +23,5 @@ from .shelf import Shelf
from .shelf import user_shelves_page, create_shelf, delete_shelf
from .shelf import shelve, unshelve
from .status import Status, Replies, CreateStatus, DeleteStatus
+from .updates import Updates
from .user import User, EditUser, Followers, Following
diff --git a/bookwyrm/views/updates.py b/bookwyrm/views/updates.py
new file mode 100644
index 00000000..233e5191
--- /dev/null
+++ b/bookwyrm/views/updates.py
@@ -0,0 +1,17 @@
+''' endpoints for getting updates about activity '''
+from django.contrib.auth.decorators import login_required
+from django.http import JsonResponse
+from django.utils.decorators import method_decorator
+from django.views import View
+
+# pylint: disable= no-self-use
+@method_decorator(login_required, name='dispatch')
+class Updates(View):
+ ''' so the app can poll '''
+ def get(self, request):
+ ''' any notifications waiting? '''
+ return JsonResponse({
+ 'notifications': request.user.notification_set.filter(
+ read=False
+ ).count(),
+ })