Skip to content
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 Quiz expanding between questions #2184

Merged
merged 15 commits into from Mar 14, 2023
Merged

Conversation

itsyme
Copy link
Contributor

@itsyme itsyme commented Feb 23, 2023

What is the purpose of this pull request?

  • Documentation update
  • Bug fix
  • Feature addition or enhancement
  • Code maintenance
  • DevOps
  • Improve developer experience
  • Others, please explain:

Overview of changes:
Resolves #2126. Forces intro/outro cards and questions in Quiz to wait for the previous card to leave before allowing the next card to enter.

Anything you'd like to highlight/discuss:
As a side effect of this PR, gotoNextQuestion in Quiz.vue had to be refactored into two functions,gotoNextQuestion and showNextQuestion, in order for the hiding of the current question and the showing of the next question to be called in two separate places. The transition duration was also reduced to keep the same effect as before.

Testing instructions:

Proposed commit message: (wrap lines at 72 characters)
Fix expanding of Quiz during transition

Cards in Quiz expands during transition from one to the next due to
both cards being rendered in the Quiz.

This could be undesirable as it is an unexpected behaviour for users
and could lead to confusion when doing the Quiz.

Let's make the next card in the Quiz wait for the previous card to
leave before entering.

This will prevent the expansion of the Quiz component as it is
guaranteed that the Quiz will only have one card rendered at any
one time.


Checklist: ☑️

  • Updated the documentation for feature additions and enhancements
  • Added tests for bug fixes or features
  • Linked all related issues
  • No unrelated changes

Copy link
Contributor

@yucheng11122017 yucheng11122017 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @itsyme, thanks for the work on this!
I think the reason why the things in Quiz.spec.js.snap is being deleted is because it hasn't rendered yet after the triggers are triggered. I added await quizTimeOut() to lines 198 and 237 in Quiz.spec.js and it seems to work.
Also I was wondering how did you get 525 for the value of delay?

packages/vue-components/src/questions/Quiz.vue Outdated Show resolved Hide resolved
packages/vue-components/src/__tests__/Quiz.spec.js Outdated Show resolved Hide resolved
@itsyme
Copy link
Contributor Author

itsyme commented Feb 23, 2023

Thanks @yucheng11122017! I got 525 by experimenting. I tried using 500 since the transitions were 0.5s long under styles -> .question in Question.vue, however it seemed to be too short so I increased it till it achieved the desired result!

@itsyme
Copy link
Contributor Author

itsyme commented Feb 23, 2023

Hi @itsyme, thanks for the work on this! I think the reason why the things in Quiz.spec.js.snap is being deleted is because it hasn't rendered yet after the triggers are triggered. I added await quizTimeOut() to lines 198 and 237 in Quiz.spec.js and it seems to work. Also I was wondering how did you get 525 for the value of delay?

Thank you for the feedback! I added await quizTimeOut() to those two lines and it works perfectly now!

Copy link
Contributor

@ang-zeyu ang-zeyu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

flicker

There are some flickering issues introduced by this change.

Presumably because the timeout is timed to be slightly after the transition actually ends.

Consider trying:

  • something better guaranteed https://developer.mozilla.org/en-US/docs/Web/API/Element/transitionend_event (what Vue internally uses also actually)

  • if that alone dosen't work.. (i have no time to browse the spec to check if the new card is introduced right before or after the transition ends...) consider if you really want to be attaching the new card only after the transition of the previous card has finished. (I am personally fine with this, though this changes the UX)

    I believe there are just 2 main cases to consider:

    1. New card's height > old card's height
    2. Old card's height > new card's height

    What can you do in these scenarios?

    The implementation details should be clear after.

// Function to delay test until question is rendered
export default function quizTimeout() {
// eslint-disable-next-line no-promise-executor-return
return new Promise(resolve => setTimeout(resolve, 525));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Timeouts are an easy fix to many issues at first glance but we are making assumptions on browser internals and user device capabilities that are never guaranteed.

(Not to say they should never be used.. there are certainly good use cases, but I strongly don't think this is one of them)

@itsyme
Copy link
Contributor Author

itsyme commented Feb 24, 2023

Hi @ang-zeyu! Thank you for the feedback! I will try out your suggestions in the next commit!

@itsyme
Copy link
Contributor Author

itsyme commented Feb 24, 2023

I managed to overcome this issue by using position: relative for the animation when entering, this allows the incoming question to render in the same place as the previous question. However, since the intro and outro cards are not questions and were not animated, I had to add an animation to them in order to remove the expansion from intro -> first question and last question -> outro. I also realised that the progress bar is being blocked again during the animation from intro -> first question and outro -> first question (when retrying) and am currently working to fix that. I am also considering changing the name of intro-outro-card under style to something more relevant.

@ang-zeyu
Copy link
Contributor

Not sure if it has been updated but there is still some flicker currently:

paneltransitionflicker

@itsyme
Copy link
Contributor Author

itsyme commented Feb 25, 2023

Hi @ang-zeyu! Hmm that is odd. Since I made the change I have not observed this behaviour. May I know which browser you are using so that I may further investigate this issue? Thank you!

@ang-zeyu
Copy link
Contributor

Hi @ang-zeyu! Hmm that is odd. Since I made the change I have not observed this behaviour. May I know which browser you are using so that I may further investigate this issue? Thank you!

Desktop chrome/firefox + mobile chrome on android, it occurs about 50% of the time. Unlike the gif it also occurs on mcq/radio questions (unrelated to a specific type of question).

@lhw-1
Copy link
Contributor

lhw-1 commented Feb 27, 2023

I have tested this on Ubuntu 20.04, on Firefox 109.0.1:

Screencast.from.27-02-2023.12.29.07.webm

And Chromium 110.0.5481.100:
Screencast.from.27-02-2023.12.29.41.webm

Both seem to work fine without flickering.

@jovyntls
Copy link
Contributor

jovyntls commented Feb 27, 2023

Chipping in here on a different environment, I'm getting flickering as well on MacOS with Chrome:

Screen.Recording.2023-02-27.at.4.20.35.PM.mov

And MacOS with FireFox:

Screen.Recording.2023-02-27.at.4.25.14.PM.mov

But it's on and off - can't reproduce it consistently. Also nothing appearing on devtools console 🤔

@jovyntls
Copy link
Contributor

jovyntls commented Feb 27, 2023

@itsyme Try setting throttling using Chrome dev tools (open a mobile view and adjust the throttling option)? I can reproduce the flickering on this branch much more easily when I set throttling to "low-end mobile"
image

Screen.Recording.2023-02-27.at.5.02.57.PM.mov

@itsyme
Copy link
Contributor Author

itsyme commented Feb 27, 2023

Hi @lhw-1 @jovyntls! Thanks for testing it out! My guess is that the previous question's leave transition finishes slightly before the next question's enter transition finishes, leading to the div becoming height 0 for a brief moment. I will try to fix this else I will explore a different approach!

@itsyme
Copy link
Contributor Author

itsyme commented Feb 27, 2023

I managed to solve the issue by changing my approach. However as a side effect of this, gotoNextQuestion in Quiz.vue had to be refactored into two functions, gotoNextQuestion and showNextQuestion, in order for the hiding of the current question and the showing of the next question to be called in two separate places. Also, the animation duration was shortened in order to keep a similar effect to the previous animation, since the next question now waits for the previous question to fully leave before starting its animation.

@itsyme itsyme requested a review from ang-zeyu March 5, 2023 09:55
@ang-zeyu
Copy link
Contributor

@itsyme Sorry for the late response.

This UX is completely fine to me, I don't see any flickering anymore as well.

My guess is that the previous question's leave transition finishes slightly before the next question's enter transition finishes, leading to the div becoming height 0 for a brief moment. I will try to fix this else I will explore a different approach!

If you'd still like to experiment with the original UX outside of this PR,

If I recall previously you were trying to:

I think there's a few other options:

  1. Let the quiz expand/shrink to the next card's height just as the "previous card's transition ends".
    To be exact this can be either:
    • previous card's transition ends - it's still in the DOM so may not be the best option
    • previous card leaves the DOM - worth a try if you can sync the removal of position: absolute on the next card to this.
    • the next card's transition ends - I believe were going for this previously, it is difficult since the previous card leaving the DOM is not synced to this.
  2. A much easier option (I think it would be better UX wise as well) is to immediately let the quiz expand/shrink to the next card's height just as the user clicks "next". Because you can sync position: absolute on the previous card and the introduction of the next card right at the start.
  3. Make all child cards position:absolute inside the quiz, manage the height at the <quiz> level through the transition.

// Function to delay test until question is rendered
function timeoutRenderQuestion() {
// eslint-disable-next-line no-promise-executor-return
return new Promise(resolve => setTimeout(resolve, 350));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there no way to work around using a timeout?

Something like waitForSelector(...).toGoMissing() (imaginary).
Or creating your own simple transition stub.

There are 17 calls here so resolving this should help improve the speed of tests a fair bit. Unless the runner is parallel, I can't remember..

But don't spend too much time on it, 6s to me is still an ok degradation for now. (just create a follow up issue if we can't resolve this).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jovyntls could you help to merge in this MR if it looks good to you? 🙇

@jovyntls jovyntls added this to the v4.1.1 milestone Mar 13, 2023
Copy link
Contributor

@jovyntls jovyntls left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! Nice fix @itsyme, let me know if you'll be adding the tests now or opening a future issue for it - will merge if it's the latter

@itsyme
Copy link
Contributor Author

itsyme commented Mar 13, 2023

LGTM! Nice fix @itsyme, let me know if you'll be adding the tests now or opening a future issue for it - will merge if it's the latter

I will open a new issue for this, thank you @jovyntls!

@jovyntls jovyntls merged commit 33cd541 into MarkBind:master Mar 14, 2023
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Quiz component expanding when transitioning to next question
5 participants