Resources

Source Code - https://github.com/driftingruby/494-outlets-and-permanent-tags

Honeybadger is a performance monitoring and error tracking tool that combines the best monitoring features into one simple interface that works with all the frameworks you use and comes with fantastic support from a small team of passionate developers. With error tracking, performance and uptime monitoring, log management, dashboards, and more, Honeybadger has everything you need to gain real-time insights into the health of your applications.Keep your apps healthy and your customers happy with Honeybadger! It’s free to get started, and setup takes less than five minutes. Start monitoring today →

Download Source Code

Summary

# Terminal
rails action_text:install
rails g scaffold post title content:rich_text
rails g scaffold music title file:attachment
rails g stimulus track
rails g stimulus music_player

# app/views/musics/index.html.erb
<%# audio_tag url_for(music.file), controls: true if music.file.attached? && music.file.audio? %>
<% if music.file.attached? && music.file.audio? %>
  <div data-controller="track"
    data-track-music-player-outlet="#musicPlayer"
    data-audio-url="<%= url_for(music.file) %>"
    data-audio-title="<%= music.title %>">
  <button data-action="click->track#play:prevent" class="text-blue-600 hover:text-blue-800">
    ▶ Play
  </button>
<% end %>

# app/views/layouts/application.html.erb
<div data-controller="music-player" id="musicPlayer" data-turbo-permanent class="fixed bottom-0 left-0 right-0 bg-gray-900 text-white p-4 flex items-center justify-between hidden">
  <span data-music-player-target="title" class="text-lg font-semibold"></span>
  <audio data-music-player-target="audio" controls class="w-full mx-4"><audio>
<div>

# app/javascript/controllers/music_player_controller.js
import { Controller } from "@hotwired/stimulus"

// Connects to data-controller="music-player"
export default class extends Controller {
  static targets = ["audio", "title"]

  // Option 1
  // playMusic() {
  //   this.audioTarget.play()
  //   this.element.classList.remove("hidden")
  // }

  playMusic(source, title) {
    this.audioTarget.src = source
    this.titleTarget.textContent = title
    this.audioTarget.play()
    this.element.classList.remove("hidden")
  }
}

# app/javascript/controllers/track_controller.js
import { Controller } from "@hotwired/stimulus"

// Connects to data-controller="track"
export default class extends Controller {
  static outlets = ["music-player"]

  play() {
    // Option 1
    // this.musicPlayerOutlet.audioTarget.src = this.element.dataset.audioUrl
    // this.musicPlayerOutlet.titleTarget.textContent = this.element.dataset.audioTitle
    // this.musicPlayerOutlet.playMusic()

    this.musicPlayerOutlet.playMusic(
      this.element.dataset.audioUrl,
      this.element.dataset.audioTitle
    )
  }
}