diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js index d8cc43eb254..6f7f08f23b5 100644 --- a/app/assets/javascripts/application.js +++ b/app/assets/javascripts/application.js @@ -9,6 +9,7 @@ // Stuff we need to load first //= require ./discourse/lib/utilities +//= require ./discourse/lib/page-visible //= require ./discourse/lib/ajax //= require ./discourse/lib/text //= require ./discourse/lib/hash diff --git a/app/assets/javascripts/discourse/initializers/message-bus.js.es6 b/app/assets/javascripts/discourse/initializers/message-bus.js.es6 index 3ce1a033c38..a0b113765cb 100644 --- a/app/assets/javascripts/discourse/initializers/message-bus.js.es6 +++ b/app/assets/javascripts/discourse/initializers/message-bus.js.es6 @@ -1,4 +1,6 @@ // Initialize the message bus to receive messages. +import pageVisible from 'discourse/lib/page-visible'; + export default { name: "message-bus", after: 'inject-objects', @@ -36,9 +38,21 @@ export default { messageBus.ajax = function(opts) { opts.headers = opts.headers || {}; opts.headers['X-Shared-Session-Key'] = $('meta[name=shared_session_key]').attr('content'); + if (pageVisible()) { + opts.headers['Discourse-Visible'] = "true"; + } return $.ajax(opts); }; } else { + + messageBus.ajax = function(opts) { + opts.headers = opts.headers || {}; + if (pageVisible()) { + opts.headers['Discourse-Visible'] = "true"; + } + return $.ajax(opts); + }; + messageBus.baseUrl = Discourse.getURL('/'); } diff --git a/app/assets/javascripts/discourse/lib/ajax.js.es6 b/app/assets/javascripts/discourse/lib/ajax.js.es6 index 48f259fd4c9..612d1614994 100644 --- a/app/assets/javascripts/discourse/lib/ajax.js.es6 +++ b/app/assets/javascripts/discourse/lib/ajax.js.es6 @@ -1,3 +1,5 @@ +import pageVisible from 'discourse/lib/page-visible'; + let _trackView = false; let _transientHeader = null; @@ -14,6 +16,7 @@ export function viewTrackingRequired() { for performance reasons. Also automatically adjusts the URL to support installs in subfolders. **/ + export function ajax() { let url, args; let ajaxObj; @@ -47,6 +50,10 @@ export function ajax() { args.headers['Discourse-Track-View'] = "true"; } + if (pageVisible()) { + args.headers['Discourse-Visible'] = "true"; + } + args.success = (data, textStatus, xhr) => { if (xhr.getResponseHeader('Discourse-Readonly')) { Ember.run(() => Discourse.Site.currentProp('isReadOnly', true)); diff --git a/app/assets/javascripts/discourse/lib/page-visible.js.es6 b/app/assets/javascripts/discourse/lib/page-visible.js.es6 new file mode 100644 index 00000000000..e32e68d0d73 --- /dev/null +++ b/app/assets/javascripts/discourse/lib/page-visible.js.es6 @@ -0,0 +1,12 @@ +// for android we test webkit +var hiddenProperty = document.hidden !== undefined ? "hidden" : ( + document.webkitHidden !== undefined ? "webkitHidden" : undefined + ); + +export default function() { + if (hiddenProperty !== undefined){ + return !document[hiddenProperty]; + } else { + return document && document.hasFocus; + } +}; diff --git a/lib/auth/default_current_user_provider.rb b/lib/auth/default_current_user_provider.rb index 0cdfe7ad76a..3326f12dabf 100644 --- a/lib/auth/default_current_user_provider.rb +++ b/lib/auth/default_current_user_provider.rb @@ -225,7 +225,11 @@ class Auth::DefaultCurrentUserProvider end def should_update_last_seen? - !(@request.path =~ /^\/message-bus\//) + if @request.xhr? + @env["HTTP_DISCOURSE_VISIBLE".freeze] == "true".freeze + else + true + end end protected diff --git a/spec/components/auth/default_current_user_provider_spec.rb b/spec/components/auth/default_current_user_provider_spec.rb index b33b44641b1..bbdde400fc5 100644 --- a/spec/components/auth/default_current_user_provider_spec.rb +++ b/spec/components/auth/default_current_user_provider_spec.rb @@ -82,12 +82,22 @@ describe Auth::DefaultCurrentUserProvider do expect(provider("/?api_key=hello&api_username=#{user.username.downcase}").current_user.id).to eq(user.id) end - it "should not update last seen for message bus" do - expect(provider("/message-bus/anything/goes", method: "POST").should_update_last_seen?).to eq(false) - expect(provider("/message-bus/anything/goes", method: "GET").should_update_last_seen?).to eq(false) + it "should not update last seen for ajax calls without Discourse-Visible header" do + expect(provider("/topic/anything/goes", + :method => "POST", + "HTTP_X_REQUESTED_WITH" => "XMLHttpRequest" + ).should_update_last_seen?).to eq(false) end - it "should update last seen for others" do + it "should update ajax reqs with discourse visible" do + expect(provider("/topic/anything/goes", + :method => "POST", + "HTTP_X_REQUESTED_WITH" => "XMLHttpRequest", + "HTTP_DISCOURSE_VISIBLE" => "true" + ).should_update_last_seen?).to eq(true) + end + + it "should update last seen for non ajax" do expect(provider("/topic/anything/goes", method: "POST").should_update_last_seen?).to eq(true) expect(provider("/topic/anything/goes", method: "GET").should_update_last_seen?).to eq(true) end