streamer as separate application; working streamer monitor interface

This commit is contained in:
bkfox
2019-09-21 17:14:40 +02:00
parent 4e61ec1520
commit d3f39c5ade
39 changed files with 1347 additions and 148 deletions

View File

@ -108,7 +108,7 @@ class PlaylistImport:
return tracks
class Command (BaseCommand):
class Command(BaseCommand):
help = __doc__
def add_arguments(self, parser):

View File

@ -22,13 +22,17 @@ __all__ = ['Sound', 'SoundQuerySet', 'Track']
class SoundQuerySet(models.QuerySet):
def station(self, station=None, id=None):
id = station.pk if id is None else id
return self.filter(program__station__id=id)
def episode(self, episode=None, id=None):
return self.filter(episode=episode) if id is None else \
self.filter(episode__id=id)
id = episode.pk if id is None else id
return self.filter(episode__id=id)
def diffusion(self, diffusion=None, id=None):
return self.filter(episode__diffusion=diffusion) if id is None else \
self.filter(episode__diffusion__id=id)
id = diffusion.pk if id is None else id
return self.filter(episode__diffusion__id=id)
def podcasts(self):
""" Return sounds available as podcasts """
@ -49,6 +53,13 @@ class SoundQuerySet(models.QuerySet):
self = self.order_by('path')
return self.filter(path__isnull=False).values_list('path', flat=True)
def search(self, query):
return self.filter(
Q(name__icontains=query) | Q(path__icontains=query) |
Q(program__title__icontains=query) |
Q(episode__title__icontains=query)
)
class Sound(models.Model):
"""

View File

@ -1,6 +1,6 @@
from rest_framework import serializers
from .models import Diffusion, Log
from .models import Diffusion, Log, Sound
__all__ = ['LogInfo', 'LogInfoSerializer']
@ -53,3 +53,18 @@ class LogInfoSerializer(serializers.Serializer):
cover = serializers.URLField(required=False)
class SoundSerializer(serializers.ModelSerializer):
# serializers.HyperlinkedIdentityField(view_name='sound', format='html')
class Meta:
model = Sound
fields = ['pk', 'name', 'path', 'program', 'episode', 'embed', 'type',
'duration', 'mtime', 'is_good_quality', 'is_public']
def get_field_names(self, *args):
names = super().get_field_names(*args)
if not self.context['request'].user.is_staff and self.instance \
and not self.instance.is_public:
names.remove('path')
return names

View File

@ -207,6 +207,97 @@ ul.menu-list li {
fieldset[disabled] .pagination-ellipsis {
cursor: not-allowed; }
.dropdown {
display: inline-flex;
position: relative;
vertical-align: top; }
.dropdown.is-active .dropdown-menu, .dropdown.is-hoverable:hover .dropdown-menu {
display: block; }
.dropdown.is-right .dropdown-menu {
left: auto;
right: 0; }
.dropdown.is-up .dropdown-menu {
bottom: 100%;
padding-bottom: 4px;
padding-top: initial;
top: auto; }
.dropdown-menu {
display: none;
left: 0;
min-width: 12rem;
padding-top: 4px;
position: absolute;
top: 100%;
z-index: 20; }
.dropdown-content {
background-color: white;
border-radius: 4px;
box-shadow: 0 2px 3px rgba(10, 10, 10, 0.1), 0 0 0 1px rgba(10, 10, 10, 0.1);
padding-bottom: 0.5rem;
padding-top: 0.5rem; }
.dropdown-item {
color: #4a4a4a;
display: block;
font-size: 0.875rem;
line-height: 1.5;
padding: 0.375rem 1rem;
position: relative; }
a.dropdown-item,
button.dropdown-item {
padding-right: 3rem;
text-align: left;
white-space: nowrap;
width: 100%; }
a.dropdown-item:hover,
button.dropdown-item:hover {
background-color: whitesmoke;
color: #0a0a0a; }
a.dropdown-item.is-active,
button.dropdown-item.is-active {
background-color: #3273dc;
color: #fff; }
.dropdown-divider {
background-color: #dbdbdb;
border: none;
display: block;
height: 1px;
margin: 0.5rem 0; }
.autocomplete {
position: relative; }
.autocomplete .dropdown-menu {
display: block;
min-width: 100%;
max-width: 100%; }
.autocomplete .dropdown-menu.is-opened-top {
top: auto;
bottom: 100%; }
.autocomplete .dropdown-content {
overflow: auto;
max-height: 200px; }
.autocomplete .dropdown-item {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis; }
.autocomplete .dropdown-item.is-hovered {
background: whitesmoke;
color: #0a0a0a; }
.autocomplete .dropdown-item.is-disabled {
opacity: 0.5;
cursor: not-allowed; }
.autocomplete.is-small {
border-radius: 2px;
font-size: 0.75rem; }
.autocomplete.is-medium {
font-size: 1.25rem; }
.autocomplete.is-large {
font-size: 1.5rem; }
/*! bulma.io v0.7.5 | MIT License | github.com/jgthms/bulma */
@keyframes spinAround {
from {
@ -7177,6 +7268,9 @@ label.panel-block {
.is-borderless {
border: none; }
.has-text-nowrap {
white-space: nowrap; }
.has-background-transparent {
background-color: transparent; }
@ -7208,6 +7302,18 @@ a.navbar-item.is-active {
margin: 0em;
padding: 0em; }
.navbar.toolbar {
margin: 1em 0em;
background-color: transparent;
margin-bottom: 1em; }
.navbar.toolbar .title {
padding-right: 2em;
margin-right: 1em;
border-right: 1px #b5b5b5 solid;
font-size: 1.25rem;
color: #7a7a7a;
font-weight: 300; }
.card .title {
padding: 0.2em;
font-size: 1.25rem;
@ -7230,18 +7336,6 @@ a.navbar-item.is-active {
padding: 0.1em;
font-size: 0.8em; }
.filters {
margin: 1em 0em;
background-color: transparent;
margin-bottom: 1em; }
.filters .title {
padding-right: 2em;
margin-right: 1em;
border-right: 1px #b5b5b5 solid;
font-size: 1.25rem;
color: #7a7a7a;
font-weight: 300; }
.page > .cover {
float: right;
max-width: 45%; }

View File

@ -218,11 +218,47 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _nod
/*!******************************!*\
!*** ./assets/public/app.js ***!
\******************************/
/*! exports provided: app, default */
/*! exports provided: appBaseConfig, setAppConfig, getAppConfig, loadApp */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"app\", function() { return app; });\n/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! vue */ \"./node_modules/vue/dist/vue.esm.browser.js\");\n\n\n\nvar app = null;\n/* harmony default export */ __webpack_exports__[\"default\"] = (app);\n\nfunction loadApp() {\n app = new vue__WEBPACK_IMPORTED_MODULE_0__[\"default\"]({\n el: '#app',\n delimiters: [ '[[', ']]' ],\n })\n}\n\nwindow.addEventListener('load', loadApp);\n\n\n\n\n\n//# sourceURL=webpack:///./assets/public/app.js?");
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"appBaseConfig\", function() { return appBaseConfig; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"setAppConfig\", function() { return setAppConfig; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"getAppConfig\", function() { return getAppConfig; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"loadApp\", function() { return loadApp; });\n/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! vue */ \"./node_modules/vue/dist/vue.esm.browser.js\");\n\n\n\nconst appBaseConfig = {\n el: '#app',\n delimiters: ['[[', ']]'],\n}\n\n/**\n * Application config for the main application instance\n */\nvar appConfig = {};\n\nfunction setAppConfig(config) {\n for(var member in appConfig) delete appConfig[member];\n return Object.assign(appConfig, config)\n}\n\nfunction getAppConfig(config) {\n if(config instanceof Function)\n config = config()\n config = config == null ? appConfig : config;\n return {...appBaseConfig, ...config}\n}\n\n\n/**\n * Create Vue application at window 'load' event and return a Promise\n * resolving to the created app.\n *\n * config: defaults to appConfig (checked when window is loaded)\n */\nfunction loadApp(config=null) {\n return new Promise(function(resolve, reject) {\n window.addEventListener('load', function() {\n try {\n config = getAppConfig(config)\n const el = document.querySelector(config.el)\n if(!el) {\n reject(`Error: missing element ${config.el}`);\n return;\n }\n\n resolve(new vue__WEBPACK_IMPORTED_MODULE_0__[\"default\"](config))\n }\n catch(error) { reject(error) }\n })\n })\n}\n\n\n\n\n\n\n//# sourceURL=webpack:///./assets/public/app.js?");
/***/ }),
/***/ "./assets/public/autocomplete.vue":
/*!****************************************!*\
!*** ./assets/public/autocomplete.vue ***!
\****************************************/
/*! exports provided: default */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _autocomplete_vue_vue_type_template_id_70936760___WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./autocomplete.vue?vue&type=template&id=70936760& */ \"./assets/public/autocomplete.vue?vue&type=template&id=70936760&\");\n/* harmony import */ var _autocomplete_vue_vue_type_script_lang_js___WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./autocomplete.vue?vue&type=script&lang=js& */ \"./assets/public/autocomplete.vue?vue&type=script&lang=js&\");\n/* empty/unused harmony star reexport *//* harmony import */ var _node_modules_vue_loader_lib_runtime_componentNormalizer_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../node_modules/vue-loader/lib/runtime/componentNormalizer.js */ \"./node_modules/vue-loader/lib/runtime/componentNormalizer.js\");\n\n\n\n\n\n/* normalize component */\n\nvar component = Object(_node_modules_vue_loader_lib_runtime_componentNormalizer_js__WEBPACK_IMPORTED_MODULE_2__[\"default\"])(\n _autocomplete_vue_vue_type_script_lang_js___WEBPACK_IMPORTED_MODULE_1__[\"default\"],\n _autocomplete_vue_vue_type_template_id_70936760___WEBPACK_IMPORTED_MODULE_0__[\"render\"],\n _autocomplete_vue_vue_type_template_id_70936760___WEBPACK_IMPORTED_MODULE_0__[\"staticRenderFns\"],\n false,\n null,\n null,\n null\n \n)\n\n/* hot reload */\nif (false) { var api; }\ncomponent.options.__file = \"assets/public/autocomplete.vue\"\n/* harmony default export */ __webpack_exports__[\"default\"] = (component.exports);\n\n//# sourceURL=webpack:///./assets/public/autocomplete.vue?");
/***/ }),
/***/ "./assets/public/autocomplete.vue?vue&type=script&lang=js&":
/*!*****************************************************************!*\
!*** ./assets/public/autocomplete.vue?vue&type=script&lang=js& ***!
\*****************************************************************/
/*! exports provided: default */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _node_modules_vue_loader_lib_index_js_vue_loader_options_autocomplete_vue_vue_type_script_lang_js___WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! -!../../node_modules/vue-loader/lib??vue-loader-options!./autocomplete.vue?vue&type=script&lang=js& */ \"./node_modules/vue-loader/lib/index.js?!./assets/public/autocomplete.vue?vue&type=script&lang=js&\");\n/* empty/unused harmony star reexport */ /* harmony default export */ __webpack_exports__[\"default\"] = (_node_modules_vue_loader_lib_index_js_vue_loader_options_autocomplete_vue_vue_type_script_lang_js___WEBPACK_IMPORTED_MODULE_0__[\"default\"]); \n\n//# sourceURL=webpack:///./assets/public/autocomplete.vue?");
/***/ }),
/***/ "./assets/public/autocomplete.vue?vue&type=template&id=70936760&":
/*!***********************************************************************!*\
!*** ./assets/public/autocomplete.vue?vue&type=template&id=70936760& ***!
\***********************************************************************/
/*! exports provided: render, staticRenderFns */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _node_modules_vue_loader_lib_loaders_templateLoader_js_vue_loader_options_node_modules_vue_loader_lib_index_js_vue_loader_options_autocomplete_vue_vue_type_template_id_70936760___WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! -!../../node_modules/vue-loader/lib/loaders/templateLoader.js??vue-loader-options!../../node_modules/vue-loader/lib??vue-loader-options!./autocomplete.vue?vue&type=template&id=70936760& */ \"./node_modules/vue-loader/lib/loaders/templateLoader.js?!./node_modules/vue-loader/lib/index.js?!./assets/public/autocomplete.vue?vue&type=template&id=70936760&\");\n/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, \"render\", function() { return _node_modules_vue_loader_lib_loaders_templateLoader_js_vue_loader_options_node_modules_vue_loader_lib_index_js_vue_loader_options_autocomplete_vue_vue_type_template_id_70936760___WEBPACK_IMPORTED_MODULE_0__[\"render\"]; });\n\n/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, \"staticRenderFns\", function() { return _node_modules_vue_loader_lib_loaders_templateLoader_js_vue_loader_options_node_modules_vue_loader_lib_index_js_vue_loader_options_autocomplete_vue_vue_type_template_id_70936760___WEBPACK_IMPORTED_MODULE_0__[\"staticRenderFns\"]; });\n\n\n\n//# sourceURL=webpack:///./assets/public/autocomplete.vue?");
/***/ }),
@ -234,7 +270,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) *
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! vue */ \"./node_modules/vue/dist/vue.esm.browser.js\");\n/* harmony import */ var _fortawesome_fontawesome_free_css_all_min_css__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @fortawesome/fontawesome-free/css/all.min.css */ \"./node_modules/@fortawesome/fontawesome-free/css/all.min.css\");\n/* harmony import */ var _fortawesome_fontawesome_free_css_all_min_css__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_fortawesome_fontawesome_free_css_all_min_css__WEBPACK_IMPORTED_MODULE_1__);\n/* harmony import */ var _fortawesome_fontawesome_free_css_fontawesome_min_css__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @fortawesome/fontawesome-free/css/fontawesome.min.css */ \"./node_modules/@fortawesome/fontawesome-free/css/fontawesome.min.css\");\n/* harmony import */ var _fortawesome_fontawesome_free_css_fontawesome_min_css__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(_fortawesome_fontawesome_free_css_fontawesome_min_css__WEBPACK_IMPORTED_MODULE_2__);\n/* harmony import */ var _app__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./app */ \"./assets/public/app.js\");\n/* harmony import */ var _liveInfo__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./liveInfo */ \"./assets/public/liveInfo.js\");\n/* harmony import */ var _styles_scss__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./styles.scss */ \"./assets/public/styles.scss\");\n/* harmony import */ var _styles_scss__WEBPACK_IMPORTED_MODULE_5___default = /*#__PURE__*/__webpack_require__.n(_styles_scss__WEBPACK_IMPORTED_MODULE_5__);\n/* harmony import */ var _player_vue__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./player.vue */ \"./assets/public/player.vue\");\n/**\n * This module includes code available for both the public website and\n * administration interface)\n */\n//-- vendor\n\n\n\n\n\n\n//-- aircox\n\n\n\n\n\n\n\nvue__WEBPACK_IMPORTED_MODULE_0__[\"default\"].component('a-player', _player_vue__WEBPACK_IMPORTED_MODULE_6__[\"default\"])\n\n\nwindow.aircox = {\n app: _app__WEBPACK_IMPORTED_MODULE_3__[\"default\"],\n LiveInfo: _liveInfo__WEBPACK_IMPORTED_MODULE_4__[\"default\"],\n}\n\n\n\n//# sourceURL=webpack:///./assets/public/index.js?");
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! vue */ \"./node_modules/vue/dist/vue.esm.browser.js\");\n/* harmony import */ var _fortawesome_fontawesome_free_css_all_min_css__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @fortawesome/fontawesome-free/css/all.min.css */ \"./node_modules/@fortawesome/fontawesome-free/css/all.min.css\");\n/* harmony import */ var _fortawesome_fontawesome_free_css_all_min_css__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_fortawesome_fontawesome_free_css_all_min_css__WEBPACK_IMPORTED_MODULE_1__);\n/* harmony import */ var _fortawesome_fontawesome_free_css_fontawesome_min_css__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @fortawesome/fontawesome-free/css/fontawesome.min.css */ \"./node_modules/@fortawesome/fontawesome-free/css/fontawesome.min.css\");\n/* harmony import */ var _fortawesome_fontawesome_free_css_fontawesome_min_css__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(_fortawesome_fontawesome_free_css_fontawesome_min_css__WEBPACK_IMPORTED_MODULE_2__);\n/* harmony import */ var _app__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./app */ \"./assets/public/app.js\");\n/* harmony import */ var _styles_scss__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./styles.scss */ \"./assets/public/styles.scss\");\n/* harmony import */ var _styles_scss__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(_styles_scss__WEBPACK_IMPORTED_MODULE_4__);\n/* harmony import */ var _player_vue__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./player.vue */ \"./assets/public/player.vue\");\n/* harmony import */ var _autocomplete_vue__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./autocomplete.vue */ \"./assets/public/autocomplete.vue\");\n/**\n * This module includes code available for both the public website and\n * administration interface)\n */\n//-- vendor\n\n\n\n\n\n\n//-- aircox\n\n\n\n\n\n\n\nvue__WEBPACK_IMPORTED_MODULE_0__[\"default\"].component('a-player', _player_vue__WEBPACK_IMPORTED_MODULE_5__[\"default\"])\nvue__WEBPACK_IMPORTED_MODULE_0__[\"default\"].component('a-autocomplete', _autocomplete_vue__WEBPACK_IMPORTED_MODULE_6__[\"default\"])\n\n\nwindow.aircox = {\n // main application\n app: null,\n\n // main application config\n appConfig: {},\n\n // player application\n playerApp: null,\n\n // player component\n get player() {\n return this.playerApp && this.playerApp.$refs.player\n }\n};\n\n\nObject(_app__WEBPACK_IMPORTED_MODULE_3__[\"loadApp\"])({el: '#player'}).then(app => { window.aircox.playerApp = app },\n () => undefined)\nObject(_app__WEBPACK_IMPORTED_MODULE_3__[\"loadApp\"])(() => window.aircox.appConfig ).then(app => { window.aircox.app = app },\n () => undefined)\n\n\n\n\n//# sourceURL=webpack:///./assets/public/index.js?");
/***/ }),
@ -309,6 +345,18 @@ eval("__webpack_require__.r(__webpack_exports__);\n//\n//\n//\n//\n//\n//\n\n\nc
/***/ }),
/***/ "./node_modules/vue-loader/lib/index.js?!./assets/public/autocomplete.vue?vue&type=script&lang=js&":
/*!*******************************************************************************************************************!*\
!*** ./node_modules/vue-loader/lib??vue-loader-options!./assets/public/autocomplete.vue?vue&type=script&lang=js& ***!
\*******************************************************************************************************************/
/*! exports provided: default */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var lodash_debounce__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! lodash/debounce */ \"./node_modules/lodash/debounce.js\");\n/* harmony import */ var lodash_debounce__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(lodash_debounce__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var buefy_dist_components_autocomplete__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! buefy/dist/components/autocomplete */ \"./node_modules/buefy/dist/components/autocomplete/index.js\");\n/* harmony import */ var buefy_dist_components_autocomplete__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(buefy_dist_components_autocomplete__WEBPACK_IMPORTED_MODULE_1__);\n/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! vue */ \"./node_modules/vue/dist/vue.esm.browser.js\");\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n\n\n\n\n\n/* harmony default export */ __webpack_exports__[\"default\"] = ({\n props: {\n url: String,\n model: Function,\n placeholder: String,\n field: {type: String, default: 'value'},\n count: {type: Number, count: 10},\n valueAttr: String,\n valueField: String,\n },\n\n data() {\n return {\n data: [],\n selected: null,\n isFetching: false,\n };\n },\n\n methods: {\n onSelect(option) {\n console.log('selected', option)\n vue__WEBPACK_IMPORTED_MODULE_2__[\"default\"].set(this, 'selected', option);\n this.$emit('select', option);\n },\n\n fetch: lodash_debounce__WEBPACK_IMPORTED_MODULE_0___default()(function(query) {\n if(!query)\n return;\n\n this.isFetching = true;\n this.model.fetchAll(this.url.replace('${query}', query))\n .then(data => {\n this.data = data;\n this.isFetching = false;\n }, data => { this.isFetching = false; Promise.reject(data) })\n }),\n },\n\n components: {\n Autocomplete: buefy_dist_components_autocomplete__WEBPACK_IMPORTED_MODULE_1__[\"Autocomplete\"],\n },\n});\n\n\n\n//# sourceURL=webpack:///./assets/public/autocomplete.vue?./node_modules/vue-loader/lib??vue-loader-options");
/***/ }),
/***/ "./node_modules/vue-loader/lib/index.js?!./assets/public/player.vue?vue&type=script&lang=js&":
/*!*************************************************************************************************************!*\
!*** ./node_modules/vue-loader/lib??vue-loader-options!./assets/public/player.vue?vue&type=script&lang=js& ***!
@ -333,6 +381,18 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) *
/***/ }),
/***/ "./node_modules/vue-loader/lib/loaders/templateLoader.js?!./node_modules/vue-loader/lib/index.js?!./assets/public/autocomplete.vue?vue&type=template&id=70936760&":
/*!*****************************************************************************************************************************************************************************************************!*\
!*** ./node_modules/vue-loader/lib/loaders/templateLoader.js??vue-loader-options!./node_modules/vue-loader/lib??vue-loader-options!./assets/public/autocomplete.vue?vue&type=template&id=70936760& ***!
\*****************************************************************************************************************************************************************************************************/
/*! exports provided: render, staticRenderFns */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"render\", function() { return render; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"staticRenderFns\", function() { return staticRenderFns; });\nvar render = function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\n \"div\",\n { staticClass: \"control\" },\n [\n _c(\"Autocomplete\", {\n ref: \"autocomplete\",\n attrs: {\n data: _vm.data,\n placeholder: _vm.placeholder,\n field: _vm.field,\n loading: _vm.isFetching,\n \"open-on-focus\": \"\"\n },\n on: {\n typing: _vm.fetch,\n select: function(object) {\n return _vm.onSelect(object)\n }\n }\n }),\n _vm._v(\" \"),\n _vm.valueField\n ? _c(\"input\", {\n ref: \"value\",\n attrs: { type: \"hidden\", name: _vm.valueField },\n domProps: {\n value:\n _vm.selected && _vm.selected[_vm.valueAttr || _vm.valueField]\n }\n })\n : _vm._e()\n ],\n 1\n )\n}\nvar staticRenderFns = []\nrender._withStripped = true\n\n\n\n//# sourceURL=webpack:///./assets/public/autocomplete.vue?./node_modules/vue-loader/lib/loaders/templateLoader.js??vue-loader-options!./node_modules/vue-loader/lib??vue-loader-options");
/***/ }),
/***/ "./node_modules/vue-loader/lib/loaders/templateLoader.js?!./node_modules/vue-loader/lib/index.js?!./assets/public/player.vue?vue&type=template&id=42a56ec9&":
/*!***********************************************************************************************************************************************************************************************!*\
!*** ./node_modules/vue-loader/lib/loaders/templateLoader.js??vue-loader-options!./node_modules/vue-loader/lib??vue-loader-options!./assets/public/player.vue?vue&type=template&id=42a56ec9& ***!

View File

@ -189,6 +189,97 @@
fieldset[disabled] .pagination-ellipsis {
cursor: not-allowed; }
.dropdown {
display: inline-flex;
position: relative;
vertical-align: top; }
.dropdown.is-active .dropdown-menu, .dropdown.is-hoverable:hover .dropdown-menu {
display: block; }
.dropdown.is-right .dropdown-menu {
left: auto;
right: 0; }
.dropdown.is-up .dropdown-menu {
bottom: 100%;
padding-bottom: 4px;
padding-top: initial;
top: auto; }
.dropdown-menu {
display: none;
left: 0;
min-width: 12rem;
padding-top: 4px;
position: absolute;
top: 100%;
z-index: 20; }
.dropdown-content {
background-color: white;
border-radius: 4px;
box-shadow: 0 2px 3px rgba(10, 10, 10, 0.1), 0 0 0 1px rgba(10, 10, 10, 0.1);
padding-bottom: 0.5rem;
padding-top: 0.5rem; }
.dropdown-item {
color: #4a4a4a;
display: block;
font-size: 0.875rem;
line-height: 1.5;
padding: 0.375rem 1rem;
position: relative; }
a.dropdown-item,
button.dropdown-item {
padding-right: 3rem;
text-align: left;
white-space: nowrap;
width: 100%; }
a.dropdown-item:hover,
button.dropdown-item:hover {
background-color: whitesmoke;
color: #0a0a0a; }
a.dropdown-item.is-active,
button.dropdown-item.is-active {
background-color: #3273dc;
color: #fff; }
.dropdown-divider {
background-color: #dbdbdb;
border: none;
display: block;
height: 1px;
margin: 0.5rem 0; }
.autocomplete {
position: relative; }
.autocomplete .dropdown-menu {
display: block;
min-width: 100%;
max-width: 100%; }
.autocomplete .dropdown-menu.is-opened-top {
top: auto;
bottom: 100%; }
.autocomplete .dropdown-content {
overflow: auto;
max-height: 200px; }
.autocomplete .dropdown-item {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis; }
.autocomplete .dropdown-item.is-hovered {
background: whitesmoke;
color: #0a0a0a; }
.autocomplete .dropdown-item.is-disabled {
opacity: 0.5;
cursor: not-allowed; }
.autocomplete.is-small {
border-radius: 2px;
font-size: 0.75rem; }
.autocomplete.is-medium {
font-size: 1.25rem; }
.autocomplete.is-large {
font-size: 1.5rem; }
/*! bulma.io v0.7.5 | MIT License | github.com/jgthms/bulma */
@keyframes spinAround {
from {
@ -7159,6 +7250,9 @@ label.panel-block {
.is-borderless {
border: none; }
.has-text-nowrap {
white-space: nowrap; }
.has-background-transparent {
background-color: transparent; }
@ -7190,6 +7284,18 @@ a.navbar-item.is-active {
margin: 0em;
padding: 0em; }
.navbar.toolbar {
margin: 1em 0em;
background-color: transparent;
margin-bottom: 1em; }
.navbar.toolbar .title {
padding-right: 2em;
margin-right: 1em;
border-right: 1px #b5b5b5 solid;
font-size: 1.25rem;
color: #7a7a7a;
font-weight: 300; }
.card .title {
padding: 0.2em;
font-size: 1.25rem;
@ -7212,18 +7318,6 @@ a.navbar-item.is-active {
padding: 0.1em;
font-size: 0.8em; }
.filters {
margin: 1em 0em;
background-color: transparent;
margin-bottom: 1em; }
.filters .title {
padding-right: 2em;
margin-right: 1em;
border-right: 1px #b5b5b5 solid;
font-size: 1.25rem;
color: #7a7a7a;
font-weight: 300; }
.page > .cover {
float: right;
max-width: 45%; }

View File

@ -159,11 +159,47 @@
/*!******************************!*\
!*** ./assets/public/app.js ***!
\******************************/
/*! exports provided: app, default */
/*! exports provided: appBaseConfig, setAppConfig, getAppConfig, loadApp */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"app\", function() { return app; });\n/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! vue */ \"./node_modules/vue/dist/vue.esm.browser.js\");\n\n\n\nvar app = null;\n/* harmony default export */ __webpack_exports__[\"default\"] = (app);\n\nfunction loadApp() {\n app = new vue__WEBPACK_IMPORTED_MODULE_0__[\"default\"]({\n el: '#app',\n delimiters: [ '[[', ']]' ],\n })\n}\n\nwindow.addEventListener('load', loadApp);\n\n\n\n\n\n//# sourceURL=webpack:///./assets/public/app.js?");
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"appBaseConfig\", function() { return appBaseConfig; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"setAppConfig\", function() { return setAppConfig; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"getAppConfig\", function() { return getAppConfig; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"loadApp\", function() { return loadApp; });\n/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! vue */ \"./node_modules/vue/dist/vue.esm.browser.js\");\n\n\n\nconst appBaseConfig = {\n el: '#app',\n delimiters: ['[[', ']]'],\n}\n\n/**\n * Application config for the main application instance\n */\nvar appConfig = {};\n\nfunction setAppConfig(config) {\n for(var member in appConfig) delete appConfig[member];\n return Object.assign(appConfig, config)\n}\n\nfunction getAppConfig(config) {\n if(config instanceof Function)\n config = config()\n config = config == null ? appConfig : config;\n return {...appBaseConfig, ...config}\n}\n\n\n/**\n * Create Vue application at window 'load' event and return a Promise\n * resolving to the created app.\n *\n * config: defaults to appConfig (checked when window is loaded)\n */\nfunction loadApp(config=null) {\n return new Promise(function(resolve, reject) {\n window.addEventListener('load', function() {\n try {\n config = getAppConfig(config)\n const el = document.querySelector(config.el)\n if(!el) {\n reject(`Error: missing element ${config.el}`);\n return;\n }\n\n resolve(new vue__WEBPACK_IMPORTED_MODULE_0__[\"default\"](config))\n }\n catch(error) { reject(error) }\n })\n })\n}\n\n\n\n\n\n\n//# sourceURL=webpack:///./assets/public/app.js?");
/***/ }),
/***/ "./assets/public/autocomplete.vue":
/*!****************************************!*\
!*** ./assets/public/autocomplete.vue ***!
\****************************************/
/*! exports provided: default */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _autocomplete_vue_vue_type_template_id_70936760___WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./autocomplete.vue?vue&type=template&id=70936760& */ \"./assets/public/autocomplete.vue?vue&type=template&id=70936760&\");\n/* harmony import */ var _autocomplete_vue_vue_type_script_lang_js___WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./autocomplete.vue?vue&type=script&lang=js& */ \"./assets/public/autocomplete.vue?vue&type=script&lang=js&\");\n/* empty/unused harmony star reexport *//* harmony import */ var _node_modules_vue_loader_lib_runtime_componentNormalizer_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../node_modules/vue-loader/lib/runtime/componentNormalizer.js */ \"./node_modules/vue-loader/lib/runtime/componentNormalizer.js\");\n\n\n\n\n\n/* normalize component */\n\nvar component = Object(_node_modules_vue_loader_lib_runtime_componentNormalizer_js__WEBPACK_IMPORTED_MODULE_2__[\"default\"])(\n _autocomplete_vue_vue_type_script_lang_js___WEBPACK_IMPORTED_MODULE_1__[\"default\"],\n _autocomplete_vue_vue_type_template_id_70936760___WEBPACK_IMPORTED_MODULE_0__[\"render\"],\n _autocomplete_vue_vue_type_template_id_70936760___WEBPACK_IMPORTED_MODULE_0__[\"staticRenderFns\"],\n false,\n null,\n null,\n null\n \n)\n\n/* hot reload */\nif (false) { var api; }\ncomponent.options.__file = \"assets/public/autocomplete.vue\"\n/* harmony default export */ __webpack_exports__[\"default\"] = (component.exports);\n\n//# sourceURL=webpack:///./assets/public/autocomplete.vue?");
/***/ }),
/***/ "./assets/public/autocomplete.vue?vue&type=script&lang=js&":
/*!*****************************************************************!*\
!*** ./assets/public/autocomplete.vue?vue&type=script&lang=js& ***!
\*****************************************************************/
/*! exports provided: default */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _node_modules_vue_loader_lib_index_js_vue_loader_options_autocomplete_vue_vue_type_script_lang_js___WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! -!../../node_modules/vue-loader/lib??vue-loader-options!./autocomplete.vue?vue&type=script&lang=js& */ \"./node_modules/vue-loader/lib/index.js?!./assets/public/autocomplete.vue?vue&type=script&lang=js&\");\n/* empty/unused harmony star reexport */ /* harmony default export */ __webpack_exports__[\"default\"] = (_node_modules_vue_loader_lib_index_js_vue_loader_options_autocomplete_vue_vue_type_script_lang_js___WEBPACK_IMPORTED_MODULE_0__[\"default\"]); \n\n//# sourceURL=webpack:///./assets/public/autocomplete.vue?");
/***/ }),
/***/ "./assets/public/autocomplete.vue?vue&type=template&id=70936760&":
/*!***********************************************************************!*\
!*** ./assets/public/autocomplete.vue?vue&type=template&id=70936760& ***!
\***********************************************************************/
/*! exports provided: render, staticRenderFns */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _node_modules_vue_loader_lib_loaders_templateLoader_js_vue_loader_options_node_modules_vue_loader_lib_index_js_vue_loader_options_autocomplete_vue_vue_type_template_id_70936760___WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! -!../../node_modules/vue-loader/lib/loaders/templateLoader.js??vue-loader-options!../../node_modules/vue-loader/lib??vue-loader-options!./autocomplete.vue?vue&type=template&id=70936760& */ \"./node_modules/vue-loader/lib/loaders/templateLoader.js?!./node_modules/vue-loader/lib/index.js?!./assets/public/autocomplete.vue?vue&type=template&id=70936760&\");\n/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, \"render\", function() { return _node_modules_vue_loader_lib_loaders_templateLoader_js_vue_loader_options_node_modules_vue_loader_lib_index_js_vue_loader_options_autocomplete_vue_vue_type_template_id_70936760___WEBPACK_IMPORTED_MODULE_0__[\"render\"]; });\n\n/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, \"staticRenderFns\", function() { return _node_modules_vue_loader_lib_loaders_templateLoader_js_vue_loader_options_node_modules_vue_loader_lib_index_js_vue_loader_options_autocomplete_vue_vue_type_template_id_70936760___WEBPACK_IMPORTED_MODULE_0__[\"staticRenderFns\"]; });\n\n\n\n//# sourceURL=webpack:///./assets/public/autocomplete.vue?");
/***/ }),
@ -175,7 +211,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) *
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! vue */ \"./node_modules/vue/dist/vue.esm.browser.js\");\n/* harmony import */ var _fortawesome_fontawesome_free_css_all_min_css__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @fortawesome/fontawesome-free/css/all.min.css */ \"./node_modules/@fortawesome/fontawesome-free/css/all.min.css\");\n/* harmony import */ var _fortawesome_fontawesome_free_css_all_min_css__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_fortawesome_fontawesome_free_css_all_min_css__WEBPACK_IMPORTED_MODULE_1__);\n/* harmony import */ var _fortawesome_fontawesome_free_css_fontawesome_min_css__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @fortawesome/fontawesome-free/css/fontawesome.min.css */ \"./node_modules/@fortawesome/fontawesome-free/css/fontawesome.min.css\");\n/* harmony import */ var _fortawesome_fontawesome_free_css_fontawesome_min_css__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(_fortawesome_fontawesome_free_css_fontawesome_min_css__WEBPACK_IMPORTED_MODULE_2__);\n/* harmony import */ var _app__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./app */ \"./assets/public/app.js\");\n/* harmony import */ var _liveInfo__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./liveInfo */ \"./assets/public/liveInfo.js\");\n/* harmony import */ var _styles_scss__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./styles.scss */ \"./assets/public/styles.scss\");\n/* harmony import */ var _styles_scss__WEBPACK_IMPORTED_MODULE_5___default = /*#__PURE__*/__webpack_require__.n(_styles_scss__WEBPACK_IMPORTED_MODULE_5__);\n/* harmony import */ var _player_vue__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./player.vue */ \"./assets/public/player.vue\");\n/**\n * This module includes code available for both the public website and\n * administration interface)\n */\n//-- vendor\n\n\n\n\n\n\n//-- aircox\n\n\n\n\n\n\n\nvue__WEBPACK_IMPORTED_MODULE_0__[\"default\"].component('a-player', _player_vue__WEBPACK_IMPORTED_MODULE_6__[\"default\"])\n\n\nwindow.aircox = {\n app: _app__WEBPACK_IMPORTED_MODULE_3__[\"default\"],\n LiveInfo: _liveInfo__WEBPACK_IMPORTED_MODULE_4__[\"default\"],\n}\n\n\n\n//# sourceURL=webpack:///./assets/public/index.js?");
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! vue */ \"./node_modules/vue/dist/vue.esm.browser.js\");\n/* harmony import */ var _fortawesome_fontawesome_free_css_all_min_css__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @fortawesome/fontawesome-free/css/all.min.css */ \"./node_modules/@fortawesome/fontawesome-free/css/all.min.css\");\n/* harmony import */ var _fortawesome_fontawesome_free_css_all_min_css__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_fortawesome_fontawesome_free_css_all_min_css__WEBPACK_IMPORTED_MODULE_1__);\n/* harmony import */ var _fortawesome_fontawesome_free_css_fontawesome_min_css__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @fortawesome/fontawesome-free/css/fontawesome.min.css */ \"./node_modules/@fortawesome/fontawesome-free/css/fontawesome.min.css\");\n/* harmony import */ var _fortawesome_fontawesome_free_css_fontawesome_min_css__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(_fortawesome_fontawesome_free_css_fontawesome_min_css__WEBPACK_IMPORTED_MODULE_2__);\n/* harmony import */ var _app__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./app */ \"./assets/public/app.js\");\n/* harmony import */ var _styles_scss__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./styles.scss */ \"./assets/public/styles.scss\");\n/* harmony import */ var _styles_scss__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(_styles_scss__WEBPACK_IMPORTED_MODULE_4__);\n/* harmony import */ var _player_vue__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./player.vue */ \"./assets/public/player.vue\");\n/* harmony import */ var _autocomplete_vue__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./autocomplete.vue */ \"./assets/public/autocomplete.vue\");\n/**\n * This module includes code available for both the public website and\n * administration interface)\n */\n//-- vendor\n\n\n\n\n\n\n//-- aircox\n\n\n\n\n\n\n\nvue__WEBPACK_IMPORTED_MODULE_0__[\"default\"].component('a-player', _player_vue__WEBPACK_IMPORTED_MODULE_5__[\"default\"])\nvue__WEBPACK_IMPORTED_MODULE_0__[\"default\"].component('a-autocomplete', _autocomplete_vue__WEBPACK_IMPORTED_MODULE_6__[\"default\"])\n\n\nwindow.aircox = {\n // main application\n app: null,\n\n // main application config\n appConfig: {},\n\n // player application\n playerApp: null,\n\n // player component\n get player() {\n return this.playerApp && this.playerApp.$refs.player\n }\n};\n\n\nObject(_app__WEBPACK_IMPORTED_MODULE_3__[\"loadApp\"])({el: '#player'}).then(app => { window.aircox.playerApp = app },\n () => undefined)\nObject(_app__WEBPACK_IMPORTED_MODULE_3__[\"loadApp\"])(() => window.aircox.appConfig ).then(app => { window.aircox.app = app },\n () => undefined)\n\n\n\n\n//# sourceURL=webpack:///./assets/public/index.js?");
/***/ }),
@ -238,6 +274,18 @@ eval("// extracted by mini-css-extract-plugin\n\n//# sourceURL=webpack:///./asse
/***/ }),
/***/ "./node_modules/vue-loader/lib/index.js?!./assets/public/autocomplete.vue?vue&type=script&lang=js&":
/*!*******************************************************************************************************************!*\
!*** ./node_modules/vue-loader/lib??vue-loader-options!./assets/public/autocomplete.vue?vue&type=script&lang=js& ***!
\*******************************************************************************************************************/
/*! exports provided: default */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var lodash_debounce__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! lodash/debounce */ \"./node_modules/lodash/debounce.js\");\n/* harmony import */ var lodash_debounce__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(lodash_debounce__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var buefy_dist_components_autocomplete__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! buefy/dist/components/autocomplete */ \"./node_modules/buefy/dist/components/autocomplete/index.js\");\n/* harmony import */ var buefy_dist_components_autocomplete__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(buefy_dist_components_autocomplete__WEBPACK_IMPORTED_MODULE_1__);\n/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! vue */ \"./node_modules/vue/dist/vue.esm.browser.js\");\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n\n\n\n\n\n/* harmony default export */ __webpack_exports__[\"default\"] = ({\n props: {\n url: String,\n model: Function,\n placeholder: String,\n field: {type: String, default: 'value'},\n count: {type: Number, count: 10},\n valueAttr: String,\n valueField: String,\n },\n\n data() {\n return {\n data: [],\n selected: null,\n isFetching: false,\n };\n },\n\n methods: {\n onSelect(option) {\n console.log('selected', option)\n vue__WEBPACK_IMPORTED_MODULE_2__[\"default\"].set(this, 'selected', option);\n this.$emit('select', option);\n },\n\n fetch: lodash_debounce__WEBPACK_IMPORTED_MODULE_0___default()(function(query) {\n if(!query)\n return;\n\n this.isFetching = true;\n this.model.fetchAll(this.url.replace('${query}', query))\n .then(data => {\n this.data = data;\n this.isFetching = false;\n }, data => { this.isFetching = false; Promise.reject(data) })\n }),\n },\n\n components: {\n Autocomplete: buefy_dist_components_autocomplete__WEBPACK_IMPORTED_MODULE_1__[\"Autocomplete\"],\n },\n});\n\n\n\n//# sourceURL=webpack:///./assets/public/autocomplete.vue?./node_modules/vue-loader/lib??vue-loader-options");
/***/ }),
/***/ "./node_modules/vue-loader/lib/index.js?!./assets/public/player.vue?vue&type=script&lang=js&":
/*!*************************************************************************************************************!*\
!*** ./node_modules/vue-loader/lib??vue-loader-options!./assets/public/player.vue?vue&type=script&lang=js& ***!
@ -250,6 +298,18 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) *
/***/ }),
/***/ "./node_modules/vue-loader/lib/loaders/templateLoader.js?!./node_modules/vue-loader/lib/index.js?!./assets/public/autocomplete.vue?vue&type=template&id=70936760&":
/*!*****************************************************************************************************************************************************************************************************!*\
!*** ./node_modules/vue-loader/lib/loaders/templateLoader.js??vue-loader-options!./node_modules/vue-loader/lib??vue-loader-options!./assets/public/autocomplete.vue?vue&type=template&id=70936760& ***!
\*****************************************************************************************************************************************************************************************************/
/*! exports provided: render, staticRenderFns */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"render\", function() { return render; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"staticRenderFns\", function() { return staticRenderFns; });\nvar render = function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\n \"div\",\n { staticClass: \"control\" },\n [\n _c(\"Autocomplete\", {\n ref: \"autocomplete\",\n attrs: {\n data: _vm.data,\n placeholder: _vm.placeholder,\n field: _vm.field,\n loading: _vm.isFetching,\n \"open-on-focus\": \"\"\n },\n on: {\n typing: _vm.fetch,\n select: function(object) {\n return _vm.onSelect(object)\n }\n }\n }),\n _vm._v(\" \"),\n _vm.valueField\n ? _c(\"input\", {\n ref: \"value\",\n attrs: { type: \"hidden\", name: _vm.valueField },\n domProps: {\n value:\n _vm.selected && _vm.selected[_vm.valueAttr || _vm.valueField]\n }\n })\n : _vm._e()\n ],\n 1\n )\n}\nvar staticRenderFns = []\nrender._withStripped = true\n\n\n\n//# sourceURL=webpack:///./assets/public/autocomplete.vue?./node_modules/vue-loader/lib/loaders/templateLoader.js??vue-loader-options!./node_modules/vue-loader/lib??vue-loader-options");
/***/ }),
/***/ "./node_modules/vue-loader/lib/loaders/templateLoader.js?!./node_modules/vue-loader/lib/index.js?!./assets/public/player.vue?vue&type=template&id=42a56ec9&":
/*!***********************************************************************************************************************************************************************************************!*\
!*** ./node_modules/vue-loader/lib/loaders/templateLoader.js??vue-loader-options!./node_modules/vue-loader/lib??vue-loader-options!./assets/public/player.vue?vue&type=template&id=42a56ec9& ***!

File diff suppressed because one or more lines are too long

View File

@ -1,9 +1,10 @@
{% load i18n static %}<!DOCTYPE html>
{% load i18n static aircox_admin %}<!DOCTYPE html>
{% get_current_language as LANGUAGE_CODE %}{% get_current_language_bidi as LANGUAGE_BIDI %}
<html lang="{{ LANGUAGE_CODE|default:"en-us" }}" {% if LANGUAGE_BIDI %}dir="rtl"{% endif %}>
<head>
<title>{% block title %}{% endblock %}</title>
<link rel="stylesheet" type="text/css" href="{% static "aircox/vendor.css" %}">
<link rel="stylesheet" type="text/css" href="{% static "admin/css/base.css" %}">
<link rel="stylesheet" type="text/css" href="{% static "aircox/main.css" %}">
<link rel="stylesheet" type="text/css" href="{% static "aircox/admin.css" %}">
@ -67,7 +68,10 @@
<div class="navbar-item has-dropdown is-hoverable">
<a href="#" class="navbar-link">{% trans "Tools" %}</a>
<div class="navbar-dropdown is-boxed is-right">
<a href="{% url 'admin:tools-stats' %}" class="navbar-item">{% trans "Statistics" %}</a>
{% get_admin_tools as admin_tools %}
{% for label, url in admin_tools %}
<a href="{{ url }}" class="navbar-item">{{ label }}</a>
{% endfor %}
</div>
</div>
@ -121,7 +125,7 @@
<!-- Content -->
<div id="content" class="{% block coltype %}colM{% endblock %}">
{% block pretitle %}{% endblock %}
{% block content_title %}{% if title %}<h1 class="subtitle is-3">{{ title }}</h1>{% endif %}{% endblock %}
{% block content_title %}{% if title %}<h1 class="title is-3">{{ title }}</h1>{% endif %}{% endblock %}
{% block content %}
{% block object-tools %}{% endblock %}
{{ content }}

View File

@ -93,7 +93,7 @@ Blocks:
{% block main %}
{% if has_filters %}
<nav class="navbar filters"
<nav class="navbar toolbar"
aria-label="{% trans "list filters" %}">
{% block filters %}{% endblock %}
</nav>
@ -132,8 +132,8 @@ Blocks:
</div>
<hr>
{% include "aircox/player.html" %}
</div>
<div id="player">{% include "aircox/player.html" %}</div>
</body>
</html>

View File

@ -38,7 +38,9 @@ Context:
<hr>
<h4 class="title is-4">{% trans "Last publications" %}</h4>
{% with has_headline=True %}
{{ block.super }}
{% endwith %}
{% endblock %}

View File

@ -16,7 +16,7 @@
</noscript>
<a-player ref="player" src="{{ audio_streams.0 }}"
live-info-url="{% url "api-live" %}" :live-info-timeout="15"
live-info-url="{% url "api-live" %}" :live-info-timeout="20"
button-title="{% trans "Play or pause audio" %}">
<template v-slot:sources>
{% for stream in audio_streams %}

View File

@ -12,12 +12,17 @@ __all__ = ['BaseAdminView', 'StatisticsView']
class BaseAdminView(LoginRequiredMixin, UserPassesTestMixin):
title = ''
@property
def station(self):
return self.request.station
def test_func(self):
return self.request.user.is_staff
def get_context_data(self, **kwargs):
kwargs.update(admin.site.each_context(self.request))
kwargs.setdefault('title', self.title)
kwargs.setdefault('station', self.station)
return super().get_context_data(**kwargs)