Vue3: Remove unnecessary wrapping div.

This commit is contained in:
Buster Neece 2022-12-17 19:07:15 -06:00
parent 8259989f6a
commit 27e5be80ee
No known key found for this signature in database
GPG Key ID: F1D2E64A0005E80E
40 changed files with 2503 additions and 2558 deletions

View File

@ -1,32 +1,30 @@
<template>
<div>
<h3 class="card-subtitle">{{ $gettext('New Key Generated') }}</h3>
<h3 class="card-subtitle">{{ $gettext('New Key Generated') }}</h3>
<p class="card-text">
<b>{{ $gettext('Important: copy the key below before continuing!') }}</b>
{{ $gettext('You will not be able to retrieve it again.') }}
</p>
<p class="card-text">
<b>{{ $gettext('Important: copy the key below before continuing!') }}</b>
{{ $gettext('You will not be able to retrieve it again.') }}
</p>
<p class="card-text">
{{ $gettext('Your full API key is below:') }}
</p>
<p class="card-text">
{{ $gettext('Your full API key is below:') }}
</p>
<div class="px-2">
<code id="api_key">{{ newKey }}</code>
<div class="buttons pt-2">
<copy-to-clipboard-button :text="newKey"></copy-to-clipboard-button>
</div>
<div class="px-2">
<code id="api_key">{{ newKey }}</code>
<div class="buttons pt-2">
<copy-to-clipboard-button :text="newKey"></copy-to-clipboard-button>
</div>
<p class="card-text pt-3">
{{
$gettext('When making API calls, you can pass this value in the "X-API-Key" header to authenticate as yourself.')
}}
</p>
<p class="card-text">
{{ $gettext('You can only perform the actions your user account is allowed to perform.') }}
</p>
</div>
<p class="card-text pt-3">
{{
$gettext('When making API calls, you can pass this value in the "X-API-Key" header to authenticate as yourself.')
}}
</p>
<p class="card-text">
{{ $gettext('You can only perform the actions your user account is allowed to perform.') }}
</p>
</template>
<script setup>

View File

@ -1,68 +1,66 @@
<template>
<div>
<b-form-fieldset>
<b-form-row>
<b-wrapped-form-group class="col-md-6" id="form_name" :field="form.name">
<b-form-fieldset>
<b-form-row>
<b-wrapped-form-group class="col-md-6" id="form_name" :field="form.name">
<template #label>
{{ $gettext('Name') }}
</template>
</b-wrapped-form-group>
<b-wrapped-form-group class="col-md-6" id="form_email" :field="form.email">
<template #label>
{{ $gettext('E-mail Address') }}
</template>
</b-wrapped-form-group>
</b-form-row>
</b-form-fieldset>
<b-form-fieldset>
<template #label>
{{ $gettext('Customization') }}
</template>
<b-form-row>
<b-col md="6">
<b-wrapped-form-group id="edit_form_locale"
:field="form.locale">
<template #label>
{{ $gettext('Name') }}
{{ $gettext('Language') }}
</template>
<template #default="props">
<b-form-radio-group stacked :id="props.id" :options="localeOptions"
v-model="props.field.$model">
</b-form-radio-group>
</template>
</b-wrapped-form-group>
</b-col>
<b-col md="6">
<b-wrapped-form-group id="edit_form_theme"
:field="form.theme">
<template #label>
{{ $gettext('Site Theme') }}
</template>
<template #default="props">
<b-form-radio-group stacked :id="props.id" :options="themeOptions"
v-model="props.field.$model">
</b-form-radio-group>
</template>
</b-wrapped-form-group>
<b-wrapped-form-group class="col-md-6" id="form_email" :field="form.email">
<b-wrapped-form-group id="edit_form_show_24_hour_time"
:field="form.show_24_hour_time">
<template #label>
{{ $gettext('E-mail Address') }}
{{ $gettext('Time Display') }}
</template>
<template #default="props">
<b-form-radio-group stacked :id="props.id" :options="show24hourOptions"
v-model="props.field.$model">
</b-form-radio-group>
</template>
</b-wrapped-form-group>
</b-form-row>
</b-form-fieldset>
<b-form-fieldset>
<template #label>
{{ $gettext('Customization') }}
</template>
<b-form-row>
<b-col md="6">
<b-wrapped-form-group id="edit_form_locale"
:field="form.locale">
<template #label>
{{ $gettext('Language') }}
</template>
<template #default="props">
<b-form-radio-group stacked :id="props.id" :options="localeOptions"
v-model="props.field.$model">
</b-form-radio-group>
</template>
</b-wrapped-form-group>
</b-col>
<b-col md="6">
<b-wrapped-form-group id="edit_form_theme"
:field="form.theme">
<template #label>
{{ $gettext('Site Theme') }}
</template>
<template #default="props">
<b-form-radio-group stacked :id="props.id" :options="themeOptions"
v-model="props.field.$model">
</b-form-radio-group>
</template>
</b-wrapped-form-group>
<b-wrapped-form-group id="edit_form_show_24_hour_time"
:field="form.show_24_hour_time">
<template #label>
{{ $gettext('Time Display') }}
</template>
<template #default="props">
<b-form-radio-group stacked :id="props.id" :options="show24hourOptions"
v-model="props.field.$model">
</b-form-radio-group>
</template>
</b-wrapped-form-group>
</b-col>
</b-form-row>
</b-form-fieldset>
</div>
</b-col>
</b-form-row>
</b-form-fieldset>
</template>
<script>

View File

@ -1,48 +1,46 @@
<template>
<div>
<b-card no-body>
<b-card-header header-bg-variant="primary-dark">
<h2 class="card-title">{{ $gettext('Custom Fields') }}</h2>
</b-card-header>
<b-card no-body>
<b-card-header header-bg-variant="primary-dark">
<h2 class="card-title">{{ $gettext('Custom Fields') }}</h2>
</b-card-header>
<info-card>
<p class="card-text">
{{
$gettext('Create custom fields to store extra metadata about each media file uploaded to your station libraries.')
}}
</p>
</info-card>
<info-card>
<p class="card-text">
{{
$gettext('Create custom fields to store extra metadata about each media file uploaded to your station libraries.')
}}
</p>
</info-card>
<b-card-body body-class="card-padding-sm">
<b-button variant="outline-primary" @click.prevent="doCreate">
<icon icon="add"></icon>
{{ $gettext('Add Custom Field') }}
</b-button>
</b-card-body>
<b-card-body body-class="card-padding-sm">
<b-button variant="outline-primary" @click.prevent="doCreate">
<icon icon="add"></icon>
{{ $gettext('Add Custom Field') }}
</b-button>
</b-card-body>
<data-table ref="datatable" id="custom_fields" :fields="fields" :show-toolbar="false" :api-url="listUrl">
<template #cell(name)="row">
{{ row.item.name }} <code>{{ row.item.short_name }}</code>
</template>
<template #cell(auto_assign)="row">
{{ getAutoAssignName(row.item.auto_assign) }}
</template>
<template #cell(actions)="row">
<b-button-group size="sm">
<b-button size="sm" variant="primary" @click.prevent="doEdit(row.item.links.self)">
{{ $gettext('Edit') }}
</b-button>
<b-button size="sm" variant="danger" @click.prevent="doDelete(row.item.links.self)">
{{ $gettext('Delete') }}
</b-button>
</b-button-group>
</template>
</data-table>
</b-card>
<data-table ref="datatable" id="custom_fields" :fields="fields" :show-toolbar="false" :api-url="listUrl">
<template #cell(name)="row">
{{ row.item.name }} <code>{{ row.item.short_name }}</code>
</template>
<template #cell(auto_assign)="row">
{{ getAutoAssignName(row.item.auto_assign) }}
</template>
<template #cell(actions)="row">
<b-button-group size="sm">
<b-button size="sm" variant="primary" @click.prevent="doEdit(row.item.links.self)">
{{ $gettext('Edit') }}
</b-button>
<b-button size="sm" variant="danger" @click.prevent="doDelete(row.item.links.self)">
{{ $gettext('Delete') }}
</b-button>
</b-button-group>
</template>
</data-table>
</b-card>
<edit-modal ref="editModal" :create-url="listUrl" :auto-assign-types="autoAssignTypes"
@relist="relist"></edit-modal>
</div>
<edit-modal ref="editModal" :create-url="listUrl" :auto-assign-types="autoAssignTypes"
@relist="relist"></edit-modal>
</template>
<script>

View File

@ -1,31 +1,29 @@
<template>
<div>
<div class="card mb-3">
<div class="card-header bg-primary-dark">
<h2 class="card-title">
{{ $gettext('System Logs') }}
</h2>
</div>
<log-list :url="systemLogsUrl" @view="viewLog"></log-list>
<div class="card mb-3">
<div class="card-header bg-primary-dark">
<h2 class="card-title">
{{ $gettext('System Logs') }}
</h2>
</div>
<div class="card" v-if="stationLogs.length > 0">
<div class="card-header bg-primary-dark">
<h2 class="card-title">
{{ $gettext('Logs by Station') }}
</h2>
</div>
<b-tabs pills lazy nav-class="card-header-pills" nav-wrapper-class="card-header">
<b-tab v-for="row in stationLogs" :key="row.id" :title="row.name">
<log-list :url="row.url" @view="viewLog"></log-list>
</b-tab>
</b-tabs>
</div>
<streaming-log-modal ref="modal"></streaming-log-modal>
<log-list :url="systemLogsUrl" @view="viewLog"></log-list>
</div>
<div class="card" v-if="stationLogs.length > 0">
<div class="card-header bg-primary-dark">
<h2 class="card-title">
{{ $gettext('Logs by Station') }}
</h2>
</div>
<b-tabs pills lazy nav-class="card-header-pills" nav-wrapper-class="card-header">
<b-tab v-for="row in stationLogs" :key="row.id" :title="row.name">
<log-list :url="row.url" @view="viewLog"></log-list>
</b-tab>
</b-tabs>
</div>
<streaming-log-modal ref="modal"></streaming-log-modal>
</template>
<script>

View File

@ -1,54 +1,52 @@
<template>
<div>
<b-card no-body>
<b-card-header header-bg-variant="primary-dark">
<h2 class="card-title">{{ $gettext('Roles & Permissions') }}</h2>
</b-card-header>
<b-card no-body>
<b-card-header header-bg-variant="primary-dark">
<h2 class="card-title">{{ $gettext('Roles & Permissions') }}</h2>
</b-card-header>
<info-card>
<p class="card-text">
{{
$gettext('AzuraCast uses a role-based access control system. Roles are given permissions to certain sections of the site, then users are assigned into those roles.')
}}
</p>
</info-card>
<info-card>
<p class="card-text">
{{
$gettext('AzuraCast uses a role-based access control system. Roles are given permissions to certain sections of the site, then users are assigned into those roles.')
}}
</p>
</info-card>
<b-card-body body-class="card-padding-sm">
<b-button variant="outline-primary" @click.prevent="doCreate">
<icon icon="add"></icon>
{{ $gettext('Add Role') }}
</b-button>
</b-card-body>
<b-card-body body-class="card-padding-sm">
<b-button variant="outline-primary" @click.prevent="doCreate">
<icon icon="add"></icon>
{{ $gettext('Add Role') }}
</b-button>
</b-card-body>
<data-table ref="datatable" id="permissions" paginated :fields="fields" :api-url="listUrl">
<template #cell(permissions)="row">
<div v-if="row.item.permissions.global.length > 0">
{{ $gettext('Global') }}
:
{{ getGlobalPermissionNames(row.item.permissions.global).join(', ') }}
</div>
<div v-for="(permissions, stationId) in row.item.permissions.station" :key="stationId">
<b>{{ getStationName(stationId) }}</b>:
{{ getStationPermissionNames(permissions).join(', ') }}
</div>
</template>
<template #cell(actions)="row">
<b-button-group size="sm" v-if="!row.item.is_super_admin">
<b-button size="sm" variant="primary" @click.prevent="doEdit(row.item.links.self)">
{{ $gettext('Edit') }}
</b-button>
<b-button v-if="row.item.id !== 1" size="sm" variant="danger"
@click.prevent="doDelete(row.item.links.self)">
{{ $gettext('Delete') }}
</b-button>
</b-button-group>
</template>
</data-table>
</b-card>
<data-table ref="datatable" id="permissions" paginated :fields="fields" :api-url="listUrl">
<template #cell(permissions)="row">
<div v-if="row.item.permissions.global.length > 0">
{{ $gettext('Global') }}
:
{{ getGlobalPermissionNames(row.item.permissions.global).join(', ') }}
</div>
<div v-for="(permissions, stationId) in row.item.permissions.station" :key="stationId">
<b>{{ getStationName(stationId) }}</b>:
{{ getStationPermissionNames(permissions).join(', ') }}
</div>
</template>
<template #cell(actions)="row">
<b-button-group size="sm" v-if="!row.item.is_super_admin">
<b-button size="sm" variant="primary" @click.prevent="doEdit(row.item.links.self)">
{{ $gettext('Edit') }}
</b-button>
<b-button v-if="row.item.id !== 1" size="sm" variant="danger"
@click.prevent="doDelete(row.item.links.self)">
{{ $gettext('Delete') }}
</b-button>
</b-button-group>
</template>
</data-table>
</b-card>
<edit-modal ref="editModal" :create-url="listUrl" :station-permissions="stationPermissions" :stations="stations"
:global-permissions="globalPermissions" @relist="relist"></edit-modal>
</div>
<edit-modal ref="editModal" :create-url="listUrl" :station-permissions="stationPermissions" :stations="stations"
:global-permissions="globalPermissions" @relist="relist"></edit-modal>
</template>
<script>

View File

@ -1,83 +1,81 @@
<template>
<div>
<b-form-fieldset>
<template #label>
{{ $gettext('Privacy') }}
</template>
<b-form-fieldset>
<template #label>
{{ $gettext('Privacy') }}
</template>
<b-form-row>
<b-wrapped-form-group class="col-md-12" id="edit_form_analytics" :field="form.analytics">
<template #label="{lang}">
{{ $gettext('Listener Analytics Collection') }}
</template>
<template #description="{lang}">
{{
$gettext('Aggregate listener statistics are used to show station reports across the system. IP-based listener statistics are used to view live listener tracking and may be required for royalty reports.')
}}
</template>
<template #default="props">
<b-form-radio-group stacked :id="props.id" v-model="props.field.$model">
<b-form-radio value="all">
<b>
{{ $gettext('Full:') }}
</b>
{{ $gettext('Collect aggregate listener statistics and IP-based listener statistics') }}
</b-form-radio>
<b-form-radio value="no_ip">
<b>
{{ $gettext('Limited:') }}
</b>
{{ $gettext('Only collect aggregate listener statistics') }}
</b-form-radio>
<b-form-radio value="none">
<b>
{{ $gettext('None:') }}
</b>
{{ $gettext('Do not collect any listener analytics') }}
</b-form-radio>
</b-form-radio-group>
</template>
</b-wrapped-form-group>
</b-form-row>
</b-form-fieldset>
<b-form-row>
<b-wrapped-form-group class="col-md-12" id="edit_form_analytics" :field="form.analytics">
<template #label="{lang}">
{{ $gettext('Listener Analytics Collection') }}
</template>
<template #description="{lang}">
{{
$gettext('Aggregate listener statistics are used to show station reports across the system. IP-based listener statistics are used to view live listener tracking and may be required for royalty reports.')
}}
</template>
<template #default="props">
<b-form-radio-group stacked :id="props.id" v-model="props.field.$model">
<b-form-radio value="all">
<b>
{{ $gettext('Full:') }}
</b>
{{ $gettext('Collect aggregate listener statistics and IP-based listener statistics') }}
</b-form-radio>
<b-form-radio value="no_ip">
<b>
{{ $gettext('Limited:') }}
</b>
{{ $gettext('Only collect aggregate listener statistics') }}
</b-form-radio>
<b-form-radio value="none">
<b>
{{ $gettext('None:') }}
</b>
{{ $gettext('Do not collect any listener analytics') }}
</b-form-radio>
</b-form-radio-group>
</template>
</b-wrapped-form-group>
</b-form-row>
</b-form-fieldset>
<b-form-fieldset>
<template #label>
{{ $gettext('Security') }}
</template>
<b-form-fieldset>
<template #label>
{{ $gettext('Security') }}
</template>
<b-form-row>
<b-wrapped-form-checkbox class="col-md-12" id="edit_form_always_use_ssl"
:field="form.always_use_ssl">
<template #label="{lang}">
{{ $gettext('Always Use HTTPS') }}
</template>
<template #description="{lang}">
{{
$gettext('Set to "Yes" to always use "https://" secure URLs, and to automatically redirect to the secure URL when an insecure URL is visited.')
}}
</template>
</b-wrapped-form-checkbox>
<b-form-row>
<b-wrapped-form-checkbox class="col-md-12" id="edit_form_always_use_ssl"
:field="form.always_use_ssl">
<template #label="{lang}">
{{ $gettext('Always Use HTTPS') }}
</template>
<template #description="{lang}">
{{
$gettext('Set to "Yes" to always use "https://" secure URLs, and to automatically redirect to the secure URL when an insecure URL is visited.')
}}
</template>
</b-wrapped-form-checkbox>
<b-wrapped-form-group class="col-md-12" id="edit_form_api_access_control"
:field="form.api_access_control">
<template #label="{lang}">
{{ $gettext('API "Access-Control-Allow-Origin" Header') }}
</template>
<template #description="{lang}">
{{
$gettext('Set to * to allow all sources, or specify a list of origins separated by a comma (,).')
}}
<br>
<a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Origin"
target="_blank">
{{ $gettext('Learn more about this header.') }}
</a>
</template>
</b-wrapped-form-group>
</b-form-row>
</b-form-fieldset>
</div>
<b-wrapped-form-group class="col-md-12" id="edit_form_api_access_control"
:field="form.api_access_control">
<template #label="{lang}">
{{ $gettext('API "Access-Control-Allow-Origin" Header') }}
</template>
<template #description="{lang}">
{{
$gettext('Set to * to allow all sources, or specify a list of origins separated by a comma (,).')
}}
<br>
<a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Origin"
target="_blank">
{{ $gettext('Learn more about this header.') }}
</a>
</template>
</b-wrapped-form-group>
</b-form-row>
</b-form-fieldset>
</template>
<script>

View File

