mirror of
https://github.com/zulip/zulip.git
synced 2025-11-06 23:13:25 +00:00
We don't typically have these (see message type, etc.) and removing them will allow simplifying the code. (imported from commit fbefb08ee9b08c73f32c8150a6fa1060957aa8ad)
128 lines
3.4 KiB
JavaScript
128 lines
3.4 KiB
JavaScript
var activity = (function () {
|
|
var exports = {};
|
|
|
|
/*
|
|
Helpers for detecting user activity and managing user idle states
|
|
*/
|
|
|
|
/* 15 minutes after no activity, idle regardless of focus */
|
|
var DEFAULT_IDLE_TIMEOUT_MS = 15 * 60 * 1000;
|
|
/* 1 minute between keep-alive pings */
|
|
var ACTIVE_PING_INTERVAL_MS = 60 * 1000;
|
|
|
|
/* Timeouts for away and idle state */
|
|
var AWAY_THRESHOLD_SECS = 5 * 60;
|
|
var IDLE_THRESHOLD_SECS = DEFAULT_IDLE_TIMEOUT_MS / 1000;
|
|
|
|
/* Keep in sync with views.py:json_update_active_status() */
|
|
var ACTIVE = "active";
|
|
var IDLE = "idle";
|
|
|
|
var has_focus = true;
|
|
var ping_timer;
|
|
|
|
function sort_users(users, user_info) {
|
|
// TODO sort by unread count first, once we support that
|
|
users.sort(function (a, b) {
|
|
if (user_info[a] === 'active' && user_info[b] !== 'active') {
|
|
return -1;
|
|
} else if (user_info[b] === 'active' && user_info[a] !== 'active') {
|
|
return 1;
|
|
}
|
|
|
|
if (user_info[a] === 'away' && user_info[b] !== 'away') {
|
|
return -1;
|
|
} else if (user_info[b] === 'away' && user_info[a] !== 'away') {
|
|
return 1;
|
|
}
|
|
|
|
// Sort equivalent PM names alphabetically
|
|
var full_name_a = a;
|
|
var full_name_b = b;
|
|
if (people_dict[a] !== undefined) {
|
|
full_name_a = people_dict[a].full_name;
|
|
}
|
|
if (people_dict[b] !== undefined) {
|
|
full_name_b = people_dict[b].full_name;
|
|
}
|
|
return full_name_a.localeCompare(full_name_b);
|
|
});
|
|
|
|
return users;
|
|
}
|
|
|
|
function focus_lost() {
|
|
if (!has_focus) {
|
|
return false;
|
|
}
|
|
|
|
has_focus = false;
|
|
|
|
clearInterval(ping_timer);
|
|
ping_timer = undefined;
|
|
|
|
$.post('/json/update_active_status', {status: IDLE});
|
|
|
|
}
|
|
|
|
function focus_ping() {
|
|
if (!has_focus) {
|
|
return;
|
|
}
|
|
|
|
$.post('/json/update_active_status', {status: ACTIVE}, function (data) {
|
|
var now = new Date().getTime() / 1000;
|
|
var user_info = {};
|
|
var users = [];
|
|
|
|
// Ping returns the active peer list
|
|
$.each(data.presences, function (this_email, presence) {
|
|
var age = -1;
|
|
|
|
if (presence.website !== undefined && presence.website.timestamp !== undefined) {
|
|
age = now - presence.website.timestamp;
|
|
}
|
|
|
|
if (email !== this_email) {
|
|
var status = 'idle';
|
|
if (presence.website !== undefined
|
|
&& presence.website.status === ACTIVE && age >= 0) {
|
|
if (age < AWAY_THRESHOLD_SECS) {
|
|
status = 'active';
|
|
} else if (age < IDLE_THRESHOLD_SECS) {
|
|
status = 'away';
|
|
}
|
|
}
|
|
user_info[this_email] = status;
|
|
}
|
|
});
|
|
users = sort_users(Object.keys(user_info), user_info);
|
|
ui.set_presence_list(users, user_info);
|
|
});
|
|
}
|
|
|
|
function focus_gained() {
|
|
if (!has_focus) {
|
|
has_focus = true;
|
|
ping_timer = setInterval(focus_ping, ACTIVE_PING_INTERVAL_MS);
|
|
|
|
focus_ping();
|
|
}
|
|
}
|
|
|
|
exports.initialize = function () {
|
|
$(window).focus(focus_gained);
|
|
$(window).idle({idle: DEFAULT_IDLE_TIMEOUT_MS,
|
|
onIdle: focus_lost,
|
|
onActive: focus_gained,
|
|
keepTracking: true});
|
|
|
|
ping_timer = setInterval(focus_ping, ACTIVE_PING_INTERVAL_MS);
|
|
|
|
focus_ping();
|
|
};
|
|
|
|
return exports;
|
|
|
|
}());
|