Move redundant datetime formatting code into a unified station-timezone-aware composable.
This commit is contained in:
parent
87e7802d01
commit
f6b998a17b
|
@ -151,7 +151,7 @@
|
|||
|
||||
<script setup lang="ts">
|
||||
import Icon from "~/components/Common/Icon.vue";
|
||||
import DataTable, { DataTableField } from "~/components/Common/DataTable.vue";
|
||||
import DataTable, {DataTableField} from "~/components/Common/DataTable.vue";
|
||||
import AdminBackupsLastOutputModal from "./Backups/LastOutputModal.vue";
|
||||
import formatFileSize from "~/functions/formatFileSize";
|
||||
import AdminBackupsConfigureModal from "~/components/Admin/Backups/ConfigureModal.vue";
|
||||
|
@ -196,7 +196,7 @@ const settings = ref({...blankSettings});
|
|||
|
||||
const {$gettext} = useTranslate();
|
||||
const {timeConfig} = useAzuraCast();
|
||||
const {DateTime} = useLuxon();
|
||||
const {DateTime, timestampToRelative} = useLuxon();
|
||||
|
||||
const fields: DataTableField[] = [
|
||||
{
|
||||
|
@ -250,8 +250,6 @@ const relist = () => {
|
|||
|
||||
onMounted(relist);
|
||||
|
||||
const {timestampToRelative} = useLuxon();
|
||||
|
||||
const $lastOutputModal = ref<InstanceType<typeof AdminBackupsLastOutputModal> | null>(null);
|
||||
const showLastOutput = () => {
|
||||
$lastOutputModal.value?.show();
|
||||
|
|
|
@ -96,13 +96,13 @@
|
|||
v-if="item.publish_at"
|
||||
class="badge text-bg-secondary"
|
||||
>
|
||||
{{ formatTime(item.publish_at) }}
|
||||
{{ formatTimestampAsDateTime(item.publish_at) }}
|
||||
</span>
|
||||
<span
|
||||
v-else
|
||||
class="badge text-bg-secondary"
|
||||
>
|
||||
{{ formatTime(item.created_at) }}
|
||||
{{ formatTimestampAsDateTime(item.created_at) }}
|
||||
</span>
|
||||
<span
|
||||
v-if="item.explicit"
|
||||
|
@ -141,8 +141,7 @@ import {useTranslate} from "~/vendor/gettext.ts";
|
|||
import {IconRss} from "~/components/Common/icons.ts";
|
||||
import Icon from "~/components/Common/Icon.vue";
|
||||
import PlayButton from "~/components/Common/PlayButton.vue";
|
||||
import {useLuxon} from "~/vendor/luxon.ts";
|
||||
import {useAzuraCast, useAzuraCastStation} from "~/vendor/azuracast.ts";
|
||||
import useStationDateTimeFormatter from "~/functions/useStationDateTimeFormatter.ts";
|
||||
|
||||
const {params} = useRoute();
|
||||
|
||||
|
@ -164,17 +163,5 @@ const fields: DataTableField[] = [
|
|||
{key: 'actions', label: $gettext('Actions'), sortable: false, class: 'shrink'}
|
||||
];
|
||||
|
||||
const {DateTime} = useLuxon();
|
||||
const {timezone} = useAzuraCastStation();
|
||||
const {timeConfig} = useAzuraCast();
|
||||
|
||||
const formatTime = (value) => {
|
||||
if (!value) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return DateTime.fromSeconds(value).setZone(timezone).toLocaleString(
|
||||
{...DateTime.DATETIME_MED, ...timeConfig}
|
||||
);
|
||||
};
|
||||
const {formatTimestampAsDateTime} = useStationDateTimeFormatter();
|
||||
</script>
|
||||
|
|
|
@ -84,13 +84,13 @@
|
|||
v-if="episode.publish_at"
|
||||
class="badge text-bg-secondary"
|
||||
>
|
||||
{{ formatTime(episode.publish_at) }}
|
||||
{{ formatTimestampAsDateTime(episode.publish_at) }}
|
||||
</span>
|
||||
<span
|
||||
v-else
|
||||
class="badge text-bg-secondary"
|
||||
>
|
||||
{{ formatTime(episode.created_at) }}
|
||||
{{ formatTimestampAsDateTime(episode.created_at) }}
|
||||
</span>
|
||||
<span
|
||||
v-if="episode.explicit"
|
||||
|
@ -123,8 +123,7 @@ import {useAxios} from "~/vendor/axios.ts";
|
|||
import useRefreshableAsyncState from "~/functions/useRefreshableAsyncState.ts";
|
||||
import AlbumArt from "~/components/Common/AlbumArt.vue";
|
||||
import PlayButton from "~/components/Common/PlayButton.vue";
|
||||
import {useLuxon} from "~/vendor/luxon.ts";
|
||||
import {useAzuraCast, useAzuraCastStation} from "~/vendor/azuracast.ts";
|
||||
import useStationDateTimeFormatter from "~/functions/useStationDateTimeFormatter.ts";
|
||||
|
||||
const {params} = useRoute();
|
||||
|
||||
|
@ -143,17 +142,5 @@ const {state: episode, isLoading: episodeLoading} = useRefreshableAsyncState(
|
|||
{},
|
||||
);
|
||||
|
||||
const {DateTime} = useLuxon();
|
||||
const {timezone} = useAzuraCastStation();
|
||||
const {timeConfig} = useAzuraCast();
|
||||
|
||||
const formatTime = (value) => {
|
||||
if (!value) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return DateTime.fromSeconds(value).setZone(timezone).toLocaleString(
|
||||
{...DateTime.DATETIME_MED, ...timeConfig}
|
||||
);
|
||||
};
|
||||
const {formatTimestampAsDateTime} = useStationDateTimeFormatter();
|
||||
</script>
|
||||
|
|
|
@ -241,7 +241,7 @@
|
|||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import DataTable, { DataTableField } from '~/components/Common/DataTable.vue';
|
||||
import DataTable, {DataTableField} from '~/components/Common/DataTable.vue';
|
||||
import MediaToolbar from './Media/MediaToolbar.vue';
|
||||
import Breadcrumb from './Media/Breadcrumb.vue';
|
||||
import FileUpload from './Media/FileUpload.vue';
|
||||
|
@ -256,14 +256,13 @@ import PlayButton from "~/components/Common/PlayButton.vue";
|
|||
import {useTranslate} from "~/vendor/gettext";
|
||||
import {computed, ref, watch} from "vue";
|
||||
import {forEach, map, partition} from "lodash";
|
||||
import {useAzuraCast, useAzuraCastStation} from "~/vendor/azuracast";
|
||||
import formatFileSize from "../../functions/formatFileSize";
|
||||
import InfoCard from "~/components/Common/InfoCard.vue";
|
||||
import {useLuxon} from "~/vendor/luxon";
|
||||
import {getStationApiUrl} from "~/router";
|
||||
import {useRoute, useRouter} from "vue-router";
|
||||
import {IconFile, IconFolder, IconImage} from "~/components/Common/icons";
|
||||
import {DataTableTemplateRef} from "~/functions/useHasDatatable.ts";
|
||||
import useStationDateTimeFormatter from "~/functions/useStationDateTimeFormatter.ts";
|
||||
|
||||
const props = defineProps({
|
||||
initialPlaylists: {
|
||||
|
@ -300,9 +299,8 @@ const renameUrl = getStationApiUrl('/files/rename');
|
|||
const quotaUrl = getStationApiUrl('/quota/station_media');
|
||||
|
||||
const {$gettext} = useTranslate();
|
||||
const {timeConfig} = useAzuraCast();
|
||||
const {timezone} = useAzuraCastStation();
|
||||
const {DateTime} = useLuxon();
|
||||
|
||||
const {formatTimestampAsDateTime} = useStationDateTimeFormatter();
|
||||
|
||||
const fields = computed<DataTableField[]>(() => {
|
||||
const fields: DataTableField[] = [
|
||||
|
@ -337,15 +335,7 @@ const fields = computed<DataTableField[]>(() => {
|
|||
key: 'timestamp',
|
||||
label: $gettext('Modified'),
|
||||
sortable: true,
|
||||
formatter: (value) => {
|
||||
if (!value) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return DateTime.fromSeconds(value).setZone(timezone).toLocaleString(
|
||||
{...DateTime.DATETIME_MED, ...timeConfig}
|
||||
);
|
||||
},
|
||||
formatter: (value) => formatTimestampAsDateTime(value),
|
||||
selectable: true,
|
||||
visible: true
|
||||
},
|
||||
|
|
|
@ -45,9 +45,8 @@
|
|||
<script setup lang="ts">
|
||||
import {map} from "lodash";
|
||||
import {computed} from "vue";
|
||||
import {useAzuraCast, useAzuraCastStation} from "~/vendor/azuracast";
|
||||
import CardPage from "~/components/Common/CardPage.vue";
|
||||
import {useLuxon} from "~/vendor/luxon";
|
||||
import useStationDateTimeFormatter from "~/functions/useStationDateTimeFormatter.ts";
|
||||
|
||||
const props = defineProps({
|
||||
scheduleItems: {
|
||||
|
@ -56,39 +55,35 @@ const props = defineProps({
|
|||
}
|
||||
});
|
||||
|
||||
const {timeConfig} = useAzuraCast();
|
||||
const {timezone} = useAzuraCastStation();
|
||||
|
||||
const {DateTime} = useLuxon();
|
||||
const {
|
||||
DateTime,
|
||||
now,
|
||||
timestampToDateTime,
|
||||
formatDateTime
|
||||
} = useStationDateTimeFormatter();
|
||||
|
||||
const processedScheduleItems = computed(() => {
|
||||
const now = DateTime.now().setZone(timezone);
|
||||
const nowTz = now();
|
||||
|
||||
return map(props.scheduleItems, (row) => {
|
||||
const start_moment = DateTime.fromSeconds(row.start_timestamp).setZone(timezone);
|
||||
const end_moment = DateTime.fromSeconds(row.end_timestamp).setZone(timezone);
|
||||
const startMoment = timestampToDateTime(row.start_timestamp);
|
||||
const endMoment = timestampToDateTime(row.end_timestamp);
|
||||
|
||||
row.time_until = start_moment.toRelative();
|
||||
row.time_until = startMoment.toRelative();
|
||||
|
||||
if (start_moment.hasSame(now, 'day')) {
|
||||
row.start_formatted = start_moment.toLocaleString(
|
||||
{...DateTime.TIME_SIMPLE, ...timeConfig}
|
||||
);
|
||||
} else {
|
||||
row.start_formatted = start_moment.toLocaleString(
|
||||
{...DateTime.DATETIME_MED, ...timeConfig}
|
||||
);
|
||||
}
|
||||
row.start_formatted = formatDateTime(
|
||||
startMoment,
|
||||
startMoment.hasSame(nowTz, 'day')
|
||||
? DateTime.TIME_SIMPLE
|
||||
: DateTime.DATETIME_MED
|
||||
);
|
||||
|
||||
if (end_moment.hasSame(start_moment, 'day')) {
|
||||
row.end_formatted = end_moment.toLocaleString(
|
||||
{...DateTime.TIME_SIMPLE, ...timeConfig}
|
||||
);
|
||||
} else {
|
||||
row.end_formatted = end_moment.toLocaleString(
|
||||
{...DateTime.DATETIME_MED, ...timeConfig}
|
||||
);
|
||||
}
|
||||
row.end_formatted = formatDateTime(
|
||||
endMoment,
|
||||
endMoment.hasSame(startMoment, 'day')
|
||||
? DateTime.TIME_SIMPLE
|
||||
: DateTime.DATETIME_MED
|
||||
);
|
||||
|
||||
return row;
|
||||
});
|
||||
|
|
|
@ -53,8 +53,8 @@
|
|||
</div>
|
||||
</template>
|
||||
<template #cell(played_at)="row">
|
||||
{{ formatTime(row.item.played_at) }}<br>
|
||||
<small>{{ formatRelativeTime(row.item.played_at) }}</small>
|
||||
{{ formatTimestampAsTime(row.item.played_at) }}<br>
|
||||
<small>{{ formatTimestampAsRelative(row.item.played_at) }}</small>
|
||||
</template>
|
||||
<template #cell(source)="row">
|
||||
<div v-if="row.item.is_request">
|
||||
|
@ -74,7 +74,6 @@
|
|||
import DataTable, {DataTableField} from '../Common/DataTable.vue';
|
||||
import QueueLogsModal from './Queue/LogsModal.vue';
|
||||
import Icon from "~/components/Common/Icon.vue";
|
||||
import {useAzuraCast, useAzuraCastStation} from "~/vendor/azuracast";
|
||||
import {useTranslate} from "~/vendor/gettext";
|
||||
import {computed, ref} from "vue";
|
||||
import useConfirmAndDelete from "~/functions/useConfirmAndDelete";
|
||||
|
@ -83,10 +82,10 @@ import {useNotify} from "~/functions/useNotify";
|
|||
import {useAxios} from "~/vendor/axios";
|
||||
import {useSweetAlert} from "~/vendor/sweetalert";
|
||||
import CardPage from "~/components/Common/CardPage.vue";
|
||||
import {useLuxon} from "~/vendor/luxon";
|
||||
import {getStationApiUrl} from "~/router";
|
||||
import {IconRemove} from "~/components/Common/icons";
|
||||
import {useIntervalFn} from "@vueuse/core";
|
||||
import useStationDateTimeFormatter from "~/functions/useStationDateTimeFormatter.ts";
|
||||
|
||||
const listUrl = getStationApiUrl('/queue');
|
||||
const clearUrl = getStationApiUrl('/queue/clear');
|
||||
|
@ -100,20 +99,10 @@ const fields: DataTableField[] = [
|
|||
{key: 'source', label: $gettext('Source'), sortable: false}
|
||||
];
|
||||
|
||||
const {timezone} = useAzuraCastStation();
|
||||
|
||||
const {DateTime} = useLuxon();
|
||||
|
||||
const getDateTime = (timestamp) =>
|
||||
DateTime.fromSeconds(timestamp).setZone(timezone);
|
||||
|
||||
const {timeConfig} = useAzuraCast();
|
||||
|
||||
const formatTime = (time) => getDateTime(time).toLocaleString(
|
||||
{...DateTime.TIME_WITH_SECONDS, ...timeConfig}
|
||||
);
|
||||
|
||||
const formatRelativeTime = (time) => getDateTime(time).toRelative();
|
||||
const {
|
||||
formatTimestampAsTime,
|
||||
formatTimestampAsRelative
|
||||
} = useStationDateTimeFormatter();
|
||||
|
||||
const $datatable = ref<DataTableTemplateRef>(null);
|
||||
const {relist} = useHasDatatable($datatable);
|
||||
|
|
|
@ -191,8 +191,6 @@ import DateRangeDropdown from "~/components/Common/DateRangeDropdown.vue";
|
|||
import {computed, ComputedRef, nextTick, onMounted, Ref, ref, ShallowRef, shallowRef, watch} from "vue";
|
||||
import {useTranslate} from "~/vendor/gettext";
|
||||
import {useAxios} from "~/vendor/axios";
|
||||
import {useAzuraCast, useAzuraCastStation} from "~/vendor/azuracast";
|
||||
import {useLuxon} from "~/vendor/luxon";
|
||||
import {getStationApiUrl} from "~/router";
|
||||
import {IconDesktopWindows, IconDownload, IconRouter, IconSmartphone} from "~/components/Common/icons";
|
||||
import useHasDatatable, {DataTableTemplateRef} from "~/functions/useHasDatatable";
|
||||
|
@ -201,6 +199,7 @@ import {filter} from "lodash";
|
|||
import formatTime from "~/functions/formatTime.ts";
|
||||
import ListenerFiltersBar from "./Listeners/FiltersBar.vue";
|
||||
import {ApiListener} from "~/entities/ApiInterfaces.ts";
|
||||
import useStationDateTimeFormatter from "~/functions/useStationDateTimeFormatter.ts";
|
||||
|
||||
const props = defineProps({
|
||||
attribution: {
|
||||
|
@ -214,11 +213,13 @@ const apiUrl = getStationApiUrl('/listeners');
|
|||
const isLive = ref<boolean>(true);
|
||||
const listeners: ShallowRef<ApiListener[]> = shallowRef([]);
|
||||
|
||||
const {timezone} = useAzuraCastStation();
|
||||
const {timeConfig} = useAzuraCast();
|
||||
const {
|
||||
DateTime,
|
||||
now,
|
||||
formatTimestampAsDateTime
|
||||
} = useStationDateTimeFormatter();
|
||||
|
||||
const {DateTime} = useLuxon();
|
||||
const nowTz = DateTime.now().setZone(timezone);
|
||||
const nowTz = now();
|
||||
|
||||
const minDate = nowTz.minus({years: 5}).toJSDate();
|
||||
const maxDate = nowTz.plus({days: 5}).toJSDate();
|
||||
|
@ -266,14 +267,10 @@ const fields: DataTableField[] = [
|
|||
key: 'connected_on',
|
||||
label: $gettext('Start Time'),
|
||||
sortable: true,
|
||||
formatter: (_col, _key, item) => {
|
||||
return DateTime.fromSeconds(
|
||||
item.connected_on,
|
||||
{zone: timezone}
|
||||
).toLocaleString(
|
||||
{...DateTime.DATETIME_SHORT, ...timeConfig}
|
||||
);
|
||||
},
|
||||
formatter: (_col, _key, item) => formatTimestampAsDateTime(
|
||||
item.connected_on,
|
||||
DateTime.DATETIME_SHORT
|
||||
),
|
||||
selectable: true,
|
||||
visible: false
|
||||
},
|
||||
|
@ -281,14 +278,10 @@ const fields: DataTableField[] = [
|
|||
key: 'connected_until',
|
||||
label: $gettext('End Time'),
|
||||
sortable: true,
|
||||
formatter: (_col, _key, item) => {
|
||||
return DateTime.fromSeconds(
|
||||
item.connected_until,
|
||||
{zone: timezone}
|
||||
).toLocaleString(
|
||||
{...DateTime.DATETIME_SHORT, ...timeConfig}
|
||||
);
|
||||
},
|
||||
formatter: (_col, _key, item) => formatTimestampAsDateTime(
|
||||
item.connected_until,
|
||||
DateTime.DATETIME_SHORT
|
||||
),
|
||||
selectable: true,
|
||||
visible: false
|
||||
},
|
||||
|
|
|
@ -92,11 +92,10 @@ import StreamsTab from "./Overview/StreamsTab.vue";
|
|||
import ClientsTab from "./Overview/ClientsTab.vue";
|
||||
import ListeningTimeTab from "~/components/Stations/Reports/Overview/ListeningTimeTab.vue";
|
||||
import {ref} from "vue";
|
||||
import {useAzuraCastStation} from "~/vendor/azuracast";
|
||||
import {useLuxon} from "~/vendor/luxon";
|
||||
import {getStationApiUrl} from "~/router";
|
||||
import Tabs from "~/components/Common/Tabs.vue";
|
||||
import Tab from "~/components/Common/Tab.vue";
|
||||
import useStationDateTimeFormatter from "~/functions/useStationDateTimeFormatter.ts";
|
||||
|
||||
const props = defineProps({
|
||||
showFullAnalytics: {
|
||||
|
@ -113,11 +112,9 @@ const byCountryUrl = getStationApiUrl('/reports/overview/by-country');
|
|||
const byClientUrl = getStationApiUrl('/reports/overview/by-client');
|
||||
const listeningTimeUrl = getStationApiUrl('/reports/overview/by-listening-time');
|
||||
|
||||
const {timezone} = useAzuraCastStation();
|
||||
const {DateTime} = useLuxon();
|
||||
|
||||
const nowTz = DateTime.now().setZone(timezone);
|
||||
const {now} = useStationDateTimeFormatter();
|
||||
|
||||
const nowTz = now();
|
||||
const dateRange = ref({
|
||||
startDate: nowTz.minus({days: 13}).toJSDate(),
|
||||
endDate: nowTz.toJSDate(),
|
||||
|
|
|
@ -56,14 +56,14 @@
|
|||
:api-url="listUrlForType"
|
||||
>
|
||||
<template #cell(timestamp)="row">
|
||||
{{ formatTime(row.item.timestamp) }}
|
||||
{{ formatTimestampAsDateTime(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) }}
|
||||
{{ formatTimestampAsDateTime(row.item.played_at) }}
|
||||
</span>
|
||||
</template>
|
||||
<template #cell(song_title)="row">
|
||||
|
@ -93,18 +93,17 @@
|
|||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import DataTable, { DataTableField } from '~/components/Common/DataTable.vue';
|
||||
import DataTable, {DataTableField} from '~/components/Common/DataTable.vue';
|
||||
import Icon from "~/components/Common/Icon.vue";
|
||||
import {useAzuraCast, useAzuraCastStation} from "~/vendor/azuracast";
|
||||
import {computed, nextTick, ref} from "vue";
|
||||
import {useTranslate} from "~/vendor/gettext";
|
||||
import {useSweetAlert} from "~/vendor/sweetalert";
|
||||
import {useNotify} from "~/functions/useNotify";
|
||||
import {useAxios} from "~/vendor/axios";
|
||||
import {useLuxon} from "~/vendor/luxon";
|
||||
import {getStationApiUrl} from "~/router";
|
||||
import {IconRemove} from "~/components/Common/icons";
|
||||
import {DataTableTemplateRef} from "~/functions/useHasDatatable.ts";
|
||||
import useStationDateTimeFormatter from "~/functions/useStationDateTimeFormatter.ts";
|
||||
|
||||
const listUrl = getStationApiUrl('/reports/requests');
|
||||
const clearUrl = getStationApiUrl('/reports/requests/clear');
|
||||
|
@ -147,16 +146,7 @@ const setType = (type) => {
|
|||
nextTick(relist);
|
||||
};
|
||||
|
||||
const {timeConfig} = useAzuraCast();
|
||||
const {timezone} = useAzuraCastStation();
|
||||
|
||||
const {DateTime} = useLuxon();
|
||||
|
||||
const formatTime = (time) => {
|
||||
return DateTime.fromSeconds(time).setZone(timezone).toLocaleString(
|
||||
{...DateTime.DATETIME_MED, ...timeConfig}
|
||||
);
|
||||
};
|
||||
const {formatTimestampAsDateTime} = useStationDateTimeFormatter();
|
||||
|
||||
const {confirmDelete} = useSweetAlert();
|
||||
const {notifySuccess} = useNotify();
|
||||
|
|
|
@ -114,16 +114,14 @@ import FormFieldset from "~/components/Form/FormFieldset.vue";
|
|||
import FormGroupCheckbox from "~/components/Form/FormGroupCheckbox.vue";
|
||||
import {useVuelidateOnForm} from "~/functions/useVuelidateOnForm";
|
||||
import {getStationApiUrl} from "~/router";
|
||||
import {useLuxon} from "~/vendor/luxon";
|
||||
import {useAzuraCastStation} from "~/vendor/azuracast";
|
||||
import CardPage from "~/components/Common/CardPage.vue";
|
||||
import useStationDateTimeFormatter from "~/functions/useStationDateTimeFormatter.ts";
|
||||
|
||||
const apiUrl = getStationApiUrl('/reports/soundexchange');
|
||||
|
||||
const {DateTime} = useLuxon();
|
||||
const {timezone} = useAzuraCastStation();
|
||||
const {now} = useStationDateTimeFormatter();
|
||||
|
||||
const lastMonth = DateTime.now().setZone(timezone).minus({months: 1});
|
||||
const lastMonth = now().minus({months: 1});
|
||||
|
||||
const {v$} = useVuelidateOnForm(
|
||||
{
|
||||
|
|
|
@ -86,22 +86,20 @@
|
|||
|
||||
<script setup lang="ts">
|
||||
import Icon from "~/components/Common/Icon.vue";
|
||||
import DataTable, { DataTableField } from "~/components/Common/DataTable.vue";
|
||||
import DataTable, {DataTableField} from "~/components/Common/DataTable.vue";
|
||||
import DateRangeDropdown from "~/components/Common/DateRangeDropdown.vue";
|
||||
import {useAzuraCast, useAzuraCastStation} from "~/vendor/azuracast";
|
||||
import {useAzuraCast} from "~/vendor/azuracast";
|
||||
import {computed, ref, watch} from "vue";
|
||||
import {useTranslate} from "~/vendor/gettext";
|
||||
import {useLuxon} from "~/vendor/luxon";
|
||||
import {getStationApiUrl} from "~/router";
|
||||
import {IconDownload, IconTrendingDown, IconTrendingUp} from "~/components/Common/icons";
|
||||
import useHasDatatable, {DataTableTemplateRef} from "~/functions/useHasDatatable.ts";
|
||||
import useStationDateTimeFormatter from "~/functions/useStationDateTimeFormatter.ts";
|
||||
|
||||
const baseApiUrl = getStationApiUrl('/history');
|
||||
|
||||
const {timezone} = useAzuraCastStation();
|
||||
const {DateTime} = useLuxon();
|
||||
|
||||
const nowTz = DateTime.now().setZone(timezone);
|
||||
const {now} = useStationDateTimeFormatter();
|
||||
const nowTz = now();
|
||||
|
||||
const dateRange = ref(
|
||||
{
|
||||
|
|
|
@ -64,14 +64,14 @@
|
|||
import {ref} from "vue";
|
||||
import Icon from "~/components/Common/Icon.vue";
|
||||
import SidebarMenu from "~/components/Common/SidebarMenu.vue";
|
||||
import {useAzuraCast, useAzuraCastStation} from "~/vendor/azuracast";
|
||||
import {useAzuraCastStation} from "~/vendor/azuracast";
|
||||
import {useEventBus, useIntervalFn} from "@vueuse/core";
|
||||
import {useStationsMenu} from "~/components/Stations/menu";
|
||||
import {StationPermission, userAllowedForStation} from "~/acl";
|
||||
import {useAxios} from "~/vendor/axios.ts";
|
||||
import {getStationApiUrl} from "~/router.ts";
|
||||
import {useLuxon} from "~/vendor/luxon.ts";
|
||||
import {IconEdit} from "~/components/Common/icons.ts";
|
||||
import useStationDateTimeFormatter from "~/functions/useStationDateTimeFormatter.ts";
|
||||
|
||||
const props = defineProps({
|
||||
station: {
|
||||
|
@ -82,17 +82,13 @@ const props = defineProps({
|
|||
|
||||
const menuItems = useStationsMenu();
|
||||
|
||||
const {timeConfig} = useAzuraCast();
|
||||
const {name, timezone} = useAzuraCastStation();
|
||||
const {DateTime} = useLuxon();
|
||||
const {name} = useAzuraCastStation();
|
||||
const {DateTime, formatNowAsTime} = useStationDateTimeFormatter();
|
||||
|
||||
const clock = ref('');
|
||||
|
||||
useIntervalFn(() => {
|
||||
clock.value = DateTime.now().setZone(timezone).toLocaleString({
|
||||
...DateTime.TIME_WITH_SHORT_OFFSET,
|
||||
...timeConfig
|
||||
})
|
||||
clock.value = formatNowAsTime(DateTime.TIME_WITH_SHORT_OFFSET);
|
||||
}, 1000, {
|
||||
immediate: true,
|
||||
immediateCallback: true
|
||||
|
|
|
@ -63,24 +63,23 @@ import InlinePlayer from '~/components/InlinePlayer.vue';
|
|||
import Icon from '~/components/Common/Icon.vue';
|
||||
import PlayButton from "~/components/Common/PlayButton.vue";
|
||||
import '~/vendor/sweetalert';
|
||||
import {useAzuraCast} from "~/vendor/azuracast";
|
||||
import {ref} from "vue";
|
||||
import {useTranslate} from "~/vendor/gettext";
|
||||
import {useSweetAlert} from "~/vendor/sweetalert";
|
||||
import {useNotify} from "~/functions/useNotify";
|
||||
import {useAxios} from "~/vendor/axios";
|
||||
import Modal from "~/components/Common/Modal.vue";
|
||||
import {useLuxon} from "~/vendor/luxon";
|
||||
import {IconDownload} from "~/components/Common/icons";
|
||||
import {DataTableTemplateRef} from "~/functions/useHasDatatable.ts";
|
||||
import {ModalTemplateRef, useHasModal} from "~/functions/useHasModal.ts";
|
||||
import {usePlayerStore, useProvidePlayerStore} from "~/functions/usePlayerStore.ts";
|
||||
import useStationDateTimeFormatter from "~/functions/useStationDateTimeFormatter.ts";
|
||||
|
||||
const listUrl = ref(null);
|
||||
|
||||
const {$gettext} = useTranslate();
|
||||
const {timeConfig} = useAzuraCast();
|
||||
const {DateTime} = useLuxon();
|
||||
|
||||
const {formatTimestampAsDateTime} = useStationDateTimeFormatter();
|
||||
|
||||
const fields: DataTableField[] = [
|
||||
{
|
||||
|
@ -93,11 +92,7 @@ const fields: DataTableField[] = [
|
|||
key: 'timestampStart',
|
||||
label: $gettext('Start Time'),
|
||||
sortable: false,
|
||||
formatter: (value) => {
|
||||
return DateTime.fromSeconds(value).toLocaleString(
|
||||
{...DateTime.DATETIME_MED, ...timeConfig}
|
||||
);
|
||||
},
|
||||
formatter: (value) => formatTimestampAsDateTime(value),
|
||||
class: 'ps-3'
|
||||
},
|
||||
{
|
||||
|
@ -105,13 +100,9 @@ const fields: DataTableField[] = [
|
|||
label: $gettext('End Time'),
|
||||
sortable: false,
|
||||
formatter: (value) => {
|
||||
if (value === 0) {
|
||||
return $gettext('Live');
|
||||
}
|
||||
|
||||
return DateTime.fromSeconds(value).toLocaleString(
|
||||
{...DateTime.DATETIME_MED, ...timeConfig}
|
||||
);
|
||||
return value === 0
|
||||
? $gettext('Live')
|
||||
: formatTimestampAsDateTime(value);
|
||||
}
|
||||
},
|
||||
{
|
||||
|
|
|
@ -0,0 +1,81 @@
|
|||
import {useLuxon} from "~/vendor/luxon.ts";
|
||||
import {useAzuraCast, useAzuraCastStation} from "~/vendor/azuracast.ts";
|
||||
import {DateTimeMaybeValid} from "luxon";
|
||||
|
||||
export default function useStationDateTimeFormatter() {
|
||||
const {DateTime, Duration} = useLuxon();
|
||||
const {timeConfig} = useAzuraCast();
|
||||
const {timezone} = useAzuraCastStation();
|
||||
|
||||
const timestampToDateTime = (value): DateTimeMaybeValid =>
|
||||
DateTime.fromSeconds(value).setZone(timezone);
|
||||
|
||||
const now = (): DateTimeMaybeValid =>
|
||||
DateTime.now().setZone(timezone);
|
||||
|
||||
const formatDateTime = (
|
||||
value: DateTimeMaybeValid,
|
||||
format: Intl.DateTimeFormatOptions
|
||||
) => value.toLocaleString(
|
||||
{...format, ...timeConfig}
|
||||
);
|
||||
|
||||
const formatDateTimeAsDateTime = (
|
||||
value: DateTimeMaybeValid,
|
||||
format: Intl.DateTimeFormatOptions | null = null
|
||||
) => formatDateTime(value, format ?? DateTime.DATETIME_MED);
|
||||
|
||||
const formatDateTimeAsTime = (
|
||||
value: DateTimeMaybeValid,
|
||||
format: Intl.DateTimeFormatOptions | null = null
|
||||
) => formatDateTime(value, format ?? DateTime.TIME_WITH_SECONDS);
|
||||
|
||||
const formatDateTimeAsRelative = (
|
||||
value: DateTimeMaybeValid
|
||||
) => value.toRelative();
|
||||
|
||||
const formatTimestampAsDateTime = (
|
||||
value: any,
|
||||
format: Intl.DateTimeFormatOptions | null = null
|
||||
) =>
|
||||
(value)
|
||||
? formatDateTimeAsDateTime(timestampToDateTime(value), format)
|
||||
: ''
|
||||
|
||||
const formatTimestampAsTime = (
|
||||
value: any,
|
||||
format: Intl.DateTimeFormatOptions | null = null
|
||||
) =>
|
||||
(value)
|
||||
? formatDateTimeAsTime(timestampToDateTime(value), format)
|
||||
: ''
|
||||
|
||||
const formatTimestampAsRelative = (value) =>
|
||||
(value)
|
||||
? formatDateTimeAsRelative(timestampToDateTime(value))
|
||||
: '';
|
||||
|
||||
const formatNowAsDateTime = (
|
||||
format: Intl.DateTimeFormatOptions | null = null
|
||||
) => formatDateTimeAsDateTime(now(), format);
|
||||
|
||||
const formatNowAsTime = (
|
||||
format: Intl.DateTimeFormatOptions | null = null
|
||||
) => formatDateTimeAsTime(now(), format);
|
||||
|
||||
return {
|
||||
DateTime,
|
||||
Duration,
|
||||
timestampToDateTime,
|
||||
now,
|
||||
formatDateTime,
|
||||
formatDateTimeAsDateTime,
|
||||
formatDateTimeAsTime,
|
||||
formatDateTimeAsRelative,
|
||||
formatTimestampAsDateTime,
|
||||
formatTimestampAsTime,
|
||||
formatTimestampAsRelative,
|
||||
formatNowAsDateTime,
|
||||
formatNowAsTime
|
||||
};
|
||||
}
|
Loading…
Reference in New Issue