forked from rc/aircox
		
	work on player
This commit is contained in:
		
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							@ -1,6 +1,16 @@
 | 
				
			|||||||
{% extends "aircox/page_detail.html" %}
 | 
					{% extends "aircox/page_detail.html" %}
 | 
				
			||||||
{% comment %}List of a show's episodes for a specific{% endcomment %}
 | 
					{% comment %}List of a show's episodes for a specific{% endcomment %}
 | 
				
			||||||
{% load i18n %}
 | 
					{% load i18n aircox %}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					{% block head_extra %}
 | 
				
			||||||
 | 
					<script id="page">
 | 
				
			||||||
 | 
					    window.addEventListener('load', ev => {
 | 
				
			||||||
 | 
					        Vue.set(aircox.app, 'page', {
 | 
				
			||||||
 | 
					                podcasts: new aircox.Set(aircox.Sound, {items: {{ podcasts|json|safe }}})
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					</script>
 | 
				
			||||||
 | 
					{% endblock head_extra %}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
{% include "aircox/program_sidebar.html" %}
 | 
					{% include "aircox/program_sidebar.html" %}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -38,10 +48,19 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    {% if podcasts %}
 | 
					    {% if podcasts %}
 | 
				
			||||||
    <section class="column">
 | 
					    <section class="column">
 | 
				
			||||||
        <h5 class="title is-5">{% trans "Podcasts" %}</h5>
 | 
					        <a-playlist v-if="page" :set="page.podcasts"
 | 
				
			||||||
 | 
					            name="{{ page.title }}"
 | 
				
			||||||
 | 
					            :player="player" :actions="['play']"
 | 
				
			||||||
 | 
					            @select="player.playItems('queue', $event.item)">
 | 
				
			||||||
 | 
					            <template v-slot:header>
 | 
				
			||||||
 | 
					                <h5 class="title is-5">{% trans "Podcasts" %}</h5>
 | 
				
			||||||
 | 
					            </template>
 | 
				
			||||||
 | 
					        </a-playlist>
 | 
				
			||||||
 | 
					        {% comment %}
 | 
				
			||||||
        {% for object in podcasts %}
 | 
					        {% for object in podcasts %}
 | 
				
			||||||
        {% include "aircox/widgets/podcast_item.html" %}
 | 
					        {% include "aircox/widgets/podcast_item.html" %}
 | 
				
			||||||
        {% endfor %}
 | 
					        {% endfor %}
 | 
				
			||||||
 | 
					        {% endcomment %}
 | 
				
			||||||
    </section>
 | 
					    </section>
 | 
				
			||||||
    {% endif %}
 | 
					    {% endif %}
 | 
				
			||||||
</div>
 | 
					</div>
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										8
									
								
								aircox/templates/aircox/program_sidebar.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								aircox/templates/aircox/program_sidebar.html
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,8 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					{% block sidebar_title %}
 | 
				
			||||||
 | 
					{% with program.title as program %}
 | 
				
			||||||
 | 
					{% blocktrans %}Recently on {{ program }}{% endblocktrans %}
 | 
				
			||||||
 | 
					{% endwith %}
 | 
				
			||||||
 | 
					{% endblock %}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -12,7 +12,7 @@ List item for a podcast.
 | 
				
			|||||||
    {% endif %}
 | 
					    {% endif %}
 | 
				
			||||||
    {% endcomment %}
 | 
					    {% endcomment %}
 | 
				
			||||||
    <a-sound-item :data="{{ object|json }}" :player="player"
 | 
					    <a-sound-item :data="{{ object|json }}" :player="player"
 | 
				
			||||||
        :actions="['play','queue']" @click="player.play(item)">
 | 
					        :actions="['play']" @click="player.play(item)">
 | 
				
			||||||
    </a-sound-item>
 | 
					    </a-sound-item>
 | 
				
			||||||
</div>
 | 
					</div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -2,6 +2,7 @@ import random
 | 
				
			|||||||
import json
 | 
					import json
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from django import template
 | 
					from django import template
 | 
				
			||||||
 | 
					from django.utils.safestring import mark_safe
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from aircox.models import Page, Diffusion, Log
 | 
					from aircox.models import Page, Diffusion, Log
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -5,14 +5,18 @@ export const defaultConfig = {
 | 
				
			|||||||
    el: '#app',
 | 
					    el: '#app',
 | 
				
			||||||
    delimiters: ['[[', ']]'],
 | 
					    delimiters: ['[[', ']]'],
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    computed: {
 | 
					    data() {
 | 
				
			||||||
        player() {
 | 
					        return {
 | 
				
			||||||
            return window.aircox.player;
 | 
					            page: null,
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    computed: {
 | 
				
			||||||
 | 
					        player() { return window.aircox.player; }
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export function App(config) {
 | 
					export default function App(config) {
 | 
				
			||||||
    return (new AppConfig(config)).load()
 | 
					    return (new AppConfig(config)).load()
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -10,16 +10,20 @@ import '@fortawesome/fontawesome-free/css/fontawesome.min.css';
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//-- aircox
 | 
					//-- aircox
 | 
				
			||||||
import {App} from './app';
 | 
					import App from './app';
 | 
				
			||||||
 | 
					import Sound from './sound';
 | 
				
			||||||
 | 
					import {Set} from './model';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import './styles.scss';
 | 
					import './styles.scss';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import Autocomplete from './autocomplete.vue';
 | 
					import Autocomplete from './autocomplete.vue';
 | 
				
			||||||
import Player from './player.vue';
 | 
					import Player from './player.vue';
 | 
				
			||||||
 | 
					import Playlist from './playlist.vue';
 | 
				
			||||||
import SoundItem from './soundItem';
 | 
					import SoundItem from './soundItem';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Vue.component('a-autocomplete', Autocomplete)
 | 
					Vue.component('a-autocomplete', Autocomplete)
 | 
				
			||||||
Vue.component('a-player', Player)
 | 
					Vue.component('a-player', Player)
 | 
				
			||||||
 | 
					Vue.component('a-playlist', Playlist)
 | 
				
			||||||
Vue.component('a-sound-item', SoundItem)
 | 
					Vue.component('a-sound-item', SoundItem)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -36,8 +40,11 @@ window.aircox = {
 | 
				
			|||||||
    // player component
 | 
					    // player component
 | 
				
			||||||
    get player() {
 | 
					    get player() {
 | 
				
			||||||
        return this.playerApp && this.playerApp.$refs.player
 | 
					        return this.playerApp && this.playerApp.$refs.player
 | 
				
			||||||
    }
 | 
					    },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Set: Set, Sound: Sound,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					window.Vue = Vue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
App({el: '#player'}).then(app => window.aircox.playerApp = app,
 | 
					App({el: '#player'}).then(app => window.aircox.playerApp = app,
 | 
				
			||||||
 | 
				
			|||||||
@ -2,13 +2,11 @@
 | 
				
			|||||||
    <div>
 | 
					    <div>
 | 
				
			||||||
        <slot name="header"></slot>
 | 
					        <slot name="header"></slot>
 | 
				
			||||||
        <ul :class="listClass">
 | 
					        <ul :class="listClass">
 | 
				
			||||||
            <slot name="start"></slot>
 | 
					 | 
				
			||||||
            <template v-for="(item,index) in items">
 | 
					            <template v-for="(item,index) in items">
 | 
				
			||||||
                <li :class="itemClass" @click="select(index)">
 | 
					                <li :class="itemClass" @click="select(index)">
 | 
				
			||||||
                    <slot name="item" :set="set" :index="index" :item="item"></slot>
 | 
					                    <slot name="item" :selected="index == selectedIndex" :set="set" :index="index" :item="item"></slot>
 | 
				
			||||||
                </li>
 | 
					                </li>
 | 
				
			||||||
            </template>
 | 
					            </template>
 | 
				
			||||||
            <slot name="end"></slot>
 | 
					 | 
				
			||||||
        </ul>
 | 
					        </ul>
 | 
				
			||||||
        <slot name="footer"></slot>
 | 
					        <slot name="footer"></slot>
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
@ -17,14 +15,14 @@
 | 
				
			|||||||
export default {
 | 
					export default {
 | 
				
			||||||
    data() {
 | 
					    data() {
 | 
				
			||||||
        return {
 | 
					        return {
 | 
				
			||||||
            selectedIndex: this.default,
 | 
					            selectedIndex: this.defaultIndex,
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    props: {
 | 
					    props: {
 | 
				
			||||||
        listClass: String,
 | 
					        listClass: String,
 | 
				
			||||||
        itemClass: String,
 | 
					        itemClass: String,
 | 
				
			||||||
        default: { type: Number, default: -1},
 | 
					        defaultIndex: { type: Number, default: -1},
 | 
				
			||||||
        set: Object,
 | 
					        set: Object,
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -34,31 +32,37 @@ export default {
 | 
				
			|||||||
        length() { return this.set.length },
 | 
					        length() { return this.set.length },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        selected() {
 | 
					        selected() {
 | 
				
			||||||
            return this.items && this.items.length > this.selectedIndex > -1
 | 
					            return this.selectedIndex > -1 && this.items.length > this.selectedIndex > -1
 | 
				
			||||||
                ? this.items[this.selectedIndex] : null;
 | 
					                ? this.items[this.selectedIndex] : null;
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    methods: {
 | 
					    methods: {
 | 
				
			||||||
        select(index=null) {
 | 
					        get(index) { return this.set.get(index) },
 | 
				
			||||||
            if(index === null)
 | 
					        find(item) { return this.set.find(item) },
 | 
				
			||||||
                index = this.selectedIndex;
 | 
					        findIndex(item) { return this.set.findIndex(item) },
 | 
				
			||||||
            else if(this.selectedIndex == index)
 | 
					 | 
				
			||||||
                return;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
            this.selectedIndex = Math.min(index, this.items.length-1);
 | 
					        push(...items) {
 | 
				
			||||||
            this.$emit('select', { item: this.selected, index: this.selectedIndex });
 | 
					            let index = this.set.length;
 | 
				
			||||||
 | 
					            for(var item of items)
 | 
				
			||||||
 | 
					                this.set.push(item);
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        remove(index, select=False) {
 | 
				
			||||||
 | 
					            this.set.remove(index);
 | 
				
			||||||
 | 
					            if(index < this.selectedIndex)
 | 
				
			||||||
 | 
					                this.selectedIndex--;
 | 
				
			||||||
 | 
					            if(select && this.selectedIndex == index)
 | 
				
			||||||
 | 
					                this.select(index)
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        select(index) {
 | 
				
			||||||
 | 
					            this.selectedIndex = index > -1  && this.items.length ? index % this.items.length : -1;
 | 
				
			||||||
 | 
					            this.$emit('select', { target: this, item: this.selected, index: this.selectedIndex });
 | 
				
			||||||
            return this.selectedIndex;
 | 
					            return this.selectedIndex;
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        selectNext() {
 | 
					 | 
				
			||||||
            let index = this.selectedIndex + 1;
 | 
					 | 
				
			||||||
            return this.select(index >= this.items.length ? -1 : index);
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // add()
 | 
					 | 
				
			||||||
        // insert() + drag & drop
 | 
					 | 
				
			||||||
        // remove()
 | 
					 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
</script>
 | 
					</script>
 | 
				
			||||||
 | 
				
			|||||||
@ -107,16 +107,19 @@ export default class Model {
 | 
				
			|||||||
 */
 | 
					 */
 | 
				
			||||||
export class Set {
 | 
					export class Set {
 | 
				
			||||||
    constructor(model, {items=[],url=null,args={},unique=null,max=null,storeKey=null}={}) {
 | 
					    constructor(model, {items=[],url=null,args={},unique=null,max=null,storeKey=null}={}) {
 | 
				
			||||||
        this.items = items.map(x => x instanceof model ? x : new model(x, args));
 | 
					        this.items = [];
 | 
				
			||||||
        this.model = model;
 | 
					        this.model = model;
 | 
				
			||||||
        this.url = url;
 | 
					        this.url = url;
 | 
				
			||||||
        this.unique = unique;
 | 
					        this.unique = unique;
 | 
				
			||||||
        this.max = max;
 | 
					        this.max = max;
 | 
				
			||||||
        this.storeKey = storeKey;
 | 
					        this.storeKey = storeKey;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        for(var item of items)
 | 
				
			||||||
 | 
					            this.push(item, {args: args, save: false});
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    get length() { return this.items.length }
 | 
					    get length() { return this.items.length }
 | 
				
			||||||
    indexOf(...args) { return this.items.indexOf(...args); }
 | 
					    get(index) { return this.items[index] }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Fetch multiple items from server
 | 
					     * Fetch multiple items from server
 | 
				
			||||||
@ -141,35 +144,54 @@ export class Set {
 | 
				
			|||||||
     * Store list into localStorage
 | 
					     * Store list into localStorage
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    store() {
 | 
					    store() {
 | 
				
			||||||
        if(this.storeKey)
 | 
					        this.storeKey && window.localStorage.setItem(this.storeKey, JSON.stringify(
 | 
				
			||||||
            window.localStorage.setItem(this.storeKey, JSON.stringify(
 | 
					            this.items.map(i => i.data)));
 | 
				
			||||||
                this.items.map(i => i.data)));
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    push(item, {args={}}={}) {
 | 
					    /**
 | 
				
			||||||
 | 
					     * Save item
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    save() {
 | 
				
			||||||
 | 
					        this.storeKey && this.store();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Find item by id
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    find(item) {
 | 
				
			||||||
 | 
					        return this.items.find(x => x.id == item.id);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Find item index by id
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    findIndex(item) {
 | 
				
			||||||
 | 
					        return this.items.findIndex(x => x.id == item.id);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Add item to set
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    push(item, {args={},save=true}={}) {
 | 
				
			||||||
        item = item instanceof this.model ? item : new this.model(item, args);
 | 
					        item = item instanceof this.model ? item : new this.model(item, args);
 | 
				
			||||||
        if(this.unique && this.items.find(x => x.id == item.id))
 | 
					        if(this.unique) {
 | 
				
			||||||
            return;
 | 
					            let index = this.findIndex(item);
 | 
				
			||||||
 | 
					            if(index > -1)
 | 
				
			||||||
 | 
					                this.items.splice(index,1);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
        if(this.max && this.items.length >= this.max)
 | 
					        if(this.max && this.items.length >= this.max)
 | 
				
			||||||
            this.items.splice(0,this.items.length-this.max)
 | 
					            this.items.splice(0,this.items.length-this.max)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        this.items.push(item);
 | 
					        this.items.push(item);
 | 
				
			||||||
        this._updated()
 | 
					        save && this.save();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    remove(item, {args={}}={}) {
 | 
					    /**
 | 
				
			||||||
        item = item instanceof this.model ? item : new this.model(item, args);
 | 
					     * Remove item from set by index
 | 
				
			||||||
        let index = this.items.findIndex(x => x.id == item.id);
 | 
					     */
 | 
				
			||||||
        if(index == -1)
 | 
					    remove(index, {save=true}={}) {
 | 
				
			||||||
            return;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        this.items.splice(index,1);
 | 
					        this.items.splice(index,1);
 | 
				
			||||||
        this._updated()
 | 
					        save && this.save();
 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    _updated() {
 | 
					 | 
				
			||||||
        Vue.set(this, 'items', this.items);
 | 
					 | 
				
			||||||
        this.store();
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -1,39 +1,38 @@
 | 
				
			|||||||
<template>
 | 
					<template>
 | 
				
			||||||
    <div class="player">
 | 
					    <div class="player">
 | 
				
			||||||
        <List ref="queue" class="player-panel menu" v-show="panel == 'queue' && queue.length"
 | 
					        <Playlist ref="history" class="panel-menu menu" v-show="panel == 'history'"
 | 
				
			||||||
            :set="queue" @select="onSelect" 
 | 
					            name="History"
 | 
				
			||||||
 | 
					            :editable="true" :player="self" :set="sets.history" @select="play('pin', $event.index)"
 | 
				
			||||||
            listClass="menu-list" itemClass="menu-item">
 | 
					            listClass="menu-list" itemClass="menu-item">
 | 
				
			||||||
            <template v-slot:header>
 | 
					            <template v-slot:header="">
 | 
				
			||||||
                <p class="menu-label">
 | 
					 | 
				
			||||||
                    <span class="icon"><span class="fa fa-list"></span></span>
 | 
					 | 
				
			||||||
                    Playlist
 | 
					 | 
				
			||||||
                </p>
 | 
					 | 
				
			||||||
            </template>
 | 
					 | 
				
			||||||
            <template v-slot:item="{item,index,set}">
 | 
					 | 
				
			||||||
                <SoundItem activeClass="is-active" :data="item" :player="self" :set="set"
 | 
					 | 
				
			||||||
                    :actions="['remove']">
 | 
					 | 
				
			||||||
                    <template v-slot:actions="{active,set}">
 | 
					 | 
				
			||||||
                        <!-- TODO: stop player if active -->
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                    </template>
 | 
					 | 
				
			||||||
                </SoundItem>
 | 
					 | 
				
			||||||
            </template>
 | 
					 | 
				
			||||||
        </List>
 | 
					 | 
				
			||||||
        <List ref="history" class="player-panel menu" v-show="panel == 'history' && history.length"
 | 
					 | 
				
			||||||
            :set="history" @select="onSelect"
 | 
					 | 
				
			||||||
            listClass="menu-list" itemClass="menu-item">
 | 
					 | 
				
			||||||
            <template v-slot:header>
 | 
					 | 
				
			||||||
                <p class="menu-label">
 | 
					                <p class="menu-label">
 | 
				
			||||||
                    <span class="icon"><span class="fa fa-clock"></span></span>
 | 
					                    <span class="icon"><span class="fa fa-clock"></span></span>
 | 
				
			||||||
                    History
 | 
					                    History
 | 
				
			||||||
                </p>
 | 
					                </p>
 | 
				
			||||||
            </template>
 | 
					            </template>
 | 
				
			||||||
            <template v-slot:item="{item,index,set}">
 | 
					        </Playlist>
 | 
				
			||||||
                <SoundItem activeClass="is-active" :data="item" :player="self" :set="set"
 | 
					        <Playlist ref="pin" class="player-panel menu" v-show="panel == 'pin'"
 | 
				
			||||||
                    :actions="['queue','remove']">
 | 
					            name="Pinned"
 | 
				
			||||||
                </SoundItem>
 | 
					            :editable="true" :player="self" :set="sets.pin" @select="play('pin', $event.index)" 
 | 
				
			||||||
 | 
					            listClass="menu-list" itemClass="menu-item">
 | 
				
			||||||
 | 
					            <template v-slot:header="">
 | 
				
			||||||
 | 
					                <p class="menu-label">
 | 
				
			||||||
 | 
					                    <span class="icon"><span class="fa fa-thumbtack"></span></span>
 | 
				
			||||||
 | 
					                    Pinned
 | 
				
			||||||
 | 
					                </p>
 | 
				
			||||||
            </template>
 | 
					            </template>
 | 
				
			||||||
        </List>
 | 
					        </Playlist>
 | 
				
			||||||
 | 
					        <Playlist ref="queue" class="player-panel menu" v-show="panel == 'queue'"
 | 
				
			||||||
 | 
					            :editable="true" :player="self" :set="sets.queue" @select="play('queue', $event.index)" 
 | 
				
			||||||
 | 
					            listClass="menu-list" itemClass="menu-item">
 | 
				
			||||||
 | 
					            <template v-slot:header="">
 | 
				
			||||||
 | 
					                <p class="menu-label">
 | 
				
			||||||
 | 
					                    <span class="icon"><span class="fa fa-list"></span></span>
 | 
				
			||||||
 | 
					                    Playlist
 | 
				
			||||||
 | 
					                </p>
 | 
				
			||||||
 | 
					            </template>
 | 
				
			||||||
 | 
					        </Playlist>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        <div class="player-bar media">
 | 
					        <div class="player-bar media">
 | 
				
			||||||
            <div class="media-left">
 | 
					            <div class="media-left">
 | 
				
			||||||
                <div class="button" @click="togglePlay()"
 | 
					                <div class="button" @click="togglePlay()"
 | 
				
			||||||
@ -53,26 +52,31 @@
 | 
				
			|||||||
                <slot name="content" :current="current"></slot>
 | 
					                <slot name="content" :current="current"></slot>
 | 
				
			||||||
            </div>
 | 
					            </div>
 | 
				
			||||||
            <div class="media-right">
 | 
					            <div class="media-right">
 | 
				
			||||||
                <button class="button" v-if="active" @click="load() && play()">
 | 
					                <button class="button has-text-weight-bold" v-if="loaded" @click="playLive()">
 | 
				
			||||||
                    <span class="icon has-text-danger">
 | 
					                    <span class="icon has-text-danger">
 | 
				
			||||||
                        <span class="fa fa-broadcast-tower"></span>
 | 
					                        <span class="fa fa-broadcast-tower"></span>
 | 
				
			||||||
                    </span>
 | 
					                    </span>
 | 
				
			||||||
                    <span>Live</span>
 | 
					                    <span>Live</span>
 | 
				
			||||||
                </button>
 | 
					                </button>
 | 
				
			||||||
 | 
					                <button :class="playlistButtonClass('history')"
 | 
				
			||||||
                <button class="button" v-if="history.length"
 | 
					                        @click="togglePanel('history')">
 | 
				
			||||||
                    @click="togglePanel('history')"
 | 
					                    <span class="mr-2 is-size-6" v-if="sets.history.length">
 | 
				
			||||||
                    :class="[panel == 'history' ? 'is-info' : '']" >
 | 
					                        {{ sets.history.length }}</span>
 | 
				
			||||||
                    <span class="icon">
 | 
					                    <span class="icon"><span class="fa fa-clock"></span></span>
 | 
				
			||||||
                        <span class="fa fa-clock"></span>
 | 
					 | 
				
			||||||
                    </span>
 | 
					 | 
				
			||||||
                </button>
 | 
					                </button>
 | 
				
			||||||
                <button class="button" v-if="queue.length"
 | 
					                <button :class="playlistButtonClass('pin')"
 | 
				
			||||||
                    @click="togglePanel('queue')"
 | 
					                        @click="togglePanel('pin')">
 | 
				
			||||||
                    :class="[panel == 'queue' ? 'is-info' : '']" >
 | 
					                    <span class="mr-2 is-size-6" v-if="sets.pin.length">
 | 
				
			||||||
                    <span class="mr-2 is-size-6">{{ queue.length }}</span>
 | 
					                        {{ 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">
 | 
				
			||||||
 | 
					                        {{ sets.queue.length }}</span>
 | 
				
			||||||
                    <span class="icon"><span class="fa fa-list"></span></span>
 | 
					                    <span class="icon"><span class="fa fa-list"></span></span>
 | 
				
			||||||
                </button>
 | 
					                </button>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            </div>
 | 
					            </div>
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
        <div v-if="progress">
 | 
					        <div v-if="progress">
 | 
				
			||||||
@ -84,8 +88,7 @@
 | 
				
			|||||||
<script>
 | 
					<script>
 | 
				
			||||||
import Vue, { ref } from 'vue';
 | 
					import Vue, { ref } from 'vue';
 | 
				
			||||||
import Live from './live';
 | 
					import Live from './live';
 | 
				
			||||||
import List from './list';
 | 
					import Playlist from './playlist';
 | 
				
			||||||
import SoundItem from './soundItem';
 | 
					 | 
				
			||||||
import Sound from './sound';
 | 
					import Sound from './sound';
 | 
				
			||||||
import {Set} from './model';
 | 
					import {Set} from './model';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -100,11 +103,20 @@ export default {
 | 
				
			|||||||
    data() {
 | 
					    data() {
 | 
				
			||||||
        return {
 | 
					        return {
 | 
				
			||||||
            state: State.paused,
 | 
					            state: State.paused,
 | 
				
			||||||
            active: null,
 | 
					            /// Loaded item
 | 
				
			||||||
 | 
					            loaded: null,
 | 
				
			||||||
 | 
					            /// Live instance
 | 
				
			||||||
            live: this.liveArgs ? new Live(this.liveArgs) : null,
 | 
					            live: this.liveArgs ? new Live(this.liveArgs) : null,
 | 
				
			||||||
 | 
					            //! Active panel name
 | 
				
			||||||
            panel: null,
 | 
					            panel: null,
 | 
				
			||||||
            queue: Set.storeLoad(Sound, "player.queue", { max: 30, unique: true }),
 | 
					            //! current playing playlist component
 | 
				
			||||||
            history: Set.storeLoad(Sound, "player.history", { max: 30, unique: true }),
 | 
					            playlist: null,
 | 
				
			||||||
 | 
					            //! players' playlists' sets
 | 
				
			||||||
 | 
					            sets: {
 | 
				
			||||||
 | 
					                queue: Set.storeLoad(Sound, "playlist.queue", { max: 30, unique: true }),
 | 
				
			||||||
 | 
					                pin: Set.storeLoad(Sound, "player.pin", { max: 30, unique: true }),
 | 
				
			||||||
 | 
					                history: Set.storeLoad(Sound, "player.history", { max: 30, unique: true }),
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -120,7 +132,7 @@ export default {
 | 
				
			|||||||
        self() { return this; },
 | 
					        self() { return this; },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        current() {
 | 
					        current() {
 | 
				
			||||||
            return this.active || this.live && this.live.current;
 | 
					            return this.loaded || this.live && this.live.current;
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        progress() {
 | 
					        progress() {
 | 
				
			||||||
@ -137,15 +149,35 @@ export default {
 | 
				
			|||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    methods: {
 | 
					    methods: {
 | 
				
			||||||
 | 
					        playlistButtonClass(name) {
 | 
				
			||||||
 | 
					            let set = this.sets[name];
 | 
				
			||||||
 | 
					            return (set ? (set.length ? "" : "has-text-grey-light ")
 | 
				
			||||||
 | 
					                       + (this.panel == name ? "is-info "
 | 
				
			||||||
 | 
					                          : this.playlist && this.playlist == this.$refs[name] ? 'is-primary '
 | 
				
			||||||
 | 
					                          : '') : '')
 | 
				
			||||||
 | 
					                + "button has-text-weight-bold";
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /// Show/hide panel
 | 
				
			||||||
        togglePanel(panel) {
 | 
					        togglePanel(panel) {
 | 
				
			||||||
            this.panel = this.panel == panel ? null : panel;
 | 
					            this.panel = this.panel == panel ? null : panel;
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        isActive(item) {
 | 
					        /// Return True if item is loaded
 | 
				
			||||||
            return item && this.active && this.active.src == item.src;
 | 
					        isLoaded(item) {
 | 
				
			||||||
 | 
					            return this.loaded && this.loaded.src == item.src;
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        _load(src) {
 | 
					        /// Return True if item is loaded
 | 
				
			||||||
 | 
					        isPlaying(item) {
 | 
				
			||||||
 | 
					            return this.isLoaded(item) && !this.player.paused;
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        load(playlist, {src=null, item=null}={}) {
 | 
				
			||||||
 | 
					            src = src || item.src;
 | 
				
			||||||
 | 
					            this.loaded = item;
 | 
				
			||||||
 | 
					            this.playlist = playlist ? this.$refs[playlist] : null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            const audio = this.$refs.audio;
 | 
					            const audio = this.$refs.audio;
 | 
				
			||||||
            if(src instanceof Array) {
 | 
					            if(src instanceof Array) {
 | 
				
			||||||
                audio.innerHTML = '';
 | 
					                audio.innerHTML = '';
 | 
				
			||||||
@ -161,22 +193,43 @@ export default {
 | 
				
			|||||||
            audio.load();
 | 
					            audio.load();
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        load(item) {
 | 
					        /// Play a playlist's sound (by playlist name, and sound index)
 | 
				
			||||||
 | 
					        play(playlist=null, index=0) {
 | 
				
			||||||
 | 
					            if(!playlist)
 | 
				
			||||||
 | 
					                playlist = 'queue';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            let item = this.$refs[playlist].get(index);
 | 
				
			||||||
            if(item) {
 | 
					            if(item) {
 | 
				
			||||||
                this._load(item.src)
 | 
					                this.load(playlist, {item: item});
 | 
				
			||||||
                this.history.push(item);
 | 
					                this.sets.history.push(item);
 | 
				
			||||||
 | 
					                this.$refs.audio.play().catch(e => console.error(e))
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            else
 | 
					            else
 | 
				
			||||||
                this._load(this.live.src);
 | 
					                throw `No sound at index ${index} for playlist ${playlist}`;
 | 
				
			||||||
            this.$set(this, 'active', item);
 | 
					 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        play(item) {
 | 
					        /// Push items to playlist (by name)
 | 
				
			||||||
            if(item)
 | 
					        push(playlist, ...items) {
 | 
				
			||||||
                this.load(item);
 | 
					            this.$refs[playlist].push(...items);
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /// Push and play items
 | 
				
			||||||
 | 
					        playItems(playlist, ...items) {
 | 
				
			||||||
 | 
					            this.push(playlist, ...items);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            let index = this.$refs[playlist].findIndex(items[0]);
 | 
				
			||||||
 | 
					            this.$refs[playlist].selectedIndex = index;
 | 
				
			||||||
 | 
					            this.play(playlist, index);
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /// Play live stream
 | 
				
			||||||
 | 
					        playLive() {
 | 
				
			||||||
 | 
					            this.load(null, {src: this.live.src});
 | 
				
			||||||
            this.$refs.audio.play().catch(e => console.error(e))
 | 
					            this.$refs.audio.play().catch(e => console.error(e))
 | 
				
			||||||
 | 
					            this.panel = '';
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /// Pause
 | 
				
			||||||
        pause() {
 | 
					        pause() {
 | 
				
			||||||
            this.$refs.audio.pause()
 | 
					            this.$refs.audio.pause()
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
@ -184,33 +237,30 @@ export default {
 | 
				
			|||||||
        //! Play/pause
 | 
					        //! Play/pause
 | 
				
			||||||
        togglePlay() {
 | 
					        togglePlay() {
 | 
				
			||||||
            if(this.paused)
 | 
					            if(this.paused)
 | 
				
			||||||
                this.play()
 | 
					                this.$refs.audio.play().catch(e => console.error(e))
 | 
				
			||||||
            else
 | 
					            else
 | 
				
			||||||
                this.pause()
 | 
					                this.pause()
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        //! Push item to queue
 | 
					        //! Pin/Unpin an item
 | 
				
			||||||
        push(item) {
 | 
					        togglePin(item) {
 | 
				
			||||||
            this.queue.push(item);
 | 
					            let index = this.sets.pin.findIndex(item);
 | 
				
			||||||
            this.panel = 'queue';
 | 
					            if(index > -1)
 | 
				
			||||||
 | 
					                this.sets.pin.remove(index);
 | 
				
			||||||
 | 
					            else {
 | 
				
			||||||
 | 
					                this.sets.pin.push(item);
 | 
				
			||||||
 | 
					                if(!this.panel)
 | 
				
			||||||
 | 
					                    this.panel = 'pin';
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /// Audio player state change event
 | 
				
			||||||
        onState(event) {
 | 
					        onState(event) {
 | 
				
			||||||
            const audio = this.$refs.audio;
 | 
					            const audio = this.$refs.audio;
 | 
				
			||||||
            this.state = audio.paused ? State.paused : State.playing;
 | 
					            this.state = audio.paused ? State.paused : State.playing;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if(event.type == 'ended' && this.active) {
 | 
					            if(event.type == 'ended' && (!this.playlist || this.playlist.selectNext() == -1))
 | 
				
			||||||
                this.queue.remove(this.active);
 | 
					                this.playLive();
 | 
				
			||||||
                if(this.queue.length)
 | 
					 | 
				
			||||||
                    this.$refs.queue.select(0);
 | 
					 | 
				
			||||||
                else
 | 
					 | 
				
			||||||
                    this.load();
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        onSelect({item,index}) {
 | 
					 | 
				
			||||||
            if(!this.isActive(item))
 | 
					 | 
				
			||||||
                this.play(item);
 | 
					 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -218,9 +268,7 @@ export default {
 | 
				
			|||||||
        this.sources = this.$slots.sources;
 | 
					        this.sources = this.$slots.sources;
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    components: {
 | 
					    components: { Playlist },
 | 
				
			||||||
        List, SoundItem,
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
</script>
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										58
									
								
								assets/public/playlist.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										58
									
								
								assets/public/playlist.vue
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,58 @@
 | 
				
			|||||||
 | 
					<template>
 | 
				
			||||||
 | 
					    <div>
 | 
				
			||||||
 | 
					        <slot name="header"></slot>
 | 
				
			||||||
 | 
					        <ul :class="listClass">
 | 
				
			||||||
 | 
					            <li v-for="(item,index) in items" :class="itemClass" @click="!hasAction('play') && select(index)">
 | 
				
			||||||
 | 
					                <a :class="index == selectedIndex ? 'is-active' : ''">
 | 
				
			||||||
 | 
					                    <SoundItem
 | 
				
			||||||
 | 
					                        :data="item" :index="index" :player="player" :set="set"
 | 
				
			||||||
 | 
					                        @togglePlay="togglePlay(index)"
 | 
				
			||||||
 | 
					                        :actions="actions">
 | 
				
			||||||
 | 
					                        <template v-slot:actions="{loaded,set}">
 | 
				
			||||||
 | 
					                            <button class="button" v-if="editable" @click.stop="remove(index,true)">
 | 
				
			||||||
 | 
					                                <span class="icon is-small"><span class="fa fa-minus"></span></span>
 | 
				
			||||||
 | 
					                            </button>
 | 
				
			||||||
 | 
					                        </template>
 | 
				
			||||||
 | 
					                    </SoundItem>
 | 
				
			||||||
 | 
					                </a>
 | 
				
			||||||
 | 
					            </li>
 | 
				
			||||||
 | 
					        </ul>
 | 
				
			||||||
 | 
					        <slot name="footer"></slot>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					</template>
 | 
				
			||||||
 | 
					<script>
 | 
				
			||||||
 | 
					import List from './list';
 | 
				
			||||||
 | 
					import SoundItem from './soundItem';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export default {
 | 
				
			||||||
 | 
					    extends: List,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    props: {
 | 
				
			||||||
 | 
					        actions: Array,
 | 
				
			||||||
 | 
					        name: String,
 | 
				
			||||||
 | 
					        player: Object,
 | 
				
			||||||
 | 
					        editable: Boolean,
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    computed: {
 | 
				
			||||||
 | 
					        self() { return this; }
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    methods: {
 | 
				
			||||||
 | 
					        hasAction(action) { return this.actions && this.actions.indexOf(action) != -1; },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        selectNext() {
 | 
				
			||||||
 | 
					            let index = this.selectedIndex + 1;
 | 
				
			||||||
 | 
					            return this.select(index >= this.items.length ? -1 : index);
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        togglePlay(index) {
 | 
				
			||||||
 | 
					            if(this.player.isPlaying(this.set.get(index)))
 | 
				
			||||||
 | 
					                this.player.pause();
 | 
				
			||||||
 | 
					            else
 | 
				
			||||||
 | 
					                this.select(index)
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    components: { List, SoundItem },
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					</script>
 | 
				
			||||||
@ -1,32 +1,29 @@
 | 
				
			|||||||
<template>
 | 
					<template>
 | 
				
			||||||
    <a :class="[active ? activeClass : '']" @click="actions.indexOf('play') == -1 && play()">
 | 
					    <div class="media">
 | 
				
			||||||
        <div class="media">
 | 
					        <div class="media-left" v-if="hasAction('play')">
 | 
				
			||||||
            <div class="media-left" v-if="hasAction('play')">
 | 
					            <button class="button" @click="$emit('togglePlay')">
 | 
				
			||||||
                <button class="button" @click="play()">
 | 
					                <div class="icon">
 | 
				
			||||||
                    <div class="icon">
 | 
					                    <span class="fa fa-pause" v-if="playing || loading"></span>
 | 
				
			||||||
                        <span class="fa fa-pause" v-if="playing || loading"></span>
 | 
					                    <span class="fa fa-play" v-else></span>
 | 
				
			||||||
                        <span class="fa fa-play" v-else></span>
 | 
					                </div>
 | 
				
			||||||
                    </div>
 | 
					            </button>
 | 
				
			||||||
                </button>
 | 
					 | 
				
			||||||
            </div>
 | 
					 | 
				
			||||||
            <div class="media-content">
 | 
					 | 
				
			||||||
                <slot name="content" :player="player" :item="item" :active="active">
 | 
					 | 
				
			||||||
                    <h4 class="title is-4 is-inline-block">
 | 
					 | 
				
			||||||
                        {{ name || item.name }}
 | 
					 | 
				
			||||||
                    </h4>
 | 
					 | 
				
			||||||
                </slot>
 | 
					 | 
				
			||||||
            </div>
 | 
					 | 
				
			||||||
            <div class="media-right">
 | 
					 | 
				
			||||||
                <button class="button" v-if="hasAction('queue')" @click.stop="player.push(item)">
 | 
					 | 
				
			||||||
                    <span class="icon is-small"><span class="fa fa-list"></span></span>
 | 
					 | 
				
			||||||
                </button>
 | 
					 | 
				
			||||||
                <button class="button" v-if="hasAction('remove')" @click.stop="set.remove(item)">
 | 
					 | 
				
			||||||
                    <span class="icon is-small"><span class="fa fa-minus"></span></span>
 | 
					 | 
				
			||||||
                </button>
 | 
					 | 
				
			||||||
                <slot name="actions" :player="player" :item="item" :active="active"></slot>
 | 
					 | 
				
			||||||
            </div>
 | 
					 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
    </a>
 | 
					        <div class="media-content">
 | 
				
			||||||
 | 
					            <slot name="content" :player="player" :item="item" :loaded="loaded">
 | 
				
			||||||
 | 
					                <h4 class="title is-4 is-inline-block">
 | 
				
			||||||
 | 
					                    {{ name || item.name }}
 | 
				
			||||||
 | 
					                </h4>
 | 
				
			||||||
 | 
					            </slot>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					        <div class="media-right">
 | 
				
			||||||
 | 
					            <button class="button" v-if="player.$refs.pin != $parent" @click.stop="player.togglePin(item)">
 | 
				
			||||||
 | 
					                <span class="icon is-small">
 | 
				
			||||||
 | 
					                    <span :class="(pinned ? '' : 'has-text-grey-light ') + 'fa fa-thumbtack'"></span>
 | 
				
			||||||
 | 
					                </span>
 | 
				
			||||||
 | 
					            </button>
 | 
				
			||||||
 | 
					            <slot name="actions" :player="player" :item="item" :loaded="loaded"></slot>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
</template>
 | 
					</template>
 | 
				
			||||||
<script>
 | 
					<script>
 | 
				
			||||||
import Model from './model';
 | 
					import Model from './model';
 | 
				
			||||||
@ -37,36 +34,25 @@ export default {
 | 
				
			|||||||
        data: {type: Object, default: x => {}},
 | 
					        data: {type: Object, default: x => {}},
 | 
				
			||||||
        name: String,
 | 
					        name: String,
 | 
				
			||||||
        cover: String,
 | 
					        cover: String,
 | 
				
			||||||
        set: Object,
 | 
					 | 
				
			||||||
        player: Object,
 | 
					        player: Object,
 | 
				
			||||||
        page_url: String,
 | 
					        page_url: String,
 | 
				
			||||||
        activeClass: String,
 | 
					 | 
				
			||||||
        actions: {type:Array, default: x => []},
 | 
					        actions: {type:Array, default: x => []},
 | 
				
			||||||
 | 
					        index: {type:Number, default: null},
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    computed: {
 | 
					    computed: {
 | 
				
			||||||
        item() { return this.data instanceof Model ? this.data : new Sound(this.data || {}); },
 | 
					        item() { return this.data instanceof Model ? this.data : new Sound(this.data || {}); },
 | 
				
			||||||
        active() { return this.player && this.player.isActive(this.item) },
 | 
					        loaded() { return this.player && this.player.isLoaded(this.item) },
 | 
				
			||||||
        playing() { return this.player && this.player.playing && this.active },
 | 
					        playing() { return this.player && this.player.playing && this.loaded },
 | 
				
			||||||
        paused()  { return this.player && this.player.paused && this.active },
 | 
					        paused()  { return this.player && this.player.paused && this.loaded },
 | 
				
			||||||
        loading() { return this.player && this.player.loading && this.active },
 | 
					        loading() { return this.player && this.player.loading && this.loaded },
 | 
				
			||||||
 | 
					        pinned() { return this.player && this.player.sets.pin.find(this.item) },
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    methods: {
 | 
					    methods: {
 | 
				
			||||||
        hasAction(action) {
 | 
					        hasAction(action) {
 | 
				
			||||||
            return this.actions && this.actions.indexOf(action) != -1;
 | 
					            return this.actions && this.actions.indexOf(action) != -1;
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
 | 
					 | 
				
			||||||
        play() {
 | 
					 | 
				
			||||||
            if(this.player && this.active)
 | 
					 | 
				
			||||||
                this.player.togglePlay()
 | 
					 | 
				
			||||||
            else
 | 
					 | 
				
			||||||
                this.player.play(this.item);
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        push_to(playlist) {
 | 
					 | 
				
			||||||
            this.player.playlists[playlist].push(this.item, {unique_key:'id'});
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
</script>
 | 
					</script>
 | 
				
			||||||
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user