(Un)follow and boost/like buttons via javascript

Works on #78
This commit is contained in:
Mouse Reeve 2020-03-21 14:29:39 -07:00
parent 1ec515034c
commit e0bd8200ad
8 changed files with 49 additions and 37 deletions

View File

@ -4,14 +4,12 @@ from Crypto.PublicKey import RSA
from Crypto.Signature import pkcs1_15 from Crypto.Signature import pkcs1_15
from Crypto.Hash import SHA256 from Crypto.Hash import SHA256
from django.http import HttpResponse, HttpResponseBadRequest, \ from django.http import HttpResponse, HttpResponseBadRequest, \
HttpResponseNotFound, JsonResponse HttpResponseNotFound
from django.views.decorators.csrf import csrf_exempt from django.views.decorators.csrf import csrf_exempt
import django.db.utils import django.db.utils
from django.db.models import Q
import json import json
import requests import requests
from fedireads import activitypub
from fedireads import models from fedireads import models
from fedireads import outgoing from fedireads import outgoing
from fedireads.status import create_review_from_activity, \ from fedireads.status import create_review_from_activity, \
@ -191,7 +189,10 @@ def handle_incoming_follow_reject(activity):
rejecter = get_or_create_remote_user(activity['actor']) rejecter = get_or_create_remote_user(activity['actor'])
try: try:
request = models.UserFollowRequest.objects.get(user_subject=requester, user_object=rejecter) request = models.UserFollowRequest.objects.get(
user_subject=requester,
user_object=rejecter
)
request.delete() request.delete()
except models.UserFollowRequest.DoesNotExist: except models.UserFollowRequest.DoesNotExist:
pass pass

View File

@ -498,6 +498,10 @@ blockquote .icon-quote-open {
height: 4em; height: 4em;
} }
.hidden {
display: none;
}
table { table {
border-collapse: collapse; border-collapse: collapse;
margin: 1em; margin: 1em;

View File

@ -6,10 +6,14 @@ function hide_element(element) {
function interact(e) { function interact(e) {
e.preventDefault(); e.preventDefault();
ajaxPost(e.target); ajaxPost(e.target);
if (e.target.className.includes('active')) { var identifier = e.target.getAttribute('data-id');
e.target.className = ''; var elements = document.getElementsByClassName(identifier);
} else { for (var i = 0; i < elements.length; i++) {
e.target.className += ' active'; if (elements[i].className.includes('hidden')) {
elements[i].className = elements[i].className.replace('hidden', '');
} else {
elements[i].className += ' hidden';
}
} }
return true; return true;
} }
@ -21,26 +25,9 @@ function comment(e) {
return true; return true;
} }
function ajaxPost(form, callback) { function ajaxPost(form) {
// jeez. https://stackoverflow.com/questions/33021995 fetch(form.action, {
var url = form.action; method : "POST",
var xhr = new XMLHttpRequest(); body: new FormData(form)
});
var params = [].filter.call(form.elements, function(el) {
return typeof(el.checked) === 'undefined' || el.checked;
})
.filter(function(el) { return !!el.name; })
.filter(function(el) { return el.disabled; })
.map(function(el) {
return encodeURIComponent(el.name) + '=' + encodeURIComponent(el.value);
}).join('&');
xhr.open('POST', url);
xhr.setRequestHeader('Content-type', 'application/x-form-urlencoded');
xhr.setRequestHeader('X-CSRFToken', csrf_token);
if (callback) {
xhr.onload = callback.bind(xhr);
}
xhr.send(params);
} }

View File

@ -0,0 +1 @@
module.exports=function(e,n){return n=n||{},new Promise(function(t,r){var s=new XMLHttpRequest,o=[],u=[],i={},a=function(){return{ok:2==(s.status/100|0),statusText:s.statusText,status:s.status,url:s.responseURL,text:function(){return Promise.resolve(s.responseText)},json:function(){return Promise.resolve(JSON.parse(s.responseText))},blob:function(){return Promise.resolve(new Blob([s.response]))},clone:a,headers:{keys:function(){return o},entries:function(){return u},get:function(e){return i[e.toLowerCase()]},has:function(e){return e.toLowerCase()in i}}}};for(var l in s.open(n.method||"get",e,!0),s.onload=function(){s.getAllResponseHeaders().replace(/^(.*?):[^\S\n]*([\s\S]*?)$/gm,function(e,n,t){o.push(n=n.toLowerCase()),u.push([n,t]),i[n]=i[n]?i[n]+","+t:t}),t(a())},s.onerror=r,s.withCredentials="include"==n.credentials,n.headers)s.setRequestHeader(l,n.headers[l]);s.send(n.body||null)})};

View File

@ -72,6 +72,7 @@
<script> <script>
var csrf_token = '{{ csrf_token }}'; var csrf_token = '{{ csrf_token }}';
</script> </script>
<script src="/static/js/unfetch.js"></script>
<script src="/static/js/shared.js"></script> <script src="/static/js/shared.js"></script>
</body> </body>
</html> </html>

View File

@ -1,10 +1,13 @@
{% if request.user == user %} {% if request.user == user %}
{% elif request.user in user.follower_requests.all %} {% elif request.user in user.follower_requests.all %}
<div> <div>
Follow request already sent. Follow request already sent.
</div> </div>
{% elif not request.user in user.followers.all %}
<form action="/follow/" method="post"> {% else %}
<form action="/follow/" method="POST" onsubmit="interact(event)" class="follow-{{ user.id }} {% if request.user in user.followers.all %}hidden{%endif %}" data-id="follow-{{ user.id }}">
{% csrf_token %} {% csrf_token %}
<input type="hidden" name="user" value="{{ user.username }}"></input> <input type="hidden" name="user" value="{{ user.username }}"></input>
{% if user.manually_approves_followers %} {% if user.manually_approves_followers %}
@ -13,8 +16,7 @@ Follow request already sent.
<button type="submit">Follow</button> <button type="submit">Follow</button>
{% endif %} {% endif %}
</form> </form>
{% else %} <form action="/unfollow/" method="POST" onsubmit="interact(event)" class="follow-{{ user.id }} {% if not request.user in user.followers.all %}hidden{%endif %}" data-id="follow-{{ user.id }}">
<form action="/unfollow/" method="post">
{% csrf_token %} {% csrf_token %}
<input type="hidden" name="user" value="{{ user.username }}"></input> <input type="hidden" name="user" value="{{ user.username }}"></input>
<button type="submit">Unfollow</button> <button type="submit">Unfollow</button>

View File

@ -12,7 +12,7 @@
</button> </button>
</form> </form>
<form name="boost" action="/boost/{{ activity.id }}" method="POST" onsubmit="return interact(event)" class="{% if False %}active{% endif %}"> <form name="boost" action="/boost/{{ activity.id }}" method="post" onsubmit="return interact(event)" class="boost-{{ status.id }} {% if False %}hidden{% endif %}" data-id="boost-{{ status.id }}">
{% csrf_token %} {% csrf_token %}
<button type="submit"> <button type="submit">
<span class="icon icon-boost"> <span class="icon icon-boost">
@ -20,8 +20,16 @@
</span> </span>
</button> </button>
</form> </form>
<form name="unboost" action="/unboost/{{ activity.id }}" method="post" onsubmit="return interact(event)" class="boost-{{ status.id }} active {% if not False %}hidden{% endif %}" data-id="boost-{{ status.id }}">
{% csrf_token %}
<button type="submit">
<span class="icon icon-boost">
<span class="hidden-text">Un-boost status</span>
</span>
</button>
</form>
<form name="favorite" action="/favorite/{{ activity.id }}" method="POST" onsubmit="return interact(event)" class="{% if request.user|liked:status %}active{% endif %}"> <form name="favorite" action="/favorite/{{ activity.id }}" method="POST" onsubmit="return interact(event)" class="fav-{{ status.id }} {% if request.user|liked:status %}hidden{% endif %}" data-id="fav-{{ status.id }}">
{% csrf_token %} {% csrf_token %}
<button type="submit"> <button type="submit">
<span class="icon icon-heart"> <span class="icon icon-heart">
@ -29,5 +37,13 @@
</span> </span>
</button> </button>
</form> </form>
<form name="favorite" action="/favorite/{{ activity.id }}" method="POST" onsubmit="return interact(event)" class="fav-{{ status.id }} active {% if not request.user|liked:status %}hidden{% endif %}" data-id="fav-{{ status.id }}">
{% csrf_token %}
<button type="submit">
<span class="icon icon-heart">
<span class="hidden-text">Un-like status</span>
</span>
</button>
</form>
</div> </div>

View File

@ -1,6 +1,6 @@
{% extends 'layout.html' %} {% extends 'layout.html' %}
{% block content %} {% block content %}
<div id="content"> <div class="content-container">
{% for result in results %} {% for result in results %}
<div> <div>
<h2>{{ result.username }}</h2> <h2>{{ result.username }}</h2>