You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@allura.apache.org by je...@apache.org on 2015/07/22 16:41:46 UTC
[24/29] allura git commit: [#7685] ticket:819 Use ajax requests in
subscription icons
[#7685] ticket:819 Use ajax requests in subscription icons
Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/100d91da
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/100d91da
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/100d91da
Branch: refs/heads/ib/7685
Commit: 100d91da39fc02a5c65326a37e92b1be1c00d2ee
Parents: 0ec05d5
Author: Igor Bondarenko <je...@gmail.com>
Authored: Fri Jul 10 18:03:02 2015 +0300
Committer: Igor Bondarenko <je...@gmail.com>
Committed: Wed Jul 22 15:35:26 2015 +0300
----------------------------------------------------------------------
Allura/allura/controllers/repository.py | 7 +-
.../lib/widgets/resources/js/subscriptions.js | 99 ++++++++++++++++++++
Allura/allura/lib/widgets/subscriptions.py | 7 +-
Allura/allura/templates/widgets/subscribe.html | 44 ++++-----
ForgeBlog/forgeblog/main.py | 11 ++-
.../forgediscussion/controllers/forum.py | 7 +-
ForgeTracker/forgetracker/tracker_main.py | 14 ++-
ForgeWiki/forgewiki/wiki_main.py | 7 +-
8 files changed, 158 insertions(+), 38 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/allura/blob/100d91da/Allura/allura/controllers/repository.py
----------------------------------------------------------------------
diff --git a/Allura/allura/controllers/repository.py b/Allura/allura/controllers/repository.py
index 0178723..2b9ae89 100644
--- a/Allura/allura/controllers/repository.py
+++ b/Allura/allura/controllers/repository.py
@@ -688,7 +688,7 @@ class TreeBrowser(BaseController, DispatchIndex):
self._path + '/' + next,
self), rest
- @expose()
+ @expose('json:')
@require_post()
@validate(subscribe_form)
def subscribe(self, subscribe=None, unsubscribe=None, **kw):
@@ -696,7 +696,10 @@ class TreeBrowser(BaseController, DispatchIndex):
M.Mailbox.subscribe()
elif unsubscribe:
M.Mailbox.unsubscribe()
- redirect(request.referer)
+ return {
+ 'status': 'ok',
+ 'subscribed': M.Mailbox.subscribed(),
+ }
class FileBrowser(BaseController):
http://git-wip-us.apache.org/repos/asf/allura/blob/100d91da/Allura/allura/lib/widgets/resources/js/subscriptions.js
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/widgets/resources/js/subscriptions.js b/Allura/allura/lib/widgets/resources/js/subscriptions.js
new file mode 100644
index 0000000..c03bbeb
--- /dev/null
+++ b/Allura/allura/lib/widgets/resources/js/subscriptions.js
@@ -0,0 +1,99 @@
+/*
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+*/
+
+var dom = React.createElement;
+
+/* top-level form state */
+var state = {
+ 'thing': 'tool',
+ 'subscribed': false,
+ 'url': '',
+ 'icon': {}
+};
+
+SubscriptionForm = React.createClass({
+
+ render: function() {
+ var action = this.props.subscribed ? "Unsubscribe from" : "Subscribe to";
+ var title = action + ' this ' + this.props.thing;
+ var link_opts = {
+ className: this.props.subscribed ? 'active' : '',
+ href: '#',
+ title: title,
+ onClick: this.handleClick
+ };
+ var icon_opts = {
+ 'data-icon': this.props.icon.char,
+ className: 'ico ' + this.props.icon.css,
+ title: title
+ };
+ return dom('a', link_opts, dom('b', icon_opts));
+ },
+
+ handleClick: function() {
+ var url = this.props.url;
+ var csrf = $.cookie('_session_id');
+ var data = {_session_id: csrf};
+ if (this.props.subscribed) {
+ data.unsubscribe = true;
+ } else {
+ data.subscribe = true;
+ }
+ set_state({in_progress: true});
+ /*
+ * TODO:
+ * - show 'in-progress' status to user somehow
+ * - handle errors (show to the user in some kind of popup/flash?)
+ * - If user is subscribed to the whole tool and she tries to subsribe to
+ * the artifact she will not be subscribed, so nothing will change in the
+ * UI and it's confusing. We need to show some information message in
+ * such case
+ */
+ $.post(url, data, function(resp) {
+ if (resp.status == 'ok') {
+ set_state({subscribed: resp.subscribed});
+ }
+ }).always(function() {
+ set_state({in_progress: false});
+ });
+ return false;
+ }
+
+});
+
+function set_state(new_state) {
+ /* Set state and re-render entire UI */
+ for (var key in new_state) {
+ state[key] = new_state[key];
+ }
+ render(state);
+}
+
+function render(state) {
+ var props = {};
+ for (var key in state) { props[key] = state[key]; }
+ React.render(
+ dom(SubscriptionForm, props),
+ document.getElementById('subscription-form')
+ );
+}
+
+$(function() {
+ set_state(document.SUBSCRIPTION_OPTIONS);
+});
http://git-wip-us.apache.org/repos/asf/allura/blob/100d91da/Allura/allura/lib/widgets/subscriptions.py
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/widgets/subscriptions.py b/Allura/allura/lib/widgets/subscriptions.py
index dec1274..c8d3dcd 100644
--- a/Allura/allura/lib/widgets/subscriptions.py
+++ b/Allura/allura/lib/widgets/subscriptions.py
@@ -75,7 +75,7 @@ class SubscribeForm(ew.SimpleForm):
defaults = dict(
ew.SimpleForm.defaults,
thing='tool',
- style='text',
+ style='icon',
tool_subscribed=False,
value=None)
@@ -86,3 +86,8 @@ class SubscribeForm(ew.SimpleForm):
def from_python(self, value, state):
return value
+
+ def resources(self):
+ for r in super(SubscribeForm, self).resources():
+ yield r
+ yield ew.JSLink('js/subscriptions.js')
http://git-wip-us.apache.org/repos/asf/allura/blob/100d91da/Allura/allura/templates/widgets/subscribe.html
----------------------------------------------------------------------
diff --git a/Allura/allura/templates/widgets/subscribe.html b/Allura/allura/templates/widgets/subscribe.html
index 5154eb7..1361a9c 100644
--- a/Allura/allura/templates/widgets/subscribe.html
+++ b/Allura/allura/templates/widgets/subscribe.html
@@ -17,28 +17,24 @@
under the License.
-#}
{% import 'allura:templates/jinja_master/lib.html' as lib with context %}
-{% if value %}
- {% if style == 'icon' %}
- <form action="{{action}}" id="subscribe_form" style="display:inline;" method="POST">
- {{lib.csrf_token()}}
- <input type="hidden" name="unsubscribe" value="1">
- <a href="#" class="artifact_unsubscribe active" title="Unsubscribe from this {{thing}}" onclick="$('#subscribe_form').submit(); return false;"><b data-icon="{{g.icons['mail'].char}}" class="ico {{g.icons['mail'].css}}" title="Unsubscribe from this {{thing}}"></b></a>
- </form>
- {% else %}
- You are currently subscribed to this {{thing}}.
- <br/>
- {{fields['unsubscribe'].display()}}
- {% endif %}
-{% else %}
- {% if style == 'icon' %}
- <form action="{{action}}" id="subscribe_form" style="display:inline;" method="POST">
- {{lib.csrf_token()}}
- <input type="hidden" name="subscribe" value="1">
- <a href="#" class="artifact_subscribe" title="Subscribe to this {{thing}}" onclick="$('#subscribe_form').submit(); return false;"><b data-icon="{{g.icons['mail'].char}}" class="ico {{g.icons['mail'].css}}" title="Subscribe to this {{thing}}"></b></a>
- </form>
- {% else %}
- You are currently not subscribed to this {{thing}}.
- <br/>
- {{fields['subscribe'].display()}}
- {% endif %}
+
+{% do g.register_forge_js('js/react.min.js', location='head_js') %}
+{% for blob in g.resource_manager.emit('head_js') %}
+{% if 'react.min.js' in blob %}
+ {{ blob }}
{% endif %}
+{% endfor %}
+
+<div id="subscription-form" style="display: inline;">{# see subscription.js #}</div>
+
+<script>
+ document.SUBSCRIPTION_OPTIONS = {
+ "thing": "{{thing}}",
+ "subscribed": {{"true" if value else "false"}},
+ "url": "{{action}}",
+ "icon": {
+ "char": "{{g.icons['mail'].char}}",
+ "css": "{{g.icons['mail'].css}}"
+ }
+ };
+</script>
http://git-wip-us.apache.org/repos/asf/allura/blob/100d91da/ForgeBlog/forgeblog/main.py
----------------------------------------------------------------------
diff --git a/ForgeBlog/forgeblog/main.py b/ForgeBlog/forgeblog/main.py
index 9007f87..adfc172 100644
--- a/ForgeBlog/forgeblog/main.py
+++ b/ForgeBlog/forgeblog/main.py
@@ -322,8 +322,10 @@ class PostController(BaseController, FeedController):
version = kw.pop('version', None)
post = self._get_version(version)
base_post = self.post
+ subscribed = M.Mailbox.subscribed(artifact=self.post)
return dict(post=post, base_post=base_post,
- page=page, limit=limit, count=post_count)
+ page=page, limit=limit, count=post_count,
+ subscribed=subscribed)
@expose('jinja:forgeblog:templates/blog/edit_post.html')
@without_trailing_slash
@@ -375,7 +377,7 @@ class PostController(BaseController, FeedController):
self.post.commit()
redirect('.')
- @expose()
+ @expose('json:')
@require_post()
@validate(W.subscribe_form)
def subscribe(self, subscribe=None, unsubscribe=None, **kw):
@@ -383,7 +385,10 @@ class PostController(BaseController, FeedController):
self.post.subscribe(type='direct')
elif unsubscribe:
self.post.unsubscribe()
- redirect(h.really_unicode(request.referer).encode('utf-8'))
+ return {
+ 'status': 'ok',
+ 'subscribed': M.Mailbox.subscribed(artifact=self.post),
+ }
def get_feed(self, project, app, user):
"""Return a :class:`allura.controllers.feed.FeedArgs` object describing
http://git-wip-us.apache.org/repos/asf/allura/blob/100d91da/ForgeDiscussion/forgediscussion/controllers/forum.py
----------------------------------------------------------------------
diff --git a/ForgeDiscussion/forgediscussion/controllers/forum.py b/ForgeDiscussion/forgediscussion/controllers/forum.py
index 94fe6d9..b915823 100644
--- a/ForgeDiscussion/forgediscussion/controllers/forum.py
+++ b/ForgeDiscussion/forgediscussion/controllers/forum.py
@@ -122,7 +122,7 @@ class ForumController(DiscussionController):
def deleted(self):
return dict()
- @expose()
+ @expose('json:')
@require_post()
@validate(W.subscribe_form)
def subscribe_to_forum(self, subscribe=None, unsubscribe=None, shortname=None, **kw):
@@ -130,7 +130,10 @@ class ForumController(DiscussionController):
self.discussion.subscribe(type='direct')
elif unsubscribe:
self.discussion.unsubscribe()
- redirect(h.really_unicode(request.referer).encode('utf-8'))
+ return {
+ 'status': 'ok',
+ 'subscribed': M.Mailbox.subscribed(artifact=self.discussion),
+ }
class ForumThreadController(ThreadController):
http://git-wip-us.apache.org/repos/asf/allura/blob/100d91da/ForgeTracker/forgetracker/tracker_main.py
----------------------------------------------------------------------
diff --git a/ForgeTracker/forgetracker/tracker_main.py b/ForgeTracker/forgetracker/tracker_main.py
index c3a83e6..0049957 100644
--- a/ForgeTracker/forgetracker/tracker_main.py
+++ b/ForgeTracker/forgetracker/tracker_main.py
@@ -1090,7 +1090,7 @@ class RootController(BaseController, FeedController):
dates=dates,
)
- @expose()
+ @expose('json:')
@require_post()
@validate(W.subscribe_form)
def subscribe(self, subscribe=None, unsubscribe=None):
@@ -1098,7 +1098,10 @@ class RootController(BaseController, FeedController):
M.Mailbox.subscribe(type='direct')
elif unsubscribe:
M.Mailbox.unsubscribe()
- redirect(request.referer)
+ return {
+ 'status': 'ok',
+ 'subscribed': M.Mailbox.subscribed(),
+ }
class BinController(BaseController):
@@ -1520,7 +1523,7 @@ class TicketController(BaseController, FeedController):
c.app.globals.invalidate_bin_counts()
redirect('.')
- @expose()
+ @expose('json:')
@require_post()
@validate(W.subscribe_form)
def subscribe(self, subscribe=None, unsubscribe=None):
@@ -1528,7 +1531,10 @@ class TicketController(BaseController, FeedController):
self.ticket.subscribe(type='direct')
elif unsubscribe:
self.ticket.unsubscribe()
- redirect(request.referer)
+ return {
+ 'status': 'ok',
+ 'subscribed': M.Mailbox.subscribed(artifact=self.ticket),
+ }
@expose('json:')
@require_post()
http://git-wip-us.apache.org/repos/asf/allura/blob/100d91da/ForgeWiki/forgewiki/wiki_main.py
----------------------------------------------------------------------
diff --git a/ForgeWiki/forgewiki/wiki_main.py b/ForgeWiki/forgewiki/wiki_main.py
index 229a348..9fca1c2 100644
--- a/ForgeWiki/forgewiki/wiki_main.py
+++ b/ForgeWiki/forgewiki/wiki_main.py
@@ -737,7 +737,7 @@ class PageController(BaseController, FeedController):
self.page.add_multiple_attachments(file_info)
redirect(request.referer)
- @expose()
+ @expose('json:')
@require_post()
@validate(W.subscribe_form)
def subscribe(self, subscribe=None, unsubscribe=None, **kw):
@@ -747,7 +747,10 @@ class PageController(BaseController, FeedController):
self.page.subscribe(type='direct')
elif unsubscribe:
self.page.unsubscribe()
- redirect(request.referer)
+ return {
+ 'status': 'ok',
+ 'subscribed': M.Mailbox.subscribed(artifact=self.page),
+ }
class WikiAttachmentController(ac.AttachmentController):