diff options
Diffstat (limited to 'hyperkitty')
-rw-r--r-- | hyperkitty/static/css/hyperkitty-message.css | 27 | ||||
-rw-r--r-- | hyperkitty/static/js/hyperkitty-thread.js | 34 | ||||
-rw-r--r-- | hyperkitty/templates/thread.html | 1 | ||||
-rw-r--r-- | hyperkitty/templates/threads/category.html | 14 | ||||
-rw-r--r-- | hyperkitty/templates/threads/right_col.html | 3 | ||||
-rw-r--r-- | hyperkitty/urls.py | 2 | ||||
-rw-r--r-- | hyperkitty/views/forms.py | 3 | ||||
-rw-r--r-- | hyperkitty/views/thread.py | 46 |
8 files changed, 128 insertions, 2 deletions
diff --git a/hyperkitty/static/css/hyperkitty-message.css b/hyperkitty/static/css/hyperkitty-message.css index 2dfb9df..f7af9b2 100644 --- a/hyperkitty/static/css/hyperkitty-message.css +++ b/hyperkitty/static/css/hyperkitty-message.css @@ -148,6 +148,33 @@ } +/* Categories */ + +#thread-overview-info #thread-category { + padding: 10px 0; + text-align: center; +} +#thread-overview-info #thread-category form { + margin: 0; + display: none; +} +#thread-overview-info #thread-category form select { + font-size: 90%; + width: 12em; +} +#thread-overview-info #thread-category a.label { + font-size: 120%; + line-height: 120%; +} + +#thread-category .question { + background-color: #f89406; +} +#thread-category .announce { + background-color: #3a87ad; +} + + /* Participants */ #participants { diff --git a/hyperkitty/static/js/hyperkitty-thread.js b/hyperkitty/static/js/hyperkitty-thread.js index 5b7765d..f2c3cd0 100644 --- a/hyperkitty/static/js/hyperkitty-thread.js +++ b/hyperkitty/static/js/hyperkitty-thread.js @@ -21,6 +21,39 @@ /* + * Categories + */ + +function setup_category() { + $("#thread-category form").submit(function (e) { + e.preventDefault(); + $.ajax({ + type: "POST", + //dataType: "json", + data : $(this).serialize(), + url: $(this).attr("action"), + success: function(data) { + $("#thread-category").html(data); + setup_category(); + }, + error: function(jqXHR, textStatus, errorThrown) { + // authentication and invalid data + alert(jqXHR.responseText); + } + }); + }); + $("#thread-category a.label").click(function(e) { + e.preventDefault(); + $(this).hide(); + $("#thread-category form").show(); + }); + $("#thread-category form select").change(function() { + $(this).parents("form").first().submit(); + }); +} + + +/* * Tagging */ @@ -39,7 +72,6 @@ function setup_tags() { e.preventDefault(); $(this).parents("form").first().submit(); }); - console.log($(this)); $(this).find("#id_tag").value(""); }, error: function(jqXHR, textStatus, errorThrown) { diff --git a/hyperkitty/templates/thread.html b/hyperkitty/templates/thread.html index 491d08a..ee102fa 100644 --- a/hyperkitty/templates/thread.html +++ b/hyperkitty/templates/thread.html @@ -77,6 +77,7 @@ <script type="text/javascript"> $(document).ready(function() { + setup_category(); setup_tags(); setup_favorites(); setup_emails_list(); diff --git a/hyperkitty/templates/threads/category.html b/hyperkitty/templates/threads/category.html new file mode 100644 index 0000000..e830678 --- /dev/null +++ b/hyperkitty/templates/threads/category.html @@ -0,0 +1,14 @@ +{% load url from future %} + + <a class="label {{category}}"> + {% if category %} + {{ category|title }} + {% else %} + No category + {% endif %} + </a> + <form method="post" action="{% url 'thread_set_category' mlist_fqdn=mlist.name threadid=threadid %}"> + {% csrf_token %} + {{ category_form.as_p }} + </form> + diff --git a/hyperkitty/templates/threads/right_col.html b/hyperkitty/templates/threads/right_col.html index 5384d03..c92eabd 100644 --- a/hyperkitty/templates/threads/right_col.html +++ b/hyperkitty/templates/threads/right_col.html @@ -38,6 +38,9 @@ <i class="unread icon-eye-close"></i> {{ unread_count }} unread messages {% endif %} </p> + <div id="thread-category"> + {% include 'threads/category.html' %} + </div> <div id="tags"> {% include 'threads/tags.html' %} </div> diff --git a/hyperkitty/urls.py b/hyperkitty/urls.py index 015737b..44a6fdb 100644 --- a/hyperkitty/urls.py +++ b/hyperkitty/urls.py @@ -84,6 +84,8 @@ urlpatterns = patterns('hyperkitty.views', 'thread.suggest_tags', name='suggest_tags'), url(r'^list/(?P<mlist_fqdn>[^/@]+@[^/@]+)/thread/(?P<threadid>\w+)/favorite$', 'thread.favorite', name='favorite'), + url(r'^list/(?P<mlist_fqdn>[^/@]+@[^/@]+)/thread/(?P<threadid>\w+)/category$', + 'thread.set_category', name='thread_set_category'), # Search diff --git a/hyperkitty/views/forms.py b/hyperkitty/views/forms.py index 99f158f..19bba26 100644 --- a/hyperkitty/views/forms.py +++ b/hyperkitty/views/forms.py @@ -135,3 +135,6 @@ class PostForm(forms.Form): message = forms.CharField(widget=forms.Textarea) attachment = forms.FileField(required=False, label="", widget=AttachmentFileInput) + +class CategoryForm(forms.Form): + category = forms.ChoiceField(label="", required=False) diff --git a/hyperkitty/views/thread.py b/hyperkitty/views/thread.py index 56f9f5c..8b080ba 100644 --- a/hyperkitty/views/thread.py +++ b/hyperkitty/views/thread.py @@ -34,7 +34,7 @@ from django.utils.timezone import utc import robot_detection from hyperkitty.models import Tag, Favorite, LastView -from forms import AddTagForm, ReplyForm +from hyperkitty.views.forms import AddTagForm, ReplyForm, CategoryForm from hyperkitty.lib import get_months, get_store, stripped_subject from hyperkitty.lib.voting import set_message_votes @@ -99,6 +99,12 @@ def thread_index(request, mlist_fqdn, threadid, month=None, year=None): else: fav_action = "rm" + # Category + categories = [ (c, c.title()) for c in store.get_categories() ] \ + + [("", "no categories")] + category_form = CategoryForm(initial={"category": thread.category or ""}) + category_form["category"].field.choices = categories + # Extract relative dates today = datetime.date.today() days_old = today - thread.starting_email.date.date() @@ -151,6 +157,8 @@ def thread_index(request, mlist_fqdn, threadid, month=None, year=None): 'participants': thread.participants, 'last_view': last_view, 'unread_count': unread_count, + 'category_form': category_form, + 'category': thread.category, } context["participants"].sort(key=lambda x: x[0].lower()) @@ -286,3 +294,39 @@ def favorite(request, mlist_fqdn, threadid): raise SuspiciousOperation return HttpResponse("success", mimetype='text/plain') + +def set_category(request, mlist_fqdn, threadid): + """ Set the category for a given thread. """ + if not request.user.is_authenticated(): + return HttpResponse('You must be logged in to add a tag', + content_type="text/plain", status=403) + if request.method != 'POST': + raise SuspiciousOperation + + store = get_store(request) + categories = [ (c, c.title()) for c in store.get_categories() ] \ + + [("", "No categories")] + category_form = CategoryForm(request.POST) + category_form["category"].field.choices = categories + + if not category_form.is_valid(): + return HttpResponse("Error settings category: invalid data", + content_type="text/plain", status=500) + + category = category_form.cleaned_data["category"] + thread = store.get_thread(mlist_fqdn, threadid) + if category and category not in store.get_categories(): + raise Http404("No such category: %s" % category) + if category != thread.category: + thread.category = category + store.commit() + + # Now refresh the category widget + FakeMList = namedtuple("MailingList", ["name"]) + context = { + "category_form": category_form, + "mlist": FakeMList(name=mlist_fqdn), + "threadid": threadid, + "category": thread.category, + } + return render(request, "threads/category.html", context) |