# HG changeset patch # User neko259 # Date 2017-12-05 20:22:03 # Node ID 8255ca3c877bed857c279e408f4fad91e7581773 # Parent be673d04e8e2b46c769a5a361a30b14518c2e073 AJAX-based thread creation diff --git a/boards/static/js/form.js b/boards/static/js/form.js --- a/boards/static/js/form.js +++ b/boards/static/js/form.js @@ -2,6 +2,8 @@ var ITEM_FILE_SOURCE = 'fileSource'; var URL_STICKERS = '/api/stickers'; var MIN_INPUT_LENGTH = 3; var URL_DELIMITER = '\n'; +// TODO This needs to be the same for attachment download time limit. +var POST_AJAX_TIMEOUT = 30000; var pastedImages = []; @@ -128,6 +130,74 @@ function addOnImagePaste() { }); } +/** + * When the form is posted, this method will be run as a callback + */ +function updateOnPost(response, statusText, xhr, form) { + var json = $.parseJSON(response); + var status = json.status; + var url = json.url; + + showAsErrors(form, ''); + $('.post-form-w').unblock(); + + if (status === 'ok') { + if (url) { + document.location = url; + } else { + resetForm(); + getThreadDiff(); + scrollToBottom(); + } + } else { + var errors = json.errors; + for (var i = 0; i < errors.length; i++) { + var fieldErrors = errors[i]; + + var error = fieldErrors.errors; + + showAsErrors(form, error); + } + } +} + +function initAjaxForm(openingPostId) { + var form = $('#form'); + + var url = '/api/add_post/'; + if (openingPostId) { + url += openingPostId + '/'; + } + + if (form.length > 0) { + var options = { + beforeSubmit: function(arr, form, options) { + $('.post-form-w').block({ message: gettext('Sending message...') }); + + $.each(pastedImages, function(i, blob) { + arr.push({ + name: "file_0", + value: blob + }); + }); + }, + success: updateOnPost, + error: function(xhr, textStatus, errorString) { + var errorText = gettext('Server error: ') + textStatus; + if (errorString) { + errorText += ' / ' + errorString; + } + showAsErrors(form, errorText); + $('.post-form-w').unblock(); + }, + url: url, + timeout: POST_AJAX_TIMEOUT + }; + + form.ajaxForm(options); + } +} + $(document).ready(function() { var powDifficulty = parseInt($('body').attr('data-pow-difficulty')); if (powDifficulty > 0 && typeof SharedWorker != 'undefined') { diff --git a/boards/static/js/thread_create.js b/boards/static/js/thread_create.js --- a/boards/static/js/thread_create.js +++ b/boards/static/js/thread_create.js @@ -40,4 +40,6 @@ function extractLast( term ) { return false; } }); + + initAjaxForm(null); }); \ No newline at end of file diff --git a/boards/static/js/thread_update.js b/boards/static/js/thread_update.js --- a/boards/static/js/thread_update.js +++ b/boards/static/js/thread_update.js @@ -30,8 +30,6 @@ var POST_UPDATED = 1; // TODO These need to be syncronized with board settings. var JS_AUTOUPDATE_PERIOD = 20000; -// TODO This needs to be the same for attachment download time limit. -var POST_AJAX_TIMEOUT = 30000; var BLINK_SPEED = 500; var ALLOWED_FOR_PARTIAL_UPDATE = [ @@ -264,34 +262,6 @@ function showNewPostsTitle(newPostCount) } } - -/** - * When the form is posted, this method will be run as a callback - */ -function updateOnPost(response, statusText, xhr, form) { - var json = $.parseJSON(response); - var status = json.status; - - showAsErrors(form, ''); - $('.post-form-w').unblock(); - - if (status === 'ok') { - resetForm(); - getThreadDiff(); - scrollToBottom(); - } else { - var errors = json.errors; - for (var i = 0; i < errors.length; i++) { - var fieldErrors = errors[i]; - - var error = fieldErrors.errors; - - showAsErrors(form, error); - } - } -} - - /** * Run js methods that are usually run on the document, on the new post */ @@ -362,33 +332,8 @@ function updateNodeAttr(oldNode, newNode var form = $('#form'); + initAjaxForm(threadId); if (form.length > 0) { - var options = { - beforeSubmit: function(arr, form, options) { - $('.post-form-w').block({ message: gettext('Sending message...') }); - - $.each(pastedImages, function(i, blob) { - arr.push({ - name: "file_0", - value: blob - }); - }); - }, - success: updateOnPost, - error: function(xhr, textStatus, errorString) { - var errorText = gettext('Server error: ') + textStatus; - if (errorString) { - errorText += ' / ' + errorString; - } - showAsErrors(form, errorText); - $('.post-form-w').unblock(); - }, - url: '/api/add_post/' + threadId + '/', - timeout: POST_AJAX_TIMEOUT - }; - - form.ajaxForm(options); - resetForm(); } } diff --git a/boards/templates/boards/all_threads.html b/boards/templates/boards/all_threads.html --- a/boards/templates/boards/all_threads.html +++ b/boards/templates/boards/all_threads.html @@ -182,7 +182,8 @@ - + + {% endblock %} diff --git a/boards/urls.py b/boards/urls.py --- a/boards/urls.py +++ b/boards/urls.py @@ -67,7 +67,8 @@ urlpatterns = [ url(r'^api/thread/(?P\w+)/$', api.api_get_thread_posts, name='get_thread'), url(r'^api/add_post/(?P\w+)/$', api.api_add_post, - name='add_post'), + name='add_post'), + url(r'^api/add_post/$', api.api_add_post, name='add_post'), url(r'^api/notifications/(?P\w+)/$', api.api_get_notifications, name='api_notifications'), url(r'^api/preview/$', api.api_get_preview, name='preview'), diff --git a/boards/views/api.py b/boards/views/api.py --- a/boards/views/api.py +++ b/boards/views/api.py @@ -9,7 +9,7 @@ from django.shortcuts import get_object_ from django.views.decorators.csrf import csrf_protect from boards.abstracts.settingsmanager import get_settings_manager -from boards.forms import PostForm, PlainErrorList +from boards.forms import PostForm, PlainErrorList, ThreadForm from boards.mdx_neboard import Parser from boards.models import Post, Thread, Tag, TagAlias from boards.models.attachment import AttachmentSticker @@ -82,20 +82,26 @@ def api_get_threaddiff(request): @csrf_protect -def api_add_post(request, opening_post_id): +def api_add_post(request, opening_post_id=None): """ Adds a post and return the JSON response for it """ - # TODO Allow thread creation here too, without specifying opening post - opening_post = get_object_or_404(Post, id=opening_post_id) + if opening_post_id: + opening_post = get_object_or_404(Post, id=opening_post_id) + else: + opening_post = None status = STATUS_OK errors = [] post = None if request.method == 'POST': - form = PostForm(request.POST, request.FILES, error_class=PlainErrorList) + if opening_post: + form = PostForm(request.POST, request.FILES, error_class=PlainErrorList) + else: + form = ThreadForm(request.POST, request.FILES, error_class=PlainErrorList) + form.session = request.session if form.need_to_ban: @@ -122,6 +128,10 @@ def api_add_post(request, opening_post_i if post: response['post_id'] = post.id + if not opening_post: + # FIXME For now we include URL only for threads to navigate to them. + # This needs to become something universal, just not yet sure how. + response['url'] = post.get_absolute_url() return HttpResponse(content=json.dumps(response))