Added api endpoint, front-end code and plugin hook for handling now playing track
This commit is contained in:
parent
44a8c114f1
commit
8e68e69f93
|
@ -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):
|
||||||
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
|
||||||
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"])
|
||||||
|
)
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
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(
|
||||||
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():
|
||||||
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
|
||||||
|
|
||||||
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):
|
||||||
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 {
|
||||||
soundsCache: [],
|
soundsCache: [],
|
||||||
soundId: null,
|
soundId: null,
|
||||||
playTimeout: null,
|
playTimeout: null,
|
||||||
nextTrackPreloaded: false
|
nextTrackPreloaded: false,
|
||||||
|
nowPlayingTimeout: null,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
|
@ -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 {
|
||||||
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 {
|
||||||
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 {
|
||||||
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
|
||||||
|
|
Loading…
Reference in New Issue