forked from rc/aircox
streamer as separate application; working streamer monitor interface
This commit is contained in:
98
assets/streamer/controllers.js
Normal file
98
assets/streamer/controllers.js
Normal file
@ -0,0 +1,98 @@
|
||||
import Vue from 'vue';
|
||||
|
||||
import Model from 'public/model';
|
||||
|
||||
|
||||
export class Streamer extends Model {
|
||||
get queues() { return this.data ? this.data.queues : []; }
|
||||
get playlists() { return this.data ? this.data.playlists : []; }
|
||||
get sources() { return [...this.queues, ...this.playlists]; }
|
||||
get source() { return this.sources.find(o => o.id == this.data.source) }
|
||||
|
||||
commit(data) {
|
||||
if(!this.data)
|
||||
this.data = { id: data.id, playlists: [], queues: [] }
|
||||
|
||||
data.playlists = Playlist.updateList(data.playlists, this.playlists)
|
||||
data.queues = Queue.updateList(data.queues, this.queues)
|
||||
super.commit(data)
|
||||
}
|
||||
}
|
||||
|
||||
export class Request extends Model {
|
||||
static getId(data) { return data.rid; }
|
||||
}
|
||||
|
||||
export class Source extends Model {
|
||||
constructor(...args) {
|
||||
super(...args);
|
||||
setInterval(() => this.tick(), 1000)
|
||||
}
|
||||
|
||||
get isQueue() { return false; }
|
||||
get isPlaylist() { return false; }
|
||||
get isPlaying() { return this.data.status == 'playing' }
|
||||
get isPaused() { return this.data.status == 'paused' }
|
||||
|
||||
get remainingString() {
|
||||
if(!this.remaining)
|
||||
return '00:00';
|
||||
|
||||
const seconds = Math.floor(this.remaining % 60);
|
||||
const minutes = Math.floor(this.remaining / 60);
|
||||
return String(minutes).padStart(2, '0') + ':' +
|
||||
String(seconds).padStart(2, '0');
|
||||
}
|
||||
|
||||
|
||||
sync() { return this.action('sync/', {method: 'POST'}, true); }
|
||||
skip() { return this.action('skip/', {method: 'POST'}, true); }
|
||||
restart() { return this.action('restart/', {method: 'POST'}, true); }
|
||||
|
||||
seek(count) {
|
||||
return this.action('seek/', {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({count: count})
|
||||
}, true)
|
||||
}
|
||||
|
||||
tick() {
|
||||
if(!this.data.remaining || !this.isPlaying)
|
||||
return;
|
||||
const delta = (Date.now() - this.commitDate) / 1000;
|
||||
Vue.set(this, 'remaining', this.data.remaining - delta)
|
||||
}
|
||||
|
||||
commit(data) {
|
||||
if(data.air_time)
|
||||
data.air_time = new Date(data.air_time);
|
||||
Vue.set(this, 'remaining', data.remaining)
|
||||
this.commitDate = Date.now()
|
||||
super.commit(data)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export class Playlist extends Source {
|
||||
get isPlaylist() { return true; }
|
||||
}
|
||||
|
||||
|
||||
export class Queue extends Source {
|
||||
get isQueue() { return true; }
|
||||
get queue() { return this.data && this.data.queue; }
|
||||
|
||||
commit(data) {
|
||||
data.queue = Request.updateList(data.queue, this.queue)
|
||||
super.commit(data)
|
||||
}
|
||||
|
||||
push(soundId) {
|
||||
return this.action('push/', {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({'sound_id': parseInt(soundId)})
|
||||
}, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
56
assets/streamer/index.js
Normal file
56
assets/streamer/index.js
Normal file
@ -0,0 +1,56 @@
|
||||
import Vue from 'vue';
|
||||
import Button from 'buefy/dist/components/button';
|
||||
|
||||
Vue.use(Button)
|
||||
|
||||
import {setAppConfig} from 'public/app';
|
||||
import Model from 'public/model';
|
||||
import Sound from 'public/sound';
|
||||
import {Streamer, Queue} from './controllers';
|
||||
|
||||
window.aircox.appConfig = {
|
||||
data() {
|
||||
return {
|
||||
// current streamer
|
||||
streamer: null,
|
||||
// all streamers
|
||||
streamers: [],
|
||||
// fetch interval id
|
||||
fetchInterval: null,
|
||||
|
||||
Sound: Sound,
|
||||
}
|
||||
},
|
||||
|
||||
computed: {
|
||||
apiUrl() {
|
||||
return this.$el && this.$el.dataset.apiUrl;
|
||||
},
|
||||
|
||||
sources() {
|
||||
var sources = this.streamer ? this.streamer.sources : [];
|
||||
return sources.filter(s => s.data)
|
||||
},
|
||||
},
|
||||
|
||||
methods: {
|
||||
fetchStreamers() {
|
||||
Streamer.fetchAll(this.apiUrl, null)
|
||||
.then(streamers => {
|
||||
Vue.set(this, 'streamers', streamers);
|
||||
Vue.set(this, 'streamer', streamers ? streamers[0] : null);
|
||||
})
|
||||
},
|
||||
},
|
||||
|
||||
mounted() {
|
||||
this.fetchStreamers();
|
||||
this.fetchInterval = setInterval(() => this.streamer && this.streamer.fetch(), 5000)
|
||||
},
|
||||
|
||||
destroyed() {
|
||||
if(this.fetchInterval !== null)
|
||||
clearInterval(this.fetchInterval)
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user