add fav and repost function
This commit is contained in:
parent
c5a762a646
commit
715a0a1a07
10 changed files with 229 additions and 46 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -133,3 +133,4 @@ tmp/restart.txt
|
|||
# Django
|
||||
migrations/
|
||||
media/img/
|
||||
db.sqlite3.sqbpro
|
||||
|
|
|
@ -63,6 +63,8 @@ class Following(models.Model):
|
|||
)
|
||||
|
||||
|
||||
|
||||
|
||||
class Post(models.Model):
|
||||
text = models.TextField()
|
||||
poster = models.ForeignKey(User, on_delete=models.CASCADE)
|
||||
|
@ -81,3 +83,24 @@ class Post(models.Model):
|
|||
)
|
||||
|
||||
|
||||
|
||||
class Repost(models.Model):
|
||||
reposter = models.ForeignKey(User, on_delete=models.CASCADE, related_name="reposter")
|
||||
reposted_post = models.ForeignKey(Post, on_delete=models.CASCADE, related_name="reposted_post")
|
||||
repost_time = models.DateTimeField(default=timezone.now())
|
||||
is_read = models.BooleanField(default=False)
|
||||
|
||||
class Reply(models.Model):
|
||||
replyer_post = models.ForeignKey(Post, on_delete=models.CASCADE, related_name="replyer_post")
|
||||
replyee_post = models.ForeignKey(Post, on_delete=models.CASCADE, related_name="replyee_post")
|
||||
is_read = models.BooleanField(default=False)
|
||||
|
||||
class Fav(models.Model):
|
||||
favouriter = models.ForeignKey(User, on_delete=models.CASCADE, related_name="favouriter")
|
||||
favourited_post = models.ForeignKey(Post, on_delete=models.CASCADE, related_name="favourited_post")
|
||||
favourited_time = models.DateTimeField(default=timezone.now())
|
||||
is_read = models.BooleanField(default=False)
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -32,7 +32,10 @@ urlpatterns = [
|
|||
path('api/get_latest_posts', views.api_get_latest_posts),
|
||||
path('api/get_previous_posts', views.api_get_previous_posts),
|
||||
path('user/<username>', views.user_timeline),
|
||||
path('api/follow_request/<request_value>/<dest_username>', views.follow_request)
|
||||
path('api/follow_request/<request_value>/<dest_username>', views.api_follow_request),
|
||||
path('api/repost_request/<post_id>', views.api_repost_request),
|
||||
path('api/fav_request/<post_id>', views.api_fav_request),
|
||||
|
||||
]
|
||||
|
||||
if settings.DEBUG:
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import json
|
||||
from django.http import HttpResponse, HttpResponseNotAllowed
|
||||
from django.template import loader
|
||||
from .models import User, Post, Following
|
||||
from .models import User, Post, Following, Fav, Repost
|
||||
from django.utils import timezone
|
||||
from django.contrib.auth.forms import UserCreationForm
|
||||
from django.shortcuts import redirect
|
||||
|
@ -37,12 +37,21 @@ def api_get_previous_posts(request):
|
|||
older_posts = Post.objects.filter(post_time__lt=oldest_datetime_object).filter(poster=poster).order_by('-id')[:20]
|
||||
else:
|
||||
pass
|
||||
older_posts_list = [{"id" : o.pk,
|
||||
"post_time" : datetime.strftime(o.post_time, "%Y-%m-%d %H:%M:%S.%f%z"),
|
||||
"poster_username" : o.poster.username,
|
||||
"poster_shown_name":o.poster.shown_name ,
|
||||
"text": o.text}
|
||||
for o in older_posts]
|
||||
|
||||
is_faved = [Fav.objects.filter(favourited_post=p).filter(favouriter=request.user).__len__() for p in older_posts]
|
||||
is_reposted = [Repost.objects.filter(reposted_post=p).filter(reposter=request.user).__len__() for p in older_posts]
|
||||
older_posts_info = zip(older_posts, is_faved, is_reposted)
|
||||
|
||||
older_posts_list = [{"id" : o[0].pk,
|
||||
"post_time" : datetime.strftime(o[0].post_time, "%Y-%m-%d %H:%M:%S.%f%z"),
|
||||
"poster_avatar" : o[0].poster.avatar.url,
|
||||
"poster_username" : o[0].poster.username,
|
||||
"poster_shown_name":o[0].poster.shown_name ,
|
||||
"text": o[0].text,
|
||||
"is_faved" : o[1],
|
||||
"is_reposted" : o[2],
|
||||
}
|
||||
for o in older_posts_info]
|
||||
if len(list(older_posts)) > 0:
|
||||
oldest_time = datetime.strftime(list(older_posts)[-1].post_time, "%Y-%m-%d %H:%M:%S.%f%z")
|
||||
else:
|
||||
|
@ -72,12 +81,20 @@ def api_get_latest_posts(request):
|
|||
poster = User.objects.get(username=username)
|
||||
newer_posts = Post.objects.filter(post_time__gt=latest_datetime_object).filter(poster=poster).order_by('-id')[:20]
|
||||
|
||||
newer_posts_list = [{"id" : o.pk,
|
||||
"post_time" : datetime.strftime(o.post_time, "%Y-%m-%d %H:%M:%S.%f%z"),
|
||||
"poster_username" : o.poster.username,
|
||||
"poster_shown_name":o.poster.shown_name ,
|
||||
"text": o.text}
|
||||
for o in newer_posts]
|
||||
is_faved = [Fav.objects.filter(favourited_post=p).filter(favouriter=request.user).__len__() for p in newer_posts]
|
||||
is_reposted = [Repost.objects.filter(reposted_post=p).filter(reposter=request.user).__len__() for p in newer_posts]
|
||||
newer_posts_infp = zip(newer_posts, is_faved, is_reposted)
|
||||
|
||||
newer_posts_list = [{"id" : o[0].pk,
|
||||
"post_time" : datetime.strftime(o[0].post_time, "%Y-%m-%d %H:%M:%S.%f%z"),
|
||||
"poster_avatar" : o[0].poster.avatar.url,
|
||||
"poster_username" : o[0].poster.username,
|
||||
"poster_shown_name":o[0].poster.shown_name ,
|
||||
"text": o[0].text,
|
||||
"is_faved" : o[1],
|
||||
"is_reposted" : o[2],
|
||||
}
|
||||
for o in newer_posts_infp]
|
||||
return JsonResponse({'newer_posts':newer_posts_list})
|
||||
else:
|
||||
return HttpResponseNotAllowed('POST')
|
||||
|
@ -273,7 +290,39 @@ def user_config(request):
|
|||
def is_custom_avatar_path(old_image_path):
|
||||
return os.path.exists(old_image_path) and (old_image_path != os.path.abspath("./media/static/default_avatar.png"))
|
||||
|
||||
def follow_request(request, request_value, dest_username):
|
||||
def api_fav_request(request, post_id):
|
||||
if request.method != "POST":
|
||||
return HttpResponseNotAllowed('POST')
|
||||
current_user = User.objects.get(id=request.user.id)
|
||||
post = Post.objects.get(id=post_id)
|
||||
|
||||
if Fav.objects.filter(favouriter = current_user, favourited_post=post).__len__() > 0:
|
||||
existed_fav = Fav.objects.filter(favouriter = current_user, favourited_post=post)[0]
|
||||
existed_fav.delete()
|
||||
return JsonResponse({'status': "deleted"})
|
||||
else:
|
||||
added_fav = Fav(favouriter = current_user, favourited_post=post)
|
||||
added_fav.save()
|
||||
return JsonResponse({'status': "faved"})
|
||||
|
||||
def api_repost_request(request, post_id):
|
||||
if request.method != "POST":
|
||||
return HttpResponseNotAllowed('POST')
|
||||
current_user = User.objects.get(id=request.user.id)
|
||||
post = Post.objects.get(id=post_id)
|
||||
|
||||
if Repost.objects.filter(reposter = current_user, reposted_post=post).__len__() > 0:
|
||||
existed_repost = Repost.objects.filter(reposter = current_user, reposted_post=post)[0]
|
||||
existed_repost.delete()
|
||||
return JsonResponse({'status': "deleted"})
|
||||
else:
|
||||
added_repost = Repost(reposter = current_user, reposted_post=post)
|
||||
added_repost.save()
|
||||
return JsonResponse({'status': "reposted"})
|
||||
|
||||
|
||||
|
||||
def api_follow_request(request, request_value, dest_username):
|
||||
if request.method != "POST":
|
||||
return HttpResponseNotAllowed('POST')
|
||||
else:
|
||||
|
@ -318,6 +367,10 @@ def user_timeline(request, username):
|
|||
else:
|
||||
viewed_timeline_list = Post.objects.filter(poster = viewed_user.id).filter(privilage = 'public').order_by('-id')[:20]
|
||||
|
||||
is_faved = [Fav.objects.filter(favourited_post=p).filter(favouriter=request.user).__len__() for p in viewed_timeline_list]
|
||||
is_reposted = [Repost.objects.filter(reposted_post=p).filter(reposter=request.user).__len__() for p in viewed_timeline_list]
|
||||
viewed_timeline_info = zip(viewed_timeline_list, is_faved, is_reposted)
|
||||
|
||||
latest_received_time = timezone.now()
|
||||
if len(viewed_timeline_list) > 0:
|
||||
oldest_received_time = list(viewed_timeline_list)[-1].post_time
|
||||
|
@ -334,7 +387,7 @@ def user_timeline(request, username):
|
|||
'user_follower_number': user_follower_number,
|
||||
'latest_received_time' : latest_received_time,
|
||||
'oldest_received_time' : oldest_received_time,
|
||||
'viewed_timeline_list': viewed_timeline_list,
|
||||
'viewed_timeline_info': viewed_timeline_info,
|
||||
}
|
||||
return HttpResponse(template.render(context, request))
|
||||
|
||||
|
@ -346,6 +399,10 @@ def home(request):
|
|||
all_i_follow = Following.objects.filter(follower=request.user.id).filter(isapproved="yes")
|
||||
all_i_follow_and_me = User.objects.filter(Q(id__in = all_i_follow) | Q(id=request.user.id))
|
||||
public_timeline_list = Post.objects.filter(poster__in = all_i_follow_and_me).order_by('-id')[:20]
|
||||
is_faved = [Fav.objects.filter(favourited_post=p).filter(favouriter=request.user).__len__() for p in public_timeline_list]
|
||||
is_reposted = [Repost.objects.filter(reposted_post=p).filter(reposter=request.user).__len__() for p in public_timeline_list]
|
||||
|
||||
public_timeline_info = zip(public_timeline_list, is_faved, is_reposted)
|
||||
|
||||
latest_received_time = timezone.now()
|
||||
|
||||
|
@ -359,6 +416,6 @@ def home(request):
|
|||
context = {
|
||||
'latest_received_time' : latest_received_time,
|
||||
'oldest_received_time' : oldest_received_time,
|
||||
'public_timeline_list': public_timeline_list,
|
||||
'public_timeline_info': public_timeline_info,
|
||||
}
|
||||
return HttpResponse(template.render(context, request))
|
|
@ -1,9 +1,40 @@
|
|||
div.avatar-preview{
|
||||
.post{
|
||||
display:flex;
|
||||
}
|
||||
.post-content{
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
.timeline-avatar-img{
|
||||
flex-direction: row;
|
||||
width:70px;
|
||||
height:70px;
|
||||
|
||||
}
|
||||
|
||||
#avatar-img{
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
width: 150px;
|
||||
height: 150px;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
.reply{
|
||||
filter: grayscale(1);
|
||||
}
|
||||
|
||||
.reply:hover{
|
||||
filter: grayscale(0);
|
||||
}
|
||||
|
||||
|
||||
.unchecked{
|
||||
filter: grayscale(1);
|
||||
}
|
||||
|
||||
.repost:hover{
|
||||
filter: grayscale(0);
|
||||
}
|
||||
|
||||
.fav:hover{
|
||||
filter: grayscale(0);
|
||||
}
|
|
@ -137,8 +137,10 @@ body: JSON.stringify({
|
|||
return item['older_posts'];})
|
||||
.then(posts => {if (posts.length == 0)
|
||||
{$('previous_post_loader').style.display = 'none';}
|
||||
else{posts.forEach(post => appendPostToTheEnd(post));
|
||||
$('oldest_time').innerHTML = new_oldest_time;}})
|
||||
else{posts.forEach(post =>
|
||||
appendPostToTheEnd(post));
|
||||
updateClickedIconEvent();
|
||||
$('oldest_time').innerHTML = new_oldest_time;}})
|
||||
}
|
||||
|
||||
|
||||
|
@ -185,6 +187,7 @@ body: JSON.stringify({
|
|||
$('new_post_notifier').style.display = "none";
|
||||
var nowTime = new Date();
|
||||
var nowTimeString = nowTime.toISOString();
|
||||
updateClickedIconEvent();
|
||||
$("latest_time").innerHTML = nowTimeString.substring(0,10) + " " + nowTimeString.substring(11,23) + "000+0000"; });
|
||||
}
|
||||
|
||||
|
@ -194,12 +197,16 @@ var new_div = document.createElement("div");
|
|||
new_div.id = `post-${post.id}`;
|
||||
new_div.className = "post";
|
||||
post_text_replaced = post.text.replace(/(\r\n|\n\r|\r|\n)/g, "<br>" );
|
||||
new_div.innerHTML = `<a href="/user/${post.poster_username}">${post.poster_shown_name}</a>
|
||||
new_div.innerHTML = `
|
||||
<img class="timeline-avatar-img" width="100" src="${post.poster_avatar}">
|
||||
<div class="post-content">
|
||||
<a href="/user/${post.poster_username}">${post.poster_shown_name}</a>
|
||||
at <a href="/post/${post.id}" class="post-time">${post.post_time}</a><br>
|
||||
${post_text_replaced}<br>
|
||||
<span id="reply-${post.id}" value="${post.id}" class="reply">↩️</span>
|
||||
- <span id="repost-${post.id}" value="${post.id}" class="repost">🔁</span>
|
||||
- <span id="fav-${post.id}" value="${post.id}" class="fav">⭐</span>`;
|
||||
<span id="reply-${post.id}" data-value="${post.id}" class="reply">↩️</span>
|
||||
- <span id="repost-${post.id}" data-value="${post.id}" class="${(post.is_reposted == "0" ? "unchecked" : "")} repost">🔁</span>
|
||||
- <span id="fav-${post.id}" data-value="${post.id}" class="${(post.is_faved == "0" ? "unchecked" : "")} fav">⭐</span>
|
||||
</div>`;
|
||||
|
||||
new_div_timestamp = new_div.getElementsByClassName('post-time')[0];
|
||||
|
||||
|
@ -220,11 +227,66 @@ public_tl.insertBefore(new_div, $('latest_time').nextSibling);
|
|||
$("new_post_notifier").addEventListener('click', getLatestPosts);
|
||||
$("previous_post_loader").addEventListener('click', getPreviousPosts);
|
||||
|
||||
async function makeRepostRequest(event){
|
||||
var postId = event.target.getAttribute('data-value');
|
||||
await fetch(`/api/repost_request/${postId}`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
"X-CSRFToken": csrf_token,
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body : ""
|
||||
}).then(response => response.json())
|
||||
.then(item => item['status'])
|
||||
.then(status =>{
|
||||
if (status == "reposted"){
|
||||
event.target.classList.remove("unchecked");
|
||||
}else if (status == "deleted"){
|
||||
event.target.classList.add("unchecked");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
async function makeFavRequest(event){
|
||||
var postId = event.target.getAttribute('data-value');
|
||||
await fetch(`/api/fav_request/${postId}`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
"X-CSRFToken": csrf_token,
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body : ""
|
||||
}).then(response => response.json())
|
||||
.then(item => item['status'])
|
||||
.then(status =>{
|
||||
if (status == "faved"){
|
||||
event.target.classList.remove("unchecked");
|
||||
}else if (status == "deleted"){
|
||||
event.target.classList.add("unchecked");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function updateClickedIconEvent(){
|
||||
var reposted_items = document.getElementsByClassName('repost');
|
||||
for (var i = 0; i < reposted_items.length; i++) {
|
||||
reposted_items[i].addEventListener('click', makeRepostRequest);
|
||||
}
|
||||
var reposted_items = document.getElementsByClassName('fav');
|
||||
for (var i = 0; i < reposted_items.length; i++) {
|
||||
reposted_items[i].addEventListener('click', makeFavRequest);
|
||||
}
|
||||
}
|
||||
|
||||
updateClickedIconEvent()
|
||||
|
||||
if (requestNote["type"] == "home"){
|
||||
$("submit_post").addEventListener('click', make_req);
|
||||
adjust_post_text();
|
||||
}
|
||||
if (requestNote["type"] == "user"){
|
||||
$("follow-user-button").addEventListener('click', make_follow_req);
|
||||
if ($("follow-user-button")){
|
||||
$("follow-user-button").addEventListener('click', make_follow_req);
|
||||
}
|
||||
}
|
|
@ -6,7 +6,7 @@
|
|||
{% endblock %}
|
||||
<meta charset="utf-8">
|
||||
{% block title %}<title>Khaikang</title>
|
||||
<link type="text/css" rel="stylesheet" href="{% static 'generic.css' %}"></style>
|
||||
<link type="text/css" rel="stylesheet" href="{% static 'generic.css' %}?{% now 'U' %}"></style>
|
||||
{% endblock %}
|
||||
</head>
|
||||
<body>
|
||||
|
|
|
@ -36,14 +36,18 @@
|
|||
<div id="new_post_notifier" value=""></div>
|
||||
<div id="latest_time" style="display: block;">{{latest_received_time|date:"Y-m-d H:i:s.u"}}+0000</div>
|
||||
|
||||
{% for public_post in public_timeline_list %}
|
||||
{% for public_post in public_timeline_info %}
|
||||
|
||||
<div id="post-{{public_post.id}}" class="post"><a href="/user/{{public_post.poster}}">{{public_post.poster.shown_name}}</a>
|
||||
at <a href="/post/{{public_post.id}}" class="post-time">{{public_post.post_time|date:"Y-m-d H:i:s.u"}}+0000</a><br/>
|
||||
{{public_post.text|linebreaksbr}}<br/>
|
||||
<span id="reply-{{public_post.id}}" value="{{public_post.id}}" class="reply">↩️</span>
|
||||
- <span id="repost-{{public_post.id}}" value="{{public_post.id}}" class="repost">🔁</span>
|
||||
- <span id="fav-{{public_post.id}}" value="{{public_post.id}}" class="fav">⭐</span>
|
||||
<div id="post-{{public_post.0.id}}" class="post">
|
||||
<img class="timeline-avatar-img" src="{{public_post.0.poster.avatar.url}}">
|
||||
<div class="post-content">
|
||||
<a href="/user/{{public_post.0.poster}}">{{public_post.0.poster.shown_name}}</a>
|
||||
at <a href="/post/{{public_post.0.id}}" class="post-time">{{public_post.0.post_time|date:"Y-m-d H:i:s.u"}}+0000</a><br/>
|
||||
{{public_post.0.text|linebreaksbr}}<br/>
|
||||
<span id="reply-{{public_post.0.id}}" data-value="{{public_post.0.id}}" class="reply">↩️</span>
|
||||
- <span id="repost-{{public_post.0.id}}" data-value="{{public_post.0.id}}" class=" {%if public_post.1 == 0 %} unchecked{% endif %} repost">🔁</span>
|
||||
- <span id="fav-{{public_post.0.id}}" data-value="{{public_post.0.id}}" class=" {%if public_post.2 == 0 %} unchecked{% endif %} fav">⭐</span>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
<div id="previous_post_loader">More posts</div>
|
||||
|
@ -52,7 +56,7 @@
|
|||
</div>
|
||||
|
||||
|
||||
<script type="text/javascript" src="{% static 'timeline.js' %}">
|
||||
<script type="text/javascript" src="{% static 'timeline.js' %}?{% now 'U' %}">
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -14,6 +14,6 @@
|
|||
|
||||
</form>
|
||||
|
||||
<script type="text/javascript" src="{% static 'user_config.js'%}">
|
||||
<script type="text/javascript" src="{% static 'user_config.js'%}?{% now 'U' %}">
|
||||
</script>
|
||||
{% endblock %}
|
|
@ -27,14 +27,16 @@ Following: <span class="fo-number">{{user_following_number}}</span> Follower: <s
|
|||
<div id="new_post_notifier" value=""></div>
|
||||
<div id="latest_time" style="display: block;">{{latest_received_time|date:"Y-m-d H:i:s.u"}}+0000</div>
|
||||
|
||||
{% for post in viewed_timeline_list %}
|
||||
{% for post in viewed_timeline_info %}
|
||||
|
||||
<div id="post-{{post.id}}" class="post"><a href="/user/{{post.poster}}">{{post.poster.shown_name}}</a>
|
||||
at <a href="/post/{{post.id}}" class="post-time">{{post.post_time|date:"Y-m-d H:i:s.u"}}+0000</a><br/>
|
||||
{{post.text|linebreaksbr}}<br/>
|
||||
<span id="reply-{{post.id}}" value="{{post.id}}" class="reply">↩️</span>
|
||||
- <span id="repost-{{post.id}}" value="{{post.id}}" class="repost">🔁</span>
|
||||
- <span id="fav-{{post.id}}" value="{{post.id}}" class="fav">⭐</span>
|
||||
<div id="post-{{post.0.id}}" class="post">
|
||||
<img class="timeline-avatar-img"src="{{post.0.poster.avatar.url}}">
|
||||
<div class="post-content"><a href="/user/{{post.0.poster}}">{{post.0.poster.shown_name}}</a>
|
||||
at <a href="/post/{{post.0.id}}" class="post-time">{{post.0.post_time|date:"Y-m-d H:i:s.u"}}+0000</a><br/>
|
||||
{{post.0.text|linebreaksbr}}<br/>
|
||||
<span id="reply-{{post.0.id}}" data-value="{{post.0.id}}" class="reply">↩️</span>
|
||||
- <span id="repost-{{post.0.id}}" data-value="{{post.0.id}}" class=" {%if post.1 == 0 %} unchecked{% endif %} repost">🔁</span>
|
||||
- <span id="fav-{{post.0.id}}" data-value="{{post.0.id}}"class=" {%if post.2 == 0 %}unchecked{% endif %} fav">⭐</span></div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
<div id="previous_post_loader">More posts</div>
|
||||
|
@ -43,7 +45,7 @@ Following: <span class="fo-number">{{user_following_number}}</span> Follower: <s
|
|||
</div>
|
||||
|
||||
|
||||
<script type="text/javascript" src="{% static 'timeline.js' %}">
|
||||
<script type="text/javascript" src="{% static 'timeline.js' %}?{% now 'U' %}">
|
||||
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue