#39: Playlist Editor #81
@ -2,6 +2,7 @@ import os
 | 
			
		||||
 | 
			
		||||
from django.db import models
 | 
			
		||||
from django.utils.translation import gettext_lazy as _
 | 
			
		||||
from django.utils.functional import cached_property
 | 
			
		||||
 | 
			
		||||
from filer.fields.image import FilerImageField
 | 
			
		||||
 | 
			
		||||
@ -74,6 +75,11 @@ class Station(models.Model):
 | 
			
		||||
 | 
			
		||||
    objects = StationQuerySet.as_manager()
 | 
			
		||||
 | 
			
		||||
    @cached_property
 | 
			
		||||
    def streams(self):
 | 
			
		||||
        """ Audio streams as list of urls. """
 | 
			
		||||
        return self.audio_streams.split('\n') if self.audio_streams else []
 | 
			
		||||
 | 
			
		||||
    def __str__(self):
 | 
			
		||||
        return self.name
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -10807,6 +10807,9 @@ a.navbar-item.is-active {
 | 
			
		||||
.player .player-bar {
 | 
			
		||||
  border-top: 1px hsl(0deg, 0%, 71%) solid;
 | 
			
		||||
}
 | 
			
		||||
.player .player-bar > div {
 | 
			
		||||
  height: 3.75em !important;
 | 
			
		||||
}
 | 
			
		||||
.player .player-bar > .media-left:not(:last-child) {
 | 
			
		||||
  margin-right: 0em;
 | 
			
		||||
}
 | 
			
		||||
@ -10823,7 +10826,8 @@ a.navbar-item.is-active {
 | 
			
		||||
}
 | 
			
		||||
.player .player-bar .button {
 | 
			
		||||
  font-size: 1.5rem !important;
 | 
			
		||||
  height: 2.5em;
 | 
			
		||||
  height: 100%;
 | 
			
		||||
  padding: auto 0.2em !important;
 | 
			
		||||
  min-width: 2.5em;
 | 
			
		||||
  border-radius: 0px;
 | 
			
		||||
  transition: background-color 1s;
 | 
			
		||||
 | 
			
		||||
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							@ -5,12 +5,13 @@ Base template used to display a Page
 | 
			
		||||
 | 
			
		||||
Context:
 | 
			
		||||
- page: page
 | 
			
		||||
- parent: parent page
 | 
			
		||||
{% endcomment %}
 | 
			
		||||
 | 
			
		||||
{% block header_crumbs %}
 | 
			
		||||
{{ block.super }}
 | 
			
		||||
{% if page.category %}
 | 
			
		||||
/ {{ page.category.title }}
 | 
			
		||||
{% if parent %} / {% endif %} {{ page.category.title }}
 | 
			
		||||
{% endif %}
 | 
			
		||||
{% endblock %}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -9,8 +9,9 @@ The audio player
 | 
			
		||||
    role="{% translate "player" %}"
 | 
			
		||||
    aria-description="{% translate "Audio player used to listen to the radio and podcasts" %}">
 | 
			
		||||
    <noscript>
 | 
			
		||||
        <audio src="{{ audio_streams.0 }}" controls>
 | 
			
		||||
            {% for stream in audio_streams %}
 | 
			
		||||
        <audio src="{% if request.station.streams %}{{ request.station.streams.0 }}{% endif %}"
 | 
			
		||||
                controls>
 | 
			
		||||
            {% for stream in request.station.streams %}
 | 
			
		||||
            <source src="{{ stream }}" />
 | 
			
		||||
            {% endfor %}
 | 
			
		||||
        </audio>
 | 
			
		||||
@ -18,7 +19,7 @@ The audio player
 | 
			
		||||
    </noscript>
 | 
			
		||||
 | 
			
		||||
    <a-player ref="player"
 | 
			
		||||
            :live-args="{url: '{% url "api:live" %}', timeout:10, src: {{ audio_streams|json }} || []}"
 | 
			
		||||
            :live-args="{% player_live_attr %}"
 | 
			
		||||
            button-title="{% translate "Play or pause audio" %}">
 | 
			
		||||
        <template v-slot:content="{ loaded, live, current }">
 | 
			
		||||
            <h4 v-if="loaded" class="title is-4">
 | 
			
		||||
 | 
			
		||||
@ -53,6 +53,16 @@ def do_json(obj, fields=""):
 | 
			
		||||
    return json.dumps(obj)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@register.simple_tag(name='player_live_attr', takes_context=True)
 | 
			
		||||
def do_player_live_attr(context):
 | 
			
		||||
    """ Player 'live-args' attribute value """
 | 
			
		||||
    station = getattr(context['request'], 'station', None)
 | 
			
		||||
    return json.dumps({
 | 
			
		||||
        'url': reverse('api:live'),
 | 
			
		||||
        'src': station and station.audio_streams.split('\n')
 | 
			
		||||
    })
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@register.simple_tag(name='nav_items', takes_context=True)
 | 
			
		||||
def do_nav_items(context, menu, **kwargs):
 | 
			
		||||
    """ Render navigation items for the provided menu name. """
 | 
			
		||||
 | 
			
		||||
@ -1,14 +1,10 @@
 | 
			
		||||
 | 
			
		||||
from django.http import Http404
 | 
			
		||||
from django.views.generic import DetailView, ListView
 | 
			
		||||
from django.views.generic.base import TemplateResponseMixin, ContextMixin
 | 
			
		||||
from django.urls import reverse
 | 
			
		||||
 | 
			
		||||
from ..models import Page
 | 
			
		||||
from ..utils import Redirect
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
__all__ = ['BaseView']
 | 
			
		||||
__all__ = ('BaseView', 'BaseAPIView')
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class BaseView(TemplateResponseMixin, ContextMixin):
 | 
			
		||||
@ -55,8 +51,8 @@ class BaseView(TemplateResponseMixin, ContextMixin):
 | 
			
		||||
            kwargs['audio_streams'] = streams
 | 
			
		||||
 | 
			
		||||
        if 'model' not in kwargs:
 | 
			
		||||
            model = getattr(self, 'model', None) or hasattr(self, 'object') and \
 | 
			
		||||
                        type(self.object)
 | 
			
		||||
            model = getattr(self, 'model', None) or \
 | 
			
		||||
                        hasattr(self, 'object') and type(self.object)
 | 
			
		||||
            kwargs['model'] = model
 | 
			
		||||
 | 
			
		||||
        return super().get_context_data(**kwargs)
 | 
			
		||||
 | 
			
		||||
@ -229,6 +229,10 @@ a.navbar-item.is-active {
 | 
			
		||||
    .player-bar {
 | 
			
		||||
        border-top: 1px $grey-light solid;
 | 
			
		||||
 | 
			
		||||
        > div {
 | 
			
		||||
            height: 3.75em !important;
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        > .media-left:not(:last-child) {
 | 
			
		||||
            margin-right: 0em;
 | 
			
		||||
        }
 | 
			
		||||
@ -249,7 +253,8 @@ a.navbar-item.is-active {
 | 
			
		||||
 | 
			
		||||
        .button {
 | 
			
		||||
            font-size: 1.5rem !important;
 | 
			
		||||
            height: 2.5em;
 | 
			
		||||
            height: 100%;
 | 
			
		||||
            padding: auto 0.2em !important;
 | 
			
		||||
            min-width: 2.5em;
 | 
			
		||||
            border-radius: 0px;
 | 
			
		||||
            transition: background-color 1s;
 | 
			
		||||
 | 
			
		||||
@ -52,13 +52,13 @@
 | 
			
		||||
                </button>
 | 
			
		||||
                <button ref="pinPlaylistButton" :class="playlistButtonClass('pin')"
 | 
			
		||||
                        @click="togglePanel('pin')">
 | 
			
		||||
                    <span class="mr-2 is-size-6" v-if="sets.pin.length">
 | 
			
		||||
                    <span class="is-size-6" v-if="sets.pin.length">
 | 
			
		||||
                        {{ sets.pin.length }}</span>
 | 
			
		||||
                    <span class="icon"><span class="fa fa-thumbtack"></span></span>
 | 
			
		||||
                </button>
 | 
			
		||||
                <button :class="playlistButtonClass('queue')"
 | 
			
		||||
                        @click="togglePanel('queue')">
 | 
			
		||||
                    <span class="mr-2 is-size-6" v-if="sets.queue.length">
 | 
			
		||||
                    <span class="is-size-6" v-if="sets.queue.length">
 | 
			
		||||
                        {{ sets.queue.length }}</span>
 | 
			
		||||
                    <span class="icon"><span class="fa fa-list"></span></span>
 | 
			
		||||
                </button>
 | 
			
		||||
@ -186,13 +186,11 @@ export default {
 | 
			
		||||
                if(!item)
 | 
			
		||||
                    throw `No sound at index ${index} for playlist ${playlist}`;
 | 
			
		||||
                this.loaded = item
 | 
			
		||||
                this.current = item
 | 
			
		||||
                src = item.src;
 | 
			
		||||
            }
 | 
			
		||||
            // from live
 | 
			
		||||
            else {
 | 
			
		||||
                this.loaded = null;
 | 
			
		||||
                this.current = this.live.current
 | 
			
		||||
                src = this.live.src;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user