@ -1,230 +1,228 @@
<template>
<div>
<b-form-fieldset>
<template #label>
{{ $gettext('AzuraCast Update Checks') }}
</template>
<b-form-fieldset>
<template #label>
{{ $gettext('AzuraCast Update Checks') }}
</template>
<b-form-row>
<b-form-markup class="col-md-6" id="form_release_channel">
<template #label="{lang}">
{{ $gettext('Release Channel') }}
</template>
<template #description="{lang}">
<a href="https://docs.azuracast.com/en/getting-started/updates/release-channels"
target="_blank">
{{ $gettext('Learn more about release channels in the AzuraCast docs.') }}
</a>
</template>
<b-form-row>
<b-form-markup class="col-md-6" id="form_release_channel">
<template #label="{lang}">
{{ $gettext('Release Channel') }}
</template>
<template #description="{lang}">
<a href="https://docs.azuracast.com/en/getting-started/updates/release-channels"
target="_blank">
{{ $gettext('Learn more about release channels in the AzuraCast docs.') }}
</a>
</template>
<p class="card-text font-weight-bold">
{{ langReleaseChannel }}
</p>
</b-form-markup>
<p class="card-text font-weight-bold">
{{ langReleaseChannel }}
</p>
</b-form-markup>
<b-wrapped-form-checkbox class="col-md-6" id="edit_form_check_for_updates"
:field="form.check_for_updates">
<template #label="{lang}">
{{ $gettext('Show Update Announcements') }}
</template>
<template #description="{lang}">
{{ $gettext('Show new releases within your update channel on the AzuraCast homepage.') }}
</template>
</b-wrapped-form-checkbox>
</b-form-row>
</b-form-fieldset>
<b-wrapped-form-checkbox class="col-md-6" id="edit_form_check_for_updates"
:field="form.check_for_updates">
<template #label="{lang}">
{{ $gettext('Show Update Announcements') }}
</template>
<template #description="{lang}">
{{ $gettext('Show new releases within your update channel on the AzuraCast homepage.') }}
</template>
</b-wrapped-form-checkbox>
</b-form-row>
</b-form-fieldset>
<b-form-fieldset>
<template #label>
{{ $gettext('LetsEncrypt') }}
</template>
<template #description>
{{
$gettext('LetsEncrypt provides simple, free SSL certificates allowing you to secure traffic through your control panel and radio streams.')
}}
</template>
<b-form-fieldset>
<template #label>
{{ $gettext('LetsEncrypt') }}
</template>
<template #description>
{{
$gettext('LetsEncrypt provides simple, free SSL certificates allowing you to secure traffic through your control panel and radio streams.')
}}
</template>
<b-form-row>
<b-wrapped-form-group class="col-md-6" id="edit_form_acme_domains"
:field="form.acme_domains">
<template #label="{lang}">
{{ $gettext('Domain Name(s)') }}
</template>
<template #description="{lang}">
{{
$gettext('All listed domain names should point to this AzuraCast installation. Separate multiple domain names with commas.')
}}
</template>
</b-wrapped-form-group>
<b-form-row>
<b-wrapped-form-group class="col-md-6" id="edit_form_acme_domains"
:field="form.acme_domains">
<template #label="{lang}">
{{ $gettext('Domain Name(s)') }}
</template>
<template #description="{lang}">
{{
$gettext('All listed domain names should point to this AzuraCast installation. Separate multiple domain names with commas.')
}}
</template>
</b-wrapped-form-group>
<b-wrapped-form-group class="col-md-6" id="edit_form_acme_email"
:field="form.acme_email" input-type="email">
<template #label="{lang}">
{{ $gettext('E-mail Address (Optional)') }}
</template>
<template #description="{lang}">
{{ $gettext('Enter your e-mail address to receive updates about your certificate.') }}
</template>
</b-wrapped-form-group>
<b-wrapped-form-group class="col-md-6" id="edit_form_acme_email"
:field="form.acme_email" input-type="email">
<template #label="{lang}">
{{ $gettext('E-mail Address (Optional)') }}
</template>
<template #description="{lang}">
{{ $gettext('Enter your e-mail address to receive updates about your certificate.') }}
</template>
</b-wrapped-form-group>
<div class="form-group col">
<b-button size="sm" variant="primary" :disabled="form.$anyDirty" @click="generateAcmeCert">
<icon icon="badge"></icon>
{{ $gettext('Generate/Renew Certificate') }}
<span v-if="form.$anyDirty">
({{ $gettext('Save Changes first') }})
</span>
</b-button>
</div>
</b-form-row>
</b-form-fieldset>
<div class="form-group col">
<b-button size="sm" variant="primary" :disabled="form.$anyDirty" @click="generateAcmeCert">
<icon icon="badge"></icon>
{{ $gettext('Generate/Renew Certificate') }}
<span v-if="form.$anyDirty">
({{ $gettext('Save Changes first') }})
</span>
</b-button>
</div>
</b-form-row>
</b-form-fieldset>
<b-form-fieldset>
<template #label>
{{ $gettext('E-mail Delivery Service') }}
</template>
<template #description>
{{ $gettext('Used for "Forgot Password" functionality, web hooks and other functions.') }}
</template>
<b-form-fieldset>
<template #label>
{{ $gettext('E-mail Delivery Service') }}
</template>
<template #description>
{{ $gettext('Used for "Forgot Password" functionality, web hooks and other functions.') }}
</template>
<b-form-row>
<b-wrapped-form-checkbox class="col-md-12" id="edit_form_mail_enabled"
:field="form.mail_enabled">
<template #label="{lang}">
{{ $gettext('Enable Mail Delivery') }}
</template>
</b-wrapped-form-checkbox>
</b-form-row>
<b-form-row>
<b-wrapped-form-checkbox class="col-md-12" id="edit_form_mail_enabled"
:field="form.mail_enabled">
<template #label="{lang}">
{{ $gettext('Enable Mail Delivery') }}
</template>
</b-wrapped-form-checkbox>
</b-form-row>
<b-form-row v-if="form.mail_enabled.$model" class="mt-2">
<b-wrapped-form-group class="col-md-6" id="edit_form_mail_sender_name"
:field="form.mail_sender_name">
<template #label="{lang}">
{{ $gettext('Sender Name') }}
</template>
</b-wrapped-form-group>
<b-form-row v-if="form.mail_enabled.$model" class="mt-2">
<b-wrapped-form-group class="col-md-6" id="edit_form_mail_sender_name"
:field="form.mail_sender_name">
<template #label="{lang}">
{{ $gettext('Sender Name') }}
</template>
</b-wrapped-form-group>
<b-wrapped-form-group class="col-md-6" id="edit_form_mail_sender_email"
:field="form.mail_sender_email" input-type="email">
<template #label="{lang}">
{{ $gettext('Sender E-mail Address') }}
</template>
</b-wrapped-form-group>
<b-wrapped-form-group class="col-md-6" id="edit_form_mail_sender_email"
:field="form.mail_sender_email" input-type="email">
<template #label="{lang}">
{{ $gettext('Sender E-mail Address') }}
</template>
</b-wrapped-form-group>
<b-wrapped-form-group class="col-md-4" id="edit_form_mail_smtp_host"
:field="form.mail_smtp_host">
<template #label="{lang}">
{{ $gettext('SMTP Host') }}
</template>
</b-wrapped-form-group>
<b-wrapped-form-group class="col-md-4" id="edit_form_mail_smtp_host"
:field="form.mail_smtp_host">
<template #label="{lang}">
{{ $gettext('SMTP Host') }}
</template>
</b-wrapped-form-group>
<b-wrapped-form-group class="col-md-3" id="edit_form_mail_smtp_port"
:field="form.mail_smtp_port" input-type="number">
<template #label="{lang}">
{{ $gettext('SMTP Port') }}
</template>
</b-wrapped-form-group>
<b-wrapped-form-group class="col-md-3" id="edit_form_mail_smtp_port"
:field="form.mail_smtp_port" input-type="number">
<template #label="{lang}">
{{ $gettext('SMTP Port') }}
</template>
</b-wrapped-form-group>
<b-wrapped-form-checkbox class="col-md-5" id="edit_form_mail_smtp_secure"
:field="form.mail_smtp_secure">
<template #label="{lang}">
{{ $gettext('Use Secure (TLS) SMTP Connection') }}
</template>
<template #description="{lang}">
{{ $gettext('Usually enabled for port 465, disabled for ports 587 or 25.') }}
</template>
</b-wrapped-form-checkbox>
<b-wrapped-form-checkbox class="col-md-5" id="edit_form_mail_smtp_secure"
:field="form.mail_smtp_secure">
<template #label="{lang}">
{{ $gettext('Use Secure (TLS) SMTP Connection') }}
</template>
<template #description="{lang}">
{{ $gettext('Usually enabled for port 465, disabled for ports 587 or 25.') }}
</template>
</b-wrapped-form-checkbox>
<b-wrapped-form-group class="col-md-6" id="edit_form_mail_smtp_username"
:field="form.mail_smtp_username">
<template #label="{lang}">
{{ $gettext('SMTP Username') }}
</template>
</b-wrapped-form-group>
<b-wrapped-form-group class="col-md-6" id="edit_form_mail_smtp_username"
:field="form.mail_smtp_username">
<template #label="{lang}">
{{ $gettext('SMTP Username') }}
</template>
</b-wrapped-form-group>
<b-wrapped-form-group class="col-md-6" id="edit_form_mail_smtp_password"
:field="form.mail_smtp_password" input-type="password">
<template #label="{lang}">
{{ $gettext('SMTP Password') }}
</template>
</b-wrapped-form-group>
<b-wrapped-form-group class="col-md-6" id="edit_form_mail_smtp_password"
:field="form.mail_smtp_password" input-type="password">
<template #label="{lang}">
{{ $gettext('SMTP Password') }}
</template>
</b-wrapped-form-group>
<div class="form-group col">
<b-button size="sm" variant="primary" :disabled="form.$anyDirty" v-b-modal.send_test_message>
<icon icon="send"></icon>
{{ $gettext('Send Test Message') }}
<span v-if="form.$anyDirty">
({{ $gettext('Save Changes first') }})
</span>
</b-button>
</div>
</b-form-row>
</b-form-fieldset>
<div class="form-group col">
<b-button size="sm" variant="primary" :disabled="form.$anyDirty" v-b-modal.send_test_message>
<icon icon="send"></icon>
{{ $gettext('Send Test Message') }}
<span v-if="form.$anyDirty">
({{ $gettext('Save Changes first') }})
</span>
</b-button>
</div>
</b-form-row>
</b-form-fieldset>
<b-form-fieldset>
<template #label>
{{ $gettext('Avatar Service') }}
</template>
<b-form-fieldset>
<template #label>
{{ $gettext('Avatar Service') }}
</template>
<b-form-row>
<b-wrapped-form-group class="col-md-6" id="edit_form_avatar_service" :field="form.avatar_service">
<template #label="{lang}">
{{ $gettext('Avatar Service') }}
</template>
<template #default="props">
<b-form-radio-group stacked :id="props.id" v-model="props.field.$model"
:options="avatarServiceOptions"></b-form-radio-group>
</template>
</b-wrapped-form-group>
<b-form-row>
<b-wrapped-form-group class="col-md-6" id="edit_form_avatar_service" :field="form.avatar_service">
<template #label="{lang}">
{{ $gettext('Avatar Service') }}
</template>
<template #default="props">
<b-form-radio-group stacked :id="props.id" v-model="props.field.$model"
:options="avatarServiceOptions"></b-form-radio-group>
</template>
</b-wrapped-form-group>
<b-wrapped-form-group class="col-md-6" id="edit_form_avatar_default_url"
:field="form.avatar_default_url">
<template #label="{lang}">
{{ $gettext('Default Avatar URL') }}
</template>
</b-wrapped-form-group>
</b-form-row>
</b-form-fieldset>
<b-wrapped-form-group class="col-md-6" id="edit_form_avatar_default_url"
:field="form.avatar_default_url">
<template #label="{lang}">
{{ $gettext('Default Avatar URL') }}
</template>
</b-wrapped-form-group>
</b-form-row>
</b-form-fieldset>
<b-form-fieldset>
<template #label>
{{ $gettext('Album Art') }}
</template>
<b-form-fieldset>
<template #label>
{{ $gettext('Album Art') }}
</template>
<b-form-row>
<b-wrapped-form-checkbox class="col-md-6" id="use_external_album_art_in_apis"
:field="form.use_external_album_art_in_apis">
<template #label="{lang}">
{{ $gettext('Check Web Services for Album Art for "Now Playing" Tracks') }}
</template>
</b-wrapped-form-checkbox>
<b-form-row>
<b-wrapped-form-checkbox class="col-md-6" id="use_external_album_art_in_apis"
:field="form.use_external_album_art_in_apis">
<template #label="{lang}">
{{ $gettext('Check Web Services for Album Art for "Now Playing" Tracks') }}
</template>
</b-wrapped-form-checkbox>
<b-wrapped-form-checkbox class="col-md-6" id="use_external_album_art_when_processing_media"
:field="form.use_external_album_art_when_processing_media">
<template #label="{lang}">
{{ $gettext('Check Web Services for Album Art When Uploading Media') }}
</template>
</b-wrapped-form-checkbox>
<b-wrapped-form-checkbox class="col-md-6" id="use_external_album_art_when_processing_media"
:field="form.use_external_album_art_when_processing_media">
<template #label="{lang}">
{{ $gettext('Check Web Services for Album Art When Uploading Media') }}
</template>
</b-wrapped-form-checkbox>
<b-wrapped-form-group class="col-md-12" id="edit_form_last_fm_api_key" :field="form.last_fm_api_key">
<template #label="{lang}">
{{ $gettext('Last.fm API Key') }}
</template>
<template #description="{lang}">
{{ $gettext('This service can provide album art for tracks where none is available locally.') }}
<br>
<a href="https://www.last.fm/api/account/create" target="_blank">
{{ $gettext('Apply for an API key at Last.fm') }}
</a>
</template>
</b-wrapped-form-group>
</b-form-row>
</b-form-fieldset>
<b-wrapped-form-group class="col-md-12" id="edit_form_last_fm_api_key" :field="form.last_fm_api_key">
<template #label="{lang}">
{{ $gettext('Last.fm API Key') }}
</template>
<template #description="{lang}">
{{ $gettext('This service can provide album art for tracks where none is available locally.') }}
<br>
<a href="https://www.last.fm/api/account/create" target="_blank">
{{ $gettext('Apply for an API key at Last.fm') }}
</a>
</template>
</b-wrapped-form-group>
</b-form-row>
</b-form-fieldset>
<streaming-log-modal ref="acmeModal"></streaming-log-modal>
<streaming-log-modal ref="acmeModal"></streaming-log-modal>
<admin-settings-test-message-modal :test-message-url="testMessageUrl"></admin-settings-test-message-modal>
</div>
<admin-settings-test-message-modal :test-message-url="testMessageUrl"></admin-settings-test-message-modal>
</template>
<script>

View File

@ -1,53 +1,51 @@
<template>
<div>
<b-card no-body>
<b-card-header header-bg-variant="primary-dark">
<h2 class="card-title">{{ $gettext('Stations') }}</h2>
</b-card-header>
<b-card no-body>
<b-card-header header-bg-variant="primary-dark">
<h2 class="card-title">{{ $gettext('Stations') }}</h2>
</b-card-header>
<b-card-body body-class="card-padding-sm">
<b-button variant="outline-primary" @click.prevent="doCreate">
<icon icon="add"></icon>
{{ $gettext('Add Station') }}
</b-button>
</b-card-body>
<b-card-body body-class="card-padding-sm">
<b-button variant="outline-primary" @click.prevent="doCreate">
<icon icon="add"></icon>
{{ $gettext('Add Station') }}
</b-button>
</b-card-body>
<data-table ref="datatable" id="stations" paginated :fields="fields" :api-url="listUrl">
<template #cell(name)="row">
<big>{{ row.item.name }}</big><br>
<code>{{ row.item.short_name }}</code>
</template>
<template #cell(frontend_type)="row">
{{ getFrontendName(row.item.frontend_type) }}
</template>
<template #cell(backend_type)="row">
{{ getBackendName(row.item.backend_type) }}
</template>
<template #cell(actions)="row">
<b-button-group size="sm">
<b-button size="sm" variant="secondary" :href="row.item.links.manage" target="_blank">
{{ $gettext('Manage') }}
</b-button>
<b-button size="sm" variant="secondary"
@click.prevent="doClone(row.item.name, row.item.links.clone)">
{{ $gettext('Clone') }}
</b-button>
<b-button size="sm" variant="primary" @click.prevent="doEdit(row.item.links.self)">
{{ $gettext('Edit') }}
</b-button>
<b-button size="sm" variant="danger" @click.prevent="doDelete(row.item.links.self)">
{{ $gettext('Delete') }}
</b-button>
</b-button-group>
</template>
</data-table>
</b-card>
<data-table ref="datatable" id="stations" paginated :fields="fields" :api-url="listUrl">
<template #cell(name)="row">
<big>{{ row.item.name }}</big><br>
<code>{{ row.item.short_name }}</code>
</template>
<template #cell(frontend_type)="row">
{{ getFrontendName(row.item.frontend_type) }}
</template>
<template #cell(backend_type)="row">
{{ getBackendName(row.item.backend_type) }}
</template>
<template #cell(actions)="row">
<b-button-group size="sm">
<b-button size="sm" variant="secondary" :href="row.item.links.manage" target="_blank">
{{ $gettext('Manage') }}
</b-button>
<b-button size="sm" variant="secondary"
@click.prevent="doClone(row.item.name, row.item.links.clone)">
{{ $gettext('Clone') }}
</b-button>
<b-button size="sm" variant="primary" @click.prevent="doEdit(row.item.links.self)">
{{ $gettext('Edit') }}
</b-button>
<b-button size="sm" variant="danger" @click.prevent="doDelete(row.item.links.self)">
{{ $gettext('Delete') }}
</b-button>
</b-button-group>
</template>
</data-table>
</b-card>
<admin-stations-edit-modal v-bind="$props" ref="editModal" :create-url="listUrl"
@relist="relist"></admin-stations-edit-modal>
<admin-stations-edit-modal v-bind="$props" ref="editModal" :create-url="listUrl"
@relist="relist"></admin-stations-edit-modal>
<admin-stations-clone-modal ref="cloneModal" @relist="relist"></admin-stations-clone-modal>
</div>
<admin-stations-clone-modal ref="cloneModal" @relist="relist"></admin-stations-clone-modal>
</template>
<script>

View File

@ -1,71 +1,69 @@
<template>
<div>
<b-form-group>
<b-form-fieldset>
<b-form-row>
<b-wrapped-form-checkbox class="col-md-6" id="edit_form_is_enabled" :field="form.is_enabled">
<template #label="{lang}">
{{ $gettext('Enable Broadcasting') }}
</template>
<template #description="{lang}">
{{ $gettext('If disabled, the station will not broadcast or shuffle its AutoDJ.') }}
</template>
</b-wrapped-form-checkbox>
<b-form-group>
<b-form-fieldset>
<b-form-row>
<b-wrapped-form-checkbox class="col-md-6" id="edit_form_is_enabled" :field="form.is_enabled">
<template #label="{lang}">
{{ $gettext('Enable Broadcasting') }}
</template>
<template #description="{lang}">
{{ $gettext('If disabled, the station will not broadcast or shuffle its AutoDJ.') }}
</template>
</b-wrapped-form-checkbox>
<b-wrapped-form-group v-if="showAdvanced" class="col-md-6" id="edit_form_radio_base_dir"
:field="form.radio_base_dir" advanced>
<b-wrapped-form-group v-if="showAdvanced" class="col-md-6" id="edit_form_radio_base_dir"
:field="form.radio_base_dir" advanced>
<template #label="{lang}">
{{ $gettext('Base Station Directory') }}
</template>
<template #description="{lang}">
{{
$gettext('The parent directory where station playlist and configuration files are stored. Leave blank to use default directory.')
}}
</template>
</b-wrapped-form-group>
</b-form-row>
</b-form-fieldset>
<b-form-fieldset>
<b-overlay variant="card" :show="storageLocationsLoading">
<b-form-row>
<b-wrapped-form-group class="col-md-12" id="edit_form_media_storage_location"
:field="form.media_storage_location">
<template #label="{lang}">
{{ $gettext('Base Station Directory') }}
{{ $gettext('Media Storage Location') }}
</template>
<template #description="{lang}">
{{
$gettext('The parent directory where station playlist and configuration files are stored. Leave blank to use default directory.')
}}
<template #default="props">
<b-form-select :id="props.id" v-model="props.field.$model"
:options="storageLocationOptions.media_storage_location"></b-form-select>
</template>
</b-wrapped-form-group>
<b-wrapped-form-group class="col-md-12" id="edit_form_recordings_storage_location"
:field="form.recordings_storage_location">
<template #label="{lang}">
{{ $gettext('Live Recordings Storage Location') }}
</template>
<template #default="props">
<b-form-select :id="props.id" v-model="props.field.$model"
:options="storageLocationOptions.recordings_storage_location"></b-form-select>
</template>
</b-wrapped-form-group>
<b-wrapped-form-group class="col-md-12" id="edit_form_podcasts_storage_location"
:field="form.podcasts_storage_location">
<template #label="{lang}">
{{ $gettext('Podcasts Storage Location') }}
</template>
<template #default="props">
<b-form-select :id="props.id" v-model="props.field.$model"
:options="storageLocationOptions.podcasts_storage_location"></b-form-select>
</template>
</b-wrapped-form-group>
</b-form-row>
</b-form-fieldset>
<b-form-fieldset>
<b-overlay variant="card" :show="storageLocationsLoading">
<b-form-row>
<b-wrapped-form-group class="col-md-12" id="edit_form_media_storage_location"
:field="form.media_storage_location">
<template #label="{lang}">
{{ $gettext('Media Storage Location') }}
</template>
<template #default="props">
<b-form-select :id="props.id" v-model="props.field.$model"
:options="storageLocationOptions.media_storage_location"></b-form-select>
</template>
</b-wrapped-form-group>
<b-wrapped-form-group class="col-md-12" id="edit_form_recordings_storage_location"
:field="form.recordings_storage_location">
<template #label="{lang}">
{{ $gettext('Live Recordings Storage Location') }}
</template>
<template #default="props">
<b-form-select :id="props.id" v-model="props.field.$model"
:options="storageLocationOptions.recordings_storage_location"></b-form-select>
</template>
</b-wrapped-form-group>
<b-wrapped-form-group class="col-md-12" id="edit_form_podcasts_storage_location"
:field="form.podcasts_storage_location">
<template #label="{lang}">
{{ $gettext('Podcasts Storage Location') }}
</template>
<template #default="props">
<b-form-select :id="props.id" v-model="props.field.$model"
:options="storageLocationOptions.podcasts_storage_location"></b-form-select>
</template>
</b-wrapped-form-group>
</b-form-row>
</b-overlay>
</b-form-fieldset>
</b-form-group>
</div>
</b-overlay>
</b-form-fieldset>
</b-form-group>
</template>
<script>

View File

@ -1,19 +1,69 @@
<template>
<div>
<b-form-fieldset>
<b-form-row>
<b-wrapped-form-group class="col-md-12" id="edit_form_backend_type"
:field="form.backend_type">
<template #label="{lang}">
{{ $gettext('AutoDJ Service') }}
</template>
<template #description="{lang}">
{{
$gettext('This software shuffles from playlists of music constantly and plays when no other radio source is available.')
}}
</template>
<template #default="props">
<b-form-radio-group stacked :id="props.id" :options="backendTypeOptions"
v-model="props.field.$model">
</b-form-radio-group>
</template>
</b-wrapped-form-group>
</b-form-row>
</b-form-fieldset>
<b-form-fieldset v-if="isBackendEnabled">
<b-form-fieldset>
<b-form-row>
<b-wrapped-form-group class="col-md-12" id="edit_form_backend_type"
:field="form.backend_type">
<b-wrapped-form-group class="col-md-7" id="edit_form_backend_crossfade_type"
:field="form.backend_config.crossfade_type">
<template #label="{lang}">
{{ $gettext('AutoDJ Service') }}
{{ $gettext('Crossfade Method') }}
</template>
<template #description="{lang}">
{{
$gettext('This software shuffles from playlists of music constantly and plays when no other radio source is available.')
$gettext('Choose a method to use when transitioning from one song to another. Smart Mode considers the volume of the two tracks when fading for a smoother effect, but requires more CPU resources.')
}}
</template>
<template #default="props">
<b-form-radio-group stacked :id="props.id" :options="backendTypeOptions"
<b-form-radio-group stacked :id="props.id" :options="crossfadeOptions"
v-model="props.field.$model">
</b-form-radio-group>
</template>
</b-wrapped-form-group>
<b-wrapped-form-group class="col-md-5" id="edit_form_backend_crossfade"
:field="form.backend_config.crossfade" input-type="number"
:input-attrs="{ min: '0.0', max: '30.0', step: '0.1' }">
<template #label="{lang}">
{{ $gettext('Crossfade Duration (Seconds)') }}
</template>
<template #description="{lang}">
{{ $gettext('Number of seconds to overlap songs.') }}
</template>
</b-wrapped-form-group>
</b-form-row>
<b-form-row>
<b-wrapped-form-group class="col-md-12" id="edit_form_backend_config_audio_processing_method"
:field="form.backend_config.audio_processing_method">
<template #label="{lang}">
{{ $gettext('Audio Processing Method') }}
</template>
<template #description="{lang}">
{{
$gettext('Choose a method to use for processing audio which produces a more uniform and "full" sound for your station.')
}}
</template>
<template #default="props">
<b-form-radio-group stacked :id="props.id" :options="audioProcessingOptions"
v-model="props.field.$model">
</b-form-radio-group>
</template>
@ -21,207 +71,155 @@
</b-form-row>
</b-form-fieldset>
<b-form-fieldset v-if="isBackendEnabled">
<b-form-fieldset v-if="isStereoToolEnabled && isStereoToolInstalled">
<template #label>
{{ $gettext('Stereo Tool') }}
</template>
<template #description>
{{
$gettext('Stereo Tool is an industry standard for software audio processing. For more information on how to configure it, please refer to the')
}}
<a href="https://www.thimeo.com/stereo-tool/" target="_blank">
{{ $gettext('Stereo Tool documentation.') }}
</a>
</template>
<b-form-fieldset>
<b-form-row>
<b-wrapped-form-group class="col-md-7" id="edit_form_backend_crossfade_type"
:field="form.backend_config.crossfade_type">
<b-wrapped-form-group class="col-md-7" id="edit_form_backend_stereo_tool_license_key"
:field="form.backend_config.stereo_tool_license_key" input-type="text">
<template #label="{lang}">
{{ $gettext('Crossfade Method') }}
{{ $gettext('Stereo Tool License Key') }}
</template>
<template #description="{lang}">
{{
$gettext('Choose a method to use when transitioning from one song to another. Smart Mode considers the volume of the two tracks when fading for a smoother effect, but requires more CPU resources.')
}}
</template>
<template #default="props">
<b-form-radio-group stacked :id="props.id" :options="crossfadeOptions"
v-model="props.field.$model">
</b-form-radio-group>
</template>
</b-wrapped-form-group>
<b-wrapped-form-group class="col-md-5" id="edit_form_backend_crossfade"
:field="form.backend_config.crossfade" input-type="number"
:input-attrs="{ min: '0.0', max: '30.0', step: '0.1' }">
<template #label="{lang}">
{{ $gettext('Crossfade Duration (Seconds)') }}
</template>
<template #description="{lang}">
{{ $gettext('Number of seconds to overlap songs.') }}
</template>
</b-wrapped-form-group>
</b-form-row>
<b-form-row>
<b-wrapped-form-group class="col-md-12" id="edit_form_backend_config_audio_processing_method"
:field="form.backend_config.audio_processing_method">
<template #label="{lang}">
{{ $gettext('Audio Processing Method') }}
</template>
<template #description="{lang}">
{{
$gettext('Choose a method to use for processing audio which produces a more uniform and "full" sound for your station.')
}}
</template>
<template #default="props">
<b-form-radio-group stacked :id="props.id" :options="audioProcessingOptions"
v-model="props.field.$model">
</b-form-radio-group>
</template>
</b-wrapped-form-group>
</b-form-row>
</b-form-fieldset>
<b-form-fieldset v-if="isStereoToolEnabled && isStereoToolInstalled">
<template #label>
{{ $gettext('Stereo Tool') }}
</template>
<template #description>
{{
$gettext('Stereo Tool is an industry standard for software audio processing. For more information on how to configure it, please refer to the')
}}
<a href="https://www.thimeo.com/stereo-tool/" target="_blank">
{{ $gettext('Stereo Tool documentation.') }}
</a>
</template>
<b-form-fieldset>
<b-form-row>
<b-wrapped-form-group class="col-md-7" id="edit_form_backend_stereo_tool_license_key"
:field="form.backend_config.stereo_tool_license_key" input-type="text">
<template #label="{lang}">
{{ $gettext('Stereo Tool License Key') }}
</template>
<template #description="{lang}">
{{
$gettext('Provide a valid license key from Thimeo. Functionality is limited without a license key.')
}}
</template>
</b-wrapped-form-group>
<b-form-markup class="col-md-5" id="edit_form_backend_stereo_tool_config">
<template #label="{lang}">
{{ $gettext('Upload Stereo Tool Configuration') }}
</template>
<p class="card-text">
{{
$gettext('Upload a Stereo Tool configuration file from the "Broadcasting" submenu in the station profile.')
}}
</p>
</b-form-markup>
</b-form-row>
</b-form-fieldset>
</b-form-fieldset>
<b-form-fieldset v-if="showAdvanced">
<template #label>
{{ $gettext('Advanced Configuration') }}
</template>
<b-form-row>
<b-wrapped-form-checkbox class="col-md-6"
id="edit_form_backend_use_manual_autodj"
:field="form.backend_config.use_manual_autodj" advanced>
<template #label="{lang}">
{{ $gettext('Manual AutoDJ Mode') }}
</template>
<template #description="{lang}">
{{
$gettext('This mode disables AzuraCast\'s AutoDJ management, using Liquidsoap itself to manage song playback. "Next Song" and some other features will not be available.')
}}
</template>
</b-wrapped-form-checkbox>
<b-wrapped-form-checkbox class="col-md-6"
id="edit_form_backend_enable_replaygain_metadata"
:field="form.backend_config.enable_replaygain_metadata" advanced>
<template #label="{lang}">
{{ $gettext('Use Replaygain Metadata') }}
</template>
<template #description="{lang}">
{{
$gettext('Instruct Liquidsoap to use any replaygain metadata associated with a song to control its volume level. This may increase CPU consumption.')
}}
</template>
</b-wrapped-form-checkbox>
<b-wrapped-form-group class="col-md-6" id="edit_form_backend_telnet_port"
:field="form.backend_config.telnet_port" input-type="number"
:input-attrs="{ min: '0' }" advanced>
<template #label="{lang}">
{{ $gettext('Customize Internal Request Processing Port') }}
</template>
<template #description="{lang}">
{{
$gettext('This port is not used by any external process. Only modify this port if the assigned port is in use. Leave blank to automatically assign a port.')
$gettext('Provide a valid license key from Thimeo. Functionality is limited without a license key.')
}}
</template>
</b-wrapped-form-group>
<b-wrapped-form-group class="col-md-6" id="edit_form_backend_autodj_queue_length"
:field="form.backend_config.autodj_queue_length" input-type="number"
:input-attrs="{ min: '2', max: '25' }" advanced>
<b-form-markup class="col-md-5" id="edit_form_backend_stereo_tool_config">
<template #label="{lang}">
{{ $gettext('AutoDJ Queue Length') }}
{{ $gettext('Upload Stereo Tool Configuration') }}
</template>
<template #description="{lang}">
{{
$gettext('This determines how many songs in advance the AutoDJ will automatically fill the queue.')
}}
</template>
</b-wrapped-form-group>
<b-wrapped-form-group class="col-md-6" id="edit_form_backend_charset"
:field="form.backend_config.charset" advanced>
<template #label="{lang}">
{{ $gettext('Character Set Encoding') }}
</template>
<template #description="{lang}">
<p class="card-text">
{{
$gettext('For most cases, use the default UTF-8 encoding. The older ISO-8859-1 encoding can be used if accepting connections from Shoutcast 1 DJs or using other legacy software.')
$gettext('Upload a Stereo Tool configuration file from the "Broadcasting" submenu in the station profile.')
}}
</template>
<template #default="props">
<b-form-radio-group stacked :id="props.id" :options="charsetOptions"
v-model="props.field.$model">
</b-form-radio-group>
</template>
</b-wrapped-form-group>
<b-wrapped-form-group class="col-md-6" id="edit_form_backend_performance_mode"
:field="form.backend_config.performance_mode" advanced>
<template #label="{lang}">
{{ $gettext('Liquidsoap Performance Tuning') }}
</template>
<template #description="{lang}">
{{
$gettext('If your installation is constrained by CPU or memory, you can change this setting to tune the resources used by Liquidsoap.')
}}
</template>
<template #default="props">
<b-form-radio-group stacked :id="props.id" :options="performanceModeOptions"
v-model="props.field.$model">
</b-form-radio-group>
</template>
</b-wrapped-form-group>
<b-wrapped-form-group class="col-md-6" id="edit_form_backend_duplicate_prevention_time_range"
:field="form.backend_config.duplicate_prevention_time_range"
input-type="number" :input-attrs="{ min: '0', max: '1440' }" advanced>
<template #label="{lang}">
{{ $gettext('Duplicate Prevention Time Range (Minutes)') }}
</template>
<template #description="{lang}">
{{
$gettext('This specifies the time range (in minutes) of the song history that the duplicate song prevention algorithm should take into account.')
}}
</template>
</b-wrapped-form-group>
</p>
</b-form-markup>
</b-form-row>
</b-form-fieldset>
</b-form-fieldset>
</div>
<b-form-fieldset v-if="showAdvanced">
<template #label>
{{ $gettext('Advanced Configuration') }}
</template>
<b-form-row>
<b-wrapped-form-checkbox class="col-md-6"
id="edit_form_backend_use_manual_autodj"
:field="form.backend_config.use_manual_autodj" advanced>
<template #label="{lang}">
{{ $gettext('Manual AutoDJ Mode') }}
</template>
<template #description="{lang}">
{{
$gettext('This mode disables AzuraCast\'s AutoDJ management, using Liquidsoap itself to manage song playback. "Next Song" and some other features will not be available.')
}}
</template>
</b-wrapped-form-checkbox>
<b-wrapped-form-checkbox class="col-md-6"
id="edit_form_backend_enable_replaygain_metadata"
:field="form.backend_config.enable_replaygain_metadata" advanced>
<template #label="{lang}">
{{ $gettext('Use Replaygain Metadata') }}
</template>
<template #description="{lang}">
{{
$gettext('Instruct Liquidsoap to use any replaygain metadata associated with a song to control its volume level. This may increase CPU consumption.')
}}
</template>
</b-wrapped-form-checkbox>
<b-wrapped-form-group class="col-md-6" id="edit_form_backend_telnet_port"
:field="form.backend_config.telnet_port" input-type="number"
:input-attrs="{ min: '0' }" advanced>
<template #label="{lang}">
{{ $gettext('Customize Internal Request Processing Port') }}
</template>
<template #description="{lang}">
{{
$gettext('This port is not used by any external process. Only modify this port if the assigned port is in use. Leave blank to automatically assign a port.')
}}
</template>
</b-wrapped-form-group>
<b-wrapped-form-group class="col-md-6" id="edit_form_backend_autodj_queue_length"
:field="form.backend_config.autodj_queue_length" input-type="number"
:input-attrs="{ min: '2', max: '25' }" advanced>
<template #label="{lang}">
{{ $gettext('AutoDJ Queue Length') }}
</template>
<template #description="{lang}">
{{
$gettext('This determines how many songs in advance the AutoDJ will automatically fill the queue.')
}}
</template>
</b-wrapped-form-group>
<b-wrapped-form-group class="col-md-6" id="edit_form_backend_charset"
:field="form.backend_config.charset" advanced>
<template #label="{lang}">
{{ $gettext('Character Set Encoding') }}
</template>
<template #description="{lang}">
{{
$gettext('For most cases, use the default UTF-8 encoding. The older ISO-8859-1 encoding can be used if accepting connections from Shoutcast 1 DJs or using other legacy software.')
}}
</template>
<template #default="props">
<b-form-radio-group stacked :id="props.id" :options="charsetOptions"
v-model="props.field.$model">
</b-form-radio-group>
</template>
</b-wrapped-form-group>
<b-wrapped-form-group class="col-md-6" id="edit_form_backend_performance_mode"
:field="form.backend_config.performance_mode" advanced>
<template #label="{lang}">
{{ $gettext('Liquidsoap Performance Tuning') }}
</template>
<template #description="{lang}">
{{
$gettext('If your installation is constrained by CPU or memory, you can change this setting to tune the resources used by Liquidsoap.')
}}
</template>
<template #default="props">
<b-form-radio-group stacked :id="props.id" :options="performanceModeOptions"
v-model="props.field.$model">
</b-form-radio-group>
</template>
</b-wrapped-form-group>
<b-wrapped-form-group class="col-md-6" id="edit_form_backend_duplicate_prevention_time_range"
:field="form.backend_config.duplicate_prevention_time_range"
input-type="number" :input-attrs="{ min: '0', max: '1440' }" advanced>
<template #label="{lang}">
{{ $gettext('Duplicate Prevention Time Range (Minutes)') }}
</template>
<template #description="{lang}">
{{
$gettext('This specifies the time range (in minutes) of the song history that the duplicate song prevention algorithm should take into account.')
}}
</template>
</b-wrapped-form-group>
</b-form-row>
</b-form-fieldset>
</b-form-fieldset>
</template>
<script>

View File

@ -1,176 +1,174 @@
<template>
<div>
<b-form-fieldset>
<b-form-fieldset>
<b-form-row>
<b-wrapped-form-group class="col-md-12" id="edit_form_frontend_type"
:field="form.frontend_type">
<template #label="{lang}">
{{ $gettext('Broadcasting Service') }}
</template>
<template #description="{lang}">
{{ $gettext('This software delivers your broadcast to the listening audience.') }}
</template>
<template #default="props">
<b-form-radio-group stacked :id="props.id" :options="frontendTypeOptions"
v-model="props.field.$model">
</b-form-radio-group>
</template>
</b-wrapped-form-group>
</b-form-row>
</b-form-fieldset>
<b-form-fieldset v-if="isLocalFrontend">
<b-form-fieldset v-if="isShoutcastFrontend">
<b-form-row>
<b-wrapped-form-group class="col-md-12" id="edit_form_frontend_type"
:field="form.frontend_type">
<b-wrapped-form-group class="col-md-6" id="edit_form_frontend_sc_license_id"
:field="form.frontend_config.sc_license_id">
<template #label="{lang}">
{{ $gettext('Broadcasting Service') }}
{{ $gettext('Shoutcast License ID') }}
</template>
<template #description="{lang}">
{{ $gettext('This software delivers your broadcast to the listening audience.') }}
</template>
<template #default="props">
<b-form-radio-group stacked :id="props.id" :options="frontendTypeOptions"
v-model="props.field.$model">
</b-form-radio-group>
</b-wrapped-form-group>
<b-wrapped-form-group class="col-md-6" id="edit_form_frontend_sc_user_id"
:field="form.frontend_config.sc_user_id">
<template #label="{lang}">
{{ $gettext('Shoutcast User ID') }}
</template>
</b-wrapped-form-group>
</b-form-row>
</b-form-fieldset>
<b-form-fieldset v-if="isLocalFrontend">
<b-form-fieldset v-if="isShoutcastFrontend">
<b-form-row>
<b-wrapped-form-group class="col-md-6" id="edit_form_frontend_sc_license_id"
:field="form.frontend_config.sc_license_id">
<template #label="{lang}">
{{ $gettext('Shoutcast License ID') }}
</template>
</b-wrapped-form-group>
<b-form-fieldset>
<b-form-row>
<b-wrapped-form-group class="col-md-6" id="edit_form_frontend_source_pw"
:field="form.frontend_config.source_pw">
<template #label="{lang}">
{{ $gettext('Customize Source Password') }}
</template>
<template #description="{lang}">
{{ $gettext('Leave blank to automatically generate a new password.') }}
</template>
</b-wrapped-form-group>
<b-wrapped-form-group class="col-md-6" id="edit_form_frontend_sc_user_id"
:field="form.frontend_config.sc_user_id">
<template #label="{lang}">
{{ $gettext('Shoutcast User ID') }}
</template>
</b-wrapped-form-group>
</b-form-row>
</b-form-fieldset>
<b-wrapped-form-group class="col-md-6" id="edit_form_frontend_admin_pw"
:field="form.frontend_config.admin_pw">
<template #label="{lang}">
{{ $gettext('Customize Administrator Password') }}
</template>
<template #description="{lang}">
{{ $gettext('Leave blank to automatically generate a new password.') }}
</template>
</b-wrapped-form-group>
<b-form-fieldset>
<b-form-row>
<b-wrapped-form-group class="col-md-6" id="edit_form_frontend_source_pw"
:field="form.frontend_config.source_pw">
<template #label="{lang}">
{{ $gettext('Customize Source Password') }}
</template>
<template #description="{lang}">
{{ $gettext('Leave blank to automatically generate a new password.') }}
</template>
</b-wrapped-form-group>
<b-wrapped-form-group v-if="showAdvanced" class="col-md-6" id="edit_form_frontend_port"
:field="form.frontend_config.port" input-type="number"
:input-attrs="{min: '0'}" advanced>
<template #label="{lang}">
{{ $gettext('Customize Broadcasting Port') }}
</template>
<template #description="{lang}">
{{
$gettext('No other program can be using this port. Leave blank to automatically assign a port.')
}}
</template>
</b-wrapped-form-group>
<b-wrapped-form-group class="col-md-6" id="edit_form_frontend_admin_pw"
:field="form.frontend_config.admin_pw">
<template #label="{lang}">
{{ $gettext('Customize Administrator Password') }}
</template>
<template #description="{lang}">
{{ $gettext('Leave blank to automatically generate a new password.') }}
</template>
</b-wrapped-form-group>
<b-wrapped-form-group v-if="showAdvanced" class="col-md-6" id="edit_form_frontend_port"
:field="form.frontend_config.port" input-type="number"
:input-attrs="{min: '0'}" advanced>
<template #label="{lang}">
{{ $gettext('Customize Broadcasting Port') }}
</template>
<template #description="{lang}">
{{
$gettext('No other program can be using this port. Leave blank to automatically assign a port.')
}}
</template>
</b-wrapped-form-group>
<b-wrapped-form-group v-if="showAdvanced" class="col-md-6" id="edit_form_max_listeners"
:field="form.frontend_config.max_listeners" advanced>
<template #label="{lang}">
{{ $gettext('Maximum Listeners') }}
</template>
<template #description="{lang}">
{{
$gettext('Maximum number of total listeners across all streams. Leave blank to use the default.')
}}
</template>
</b-wrapped-form-group>
</b-form-row>
</b-form-fieldset>
<b-form-fieldset v-if="showAdvanced">
<b-form-row>
<b-col md="5">
<b-wrapped-form-group id="edit_form_frontend_banned_ips"
:field="form.frontend_config.banned_ips" input-type="textarea"
:input-attrs="{class: 'text-preformatted'}" advanced>
<template #label="{lang}">
{{ $gettext('Banned IP Addresses') }}
</template>
<template #description="{lang}">
{{ $gettext('List one IP address or group (in CIDR format) per line.') }}
</template>
</b-wrapped-form-group>
<b-wrapped-form-group id="edit_form_frontend_allowed_ips"
:field="form.frontend_config.allowed_ips" input-type="textarea"
:input-attrs="{class: 'text-preformatted'}" advanced>
<template #label="{lang}">
{{ $gettext('Allowed IP Addresses') }}
</template>
<template #description="{lang}">
{{ $gettext('List one IP address or group (in CIDR format) per line.') }}
</template>
</b-wrapped-form-group>
<b-wrapped-form-group id="edit_form_frontend_banned_user_agents"
:field="form.frontend_config.banned_user_agents" input-type="textarea"
:input-attrs="{class: 'text-preformatted'}" advanced>
<template #label="{lang}">
{{ $gettext('Banned User Agents') }}
</template>
<template #description="{lang}">
{{ $gettext('List one user agent per line. Wildcards (*) are allowed.') }}
</template>
</b-wrapped-form-group>
</b-col>
<b-wrapped-form-group class="col-md-7" id="edit_form_frontend_banned_countries"
:field="form.frontend_config.banned_countries"
advanced>
<template #label="{lang}">
{{ $gettext('Banned Countries') }}
</template>
<template #description="{lang}">
{{ $gettext('Select the countries that are not allowed to connect to the streams.') }}
</template>
<template #default="props">
<b-form-select :id="props.id" v-model="props.field.$model"
:options="countryOptions" style="min-height: 300px;"
multiple></b-form-select>
<b-button block variant="outline-primary" @click.prevent="clearCountries">
{{ $gettext('Clear List') }}
</b-button>
</template>
</b-wrapped-form-group>
</b-form-row>
</b-form-fieldset>
<b-form-fieldset v-if="showAdvanced">
<template #label>
{{ $gettext('Custom Configuration') }}
</template>
<template #description>
{{ $gettext('This code will be included in the frontend configuration. Allowed formats are:') }}
<ul>
<li>JSON: <code>{"new_key": "new_value"}</code></li>
<li>XML: <code>&lt;new_key&gt;new_value&lt;/new_key&gt;</code></li>
</ul>
</template>
<b-form-row>
<b-wrapped-form-group class="col-md-12" id="edit_form_frontend_custom_config"
:field="form.frontend_config.custom_config" input-type="textarea"
:input-attrs="{class: 'text-preformatted', spellcheck: 'false', 'max-rows': 25, rows: 5}"
advanced>
<template #label="{lang}">
{{ $gettext('Custom Configuration') }}
</template>
</b-wrapped-form-group>
</b-form-row>
</b-form-fieldset>
<b-wrapped-form-group v-if="showAdvanced" class="col-md-6" id="edit_form_max_listeners"
:field="form.frontend_config.max_listeners" advanced>
<template #label="{lang}">
{{ $gettext('Maximum Listeners') }}
</template>
<template #description="{lang}">
{{
$gettext('Maximum number of total listeners across all streams. Leave blank to use the default.')
}}
</template>
</b-wrapped-form-group>
</b-form-row>
</b-form-fieldset>
</div>
<b-form-fieldset v-if="showAdvanced">
<b-form-row>
<b-col md="5">
<b-wrapped-form-group id="edit_form_frontend_banned_ips"
:field="form.frontend_config.banned_ips" input-type="textarea"
:input-attrs="{class: 'text-preformatted'}" advanced>
<template #label="{lang}">
{{ $gettext('Banned IP Addresses') }}
</template>
<template #description="{lang}">
{{ $gettext('List one IP address or group (in CIDR format) per line.') }}
</template>
</b-wrapped-form-group>
<b-wrapped-form-group id="edit_form_frontend_allowed_ips"
:field="form.frontend_config.allowed_ips" input-type="textarea"
:input-attrs="{class: 'text-preformatted'}" advanced>
<template #label="{lang}">
{{ $gettext('Allowed IP Addresses') }}
</template>
<template #description="{lang}">
{{ $gettext('List one IP address or group (in CIDR format) per line.') }}
</template>
</b-wrapped-form-group>
<b-wrapped-form-group id="edit_form_frontend_banned_user_agents"
:field="form.frontend_config.banned_user_agents" input-type="textarea"
:input-attrs="{class: 'text-preformatted'}" advanced>
<template #label="{lang}">
{{ $gettext('Banned User Agents') }}
</template>
<template #description="{lang}">
{{ $gettext('List one user agent per line. Wildcards (*) are allowed.') }}
</template>
</b-wrapped-form-group>
</b-col>
<b-wrapped-form-group class="col-md-7" id="edit_form_frontend_banned_countries"
:field="form.frontend_config.banned_countries"
advanced>
<template #label="{lang}">
{{ $gettext('Banned Countries') }}
</template>
<template #description="{lang}">
{{ $gettext('Select the countries that are not allowed to connect to the streams.') }}
</template>
<template #default="props">
<b-form-select :id="props.id" v-model="props.field.$model"
:options="countryOptions" style="min-height: 300px;"
multiple></b-form-select>
<b-button block variant="outline-primary" @click.prevent="clearCountries">
{{ $gettext('Clear List') }}
</b-button>
</template>
</b-wrapped-form-group>
</b-form-row>
</b-form-fieldset>
<b-form-fieldset v-if="showAdvanced">
<template #label>
{{ $gettext('Custom Configuration') }}
</template>
<template #description>
{{ $gettext('This code will be included in the frontend configuration. Allowed formats are:') }}
<ul>
<li>JSON: <code>{"new_key": "new_value"}</code></li>
<li>XML: <code>&lt;new_key&gt;new_value&lt;/new_key&gt;</code></li>
</ul>
</template>
<b-form-row>
<b-wrapped-form-group class="col-md-12" id="edit_form_frontend_custom_config"
:field="form.frontend_config.custom_config" input-type="textarea"
:input-attrs="{class: 'text-preformatted', spellcheck: 'false', 'max-rows': 25, rows: 5}"
advanced>
<template #label="{lang}">
{{ $gettext('Custom Configuration') }}
</template>
</b-wrapped-form-group>
</b-form-row>
</b-form-fieldset>
</b-form-fieldset>
</template>
<script>

View File

@ -1,77 +1,77 @@
<template>
<div>
<b-form-fieldset v-if="isBackendEnabled">
<b-form-fieldset v-if="isBackendEnabled">
<b-form-fieldset>
<template #label>
{{ $gettext('HTTP Live Streaming (HLS)') }}
</template>
<template #description>
{{
$gettext('HTTP Live Streaming (HLS) is a new adaptive-bitrate technology supported by some clients. It does not use the standard broadcasting frontends.')
}}
</template>
<b-form-fieldset>
<template #label>
{{ $gettext('HTTP Live Streaming (HLS)') }}
</template>
<template #description>
{{ $gettext('HTTP Live Streaming (HLS) is a new adaptive-bitrate technology supported by some clients. It does not use the standard broadcasting frontends.') }}
</template>
<b-form-row>
<b-wrapped-form-checkbox class="col-md-12" id="edit_form_enable_hls"
:field="form.enable_hls">
<template #label="{lang}">
{{ $gettext('Enable HTTP Live Streaming (HLS)') }}
</template>
</b-wrapped-form-checkbox>
</b-form-row>
</b-form-fieldset>
<b-form-fieldset>
<b-form-row>
<b-wrapped-form-checkbox class="col-md-12" id="edit_form_enable_hls"
:field="form.enable_hls">
<template #label="{lang}">
{{ $gettext('Enable HTTP Live Streaming (HLS)') }}
</template>
</b-wrapped-form-checkbox>
</b-form-row>
</b-form-fieldset>
<b-form-fieldset v-if="form.enable_hls.$model">
<b-form-row>
<b-wrapped-form-checkbox class="col-md-12" id="edit_form_backend_hls_enable_on_public_player"
:field="form.backend_config.hls_enable_on_public_player">
<template #label="{lang}">
{{ $gettext('Show HLS Stream on Public Player') }}
</template>
</b-wrapped-form-checkbox>
<b-form-fieldset v-if="form.enable_hls.$model">
<b-form-row>
<b-wrapped-form-checkbox class="col-md-12" id="edit_form_backend_hls_enable_on_public_player"
:field="form.backend_config.hls_enable_on_public_player">
<template #label="{lang}">
{{ $gettext('Show HLS Stream on Public Player') }}
</template>
</b-wrapped-form-checkbox>
<b-wrapped-form-checkbox class="col-md-12" id="edit_form_backend_hls_is_default"
:field="form.backend_config.hls_is_default">
<template #label="{lang}">
{{ $gettext('Make HLS Stream Default in Public Player') }}
</template>
</b-wrapped-form-checkbox>
</b-form-row>
</b-form-fieldset>
<b-wrapped-form-checkbox class="col-md-12" id="edit_form_backend_hls_is_default"
:field="form.backend_config.hls_is_default">
<template #label="{lang}">
{{ $gettext('Make HLS Stream Default in Public Player') }}
</template>
</b-wrapped-form-checkbox>
</b-form-row>
</b-form-fieldset>
<b-form-fieldset v-if="showAdvanced && form.enable_hls.$model">
<b-form-row>
<b-wrapped-form-group class="col-md-4"
id="edit_form_backend_hls_segment_length"
:field="form.backend_config.hls_segment_length" input-type="number"
:input-attrs="{ min: '0', max: '60' }" advanced>
<template #label="{lang}">
{{ $gettext('Segment Length (Seconds)') }}
</template>
</b-wrapped-form-group>
<b-form-fieldset v-if="showAdvanced && form.enable_hls.$model">
<b-form-row>
<b-wrapped-form-group class="col-md-4"
id="edit_form_backend_hls_segment_length"
:field="form.backend_config.hls_segment_length" input-type="number"
:input-attrs="{ min: '0', max: '60' }" advanced>
<template #label="{lang}">
{{ $gettext('Segment Length (Seconds)') }}
</template>
</b-wrapped-form-group>
<b-wrapped-form-group class="col-md-4"
id="edit_form_backend_hls_segments_in_playlist"
:field="form.backend_config.hls_segments_in_playlist" input-type="number"
:input-attrs="{ min: '0', max: '60' }" advanced>
<template #label="{lang}">
{{ $gettext('Segments in Playlist') }}
</template>
</b-wrapped-form-group>
<b-wrapped-form-group class="col-md-4"
id="edit_form_backend_hls_segments_in_playlist"
:field="form.backend_config.hls_segments_in_playlist" input-type="number"
:input-attrs="{ min: '0', max: '60' }" advanced>
<template #label="{lang}">
{{ $gettext('Segments in Playlist') }}
</template>
</b-wrapped-form-group>
<b-wrapped-form-group class="col-md-4"
id="edit_form_backend_hls_segments_overhead"
:field="form.backend_config.hls_segments_overhead" input-type="number"
:input-attrs="{ min: '0', max: '60' }" advanced>
<template #label="{lang}">
{{ $gettext('Segments Overhead') }}
</template>
</b-wrapped-form-group>
</b-form-row>
</b-form-fieldset>
<b-wrapped-form-group class="col-md-4"
id="edit_form_backend_hls_segments_overhead"
:field="form.backend_config.hls_segments_overhead" input-type="number"
:input-attrs="{ min: '0', max: '60' }" advanced>
<template #label="{lang}">
{{ $gettext('Segments Overhead') }}
</template>
</b-wrapped-form-group>
</b-form-row>
</b-form-fieldset>
</b-form-fieldset>
<backend-disabled v-else></backend-disabled>
</div>
</b-form-fieldset>
<backend-disabled v-else></backend-disabled>
</template>
<script>

View File

@ -1,145 +1,143 @@
<template>
<div>
<b-form-fieldset>
<b-form-row>
<b-wrapped-form-group class="col-md-12" id="edit_form_name" :field="form.name">
<template #label="{lang}">
{{ $gettext('Name') }}
</template>
</b-wrapped-form-group>
<b-form-fieldset>
<b-form-row>
<b-wrapped-form-group class="col-md-12" id="edit_form_name" :field="form.name">
<template #label="{lang}">
{{ $gettext('Name') }}
</template>
</b-wrapped-form-group>
<b-wrapped-form-group class="col-md-12" id="edit_form_description" :field="form.description"
input-type="textarea">
<template #label="{lang}">
{{ $gettext('Description') }}
</template>
</b-wrapped-form-group>
<b-wrapped-form-group class="col-md-12" id="edit_form_description" :field="form.description"
input-type="textarea">
<template #label="{lang}">
{{ $gettext('Description') }}
</template>
</b-wrapped-form-group>
<b-wrapped-form-group class="col-md-6" id="edit_form_genre" :field="form.genre">
<template #label="{lang}">
{{ $gettext('Genre') }}
</template>
</b-wrapped-form-group>
<b-wrapped-form-group class="col-md-6" id="edit_form_genre" :field="form.genre">
<template #label="{lang}">
{{ $gettext('Genre') }}
</template>
</b-wrapped-form-group>
<b-wrapped-form-group class="col-md-6" id="edit_form_url" :field="form.url" input-type="url">
<template #label="{lang}">
{{ $gettext('Web Site URL') }}
</template>
<template #description="{lang}">
{{
$gettext('Note: This should be the public-facing homepage of the radio station, not the AzuraCast URL. It will be included in broadcast details.')
}}
</template>
</b-wrapped-form-group>
<b-wrapped-form-group class="col-md-6" id="edit_form_url" :field="form.url" input-type="url">
<template #label="{lang}">
{{ $gettext('Web Site URL') }}
</template>
<template #description="{lang}">
{{
$gettext('Note: This should be the public-facing homepage of the radio station, not the AzuraCast URL. It will be included in broadcast details.')
}}
</template>
</b-wrapped-form-group>
<b-wrapped-form-group class="col-md-12" id="edit_form_timezone" :field="form.timezone">
<template #label="{lang}">
{{ $gettext('Time Zone') }}
</template>
<template #description="{lang}">
{{
$gettext('Scheduled playlists and other timed items will be controlled by this time zone.')
}}
</template>
<template #default="props">
<b-form-select :id="props.id" v-model="props.field.$model"
:options="timezoneOptions"></b-form-select>
</template>
</b-wrapped-form-group>
<b-wrapped-form-group class="col-md-12" id="edit_form_timezone" :field="form.timezone">
<template #label="{lang}">
{{ $gettext('Time Zone') }}
</template>
<template #description="{lang}">
{{
$gettext('Scheduled playlists and other timed items will be controlled by this time zone.')
}}
</template>
<template #default="props">
<b-form-select :id="props.id" v-model="props.field.$model"
:options="timezoneOptions"></b-form-select>
</template>
</b-wrapped-form-group>
<b-wrapped-form-group class="col-md-6" id="edit_form_default_album_art_url"
:field="form.default_album_art_url">
<template #label="{lang}">
{{ $gettext('Default Album Art URL') }}
</template>
<template #description="{lang}">
{{
$gettext('If a song has no album art, this URL will be listed instead. Leave blank to use the standard placeholder art.')
}}
</template>
</b-wrapped-form-group>
<b-wrapped-form-group class="col-md-6" id="edit_form_default_album_art_url"
:field="form.default_album_art_url">
<template #label="{lang}">
{{ $gettext('Default Album Art URL') }}
</template>
<template #description="{lang}">
{{
$gettext('If a song has no album art, this URL will be listed instead. Leave blank to use the standard placeholder art.')
}}
</template>
</b-wrapped-form-group>
<b-wrapped-form-group v-if="showAdvanced" class="col-md-6" id="edit_form_short_name"
:field="form.short_name" advanced>
<template #label="{lang}">
{{ $gettext('URL Stub') }}
</template>
<template #description="{lang}">
{{
$gettext('Optionally specify a short URL-friendly name, such as "my_station_name", that will be used in this station\'s URLs. Leave this field blank to automatically create one based on the station name.')
}}
</template>
</b-wrapped-form-group>
<b-wrapped-form-group v-if="showAdvanced" class="col-md-6" id="edit_form_short_name"
:field="form.short_name" advanced>
<template #label="{lang}">
{{ $gettext('URL Stub') }}
</template>
<template #description="{lang}">
{{
$gettext('Optionally specify a short URL-friendly name, such as "my_station_name", that will be used in this station\'s URLs. Leave this field blank to automatically create one based on the station name.')
}}
</template>
</b-wrapped-form-group>
<b-wrapped-form-group v-if="showAdvanced" class="col-md-6" id="edit_form_api_history_items"
:field="form.api_history_items" advanced>
<template #label="{lang}">
{{ $gettext('Number of Visible Recent Songs') }}
</template>
<template #description="{lang}">
{{
$gettext('Customize the number of songs that will appear in the "Song History" section for this station and in all public APIs.')
}}
</template>
<template #default="props">
<b-form-select :id="props.id" v-model="props.field.$model"
:options="historyItemsOptions"></b-form-select>
</template>
</b-wrapped-form-group>
</b-form-row>
</b-form-fieldset>
<b-wrapped-form-group v-if="showAdvanced" class="col-md-6" id="edit_form_api_history_items"
:field="form.api_history_items" advanced>
<template #label="{lang}">
{{ $gettext('Number of Visible Recent Songs') }}
</template>
<template #description="{lang}">
{{
$gettext('Customize the number of songs that will appear in the "Song History" section for this station and in all public APIs.')
}}
</template>
<template #default="props">
<b-form-select :id="props.id" v-model="props.field.$model"
:options="historyItemsOptions"></b-form-select>
</template>
</b-wrapped-form-group>
</b-form-row>
</b-form-fieldset>
<b-form-fieldset>
<template #label>
{{ $gettext('Public Pages') }}
</template>
<b-form-fieldset>
<template #label>
{{ $gettext('Public Pages') }}
</template>
<b-form-row>
<b-wrapped-form-checkbox class="col-md-12" id="edit_form_enable_public_page"
:field="form.enable_public_page">
<template #label="{lang}">
{{ $gettext('Enable Public Pages') }}
</template>
<template #description="{lang}">
{{ $gettext('Show the station in public pages and general API results.') }}
</template>
</b-wrapped-form-checkbox>
</b-form-row>
</b-form-fieldset>
<b-form-row>
<b-wrapped-form-checkbox class="col-md-12" id="edit_form_enable_public_page"
:field="form.enable_public_page">
<template #label="{lang}">
{{ $gettext('Enable Public Pages') }}
</template>
<template #description="{lang}">
{{ $gettext('Show the station in public pages and general API results.') }}
</template>
</b-wrapped-form-checkbox>
</b-form-row>
</b-form-fieldset>
<b-form-fieldset>
<template #label>
{{ $gettext('On-Demand Streaming') }}
</template>
<b-form-fieldset>
<template #label>
{{ $gettext('On-Demand Streaming') }}
</template>
<b-form-row>
<b-wrapped-form-checkbox class="col-md-12" id="edit_form_enable_on_demand"
:field="form.enable_on_demand">
<template #label="{lang}">
{{ $gettext('Enable On-Demand Streaming') }}
</template>
<template #description="{lang}">
{{
$gettext('If enabled, music from playlists with on-demand streaming enabled will be available to stream via a specialized public page.')
}}
</template>
</b-wrapped-form-checkbox>
<b-form-row>
<b-wrapped-form-checkbox class="col-md-12" id="edit_form_enable_on_demand"
:field="form.enable_on_demand">
<template #label="{lang}">
{{ $gettext('Enable On-Demand Streaming') }}
</template>
<template #description="{lang}">
{{
$gettext('If enabled, music from playlists with on-demand streaming enabled will be available to stream via a specialized public page.')
}}
</template>
</b-wrapped-form-checkbox>
<b-wrapped-form-checkbox v-if="form.enable_on_demand.$model" class="col-md-12"
id="edit_form_enable_on_demand_download"
:field="form.enable_on_demand_download">
<template #label="{lang}">
{{ $gettext('Enable Downloads on On-Demand Page') }}
</template>
<template #description="{lang}">
{{
$gettext('If enabled, a download button will also be present on the public "On-Demand" page.')
}}
</template>
</b-wrapped-form-checkbox>
</b-form-row>
</b-form-fieldset>
</div>
<b-wrapped-form-checkbox v-if="form.enable_on_demand.$model" class="col-md-12"
id="edit_form_enable_on_demand_download"
:field="form.enable_on_demand_download">
<template #label="{lang}">
{{ $gettext('Enable Downloads on On-Demand Page') }}
</template>
<template #description="{lang}">
{{
$gettext('If enabled, a download button will also be present on the public "On-Demand" page.')
}}
</template>
</b-wrapped-form-checkbox>
</b-form-row>
</b-form-fieldset>
</template>
<script>

View File

@ -1,65 +1,63 @@
<template>
<div>
<b-form-fieldset v-if="isBackendEnabled">
<b-form-fieldset v-if="isBackendEnabled">
<b-form-fieldset>
<template #label>
{{ $gettext('Song Requests') }}
</template>
<template #description>
{{
$gettext('Some stream licensing providers may have specific rules regarding song requests. Check your local regulations for more information.')
}}
</template>
<b-form-fieldset>
<template #label>
{{ $gettext('Song Requests') }}
</template>
<template #description>
{{
$gettext('Some stream licensing providers may have specific rules regarding song requests. Check your local regulations for more information.')
}}
</template>
<b-form-row>
<b-wrapped-form-checkbox class="col-md-12" id="edit_form_enable_requests"
:field="form.enable_requests">
<template #label="{lang}">
{{ $gettext('Allow Song Requests') }}
</template>
<template #description="{lang}">
{{
$gettext('Enable listeners to request a song for play on your station. Only songs that are already in your playlists are requestable.')
}}
</template>
</b-wrapped-form-checkbox>
</b-form-row>
</b-form-fieldset>
<b-form-fieldset>
<b-form-row>
<b-wrapped-form-checkbox class="col-md-12" id="edit_form_enable_requests"
:field="form.enable_requests">
<template #label="{lang}">
{{ $gettext('Allow Song Requests') }}
</template>
<template #description="{lang}">
{{
$gettext('Enable listeners to request a song for play on your station. Only songs that are already in your playlists are requestable.')
}}
</template>
</b-wrapped-form-checkbox>
</b-form-row>
</b-form-fieldset>
<b-form-fieldset v-if="form.enable_requests.$model">
<b-form-row>
<b-wrapped-form-group class="col-md-6" id="edit_form_request_delay"
:field="form.request_delay" input-type="number"
:input-attrs="{ min: '0', max: '1440' }">
<template #label="{lang}">
{{ $gettext('Request Minimum Delay (Minutes)') }}
</template>
<template #description="{lang}">
{{
$gettext('If requests are enabled, this specifies the minimum delay (in minutes) between a request being submitted and being played. If set to zero, a minor delay of 15 seconds is applied to prevent request floods.')
}}
</template>
</b-wrapped-form-group>
<b-form-fieldset v-if="form.enable_requests.$model">
<b-form-row>
<b-wrapped-form-group class="col-md-6" id="edit_form_request_delay"
:field="form.request_delay" input-type="number"
:input-attrs="{ min: '0', max: '1440' }">
<template #label="{lang}">
{{ $gettext('Request Minimum Delay (Minutes)') }}
</template>
<template #description="{lang}">
{{
$gettext('If requests are enabled, this specifies the minimum delay (in minutes) between a request being submitted and being played. If set to zero, a minor delay of 15 seconds is applied to prevent request floods.')
}}
</template>
</b-wrapped-form-group>
<b-wrapped-form-group class="col-md-6" id="edit_form_request_threshold"
:field="form.request_threshold" input-type="number"
:input-attrs="{ min: '0', max: '1440' }">
<template #label="{lang}">
{{ $gettext('Request Last Played Threshold (Minutes)') }}
</template>
<template #description="{lang}">
{{
$gettext('This specifies the minimum time (in minutes) between a song playing on the radio and being available to request again. Set to 0 for no threshold.')
}}
</template>
</b-wrapped-form-group>
</b-form-row>
</b-form-fieldset>
<b-wrapped-form-group class="col-md-6" id="edit_form_request_threshold"
:field="form.request_threshold" input-type="number"
:input-attrs="{ min: '0', max: '1440' }">
<template #label="{lang}">
{{ $gettext('Request Last Played Threshold (Minutes)') }}
</template>
<template #description="{lang}">
{{
$gettext('This specifies the minimum time (in minutes) between a song playing on the radio and being available to request again. Set to 0 for no threshold.')
}}
</template>
</b-wrapped-form-group>
</b-form-row>
</b-form-fieldset>
</b-form-fieldset>
<backend-disabled v-else></backend-disabled>
</div>
</b-form-fieldset>
<backend-disabled v-else></backend-disabled>
</template>
<script>

View File

@ -1,139 +1,137 @@
<template>
<div>
<b-form-fieldset v-if="isBackendEnabled">
<b-form-fieldset>
<template #label>
{{ $gettext('Streamers/DJs') }}
</template>
<b-form-fieldset v-if="isBackendEnabled">
<b-form-fieldset>
<template #label>
{{ $gettext('Streamers/DJs') }}
</template>
<b-form-fieldset>
<b-form-row>
<b-wrapped-form-checkbox class="col-md-12" id="edit_form_enable_streamers"
:field="form.enable_streamers">
<template #label="{lang}">
{{ $gettext('Allow Streamers / DJs') }}
</template>
<template #description="{lang}">
{{
$gettext('If enabled, streamers (or DJs) will be able to connect directly to your stream and broadcast live music that interrupts the AutoDJ stream.')
}}
</template>
</b-wrapped-form-checkbox>
</b-form-row>
</b-form-fieldset>
<b-form-fieldset v-if="form.enable_streamers.$model">
<b-form-fieldset>
<b-form-row>
<b-wrapped-form-checkbox class="col-md-12" id="edit_form_enable_streamers"
:field="form.enable_streamers">
<b-wrapped-form-checkbox class="col-md-12" id="edit_form_backend_record_streams"
:field="form.backend_config.record_streams">
<template #label="{lang}">
{{ $gettext('Allow Streamers / DJs') }}
{{ $gettext('Record Live Broadcasts') }}
</template>
<template #description="{lang}">
{{
$gettext('If enabled, streamers (or DJs) will be able to connect directly to your stream and broadcast live music that interrupts the AutoDJ stream.')
$gettext('If enabled, AzuraCast will automatically record any live broadcasts made to this station to per-broadcast recordings.')
}}
</template>
</b-wrapped-form-checkbox>
</b-form-row>
</b-form-fieldset>
<b-form-fieldset v-if="form.enable_streamers.$model">
<b-form-fieldset>
<b-form-row>
<b-wrapped-form-checkbox class="col-md-12" id="edit_form_backend_record_streams"
:field="form.backend_config.record_streams">
<template #label="{lang}">
{{ $gettext('Record Live Broadcasts') }}
</template>
<template #description="{lang}">
{{
$gettext('If enabled, AzuraCast will automatically record any live broadcasts made to this station to per-broadcast recordings.')
}}
</template>
</b-wrapped-form-checkbox>
</b-form-row>
</b-form-fieldset>
<b-form-fieldset v-if="form.backend_config.record_streams.$model">
<b-form-row>
<b-wrapped-form-group class="col-md-6" id="edit_form_backend_record_streams_format"
:field="form.backend_config.record_streams_format">
<template #label="{lang}">
{{ $gettext('Live Broadcast Recording Format') }}
</template>
<b-form-fieldset v-if="form.backend_config.record_streams.$model">
<b-form-row>
<b-wrapped-form-group class="col-md-6" id="edit_form_backend_record_streams_format"
:field="form.backend_config.record_streams_format">
<template #label="{lang}">
{{ $gettext('Live Broadcast Recording Format') }}
</template>
<template #default="props">
<b-form-radio-group stacked :id="props.id" :options="recordStreamsOptions"
v-model="props.field.$model">
</b-form-radio-group>
</template>
</b-wrapped-form-group>
<template #default="props">
<b-form-radio-group stacked :id="props.id" :options="recordStreamsOptions"
v-model="props.field.$model">
</b-form-radio-group>
</template>
</b-wrapped-form-group>
<b-wrapped-form-group class="col-md-6" id="edit_form_backend_record_streams_bitrate"
:field="form.backend_config.record_streams_bitrate">
<template #label="{lang}">
{{ $gettext('Live Broadcast Recording Bitrate (kbps)') }}
</template>
<b-wrapped-form-group class="col-md-6" id="edit_form_backend_record_streams_bitrate"
:field="form.backend_config.record_streams_bitrate">
<template #label="{lang}">
{{ $gettext('Live Broadcast Recording Bitrate (kbps)') }}
</template>
<template #default="props">
<b-form-radio-group stacked :id="props.id" :options="recordBitrateOptions"
v-model="props.field.$model">
</b-form-radio-group>
</template>
</b-wrapped-form-group>
</b-form-row>
</b-form-fieldset>
<template #default="props">
<b-form-radio-group stacked :id="props.id" :options="recordBitrateOptions"
v-model="props.field.$model">
</b-form-radio-group>
</template>
</b-wrapped-form-group>
</b-form-row>
</b-form-fieldset>
<b-form-fieldset>
<b-form-row>
<b-wrapped-form-group class="col-md-6" id="edit_form_disconnect_deactivate_streamer"
:field="form.disconnect_deactivate_streamer" input-type="number"
:input-attrs="{ min: '0' }">
<template #label="{lang}">
{{ $gettext('Deactivate Streamer on Disconnect (Seconds)') }}
</template>
<template #description="{lang}">
{{
$gettext('This is the number of seconds until a streamer who has been manually disconnected can reconnect to the stream. Set to 0 to allow the streamer to immediately reconnect.')
}}
</template>
</b-wrapped-form-group>
<b-form-fieldset>
<b-form-row>
<b-wrapped-form-group class="col-md-6" id="edit_form_disconnect_deactivate_streamer"
:field="form.disconnect_deactivate_streamer" input-type="number"
:input-attrs="{ min: '0' }">
<template #label="{lang}">
{{ $gettext('Deactivate Streamer on Disconnect (Seconds)') }}
</template>
<template #description="{lang}">
{{
$gettext('This is the number of seconds until a streamer who has been manually disconnected can reconnect to the stream. Set to 0 to allow the streamer to immediately reconnect.')
}}
</template>
</b-wrapped-form-group>
<b-wrapped-form-group v-if="showAdvanced" class="col-md-6"
id="edit_form_backend_dj_port"
:field="form.backend_config.dj_port" input-type="number"
:input-attrs="{ min: '0' }" advanced>
<template #label="{lang}">
{{ $gettext('Customize DJ/Streamer Port') }}
</template>
<template #description="{lang}">
{{
$gettext('No other program can be using this port. Leave blank to automatically assign a port.')
}}
<br>
{{
$gettext('Note: the port after this one will automatically be used for legacy connections.')
}}
</template>
</b-wrapped-form-group>
<b-wrapped-form-group v-if="showAdvanced" class="col-md-6"
id="edit_form_backend_dj_port"
:field="form.backend_config.dj_port" input-type="number"
:input-attrs="{ min: '0' }" advanced>
<template #label="{lang}">
{{ $gettext('Customize DJ/Streamer Port') }}
</template>
<template #description="{lang}">
{{
$gettext('No other program can be using this port. Leave blank to automatically assign a port.')
}}
<br>
{{
$gettext('Note: the port after this one will automatically be used for legacy connections.')
}}
</template>
</b-wrapped-form-group>
<b-wrapped-form-group class="col-md-6" id="edit_form_backend_dj_buffer"
:field="form.backend_config.dj_buffer" input-type="number"
:input-attrs="{ min: '0', max: '60' }">
<template #label="{lang}">
{{ $gettext('DJ/Streamer Buffer Time (Seconds)') }}
</template>
<template #description="{lang}">
{{
$gettext('The number of seconds of signal to store in case of interruption. Set to the lowest value that your DJs can use without stream interruptions.')
}}
</template>
</b-wrapped-form-group>
<b-wrapped-form-group class="col-md-6" id="edit_form_backend_dj_buffer"
:field="form.backend_config.dj_buffer" input-type="number"
:input-attrs="{ min: '0', max: '60' }">
<template #label="{lang}">
{{ $gettext('DJ/Streamer Buffer Time (Seconds)') }}
</template>
<template #description="{lang}">
{{
$gettext('The number of seconds of signal to store in case of interruption. Set to the lowest value that your DJs can use without stream interruptions.')
}}
</template>
</b-wrapped-form-group>
<b-wrapped-form-group v-if="showAdvanced" class="col-md-6"
id="edit_form_backend_dj_mount_point"
:field="form.backend_config.dj_mount_point" advanced>
<template #label="{lang}">
{{ $gettext('Customize DJ/Streamer Mount Point') }}
</template>
<template #description="{lang}">
{{
$gettext('If your streaming software requires a specific mount point path, specify it here. Otherwise, use the default.')
}}
</template>
</b-wrapped-form-group>
</b-form-row>
</b-form-fieldset>
<b-wrapped-form-group v-if="showAdvanced" class="col-md-6"
id="edit_form_backend_dj_mount_point"
:field="form.backend_config.dj_mount_point" advanced>
<template #label="{lang}">
{{ $gettext('Customize DJ/Streamer Mount Point') }}
</template>
<template #description="{lang}">
{{
$gettext('If your streaming software requires a specific mount point path, specify it here. Otherwise, use the default.')
}}
</template>
</b-wrapped-form-group>
</b-form-row>
</b-form-fieldset>
</b-form-fieldset>
</b-form-fieldset>
<backend-disabled v-else></backend-disabled>
</div>
</b-form-fieldset>
<backend-disabled v-else></backend-disabled>
</template>
<script>

View File

@ -1,57 +1,56 @@
<template>
<div>
<b-card no-body>
<b-card-header header-bg-variant="primary-dark">
<h2 class="card-title">{{ $gettext('Storage Locations') }}</h2>
</b-card-header>
<b-tabs pills card lazy>
<b-tab v-for="tab in tabs" :key="tab.type" :active="activeType === tab.type" @click="setType(tab.type)"
:title="tab.title" no-body></b-tab>
</b-tabs>
<b-card no-body>
<b-card-header header-bg-variant="primary-dark">
<h2 class="card-title">{{ $gettext('Storage Locations') }}</h2>
</b-card-header>
<b-tabs pills card lazy>
<b-tab v-for="tab in tabs" :key="tab.type" :active="activeType === tab.type" @click="setType(tab.type)"
:title="tab.title" no-body></b-tab>
</b-tabs>
<b-card-body body-class="card-padding-sm">
<b-button variant="outline-primary" @click.prevent="doCreate">
<icon icon="add"></icon>
{{ $gettext('Add Storage Location') }}
</b-button>
</b-card-body>
<b-card-body body-class="card-padding-sm">
<b-button variant="outline-primary" @click.prevent="doCreate">
<icon icon="add"></icon>
{{ $gettext('Add Storage Location') }}
</b-button>
</b-card-body>
<data-table ref="datatable" id="admin_storage_locations" :show-toolbar="false" :fields="fields" :responsive="false"
:api-url="listUrlForType">
<template #cell(actions)="row">
<b-button-group size="sm">
<b-button size="sm" variant="primary" @click.prevent="doEdit(row.item.links.self)">
{{ $gettext('Edit') }}
</b-button>
<b-button size="sm" variant="danger" @click.prevent="doDelete(row.item.links.self)">
{{ $gettext('Delete') }}
</b-button>
</b-button-group>
</template>
<template #cell(adapter)="row">
<h5 class="m-0">{{ getAdapterName(row.item.adapter) }}</h5>
<p class="card-text">{{ row.item.uri }}</p>
</template>
<template #cell(space)="row">
<template v-if="row.item.storageAvailable">
<b-progress :value="row.item.storageUsedPercent" show-progress height="15px" class="mb-1"
:variant="getProgressVariant(row.item.storageUsedPercent)">
</b-progress>
<data-table ref="datatable" id="admin_storage_locations" :show-toolbar="false" :fields="fields"
:responsive="false"
:api-url="listUrlForType">
<template #cell(actions)="row">
<b-button-group size="sm">
<b-button size="sm" variant="primary" @click.prevent="doEdit(row.item.links.self)">
{{ $gettext('Edit') }}
</b-button>
<b-button size="sm" variant="danger" @click.prevent="doDelete(row.item.links.self)">
{{ $gettext('Delete') }}
</b-button>
</b-button-group>
</template>
<template #cell(adapter)="row">
<h5 class="m-0">{{ getAdapterName(row.item.adapter) }}</h5>
<p class="card-text">{{ row.item.uri }}</p>
</template>
<template #cell(space)="row">
<template v-if="row.item.storageAvailable">
<b-progress :value="row.item.storageUsedPercent" show-progress height="15px" class="mb-1"
:variant="getProgressVariant(row.item.storageUsedPercent)">
</b-progress>
{{ getSpaceUsed(row.item) }}
</template>
<template v-else>
{{ getSpaceUsed(row.item) }}
</template>
{{ getSpaceUsed(row.item) }}
</template>
<template #cell(stations)="row">
{{ row.item.stations.join(', ') }}
<template v-else>
{{ getSpaceUsed(row.item) }}
</template>
</data-table>
</b-card>
</template>
<template #cell(stations)="row">
{{ row.item.stations.join(', ') }}
</template>
</data-table>
</b-card>
<edit-modal ref="editModal" :create-url="listUrl" :type="activeType" @relist="relist"></edit-modal>
</div>
<edit-modal ref="editModal" :create-url="listUrl" :type="activeType" @relist="relist"></edit-modal>
</template>
<script>

View File

@ -1,178 +1,183 @@
<template>
<div>
<b-form-group>
<b-form-row>
<b-wrapped-form-group class="col-md-12" id="form_edit_adapter" :field="form.adapter">
<template #label="{lang}">
{{ $gettext('Storage Adapter') }}
</template>
<template #default="props">
<b-form-radio-group stacked :id="props.id" v-model="props.field.$model">
<b-form-radio value="local">
{{ $gettext('Local Filesystem') }}
</b-form-radio>
<b-form-radio value="s3">
{{ $gettext('Remote: S3 Compatible') }}
</b-form-radio>
<b-form-radio value="dropbox">
{{ $gettext('Remote: Dropbox') }}
</b-form-radio>
<b-form-radio value="sftp">
{{ $gettext('Remote: SFTP') }}
</b-form-radio>
</b-form-radio-group>
</template>
</b-wrapped-form-group>
<b-form-group>
<b-form-row>
<b-wrapped-form-group class="col-md-12" id="form_edit_adapter" :field="form.adapter">
<template #label="{lang}">
{{ $gettext('Storage Adapter') }}
</template>
<template #default="props">
<b-form-radio-group stacked :id="props.id" v-model="props.field.$model">
<b-form-radio value="local">
{{ $gettext('Local Filesystem') }}
</b-form-radio>
<b-form-radio value="s3">
{{ $gettext('Remote: S3 Compatible') }}
</b-form-radio>
<b-form-radio value="dropbox">
{{ $gettext('Remote: Dropbox') }}
</b-form-radio>
<b-form-radio value="sftp">
{{ $gettext('Remote: SFTP') }}
</b-form-radio>
</b-form-radio-group>
</template>
</b-wrapped-form-group>
<b-wrapped-form-group class="col-md-12" id="form_edit_path" :field="form.path">
<template #label="{lang}">
{{ $gettext('Path/Suffix') }}
</template>
<template #description="{lang}">
{{ $gettext('For local filesystems, this is the base path of the directory. For remote filesystems, this is the folder prefix.') }}
</template>
</b-wrapped-form-group>
<b-wrapped-form-group class="col-md-12" id="form_edit_path" :field="form.path">
<template #label="{lang}">
{{ $gettext('Path/Suffix') }}
</template>
<template #description="{lang}">
{{
$gettext('For local filesystems, this is the base path of the directory. For remote filesystems, this is the folder prefix.')
}}
</template>
</b-wrapped-form-group>
<b-wrapped-form-group class="col-md-12" id="form_edit_storageQuota" :field="form.storageQuota">
<template #label="{lang}">
{{ $gettext('Storage Quota') }}
</template>
<template #description="{lang}">
{{ $gettext('Set a maximum disk space that this storage location can use. Specify the size with unit, i.e. "8 GB". Units are measured in 1024 bytes. Leave blank to default to the available space on the disk.') }}
</template>
</b-wrapped-form-group>
</b-form-row>
</b-form-group>
<b-wrapped-form-group class="col-md-12" id="form_edit_storageQuota" :field="form.storageQuota">
<template #label="{lang}">
{{ $gettext('Storage Quota') }}
</template>
<template #description="{lang}">
{{
$gettext('Set a maximum disk space that this storage location can use. Specify the size with unit, i.e. "8 GB". Units are measured in 1024 bytes. Leave blank to default to the available space on the disk.')
}}
</template>
</b-wrapped-form-group>
</b-form-row>
</b-form-group>
<b-card v-show="form.adapter.$model === 's3'" class="mb-3" no-body>
<div class="card-header bg-primary-dark">
<h2 class="card-title">
{{ $gettext('Remote: S3 Compatible') }}
</h2>
</div>
<b-card-body>
<b-form-group>
<b-form-row>
<b-wrapped-form-group class="col-md-6" id="form_edit_s3CredentialKey"
:field="form.s3CredentialKey">
<template #label="{lang}">
{{ $gettext('Access Key ID') }}
</template>
</b-wrapped-form-group>
<b-card v-show="form.adapter.$model === 's3'" class="mb-3" no-body>
<div class="card-header bg-primary-dark">
<h2 class="card-title">
{{ $gettext('Remote: S3 Compatible') }}
</h2>
</div>
<b-card-body>
<b-form-group>
<b-form-row>
<b-wrapped-form-group class="col-md-6" id="form_edit_s3CredentialKey"
:field="form.s3CredentialKey">
<template #label="{lang}">
{{ $gettext('Access Key ID') }}
</template>
</b-wrapped-form-group>
<b-wrapped-form-group class="col-md-6" id="form_edit_s3CredentialSecret"
:field="form.s3CredentialSecret">
<template #label="{lang}">
{{ $gettext('Secret Key') }}
</template>
</b-wrapped-form-group>
<b-wrapped-form-group class="col-md-6" id="form_edit_s3CredentialSecret"
:field="form.s3CredentialSecret">
<template #label="{lang}">
{{ $gettext('Secret Key') }}
</template>
</b-wrapped-form-group>
<b-wrapped-form-group class="col-md-6" id="form_edit_s3Endpoint" :field="form.s3Endpoint">
<template #label="{lang}">
{{ $gettext('Endpoint') }}
</template>
</b-wrapped-form-group>
<b-wrapped-form-group class="col-md-6" id="form_edit_s3Endpoint" :field="form.s3Endpoint">
<template #label="{lang}">
{{ $gettext('Endpoint') }}
</template>
</b-wrapped-form-group>
<b-wrapped-form-group class="col-md-6" id="form_edit_s3Bucket" :field="form.s3Bucket">
<template #label="{lang}">
{{ $gettext('Bucket Name') }}
</template>
</b-wrapped-form-group>
<b-wrapped-form-group class="col-md-6" id="form_edit_s3Bucket" :field="form.s3Bucket">
<template #label="{lang}">
{{ $gettext('Bucket Name') }}
</template>
</b-wrapped-form-group>
<b-wrapped-form-group class="col-md-6" id="form_edit_s3Region" :field="form.s3Region">
<template #label="{lang}">
{{ $gettext('Region') }}
</template>
</b-wrapped-form-group>
<b-wrapped-form-group class="col-md-6" id="form_edit_s3Region" :field="form.s3Region">
<template #label="{lang}">
{{ $gettext('Region') }}
</template>
</b-wrapped-form-group>
<b-wrapped-form-group class="col-md-6" id="form_edit_s3Version" :field="form.s3Version">
<template #label="{lang}">
{{ $gettext('API Version') }}
</template>
</b-wrapped-form-group>
</b-form-row>
</b-form-group>
</b-card-body>
</b-card>
<b-wrapped-form-group class="col-md-6" id="form_edit_s3Version" :field="form.s3Version">
<template #label="{lang}">
{{ $gettext('API Version') }}
</template>
</b-wrapped-form-group>
</b-form-row>
</b-form-group>
</b-card-body>
</b-card>
<b-card v-show="form.adapter.$model === 'dropbox'" class="mb-3" no-body>
<div class="card-header bg-primary-dark">
<h2 class="card-title">
{{ $gettext('Remote: Dropbox') }}
</h2>
</div>
<b-card-body>
<b-form-group>
<b-form-row>
<b-wrapped-form-group class="col-md-12" id="form_edit_dropboxAuthToken"
:field="form.dropboxAuthToken">
<template #label="{lang}">
{{ $gettext('Dropbox Generated Access Token') }}
</template>
<template #description="{lang}">
{{ $gettext('Note: Dropbox now only issues short-lived tokens that will not work for this purpose. If your token begins with "sl", it is short-lived and will not work correctly.') }}
</template>
</b-wrapped-form-group>
</b-form-row>
</b-form-group>
</b-card-body>
</b-card>
<b-card v-show="form.adapter.$model === 'sftp'" class="mb-3" no-body>
<div class="card-header bg-primary-dark">
<h2 class="card-title">
{{ $gettext('Remote: SFTP') }}
</h2>
</div>
<b-card-body>
<b-form-group>
<b-form-row>
<b-wrapped-form-group class="col-md-12 col-lg-6" id="form_edit_sftpHost"
:field="form.sftpHost">
<template #label="{lang}">
{{ $gettext('SFTP Host') }}
</template>
</b-wrapped-form-group>
<b-card v-show="form.adapter.$model === 'dropbox'" class="mb-3" no-body>
<div class="card-header bg-primary-dark">
<h2 class="card-title">
{{ $gettext('Remote: Dropbox') }}
</h2>
</div>
<b-card-body>
<b-form-group>
<b-form-row>
<b-wrapped-form-group class="col-md-12" id="form_edit_dropboxAuthToken"
:field="form.dropboxAuthToken">
<template #label="{lang}">
{{ $gettext('Dropbox Generated Access Token') }}
</template>
<template #description="{lang}">
{{
$gettext('Note: Dropbox now only issues short-lived tokens that will not work for this purpose. If your token begins with "sl", it is short-lived and will not work correctly.')
}}
</template>
</b-wrapped-form-group>
</b-form-row>
</b-form-group>
</b-card-body>
</b-card>
<b-wrapped-form-group class="col-md-12 col-lg-6" id="form_edit_sftpPort" input-type="number" min="1" step="1"
:field="form.sftpPort">
<template #label="{lang}">
{{ $gettext('SFTP Port') }}
</template>
</b-wrapped-form-group>
<b-card v-show="form.adapter.$model === 'sftp'" class="mb-3" no-body>
<div class="card-header bg-primary-dark">
<h2 class="card-title">
{{ $gettext('Remote: SFTP') }}
</h2>
</div>
<b-card-body>
<b-form-group>
<b-form-row>
<b-wrapped-form-group class="col-md-12 col-lg-6" id="form_edit_sftpHost"
:field="form.sftpHost">
<template #label="{lang}">
{{ $gettext('SFTP Host') }}
</template>
</b-wrapped-form-group>
<b-wrapped-form-group class="col-md-12 col-lg-6" id="form_edit_sftpUsername"
:field="form.sftpUsername">
<template #label="{lang}">
{{ $gettext('SFTP Username') }}
</template>
</b-wrapped-form-group>
<b-wrapped-form-group class="col-md-12 col-lg-6" id="form_edit_sftpPort" input-type="number" min="1"
step="1"
:field="form.sftpPort">
<template #label="{lang}">
{{ $gettext('SFTP Port') }}
</template>
</b-wrapped-form-group>
<b-wrapped-form-group class="col-md-12 col-lg-6" id="form_edit_sftpPassword"
:field="form.sftpPassword">
<template #label="{lang}">
{{ $gettext('SFTP Password') }}
</template>
</b-wrapped-form-group>
<b-wrapped-form-group class="col-md-12 col-lg-6" id="form_edit_sftpUsername"
:field="form.sftpUsername">
<template #label="{lang}">
{{ $gettext('SFTP Username') }}
</template>
</b-wrapped-form-group>
<b-wrapped-form-group class="col-md-12" id="form_edit_sftpPrivateKeyPassPhrase"
:field="form.sftpPrivateKeyPassPhrase">
<template #label="{lang}">
{{ $gettext('SFTP Private Key Pass Phrase') }}
</template>
</b-wrapped-form-group>
<b-wrapped-form-group class="col-md-12" id="form_edit_sftpPrivateKey" input-type="textarea"
:field="form.sftpPrivateKey">
<template #label="{lang}">
{{ $gettext('SFTP Private Key') }}
</template>
</b-wrapped-form-group>
</b-form-row>
</b-form-group>
</b-card-body>
</b-card>
</div>
<b-wrapped-form-group class="col-md-12 col-lg-6" id="form_edit_sftpPassword"
:field="form.sftpPassword">
<template #label="{lang}">
{{ $gettext('SFTP Password') }}
</template>
</b-wrapped-form-group>
<b-wrapped-form-group class="col-md-12" id="form_edit_sftpPrivateKeyPassPhrase"
:field="form.sftpPrivateKeyPassPhrase">
<template #label="{lang}">
{{ $gettext('SFTP Private Key Pass Phrase') }}
</template>
</b-wrapped-form-group>
<b-wrapped-form-group class="col-md-12" id="form_edit_sftpPrivateKey" input-type="textarea"
:field="form.sftpPrivateKey">
<template #label="{lang}">
{{ $gettext('SFTP Private Key') }}
</template>
</b-wrapped-form-group>
</b-form-row>
</b-form-group>
</b-card-body>
</b-card>
</template>
<script>

View File

@ -1,48 +1,46 @@
<template>
<div>
<b-card no-body>
<b-card-header header-bg-variant="primary-dark">
<h2 class="card-title">{{ $gettext('Users') }}</h2>
</b-card-header>
<b-card no-body>
<b-card-header header-bg-variant="primary-dark">
<h2 class="card-title">{{ $gettext('Users') }}</h2>
</b-card-header>
<b-card-body body-class="card-padding-sm">
<b-button variant="outline-primary" @click.prevent="doCreate">
<icon icon="add"></icon>
{{ $gettext('Add User') }}
</b-button>
</b-card-body>
<b-card-body body-class="card-padding-sm">
<b-button variant="outline-primary" @click.prevent="doCreate">
<icon icon="add"></icon>
{{ $gettext('Add User') }}
</b-button>
</b-card-body>
<data-table ref="datatable" id="users" paginated :fields="fields" :api-url="listUrl">
<template #cell(name)="row">
<h5 class="mb-0" v-if="row.item.name !== ''">{{ row.item.name }}</h5>
<a :href="'mailto:'+row.item.email">{{ row.item.email }}</a>
<span v-if="row.item.is_me" class="badge badge-primary">
{{ $gettext('You') }}
</span>
</template>
<template #cell(roles)="row">
<div v-for="role in row.item.roles" :key="role.id">
{{ role.name }}
</div>
</template>
<template #cell(actions)="row">
<b-button-group size="sm" v-if="!row.item.is_me">
<b-button size="sm" variant="secondary" :href="row.item.links.masquerade" target="_blank">
{{ $gettext('Log In') }}
</b-button>
<b-button size="sm" variant="primary" @click.prevent="doEdit(row.item.links.self)">
{{ $gettext('Edit') }}
</b-button>
<b-button size="sm" variant="danger" @click.prevent="doDelete(row.item.links.self)">
{{ $gettext('Delete') }}
</b-button>
</b-button-group>
</template>
</data-table>
</b-card>
<data-table ref="datatable" id="users" paginated :fields="fields" :api-url="listUrl">
<template #cell(name)="row">
<h5 class="mb-0" v-if="row.item.name !== ''">{{ row.item.name }}</h5>
<a :href="'mailto:'+row.item.email">{{ row.item.email }}</a>
<span v-if="row.item.is_me" class="badge badge-primary">
{{ $gettext('You') }}
</span>
</template>
<template #cell(roles)="row">
<div v-for="role in row.item.roles" :key="role.id">
{{ role.name }}
</div>
</template>
<template #cell(actions)="row">
<b-button-group size="sm" v-if="!row.item.is_me">
<b-button size="sm" variant="secondary" :href="row.item.links.masquerade" target="_blank">
{{ $gettext('Log In') }}
</b-button>
<b-button size="sm" variant="primary" @click.prevent="doEdit(row.item.links.self)">
{{ $gettext('Edit') }}
</b-button>
<b-button size="sm" variant="danger" @click.prevent="doDelete(row.item.links.self)">
{{ $gettext('Delete') }}
</b-button>
</b-button-group>
</template>
</data-table>
</b-card>
<edit-modal ref="editModal" :create-url="listUrl" :roles="roles" @relist="relist"></edit-modal>
</div>
<edit-modal ref="editModal" :create-url="listUrl" :roles="roles" @relist="relist"></edit-modal>
</template>
<script>

View File

@ -1,7 +1,5 @@
<template>
<div>
<audio ref="audio" v-if="isPlaying" v-bind:title="title"/>
</div>
<audio ref="audio" v-if="isPlaying" v-bind:title="title"/>
</template>
<script>

View File

@ -1,44 +1,42 @@
<template>
<div style="display: contents">
<audio-player ref="player" :volume="volume" :is-muted="isMuted"></audio-player>
<audio-player ref="player" :volume="volume" :is-muted="isMuted"></audio-player>
<div class="ml-3 player-inline" v-if="isPlaying">
<div class="inline-seek d-inline-flex align-items-center ml-1" v-if="!current.isStream && duration !== 0">
<div class="flex-shrink-0 mx-1 text-white-50 time-display">
{{ currentTimeText }}
</div>
<div class="flex-fill mx-2">
<input type="range" :title="$gettext('Seek')" class="player-seek-range custom-range" min="0"
max="100"
step="1" v-model="progress">
</div>
<div class="flex-shrink-0 mx-1 text-white-50 time-display">
{{ durationText }}
</div>
<div class="ml-3 player-inline" v-if="isPlaying">
<div class="inline-seek d-inline-flex align-items-center ml-1" v-if="!current.isStream && duration !== 0">
<div class="flex-shrink-0 mx-1 text-white-50 time-display">
{{ currentTimeText }}
</div>
<div class="flex-fill mx-2">
<input type="range" :title="$gettext('Seek')" class="player-seek-range custom-range" min="0"
max="100"
step="1" v-model="progress">
</div>
<div class="flex-shrink-0 mx-1 text-white-50 time-display">
{{ durationText }}
</div>
</div>
<a class="btn btn-sm btn-outline-light px-2 ml-1" href="#" @click.prevent="stop()"
:aria-label="$gettext('Stop')">
<icon icon="stop"></icon>
</a>
<div class="inline-volume-controls d-inline-flex align-items-center ml-1">
<div class="flex-shrink-0">
<a class="btn btn-sm btn-outline-light px-2" href="#" @click.prevent="volume = 0"
:aria-label="$gettext('Mute')">
<icon icon="volume_mute"></icon>
</a>
</div>
<div class="flex-fill mx-1">
<input type="range" :title="$gettext('Volume')" class="player-volume-range custom-range" min="0"
max="100"
step="1" v-model="volume">
</div>
<div class="flex-shrink-0">
<a class="btn btn-sm btn-outline-light px-2" href="#" @click.prevent="volume = 100"
:aria-label="$gettext('Full Volume')">
<icon icon="volume_up"></icon>
</a>
</div>
<a class="btn btn-sm btn-outline-light px-2 ml-1" href="#" @click.prevent="stop()"
:aria-label="$gettext('Stop')">
<icon icon="stop"></icon>
</a>
<div class="inline-volume-controls d-inline-flex align-items-center ml-1">
<div class="flex-shrink-0">
<a class="btn btn-sm btn-outline-light px-2" href="#" @click.prevent="volume = 0"
:aria-label="$gettext('Mute')">
<icon icon="volume_mute"></icon>
</a>
</div>
<div class="flex-fill mx-1">
<input type="range" :title="$gettext('Volume')" class="player-volume-range custom-range" min="0"
max="100"
step="1" v-model="volume">
</div>
<div class="flex-shrink-0">
<a class="btn btn-sm btn-outline-light px-2" href="#" @click.prevent="volume = 100"
:aria-label="$gettext('Full Volume')">
<icon icon="volume_up"></icon>
</a>
</div>
</div>
</div>

View File

@ -1,36 +1,34 @@
<template>
<div>
<div class="public-page">
<div class="card">
<div class="card-body">
<h2 class="card-title">{{ stationName }}</h2>
<div class="public-page">
<div class="card">
<div class="card-body">
<h2 class="card-title">{{ stationName }}</h2>
<div class="stations nowplaying">
<radio-player v-bind="$props" @np_updated="onNowPlayingUpdate"></radio-player>
</div>
</div>
<div class="card-actions">
<a class="btn btn-sm btn-outline-secondary" v-b-modal.song_history_modal>
<icon icon="history"></icon>
{{ $gettext('Song History') }}
</a>
<a class="btn btn-sm btn-outline-secondary" v-if="enableRequests" v-b-modal.request_modal>
<icon icon="help_outline"></icon>
{{ $gettext('Request Song') }}
</a>
<a class="btn btn-sm btn-outline-secondary" :href="downloadPlaylistUri">
<icon icon="file_download"></icon>
{{ $gettext('Playlist') }}
</a>
<div class="stations nowplaying">
<radio-player v-bind="$props" @np_updated="onNowPlayingUpdate"></radio-player>
</div>
</div>
</div>
<song-history-modal :show-album-art="showAlbumArt" ref="history_modal"></song-history-modal>
<request-modal :show-album-art="showAlbumArt" :request-list-uri="requestListUri"
:custom-fields="customFields"></request-modal>
<div class="card-actions">
<a class="btn btn-sm btn-outline-secondary" v-b-modal.song_history_modal>
<icon icon="history"></icon>
{{ $gettext('Song History') }}
</a>
<a class="btn btn-sm btn-outline-secondary" v-if="enableRequests" v-b-modal.request_modal>
<icon icon="help_outline"></icon>
{{ $gettext('Request Song') }}
</a>
<a class="btn btn-sm btn-outline-secondary" :href="downloadPlaylistUri">
<icon icon="file_download"></icon>
{{ $gettext('Playlist') }}
</a>
</div>
</div>
</div>
<song-history-modal :show-album-art="showAlbumArt" ref="history_modal"></song-history-modal>
<request-modal :show-album-art="showAlbumArt" :request-list-uri="requestListUri"
:custom-fields="customFields"></request-modal>
</template>
<script setup>

View File

@ -1,26 +1,26 @@
<template>
<div>
<setup-step :step="2"></setup-step>
<setup-step :step="2"></setup-step>
<b-card no-body>
<div class="card-header bg-primary-dark">
<h3 class="card-title">
{{ $gettext('Create a New Radio Station') }}
</h3>
</div>
<b-card no-body>
<div class="card-header bg-primary-dark">
<h3 class="card-title">
{{ $gettext('Create a New Radio Station') }}
</h3>
</div>
<info-card>
{{ $gettext('Continue the setup process by creating your first radio station below. You can edit any of these details later.') }}
</info-card>
<info-card>
{{
$gettext('Continue the setup process by creating your first radio station below. You can edit any of these details later.')
}}
</info-card>
<admin-stations-form v-bind="$props" ref="form" :is-edit-mode="false" :create-url="createUrl"
@submitted="onSubmitted">
<template #submitButtonText>
{{ $gettext('Create and Continue') }}
</template>
</admin-stations-form>
</b-card>
</div>
<admin-stations-form v-bind="$props" ref="form" :is-edit-mode="false" :create-url="createUrl"
@submitted="onSubmitted">
<template #submitButtonText>
{{ $gettext('Create and Continue') }}
</template>
</admin-stations-form>
</b-card>
</template>
<script>

View File

@ -1,51 +1,49 @@
<template>
<div>
<b-card no-body>
<b-card-header header-bg-variant="primary-dark">
<h2 class="card-title">{{ $gettext('HLS Streams') }}</h2>
</b-card-header>
<b-card no-body>
<b-card-header header-bg-variant="primary-dark">
<h2 class="card-title">{{ $gettext('HLS Streams') }}</h2>
</b-card-header>
<info-card>
<p class="card-text">
{{
$gettext('HTTP Live Streaming (HLS) is a new adaptive-bitrate streaming technology. From this page, you can configure the individual bitrates and formats that are included in the combined HLS stream.')
}}
</p>
</info-card>
<info-card>
<p class="card-text">
{{
$gettext('HTTP Live Streaming (HLS) is a new adaptive-bitrate streaming technology. From this page, you can configure the individual bitrates and formats that are included in the combined HLS stream.')
}}
</p>
</info-card>
<b-card-body body-class="card-padding-sm">
<b-button variant="outline-primary" @click.prevent="doCreate">
<icon icon="add"></icon>
{{ $gettext('Add HLS Stream') }}
</b-button>
</b-card-body>
<b-card-body body-class="card-padding-sm">
<b-button variant="outline-primary" @click.prevent="doCreate">
<icon icon="add"></icon>
{{ $gettext('Add HLS Stream') }}
</b-button>
</b-card-body>
<data-table ref="datatable" id="station_hls_streams" :fields="fields" paginated
:api-url="listUrl">
<template #cell(name)="row">
<h5 class="m-0">{{ row.item.name }}</h5>
</template>
<template #cell(format)="row">
{{ upper(row.item.format) }}
</template>
<template #cell(bitrate)="row">
{{ row.item.bitrate }}kbps
</template>
<template #cell(actions)="row">
<b-button-group size="sm">
<b-button size="sm" variant="primary" @click.prevent="doEdit(row.item.links.self)">
{{ $gettext('Edit') }}
</b-button>
<b-button size="sm" variant="danger" @click.prevent="doDelete(row.item.links.self)">
{{ $gettext('Delete') }}
</b-button>
</b-button-group>
</template>
</data-table>
</b-card>
<data-table ref="datatable" id="station_hls_streams" :fields="fields" paginated
:api-url="listUrl">
<template #cell(name)="row">
<h5 class="m-0">{{ row.item.name }}</h5>
</template>
<template #cell(format)="row">
{{ upper(row.item.format) }}
</template>
<template #cell(bitrate)="row">
{{ row.item.bitrate }}kbps
</template>
<template #cell(actions)="row">
<b-button-group size="sm">
<b-button size="sm" variant="primary" @click.prevent="doEdit(row.item.links.self)">
{{ $gettext('Edit') }}
</b-button>
<b-button size="sm" variant="danger" @click.prevent="doDelete(row.item.links.self)">
{{ $gettext('Delete') }}
</b-button>
</b-button-group>
</template>
</data-table>
</b-card>
<edit-modal ref="editModal" :create-url="listUrl" @relist="relist" @needs-restart="mayNeedRestart"></edit-modal>
</div>
<edit-modal ref="editModal" :create-url="listUrl" @relist="relist" @needs-restart="mayNeedRestart"></edit-modal>
</template>
<script>

View File

@ -1,49 +1,49 @@
<template>
<div>
<p>
{{ $gettext('Set cue and fade points using the visual editor. The timestamps will be saved to the corresponding fields in the advanced playback settings.') }}
</p>
<p>
{{
$gettext('Set cue and fade points using the visual editor. The timestamps will be saved to the corresponding fields in the advanced playback settings.')
}}
</p>
<b-form-group>
<waveform ref="waveform" :audio-url="audioUrl" :waveform-url="waveformUrl"
@ready="updateRegions"></waveform>
</b-form-group>
<b-form-group>
<b-button-group>
<b-button variant="light" @click="playAudio">
<icon icon="play_arrow"></icon>
<span class="sr-only">{{ $gettext('Play') }}</span>
</b-button>
<b-button variant="dark" @click="stopAudio">
<icon icon="stop"></icon>
<span class="sr-only">{{ $gettext('Stop') }}</span>
</b-button>
</b-button-group>
<b-button-group>
<b-button variant="primary" @click="setCueIn">
{{ $gettext('Set Cue In') }}
</b-button>
<b-form-group>
<waveform ref="waveform" :audio-url="audioUrl" :waveform-url="waveformUrl"
@ready="updateRegions"></waveform>
</b-form-group>
<b-form-group>
<b-button-group>
<b-button variant="light" @click="playAudio">
<icon icon="play_arrow"></icon>
<span class="sr-only">{{ $gettext('Play') }}</span>
</b-button>
<b-button variant="dark" @click="stopAudio">
<icon icon="stop"></icon>
<span class="sr-only">{{ $gettext('Stop') }}</span>
</b-button>
</b-button-group>
<b-button-group>
<b-button variant="primary" @click="setCueIn">
{{ $gettext('Set Cue In') }}
</b-button>
<b-button variant="primary" @click="setCueOut">
{{ $gettext('Set Cue Out') }}
</b-button>
</b-button-group>
<b-button-group>
<b-button variant="warning" @click="setFadeOverlap">
{{ $gettext('Set Overlap') }}
</b-button>
</b-button-group>
<b-button-group>
<b-button variant="danger" @click="setFadeIn">
{{ $gettext('Set Fade In') }}
</b-button>
<b-button variant="primary" @click="setCueOut">
{{ $gettext('Set Cue Out') }}
</b-button>
</b-button-group>
<b-button-group>
<b-button variant="warning" @click="setFadeOverlap">
{{ $gettext('Set Overlap') }}
</b-button>
</b-button-group>
<b-button-group>
<b-button variant="danger" @click="setFadeIn">
{{ $gettext('Set Fade In') }}
</b-button>
<b-button variant="danger" @click="setFadeOut">
{{ $gettext('Set Fade Out') }}
</b-button>
</b-button-group>
</b-form-group>
</div>
<b-button variant="danger" @click="setFadeOut">
{{ $gettext('Set Fade Out') }}
</b-button>
</b-button-group>
</b-form-group>
</template>
<script>

View File

@ -1,64 +1,62 @@
<template>
<div>
<b-card no-body>
<b-card-header header-bg-variant="primary-dark">
<h2 class="card-title">{{ $gettext('Mount Points') }}</h2>
</b-card-header>
<b-card no-body>
<b-card-header header-bg-variant="primary-dark">
<h2 class="card-title">{{ $gettext('Mount Points') }}</h2>
</b-card-header>
<info-card>
<p class="card-text">
{{
$gettext('Mount points are how listeners connect and listen to your station. Each mount point can be a different audio format or quality. Using mount points, you can set up a high-quality stream for broadband listeners and a mobile stream for phone users.')
}}
</p>
</info-card>
<info-card>
<p class="card-text">
{{
$gettext('Mount points are how listeners connect and listen to your station. Each mount point can be a different audio format or quality. Using mount points, you can set up a high-quality stream for broadband listeners and a mobile stream for phone users.')
}}
</p>
</info-card>
<b-card-body body-class="card-padding-sm">
<b-button variant="outline-primary" @click.prevent="doCreate">
<icon icon="add"></icon>
{{ $gettext('Add Mount Point') }}
</b-button>
</b-card-body>
<b-card-body body-class="card-padding-sm">
<b-button variant="outline-primary" @click.prevent="doCreate">
<icon icon="add"></icon>
{{ $gettext('Add Mount Point') }}
</b-button>
</b-card-body>
<data-table ref="datatable" id="station_mounts" :fields="fields" paginated
:api-url="listUrl">
<template #cell(display_name)="row">
<h5 class="m-0">
<a :href="row.item.links.listen">{{ row.item.display_name }}</a>
</h5>
<div v-if="row.item.is_default">
<span class="badge badge-success">
{{ $gettext('Default Mount') }}
</span>
</div>
<data-table ref="datatable" id="station_mounts" :fields="fields" paginated
:api-url="listUrl">
<template #cell(display_name)="row">
<h5 class="m-0">
<a :href="row.item.links.listen">{{ row.item.display_name }}</a>
</h5>
<div v-if="row.item.is_default">
<span class="badge badge-success">
{{ $gettext('Default Mount') }}
</span>
</div>
</template>
<template #cell(enable_autodj)="row">
<template v-if="row.item.enable_autodj">
{{ $gettext('Enabled') }}
-
{{ row.item.autodj_bitrate }}kbps {{ upper(row.item.autodj_format) }}
</template>
<template #cell(enable_autodj)="row">
<template v-if="row.item.enable_autodj">
{{ $gettext('Enabled') }}
-
{{ row.item.autodj_bitrate }}kbps {{ upper(row.item.autodj_format) }}
</template>
<template v-else>
{{ $gettext('Disabled') }}
</template>
<template v-else>
{{ $gettext('Disabled') }}
</template>
<template #cell(actions)="row">
<b-button-group size="sm">
<b-button size="sm" variant="primary" @click.prevent="doEdit(row.item.links.self)">
{{ $gettext('Edit') }}
</b-button>
<b-button size="sm" variant="danger" @click.prevent="doDelete(row.item.links.self)">
{{ $gettext('Delete') }}
</b-button>
</b-button-group>
</template>
</data-table>
</b-card>
</template>
<template #cell(actions)="row">
<b-button-group size="sm">
<b-button size="sm" variant="primary" @click.prevent="doEdit(row.item.links.self)">
{{ $gettext('Edit') }}
</b-button>
<b-button size="sm" variant="danger" @click.prevent="doDelete(row.item.links.self)">
{{ $gettext('Delete') }}
</b-button>
</b-button-group>
</template>
</data-table>
</b-card>
<edit-modal ref="editModal" :create-url="listUrl" :new-intro-url="newIntroUrl"
:show-advanced="showAdvanced" :station-frontend-type="stationFrontendType"
@relist="relist" @needs-restart="mayNeedRestart"></edit-modal>
</div>
<edit-modal ref="editModal" :create-url="listUrl" :new-intro-url="newIntroUrl"
:show-advanced="showAdvanced" :station-frontend-type="stationFrontendType"
@relist="relist" @needs-restart="mayNeedRestart"></edit-modal>
</template>
<script>

View File

@ -1,136 +1,134 @@
<template>
<div>
<b-card no-body>
<b-card-header header-bg-variant="primary-dark">
<b-row class="align-items-center">
<b-col md="6">
<h2 class="card-title">{{ $gettext('Playlists') }}</h2>
</b-col>
<b-col md="6" class="text-right text-muted">
{{
$gettext(
'This station\'s time zone is currently %{tz}.',
{tz: stationTimeZone}
)
}}
</b-col>
</b-row>
</b-card-header>
<b-tabs pills card lazy>
<b-tab :title="langAllPlaylistsTab" no-body>
<b-card-body body-class="card-padding-sm">
<b-button variant="outline-primary" @click.prevent="doCreate">
<icon icon="add"></icon>
{{ $gettext('Add Playlist') }}
</b-button>
</b-card-body>
<b-card no-body>
<b-card-header header-bg-variant="primary-dark">
<b-row class="align-items-center">
<b-col md="6">
<h2 class="card-title">{{ $gettext('Playlists') }}</h2>
</b-col>
<b-col md="6" class="text-right text-muted">
{{
$gettext(
'This station\'s time zone is currently %{tz}.',
{tz: stationTimeZone}
)
}}
</b-col>
</b-row>
</b-card-header>
<b-tabs pills card lazy>
<b-tab :title="langAllPlaylistsTab" no-body>
<b-card-body body-class="card-padding-sm">
<b-button variant="outline-primary" @click.prevent="doCreate">
<icon icon="add"></icon>
{{ $gettext('Add Playlist') }}
</b-button>
</b-card-body>
<data-table ref="datatable" id="station_playlists" paginated :fields="fields" :responsive="false"
:api-url="listUrl">
<template #cell(actions)="row">
<b-button-group size="sm">
<b-button size="sm" variant="primary" @click.prevent="doEdit(row.item.links.self)">
{{ $gettext('Edit') }}
</b-button>
<b-button size="sm" variant="danger" @click.prevent="doDelete(row.item.links.self)">
{{ $gettext('Delete') }}
</b-button>
<data-table ref="datatable" id="station_playlists" paginated :fields="fields" :responsive="false"
:api-url="listUrl">
<template #cell(actions)="row">
<b-button-group size="sm">
<b-button size="sm" variant="primary" @click.prevent="doEdit(row.item.links.self)">
{{ $gettext('Edit') }}
</b-button>
<b-button size="sm" variant="danger" @click.prevent="doDelete(row.item.links.self)">
{{ $gettext('Delete') }}
</b-button>
<b-dropdown size="sm" variant="dark" boundary="window" :text="langMore">
<b-dropdown-item @click.prevent="doModify(row.item.links.toggle)">
{{ langToggleButton(row.item) }}
<b-dropdown size="sm" variant="dark" boundary="window" :text="langMore">
<b-dropdown-item @click.prevent="doModify(row.item.links.toggle)">
{{ langToggleButton(row.item) }}
</b-dropdown-item>
<b-dropdown-item @click.prevent="doImport(row.item.links.import)"
v-if="row.item.source === 'songs'">
{{ langImportButton }}
</b-dropdown-item>
<b-dropdown-item @click.prevent="doReorder(row.item.links.order)"
v-if="row.item.source === 'songs' && row.item.order === 'sequential'">
{{ langReorderButton }}
</b-dropdown-item>
<b-dropdown-item @click.prevent="doQueue(row.item.links.queue)"
v-if="row.item.source === 'songs' && row.item.order !== 'random'">
{{ langQueueButton }}
</b-dropdown-item>
<b-dropdown-item @click.prevent="doModify(row.item.links.reshuffle)"
v-if="row.item.order === 'shuffle'">
{{ langReshuffleButton }}
</b-dropdown-item>
<b-dropdown-item @click.prevent="doClone(row.item.name, row.item.links.clone)">
{{ langCloneButton }}
</b-dropdown-item>
<template v-for="format in ['pls', 'm3u']">
<b-dropdown-item :href="row.item.links.export[format]" target="_blank">
{{
$gettext(
'Export %{format}',
{format: format.toUpperCase()}
)
}}
</b-dropdown-item>
<b-dropdown-item @click.prevent="doImport(row.item.links.import)"
v-if="row.item.source === 'songs'">
{{ langImportButton }}
</b-dropdown-item>
<b-dropdown-item @click.prevent="doReorder(row.item.links.order)"
v-if="row.item.source === 'songs' && row.item.order === 'sequential'">
{{ langReorderButton }}
</b-dropdown-item>
<b-dropdown-item @click.prevent="doQueue(row.item.links.queue)"
v-if="row.item.source === 'songs' && row.item.order !== 'random'">
{{ langQueueButton }}
</b-dropdown-item>
<b-dropdown-item @click.prevent="doModify(row.item.links.reshuffle)"
v-if="row.item.order === 'shuffle'">
{{ langReshuffleButton }}
</b-dropdown-item>
<b-dropdown-item @click.prevent="doClone(row.item.name, row.item.links.clone)">
{{ langCloneButton }}
</b-dropdown-item>
<template v-for="format in ['pls', 'm3u']">
<b-dropdown-item :href="row.item.links.export[format]" target="_blank">
{{
$gettext(
'Export %{format}',
{format: format.toUpperCase()}
)
}}
</b-dropdown-item>
</template>
</b-dropdown>
</b-button-group>
</template>
</b-dropdown>
</b-button-group>
</template>
<template #cell(name)="row">
<h5 class="m-0">{{ row.item.name }}</h5>
<div>
<span class="badge badge-dark">
<template v-if="row.item.source === 'songs'">
{{ $gettext('Song-based') }}
</template>
<template v-else>
{{ $gettext('Remote URL') }}
</template>
</span>
<span class="badge badge-primary" v-if="row.item.is_jingle">
{{ $gettext('Jingle Mode') }}
</span>
<span class="badge badge-info"
v-if="row.item.source === 'songs' && row.item.order === 'sequential'">
{{ $gettext('Sequential') }}
</span>
<span class="badge badge-info" v-if="row.item.include_in_on_demand">
{{ $gettext('On-Demand') }}
</span>
<span class="badge badge-success" v-if="row.item.include_in_automation">
{{ $gettext('Auto-Assigned') }}
</span>
<span class="badge badge-danger" v-if="!row.item.is_enabled">
{{ $gettext('Disabled') }}
</span>
</div>
</template>
<template #cell(scheduling)="row">
<span v-html="formatType(row.item)"></span>
</template>
<template #cell(num_songs)="row">
<template v-if="row.item.source === 'songs'">
<a :href="filesUrl+'#playlist:'+encodeURIComponent(row.item.name)">
{{ row.item.num_songs }}
</a>
({{ formatLength(row.item.total_length) }})
</template>
<template #cell(name)="row">
<h5 class="m-0">{{ row.item.name }}</h5>
<div>
<span class="badge badge-dark">
<template v-if="row.item.source === 'songs'">
{{ $gettext('Song-based') }}
</template>
<template v-else>
{{ $gettext('Remote URL') }}
</template>
</span>
<span class="badge badge-primary" v-if="row.item.is_jingle">
{{ $gettext('Jingle Mode') }}
</span>
<span class="badge badge-info"
v-if="row.item.source === 'songs' && row.item.order === 'sequential'">
{{ $gettext('Sequential') }}
</span>
<span class="badge badge-info" v-if="row.item.include_in_on_demand">
{{ $gettext('On-Demand') }}
</span>
<span class="badge badge-success" v-if="row.item.include_in_automation">
{{ $gettext('Auto-Assigned') }}
</span>
<span class="badge badge-danger" v-if="!row.item.is_enabled">
{{ $gettext('Disabled') }}
</span>
</div>
</template>
<template #cell(scheduling)="row">
<span v-html="formatType(row.item)"></span>
</template>
<template #cell(num_songs)="row">
<template v-if="row.item.source === 'songs'">
<a :href="filesUrl+'#playlist:'+encodeURIComponent(row.item.name)">
{{ row.item.num_songs }}
</a>
({{ formatLength(row.item.total_length) }})
</template>
<template v-else>&nbsp;</template>
</template>
</data-table>
</b-tab>
<b-tab :title="langScheduleViewTab" no-body>
<schedule ref="schedule" :schedule-url="scheduleUrl" :station-time-zone="stationTimeZone"
@click="doCalendarClick"></schedule>
</b-tab>
</b-tabs>
</b-card>
<template v-else>&nbsp;</template>
</template>
</data-table>
</b-tab>
<b-tab :title="langScheduleViewTab" no-body>
<schedule ref="schedule" :schedule-url="scheduleUrl" :station-time-zone="stationTimeZone"
@click="doCalendarClick"></schedule>
</b-tab>
</b-tabs>
</b-card>
<edit-modal ref="editModal" :create-url="listUrl" :station-time-zone="stationTimeZone"
:enable-advanced-features="enableAdvancedFeatures"
@relist="relist" @needs-restart="mayNeedRestart"></edit-modal>
<reorder-modal ref="reorderModal"></reorder-modal>
<queue-modal ref="queueModal"></queue-modal>
<reorder-modal ref="reorderModal"></reorder-modal>
<import-modal ref="importModal" @relist="relist"></import-modal>
<clone-modal ref="cloneModal" @relist="relist" @needs-restart="mayNeedRestart"></clone-modal>
</div>
<edit-modal ref="editModal" :create-url="listUrl" :station-time-zone="stationTimeZone"
:enable-advanced-features="enableAdvancedFeatures"
@relist="relist" @needs-restart="mayNeedRestart"></edit-modal>
<reorder-modal ref="reorderModal"></reorder-modal>
<queue-modal ref="queueModal"></queue-modal>
<reorder-modal ref="reorderModal"></reorder-modal>
<import-modal ref="importModal" @relist="relist"></import-modal>
<clone-modal ref="cloneModal" @relist="relist" @needs-restart="mayNeedRestart"></clone-modal>
</template>
<script>

View File

