Reset badge count to zero when last active time is bumped

This commit is contained in:
David Baker 2015-01-28 11:55:49 +00:00
parent f7c4daa8f9
commit 273b12729b
4 changed files with 76 additions and 3 deletions

View File

@ -86,6 +86,10 @@ class PresenceHandler(BaseHandler):
"changed_presencelike_data", self.changed_presencelike_data
)
# outbound signal from the presence module to advertise when a user's
# presence has changed
distributor.declare("user_presence_changed")
self.distributor = distributor
self.federation = hs.get_replication_layer()
@ -603,6 +607,7 @@ class PresenceHandler(BaseHandler):
room_ids=room_ids,
statuscache=statuscache,
)
yield self.distributor.fire("user_presence_changed", user, statuscache)
@defer.inlineCallbacks
def _push_presence_remote(self, user, destination, state=None):

View File

@ -54,6 +54,9 @@ class Pusher(object):
self.failing_since = failing_since
self.alive = True
# The last value of last_active_time that we saw
self.last_last_active_time = 0
@defer.inlineCallbacks
def _actions_for_event(self, ev):
"""
@ -273,6 +276,22 @@ class Pusher(object):
"""
pass
def reset_badge_count(self):
pass
def presence_changed(self, state):
"""
We clear badge counts whenever a user's last_active time is bumped
This is by no means perfect but I think it's the best we can do
without read receipts.
"""
if 'last_active' in state.state:
last_active = state.state['last_active']
if last_active > self.last_last_active_time:
logger.info("Resetting badge count for %s", self.user_name)
self.reset_badge_count()
self.last_last_active_time = last_active
def _value_for_dotted_key(dotted_key, event):
parts = dotted_key.split(".")

View File

@ -71,11 +71,12 @@ class HttpPusher(Pusher):
# we may have to fetch this over federation and we
# can't trust it anyway: is it worth it?
#'from_display_name': 'Steve Stevington'
#'counts': { -- we don't mark messages as read yet so
'counts': { #-- we don't mark messages as read yet so
# we have no way of knowing
# 'unread': 1,
# Just set the badge to 1 until we have read receipts
'unread': 1,
# 'missed_calls': 2
# },
},
'devices': [
{
'app_id': self.app_id,
@ -111,3 +112,34 @@ class HttpPusher(Pusher):
if 'rejected' in resp:
rejected = resp['rejected']
defer.returnValue(rejected)
@defer.inlineCallbacks
def reset_badge_count(self):
d = {
'notification': {
'id': '',
'type': None,
'from': '',
'counts': {
'unread': 0,
'missed_calls': 0
},
'devices': [
{
'app_id': self.app_id,
'pushkey': self.pushkey,
'pushkey_ts': long(self.pushkey_ts / 1000),
'data': self.data_minus_url,
}
]
}
}
try:
resp = yield self.httpCli.post_json_get_json(self.url, d)
except:
logger.exception("Failed to push %s ", self.url)
defer.returnValue(False)
rejected = []
if 'rejected' in resp:
rejected = resp['rejected']
defer.returnValue(rejected)

View File

@ -18,6 +18,7 @@ from twisted.internet import defer
from httppusher import HttpPusher
from synapse.push import PusherConfigException
from synapse.api.constants import PresenceState
import logging
import json
@ -32,6 +33,22 @@ class PusherPool:
self.pushers = {}
self.last_pusher_started = -1
distributor = self.hs.get_distributor()
distributor.observe(
"user_presence_changed", self.user_presence_changed
)
@defer.inlineCallbacks
def user_presence_changed(self, user, state):
user_name = user.to_string()
# until we have read receipts, pushers use this to reset a user's
# badge counters to zero
for p in self.pushers.values():
if p.user_name == user_name:
yield p.presence_changed(state)
@defer.inlineCallbacks
def start(self):
pushers = yield self.store.get_all_pushers()