diff options
author | Evgeny Fadeev <evgeny.fadeev@gmail.com> | 2012-05-06 17:58:32 -0400 |
---|---|---|
committer | Evgeny Fadeev <evgeny.fadeev@gmail.com> | 2012-05-06 17:58:32 -0400 |
commit | 10279a75eeee523dd16db092b9e1da424f9060dc (patch) | |
tree | a58b9df57aa0819b3731604bca291f3c2115b323 | |
parent | 3cb0e5f86f1a7e06f2af669676dc8e3d2b0feb12 (diff) | |
download | askbot-10279a75eeee523dd16db092b9e1da424f9060dc.tar.gz askbot-10279a75eeee523dd16db092b9e1da424f9060dc.tar.bz2 askbot-10279a75eeee523dd16db092b9e1da424f9060dc.zip |
added "anyone can join" control to the group profile editor
-rw-r--r-- | askbot/skins/common/media/js/post.js | 27 | ||||
-rw-r--r-- | askbot/skins/common/media/js/utils.js | 103 | ||||
-rw-r--r-- | askbot/skins/default/media/bootstrap/css/bootstrap.css | 8 | ||||
-rw-r--r-- | askbot/skins/default/media/style/style.less | 6 | ||||
-rw-r--r-- | askbot/skins/default/templates/user_profile/user_inbox.html | 2 | ||||
-rw-r--r-- | askbot/skins/default/templates/users.html | 6 | ||||
-rw-r--r-- | askbot/skins/default/templates/widgets/group_info.html | 30 | ||||
-rw-r--r-- | askbot/urls.py | 8 | ||||
-rw-r--r-- | askbot/views/commands.py | 71 |
9 files changed, 172 insertions, 89 deletions
diff --git a/askbot/skins/common/media/js/post.js b/askbot/skins/common/media/js/post.js index 9f417642..e018197c 100644 --- a/askbot/skins/common/media/js/post.js +++ b/askbot/skins/common/media/js/post.js @@ -2314,15 +2314,22 @@ UserGroupProfileEditor.prototype.decorate = function(element){ var change_logo_btn = element.find('.change-logo'); this._change_logo_btn = change_logo_btn; - var moderate_email_btn = element.find('.moderate-email'); + var moderate_email_toggle = new TwoStateToggle(); + moderate_email_toggle.setPostData({ + group_id: this.getTagId(), + property_name: 'moderate_email' + }); + var moderate_email_btn = element.find('#moderate-email'); this._moderate_email_btn = moderate_email_btn; - var me = this; - setupButtonEventHandlers( - moderate_email_btn, - function(){ - me.toggleEmailModeration(); - } - ) + moderate_email_toggle.decorate(moderate_email_btn); + + var open_group_toggle = new TwoStateToggle(); + open_group_toggle.setPostData({ + group_id: this.getTagId(), + property_name: 'is_open' + }); + var open_group_btn = element.find('#open-or-close-group'); + open_group_toggle.decorate(open_group_btn); var logo_changer = new ImageChanger(); logo_changer.setImageElement(element.find('.group-logo')); @@ -2341,10 +2348,10 @@ UserGroupProfileEditor.prototype.decorate = function(element){ }; var GroupJoinButton = function(group_id){ - FollowToggle.call(this); + TwoStateToggle.call(this); this._group_id = group_id; }; -inherits(GroupJoinButton, FollowToggle); +inherits(GroupJoinButton, TwoStateToggle); GroupJoinButton.prototype.getPostData = function(){ return { group_id: this._group_id }; diff --git a/askbot/skins/common/media/js/utils.js b/askbot/skins/common/media/js/utils.js index 0c908b5d..d69777cd 100644 --- a/askbot/skins/common/media/js/utils.js +++ b/askbot/skins/common/media/js/utils.js @@ -481,13 +481,14 @@ DeleteIcon.prototype.setContent = function(content){ /** * A button on which user can click * and become added to some group (followers, group members, etc.) + * or toggle some state on/off * The button has four states on-prompt, off-prompt, on-state and off-state * on-prompt is activated on mouseover, when user is not part of group * off-prompt - on mouseover, when user is part of group * on-state - when user is part of group and mouse is not over the button * off-state - same as above, but when user is not part of the group */ -var FollowToggle = function(){ +var TwoStateToggle = function(){ SimpleControl.call(this); this._state = null; this._state_messages = {}; @@ -497,10 +498,21 @@ var FollowToggle = function(){ 'on-prompt', 'off-prompt' ]; + this._handler = this.getDefaultHandler(); + this._post_data = {}; + this.toggleUrl = '';//public property }; -inherits(FollowToggle, SimpleControl); +inherits(TwoStateToggle, SimpleControl); -FollowToggle.prototype.resetStyles = function(){ +TwoStateToggle.prototype.setPostData = function(data){ + this._post_data = data; +}; + +TwoStateToggle.prototype.getPostData = function(){ + return this._post_data; +}; + +TwoStateToggle.prototype.resetStyles = function(){ var element = this._element; var states = this._states; $.each(states, function(idx, state){ @@ -509,11 +521,11 @@ FollowToggle.prototype.resetStyles = function(){ this._element.html(''); }; -FollowToggle.prototype.isOn = function(){ +TwoStateToggle.prototype.isOn = function(){ return this._element.hasClass('on'); }; -FollowToggle.prototype.setOn = function(is_on){ +TwoStateToggle.prototype.setOn = function(is_on){ if (is_on){ this._element.addClass('on'); this._element.html(this._state_messages['on-state']); @@ -523,35 +535,78 @@ FollowToggle.prototype.setOn = function(is_on){ } }; -FollowToggle.prototype.setState = function(state){ +TwoStateToggle.prototype.getDefaultHandler = function(){ + var me = this; + return function(){ + var data = me.getPostData(); + data['disable'] = me.isOn(); + $.ajax({ + type: 'POST', + dataType: 'json', + cache: false, + url: me.toggleUrl, + data: data, + success: function(data) { + if (data['success']) { + me.setOn('is_enabled'); + } else { + showMessage(me.getElement(), data['message']); + } + } + }); + }; +}; + +TwoStateToggle.prototype.setState = function(state){ + var element = this._element; this._state = state; - if (this._element){ - this.resetStyles(); - this._element.addClass(state); - this._element.html(this._state_messages[state]); + if (element) { + if ( + element.attr('nodeName') === 'INPUT' && + element.attr('type') === 'checkbox' + ) { + if (state === 'on-state') { + element.attr('checked', true); + } else if (state === 'off-state') { + element.attr('checked', false); + } + } else { + this.resetStyles(); + element.addClass(state); + this._element.html(this._state_messages[state]); + } } }; -FollowToggle.prototype.decorate = function(element){ +TwoStateToggle.prototype.decorate = function(element){ this._element = element; //read messages for all states var messages = {}; - $.each(this._states, function(idx, state){ - if (state === 'off-state'){ - return; - } - messages[state] = element.attr('data-' + state + '-text'); - }); - messages['off-state'] = messages['on-prompt'] + messages['on-state'] = + element.attr('data-on-state-text') || gettext('enabled'); + messages['off-state'] = + element.attr('data-off-state-text') || gettext('disabled'); + messages['on-prompt'] = + element.attr('data-on-prompt-text') || messages['on-state']; + messages['off-prompt'] = + element.attr('data-off-prompt-text') || messages['off-state']; this._state_messages = messages; + this.toggleUrl = element.attr('data-toggle-url'); + //detect state and save it - var text = $.trim(element.html()); - for (var i = 0; i < this._states.length; i++){ - var state = this._states[i]; - if (text === messages[state]){ - this._state = state; - break; + if ( + element.attr('nodeName') === 'INPUT' && element.attr('type', 'checkbox') + ) { + this._state = element.attr('checked') ? 'state-on' : 'state-off'; + } else { + var text = $.trim(element.html()); + for (var i = 0; i < this._states.length; i++){ + var state = this._states[i]; + if (text === messages[state]){ + this._state = state; + break; + } } } diff --git a/askbot/skins/default/media/bootstrap/css/bootstrap.css b/askbot/skins/default/media/bootstrap/css/bootstrap.css index 5ffd980f..9447a9a2 100644 --- a/askbot/skins/default/media/bootstrap/css/bootstrap.css +++ b/askbot/skins/default/media/bootstrap/css/bootstrap.css @@ -570,7 +570,7 @@ pre code { max-height: 340px; overflow-y: scroll; } -.label { +/*.label { padding: 1px 4px 2px; font-size: 10.998px; font-weight: bold; @@ -587,7 +587,7 @@ pre code { .label:hover { color: #ffffff; text-decoration: none; -} +}*/ .label-important { background-color: #b94a48; } @@ -3076,10 +3076,10 @@ input[type="submit"].btn.btn-mini { display: inline-block; padding: 5px 14px; background-color: #fff; - border: 1px solid #ddd; + /*border: 1px solid #ddd; -webkit-border-radius: 15px; -moz-border-radius: 15px; - border-radius: 15px; + border-radius: 15px;*/ } .pager a:hover { text-decoration: none; diff --git a/askbot/skins/default/media/style/style.less b/askbot/skins/default/media/style/style.less index 43f5be61..27424871 100644 --- a/askbot/skins/default/media/style/style.less +++ b/askbot/skins/default/media/style/style.less @@ -673,6 +673,11 @@ body.anon { } } +.users-page .box label { + display: inline; + float: none; +} + .statsWidget p{ color:@info-text; font-size:16px; @@ -2133,7 +2138,6 @@ ul#related-tags li { .openid-signin, .meta, -.users-page, .user-profile-edit-page, { font-size:13px; diff --git a/askbot/skins/default/templates/user_profile/user_inbox.html b/askbot/skins/default/templates/user_profile/user_inbox.html index ee7057e3..cda45027 100644 --- a/askbot/skins/default/templates/user_profile/user_inbox.html +++ b/askbot/skins/default/templates/user_profile/user_inbox.html @@ -1,7 +1,7 @@ {% extends "user_profile/user.html" %} {% import "macros.html" as macros %} {% block before_css %} - <link href="{{'/bootstrap/css/bootstrap.min.css'|media}}" rel="stylesheet" type="text/css" /> + <link href="{{'/bootstrap/css/bootstrap.css'|media}}" rel="stylesheet" type="text/css" /> {% endblock %} <!-- user_responses.html --> {# diff --git a/askbot/skins/default/templates/users.html b/askbot/skins/default/templates/users.html index 595bbd72..ec4946bb 100644 --- a/askbot/skins/default/templates/users.html +++ b/askbot/skins/default/templates/users.html @@ -2,6 +2,11 @@ {% import "macros.html" as macros %} <!-- users.html --> {% block title %}{% spaceless %}{% trans %}Users{% endtrans %}{% endspaceless %}{% endblock %} +{% block before_css %} + {% if group and request.user.is_administrator() %} + <link href="{{'/bootstrap/css/bootstrap.css'|media}}" rel="stylesheet" type="text/css" /> + {% endif %} +{% endblock %} {% block forestyle %} <link rel="stylesheet" type="text/css" href="{{"/js/wmd/wmd.css"|media}}" /> {% endblock %} @@ -75,7 +80,6 @@ askbot['urls']['save_tag_wiki_text'] = '{% url save_tag_wiki_text %}'; askbot['urls']['save_group_logo_url'] = '{% url save_group_logo_url %}'; askbot['urls']['delete_group_logo_url'] = '{% url delete_group_logo %}'; - askbot['urls']['toggle_group_email_moderation'] = '{% url toggle_group_email_moderation %}'; askbot['urls']['join_or_leave_group'] = '{% url join_or_leave_group %}'; </script> <script type='text/javascript' src='{{"/js/editor.js"|media}}'></script> diff --git a/askbot/skins/default/templates/widgets/group_info.html b/askbot/skins/default/templates/widgets/group_info.html index b819db79..7e4b3e1e 100644 --- a/askbot/skins/default/templates/widgets/group_info.html +++ b/askbot/skins/default/templates/widgets/group_info.html @@ -19,6 +19,7 @@ data-off-prompt-text="{% trans %}Leave this group{% endtrans %}" data-on-prompt-text="{% trans %}Join this group{% endtrans %}" data-on-state-text="{% trans %}You are a member{% endtrans %}" + data-off-state-text="{% trans %}Join this group{% endtrans %}" > {% if user_is_group_member %} {% trans %}You are a member{% endtrans %} @@ -29,7 +30,7 @@ {% endif %} </button> {% endif %} - {% if request.user.is_authenticated() and request.user.is_administrator_or_moderator() %} + {% if request.user.is_authenticated() and request.user.is_administrator() %} <div class="controls"> <a class="edit-description" >{% trans %}edit description{% endtrans %}</a> @@ -44,16 +45,27 @@ <a class="change-logo" >{% trans %}add logo{% endtrans %}</a> {% endif %} + <br/> {% if group_email_moderation_enabled %} - <span>|</span> - {% if group.group_profile.moderate_email %} - <a class="moderate-email" - >{% trans %}disable moderation of emailed questions{% endtrans %}</a> - {% else %} - <a class="moderate-email" - >{% trans %}moderate emailed questions{% endtrans %}</a> - {% endif %} + <input type="checkbox" + id="moderate-email" + {% if group.group_profile.moderate_email %}checked="checked"{% endif %} + data-toggle-url="{% url toggle_group_profile_property %}" + /> + <label for="moderate-email"> + {% trans %}moderate emailed questions{% endtrans %} + </label> + <br/> {% endif %} + <input type="checkbox" + id="open-or-close-group" + {% if group.group_profile.is_open %}checked="checked"{% endif %} + data-toggle-url="{% url toggle_group_profile_property %}" + /> + <label for="open-or-close-group"> + {% trans %}anyone can join{% endtrans %} + </label> + <br/> </div> {% endif %} </div> diff --git a/askbot/urls.py b/askbot/urls.py index 7a3eb248..fb9ea977 100644 --- a/askbot/urls.py +++ b/askbot/urls.py @@ -213,9 +213,9 @@ urlpatterns = patterns('', name = 'delete_group_logo' ), url(#ajax only - r'^toggle-group-email-moderation/', - views.commands.toggle_group_email_moderation, - name = 'toggle_group_email_moderation' + r'^toggle-group-profile-property/', + views.commands.toggle_group_profile_property, + name = 'toggle_group_profile_property' ), url( r'^get-groups-list/', @@ -311,7 +311,7 @@ urlpatterns = patterns('', url(#ajax only r'^join-or-leave-group/$', views.commands.join_or_leave_group, - name='join_or_leave_group' + name = 'join_or_leave_group' ), url( r'^feeds/(?P<url>.*)/$', diff --git a/askbot/views/commands.py b/askbot/views/commands.py index 6825461e..4a560f1e 100644 --- a/askbot/views/commands.py +++ b/askbot/views/commands.py @@ -10,7 +10,7 @@ from django.core import exceptions from django.core.urlresolvers import reverse from django.contrib.auth.decorators import login_required from django.http import HttpResponse, HttpResponseRedirect, Http404, HttpResponseBadRequest -from django.forms import ValidationError, IntegerField +from django.forms import ValidationError, IntegerField, CharField from django.shortcuts import get_object_or_404 from django.views.decorators import csrf from django.utils import simplejson @@ -731,32 +731,6 @@ def read_message(request):#marks message a read @csrf.csrf_exempt @decorators.ajax_only @decorators.post_only -def join_or_leave_group(request): - """only current user can join/leave group""" - if request.user.is_anonymous(): - raise exceptions.PermissionDenied() - - group_id = IntegerField().clean(request.POST['group_id']) - group = models.Tag.objects.get(id = group_id) - - if request.user.is_group_member(group): - action = 'remove' - is_member = False - else: - action = 'add' - is_member = True - request.user.edit_group_membership( - user = request.user, - group = group, - action = action - ) - return {'is_member': is_member} - - - -@csrf.csrf_exempt -@decorators.ajax_only -@decorators.post_only @decorators.admins_only def edit_group_membership(request): form = forms.EditGroupMembershipForm(request.POST) @@ -821,6 +795,7 @@ def delete_group_logo(request): group.group_profile.logo_url = None group.group_profile.save() + @csrf.csrf_exempt @decorators.ajax_only @decorators.post_only @@ -830,21 +805,47 @@ def delete_post_reject_reason(request): reason = models.PostFlagReason.objects.get(id = reason_id) reason.delete() + @csrf.csrf_exempt @decorators.ajax_only @decorators.post_only @decorators.admins_only -def toggle_group_email_moderation(request): +def toggle_group_profile_property(request): + #todo: this might be changed to more general "toggle object property" group_id = IntegerField().clean(int(request.POST['group_id'])) - group = models.Tag.group_tags.get(id = group_id) - group.group_profile.moderate_email = not group.group_profile.moderate_email + property_name = CharField().clean(request.POST['property_name']) + assert property_name in ('is_open', 'moderate_email') + + group = models.Tag.objects.get(id = group_id) + new_value = not getattr(group.group_profile, property_name) + setattr(group.group_profile, property_name, new_value) group.group_profile.save() - if group.group_profile.moderate_email: - new_button_text = _('disable moderation of emailed questions') - else: - new_button_text = _('moderate emailed questions') - return {'new_button_text': new_button_text} + return {'is_enabled': new_value} + + +@csrf.csrf_exempt +@decorators.ajax_only +@decorators.post_only +def join_or_leave_group(request): + """only current user can join/leave group""" + if request.user.is_anonymous(): + raise exceptions.PermissionDenied() + group_id = IntegerField().clean(request.POST['group_id']) + group = models.Tag.objects.get(id = group_id) + + if request.user.is_group_member(group): + action = 'remove' + is_member = False + else: + action = 'add' + is_member = True + request.user.edit_group_membership( + user = request.user, + group = group, + action = action + ) + return {'is_member': is_member} @csrf.csrf_exempt |