Skip to content

Commit

Permalink
feat: enable editing townsquare comments
Browse files Browse the repository at this point in the history
Comments can be edited. Editing can be cancled via Cancel button or
ESC.

This is part of the townsquare improvements:
#6003

fixes #6010
  • Loading branch information
walidmujahid committed Apr 8, 2020
1 parent f1d43c2 commit 54844c8
Show file tree
Hide file tree
Showing 4 changed files with 218 additions and 41 deletions.
214 changes: 174 additions & 40 deletions app/assets/v2/js/activity.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,9 @@ $(document).ready(function() {
const $target = $(this).parents('.activity_detail_content');
const html = `
<p class='float-right p-0 m-0 video_options_container'>
<a href=# class='full_screen'>Full Screen <i class="fas fa-expand-arrows-alt"></i></a> |
<a href=# class='popout_screen'>Pop Out <i class="fas fa-sign-out-alt"></i></a> |
<a href=# class='new_tab'>Open in New Tab <i class="fas fa-external-link-square-alt"></i></i></a> |
<a href=# class='full_screen'>Full Screen <i class="fas fa-expand-arrows-alt"></i></a> |
<a href=# class='popout_screen'>Pop Out <i class="fas fa-sign-out-alt"></i></a> |
<a href=# class='new_tab'>Open in New Tab <i class="fas fa-external-link-square-alt"></i></i></a> |
<a href=# class=' leave_video_call'>Leave Video Call <i class="far fa-times-circle"></i></a>
</p>`;

Expand Down Expand Up @@ -535,45 +535,91 @@ $(document).ready(function() {
return;
}

// user input
var comment = $parent.parents('.box').find('.comment_container textarea').val().trim();
if ($('.editableComment')[0]) {
// edited content
const comment = $parent.parents('.box').find('.editableComment').val();

// validation
if (!comment) {
return;
}
$('.editableComment').prop('disabled', true);

$parent.parents('.box').find('.comment_container textarea').prop('disabled', true);
$('.post_comment').prop('disabled', true);
// validation
if (!comment) {
$('.editableComment').prop('disabled', false);
return;
}

$parent.parents('.activity.box').find('.loading').removeClass('hidden');
var has_hidden_comments = $parent.parents('.activity.box').find('.row.comment_row.hidden').length;
// increment number
var num = $parent.find('span.num').html();
$parent.parents('.activity.box').find('.loading').removeClass('hidden');

num = parseInt(num) + 1;
$parent.find('span.num').html(num);
const has_hidden_comments = $parent.parents('.activity.box').find('.row.comment_row.hidden').length;
const num = $parent.find('span.num').html();
const comment_id = $('.editableComment').parent().closest('.comment_row').data('id');
const url = '/api/v0.1/comment/' + comment_id;
const params = {
'method': 'EDIT',
'comment': comment,
'csrfmiddlewaretoken': $('input[name=csrfmiddlewaretoken]').val()
};

// remote post
var params = {
'method': 'comment',
'comment': comment,
'csrfmiddlewaretoken': $('input[name=csrfmiddlewaretoken]').val()
};
var url = '/api/v0.1/activity/' + $parent.data('pk');
$.post(url, params, function(response) {
const success_callback = function($parent) {
$.noop(); // do nothing
};

$.post(url, params, function(response) {
var success_callback = function($parent) {
$parent.parents('.box').find('.comment_container textarea').val('');
$parent.find('textarea').focus();
view_comments($parent, allow_close_comment_container, success_callback);
}).always(function() {
$parent.parents('.activity.box').find('.loading').addClass('hidden');
$parent.parents('.box').find('.comment_container textarea').prop('disabled', false);
$('.editableComment').prop('disabled', false);
$(`.comment_row[data-id="${comment_id}"] .comment_options`).prop('disabled', false).removeClass('hidden');
$(`.comment_row[data-id="${comment_id}"]`).parent().closest('.box')
.find('#container-post_comment')
.find('*').prop('disabled', false).removeClass('hidden');
// TODO: automatically cancel editing when another edit_comment button is clicked
$('.edit_comment').prop('disabled', false);
});
} else {
// user input
const comment = $parent.parents('.box').find('.comment_container textarea').val().trim();

$parent.parents('.box').find('.comment_container textarea').prop('disabled', true);
$('.post_comment').prop('disabled', true);

// validation
if (!comment) {
$parent.parents('.box').find('.comment_container textarea').prop('disabled', false);
$('.post_comment').prop('disabled', false);
return;
}


$parent.parents('.activity.box').find('.loading').removeClass('hidden');
const has_hidden_comments = $parent.parents('.activity.box').find('.row.comment_row.hidden').length;

// increment number
let num = $parent.find('span.num').html();

num = parseInt(num) + 1;
$parent.find('span.num').html(num);

// remote post
const params = {
'method': 'comment',
'comment': comment,
'csrfmiddlewaretoken': $('input[name=csrfmiddlewaretoken]').val()
};
var override_hide_comments = !has_hidden_comments;
const url = '/api/v0.1/activity/' + $parent.data('pk');

$.post(url, params, function(response) {
const success_callback = function($parent) {
$parent.parents('.box').find('.comment_container textarea').val('');
$parent.find('textarea').focus();

view_comments($parent, allow_close_comment_container, success_callback, override_hide_comments);
}).done(function() {
// pass
})
};
const override_hide_comments = !has_hidden_comments;

view_comments($parent, allow_close_comment_container, success_callback, override_hide_comments);
}).done(function() {
// pass
})
.fail(function() {
$parent.parents('.activity.box').find('.error').removeClass('hidden');
})
Expand All @@ -582,6 +628,7 @@ $(document).ready(function() {
$parent.parents('.box').find('.comment_container textarea').prop('disabled', false);
$('.post_comment').prop('disabled', false);
});
}
};

// converts an object to a dict
Expand Down Expand Up @@ -637,6 +684,7 @@ $(document).ready(function() {
const timeAgo = timedifferenceCvrt(new Date(comment['created_on']));
const show_tip = true;
const is_comment_owner = document.contxt.github_handle == comment['profile_handle'];
const is_edited = typeof comment['is_edited'] !== 'undefined' ? comment['is_edited'] : false;
var sorted_match_curve_html = '';

if (comment['sorted_match_curve']) {
Expand All @@ -646,6 +694,7 @@ $(document).ready(function() {
for (let j = 0; j < match_curve.length; j++) {
let ele = match_curve[j];


sorted_match_curve_html += '<li>';
sorted_match_curve_html += `Your contribution of ${ele.name} could yield $${Math.round(ele.value * 1000) / 1000} in matching.`;
sorted_match_curve_html += '</li>';
Expand Down Expand Up @@ -680,7 +729,7 @@ $(document).ready(function() {
<span class="indicator" data-toggle="tooltip" title="Gitcoin Chat: ${comment['last_chat_status_title']}">
</span>
</span>
</span>
<b>${comment['name']}</b>
<span class="grey"><a class=grey href="/profile/${comment['profile_handle']}">
@${comment['profile_handle']}
Expand All @@ -707,11 +756,14 @@ $(document).ready(function() {
</span>
<span class='float-right'>
<span class="d-none d-sm-inline grey font-smaller-5 text-right">
${timeAgo}
${timeAgo} ${is_edited ? '(edited)' : ''}
</span>
<span class="font-smaller-5 mt-1" style="display: block; text-align: right;">
<span class="comment_options font-smaller-5 mt-1" style="display: block; text-align: right;">
${is_comment_owner ?
`<i data-pk=${comment['id']} class="delete_comment fas fa-trash font-smaller-7 position-relative text-black-70 mr-1 cursor-pointer" style="top:-1px; "></i>| `
: ''}
${is_comment_owner ?
`<i data-pk=${comment['id']} class="edit_comment fas fa-edit font-smaller-7 position-relative text-black-70 mr-1 cursor-pointer" style="top:-1px; "></i>| `
: ''}
${show_tip ? `
<span class="action like px-0 ${comment['is_liked'] ? 'open' : ''}" data-toggle="tooltip" title="Liked by ${comment['likes']}">
Expand All @@ -735,7 +787,7 @@ $(document).ready(function() {
}

const post_comment_html = `
<div class="row py-2 mx-auto">
<div id="container-post_comment" class="row py-2 mx-auto">
<div class="col-sm-1 mt-1 activity-avatar d-none d-sm-inline">
<img src="/dynamic/avatar/${document.contxt.github_handle}">
</div>
Expand Down Expand Up @@ -836,6 +888,59 @@ $(document).ready(function() {
post_comment($target, false);
});


// cancel editing comment
$(document).on('click', '.cancel_edit', function(e) {
e.preventDefault();
const comment_id = $(this).data('id');
const editableContainer = $('#editableContainer');

const url = '/api/v0.1/comment/' + comment_id;
const params = {
'method': 'GET_COMMENT'
};

$.get(url, params, function(response) {
let the_comment = response['comment'];

the_comment = urlify(the_comment);
the_comment = linkify(the_comment);
the_comment = the_comment.replace(/\r\n|\r|\n/g, '<br />');

editableContainer.replaceWith(`<div class="activity_comments_main_comment">${the_comment}</div>`);

}).always(function() {
$(`.comment_row[data-id="${comment_id}"] .comment_options`).prop('disabled', false).removeClass('hidden');
$(`.comment_row[data-id="${comment_id}"]`).parent().closest('.box')
.find('#container-post_comment')
.find('*').prop('disabled', false).removeClass('hidden');
// TODO: automatically cancel editing when another edit_comment button is clicked
$('.edit_comment').prop('disabled', false);
});
});


$(document).on('click', '.edit_comment', function(e) {
e.preventDefault();
let comment_id = $(this).data('pk');
let commentContainer = $(`.comment_row[data-id="${comment_id}"] .activity_comments_main_comment`);
let content = commentContainer.html().replace(/<br>/g, '\n').trim();
let editableContainer = $(`<div id="editableContainer" class="col-12 col-sm-12 text-right"><textarea class="form-control bg-lightblue font-caption editableComment" cols="80" rows="3" data-id="${comment_id}">${content}</textarea><a href=# class="btn btn-gc-blue btn-sm mt-2 font-smaller-7 font-weight-bold cancel_edit" data-id="${comment_id}">CANCEL</a></div>`);

$(`.comment_row[data-id="${comment_id}"] .comment_options`).prop('disabled', true).addClass('hidden');
$(`.comment_row[data-id="${comment_id}"]`).parent().closest('.box')
.find('#container-post_comment')
.find('*').prop('disabled', true).addClass('hidden');

commentContainer.replaceWith(editableContainer);

$(`#editableContainer textarea[data-id="${comment_id}`).focus();

// TODO: automatically cancel editing when another edit_comment button is clicked
$('.edit_comment').prop('disabled', true);
});


$(document).on('click', '.delete_comment', function(e) {
e.preventDefault();
const comment_id = $(this).data('pk');
Expand Down Expand Up @@ -865,12 +970,42 @@ $(document).ready(function() {
});


$(document).on('keypress', '.enter-activity-comment', function(e) {
$(document).on('keyup keydown keypress', '.enter-activity-comment, .editableComment', function(e) {
if (e.which == 13 && !e.shiftKey) {
const $target = $(this).parents('.activity.box').find('.comment_activity');

post_comment($target, false);
}

if (e.key === 'Escape' && typeof $('.editableComment')[0] != 'undefined') {
const comment_id = $(this).data('id');
const editableContainer = $('#editableContainer');

const url = '/api/v0.1/comment/' + comment_id;
const params = {
'method': 'GET_COMMENT'
};

$.get(url, params, function(response) {
let the_comment = response['comment'];

the_comment = urlify(the_comment);
the_comment = linkify(the_comment);
the_comment = the_comment.replace(/\r\n|\r|\n/g, '<br />');

editableContainer.replaceWith(`<div class="activity_comments_main_comment">${the_comment}</div>`);

}).always(function() {
$(`.comment_row[data-id="${comment_id}"] .comment_options`)
.prop('disabled', false)
.removeClass('hidden');
$(`.comment_row[data-id="${comment_id}"]`).parent().closest('.box')
.find('#container-post_comment')
.find('*').prop('disabled', false).removeClass('hidden');
// TODO: automatically cancel editing when another edit_comment button is clicked
$('.edit_comment').prop('disabled', false);
});
}
});

// post comment activity
Expand Down Expand Up @@ -950,7 +1085,7 @@ function throttle(fn, wait) {
}
};
}


window.addEventListener('scroll', throttle(function() {
var offset = 800;
Expand All @@ -959,4 +1094,3 @@ window.addEventListener('scroll', throttle(function() {
$('.infinite-more-link').click();
}
}, 500));

18 changes: 18 additions & 0 deletions app/townsquare/migrations/0017_comment_is_edited.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Generated by Django 2.2.4 on 2020-04-06 15:47

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('townsquare', '0016_favorite'),
]

operations = [
migrations.AddField(
model_name='comment',
name='is_edited',
field=models.BooleanField(default=False),
),
]
3 changes: 2 additions & 1 deletion app/townsquare/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ class Comment(SuperModel):
likes = ArrayField(models.IntegerField(), default=list, blank=True) #pks of users who like this post
likes_handles = ArrayField(models.CharField(max_length=200, blank=True), default=list, blank=True) #handles of users who like this post
tip_count_eth = models.DecimalField(default=0, decimal_places=5, max_digits=50)
is_edited = models.BooleanField(default=False)

def __str__(self):
return f"Comment of {self.activity.pk} by {self.profile.handle}: {self.comment}"
Expand Down Expand Up @@ -375,4 +376,4 @@ class Favorite(SuperModel):
created = models.DateTimeField(auto_now=True)

def __str__(self):
return f"Favorite {self.activity.activity_type}:{self.activity_id} by {self.user}"
return f"Favorite {self.activity.activity_type}:{self.activity_id} by {self.user}"
24 changes: 24 additions & 0 deletions app/townsquare/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -466,6 +466,8 @@ def api(request, activity_id):
counter += 1; results[counter] += time.time() - start_time; start_time = time.time()
comment_dict['sorted_match_curve'] = comment.profile.matchranking_this_round.sorted_match_curve if comment.profile.matchranking_this_round else None
counter += 1; results[counter] += time.time() - start_time; start_time = time.time()
if comment.is_edited:
comment_dict['is_edited'] = comment.is_edited
response['comments'].append(comment_dict)
for key, val in results.items():
if settings.DEBUG:
Expand Down Expand Up @@ -595,6 +597,28 @@ def comment_v1(request, comment_id):
}
return JsonResponse(response)

if method == 'EDIT':
content = request.POST.get('comment')
title = request.POST.get('comment')

comment.comment = content
comment.is_edited = True
comment.save()
response = {
'status': 203,
'message': 'comment successfully updated'
}
return JsonResponse(response)

# no perms needed responses go here
if request.GET.get('method') == 'GET_COMMENT':
response = {
'status': 202,
'message': 'comment successfully retrieved',
'comment': comment.comment,
}
return JsonResponse(response)

return JsonResponse(response)


Expand Down

0 comments on commit 54844c8

Please sign in to comment.