Commit d757d48f authored by petitminion's avatar petitminion
Browse files

Add a radio allowing to play various object at the same time. Allow to run Custom Radio Session.

Generate configuration for custom radio session in seach.vue component
parent 7e994e64
Pipeline #18027 failed with stages
in 2 minutes and 58 seconds
......@@ -51,6 +51,8 @@ class RadioSession(models.Model):
related_object = GenericForeignKey(
"related_object_content_type", "related_object_id"
)
CONFIG_VERSION = 0
config = JSONField(encoder=DjangoJSONEncoder, blank=True, null=True)
def save(self, **kwargs):
self.radio.clean(self)
......
import logging
import random
from django.core.exceptions import ValidationError
......@@ -14,6 +15,8 @@ from funkwhale_api.tags.models import Tag
from . import filters, models
from .registries import registry
logger = logging.getLogger(__name__)
class SimpleRadio(object):
related_object_field = None
......@@ -147,6 +150,37 @@ class CustomRadio(SessionRadio):
return data
@registry.register(name="custom_multiple")
class CustomMultiple(SessionRadio):
"""
Receive a vuejs generated config and use it to launch a radio session
"""
config = serializers.JSONField(required=True)
def get_config(self, data):
return data["config"]
def get_queryset_kwargs(self):
kwargs = super().get_queryset_kwargs()
kwargs["config"] = self.session.config
return kwargs
def validate_session(self, data, **context):
data = super().validate_session(data, **context)
try:
data["config"] is not None
except KeyError:
raise serializers.ValidationError(
"You must provide a configuration for this radio"
)
return data
def get_queryset(self, **kwargs):
qs = super().get_queryset(**kwargs)
return filters.run(kwargs["config"], candidates=qs)
class RelatedObjectRadio(SessionRadio):
"""Abstract radio related to an object (tag, artist, user...)"""
......
......@@ -55,7 +55,7 @@ class RadioSessionTrackSerializer(serializers.ModelSerializer):
class RadioSessionSerializer(serializers.ModelSerializer):
related_object_id = serializers.CharField(required=False, allow_null=True)
related_object_id = serializers.JSONField(required=False, allow_null=True)
class Meta:
model = models.RadioSession
......@@ -66,6 +66,7 @@ class RadioSessionSerializer(serializers.ModelSerializer):
"user",
"creation_date",
"custom_radio",
"config",
)
def validate(self, data):
......@@ -89,6 +90,9 @@ class RadioSessionSerializer(serializers.ModelSerializer):
validated_data["related_object"] = radio.get_related_object(
validated_data["related_object_id"]
)
if validated_data.get("config"):
radio = registry[validated_data["radio_type"]]()
validated_data["config"] = radio.get_config(validated_data)
return super().create(validated_data)
def to_representation(self, instance):
......
......@@ -28,7 +28,8 @@ export default {
customRadioId: { type: Number, required: false, default: null },
type: { type: String, required: false, default: '' },
clientOnly: { type: Boolean, default: false },
objectId: { type: [String, Number, Object], default: null }
objectId: { type: [String, Number, Object], default: null },
config : { type: [Array, Object], required: false, default: null}
},
computed: {
running () {
......@@ -50,7 +51,8 @@ export default {
type: this.type,
objectId: this.objectId,
customRadioId: this.customRadioId,
clientOnly: this.clientOnly
clientOnly: this.clientOnly,
config: this.config
})
}
}
......
......@@ -48,14 +48,15 @@ export default {
}
},
actions: {
start ({ commit, dispatch }, { type, objectId, customRadioId, clientOnly }) {
start ({ commit, dispatch }, { type, objectId, customRadioId, clientOnly, config }) {
const params = {
radio_type: type,
related_object_id: objectId,
custom_radio: customRadioId
custom_radio: customRadioId,
config: config
}
if (clientOnly) {
commit('current', { type, objectId, customRadioId, clientOnly })
commit('current', { type, objectId, customRadioId, clientOnly, config })
commit('running', true)
dispatch('populateQueue', true)
return
......
......@@ -22,7 +22,16 @@
<label for="query">
<translate translate-context="Content/Search/Input.Label/Noun">Search</translate>
</label>
<div v-if="type === 'tags' || type === 'artists'" class="ui right floated basic button">
<div class="ui right floated buttons">
<radio-button
type="custom_multiple"
:config="config"
/>
</div>
</div>
</h2>
<form
class="ui form"
@submit.prevent="page = 1; search()"
......@@ -143,10 +152,12 @@ import AlbumCard from '@/components/audio/album/Card'
import TrackTable from '@/components/audio/track/Table'
import Pagination from '@/components/Pagination'
import PlaylistCardList from '@/components/playlists/CardList'
import RadioButton from '@/components/radios/Button'
import RadioCard from '@/components/radios/Card'
import TagsList from '@/components/tags/List'
import axios from 'axios'
import { config } from 'vuedraggable'
export default {
components: {
......@@ -157,6 +168,7 @@ export default {
Pagination,
PlaylistCardList,
RadioCard,
RadioButton,
TagsList
},
props: {
......@@ -181,7 +193,8 @@ export default {
series: null
},
isLoading: false,
paginateBy: 25
paginateBy: 25,
config: null
}
},
computed: {
......@@ -313,6 +326,7 @@ export default {
})
}
})
this.config = this.generateConfig(this.type)
},
updateQueryString: function () {
history.pushState(
......@@ -325,7 +339,23 @@ export default {
type: this.type
}).toString()
)
}
},
generateConfig: function (type) {
let result_dict = this.results[type]["results"]
var names = new Array
for (var name in result_dict) {
if (result_dict.hasOwnProperty(name)) {
names.push(result_dict[name].name)
}
}
var obj = new Object
obj.type = type.slice(0, -1)
obj.names = names
var config = new Array
config.push(obj)
console.log(config)
return config
}
}
}
</script>
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