From e830853aee9384ef37e92713e87efea9c79d6ee6 Mon Sep 17 00:00:00 2001 From: vsvipul Date: Fri, 29 Mar 2019 04:43:07 +0530 Subject: [PATCH] desktop-presence: Use system presence data from electron-bridge. Combined with work in the desktop app, this makes it possible for the desktop app to clearly indicate to other users whether the current user is active on the system and thus would see a desktop notification, not just whether they are active in the current Zulip window. Essentially rewritten by tabbott to add unit tests and consider the desktop app data authoritative. --- frontend_tests/node_tests/activity.js | 23 ++++++++++++++++++ static/js/activity.js | 35 +++++++++++++++++++++------ 2 files changed, 50 insertions(+), 8 deletions(-) diff --git a/frontend_tests/node_tests/activity.js b/frontend_tests/node_tests/activity.js index 770caec482..04b32cac74 100644 --- a/frontend_tests/node_tests/activity.js +++ b/frontend_tests/node_tests/activity.js @@ -894,3 +894,26 @@ run_test('away_status', () => { activity.on_revoke_away(alice.user_id); assert(!user_status.is_away(alice.user_id)); }); + +run_test('electron_bridge', () => { + activity.client_is_active = false; + window.electron_bridge = undefined; + assert.equal(activity.compute_active_status(), activity.IDLE); + + activity.client_is_active = true; + assert.equal(activity.compute_active_status(), activity.ACTIVE); + + window.electron_bridge = { + idle_on_system: true, + }; + assert.equal(activity.compute_active_status(), activity.IDLE); + activity.client_is_active = false; + assert.equal(activity.compute_active_status(), activity.IDLE); + + window.electron_bridge = { + idle_on_system: false, + }; + assert.equal(activity.compute_active_status(), activity.ACTIVE); + activity.client_is_active = true; + assert.equal(activity.compute_active_status(), activity.ACTIVE); +}); diff --git a/static/js/activity.js b/static/js/activity.js index cb553aa64b..d69d79d066 100644 --- a/static/js/activity.js +++ b/static/js/activity.js @@ -262,23 +262,42 @@ exports.update_huddles = function () { show_huddles(); }; +exports.compute_active_status = function () { + // The overall algorithm intent for the `status` field is to send + // `ACTIVE` (aka green circle) if we know the user is at their + // computer, and IDLE (aka orange circle) if the user might not + // be: + // + // * For the webapp, we just know whether this window has focus. + // * For the electron desktop app, we also know whether the + // user is active or idle elsewhere on their system. + // + // The check for `idle_on_system === undefined` is feature + // detection; older desktop app releases never set that property. + if (window.electron_bridge !== undefined + && window.electron_bridge.idle_on_system !== undefined) { + if (window.electron_bridge.idle_on_system) { + return exports.IDLE; + } + return exports.ACTIVE; + } + + if (exports.client_is_active) { + return exports.ACTIVE; + } + return exports.IDLE; +}; + function send_presence_to_server(want_redraw) { - var status; if (reload_state.is_in_progress()) { blueslip.log("Skipping querying presence because reload in progress"); return; } - if (exports.client_is_active) { - status = exports.ACTIVE; - } else { - status = exports.IDLE; - } - channel.post({ url: '/json/users/me/presence', data: { - status: status, + status: exports.compute_active_status(), ping_only: !want_redraw, new_user_input: exports.new_user_input, },