diff --git a/amadeus/static/js/mural.js b/amadeus/static/js/mural.js
index 45f1f38..3f6921f 100644
--- a/amadeus/static/js/mural.js
+++ b/amadeus/static/js/mural.js
@@ -1,56 +1,7 @@
var new_posts = [];
var new_comments = {};
-// loadOnScroll handler
-var loadOnScroll = function() {
- // If the current scroll position is past out cutoff point...
- if ($(window).scrollTop() >= $(document).height() - $(window).height() - 10) {
- // temporarily unhook the scroll event watcher so we don't call a bunch of times in a row
- $(window).unbind();
- // execute the load function below that will visit the view and return the content
- loadPosts();
- }
-};
-
-var loadPosts = function() {
- var loadUrl = $('.mural').data('url'),
- pageNum = $('.mural').data('page'),
- numberPages = $('.mural').data('pages'),
- favorites = $('.mural').data('fav'),
- mine = $('.mural').data('mine'),
- showing = new_posts.join(',');
- // Check if page is equal to the number of pages
- if (pageNum == numberPages) {
- return false
- }
- // Update the page number
- pageNum = pageNum + 1;
-
- $("#loading_posts").show();
- // Configure the url we're about to hit
- setTimeout(function (){
- $.ajax({
- url: loadUrl,
- data: {'page': pageNum, "favorite": favorites, "mine": mine, "showing": showing},
- success: function(data) {
- $("#loading_posts").hide();
-
- $(".posts").append(data);
-
- $('.mural').data('page', pageNum);
-
- setTimeout(function () { postHeightLimits() }, 10);
- },
- complete: function(data, textStatus){
- // Turn the scroll monitor back on
- $(window).bind('scroll', loadOnScroll);
- }
- });
- }, 1000)
-};
$(function () {
- $(window).bind('scroll', loadOnScroll);
-
$(".post-field").click(function () {
var url = $(this).find('h4').data('url');
@@ -66,15 +17,7 @@ $(function () {
});
});
- $("#clear_filter").click(function () {
- var frm = $(this).parent();
-
- frm.find("input[type='checkbox']").prop('checked', false);
-
- frm.submit();
- });
-
- $(".comment-section").each(function () {
+ $(".comment-section:visible").each(function () {
var height = $(this)[0].scrollHeight;
$(this).animate({scrollTop: height}, 0);
@@ -127,11 +70,11 @@ function setPostFormSubmit(post = "") {
old.remove();
} else {
- $('.posts').prepend(data.view);
+ $('.posts:visible').prepend(data.view);
new_posts.push(data.new_id);
- $('.no-subjects').attr('style', 'display:none');
+ $('.no-subjects:visible').attr('style', 'display:none');
}
setTimeout(function () { postHeightLimits() }, 100);
diff --git a/amadeus/static/js/mural_category.js b/amadeus/static/js/mural_category.js
new file mode 100644
index 0000000..8c4d513
--- /dev/null
+++ b/amadeus/static/js/mural_category.js
@@ -0,0 +1,50 @@
+$('.mural-category').on('shown.bs.collapse', function(e) {
+ if($(this).is(e.target)){
+ var li = $(".breadcrumb").find('li:last-child');
+ var li_text = $(li).html();
+ var url = $(".mural_url").val();
+ var new_li = $(li).clone();
+
+ new_li.html($(this).parent().find('.panel-title span').text());
+
+ $(li).html("" + li_text + "");
+ $(li).append("/");
+
+ new_li.appendTo('.breadcrumb');
+
+ var post_section = $(this).find('.posts'),
+ without = $(this).find('.no-subjects'),
+ loading = $(this).find('.loading-posts');
+
+ if (post_section.children().length == 0) {
+ var url = $(this).find('.mural').data('url');
+
+ $.ajax({
+ url: url,
+ dataType: 'json',
+ success: function (data) {
+ loading.hide();
+
+ if (data.count > 0) {
+ post_section.append(data.posts);
+
+ without.hide();
+ } else {
+ without.show();
+ }
+ }
+ });
+ }
+ }
+});
+
+$('.mural-category').on('hidden.bs.collapse', function(e) {
+ if($(this).is(e.target)){
+ $(".breadcrumb").find('li:last-child').remove();
+
+ var li = $(".breadcrumb").find('li:last-child');
+ var text = $(li).find('a').text();
+
+ $(li).html(text);
+ }
+});
\ No newline at end of file
diff --git a/amadeus/static/js/mural_general.js b/amadeus/static/js/mural_general.js
new file mode 100644
index 0000000..c8ddaad
--- /dev/null
+++ b/amadeus/static/js/mural_general.js
@@ -0,0 +1,59 @@
+// loadOnScroll handler
+var loadOnScroll = function() {
+ // If the current scroll position is past out cutoff point...
+ if ($(window).scrollTop() >= $(document).height() - $(window).height() - 10) {
+ // temporarily unhook the scroll event watcher so we don't call a bunch of times in a row
+ $(window).unbind();
+ // execute the load function below that will visit the view and return the content
+ loadPosts();
+ }
+};
+
+var loadPosts = function() {
+ var loadUrl = $('.mural').data('url'),
+ pageNum = $('.mural').data('page'),
+ numberPages = $('.mural').data('pages'),
+ favorites = $('.mural').data('fav'),
+ mine = $('.mural').data('mine'),
+ showing = new_posts.join(',');
+ // Check if page is equal to the number of pages
+ if (pageNum == numberPages) {
+ return false
+ }
+ // Update the page number
+ pageNum = pageNum + 1;
+
+ $("#loading_posts").show();
+ // Configure the url we're about to hit
+ setTimeout(function (){
+ $.ajax({
+ url: loadUrl,
+ data: {'page': pageNum, "favorite": favorites, "mine": mine, "showing": showing},
+ success: function(data) {
+ $("#loading_posts").hide();
+
+ $(".posts").append(data);
+
+ $('.mural').data('page', pageNum);
+
+ setTimeout(function () { postHeightLimits() }, 10);
+ },
+ complete: function(data, textStatus){
+ // Turn the scroll monitor back on
+ $(window).bind('scroll', loadOnScroll);
+ }
+ });
+ }, 1000)
+};
+
+$(function () {
+ $(window).bind('scroll', loadOnScroll);
+
+ $("#clear_filter").click(function () {
+ var frm = $(this).parent();
+
+ frm.find("input[type='checkbox']").prop('checked', false);
+
+ frm.submit();
+ });
+});
\ No newline at end of file
diff --git a/mural/forms.py b/mural/forms.py
index eebc153..624b131 100644
--- a/mural/forms.py
+++ b/mural/forms.py
@@ -3,7 +3,7 @@ from django import forms
from django.utils.translation import ugettext_lazy as _
from django.utils.html import strip_tags
-from .models import GeneralPost, Comment
+from .models import GeneralPost, CategoryPost, Comment
class Validation(forms.ModelForm):
MAX_UPLOAD_SIZE = 5*1024*1024
@@ -40,6 +40,15 @@ class GeneralPostForm(Validation):
'post': forms.Textarea
}
+class CategoryPostForm(Validation):
+ class Meta:
+ model = CategoryPost
+ fields = ['action', 'post', 'image']
+ widgets = {
+ 'action': forms.RadioSelect,
+ 'post': forms.Textarea
+ }
+
class CommentForm(forms.ModelForm):
MAX_UPLOAD_SIZE = 5*1024*1024
diff --git a/mural/models.py b/mural/models.py
index 2504800..965b405 100644
--- a/mural/models.py
+++ b/mural/models.py
@@ -51,7 +51,7 @@ class GeneralPost(Mural):
return "mural:delete_general"
class CategoryPost(Mural):
- space = models.ForeignKey(Category, verbose_name = ('Category'), related_name = 'post_category')
+ space = models.ForeignKey(Category, verbose_name = ('Category'), related_name = 'post_category', null = True)
def get_id(self):
return self.id
@@ -60,10 +60,10 @@ class CategoryPost(Mural):
return self.id
def update_link(self):
- return ""
+ return "mural:update_category"
def delete_link(self):
- return ""
+ return "mural:delete_category"
class SubjectPost(Mural):
space = models.ForeignKey(Subject, verbose_name = _('Subject'), related_name = 'post_subject')
diff --git a/mural/templates/mural/list.html b/mural/templates/mural/list.html
index 260eedd..4dc5c06 100644
--- a/mural/templates/mural/list.html
+++ b/mural/templates/mural/list.html
@@ -65,7 +65,7 @@
-
+
@@ -73,4 +73,5 @@
+
{% endblock %}
\ No newline at end of file
diff --git a/mural/templates/mural/list_category.html b/mural/templates/mural/list_category.html
index 7c0db39..186ff5d 100644
--- a/mural/templates/mural/list_category.html
+++ b/mural/templates/mural/list_category.html
@@ -12,6 +12,8 @@
{% endblock %}
{% block content %}
+
+
-
+
@@ -72,14 +74,19 @@
-
{% trans 'Wish to make a new post?' %}
+ {% trans 'Wish to make a new post?' %}
+
+
+
+
{% trans 'There are no posts in this mural yet.' %}
+
{% trans 'Filter' %}
@@ -109,5 +116,9 @@
{% endif %}
+
+
+
+
{% endblock %}
\ No newline at end of file
diff --git a/mural/urls.py b/mural/urls.py
index b3b744a..b5c15bc 100644
--- a/mural/urls.py
+++ b/mural/urls.py
@@ -5,8 +5,12 @@ urlpatterns = [
url(r'^$', views.GeneralIndex.as_view(), name='manage_general'),
url(r'^categories/$', views.CategoryIndex.as_view(), name='manage_category'),
url(r'^create_gen/$', views.GeneralCreate.as_view(), name='create_general'),
+ url(r'^create_cat/(?P
[\w_-]+)/$', views.CategoryCreate.as_view(), name='create_category'),
url(r'^update_gen/(?P[\w_-]+)/$', views.GeneralUpdate.as_view(), name='update_general'),
+ url(r'^update_cat/(?P[\w_-]+)/$', views.CategoryUpdate.as_view(), name='update_category'),
url(r'^delete_gen/(?P[\w_-]+)/$', views.GeneralDelete.as_view(), name='delete_general'),
+ url(r'^delete_cat/(?P[\w_-]+)/$', views.CategoryDelete.as_view(), name='delete_category'),
+ url(r'^load_category/([\w_-]+)/$', views.load_category_posts, name='load_category'),
url(r'^favorite/([\w_-]+)/$', views.favorite, name='favorite'),
url(r'^deleted/$', views.deleted_post, name='deleted_post'),
url(r'^comment/(?P[\w_-]+)/$', views.CommentCreate.as_view(), name='create_comment'),
@@ -14,7 +18,7 @@ urlpatterns = [
url(r'^delete_comment/(?P[\w_-]+)/$', views.CommentDelete.as_view(), name='delete_comment'),
url(r'^deleted_comment/$', views.deleted_comment, name='deleted_comment'),
url(r'^render_comment/([\w_-]+)/([\w_-]+)/$', views.render_comment, name='render_comment'),
- url(r'^render_post/([\w_-]+)/([\w_-]+)/$', views.render_gen_post, name='render_post_general'),
+ url(r'^render_post/([\w_-]+)/([\w_-]+)/([\w_-]+)/$', views.render_post, name='render_post'),
url(r'^load_comments/([\w_-]+)/([\w_-]+)/$', views.load_comments, name='load_comments'),
url(r'^suggest_users/$', views.suggest_users, name='suggest_users'),
]
\ No newline at end of file
diff --git a/mural/views.py b/mural/views.py
index 5995b6f..5bc7a0c 100644
--- a/mural/views.py
+++ b/mural/views.py
@@ -19,7 +19,7 @@ from subjects.models import Subject
from users.models import User
from .models import Mural, GeneralPost, CategoryPost, SubjectPost, MuralVisualizations, MuralFavorites, Comment
-from .forms import GeneralPostForm, CommentForm
+from .forms import GeneralPostForm, CategoryPostForm, CommentForm
"""
Section for GeneralPost classes
@@ -140,7 +140,7 @@ class GeneralCreate(LoginRequiredMixin, generic.edit.CreateView):
return context
def get_success_url(self):
- return reverse_lazy('mural:render_post_general', args = (self.object.id, 'create', ))
+ return reverse_lazy('mural:render_post', args = (self.object.id, 'create', 'gen', ))
class GeneralUpdate(LoginRequiredMixin, generic.UpdateView):
login_url = reverse_lazy("users:login")
@@ -182,7 +182,7 @@ class GeneralUpdate(LoginRequiredMixin, generic.UpdateView):
return context
def get_success_url(self):
- return reverse_lazy('mural:render_post_general', args = (self.object.id, 'update', ))
+ return reverse_lazy('mural:render_post', args = (self.object.id, 'update', 'gen', ))
class GeneralDelete(LoginRequiredMixin, generic.DeleteView):
login_url = reverse_lazy("users:login")
@@ -213,6 +213,33 @@ class GeneralDelete(LoginRequiredMixin, generic.DeleteView):
"""
Section for CategoryPost classes
"""
+def load_category_posts(request, category):
+ context = {
+ 'request': request,
+ }
+
+ showing = request.GET.get('showing', '')
+
+ posts = CategoryPost.objects.extra(select = {"most_recent": "greatest(last_update, (select max(mural_comment.last_update) from mural_comment where mural_comment.post_id = mural_categorypost.mural_ptr_id))"}).filter(space__id = category).order_by("-most_recent")
+
+ paginator = Paginator(posts, 10)
+
+ try:
+ page_number = int(request.GET.get('page', 1))
+ except ValueError:
+ raise Http404
+
+ try:
+ page_obj = paginator.page(page_number)
+ except EmptyPage:
+ raise Http404
+
+ context['posts'] = page_obj.object_list
+
+ response = render_to_string("mural/_list_view.html", context, request)
+
+ return JsonResponse({"posts": response, "count": posts.count(), "num_pages": paginator.num_pages, "num_page": page_obj.number})
+
class CategoryIndex(LoginRequiredMixin, generic.ListView):
login_url = reverse_lazy("users:login")
redirect_field_name = 'next'
@@ -235,8 +262,6 @@ class CategoryIndex(LoginRequiredMixin, generic.ListView):
self.totals['category'] = MuralVisualizations.objects.filter(Q(user = user) & Q(viewed = False) & (Q(post__categorypost__space__coordinators = user) | Q(comment__post__categorypost__space__coordinators = user) | Q(post__categorypost__space__subject_category__professor = user) | Q(post__categorypost__space__subject_category__students = user) | Q(comment__post__categorypost__space__subject_category__professor = user) | Q(comment__post__categorypost__space__subject_category__students = user))).distinct().count()
self.totals['subject'] = MuralVisualizations.objects.filter(Q(user = user) & Q(viewed = False) & (Q(post__subjectpost__space__professor = user) | Q(comment__post__subjectpost__space__professor = user) | Q(post__subjectpost__space__students = user) | Q(comment__post__subjectpost__space__students = user))).distinct().count()
- print(categories)
-
return categories
def get_context_data(self, **kwargs):
@@ -248,22 +273,144 @@ class CategoryIndex(LoginRequiredMixin, generic.ListView):
return context
-def render_gen_post(request, post, msg):
- post = get_object_or_404(GeneralPost, id = post)
+class CategoryCreate(LoginRequiredMixin, generic.edit.CreateView):
+ login_url = reverse_lazy("users:login")
+ redirect_field_name = 'next'
+
+ template_name = 'mural/_form.html'
+ form_class = CategoryPostForm
+
+ def form_invalid(self, form):
+ context = super(CategoryCreate, self).form_invalid(form)
+ context.status_code = 400
+
+ return context
+
+ def form_valid(self, form):
+ self.object = form.save(commit = False)
+
+ slug = self.kwargs.get('slug', None)
+ cat = get_object_or_404(Category, slug = slug)
+
+ self.object.space = cat
+ self.object.user = self.request.user
+
+ self.object.save()
+
+ users = User.objects.all().exclude(id = self.request.user.id)
+ entries = []
+
+ notify_type = "mural"
+ user_icon = self.object.user.image_url
+ #_view = render_to_string("mural/_view.html", {"post": self.object}, self.request)
+ simple_notify = _("%s has made a post in General")%(str(self.object.user))
+ pathname = reverse("mural:manage_general")
+
+ #for user in users:
+ # entries.append(MuralVisualizations(viewed = False, user = user, post = self.object))
+ # Group("user-%s" % user.id).send({'text': json.dumps({"type": notify_type, "subtype": "create", "user_icon": user_icon, "pathname": pathname, "simple": simple_notify, "complete": _view})})
+
+ #MuralVisualizations.objects.bulk_create(entries)
+
+ return super(CategoryCreate, self).form_valid(form)
+
+ def get_context_data(self, *args, **kwargs):
+ context = super(CategoryCreate, self).get_context_data(*args, **kwargs)
+
+ context['form_url'] = reverse_lazy("mural:create_category", args = (), kwargs = {'slug': self.kwargs.get('slug', None)})
+
+ return context
+
+ def get_success_url(self):
+ return reverse_lazy('mural:render_post', args = (self.object.id, 'create', 'cat', ))
+
+class CategoryUpdate(LoginRequiredMixin, generic.UpdateView):
+ login_url = reverse_lazy("users:login")
+ redirect_field_name = 'next'
+
+ template_name = 'mural/_form.html'
+ model = CategoryPost
+ form_class = CategoryPostForm
+
+ def form_invalid(self, form):
+ context = super(CategoryUpdate, self).form_invalid(form)
+ context.status_code = 400
+
+ return context
+
+ def form_valid(self, form):
+ self.object = form.save(commit = False)
+
+ self.object.edited = True
+
+ self.object.save()
+
+ users = User.objects.all().exclude(id = self.request.user.id)
+
+ notify_type = "mural"
+ #_view = render_to_string("mural/_view.html", {"post": self.object}, self.request)
+ pathname = reverse("mural:manage_general")
+
+ #for user in users:
+ # Group("user-%s" % user.id).send({'text': json.dumps({"type": notify_type, "subtype": "update", "pathname": pathname, "complete": _view, "post_id": self.object.id})})
+
+ return super(CategoryUpdate, self).form_valid(form)
+
+ def get_context_data(self, *args, **kwargs):
+ context = super(CategoryUpdate, self).get_context_data(*args, **kwargs)
+
+ context['form_url'] = reverse_lazy("mural:update_category", args = (), kwargs = {'pk': self.object.id})
+
+ return context
+
+ def get_success_url(self):
+ return reverse_lazy('mural:render_post', args = (self.object.id, 'update', 'cat', ))
+
+class CategoryDelete(LoginRequiredMixin, generic.DeleteView):
+ login_url = reverse_lazy("users:login")
+ redirect_field_name = 'next'
+
+ template_name = 'mural/delete.html'
+ model = CategoryPost
+
+ def get_context_data(self, *args, **kwargs):
+ context = super(CategoryDelete, self).get_context_data(*args, **kwargs)
+
+ context['form_url'] = reverse_lazy("mural:delete_category", args = (), kwargs = {'pk': self.object.id})
+ context['message'] = _('Are you sure you want to delete this post?')
+
+ return context
+
+ def get_success_url(self):
+ users = User.objects.all().exclude(id = self.request.user.id)
+
+ notify_type = "mural"
+ pathname = reverse("mural:manage_general")
+
+ #for user in users:
+ # Group("user-%s" % user.id).send({'text': json.dumps({"type": notify_type, "subtype": "delete", "pathname": pathname, "post_id": self.object.id})})
+
+ return reverse_lazy('mural:deleted_post')
+
+def render_post(request, post, msg, ptype):
+ if ptype == 'gen':
+ post = get_object_or_404(GeneralPost, id = post)
+ elif ptype == 'cat':
+ post = get_object_or_404(CategoryPost, id = post)
context = {}
context['post'] = post
- msg = ""
+ message = ""
if msg == 'create':
- msg = _('Your post was published successfully!')
+ message = _('Your post was published successfully!')
else:
- msg = _('Your post was edited successfully!')
+ message = _('Your post was edited successfully!')
html = render_to_string("mural/_view.html", context, request)
- return JsonResponse({'message': msg, 'view': html, 'new_id': post.id})
+ return JsonResponse({'message': message, 'view': html, 'new_id': post.id})
def deleted_post(request):
return JsonResponse({'msg': _('Post deleted successfully!')})
@@ -282,6 +429,9 @@ def favorite(request, post):
return JsonResponse({'label': _('Favorite')})
+"""
+ Section for comment functions
+"""
class CommentCreate(LoginRequiredMixin, generic.edit.CreateView):
login_url = reverse_lazy("users:login")
redirect_field_name = 'next'
--
libgit2 0.21.2