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

Adding MuteMusic UI #45632

Merged
merged 32 commits into from May 3, 2022
Merged

Adding MuteMusic UI #45632

merged 32 commits into from May 3, 2022

Conversation

hannahbergam
Copy link
Contributor

@hannahbergam hannahbergam commented Apr 4, 2022

This PR adds a music mute button to starwars and minecraft levels. Other levels are unchanged: only leveltypes with levelTracks loaded into their MusicControllers (i.e. levels with background music separate from the other sounds of the lab) will receive this button. BackgroundMusicMuteButton is a functional component- my first!

This is a long PR, but nearly half of the additions are the creation of the BackgroundMusicMuteButton component. The infrastructure to set up the mute functionality in craft and starwars lie in the craft.js and studio.js files. Though most of this code is repeated across files, this follows the existing patterns: there is no single abstracted craft.js file. If there were, much of the existing lines could be deduped. There are some changes made to the test files as well.

The setting is saved in UserPreferences, meaning the toggle will persist for a given user across levels. To account for signed out users, this preference is also saved as a cookie on the browser. If either of these settings returns 'true', the music will be muted. Upon toggling back to the 'on' state, the cookie is removed.

When a user clicks background music back on, the track plays from the beginning. When the user presses 'mute', the track stops immediately.

There is a firehose event to track this behavior, which records whether the user chose to mute/unmute, and which lab the event occurred on (starwars vs minecraft).

The design of the data flow is atypical and based on the fact that TopInstructions receives all its data from redux. I pass mute and unmute functions through redux that are then called from the component directly.

Images of "On" state:
Screen Shot 2022-04-15 at 11 45 20 AM

Screen Shot 2022-04-15 at 11 45 31 AM

The icon for "Off" has to differ from the spec because we don't have the latest FontAwesome set of icons. Thus, the off button has a volume-off icon instead of the desired 'music-slash'.

Screen Shot 2022-04-18 at 4 20 19 PM

Links

Testing story

I updated the relevant tests in InstructionsTest.js, and added testing in InstructionsHeaderTest.

Deployment strategy

Follow-up work

When FontAwesome is updated, switch the 'off' state icon from 'volume-off' to 'music-slash'. (https://codedotorg.atlassian.net/browse/LP-2323)

Privacy

Security

Caching

PR Checklist:

  • Tests provide adequate coverage
  • Privacy and Security impacts have been assessed
  • Code is well-commented
  • New features are translatable or updates will not break translations
  • Relevant documentation has been added or updated
  • User impact is well-understood and desirable
  • Pull Request is labeled appropriately
  • Follow-up work items (including potential tech debt) are tracked and linked

@hannahbergam hannahbergam requested a review from a team as a code owner April 4, 2022 20:54
@hannahbergam hannahbergam changed the title Adding MuteMusic functionality to Front End Adding MuteMusic UI Apr 4, 2022
@hannahbergam hannahbergam requested review from a team and KylieModen April 19, 2022 23:49
Copy link
Contributor

@KylieModen KylieModen left a comment

Choose a reason for hiding this comment

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

LGTM - also confirmed the firehose event looks good for PM needs

Copy link
Contributor

@jamescodeorg jamescodeorg left a comment

Choose a reason for hiding this comment

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

Phew, nice work piecing this all together! I don't know a lot about this area so I'm learning as I review this.

I think the redux interaction here confuses me and I'm hoping we can simplify that a bit. Let me know if you want to jump on a call to discuss!

apps/src/StudioApp.js Outdated Show resolved Hide resolved
apps/src/StudioApp.js Show resolved Hide resolved
apps/src/craft/agent/craft.js Outdated Show resolved Hide resolved
config.skin.staticAvatar = MEDIA_URL + 'Sliced_Parts/Agent_Neutral.png';
config.skin.smallStaticAvatar =
MEDIA_URL + 'Sliced_Parts/Agent_Neutral.png';
config.skin.failureAvatar = MEDIA_URL + 'Sliced_Parts/Agent_Fail.png';
config.skin.winAvatar = MEDIA_URL + 'Sliced_Parts/Agent_Success.png';
config.level.levelTracks = levelTracks;
Copy link
Contributor

Choose a reason for hiding this comment

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

Sorry, I'm still having a little trouble putting all the pieces together. Why do we need to set this here?

Copy link
Contributor

Choose a reason for hiding this comment

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

If we just need to know if there is background music, maybe set config.level.hasBackgroundMusic instead?

@@ -31,13 +32,18 @@ export const setInitialData = serverUser => ({
type: SET_INITIAL_DATA,
serverUser
});
export const setMuteMusic = isBackgroundMusicMuted => ({
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm curious to hear Maureen's opinion, but I was thinking the current_user api would only provide very limited profile information (but I see we've also since added hasSeenStandardsReportInfo at some point).

I see that we're already sending this information down in user_app_options (which is kind of where I expected it). Why do we also need it here?

Copy link
Contributor

Choose a reason for hiding this comment

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

If it's already being passed from the backend in another place, let's set that value to redux instead of setting it from the API response.

Copy link
Contributor

Choose a reason for hiding this comment

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

@maureensturgeon Do we want to use redux here because that's the pattern in TopInstructions? If it were possible to get the needed data to this component without redux, would that be better or worse?

Copy link
Contributor

Choose a reason for hiding this comment

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

I think what we're trying to avoid by using redux is the prop drilling, there's a lot of room for error with prop drilling and it also is harder to follow

Copy link
Contributor

Choose a reason for hiding this comment

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

If ya'll want to explore what it would take to pass the component data without redux, I definitely think it's worth exploring that though!

@@ -379,7 +379,7 @@ def app_options
@app_options[:experiments] =
Experiment.get_all_enabled(user: current_user, section: section, script: @script).pluck(:name)
@app_options[:usingTextModePref] = !!current_user.using_text_mode
@app_options[:muteMusic] = !!current_user.mute_music
@app_options[:muteMusic] = current_user.mute_music?
Copy link
Contributor

Choose a reason for hiding this comment

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

You may also need to send this down in ApiController#user_app_options somewhere. (Sorry, this code isn't very well factored at the moment.)

@hannahbergam hannahbergam merged commit ac7e17b into staging May 3, 2022
@hannahbergam hannahbergam deleted the hbergam/mute-music branch May 3, 2022 17:55
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.

None yet

4 participants