-
Notifications
You must be signed in to change notification settings - Fork 717
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix #11891 Enhanced Input Mode Detection for Hybrid Devices #11998
Fix #11891 Enhanced Input Mode Detection for Hybrid Devices #11998
Conversation
Sorry @poju3185, I forgot to mention that we are targeting this fix to 0.16. I have retargeted the PR (please ignore the diff from that). Please follow the instructions here: https://kolibri-dev.readthedocs.io/en/develop/howtos/rebasing_a_pull_request.html |
b6d9be7
to
69a7adc
Compare
No worries. I've already rebased the pull request onto the release-v0.16.x branch as instructed. Thank you for the guidance! |
Build Artifacts
|
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.
This definitely works, but I think I'd rather make the API a bit more explicit and hide the implementation details from the API consumer.
@@ -58,6 +58,12 @@ export default class KolibriApp extends KolibriModule { | |||
return {}; | |||
} | |||
|
|||
handlePointerDown(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.
I think I would rather move all of this logic into the browserInfo.js module - and create a simple exportable boolean in there mousePointerUsed
or something like that.
This can be initialized from the localStorage initially, and then we can update both the localStorage and the value when the condition below happens.
@@ -110,6 +116,10 @@ export default class KolibriApp extends KolibriModule { | |||
...this.stateSetters.map(setter => setter(this.store)), | |||
]).then(() => { | |||
this.startRootVue(); | |||
window.addEventListener('pointerdown', this.handlePointerDown.bind(this)); |
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.
This can be done in the module level of browserInfo.js - it will only get executed once, so it feels safe to me.
In terms of unbinding, once we have detected this once, we don't need to be checking any more, so at that point we could remove the event listener.
@@ -144,7 +144,7 @@ | |||
return this.windowBreakpoint < 3; | |||
}, | |||
usesTouch() { | |||
return isTouchDevice; | |||
return isTouchDevice && localStorage.getItem('mouseUsed') !== 'true'; |
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.
As I commented above, let's add a browserInfo exportable variable that will define this value - so that the implementation details are hidden from the code consumer here.
Signed-off-by: PoJuDeSu <[email protected]>
Signed-off-by: PoJuDeSu <[email protected]>
I've made the updates, please notice that |
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.
Just one last thing to have a referent rather than a function for isMouseUsed
.
|
||
window.addEventListener('pointerdown', handlePointerDown); | ||
|
||
export function isMouseUsed() { |
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.
One of the nice things about Javascript exports is that they are referential - this has the nice effect of being able to export dynamic variables from a module.
This means that we don't have to have isMouseUsed
as a function, instead it can be initialized as:
export let isMouseUsed = localStorage.getItem('mouseUsed') === 'true';
|
||
function handlePointerDown(event) { | ||
if (event.pointerType === 'mouse') { | ||
localStorage.setItem('mouseUsed', 'true'); |
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.
Then in here we can do this and:
isMouseUsed = true;
Signed-off-by: PoJuDeSu <[email protected]>
I've made the suggested change to initialize isMouseUsed using the export with the dynamic variable approach. Now the code looks better. |
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.
This looks good! I'll ask our QA team to give it a quick test if possible, just to make sure it's all working as intended.
Hi @rtibbles - I've just tested this on a Chromebook laptop and I can confirm that I can input an answer both when using the touch screen or the trackpad. However when using only the touch screen I still have to type the answer using the physical keyboard of the device while I was expecting to see the onscreen numeric keyboard. The same is valid when I flip the physical keyboard of the Chromebook and start using it as a tablet in which case instead of seeing the onscreen numeric keyboard I see the normal digital keyboard. |
Thanks @pcenov - I think what you describe is sufficient to fix the issue at hand (being able to input at all in this scenario) but we can file a follow up issue for the behaviour that is more responsive to the current state of the device. This more responsive functionality will be significantly harder to implement. |
Follow up filed here: #12016 |
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.
Great work, thank you!
Summary
Fix #11891
This Pull Request introduces an enhancement to the input mode detection logic for devices with both touch and mouse inputs. The core of this update is a global mouse click listener across the app, ensuring that once a mouse click is detected, Perseus will consistently render in standard mode. This approach simplifies the input mode logic and provides a more predictable user experience on hybrid devices.
References
https://stackoverflow.com/a/70827986 provided by @rtibbles
Reviewer guidance
Screen.Recording.2024-03-19.at.10.47.38.AM.mov
Testing checklist
PR process
Reviewer checklist
yarn
andpip
)