Skip to content

Commit 0f8daa0

Browse files
Lesson 2: small changes
This commit proposes the following: - enables partials rendering in development mode to facilitate debugging - adds a missing colon to a partial - adds check in for ending lesson 2 - fixes a browser's console error when playing the audio: `player_controller.js:5 Uncaught (in promise) NotAllowedError: play() failed because the user didn't interact with the document first.` Having `muted` in the partial didn't fix the issue but wrapping `play()` in a check does. Please let me know if this doesn't look right. There's one issue I'm getting in lesson 2 (and lesson 3) that I couldn't figure it out. When I click in the big play button below the episode's title, I see this error in the browser's console: ``` fetch_requests.js:12 Uncaught TypeError: Cannot read properties of null (reading 'set') ``` After finishing the lesson, I still can't get the big button to work. When I click on it again to pause, it changes the icon but the audio is still playing and clicking on the bottom audio bar doesn't stop the audio either. I couldn't figure out what was missing in the lesson 2 doc but when I change to lesson 3, the buttons are working as expected.
1 parent b3ed538 commit 0f8daa0

File tree

4 files changed

+22
-5
lines changed

4 files changed

+22
-5
lines changed

app/javascript/controllers/player_controller.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,11 @@ import ApplicationController from "controllers/application_controller"
22

33
export default class extends ApplicationController {
44
play() {
5-
this.element.play()
5+
this.element.play().catch((e) => {
6+
window.addEventListener("click", () => {
7+
this.element.play();
8+
});
9+
});
610
}
711

812
toggle() {

app/views/episodes/show.html.erb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@
5454
<div class="mb-[env(safe-area-inset-bottom)] flex flex-1 flex-col gap-3 overflow-hidden p-1">
5555
<%= link_to @episode.title, podcast_episode_path(@episode.podcast, @episode), class: "truncate text-center text-sm font-bold leading-6 md:text-left" %>
5656

57-
<%= audio_tag @episode.audio, id: dom_id(@episode, :audio), class: "w-full", controls: true, muted: Rails.env.test?,
57+
<%= audio_tag @episode.audio, id: dom_id(@episode, :audio), class: "w-full", controls: true,
5858
data: {controller: "player", action: "loadeddata->player#play"} %>
5959
</div>
6060
<% end %>

config/environments/development.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@
6262
# config.i18n.raise_on_missing_translations = true
6363

6464
# Annotate rendered view with file names.
65-
# config.action_view.annotate_rendered_view_with_filenames = true
65+
config.action_view.annotate_rendered_view_with_filenames = true
6666

6767
# Uncomment if you wish to allow Action Cable access from any origin.
6868
# config.action_cable.disable_request_forgery_protection = true

lessons/lesson-2.md

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ the episode that was just clicked.
2929
You'll also note that we add `target: "_top"` to the `<turbo-frame>`. Prior to
3030
that change, any `<a>` or `<form>` elements nested within `<div id="audio">`
3131
would drive the entire page. For example, clicking the Podcast title in the
32-
audio player navigating the whole page to the Podcast in question.
32+
audio player navigates the whole page to the Podcast in question.
3333

3434
Now that those `<a>` and `<form>` elements are nested underneath a
3535
`<turbo-frame>`, their navigations would get "caught" or "trapped", and would
@@ -149,6 +149,8 @@ In short, this just ensures we only load the audio once, even if the play button
149149
is clicked multiple times.
150150

151151
```diff
152+
--- a/app/javascript/controllers/application.js
153+
+++ b/app/javascript/controllers/application.js
152154
+application.registerActionOption("reload", ({ event, value }) => {
153155
+ if (event.type == "submit") {
154156
+ const { submitter, target: form } = event
@@ -203,7 +205,7 @@ export default class extends ApplicationController {
203205
--- a/app/views/episodes/show.html.erb
204206
+++ b/app/views/episodes/show.html.erb
205207
- <%= audio_tag @episode.audio, id: dom_id(@episode, :audio), class: "w-full", controls: true %>
206-
+ <%= audio_tag @episode.audio, id: dom_id(@episode, :audio), class: "w-full", controls: true
208+
+ <%= audio_tag @episode.audio, id: dom_id(@episode, :audio), class: "w-full", controls: true,
207209
+ data: {controller: "player", action: "loadeddata->player#play"} %>
208210
```
209211

@@ -274,13 +276,24 @@ play state. This works because the `playerOutlet` is an instance of a
274276
`player_controller`, which defines a `toggle()` method.
275277

276278
```erb
279+
<%# app/views/episodes/_episode.html.erb %>
277280
data-play-button-player-outlet="#<%= dom_id(episode, :audio) %>"
278281
```
279282

280283
The `play-button` controller synchronizes the `<button>` element's
281284
`[aria-controls]` and `[aria-pressed]` attribute state with any `player`-side
282285
state changes, and routes `click` events to its own `play-button#toggle` action.
283286

287+
### Check in
288+
289+
To complete this lesson:
290+
291+
- run `./bin/rails test` to verify the tests pass
292+
- click on the play buttons in the UI and verify the the audio player is coupled with the multiple
293+
play buttons on the page
294+
295+
When you're ready, move on to the next lesson by running `./ta/start-lesson 3`.
296+
284297
[data-turbo-permanent]: https://turbo.hotwired.dev/handbook/building#persisting-elements-across-page-loads
285298
[turbo-frame]: https://turbo.hotwired.dev/handbook/frames
286299
[data-turbo-frame]: https://turbo.hotwired.dev/handbook/frames#targeting-navigation-into-or-out-of-a-frame

0 commit comments

Comments
 (0)