Verified Commit 8e68e69f authored by Eliot Berriot's avatar Eliot Berriot
Browse files

Added api endpoint, front-end code and plugin hook for handling now playing track

parent 44a8c114
...@@ -4,6 +4,7 @@ from funkwhale_api import plugins ...@@ -4,6 +4,7 @@ from funkwhale_api import plugins
from funkwhale_api.activity import serializers as activity_serializers from funkwhale_api.activity import serializers as activity_serializers
from funkwhale_api.common import utils from funkwhale_api.common import utils
from funkwhale_api.federation import serializers as federation_serializers from funkwhale_api.federation import serializers as federation_serializers
from funkwhale_api.music import models as music_models
from funkwhale_api.music.serializers import TrackActivitySerializer, TrackSerializer from funkwhale_api.music.serializers import TrackActivitySerializer, TrackSerializer
from funkwhale_api.users.serializers import UserActivitySerializer, UserBasicSerializer from funkwhale_api.users.serializers import UserActivitySerializer, UserBasicSerializer
...@@ -64,3 +65,9 @@ class ListeningWriteSerializer(serializers.ModelSerializer): ...@@ -64,3 +65,9 @@ class ListeningWriteSerializer(serializers.ModelSerializer):
plugins_conf=plugins_conf, plugins_conf=plugins_conf,
) )
return instance return instance
class NowSerializer(serializers.Serializer):
track = serializers.PrimaryKeyRelatedField(
queryset=music_models.Track.objects.all()
)
...@@ -4,3 +4,7 @@ from funkwhale_api import plugins ...@@ -4,3 +4,7 @@ from funkwhale_api import plugins
plugins.hooks.register( plugins.hooks.register(
plugins.Hook("history.listening.created", providing_args=["listening"]) plugins.Hook("history.listening.created", providing_args=["listening"])
) )
plugins.hooks.register(
plugins.Hook("history.listening.now", providing_args=["track", "user"])
)
from rest_framework import mixins, viewsets from rest_framework import mixins, viewsets, response
from rest_framework.decorators import action
from django.db.models import Prefetch from django.db.models import Prefetch
from funkwhale_api import plugins
from funkwhale_api.activity import record from funkwhale_api.activity import record
from funkwhale_api.common import fields, permissions from funkwhale_api.common import fields, permissions, utils
from funkwhale_api.music.models import Track from funkwhale_api.music.models import Track
from funkwhale_api.music import utils as music_utils from funkwhale_api.music import utils as music_utils
from . import filters, models, serializers from . import filters, models, serializers
...@@ -54,3 +56,16 @@ class ListeningViewSet( ...@@ -54,3 +56,16 @@ class ListeningViewSet(
context = super().get_serializer_context() context = super().get_serializer_context()
context["user"] = self.request.user context["user"] = self.request.user
return context return context
@action(methods=["post"], detail=False)
def now(self, request, *args, **kwargs):
serializer = serializers.NowSerializer(data=request.data)
serializer.is_valid(raise_exception=True)
utils.on_commit(
plugins.hooks.dispatch,
"history.listening.now",
user=request.user,
track=serializer.validated_data["track"],
plugins_conf=request.plugins_conf,
)
return response.Response({}, status=204)
...@@ -437,3 +437,9 @@ def plugin_class(): ...@@ -437,3 +437,9 @@ def plugin_class():
def plugin(plugin_class): def plugin(plugin_class):
return plugin_class("test", "test") return plugin_class("test", "test")
@pytest.fixture
def plugins_conf(mocker):
plugins_conf = mocker.patch("funkwhale_api.plugins.generate_plugins_conf")
return plugins_conf.return_value
...@@ -2,6 +2,8 @@ import pytest ...@@ -2,6 +2,8 @@ import pytest
from django.urls import reverse from django.urls import reverse
from funkwhale_api import plugins
@pytest.mark.parametrize("level", ["instance", "me", "followers"]) @pytest.mark.parametrize("level", ["instance", "me", "followers"])
def test_privacy_filter(preferences, level, factories, api_client): def test_privacy_filter(preferences, level, factories, api_client):
...@@ -11,3 +13,20 @@ def test_privacy_filter(preferences, level, factories, api_client): ...@@ -11,3 +13,20 @@ def test_privacy_filter(preferences, level, factories, api_client):
response = api_client.get(url) response = api_client.get(url)
assert response.status_code == 200 assert response.status_code == 200
assert response.data["count"] == 0 assert response.data["count"] == 0
def test_now(factories, logged_in_api_client, plugins_conf, mocker):
track = factories["music.Track"]()
url = reverse("api:v1:history:listenings-now")
on_commit = mocker.patch("funkwhale_api.common.utils.on_commit")
response = logged_in_api_client.post(url, {"track": track.pk})
on_commit.assert_called_once_with(
plugins.hooks.dispatch,
"history.listening.now",
track=track,
user=logged_in_api_client.user,
plugins_conf=plugins_conf,
)
assert response.status_code == 204
...@@ -266,7 +266,8 @@ export default { ...@@ -266,7 +266,8 @@ export default {
soundsCache: [], soundsCache: [],
soundId: null, soundId: null,
playTimeout: null, playTimeout: null,
nextTrackPreloaded: false nextTrackPreloaded: false,
nowPlayingTimeout: null,
} }
}, },
mounted() { mounted() {
...@@ -408,6 +409,11 @@ export default { ...@@ -408,6 +409,11 @@ export default {
}) })
}, },
onplay: function () { onplay: function () {
if (trackData.id === self.currentTrack.id) {
self.nowPlayingTimeout = setTimeout(() => {
self.$store.dispatch('player/nowPlaying', trackData)
}, 5000)
}
self.$store.commit('player/isLoadingAudio', false) self.$store.commit('player/isLoadingAudio', false)
self.$store.commit('player/resetErrorCount') self.$store.commit('player/resetErrorCount')
self.$store.commit('player/errored', false) self.$store.commit('player/errored', false)
...@@ -713,6 +719,9 @@ export default { ...@@ -713,6 +719,9 @@ export default {
watch: { watch: {
currentTrack: { currentTrack: {
async handler (newValue, oldValue) { async handler (newValue, oldValue) {
if (this.nowPlayingTimeout) {
clearTimeout(this.nowPlayingTimeout)
}
if (newValue === oldValue) { if (newValue === oldValue) {
return return
} }
...@@ -746,6 +755,9 @@ export default { ...@@ -746,6 +755,9 @@ export default {
if (newValue === true) { if (newValue === true) {
this.soundId = this.currentSound.play(this.soundId) this.soundId = this.currentSound.play(this.soundId)
} else { } else {
if (this.nowPlayingTimeout) {
clearTimeout(this.nowPlayingTimeout)
}
this.currentSound.pause(this.soundId) this.currentSound.pause(this.soundId)
} }
} else { } else {
......
...@@ -126,6 +126,14 @@ export default { ...@@ -126,6 +126,14 @@ export default {
logger.default.error('Could not record track in history') logger.default.error('Could not record track in history')
}) })
}, },
nowPlaying ({commit, rootState}, trackData) {
if (!rootState.auth.authenticated) {
return
}
return axios.post('history/listenings/now/', {'track': trackData.id}).then((response) => {}, (response) => {
logger.default.error('Could not set track as now playing')
})
},
trackEnded ({dispatch, rootState}, track) { trackEnded ({dispatch, rootState}, track) {
dispatch('trackListened', track) dispatch('trackListened', track)
let queueState = rootState.queue let queueState = rootState.queue
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment