Tree-shake Lodash and other JS fixes.

This commit is contained in:
Buster Neece 2022-12-30 16:02:15 -06:00
parent 069481353e
commit 9862a28fbe
No known key found for this signature in database
GPG Key ID: F1D2E64A0005E80E
27 changed files with 162 additions and 220 deletions

View File

@ -71,7 +71,7 @@ import DataTable from '~/components/Common/DataTable.vue';
import EditModal from './CustomFields/EditModal.vue'; import EditModal from './CustomFields/EditModal.vue';
import Icon from '~/components/Common/Icon.vue'; import Icon from '~/components/Common/Icon.vue';
import InfoCard from '~/components/Common/InfoCard.vue'; import InfoCard from '~/components/Common/InfoCard.vue';
import _, {get} from 'lodash'; import {get} from 'lodash';
import {useTranslate} from "~/vendor/gettext"; import {useTranslate} from "~/vendor/gettext";
import {ref} from "vue"; import {ref} from "vue";
import {useSweetAlert} from "~/vendor/sweetalert"; import {useSweetAlert} from "~/vendor/sweetalert";

View File

@ -368,26 +368,7 @@
class="align-middle" class="align-middle"
> >
<td class="text-center pr-2"> <td class="text-center pr-2">
<template v-if="service.running"> <running-badge :running="service.running" />
<b-badge
pill
variant="success"
:title="langServiceRunning"
>
&nbsp;&nbsp;
<span class="sr-only">{{ langServiceRunning }}</span>
</b-badge>
</template>
<template v-else>
<b-badge
pill
variant="danger"
:title="langServiceStopped"
>
&nbsp;&nbsp;
<span class="sr-only">{{ langServiceStopped }}</span>
</b-badge>
</template>
</td> </td>
<td class="pl-2"> <td class="pl-2">
<h6 class="mb-0"> <h6 class="mb-0">
@ -474,11 +455,12 @@
import Icon from '~/components/Common/Icon'; import Icon from '~/components/Common/Icon';
import CpuStatsHelpModal from "./Index/CpuStatsHelpModal"; import CpuStatsHelpModal from "./Index/CpuStatsHelpModal";
import MemoryStatsHelpModal from "./Index/MemoryStatsHelpModal"; import MemoryStatsHelpModal from "./Index/MemoryStatsHelpModal";
import _ from 'lodash'; import {isObject, upperFirst} from 'lodash';
import RunningBadge from "~/components/Common/Badges/RunningBadge.vue";
export default { export default {
name: 'AdminIndex', name: 'AdminIndex',
components: {CpuStatsHelpModal, MemoryStatsHelpModal, Icon}, components: {RunningBadge, CpuStatsHelpModal, MemoryStatsHelpModal, Icon},
props: { props: {
adminPanels: { adminPanels: {
type: Object, type: Object,
@ -537,21 +519,13 @@ export default {
services: [] services: []
}; };
}, },
computed: {
langServiceRunning() {
return this.$gettext('Service Running');
},
langServiceStopped() {
return this.$gettext('Service Stopped');
}
},
created() { created() {
this.updateStats(); this.updateStats();
this.updateServices(); this.updateServices();
}, },
methods: { methods: {
formatCpuName(cpuName) { formatCpuName(cpuName) {
return _.upperFirst(cpuName); return upperFirst(cpuName);
}, },
formatPercentageString(value) { formatPercentageString(value) {
return value + '%'; return value + '%';
@ -575,7 +549,7 @@ export default {
let key = data[0]; let key = data[0];
let value = data[1]; let value = data[1];
if (_.isObject(value)) { if (isObject(value)) {
value = value.readable + '/s'; value = value.readable + '/s';
} }

View File

@ -85,7 +85,7 @@ import DataTable from '~/components/Common/DataTable';
import EditModal from './Permissions/EditModal'; import EditModal from './Permissions/EditModal';
import Icon from '~/components/Common/Icon'; import Icon from '~/components/Common/Icon';
import InfoCard from '~/components/Common/InfoCard'; import InfoCard from '~/components/Common/InfoCard';
import _ from 'lodash'; import {filter, get, map} from 'lodash';
export default { export default {
name: 'AdminPermissions', name: 'AdminPermissions',
@ -119,17 +119,17 @@ export default {
}, },
methods: { methods: {
getGlobalPermissionNames(permissions) { getGlobalPermissionNames(permissions) {
return _.filter(_.map(permissions, (permission) => { return filter(map(permissions, (permission) => {
return _.get(this.globalPermissions, permission, null); return get(this.globalPermissions, permission, null);
})); }));
}, },
getStationPermissionNames(permissions) { getStationPermissionNames(permissions) {
return _.filter(_.map(permissions, (permission) => { return filter(map(permissions, (permission) => {
return _.get(this.stationPermissions, permission, null); return get(this.stationPermissions, permission, null);
})); }));
}, },
getStationName(stationId) { getStationName(stationId) {
return _.get(this.stations, stationId, null); return get(this.stations, stationId, null);
}, },
relist() { relist() {
this.$refs.datatable.refresh(); this.$refs.datatable.refresh();

View File

@ -31,7 +31,7 @@ import {required} from '@vuelidate/validators';
import BaseEditModal from '~/components/Common/BaseEditModal'; import BaseEditModal from '~/components/Common/BaseEditModal';
import AdminPermissionsGlobalForm from "./Form/GlobalForm"; import AdminPermissionsGlobalForm from "./Form/GlobalForm";
import AdminPermissionsStationForm from "./Form/StationForm"; import AdminPermissionsStationForm from "./Form/StationForm";
import _ from 'lodash'; import {forEach, map} from 'lodash';
import {useVuelidateOnForm} from "~/functions/useVuelidateOnForm"; import {useVuelidateOnForm} from "~/functions/useVuelidateOnForm";
export default { export default {
@ -87,7 +87,7 @@ export default {
populateForm(data) { populateForm(data) {
this.form.name = data.name; this.form.name = data.name;
this.form.permissions.global = data.permissions.global; this.form.permissions.global = data.permissions.global;
this.form.permissions.station = _.map(data.permissions.station, (permissions, stationId) => { this.form.permissions.station = map(data.permissions.station, (permissions, stationId) => {
return { return {
'station_id': stationId, 'station_id': stationId,
'permissions': permissions 'permissions': permissions
@ -103,7 +103,7 @@ export default {
} }
}; };
_.forEach(this.form.permissions.station, (row) => { forEach(this.form.permissions.station, (row) => {
form.permissions.station[row.station_id] = row.permissions; form.permissions.station[row.station_id] = row.permissions;
}); });

View File

@ -88,7 +88,7 @@
import DataTable from '~/components/Common/DataTable'; import DataTable from '~/components/Common/DataTable';
import Icon from '~/components/Common/Icon'; import Icon from '~/components/Common/Icon';
import AdminStationsEditModal from "./Stations/EditModal"; import AdminStationsEditModal from "./Stations/EditModal";
import _ from "lodash"; import {get} from "lodash";
import AdminStationsCloneModal from "./Stations/CloneModal"; import AdminStationsCloneModal from "./Stations/CloneModal";
import stationFormProps from "./Stations/stationFormProps"; import stationFormProps from "./Stations/stationFormProps";
@ -148,10 +148,10 @@ export default {
}); });
}, },
getFrontendName(frontend_type) { getFrontendName(frontend_type) {
return _.get(this.frontendTypes, [frontend_type, 'name'], ''); return get(this.frontendTypes, [frontend_type, 'name'], '');
}, },
getBackendName(backend_type) { getBackendName(backend_type) {
return _.get(this.backendTypes, [backend_type, 'name'], ''); return get(this.backendTypes, [backend_type, 'name'], '');
} }
} }
}; };

View File

@ -21,7 +21,7 @@ import useVuelidate from "@vuelidate/core";
import {email, required} from '@vuelidate/validators'; import {email, required} from '@vuelidate/validators';
import BaseEditModal from '~/components/Common/BaseEditModal'; import BaseEditModal from '~/components/Common/BaseEditModal';
import AdminUsersForm from './Form.vue'; import AdminUsersForm from './Form.vue';
import _ from 'lodash'; import {map} from 'lodash';
import validatePassword from "~/functions/validatePassword"; import validatePassword from "~/functions/validatePassword";
export default { export default {
@ -75,7 +75,7 @@ export default {
name: data.name, name: data.name,
email: data.email, email: data.email,
new_password: '', new_password: '',
roles: _.map(data.roles, 'id') roles: map(data.roles, 'id')
}; };
}, },
} }

View File

@ -16,7 +16,7 @@ export default defineComponent({
props: { props: {
title: { title: {
type: String, type: String,
required: true default: null
}, },
volume: { volume: {
type: Number, type: Number,

View File

@ -8,7 +8,7 @@
import {get} from "@vueuse/core"; import {get} from "@vueuse/core";
import {Tableau20} from "~/vendor/chartjs-colorschemes/colorschemes.tableau"; import {Tableau20} from "~/vendor/chartjs-colorschemes/colorschemes.tableau";
import {DateTime} from "luxon"; import {DateTime} from "luxon";
import _ from "lodash"; import {defaultsDeep} from "lodash";
import {Chart} from "chart.js"; import {Chart} from "chart.js";
import {onMounted, onUnmounted, ref} from "vue"; import {onMounted, onUnmounted, ref} from "vue";
import {useTranslate} from "~/vendor/gettext"; import {useTranslate} from "~/vendor/gettext";
@ -16,7 +16,9 @@ import {useTranslate} from "~/vendor/gettext";
const props = defineProps({ const props = defineProps({
options: { options: {
type: Object, type: Object,
required: true default: () => {
return {};
}
}, },
data: { data: {
type: Array, type: Array,
@ -99,7 +101,7 @@ onMounted(() => {
$chart.destroy(); $chart.destroy();
} }
let chartOptions = _.defaultsDeep({}, props.options, defaultOptions); let chartOptions = defaultsDeep({}, props.options, defaultOptions);
$chart = new Chart(get($canvas).getContext('2d'), chartOptions); $chart = new Chart(get($canvas).getContext('2d'), chartOptions);
}); });

View File

@ -75,7 +75,7 @@
<script> <script>
import InvisibleSubmitButton from "~/components/Common/InvisibleSubmitButton.vue"; import InvisibleSubmitButton from "~/components/Common/InvisibleSubmitButton.vue";
import {defineComponent} from "vue"; import {defineComponent} from "vue";
import _ from "lodash"; import {filter, includes} from "lodash";
export default defineComponent({ export default defineComponent({
components: {InvisibleSubmitButton}, components: {InvisibleSubmitButton},
@ -116,8 +116,8 @@ export default defineComponent({
emits: ['submit', 'shown', 'hidden'], emits: ['submit', 'shown', 'hidden'],
computed: { computed: {
filteredScopedSlots() { filteredScopedSlots() {
return _.filter(this.$slots, (slot, name) => { return filter(this.$slots, (slot, name) => {
return !_.includes([ return !includes([
'default', 'modal-footer' 'default', 'modal-footer'
], name); ], name);
}); });

View File

@ -11,7 +11,7 @@
<script setup> <script setup>
import {computed} from "vue"; import {computed} from "vue";
import _ from 'lodash'; import {isEmpty, padStart} from 'lodash';
const props = defineProps({ const props = defineProps({
modelValue: { modelValue: {
@ -24,7 +24,7 @@ const emit = defineEmits(['update:modelValue']);
const parseTimeCode = (timeCode) => { const parseTimeCode = (timeCode) => {
if (timeCode !== '' && timeCode !== null) { if (timeCode !== '' && timeCode !== null) {
timeCode = _.padStart(timeCode, 4, '0'); timeCode = padStart(timeCode, 4, '0');
return timeCode.substring(0, 2) + ':' + timeCode.substring(2); return timeCode.substring(0, 2) + ':' + timeCode.substring(2);
} }
@ -32,7 +32,7 @@ const parseTimeCode = (timeCode) => {
} }
const convertToTimeCode = (time) => { const convertToTimeCode = (time) => {
if (_.isEmpty(time)) { if (isEmpty(time)) {
return null; return null;
} }

View File

@ -94,7 +94,7 @@ const props = defineProps({
}, },
name: { name: {
type: String, type: String,
required: true default: null
}, },
field: { field: {
type: Object, type: Object,

View File

@ -53,7 +53,7 @@
</div> </div>
<div class="flex-fill mx-1"> <div class="flex-fill mx-1">
<input <input
v-model="volume" v-model.number="volume"
type="range" type="range"
:title="$gettext('Volume')" :title="$gettext('Volume')"
class="player-volume-range custom-range" class="player-volume-range custom-range"

View File

@ -41,7 +41,7 @@
<script> <script>
import DataTable from '~/components/Common/DataTable'; import DataTable from '~/components/Common/DataTable';
import _ from 'lodash'; import {forEach} from 'lodash';
import AlbumArt from '~/components/Common/AlbumArt'; import AlbumArt from '~/components/Common/AlbumArt';
export default { export default {
@ -95,7 +95,7 @@ export default {
} }
]; ];
_.forEach(this.customFields.slice(), (field) => { forEach(this.customFields.slice(), (field) => {
fields.push({ fields.push({
key: 'song.custom_fields.' + field.short_name, key: 'song.custom_fields.' + field.short_name,
label: field.name, label: field.name,

View File

@ -83,7 +83,7 @@
</template> </template>
<script> <script>
import track from './Track.js'; import track from './Track.js';
import _ from 'lodash'; import {first, filter, isEmpty} from 'lodash';
import Icon from '~/components/Common/Icon'; import Icon from '~/components/Common/Icon';
import VolumeSlider from "~/components/Public/WebDJ/VolumeSlider"; import VolumeSlider from "~/components/Public/WebDJ/VolumeSlider";
@ -184,15 +184,15 @@ export default {
}); });
}, },
setDevices: function (devices) { setDevices: function (devices) {
devices = _.filter(devices, function ({kind}) { devices = filter(devices, function ({kind}) {
return kind === 'audioinput'; return kind === 'audioinput';
}); });
if (_.isEmpty(devices)) { if (isEmpty(devices)) {
return; return;
} }
this.devices = devices; this.devices = devices;
this.device = _.first(devices).deviceId; this.device = first(devices).deviceId;
} }
} }
}; };

View File

@ -63,7 +63,7 @@
> >
<div class="d-flex flex-row mb-2"> <div class="d-flex flex-row mb-2">
<div class="flex-shrink-0 pt-1 pr-2"> <div class="flex-shrink-0 pt-1 pr-2">
{{ prettifyTime(position) }} {{ formatTime(position) }}
</div> </div>
<div class="flex-fill"> <div class="flex-fill">
<input <input
@ -79,7 +79,7 @@
> >
</div> </div>
<div class="flex-shrink-0 pt-1 pl-2"> <div class="flex-shrink-0 pt-1 pl-2">
{{ prettifyTime(duration) }} {{ formatTime(duration) }}
</div> </div>
</div> </div>
@ -163,11 +163,11 @@
> >
<div class="d-flex w-100 justify-content-between"> <div class="d-flex w-100 justify-content-between">
<h5 class="mb-0">{{ <h5 class="mb-0">{{
rowFile.metadata.title ? rowFile.metadata.title : lang_unknown_title rowFile?.metadata?.title ?? $gettext('Unknown Title')
}}</h5> }}</h5>
<small class="pt-1">{{ prettifyTime(rowFile.audio.length) }}</small> <small class="pt-1">{{ formatTime(rowFile.audio.length) }}</small>
</div> </div>
<p class="mb-0">{{ rowFile.metadata.artist ? rowFile.metadata.artist : lang_unknown_artist }}</p> <p class="mb-0">{{ rowFile?.metadata?.artist ?? $gettext('Unknown Artist') }}</p>
</a> </a>
</div> </div>
</div> </div>
@ -175,9 +175,10 @@
<script> <script>
import track from './Track.js'; import track from './Track.js';
import _ from 'lodash'; import {forEach} from 'lodash';
import Icon from '~/components/Common/Icon'; import Icon from '~/components/Common/Icon';
import VolumeSlider from "~/components/Public/WebDJ/VolumeSlider"; import VolumeSlider from "~/components/Public/WebDJ/VolumeSlider";
import formatTime from "../../../functions/formatTime";
export default { export default {
components: {VolumeSlider, Icon}, components: {VolumeSlider, Icon},
@ -209,12 +210,6 @@ export default {
? this.$gettext('Playlist 1') ? this.$gettext('Playlist 1')
: this.$gettext('Playlist 2'); : this.$gettext('Playlist 2');
}, },
lang_unknown_title () {
return this.$gettext('Unknown Title');
},
lang_unknown_artist () {
return this.$gettext('Unknown Artist');
},
positionPercent () { positionPercent () {
return (100.0 * this.position / parseFloat(this.duration)); return (100.0 * this.position / parseFloat(this.duration));
}, },
@ -231,38 +226,14 @@ export default {
this.$root.$on('new-cue', this.onNewCue); this.$root.$on('new-cue', this.onNewCue);
}, },
methods: { methods: {
prettifyTime(time) { formatTime,
if (typeof time === 'undefined') {
return 'N/A';
}
let hours = parseInt(time / 3600);
time %= 3600;
let minutes = parseInt(time / 60);
let seconds = parseInt(time % 60);
if (minutes < 10) {
minutes = '0' + minutes;
}
if (seconds < 10) {
seconds = '0' + seconds;
}
if (hours > 0) {
return hours + ':' + minutes + ':' + seconds;
} else {
return minutes + ':' + seconds;
}
},
cue() { cue() {
this.resumeStream(); this.resumeStream();
this.$root.$emit('new-cue', (this.passThrough) ? 'off' : this.id); this.$root.$emit('new-cue', (this.passThrough) ? 'off' : this.id);
}, },
onNewCue(new_cue) { onNewCue(new_cue) {
this.passThrough = (new_cue === this.id); this.passThrough = (new_cue === this.id);
}, },
setMixGain(new_value) { setMixGain(new_value) {
if (this.id === 'playlist_1') { if (this.id === 'playlist_1') {
this.mixGainObj.gain.value = 1.0 - new_value; this.mixGainObj.gain.value = 1.0 - new_value;
@ -270,19 +241,17 @@ export default {
this.mixGainObj.gain.value = new_value; this.mixGainObj.gain.value = new_value;
} }
}, },
addNewFiles (newFiles) { addNewFiles (newFiles) {
_.each(newFiles, (file) => { forEach(newFiles, (file) => {
file.readTaglibMetadata((data) => { file.readTaglibMetadata((data) => {
this.files.push({ this.files.push({
file: file, file: file,
audio: data.audio, audio: data.audio,
metadata: data.metadata || { title: '', artist: '' } metadata: data.metadata || {title: '', artist: ''}
}); });
}); });
}); });
}, },
play (options) { play (options) {
this.resumeStream(); this.resumeStream();

View File

@ -200,7 +200,7 @@
v-model="djUsername" v-model="djUsername"
type="text" type="text"
class="form-control" class="form-control"
:placeholder="langDjUsername" :placeholder="$gettext('Username')"
> >
</div> </div>
<div class="col-6"> <div class="col-6">
@ -208,7 +208,7 @@
v-model="djPassword" v-model="djPassword"
type="password" type="password"
class="form-control" class="form-control"
:placeholder="langDjPassword" :placeholder="$gettext('Password')"
> >
</div> </div>
</div> </div>
@ -345,12 +345,6 @@ export default {
}; };
}, },
computed: { computed: {
langDjUsername () {
return this.$gettext('Username');
},
langDjPassword () {
return this.$gettext('Password');
},
langStreamButton () { langStreamButton () {
return (this.isStreaming) return (this.isStreaming)
? this.$gettext('Stop Streaming') ? this.$gettext('Stop Streaming')

View File

@ -258,7 +258,7 @@ import PlayButton from "~/components/Common/PlayButton";</script>
<script> <script>
import formatFileSize from '~/functions/formatFileSize.js'; import formatFileSize from '~/functions/formatFileSize.js';
import _ from 'lodash'; import {forEach, map, partition} from 'lodash';
import {DateTime} from 'luxon'; import {DateTime} from 'luxon';
import {useAzuraCast} from "~/vendor/azuracast"; import {useAzuraCast} from "~/vendor/azuracast";
@ -341,7 +341,7 @@ export default {
{key: 'media.length', label: this.$gettext('Length'), sortable: true, selectable: true, visible: true} {key: 'media.length', label: this.$gettext('Length'), sortable: true, selectable: true, visible: true}
]; ];
_.forEach(this.customFields.slice(), (field) => { forEach(this.customFields.slice(), (field) => {
fields.push({ fields.push({
key: 'media.custom_fields[' + field.id + ']', key: 'media.custom_fields[' + field.id + ']',
label: field.name, label: field.name,
@ -417,12 +417,12 @@ export default {
return formatFileSize(size); return formatFileSize(size);
}, },
onRowSelected(items) { onRowSelected(items) {
let splitItems = _.partition(items, 'is_dir'); let splitItems = partition(items, 'is_dir');
this.selectedItems = { this.selectedItems = {
all: items, all: items,
files: _.map(splitItems[1], 'path'), files: map(splitItems[1], 'path'),
directories: _.map(splitItems[0], 'path') directories: map(splitItems[0], 'path')
}; };
}, },
onTriggerNavigate() { onTriggerNavigate() {

View File

@ -10,7 +10,7 @@
v-b-tooltip.hover v-b-tooltip.hover
size="sm" size="sm"
variant="primary" variant="primary"
:title="langPlaylistDropdown" :title="$gettext('Set or clear playlists from the selected media')"
> >
<template #button-content> <template #button-content>
<icon icon="clear_all" /> <icon icon="clear_all" />
@ -63,7 +63,7 @@
class="form-control p-2" class="form-control p-2"
name="new_playlist_name" name="new_playlist_name"
style="min-width: 150px;" style="min-width: 150px;"
:placeholder="langNewPlaylist" :placeholder="$gettext('New Playlist')"
> >
</label> </label>
</div> </div>
@ -101,11 +101,11 @@
> >
<template #button-content> <template #button-content>
<icon icon="more_horiz" /> <icon icon="more_horiz" />
{{ langMore }} {{ $gettext('More') }}
</template> </template>
<b-dropdown-item <b-dropdown-item
v-b-tooltip.hover v-b-tooltip.hover
:title="langQueue" :title="$gettext('Queue the selected media to play next')"
@click="doQueue" @click="doQueue"
> >
{{ $gettext('Queue') }} {{ $gettext('Queue') }}
@ -113,14 +113,14 @@
<b-dropdown-item <b-dropdown-item
v-if="supportsImmediateQueue" v-if="supportsImmediateQueue"
v-b-tooltip.hover v-b-tooltip.hover
:title="langImmediateQueue" :title="$gettext('Make the selected media play immediately, interrupting existing media')"
@click="doImmediateQueue" @click="doImmediateQueue"
> >
{{ $gettext('Play Now') }} {{ $gettext('Play Now') }}
</b-dropdown-item> </b-dropdown-item>
<b-dropdown-item <b-dropdown-item
v-b-tooltip.hover v-b-tooltip.hover
:title="langReprocess" :title="$gettext('Analyze and reprocess the selected media')"
@click="doReprocess" @click="doReprocess"
> >
{{ $gettext('Reprocess') }} {{ $gettext('Reprocess') }}
@ -149,7 +149,7 @@
</div> </div>
</template> </template>
<script> <script>
import _ from 'lodash'; import {forEach, intersection, map} from 'lodash';
import Icon from '~/components/Common/Icon'; import Icon from '~/components/Common/Icon';
import '~/vendor/sweetalert'; import '~/vendor/sweetalert';
@ -188,24 +188,6 @@ export default {
}; };
}, },
computed: { computed: {
langPlaylistDropdown() {
return this.$gettext('Set or clear playlists from the selected media');
},
langNewPlaylist() {
return this.$gettext('New Playlist');
},
langMore() {
return this.$gettext('More');
},
langImmediateQueue() {
return this.$gettext('Make the selected media play immediately, interrupting existing media');
},
langQueue() {
return this.$gettext('Queue the selected media to play next');
},
langReprocess() {
return this.$gettext('Analyze and reprocess the selected media');
},
langErrors() { langErrors() {
return this.$gettext('The request could not be processed.'); return this.$gettext('The request could not be processed.');
}, },
@ -213,12 +195,12 @@ export default {
watch: { watch: {
selectedItems (items) { selectedItems (items) {
// Get all playlists that are active on ALL selected items. // Get all playlists that are active on ALL selected items.
let playlistsForItems = _.map(items.all, (item) => { let playlistsForItems = map(items.all, (item) => {
return _.map(item.playlists, 'id'); return map(item.playlists, 'id');
}); });
// Check the checkboxes for those playlists. // Check the checkboxes for those playlists.
this.checkedPlaylists = _.intersection(...playlistsForItems); this.checkedPlaylists = intersection(...playlistsForItems);
}, },
newPlaylist (text) { newPlaylist (text) {
if (text !== '') { if (text !== '') {
@ -262,7 +244,7 @@ export default {
).then((resp) => { ).then((resp) => {
if (resp.data.success) { if (resp.data.success) {
let allItemNodes = []; let allItemNodes = [];
_.forEach(this.selectedItems.all, (item) => { forEach(this.selectedItems.all, (item) => {
allItemNodes.push(this.$createElement('div', {}, item.path_short)); allItemNodes.push(this.$createElement('div', {}, item.path_short));
}); });
@ -271,7 +253,7 @@ export default {
}); });
} else { } else {
let errorNodes = []; let errorNodes = [];
_.forEach(resp.data.errors, (error) => { forEach(resp.data.errors, (error) => {
errorNodes.push(this.$createElement('div', {}, error)); errorNodes.push(this.$createElement('div', {}, error));
}); });
@ -316,7 +298,7 @@ export default {
: this.$gettext('Playlists cleared for selected files:'); : this.$gettext('Playlists cleared for selected files:');
let allItemNodes = []; let allItemNodes = [];
_.forEach(this.selectedItems.all, (item) => { forEach(this.selectedItems.all, (item) => {
allItemNodes.push(this.$createElement('div', {}, item.path_short)); allItemNodes.push(this.$createElement('div', {}, item.path_short));
}); });
@ -328,7 +310,7 @@ export default {
this.newPlaylist = ''; this.newPlaylist = '';
} else { } else {
let errorNodes = []; let errorNodes = [];
_.forEach(resp.data.errors, (error) => { forEach(resp.data.errors, (error) => {
errorNodes.push(this.$createElement('div', {}, error)); errorNodes.push(this.$createElement('div', {}, error));
}); });

View File

@ -73,7 +73,7 @@
</template> </template>
<script> <script>
import DataTable from '~/components/Common/DataTable.vue'; import DataTable from '~/components/Common/DataTable.vue';
import _ from 'lodash'; import {forEach} from 'lodash';
import Icon from '~/components/Common/Icon'; import Icon from '~/components/Common/Icon';
export default { export default {
@ -109,8 +109,10 @@ export default {
}, },
computed: { computed: {
langHeader () { langHeader () {
let headerText = this.$gettext('Move %{ num } File(s) to'); return this.$gettext(
return this.$gettextInterpolate(headerText, { num: this.selectedItems.all.length }); 'Move %{ num } File(s) to',
{num: this.selectedItems.all.length}
);
} }
}, },
methods: { methods: {
@ -132,7 +134,7 @@ export default {
).then(() => { ).then(() => {
let notifyMessage = this.$gettext('Files moved:'); let notifyMessage = this.$gettext('Files moved:');
let itemNameNodes = []; let itemNameNodes = [];
_.forEach(this.selectedItems.all, (item) => { forEach(this.selectedItems.all, (item) => {
itemNameNodes.push(this.$createElement('div', {}, item.name)); itemNameNodes.push(this.$createElement('div', {}, item.name));
}); });

View File

@ -167,10 +167,10 @@ export default {
}, },
computed: { computed: {
langAuthhashDesc() { langAuthhashDesc() {
let text = 'If your stream is set to advertise to YP directories above, you must specify an authorization hash. You can manage authhashes <a href="%{ url }" target="_blank">on the Shoutcast web site</a>.'; return this.$gettext(
let url = 'https://radiomanager.shoutcast.com/'; 'If your stream is set to advertise to YP directories above, you must specify an authorization hash. You can manage authhashes <a href="%{ url }" target="_blank">on the Shoutcast web site</a>.',
{url: 'https://radiomanager.shoutcast.com/'}
return this.$gettextInterpolate(this.$gettext(text), {url: url}); );
}, },
isIcecast () { isIcecast () {
return FRONTEND_ICECAST === this.stationFrontendType; return FRONTEND_ICECAST === this.stationFrontendType;

View File

@ -85,8 +85,10 @@ export default {
this.resetForm(); this.resetForm();
this.cloneUrl = cloneUrl; this.cloneUrl = cloneUrl;
let langNewName = this.$gettext('%{name} - Copy'); this.form.name = this.$gettext(
this.form.name = this.$gettextInterpolate(langNewName, {name: name}); '%{name} - Copy',
{name: name}
);
this.$refs.modal.show(); this.$refs.modal.show();
}, },

View File

@ -25,7 +25,7 @@
> >
<b-img <b-img
:src="src" :src="src"
:alt="langTitle" :alt="$gettext('Artwork')"
rounded rounded
fluid fluid
/> />

View File

@ -66,6 +66,7 @@ export default {
<script setup> <script setup>
import Icon from '~/components/Common/Icon'; import Icon from '~/components/Common/Icon';
import requestsPanelProps from "~/components/Stations/Profile/requestsPanelProps"; import requestsPanelProps from "~/components/Stations/Profile/requestsPanelProps";
import EnabledBadge from "~/components/Common/Badges/EnabledBadge.vue";
const props = defineProps({ const props = defineProps({
...requestsPanelProps ...requestsPanelProps

View File

@ -56,7 +56,7 @@ export default {
<script setup> <script setup>
import {DateTime} from "luxon"; import {DateTime} from "luxon";
import _ from "lodash"; import {map} from "lodash";
import {computed} from "vue"; import {computed} from "vue";
import {useAzuraCast} from "~/vendor/azuracast"; import {useAzuraCast} from "~/vendor/azuracast";
@ -76,7 +76,7 @@ const {timeConfig} = useAzuraCast();
const processedScheduleItems = computed(() => { const processedScheduleItems = computed(() => {
const now = DateTime.now().setZone(props.stationTimeZone); const now = DateTime.now().setZone(props.stationTimeZone);
return _.map(props.scheduleItems, (row) => { return map(props.scheduleItems, (row) => {
const start_moment = DateTime.fromSeconds(row.start_timestamp).setZone(props.stationTimeZone); const start_moment = DateTime.fromSeconds(row.start_timestamp).setZone(props.stationTimeZone);
const end_moment = DateTime.fromSeconds(row.end_timestamp).setZone(props.stationTimeZone); const end_moment = DateTime.fromSeconds(row.end_timestamp).setZone(props.stationTimeZone);

View File

@ -101,7 +101,7 @@ import DataTable from '~/components/Common/DataTable';
import EditModal from './Webhooks/EditModal'; import EditModal from './Webhooks/EditModal';
import Icon from '~/components/Common/Icon'; import Icon from '~/components/Common/Icon';
import InfoCard from "~/components/Common/InfoCard"; import InfoCard from "~/components/Common/InfoCard";
import _ from 'lodash'; import {get, map} from 'lodash';
import StreamingLogModal from "~/components/Common/StreamingLogModal"; import StreamingLogModal from "~/components/Common/StreamingLogModal";
export default { export default {
@ -168,11 +168,11 @@ export default {
: 'success'; : 'success';
}, },
getWebhookName(key) { getWebhookName(key) {
return _.get(this.webhookTypes, [key, 'name'], ''); return get(this.webhookTypes, [key, 'name'], '');
}, },
getTriggerNames(triggers) { getTriggerNames(triggers) {
return _.map(triggers, (trigger) => { return map(triggers, (trigger) => {
return _.get(this.langTriggerTitles, trigger, ''); return get(this.langTriggerTitles, trigger, '');
}); });
}, },
relist() { relist() {

View File

@ -44,7 +44,7 @@ import {required} from '@vuelidate/validators';
import BaseEditModal from '~/components/Common/BaseEditModal'; import BaseEditModal from '~/components/Common/BaseEditModal';
import TypeSelect from "./Form/TypeSelect"; import TypeSelect from "./Form/TypeSelect";
import BasicInfo from "./Form/BasicInfo"; import BasicInfo from "./Form/BasicInfo";
import _ from "lodash"; import {get, map} from "lodash";
import Generic from "./Form/Generic"; import Generic from "./Form/Generic";
import Email from "./Form/Email"; import Email from "./Form/Email";
import Tunein from "./Form/Tunein"; import Tunein from "./Form/Tunein";
@ -101,7 +101,7 @@ export default {
} }
if (this.type !== null) { if (this.type !== null) {
validations.form.config = _.get(this.webhookConfig, [this.type, 'validations'], {}); validations.form.config = get(this.webhookConfig, [this.type, 'validations'], {});
} }
return validations; return validations;
@ -117,8 +117,8 @@ export default {
return []; return [];
} }
let webhookKeys = _.get(this.webhookTypes, [this.type, 'triggers'], []); let webhookKeys = get(this.webhookTypes, [this.type, 'triggers'], []);
return _.map(webhookKeys, (key) => { return map(webhookKeys, (key) => {
return { return {
html: html:
'<h6 class="font-weight-bold mb-0">' + this.triggerTitles[key] + '</h6>' '<h6 class="font-weight-bold mb-0">' + this.triggerTitles[key] + '</h6>'
@ -128,10 +128,10 @@ export default {
}); });
}, },
typeTitle() { typeTitle() {
return _.get(this.webhookTypes, [this.type, 'name'], ''); return get(this.webhookTypes, [this.type, 'name'], '');
}, },
formComponent() { formComponent() {
return _.get(this.webhookConfig, [this.type, 'component'], Generic); return get(this.webhookConfig, [this.type, 'component'], Generic);
}, },
webhookConfig() { webhookConfig() {
return { return {
@ -300,62 +300,78 @@ export default {
return this.$gettext('Powered by AzuraCast'); return this.$gettext('Powered by AzuraCast');
}, },
langDiscordDefaultContent() { langDiscordDefaultContent() {
let msg = this.$gettext('Now playing on %{ station }:'); return this.$gettext(
return this.$gettextInterpolate(msg, {'station': '{{ station.name }}'}); 'Now playing on %{ station }:',
{'station': '{{ station.name }}'}
);
}, },
langTelegramDefaultContent() { langTelegramDefaultContent() {
let msg = this.$gettext('Now playing on %{ station }: %{ title } by %{ artist }! Tune in now.'); return this.$gettext(
return this.$gettextInterpolate(msg, { 'Now playing on %{ station }: %{ title } by %{ artist }! Tune in now.',
station: '{{ station.name }}', {
title: '{{ now_playing.song.title }}', station: '{{ station.name }}',
artist: '{{ now_playing.song.artist }}' title: '{{ now_playing.song.title }}',
}); artist: '{{ now_playing.song.artist }}'
}
);
}, },
langTwitterDefaultMessage() { langTwitterDefaultMessage() {
let msg = this.$gettext('Now playing on %{ station }: %{ title } by %{ artist }! Tune in now: %{ url }'); return this.$gettext(
return this.$gettextInterpolate(msg, { 'Now playing on %{ station }: %{ title } by %{ artist }! Tune in now: %{ url }',
station: '{{ station.name }}', {
title: '{{ now_playing.song.title }}', station: '{{ station.name }}',
artist: '{{ now_playing.song.artist }}', title: '{{ now_playing.song.title }}',
url: '{{ station.public_player_url }}' artist: '{{ now_playing.song.artist }}',
}); url: '{{ station.public_player_url }}'
}
);
}, },
langTwitterSongChangedLiveMessage() { langTwitterSongChangedLiveMessage() {
let msg = this.$gettext('Now playing on %{ station }: %{ title } by %{ artist } with your host, %{ dj }! Tune in now: %{ url }'); return this.$gettext(
return this.$gettextInterpolate(msg, { 'Now playing on %{ station }: %{ title } by %{ artist } with your host, %{ dj }! Tune in now: %{ url }',
station: '{{ station.name }}', {
title: '{{ now_playing.song.title }}', station: '{{ station.name }}',
artist: '{{ now_playing.song.artist }}', title: '{{ now_playing.song.title }}',
dj: '{{ live.streamer_name }}', artist: '{{ now_playing.song.artist }}',
url: '{{ station.public_player_url }}' dj: '{{ live.streamer_name }}',
}); url: '{{ station.public_player_url }}'
}
);
}, },
langTwitterDjOnMessage() { langTwitterDjOnMessage() {
let msg = this.$gettext('%{ dj } is now live on %{ station }! Tune in now: %{ url }'); return this.$gettext(
return this.$gettextInterpolate(msg, { '%{ dj } is now live on %{ station }! Tune in now: %{ url }',
dj: '{{ live.streamer_name }}', {
station: '{{ station.name }}', dj: '{{ live.streamer_name }}',
url: '{{ station.public_player_url }}' station: '{{ station.name }}',
}); url: '{{ station.public_player_url }}'
}
);
}, },
langTwitterDjOffMessage() { langTwitterDjOffMessage() {
let msg = this.$gettext('Thanks for listening to %{ station }!'); return this.$gettext(
return this.$gettextInterpolate(msg, { 'Thanks for listening to %{ station }!',
station: '{{ station.name }}', {
}); station: '{{ station.name }}',
}
);
}, },
langTwitterStationOfflineMessage() { langTwitterStationOfflineMessage() {
let msg = this.$gettext('%{ station } is going offline for now.'); return this.$gettext(
return this.$gettextInterpolate(msg, { '%{ station } is going offline for now.',
station: '{{ station.name }}' {
}); station: '{{ station.name }}'
}
);
}, },
langTwitterStationOnlineMessage() { langTwitterStationOnlineMessage() {
let msg = this.$gettext('%{ station } is back online! Tune in now: %{ url }'); return this.$gettext(
return this.$gettextInterpolate(msg, { '%{ station } is back online! Tune in now: %{ url }',
station: '{{ station.name }}', {
url: '{{ station.public_player_url }}' station: '{{ station.name }}',
}); url: '{{ station.public_player_url }}'
}
);
} }
}, },
methods: { methods: {
@ -369,7 +385,7 @@ export default {
}, },
setType(type) { setType(type) {
this.type = type; this.type = type;
this.form.config = _.get(this.webhookConfig, [type, 'defaultConfig'], {}); this.form.config = get(this.webhookConfig, [type, 'defaultConfig'], {});
}, },
getSubmittableFormData() { getSubmittableFormData() {
let formData = this.form; let formData = this.form;

View File

@ -84,7 +84,7 @@
<script> <script>
import BWrappedFormGroup from "~/components/Form/BWrappedFormGroup"; import BWrappedFormGroup from "~/components/Form/BWrappedFormGroup";
import CommonFormattingInfo from "./FormattingInfo"; import CommonFormattingInfo from "./FormattingInfo";
import _ from 'lodash'; import {includes} from 'lodash';
export default { export default {
name: 'CommonSocialPostFields', name: 'CommonSocialPostFields',
@ -101,7 +101,7 @@ export default {
}, },
methods: { methods: {
hasTrigger(trigger) { hasTrigger(trigger) {
return _.includes(this.form.triggers.$model, trigger); return includes(this.form.triggers.$model, trigger);
} }
} }
} }