Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions app/assets/stylesheets/player.css
Original file line number Diff line number Diff line change
Expand Up @@ -89,3 +89,19 @@
@apply text-secondary;
animation: pulse 1s infinite;
}

.player--listeners {
@apply text-white text-small w-full flex flex-row items-center bg-primary rounded-md ml-2;
}

.player--listeners--icon {
@apply text-white flex items-center;
}

.player--listeners--icon > svg {
@apply h-5;
}

.player--listeners--count {
@apply ml-1 font-semibold;
}
31 changes: 31 additions & 0 deletions app/channels/listener_channel.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
class ListenerChannel < ApplicationCable::Channel
def subscribed
return unless station.live?

stream_from channel_name
station.change_listeners_count_by(1)
broadcast_listeners_count
end

def unsubscribed
return unless station.live?

stop_all_streams
station.change_listeners_count_by(-1)
broadcast_listeners_count
end

private

def broadcast_listeners_count
ActionCable.server.broadcast channel_name, { listeners: station.current_listeners_count }
end

def channel_name
@_channel_name ||= "listeners-#{station.id}"
end

def station
@_station ||= LiveStation.find(params[:station])
end
end
1 change: 1 addition & 0 deletions app/controllers/live_stations_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ def stop
station = current_user.live_station

station.update!(live: false)
station.reset_listeners_count

Turbo::StreamsChannel.broadcast_update_to station, target: :player, content: ""

Expand Down
1 change: 1 addition & 0 deletions app/javascript/application.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,4 @@ const cable = createCable({
});

start(cable);
import "channels"
6 changes: 6 additions & 0 deletions app/javascript/channels/consumer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
// Action Cable provides the framework to deal with WebSockets in Rails.
// You can generate new channels where WebSocket features live using the `bin/rails generate channel` command.

import { createConsumer } from "@rails/actioncable"

export default createConsumer()
Empty file.
21 changes: 19 additions & 2 deletions app/javascript/controllers/player_controller.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Controller } from "@hotwired/stimulus";
import FakeAudio from "fake_audio";
import { FetchRequest } from "@rails/request.js";
import consumer from "../channels/consumer"

function secondsToDuration(num) {
let mins = Math.floor(num / 60);
Expand All @@ -12,9 +13,9 @@ function secondsToDuration(num) {

// Connects to data-controller="player"
export default class extends Controller {
static targets = ["progress", "time"];
static targets = ["progress", "time", "listeners"];
static outlets = ["track"];
static values = { duration: Number, track: String, nextTrackUrl: String };
static values = { duration: Number, track: String, nextTrackUrl: String, station: Number };
static classes = ["playing"];

initialize() {
Expand Down Expand Up @@ -49,6 +50,22 @@ export default class extends Controller {
if (this.playing) {
this.play();
}

if (this.hasStationValue) {
this.subscribeListenersCount();
}
}

subscribeListenersCount() {
this.channel = consumer.subscriptions.create(
{ channel: "ListenerChannel", station: 1 },
{ station: this.stationValue,
received: (data) => {
if (this.hasListenersTarget) {
this.listenersTarget.textContent = data.listeners;
}
}
});
}

disconnect() {
Expand Down
18 changes: 18 additions & 0 deletions app/models/live_station.rb
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,22 @@ def play_next
end

def current_track = tracks.first

def reset_listeners_count()
litecache.set(cache_key, 0)
end

def change_listeners_count_by(delta)
listeners = current_listeners_count + delta
listeners = 0 if listeners.negative?
litecache.set(cache_key, listeners)
end

def current_listeners_count
litecache.get(cache_key).to_i
end

def litecache
@_litecache ||= Litecache.new
end
end
3 changes: 3 additions & 0 deletions app/views/icons/_listeners.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="w-6 h-6">
<path fill-rule="evenodd" d="M18.685 19.097A9.723 9.723 0 0021.75 12c0-5.385-4.365-9.75-9.75-9.75S2.25 6.615 2.25 12a9.723 9.723 0 003.065 7.097A9.716 9.716 0 0012 21.75a9.716 9.716 0 006.685-2.653zm-12.54-1.285A7.486 7.486 0 0112 15a7.486 7.486 0 015.855 2.812A8.224 8.224 0 0112 20.25a8.224 8.224 0 01-5.855-2.438zM15.75 9a3.75 3.75 0 11-7.5 0 3.75 3.75 0 017.5 0z" clip-rule="evenodd"/>
</svg>
7 changes: 7 additions & 0 deletions app/views/player/_player.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
data-controller="player"
data-player-duration-value="<%= track&.duration %>"
data-player-track-value="<%= track&.id %>"
data-player-station-value="<%= station&.id %>"
data-player-playing-class="player-playing"
data-player-next-track-url-value="<%= live ? play_next_live_station_path : (!station && play_next_track_path(track))%>"
data-player-track-outlet=".track"
Expand Down Expand Up @@ -30,6 +31,12 @@
<%= render "icons/signal" %>
</span>
<%= link_to "Live!", live_station_path, class: "player--title ml-2" %>
<span class="player--listeners pr-1">
<span class="player--listeners--icon">
<%= render "icons/listeners" %>
</span>
<span class="player--listeners--count" data-player-target="listeners"><%= station.current_listeners_count %></span>
</span>
</div>
<% else %>
<div class="player--radio">
Expand Down
2 changes: 2 additions & 0 deletions config/importmap.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,5 @@
pin "nanoevents", to: "https://ga.jspm.io/npm:nanoevents@7.0.1/index.js"
pin "@anycable/web", to: "https://ga.jspm.io/npm:@anycable/web@0.7.0/index.js"
pin "@turbo-boost/commands", to: "https://ga.jspm.io/npm:@turbo-boost/commands@0.0.11/app/assets/builds/@turbo-boost/commands.js"
pin "@rails/actioncable", to: "actioncable.esm.js"
pin_all_from "app/javascript/channels", under: "channels"