-
-
Notifications
You must be signed in to change notification settings - Fork 828
Conversation
Splits UserActivity into a tristate of 'active' (last < 1s), 'passive' (lasts a couple of mins) and neither. Read receipts are sent when 'active', read markers are sent while 'passive'. Also fixed a document / window mix-up on the 'blur' handler. Also adds a unit test for UserActivity because it's quite complex now (and changes UserActivity to make it testable by accessing the singleton via sharedInstance() rather than exporting it directly). Fixes element-hq/element-web#9023
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for working on this! 😁 It's a bit tricky to visualise how the sequence of timers winding other timers impacts the UX... 😅 Anyway, that's not really new from this PR.
I think a few of the comments would help clarify, so please take a look.
@@ -439,7 +439,7 @@ async function startMatrixClient() { | |||
dis.dispatch({action: 'will_start_client'}, true); | |||
|
|||
Notifier.start(); | |||
UserActivity.start(); | |||
UserActivity.sharedInstance().start(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess DMRoomMap
below reveals another, slightly different convention for shared instances. In general, the approach of sharedInstance
(to create one if it doesn't exist and return) without a separate getter seems simpler to me.
Maybe there's value in filing an issue to unify approaches for simplicity? The peg style is also related, though not quite the same. Anyway, might be worth having a consistent style, especially if want to add this kind of thing more for testing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point, I'd forgotten about DMRoomMap's approach to singletons. Have filed element-hq/element-web#9090
src/UserActivity.js
Outdated
|
||
/** | ||
* This class watches for user activity (moving the mouse or pressing a key) | ||
* and starts/stops attached timers while the user is active. | ||
* | ||
* There are two classes of 'active' a user can be: 'active' and 'passive': |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's a bit strange naming-wise for there to classes of X, where one of the values is also X. So maybe something like:
* There are two classes of 'active' a user can be: 'active' and 'passive': | |
* There are two classes of 'focused' a user can be: 'active' and 'passive': |
If you agree, we may also want to rename the class to UserFocusTracker
or something...?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mmm, 'focused' makes me think it's more just about tracking whether the window has focus. We could go with Bruno's 'activeActive' and 'passiveActive', or 'activeNow' and 'activeRecently'?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, activeNow
vs. activeRecently
sounds like the clearest so far to me.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Was just about to change this and then realised this would make functions called userCurrentlyActiveNow()
and, even better, userCurrentlyActiveRecently()
. I'll have a think...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe userActiveNowish()
and userActiveRecently()
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I was thinking maybe just userActiveNow()
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right, that could work as well.
src/UserActivity.js
Outdated
document.addEventListener("visibilitychange", this._onPageVisibilityChanged); | ||
window.addEventListener("blur", this._onWindowBlurred); | ||
window.addEventListener("focus", this._onUserActivity); | ||
this._document.onmousedown = this._onUserActivity; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe a good moment to consistently use addEventListener
here as well, rather than a mix of aEL
and on<event>
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ah yes, good point
this._document.onkeydown = this._onUserActivity; | ||
this._document.addEventListener('mousedown', this._onUserActivity); | ||
this._document.addEventListener('mousemove', this._onUserActivity); | ||
this._document.addEventListener('keydown', this._onUserActivity); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for doing this! 😁 We should also change the ones in stop
to call removeEventListener
now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A few things still to fix, I think. I'd like to see how the naming plays out.
(Clearing assignment following recent discussion to stop assigning PRs.) |
also fix more indenting
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's still more to go here to match the new naming, I think. Overall though, I think we have good terminology now. 😁
src/UserActivity.js
Outdated
this._activeTimeout = new Timer(CURRENTLY_ACTIVE_THRESHOLD_MS); | ||
this._passiveTimeout = new Timer(CURRENTLY_PASSIVE_THRESHOLD_MS); | ||
this._activeNowTimeout = new Timer(CURRENTLY_ACTIVE_THRESHOLD_MS); | ||
this._activeRecentlyTimeout = new Timer(CURRENTLY_PASSIVE_THRESHOLD_MS); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These thresholds should likely also be renamed to match as well.
src/UserActivity.js
Outdated
* See userCurrentlyActive() for what it means for a user to be 'active'. | ||
* Runs the given timer while the user is 'active', aborting when the user is no longer | ||
* considered currently active. | ||
* See userActiveNow() for what it means for a user to be 'active'. | ||
* Can be called multiple times with the same already running timer, which is a NO-OP. | ||
* Can be called before the user becomes active, in which case it is only started | ||
* later on when the user does become active. | ||
* @param {Timer} timer the timer to use | ||
*/ | ||
timeWhileActive(timer) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, shouldn't we carry the new naming through to this API as well? We'd then have timeWhileActiveNow
and timeWhileActiveRecently
.
Co-Authored-By: dbkr <[email protected]>
Co-Authored-By: dbkr <[email protected]>
…ix-react-sdk into dbkr/fix_instant_rrs_pt2
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks great! 😁 Thanks for working on the naming changes. I think it's much easier to follow now.
Splits UserActivity into a tristate of 'active' (last < 1s), 'passive' (lasts a
couple of mins) and neither. Read receipts are sent when 'active', read markers
are sent while 'passive'.
Also fixed a document / window mix-up on the 'blur' handler.
Also adds a unit test for UserActivity because it's quite complex now
(and changes UserActivity to make it testable by accessing the singleton
via sharedInstance() rather than exporting it directly).
Fixes element-hq/element-web#9023