mirror of https://github.com/zulip/zulip.git
Show a mobile icon in the presence list when relevant
We show a user as "on mobile" if: * They are only active on mobile * They are inactive on all devices and can receive push notifications (imported from commit 0510b9371727cd19c72f6990df7112921c36ad48)
This commit is contained in:
parent
4397c25976
commit
bd20a756f9
|
@ -13,6 +13,14 @@ var ACTIVE_PING_INTERVAL_MS = 50 * 1000;
|
|||
/* Mark users as offline after 140 seconds since their last checkin */
|
||||
var OFFLINE_THRESHOLD_SECS = 140;
|
||||
|
||||
// Testing
|
||||
exports._OFFLINE_THRESHOLD_SECS = OFFLINE_THRESHOLD_SECS;
|
||||
|
||||
var MOBILE_DEVICES = ["Android", "IOS"];
|
||||
|
||||
function is_mobile(device) {
|
||||
return MOBILE_DEVICES.indexOf(device) !== -1;
|
||||
}
|
||||
|
||||
var presence_descriptions = {
|
||||
active: 'is active',
|
||||
|
@ -41,6 +49,7 @@ var presence_info = {};
|
|||
|
||||
var huddle_timestamps = new Dict();
|
||||
|
||||
|
||||
exports.process_loaded_messages = function (messages) {
|
||||
_.each(messages, function (message) {
|
||||
if (message.type === 'private') {
|
||||
|
@ -222,7 +231,8 @@ function actually_update_users() {
|
|||
email: email,
|
||||
num_unread: get_num_unread(email),
|
||||
type: presence,
|
||||
type_desc: presence_descriptions[presence]
|
||||
type_desc: presence_descriptions[presence],
|
||||
mobile: presence_info[email].mobile
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -285,19 +295,45 @@ exports.update_huddles = function () {
|
|||
};
|
||||
|
||||
function status_from_timestamp(baseline_time, presence) {
|
||||
if (presence.website === undefined) {
|
||||
return {status: 'offline'};
|
||||
}
|
||||
|
||||
var age = baseline_time - presence.website.timestamp;
|
||||
|
||||
var status = 'offline';
|
||||
if (age < OFFLINE_THRESHOLD_SECS) {
|
||||
status = presence.website.status;
|
||||
}
|
||||
return {status: status};
|
||||
var mobileAvailable = false;
|
||||
var nonmobileAvailable = false;
|
||||
_.each(presence, function (device_presence, device) {
|
||||
var age = baseline_time - device_presence.timestamp;
|
||||
if (is_mobile(device)) {
|
||||
mobileAvailable = device_presence.pushable || mobileAvailable;
|
||||
}
|
||||
if (age < OFFLINE_THRESHOLD_SECS) {
|
||||
switch (device_presence.status) {
|
||||
case 'active':
|
||||
if (is_mobile(device)) {
|
||||
mobileAvailable = true;
|
||||
} else {
|
||||
nonmobileAvailable = true;
|
||||
}
|
||||
status = device_presence.status;
|
||||
break;
|
||||
case 'idle':
|
||||
if (status !== 'active') {
|
||||
status = device_presence.status;
|
||||
}
|
||||
break;
|
||||
case 'offline':
|
||||
if (status !== 'active' && status !== 'idle') {
|
||||
status = device_presence.status;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
blueslip.error('Unexpected status', {'presence_object': device_presence, 'device': device}, undefined);
|
||||
}
|
||||
}
|
||||
});
|
||||
return {status: status, mobile: !nonmobileAvailable && mobileAvailable };
|
||||
}
|
||||
|
||||
// For testing
|
||||
exports._status_from_timestamp = status_from_timestamp;
|
||||
|
||||
function focus_ping() {
|
||||
channel.post({
|
||||
url: '/json/update_active_status',
|
||||
|
|
|
@ -825,6 +825,9 @@ a .icon-vector-flip-vertical:before {
|
|||
.icon-vector-lemon:before {
|
||||
content: "\f094";
|
||||
}
|
||||
.icon-vector-mobile:before {
|
||||
content: "\f10b";
|
||||
}
|
||||
.icon-vector-phone:before {
|
||||
content: "\f095";
|
||||
}
|
||||
|
|
|
@ -444,6 +444,18 @@ a:hover code {
|
|||
border-color: gray;
|
||||
}
|
||||
|
||||
.user-device-indicator {
|
||||
display: block;
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
border-radius: 50%;
|
||||
float: left;
|
||||
position: relative;
|
||||
top: 5px;
|
||||
margin-right: 0.5em;
|
||||
content: "";
|
||||
}
|
||||
|
||||
#user_presences a, #group-pms a {
|
||||
color: #333;
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
<li data-email="{{email}}" class="user_sidebar_entry {{#if num_unread}}user-with-count {{/if}}narrow-filter user_{{type}}">
|
||||
<span class="selectable_sidebar_block">
|
||||
<span class="user-status-indicator"></span>
|
||||
<span class="user-device-indicator{{#if mobile}} icon-vector-mobile{{/if}}"></span>
|
||||
<a href="#" data-email="{{email}}" data-name="{{name}}" title="{{name}} {{type_desc}}"
|
||||
class="{{#if my_fullname}} my_fullname{{/if}}">{{name}}</a>
|
||||
</span>
|
||||
|
|
|
@ -153,3 +153,64 @@ var activity = require('js/activity.js');
|
|||
);
|
||||
}());
|
||||
|
||||
|
||||
(function test_on_mobile_property() {
|
||||
var base_time = 500;
|
||||
var presence = {
|
||||
website: {
|
||||
status: "active",
|
||||
timestamp: base_time
|
||||
}
|
||||
};
|
||||
var status = activity._status_from_timestamp(
|
||||
base_time + activity._OFFLINE_THRESHOLD_SECS - 1, presence
|
||||
);
|
||||
assert.equal(status.mobile, false);
|
||||
|
||||
presence.Android = {
|
||||
status: "active",
|
||||
timestamp: base_time + activity._OFFLINE_THRESHOLD_SECS / 2,
|
||||
pushable: false
|
||||
};
|
||||
status = activity._status_from_timestamp(
|
||||
base_time + activity._OFFLINE_THRESHOLD_SECS, presence
|
||||
);
|
||||
assert.equal(status.mobile, true);
|
||||
assert.equal(status.status, "active");
|
||||
|
||||
status = activity._status_from_timestamp(
|
||||
base_time + activity._OFFLINE_THRESHOLD_SECS - 1, presence
|
||||
);
|
||||
assert.equal(status.mobile, false);
|
||||
assert.equal(status.status, "active");
|
||||
|
||||
status = activity._status_from_timestamp(
|
||||
base_time + activity._OFFLINE_THRESHOLD_SECS * 2, presence
|
||||
);
|
||||
assert.equal(status.mobile, false);
|
||||
assert.equal(status.status, "offline");
|
||||
|
||||
presence.Android = {
|
||||
status: "idle",
|
||||
timestamp: base_time + activity._OFFLINE_THRESHOLD_SECS / 2,
|
||||
pushable: true
|
||||
};
|
||||
status = activity._status_from_timestamp(
|
||||
base_time + activity._OFFLINE_THRESHOLD_SECS, presence
|
||||
);
|
||||
assert.equal(status.mobile, true);
|
||||
assert.equal(status.status, "idle");
|
||||
|
||||
status = activity._status_from_timestamp(
|
||||
base_time + activity._OFFLINE_THRESHOLD_SECS - 1, presence
|
||||
);
|
||||
assert.equal(status.mobile, false);
|
||||
assert.equal(status.status, "active");
|
||||
|
||||
status = activity._status_from_timestamp(
|
||||
base_time + activity._OFFLINE_THRESHOLD_SECS * 2, presence
|
||||
);
|
||||
assert.equal(status.mobile, true);
|
||||
assert.equal(status.status, "offline");
|
||||
|
||||
}());
|
||||
|
|
Loading…
Reference in New Issue