@ -1,19 +1,18 @@
<template>
<div>
<episodes-view v-if="activePodcast" v-bind="$props" :podcast="activePodcast" @clear-podcast="onClearPodcast"></episodes-view>
<list-view v-else v-bind="$props" @select-podcast="onSelectPodcast"></list-view>
</div>
<episodes-view v-if="activePodcast" v-bind="$props" :podcast="activePodcast"
@clear-podcast="onClearPodcast"></episodes-view>
<list-view v-else v-bind="$props" @select-podcast="onSelectPodcast"></list-view>
</template>
<script>
import EpisodesView, { episodeViewProps } from './Podcasts/EpisodesView';
import ListView, { listViewProps } from './Podcasts/ListView';
import EpisodesView, {episodeViewProps} from './Podcasts/EpisodesView';
import ListView, {listViewProps} from './Podcasts/ListView';
export default {
name: 'StationPodcasts',
components: { ListView, EpisodesView },
components: {ListView, EpisodesView},
mixins: [episodeViewProps, listViewProps],
data () {
data() {
return {
activePodcast: null
};

View File

@ -1,73 +1,71 @@
<template>
<div>
<b-card no-body>
<b-card-header header-bg-variant="primary-dark">
<b-row class="row align-items-center">
<b-col md="7">
<div class="d-flex align-items-center">
<div class="flex-shrink-0 pr-3">
<album-art :src="podcast.art"></album-art>
</div>
<div class="flex-fill">
<h2 class="card-title">{{ podcast.title }}</h2>
<h4 class="card-subtitle text-muted">{{ $gettext('Episodes') }}</h4>
</div>
<b-card no-body>
<b-card-header header-bg-variant="primary-dark">
<b-row class="row align-items-center">
<b-col md="7">
<div class="d-flex align-items-center">
<div class="flex-shrink-0 pr-3">
<album-art :src="podcast.art"></album-art>
</div>
</b-col>
<b-col md="5" class="text-right text-white-50">
<stations-common-quota :quota-url="quotaUrl" ref="quota"></stations-common-quota>
</b-col>
</b-row>
</b-card-header>
<div class="flex-fill">
<h2 class="card-title">{{ podcast.title }}</h2>
<h4 class="card-subtitle text-muted">{{ $gettext('Episodes') }}</h4>
</div>
</div>
</b-col>
<b-col md="5" class="text-right text-white-50">
<stations-common-quota :quota-url="quotaUrl" ref="quota"></stations-common-quota>
</b-col>
</b-row>
</b-card-header>
<b-card-body body-class="card-padding-sm">
<b-button variant="bg" @click="doClearPodcast()">
<icon icon="arrow_back"></icon>
{{ $gettext('All Podcasts') }}
</b-button>
<b-card-body body-class="card-padding-sm">
<b-button variant="bg" @click="doClearPodcast()">
<icon icon="arrow_back"></icon>
{{ $gettext('All Podcasts') }}
</b-button>
<b-button variant="outline-primary" @click.prevent="doCreate">
<i class="material-icons" aria-hidden="true">add</i>
{{ $gettext('Add Episode') }}
</b-button>
</b-card-body>
<b-button variant="outline-primary" @click.prevent="doCreate">
<i class="material-icons" aria-hidden="true">add</i>
{{ $gettext('Add Episode') }}
</b-button>
</b-card-body>
<data-table ref="datatable" id="station_podcast_episodes" paginated :fields="fields" :responsive="false"
:api-url="podcast.links.episodes">
<template #cell(art)="row">
<album-art :src="row.item.art"></album-art>
<data-table ref="datatable" id="station_podcast_episodes" paginated :fields="fields" :responsive="false"
:api-url="podcast.links.episodes">
<template #cell(art)="row">
<album-art :src="row.item.art"></album-art>
</template>
<template #cell(title)="row">
<h5 class="m-0">{{ row.item.title }}</h5>
<a :href="row.item.links.public" target="_blank">{{ $gettext('Public Page') }}</a>
</template>
<template #cell(podcast_media)="row">
<template v-if="row.item.media">
<span>{{ row.item.media.original_name }}</span>
<br/>
<small>{{ row.item.media.length_text }}</small>
</template>
<template #cell(title)="row">
<h5 class="m-0">{{ row.item.title }}</h5>
<a :href="row.item.links.public" target="_blank">{{ $gettext('Public Page') }}</a>
</template>
<template #cell(podcast_media)="row">
<template v-if="row.item.media">
<span>{{ row.item.media.original_name }}</span>
<br/>
<small>{{ row.item.media.length_text }}</small>
</template>
</template>
<template #cell(explicit)="row">
<span class="badge badge-danger" v-if="row.item.explicit">{{ $gettext('Explicit') }}</span>
</template>
<template #cell(actions)="row">
<b-button-group size="sm">
<b-button size="sm" variant="primary" @click.prevent="doEdit(row.item.links.self)">
{{ $gettext('Edit') }}
</b-button>
<b-button size="sm" variant="danger" @click.prevent="doDelete(row.item.links.self)">
{{ $gettext('Delete') }}
</b-button>
</b-button-group>
</template>
</data-table>
</b-card>
</template>
<template #cell(explicit)="row">
<span class="badge badge-danger" v-if="row.item.explicit">{{ $gettext('Explicit') }}</span>
</template>
<template #cell(actions)="row">
<b-button-group size="sm">
<b-button size="sm" variant="primary" @click.prevent="doEdit(row.item.links.self)">
{{ $gettext('Edit') }}
</b-button>
<b-button size="sm" variant="danger" @click.prevent="doDelete(row.item.links.self)">
{{ $gettext('Delete') }}
</b-button>
</b-button-group>
</template>
</data-table>
</b-card>
<edit-modal ref="editEpisodeModal" :create-url="podcast.links.episodes" :station-time-zone="stationTimeZone"
:new-art-url="podcast.links.episode_new_art" :new-media-url="podcast.links.episode_new_media"
:locale="locale" :podcast-id="podcast.id" @relist="relist"></edit-modal>
</div>
<edit-modal ref="editEpisodeModal" :create-url="podcast.links.episodes" :station-time-zone="stationTimeZone"
:new-art-url="podcast.links.episode_new_art" :new-media-url="podcast.links.episode_new_media"
:locale="locale" :podcast-id="podcast.id" @relist="relist"></edit-modal>
</template>
<script>

View File

@ -1,57 +1,55 @@
<template>
<div>
<b-card no-body>
<b-card-header header-bg-variant="primary-dark">
<b-row class="align-items-center">
<b-col md="7">
<h2 class="card-title">{{ $gettext('Podcasts') }}</h2>
</b-col>
<b-col md="5" class="text-right text-white-50">
<stations-common-quota :quota-url="quotaUrl" ref="quota"></stations-common-quota>
</b-col>
</b-row>
</b-card-header>
<b-card no-body>
<b-card-header header-bg-variant="primary-dark">
<b-row class="align-items-center">
<b-col md="7">
<h2 class="card-title">{{ $gettext('Podcasts') }}</h2>
</b-col>
<b-col md="5" class="text-right text-white-50">
<stations-common-quota :quota-url="quotaUrl" ref="quota"></stations-common-quota>
</b-col>
</b-row>
</b-card-header>
<b-card-body body-class="card-padding-sm">
<b-button variant="outline-primary" @click.prevent="doCreate">
<i class="material-icons" aria-hidden="true">add</i>
{{ $gettext('Add Podcast') }}
</b-button>
</b-card-body>
<b-card-body body-class="card-padding-sm">
<b-button variant="outline-primary" @click.prevent="doCreate">
<i class="material-icons" aria-hidden="true">add</i>
{{ $gettext('Add Podcast') }}
</b-button>
</b-card-body>
<data-table ref="datatable" id="station_podcasts" paginated :fields="fields" :responsive="false"
:api-url="listUrl">
<template #cell(art)="row">
<album-art :src="row.item.art"></album-art>
</template>
<template #cell(title)="row">
<h5 class="m-0">{{ row.item.title }}</h5>
<a :href="row.item.links.public_episodes" target="_blank">{{ $gettext('Public Page') }}</a> &bull;
<a :href="row.item.links.public_feed" target="_blank">{{ $gettext('RSS Feed') }}</a>
</template>
<template #cell(num_episodes)="row">
{{ countEpisodes(row.item.episodes) }}
</template>
<template #cell(actions)="row">
<b-button-group size="sm">
<b-button size="sm" variant="primary" @click.prevent="doEdit(row.item.links.self)">
{{ $gettext('Edit') }}
</b-button>
<b-button size="sm" variant="danger" @click.prevent="doDelete(row.item.links.self)">
{{ $gettext('Delete') }}
</b-button>
<b-button size="sm" variant="dark" @click.prevent="doSelectPodcast(row.item)">
{{ $gettext('Episodes') }}
</b-button>
</b-button-group>
</template>
</data-table>
</b-card>
<data-table ref="datatable" id="station_podcasts" paginated :fields="fields" :responsive="false"
:api-url="listUrl">
<template #cell(art)="row">
<album-art :src="row.item.art"></album-art>
</template>
<template #cell(title)="row">
<h5 class="m-0">{{ row.item.title }}</h5>
<a :href="row.item.links.public_episodes" target="_blank">{{ $gettext('Public Page') }}</a> &bull;
<a :href="row.item.links.public_feed" target="_blank">{{ $gettext('RSS Feed') }}</a>
</template>
<template #cell(num_episodes)="row">
{{ countEpisodes(row.item.episodes) }}
</template>
<template #cell(actions)="row">
<b-button-group size="sm">
<b-button size="sm" variant="primary" @click.prevent="doEdit(row.item.links.self)">
{{ $gettext('Edit') }}
</b-button>
<b-button size="sm" variant="danger" @click.prevent="doDelete(row.item.links.self)">
{{ $gettext('Delete') }}
</b-button>
<b-button size="sm" variant="dark" @click.prevent="doSelectPodcast(row.item)">
{{ $gettext('Episodes') }}
</b-button>
</b-button-group>
</template>
</data-table>
</b-card>
<edit-modal ref="editPodcastModal" :create-url="listUrl" :station-time-zone="stationTimeZone"
:new-art-url="newArtUrl" :language-options="languageOptions"
:categories-options="categoriesOptions" @relist="relist"></edit-modal>
</div>
<edit-modal ref="editPodcastModal" :create-url="listUrl" :station-time-zone="stationTimeZone"
:new-art-url="newArtUrl" :language-options="languageOptions"
:categories-options="categoriesOptions" @relist="relist"></edit-modal>
</template>
<script>

View File

@ -1,34 +1,32 @@
<template>
<div>
<profile-header v-bind="$props" :np="np"></profile-header>
<profile-header v-bind="$props" :np="np"></profile-header>
<div class="row" id="profile">
<div class="col-lg-7">
<profile-now-playing v-bind="$props" :np="np"></profile-now-playing>
<div class="row" id="profile">
<div class="col-lg-7">
<profile-now-playing v-bind="$props" :np="np"></profile-now-playing>
<profile-schedule :station-time-zone="stationTimeZone" :schedule-items="np.schedule"></profile-schedule>
<profile-schedule :station-time-zone="stationTimeZone" :schedule-items="np.schedule"></profile-schedule>
<profile-streams v-bind="$props" :np="np"></profile-streams>
<profile-streams v-bind="$props" :np="np"></profile-streams>
<profile-public-pages v-bind="$props"></profile-public-pages>
</div>
<profile-public-pages v-bind="$props"></profile-public-pages>
</div>
<div class="col-lg-5">
<profile-requests v-bind="$props" v-if="stationSupportsRequests"></profile-requests>
<div class="col-lg-5">
<profile-requests v-bind="$props" v-if="stationSupportsRequests"></profile-requests>
<profile-streamers v-bind="$props" v-if="stationSupportsStreamers"></profile-streamers>
<profile-streamers v-bind="$props" v-if="stationSupportsStreamers"></profile-streamers>
<template v-if="hasActiveFrontend">
<profile-frontend v-bind="$props" :np="np"></profile-frontend>
</template>
<template v-if="hasActiveFrontend">
<profile-frontend v-bind="$props" :np="np"></profile-frontend>
</template>
<template v-if="hasActiveBackend">
<profile-backend v-bind="$props" :np="np"></profile-backend>
</template>
<template v-else>
<profile-backend-none></profile-backend-none>
</template>
</div>
<template v-if="hasActiveBackend">
<profile-backend v-bind="$props" :np="np"></profile-backend>
</template>
<template v-else>
<profile-backend-none></profile-backend-none>
</template>
</div>
</div>
</template>

View File

@ -1,57 +1,55 @@
<template>
<div>
<b-card no-body>
<b-card-header header-bg-variant="primary-dark">
<h2 class="card-title">{{ $gettext('Upcoming Song Queue') }}</h2>
</b-card-header>
<div class="card-actions">
<b-button variant="outline-danger" @click="doClear()">
<icon icon="remove"></icon>
{{ $gettext('Clear Upcoming Song Queue') }}
</b-button>
</div>
<data-table ref="datatable" id="station_queue" :fields="fields" :api-url="listUrl">
<template #cell(actions)="row">
<b-button-group>
<b-button v-if="row.item.log" size="sm" variant="primary"
@click.prevent="doShowLogs(row.item.log)">
{{ $gettext('Logs') }}
</b-button>
<b-button v-if="!row.item.sent_to_autodj" size="sm" variant="danger"
@click.prevent="doDelete(row.item.links.self)">
{{ $gettext('Delete') }}
</b-button>
</b-button-group>
</template>
<template #cell(song_title)="row">
<div v-if="row.item.autodj_custom_uri">
{{ row.item.autodj_custom_uri }}
</div>
<div v-else-if="row.item.song.title">
<b>{{ row.item.song.title }}</b><br>
{{ row.item.song.artist }}
</div>
<div v-else>
{{ row.item.song.text }}
</div>
</template>
<template #cell(played_at)="row">
{{ formatTime(row.item.played_at) }}<br>
<small>{{ formatRelativeTime(row.item.played_at) }}</small>
</template>
<template #cell(source)="row">
<div v-if="row.item.is_request">
{{ $gettext('Listener Request') }}
</div>
<div v-else-if="row.item.playlist">
{{ $gettext('Playlist') }}: {{ row.item.playlist }}
</div>
</template>
</data-table>
</b-card>
<b-card no-body>
<b-card-header header-bg-variant="primary-dark">
<h2 class="card-title">{{ $gettext('Upcoming Song Queue') }}</h2>
</b-card-header>
<div class="card-actions">
<b-button variant="outline-danger" @click="doClear()">
<icon icon="remove"></icon>
{{ $gettext('Clear Upcoming Song Queue') }}
</b-button>
</div>
<data-table ref="datatable" id="station_queue" :fields="fields" :api-url="listUrl">
<template #cell(actions)="row">
<b-button-group>
<b-button v-if="row.item.log" size="sm" variant="primary"
@click.prevent="doShowLogs(row.item.log)">
{{ $gettext('Logs') }}
</b-button>
<b-button v-if="!row.item.sent_to_autodj" size="sm" variant="danger"
@click.prevent="doDelete(row.item.links.self)">
{{ $gettext('Delete') }}
</b-button>
</b-button-group>
</template>
<template #cell(song_title)="row">
<div v-if="row.item.autodj_custom_uri">
{{ row.item.autodj_custom_uri }}
</div>
<div v-else-if="row.item.song.title">
<b>{{ row.item.song.title }}</b><br>
{{ row.item.song.artist }}
</div>
<div v-else>
{{ row.item.song.text }}
</div>
</template>
<template #cell(played_at)="row">
{{ formatTime(row.item.played_at) }}<br>
<small>{{ formatRelativeTime(row.item.played_at) }}</small>
</template>
<template #cell(source)="row">
<div v-if="row.item.is_request">
{{ $gettext('Listener Request') }}
</div>
<div v-else-if="row.item.playlist">
{{ $gettext('Playlist') }}: {{ row.item.playlist }}
</div>
</template>
</data-table>
</b-card>
<queue-logs-modal ref="logs_modal"></queue-logs-modal>
</div>
<queue-logs-modal ref="logs_modal"></queue-logs-modal>
</template>
<script>

View File

@ -1,57 +1,55 @@
<template>
<div>
<b-card no-body>
<b-card-header header-bg-variant="primary-dark">
<h2 class="card-title">{{ $gettext('Remote Relays') }}</h2>
</b-card-header>
<b-card no-body>
<b-card-header header-bg-variant="primary-dark">
<h2 class="card-title">{{ $gettext('Remote Relays') }}</h2>
</b-card-header>
<info-card>
<p class="card-text">
{{
$gettext('Remote relays let you work with broadcasting software outside this server. Any relay you include here will be included in your station\'s statistics. You can also broadcast from this server to remote relays.')
<info-card>
<p class="card-text">
{{
$gettext('Remote relays let you work with broadcasting software outside this server. Any relay you include here will be included in your station\'s statistics. You can also broadcast from this server to remote relays.')
}}
</p>
</info-card>
<b-card-body body-class="card-padding-sm">
<b-button variant="outline-primary" @click.prevent="doCreate">
<icon icon="add"></icon>
{{ $gettext('Add Remote Relay') }}
</b-button>
</b-card-body>
<data-table ref="datatable" id="station_remotes" paginated :fields="fields" :api-url="listUrl">
<template #cell(display_name)="row">
<h5 class="m-0">
<a :href="row.item.url" target="_blank">{{ row.item.display_name }}</a>
</h5>
</template>
<template #cell(enable_autodj)="row">
<template v-if="row.item.enable_autodj">
{{ $gettext('Enabled') }} - {{ row.item.autodj_bitrate }}kbps {{
upper(row.item.autodj_format)
}}
</p>
</info-card>
<b-card-body body-class="card-padding-sm">
<b-button variant="outline-primary" @click.prevent="doCreate">
<icon icon="add"></icon>
{{ $gettext('Add Remote Relay') }}
</b-button>
</b-card-body>
<data-table ref="datatable" id="station_remotes" paginated :fields="fields" :api-url="listUrl">
<template #cell(display_name)="row">
<h5 class="m-0">
<a :href="row.item.url" target="_blank">{{ row.item.display_name }}</a>
</h5>
</template>
<template #cell(enable_autodj)="row">
<template v-if="row.item.enable_autodj">
{{ $gettext('Enabled') }} - {{ row.item.autodj_bitrate }}kbps {{
upper(row.item.autodj_format)
}}
</template>
<template v-else>
{{ $gettext('Disabled') }}
</template>
<template v-else>
{{ $gettext('Disabled') }}
</template>
<template #cell(actions)="row">
<b-button-group size="sm" v-if="row.item.is_editable">
<b-button size="sm" variant="primary" @click.prevent="doEdit(row.item.links.self)">
{{ $gettext('Edit') }}
</b-button>
<b-button size="sm" variant="danger" @click.prevent="doDelete(row.item.links.self)">
{{ $gettext('Delete') }}
</b-button>
</b-button-group>
</template>
</data-table>
</b-card>
</template>
<template #cell(actions)="row">
<b-button-group size="sm" v-if="row.item.is_editable">
<b-button size="sm" variant="primary" @click.prevent="doEdit(row.item.links.self)">
{{ $gettext('Edit') }}
</b-button>
<b-button size="sm" variant="danger" @click.prevent="doDelete(row.item.links.self)">
{{ $gettext('Delete') }}
</b-button>
</b-button-group>
</template>
</data-table>
</b-card>
<remote-edit-modal ref="editModal" :create-url="listUrl"
@relist="relist" @needs-restart="mayNeedRestart"></remote-edit-modal>
</div>
<remote-edit-modal ref="editModal" :create-url="listUrl"
@relist="relist" @needs-restart="mayNeedRestart"></remote-edit-modal>
</template>
<script>

View File

@ -1,56 +1,54 @@
<template>
<div>
<b-card no-body>
<b-card-header header-bg-variant="primary-dark">
<h2 class="card-title">{{ $gettext('Song Requests') }}</h2>
</b-card-header>
<b-tabs pills card>
<b-tab v-for="tab in tabs" :key="tab.type" :active="activeType === tab.type" @click="setType(tab.type)"
:title="tab.title" no-body></b-tab>
</b-tabs>
<b-card no-body>
<b-card-header header-bg-variant="primary-dark">
<h2 class="card-title">{{ $gettext('Song Requests') }}</h2>
</b-card-header>
<b-tabs pills card>
<b-tab v-for="tab in tabs" :key="tab.type" :active="activeType === tab.type" @click="setType(tab.type)"
:title="tab.title" no-body></b-tab>
</b-tabs>
<div class="card-actions" v-if="activeType === 'pending'">
<b-button variant="outline-danger" @click="doClear()">
<icon icon="remove"></icon>
{{ $gettext('Clear Pending Requests') }}
</b-button>
</div>
<div class="card-actions" v-if="activeType === 'pending'">
<b-button variant="outline-danger" @click="doClear()">
<icon icon="remove"></icon>
{{ $gettext('Clear Pending Requests') }}
</b-button>
</div>
<data-table ref="datatable" id="station_queue" :fields="fields" :api-url="listUrlForType">
<template #cell(timestamp)="row">
{{ formatTime(row.item.timestamp) }}
</template>
<template #cell(played_at)="row">
<span v-if="row.item.played_at === 0">
{{ $gettext('Not Played') }}
</span>
<span v-else>
{{ formatTime(row.item.played_at) }}
</span>
</template>
<template #cell(song_title)="row">
<div v-if="row.item.track.title">
<b>{{ row.item.track.title }}</b><br>
{{ row.item.track.artist }}
</div>
<div v-else>
{{ row.item.track.text }}
</div>
</template>
<template #cell(ip)="row">
{{ row.item.ip }}
</template>
<template #cell(actions)="row">
<b-button-group>
<b-button v-if="row.item.played_at === 0" size="sm" variant="danger"
@click.prevent="doDelete(row.item.links.delete)">
{{ $gettext('Delete') }}
</b-button>
</b-button-group>
</template>
</data-table>
</b-card>
</div>
<data-table ref="datatable" id="station_queue" :fields="fields" :api-url="listUrlForType">
<template #cell(timestamp)="row">
{{ formatTime(row.item.timestamp) }}
</template>
<template #cell(played_at)="row">
<span v-if="row.item.played_at === 0">
{{ $gettext('Not Played') }}
</span>
<span v-else>
{{ formatTime(row.item.played_at) }}
</span>
</template>
<template #cell(song_title)="row">
<div v-if="row.item.track.title">
<b>{{ row.item.track.title }}</b><br>
{{ row.item.track.artist }}
</div>
<div v-else>
{{ row.item.track.text }}
</div>
</template>
<template #cell(ip)="row">
{{ row.item.ip }}
</template>
<template #cell(actions)="row">
<b-button-group>
<b-button v-if="row.item.played_at === 0" size="sm" variant="danger"
@click.prevent="doDelete(row.item.links.delete)">
{{ $gettext('Delete') }}
</b-button>
</b-button-group>
</template>
</data-table>
</b-card>
</template>
<script>

View File

@ -1,61 +1,61 @@
<template>
<div>
<b-card no-body>
<b-card-header header-bg-variant="primary-dark">
<h2 class="card-title">{{ $gettext('Web Hooks') }}</h2>
</b-card-header>
<b-card no-body>
<b-card-header header-bg-variant="primary-dark">
<h2 class="card-title">{{ $gettext('Web Hooks') }}</h2>
</b-card-header>
<info-card>
{{ $gettext('Web hooks let you connect to external web services and broadcast changes to your station to them.') }}
</info-card>
<info-card>
{{
$gettext('Web hooks let you connect to external web services and broadcast changes to your station to them.')
}}
</info-card>
<b-card-body body-class="card-padding-sm">
<b-button variant="outline-primary" @click.prevent="doCreate">
<icon icon="add"></icon>
{{ $gettext('Add Web Hook') }}
</b-button>
</b-card-body>
<b-card-body body-class="card-padding-sm">
<b-button variant="outline-primary" @click.prevent="doCreate">
<icon icon="add"></icon>
{{ $gettext('Add Web Hook') }}
</b-button>
</b-card-body>
<data-table ref="datatable" id="station_webhooks" :fields="fields"
:api-url="listUrl">
<template #cell(name)="row">
<big>{{ row.item.name }}</big><br>
{{ getWebhookName(row.item.type) }}
<b-badge v-if="!row.item.is_enabled" variant="danger">
{{ $gettext('Disabled') }}
</b-badge>
</template>
<template #cell(triggers)="row">
<div v-for="(name, index) in getTriggerNames(row.item.triggers)" :key="row.item.id+'_'+index"
class="small">
{{ name }}
</div>
</template>
<template #cell(actions)="row">
<b-button-group size="sm">
<b-button size="sm" variant="primary" @click.prevent="doEdit(row.item.links.self)">
{{ $gettext('Edit') }}
</b-button>
<b-button size="sm" :variant="getToggleVariant(row.item)"
@click.prevent="doToggle(row.item.links.toggle)">
{{ langToggleButton(row.item) }}
</b-button>
<b-button size="sm" variant="default" @click.prevent="doTest(row.item.links.test)">
{{ $gettext('Test') }}
</b-button>
<b-button size="sm" variant="danger" @click.prevent="doDelete(row.item.links.self)">
{{ $gettext('Delete') }}
</b-button>
</b-button-group>
</template>
</data-table>
</b-card>
<data-table ref="datatable" id="station_webhooks" :fields="fields"
:api-url="listUrl">
<template #cell(name)="row">
<big>{{ row.item.name }}</big><br>
{{ getWebhookName(row.item.type) }}
<b-badge v-if="!row.item.is_enabled" variant="danger">
{{ $gettext('Disabled') }}
</b-badge>
</template>
<template #cell(triggers)="row">
<div v-for="(name, index) in getTriggerNames(row.item.triggers)" :key="row.item.id+'_'+index"
class="small">
{{ name }}
</div>
</template>
<template #cell(actions)="row">
<b-button-group size="sm">
<b-button size="sm" variant="primary" @click.prevent="doEdit(row.item.links.self)">
{{ $gettext('Edit') }}
</b-button>
<b-button size="sm" :variant="getToggleVariant(row.item)"
@click.prevent="doToggle(row.item.links.toggle)">
{{ langToggleButton(row.item) }}
</b-button>
<b-button size="sm" variant="default" @click.prevent="doTest(row.item.links.test)">
{{ $gettext('Test') }}
</b-button>
<b-button size="sm" variant="danger" @click.prevent="doDelete(row.item.links.self)">
{{ $gettext('Delete') }}
</b-button>
</b-button-group>
</template>
</data-table>
</b-card>
<streaming-log-modal ref="logModal"></streaming-log-modal>
<edit-modal ref="editModal" :create-url="listUrl" :webhook-types="webhookTypes"
:trigger-titles="langTriggerTitles" :trigger-descriptions="langTriggerDescriptions"
:now-playing-url="nowPlayingUrl" @relist="relist"></edit-modal>
</div>
<streaming-log-modal ref="logModal"></streaming-log-modal>
<edit-modal ref="editModal" :create-url="listUrl" :webhook-types="webhookTypes"
:trigger-titles="langTriggerTitles" :trigger-descriptions="langTriggerDescriptions"
:now-playing-url="nowPlayingUrl" @relist="relist"></edit-modal>
</template>
<script>

View File

@ -1,68 +1,66 @@
<template>
<div>
<b-form-group>
<b-form-row>
<b-wrapped-form-group class="col-md-12" id="form_config_webhook_url" :field="form.config.webhook_url"
input-type="url">
<template #label="{lang}">
{{ $gettext('Discord Web Hook URL') }}
</template>
<template #description="{lang}">
{{ $gettext('This URL is provided within the Discord application.') }}
</template>
</b-wrapped-form-group>
</b-form-row>
</b-form-group>
<b-form-group>
<b-form-row>
<b-wrapped-form-group class="col-md-12" id="form_config_webhook_url" :field="form.config.webhook_url"
input-type="url">
<template #label="{lang}">
{{ $gettext('Discord Web Hook URL') }}
</template>
<template #description="{lang}">
{{ $gettext('This URL is provided within the Discord application.') }}
</template>
</b-wrapped-form-group>
</b-form-row>
</b-form-group>
<common-formatting-info :now-playing-url="nowPlayingUrl"></common-formatting-info>
<common-formatting-info :now-playing-url="nowPlayingUrl"></common-formatting-info>
<b-form-group>
<b-form-row>
<b-wrapped-form-group class="col-md-6" id="form_config_content" :field="form.config.content">
<template #label="{lang}">
{{ $gettext('Main Message Content') }}
</template>
</b-wrapped-form-group>
<b-form-group>
<b-form-row>
<b-wrapped-form-group class="col-md-6" id="form_config_content" :field="form.config.content">
<template #label="{lang}">
{{ $gettext('Main Message Content') }}
</template>
</b-wrapped-form-group>
<b-wrapped-form-group class="col-md-6" id="form_config_title" :field="form.config.title">
<template #label="{lang}">
{{ $gettext('Title') }}
</template>
</b-wrapped-form-group>
<b-wrapped-form-group class="col-md-6" id="form_config_title" :field="form.config.title">
<template #label="{lang}">
{{ $gettext('Title') }}
</template>
</b-wrapped-form-group>
<b-wrapped-form-group class="col-md-6" id="form_config_description" :field="form.config.description">
<template #label="{lang}">
{{ $gettext('Description') }}
</template>
</b-wrapped-form-group>
<b-wrapped-form-group class="col-md-6" id="form_config_description" :field="form.config.description">
<template #label="{lang}">
{{ $gettext('Description') }}
</template>
</b-wrapped-form-group>
<b-wrapped-form-group class="col-md-6" id="form_config_url" :field="form.config.url" input-type="url">
<template #label="{lang}">
{{ $gettext('URL') }}
</template>
</b-wrapped-form-group>
<b-wrapped-form-group class="col-md-6" id="form_config_url" :field="form.config.url" input-type="url">
<template #label="{lang}">
{{ $gettext('URL') }}
</template>
</b-wrapped-form-group>
<b-wrapped-form-group class="col-md-6" id="form_config_author" :field="form.config.author">
<template #label="{lang}">
{{ $gettext('Author') }}
</template>
</b-wrapped-form-group>
<b-wrapped-form-group class="col-md-6" id="form_config_author" :field="form.config.author">
<template #label="{lang}">
{{ $gettext('Author') }}
</template>
</b-wrapped-form-group>
<b-wrapped-form-group class="col-md-6" id="form_config_thumbnail" :field="form.config.thumbnail"
input-type="url">
<template #label="{lang}">
{{ $gettext('Thumbnail Image URL') }}
</template>
</b-wrapped-form-group>
<b-wrapped-form-group class="col-md-6" id="form_config_thumbnail" :field="form.config.thumbnail"
input-type="url">
<template #label="{lang}">
{{ $gettext('Thumbnail Image URL') }}
</template>
</b-wrapped-form-group>
<b-wrapped-form-group class="col-md-6" id="form_config_footer" :field="form.config.footer">
<template #label="{lang}">
{{ $gettext('Footer Text') }}
</template>
</b-wrapped-form-group>
</b-form-row>
</b-form-group>
</div>
<b-wrapped-form-group class="col-md-6" id="form_config_footer" :field="form.config.footer">
<template #label="{lang}">
{{ $gettext('Footer Text') }}
</template>
</b-wrapped-form-group>
</b-form-row>
</b-form-group>
</template>
<script>

View File

@ -1,36 +1,34 @@
<template>
<div>
<b-form-group>
<b-form-row>
<b-wrapped-form-group class="col-md-12" id="form_config_to" :field="form.config.to">
<template #label="{lang}">
{{ $gettext('Message Recipient(s)') }}
</template>
<template #description="{lang}">
{{ $gettext('E-mail addresses can be separated by commas.') }}
</template>
</b-wrapped-form-group>
</b-form-row>
</b-form-group>
<b-form-group>
<b-form-row>
<b-wrapped-form-group class="col-md-12" id="form_config_to" :field="form.config.to">
<template #label="{lang}">
{{ $gettext('Message Recipient(s)') }}
</template>
<template #description="{lang}">
{{ $gettext('E-mail addresses can be separated by commas.') }}
</template>
</b-wrapped-form-group>
</b-form-row>
</b-form-group>
<common-formatting-info :now-playing-url="nowPlayingUrl"></common-formatting-info>
<common-formatting-info :now-playing-url="nowPlayingUrl"></common-formatting-info>
<b-form-group>
<b-form-row>
<b-wrapped-form-group class="col-md-12" id="form_config_subject" :field="form.config.subject">
<template #label="{lang}">
{{ $gettext('Message Subject') }}
</template>
</b-wrapped-form-group>
<b-form-group>
<b-form-row>
<b-wrapped-form-group class="col-md-12" id="form_config_subject" :field="form.config.subject">
<template #label="{lang}">
{{ $gettext('Message Subject') }}
</template>
</b-wrapped-form-group>
<b-wrapped-form-group class="col-md-12" id="form_config_message" :field="form.config.message">
<template #label="{lang}">
{{ $gettext('Message Body') }}
</template>
</b-wrapped-form-group>
</b-form-row>
</b-form-group>
</div>
<b-wrapped-form-group class="col-md-12" id="form_config_message" :field="form.config.message">
<template #label="{lang}">
{{ $gettext('Message Body') }}
</template>
</b-wrapped-form-group>
</b-form-row>
</b-form-group>
</template>
<script>

View File

@ -1,73 +1,79 @@
<template>
<div>
<b-form-group>
<template #label>
{{ $gettext('Web Hook Details') }}
</template>
<b-form-group>
<template #label>
{{ $gettext('Web Hook Details') }}
</template>
<p class="card-text">
{{ $gettext('Web hooks automatically send a HTTP POST request to the URL you specify to notify it any time one of the triggers you specify occurs on your station.') }}
</p>
<p class="card-text">
{{ $gettext('The body of the POST message is the exact same as the NowPlaying API response for your station.') }}
</p>
<ul>
<li>
<a href="https://azuracast.com/api" target="_blank">
{{ $gettext('NowPlaying API Response') }}
</a>
</li>
</ul>
<p class="card-text">
{{ $gettext('In order to process quickly, web hooks have a short timeout, so the responding service should be optimized to handle the request in under 2 seconds.') }}
</p>
</b-form-group>
<p class="card-text">
{{
$gettext('Web hooks automatically send a HTTP POST request to the URL you specify to notify it any time one of the triggers you specify occurs on your station.')
}}
</p>
<p class="card-text">
{{
$gettext('The body of the POST message is the exact same as the NowPlaying API response for your station.')
}}
</p>
<ul>
<li>
<a href="https://azuracast.com/api" target="_blank">
{{ $gettext('NowPlaying API Response') }}
</a>
</li>
</ul>
<p class="card-text">
{{
$gettext('In order to process quickly, web hooks have a short timeout, so the responding service should be optimized to handle the request in under 2 seconds.')
}}
</p>
</b-form-group>
<b-form-group>
<b-form-row>
<b-wrapped-form-group class="col-md-12" id="form_config_webhook_url" :field="form.config.webhook_url"
input-type="url">
<template #label="{lang}">
{{ $gettext('Web Hook URL') }}
</template>
<template #description="{lang}">
{{ $gettext('The URL that will receive the POST messages any time an event is triggered.') }}
</template>
</b-wrapped-form-group>
<b-form-group>
<b-form-row>
<b-wrapped-form-group class="col-md-12" id="form_config_webhook_url" :field="form.config.webhook_url"
input-type="url">
<template #label="{lang}">
{{ $gettext('Web Hook URL') }}
</template>
<template #description="{lang}">
{{ $gettext('The URL that will receive the POST messages any time an event is triggered.') }}
</template>
</b-wrapped-form-group>
<b-wrapped-form-group class="col-md-6" id="form_config_basic_auth_username"
:field="form.config.basic_auth_username">
<template #label="{lang}">
{{ $gettext('Optional: HTTP Basic Authentication Username') }}
</template>
<template #description="{lang}">
{{ $gettext('If your web hook requires HTTP basic authentication, provide the username here.') }}
</template>
</b-wrapped-form-group>
<b-wrapped-form-group class="col-md-6" id="form_config_basic_auth_username"
:field="form.config.basic_auth_username">
<template #label="{lang}">
{{ $gettext('Optional: HTTP Basic Authentication Username') }}
</template>
<template #description="{lang}">
{{ $gettext('If your web hook requires HTTP basic authentication, provide the username here.') }}
</template>
</b-wrapped-form-group>
<b-wrapped-form-group class="col-md-6" id="form_config_basic_auth_password"
:field="form.config.basic_auth_password">
<template #label="{lang}">
{{ $gettext('Optional: HTTP Basic Authentication Password') }}
</template>
<template #description="{lang}">
{{ $gettext('If your web hook requires HTTP basic authentication, provide the password here.') }}
</template>
</b-wrapped-form-group>
<b-wrapped-form-group class="col-md-6" id="form_config_basic_auth_password"
:field="form.config.basic_auth_password">
<template #label="{lang}">
{{ $gettext('Optional: HTTP Basic Authentication Password') }}
</template>
<template #description="{lang}">
{{ $gettext('If your web hook requires HTTP basic authentication, provide the password here.') }}
</template>
</b-wrapped-form-group>
<b-wrapped-form-group class="col-md-6" id="form_config_timeout"
:field="form.config.timeout" input-type="number"
:input-attrs="{ min: '0.0', max: '600.0', step: '0.1' }">
<template #label="{lang}">
{{ $gettext('Optional: Request Timeout (Seconds)') }}
</template>
<template #description="{lang}">
{{ $gettext('The number of seconds to wait for a response from the remote server before cancelling the request.') }}
</template>
</b-wrapped-form-group>
</b-form-row>
</b-form-group>
</div>
<b-wrapped-form-group class="col-md-6" id="form_config_timeout"
:field="form.config.timeout" input-type="number"
:input-attrs="{ min: '0.0', max: '600.0', step: '0.1' }">
<template #label="{lang}">
{{ $gettext('Optional: Request Timeout (Seconds)') }}
</template>
<template #description="{lang}">
{{
$gettext('The number of seconds to wait for a response from the remote server before cancelling the request.')
}}
</template>
</b-wrapped-form-group>
</b-form-row>
</b-form-group>
</template>
<script>

View File

@ -1,75 +1,73 @@
<template>
<div>
<b-form-group>
<template #label>
{{ $gettext('Mastodon Account Details') }}
</template>
<b-form-group>
<template #label>
{{ $gettext('Mastodon Account Details') }}
</template>
<p class="card-text">
{{ $gettext('Steps for configuring a Mastodon application:') }}
</p>
<ul>
<li>
{{ $gettext('Visit your Mastodon instance.') }}
</li>
<li>
{{ $gettext('Click the "Preferences" link, then "Development" on the left side menu.') }}
</li>
<li>
{{ $gettext('Click "New Application"') }}
</li>
<li>
{{
$gettext('Enter "AzuraCast" as the application name. You can leave the URL fields unchanged. For "Scopes", only "write:media" and "write:statuses" are required.')
}}
</li>
</ul>
<p class="card-text">
<p class="card-text">
{{ $gettext('Steps for configuring a Mastodon application:') }}
</p>
<ul>
<li>
{{ $gettext('Visit your Mastodon instance.') }}
</li>
<li>
{{ $gettext('Click the "Preferences" link, then "Development" on the left side menu.') }}
</li>
<li>
{{ $gettext('Click "New Application"') }}
</li>
<li>
{{
$gettext('Once these steps are completed, enter the "Access Token" from the application\'s page into the field below.')
$gettext('Enter "AzuraCast" as the application name. You can leave the URL fields unchanged. For "Scopes", only "write:media" and "write:statuses" are required.')
}}
</p>
</b-form-group>
</li>
</ul>
<p class="card-text">
{{
$gettext('Once these steps are completed, enter the "Access Token" from the application\'s page into the field below.')
}}
</p>
</b-form-group>
<b-form-group>
<b-form-row>
<b-wrapped-form-group class="col-md-6" id="form_config_instance_url" :field="form.config.instance_url">
<template #label="{lang}">
{{ $gettext('Mastodon Instance URL') }}
</template>
<template #description="{lang}">
{{ $gettext('If your Mastodon username is "@test@example.com", enter "example.com".') }}
</template>
</b-wrapped-form-group>
<b-form-group>
<b-form-row>
<b-wrapped-form-group class="col-md-6" id="form_config_instance_url" :field="form.config.instance_url">
<template #label="{lang}">
{{ $gettext('Mastodon Instance URL') }}
</template>
<template #description="{lang}">
{{ $gettext('If your Mastodon username is "@test@example.com", enter "example.com".') }}
</template>
</b-wrapped-form-group>
<b-wrapped-form-group class="col-md-6" id="form_config_access_token"
:field="form.config.access_token">
<template #label="{lang}">
{{ $gettext('Access Token') }}
</template>
</b-wrapped-form-group>
<b-wrapped-form-group class="col-md-6" id="form_config_access_token"
:field="form.config.access_token">
<template #label="{lang}">
{{ $gettext('Access Token') }}
</template>
</b-wrapped-form-group>
<common-rate-limit-fields :form="form"></common-rate-limit-fields>
</b-form-row>
</b-form-group>
<common-rate-limit-fields :form="form"></common-rate-limit-fields>
</b-form-row>
</b-form-group>
<b-form-group>
<b-form-row>
<b-wrapped-form-group class="col-md-12" id="form_config_visibility" :field="form.config.visibility">
<template #label="{lang}">
{{ $gettext('Message Visibility') }}
</template>
<template #default="props">
<b-form-radio-group stacked :id="props.id" :options="visibilityOptions"
v-model="props.field.$model">
</b-form-radio-group>
</template>
</b-wrapped-form-group>
</b-form-row>
</b-form-group>
<b-form-group>
<b-form-row>
<b-wrapped-form-group class="col-md-12" id="form_config_visibility" :field="form.config.visibility">
<template #label="{lang}">
{{ $gettext('Message Visibility') }}
</template>
<template #default="props">
<b-form-radio-group stacked :id="props.id" :options="visibilityOptions"
v-model="props.field.$model">
</b-form-radio-group>
</template>
</b-wrapped-form-group>
</b-form-row>
</b-form-group>
<common-social-post-fields :form="form" :now-playing-url="nowPlayingUrl"></common-social-post-fields>
</div>
<common-social-post-fields :form="form" :now-playing-url="nowPlayingUrl"></common-social-post-fields>
</template>
<script>

View File

@ -1,69 +1,67 @@
<template>
<div>
<b-form-group>
<b-form-row>
<b-wrapped-form-group class="col-md-6" id="form_config_bot_token" :field="form.config.bot_token">
<template #label="{lang}">
{{ $gettext('Bot Token') }}
</template>
<template #description="{lang}">
<a href="https://core.telegram.org/bots#botfather" target="_blank">
{{ $gettext('See the Telegram Documentation for more details.') }}
</a>
</template>
</b-wrapped-form-group>
<b-form-group>
<b-form-row>
<b-wrapped-form-group class="col-md-6" id="form_config_bot_token" :field="form.config.bot_token">
<template #label="{lang}">
{{ $gettext('Bot Token') }}
</template>
<template #description="{lang}">
<a href="https://core.telegram.org/bots#botfather" target="_blank">
{{ $gettext('See the Telegram Documentation for more details.') }}
</a>
</template>
</b-wrapped-form-group>
<b-wrapped-form-group class="col-md-6" id="form_config_chat_id" :field="form.config.chat_id">
<template #label="{lang}">
{{ $gettext('Chat ID') }}
</template>
<template #description="{lang}">
{{
$gettext('Unique identifier for the target chat or username of the target channel (in the format @channelusername).')
}}
</template>
</b-wrapped-form-group>
<b-wrapped-form-group class="col-md-6" id="form_config_chat_id" :field="form.config.chat_id">
<template #label="{lang}">
{{ $gettext('Chat ID') }}
</template>
<template #description="{lang}">
{{
$gettext('Unique identifier for the target chat or username of the target channel (in the format @channelusername).')
}}
</template>
</b-wrapped-form-group>
<b-wrapped-form-group class="col-md-6" id="form_config_api" :field="form.config.api">
<template #label="{lang}">
{{ $gettext('Custom API Base URL') }}
</template>
<template #description="{lang}">
{{ $gettext('Leave blank to use the default Telegram API URL (recommended).') }}
</template>
</b-wrapped-form-group>
</b-form-row>
</b-form-group>
<b-wrapped-form-group class="col-md-6" id="form_config_api" :field="form.config.api">
<template #label="{lang}">
{{ $gettext('Custom API Base URL') }}
</template>
<template #description="{lang}">
{{ $gettext('Leave blank to use the default Telegram API URL (recommended).') }}
</template>
</b-wrapped-form-group>
</b-form-row>
</b-form-group>
<common-formatting-info :now-playing-url="nowPlayingUrl"></common-formatting-info>
<common-formatting-info :now-playing-url="nowPlayingUrl"></common-formatting-info>
<b-form-group>
<b-form-row>
<b-wrapped-form-group class="col-md-12" id="form_config_text" :field="form.config.text"
input-type="textarea">
<template #label="{lang}">
{{ $gettext('Main Message Content') }}
</template>
</b-wrapped-form-group>
<b-form-group>
<b-form-row>
<b-wrapped-form-group class="col-md-12" id="form_config_text" :field="form.config.text"
input-type="textarea">
<template #label="{lang}">
{{ $gettext('Main Message Content') }}
</template>
</b-wrapped-form-group>
<b-wrapped-form-group class="col-md-12" id="form_config_parse_mode" :field="form.config.parse_mode">
<template #label="{lang}">
{{ $gettext('Message parsing mode') }}
</template>
<template #description="{lang}">
<a href="https://core.telegram.org/bots/api#sendmessage" target="_blank">
{{ $gettext('See the Telegram documentation for more details.') }}
</a>
</template>
<template #default="props">
<b-form-radio-group stacked :id="props.id" :options="parseModeOptions"
v-model="props.field.$model">
</b-form-radio-group>
</template>
</b-wrapped-form-group>
</b-form-row>
</b-form-group>
</div>
<b-wrapped-form-group class="col-md-12" id="form_config_parse_mode" :field="form.config.parse_mode">
<template #label="{lang}">
{{ $gettext('Message parsing mode') }}
</template>
<template #description="{lang}">
<a href="https://core.telegram.org/bots/api#sendmessage" target="_blank">
{{ $gettext('See the Telegram documentation for more details.') }}
</a>
</template>
<template #default="props">
<b-form-radio-group stacked :id="props.id" :options="parseModeOptions"
v-model="props.field.$model">
</b-form-radio-group>
</template>
</b-wrapped-form-group>
</b-form-row>
</b-form-group>
</template>
<script>

View File

@ -1,70 +1,68 @@
<template>
<div>
<b-form-group>
<template #label>
{{ $gettext('Twitter Account Details') }}
</template>
<b-form-group>
<template #label>
{{ $gettext('Twitter Account Details') }}
</template>
<p class="card-text">
{{ $gettext('Steps for configuring a Twitter application:') }}
</p>
<ul>
<li>
{{
$gettext('Create a new app on the Twitter Applications site. Use this installation\'s base URL as the application URL.')
}}
<br>
<a href="https://developer.twitter.com/en/apps" target="_blank">
{{ $gettext('Twitter Applications') }}
</a>
</li>
<li>
{{ $gettext('In the newly created application, click the "Keys and Access Tokens" tab.') }}
</li>
<li>
{{ $gettext('At the bottom of the page, click "Create my access token".') }}
</li>
</ul>
<p class="card-text">
<p class="card-text">
{{ $gettext('Steps for configuring a Twitter application:') }}
</p>
<ul>
<li>
{{
$gettext('Once these steps are completed, enter the information from the "Keys and Access Tokens" page into the fields below.')
$gettext('Create a new app on the Twitter Applications site. Use this installation\'s base URL as the application URL.')
}}
</p>
</b-form-group>
<br>
<a href="https://developer.twitter.com/en/apps" target="_blank">
{{ $gettext('Twitter Applications') }}
</a>
</li>
<li>
{{ $gettext('In the newly created application, click the "Keys and Access Tokens" tab.') }}
</li>
<li>
{{ $gettext('At the bottom of the page, click "Create my access token".') }}
</li>
</ul>
<p class="card-text">
{{
$gettext('Once these steps are completed, enter the information from the "Keys and Access Tokens" page into the fields below.')
}}
</p>
</b-form-group>
<b-form-group>
<b-form-row>
<b-wrapped-form-group class="col-md-6" id="form_config_consumer_key" :field="form.config.consumer_key">
<template #label="{lang}">
{{ $gettext('Consumer Key (API Key)') }}
</template>
</b-wrapped-form-group>
<b-form-group>
<b-form-row>
<b-wrapped-form-group class="col-md-6" id="form_config_consumer_key" :field="form.config.consumer_key">
<template #label="{lang}">
{{ $gettext('Consumer Key (API Key)') }}
</template>
</b-wrapped-form-group>
<b-wrapped-form-group class="col-md-6" id="form_config_consumer_secret"
:field="form.config.consumer_secret">
<template #label="{lang}">
{{ $gettext('Consumer Secret (API Secret)') }}
</template>
</b-wrapped-form-group>
<b-wrapped-form-group class="col-md-6" id="form_config_consumer_secret"
:field="form.config.consumer_secret">
<template #label="{lang}">
{{ $gettext('Consumer Secret (API Secret)') }}
</template>
</b-wrapped-form-group>
<b-wrapped-form-group class="col-md-6" id="form_config_token" :field="form.config.token">
<template #label="{lang}">
{{ $gettext('Access Token') }}
</template>
</b-wrapped-form-group>
<b-wrapped-form-group class="col-md-6" id="form_config_token" :field="form.config.token">
<template #label="{lang}">
{{ $gettext('Access Token') }}
</template>
</b-wrapped-form-group>
<b-wrapped-form-group class="col-md-6" id="form_config_token_secret" :field="form.config.token_secret">
<template #label="{lang}">
{{ $gettext('Access Token Secret') }}
</template>
</b-wrapped-form-group>
<b-wrapped-form-group class="col-md-6" id="form_config_token_secret" :field="form.config.token_secret">
<template #label="{lang}">
{{ $gettext('Access Token Secret') }}
</template>
</b-wrapped-form-group>
<common-rate-limit-fields :form="form"></common-rate-limit-fields>
</b-form-row>
</b-form-group>
<common-rate-limit-fields :form="form"></common-rate-limit-fields>
</b-form-row>
</b-form-group>
<common-social-post-fields :form="form" :now-playing-url="nowPlayingUrl"></common-social-post-fields>
</div>
<common-social-post-fields :form="form" :now-playing-url="nowPlayingUrl"></common-social-post-fields>
</template>
<script>