FIX: last seen date erroneously updated when browser in background

In some cases user may be "last seen" even though browser tab is in
the background or computer is locked
This commit is contained in:
Sam 2017-02-28 12:34:57 -05:00
parent 352f98d084
commit 122fb8025d
6 changed files with 53 additions and 5 deletions

View File

@ -9,6 +9,7 @@
// Stuff we need to load first // Stuff we need to load first
//= require ./discourse/lib/utilities //= require ./discourse/lib/utilities
//= require ./discourse/lib/page-visible
//= require ./discourse/lib/ajax //= require ./discourse/lib/ajax
//= require ./discourse/lib/text //= require ./discourse/lib/text
//= require ./discourse/lib/hash //= require ./discourse/lib/hash

View File

@ -1,4 +1,6 @@
// Initialize the message bus to receive messages. // Initialize the message bus to receive messages.
import pageVisible from 'discourse/lib/page-visible';
export default { export default {
name: "message-bus", name: "message-bus",
after: 'inject-objects', after: 'inject-objects',
@ -36,9 +38,21 @@ export default {
messageBus.ajax = function(opts) { messageBus.ajax = function(opts) {
opts.headers = opts.headers || {}; opts.headers = opts.headers || {};
opts.headers['X-Shared-Session-Key'] = $('meta[name=shared_session_key]').attr('content'); opts.headers['X-Shared-Session-Key'] = $('meta[name=shared_session_key]').attr('content');
if (pageVisible()) {
opts.headers['Discourse-Visible'] = "true";
}
return $.ajax(opts); return $.ajax(opts);
}; };
} else { } else {
messageBus.ajax = function(opts) {
opts.headers = opts.headers || {};
if (pageVisible()) {
opts.headers['Discourse-Visible'] = "true";
}
return $.ajax(opts);
};
messageBus.baseUrl = Discourse.getURL('/'); messageBus.baseUrl = Discourse.getURL('/');
} }

View File

@ -1,3 +1,5 @@
import pageVisible from 'discourse/lib/page-visible';
let _trackView = false; let _trackView = false;
let _transientHeader = null; let _transientHeader = null;
@ -14,6 +16,7 @@ export function viewTrackingRequired() {
for performance reasons. Also automatically adjusts the URL to support installs for performance reasons. Also automatically adjusts the URL to support installs
in subfolders. in subfolders.
**/ **/
export function ajax() { export function ajax() {
let url, args; let url, args;
let ajaxObj; let ajaxObj;
@ -47,6 +50,10 @@ export function ajax() {
args.headers['Discourse-Track-View'] = "true"; args.headers['Discourse-Track-View'] = "true";
} }
if (pageVisible()) {
args.headers['Discourse-Visible'] = "true";
}
args.success = (data, textStatus, xhr) => { args.success = (data, textStatus, xhr) => {
if (xhr.getResponseHeader('Discourse-Readonly')) { if (xhr.getResponseHeader('Discourse-Readonly')) {
Ember.run(() => Discourse.Site.currentProp('isReadOnly', true)); Ember.run(() => Discourse.Site.currentProp('isReadOnly', true));

View File

@ -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;
}
};

View File

@ -225,7 +225,11 @@ class Auth::DefaultCurrentUserProvider
end end
def should_update_last_seen? def should_update_last_seen?
!(@request.path =~ /^\/message-bus\//) if @request.xhr?
@env["HTTP_DISCOURSE_VISIBLE".freeze] == "true".freeze
else
true
end
end end
protected protected

View File

@ -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) expect(provider("/?api_key=hello&api_username=#{user.username.downcase}").current_user.id).to eq(user.id)
end end
it "should not update last seen for message bus" do it "should not update last seen for ajax calls without Discourse-Visible header" do
expect(provider("/message-bus/anything/goes", method: "POST").should_update_last_seen?).to eq(false) expect(provider("/topic/anything/goes",
expect(provider("/message-bus/anything/goes", method: "GET").should_update_last_seen?).to eq(false) :method => "POST",
"HTTP_X_REQUESTED_WITH" => "XMLHttpRequest"
).should_update_last_seen?).to eq(false)
end 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: "POST").should_update_last_seen?).to eq(true)
expect(provider("/topic/anything/goes", method: "GET").should_update_last_seen?).to eq(true) expect(provider("/topic/anything/goes", method: "GET").should_update_last_seen?).to eq(true)
end end