Newer
Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
import { RouteLocationNormalizedLoaded, RouteParams, RouteRecordName, useRoute } from 'vue-router'
import { useShowStore } from '@/stores/shows'
import { useI18n } from '@/i18n'
import { useTimeSlotStore } from '@/stores/timeslots'
import { parseISO } from 'date-fns'
import { ref, shallowReadonly, watch } from 'vue'
type Route = {
name: RouteRecordName
params?: RouteParams
}
type MenuItem = {
title: string
route: Route
requiresAdmin?: boolean
}
export type MenuItemCollection = {
title: string
items: MenuItem[]
}
type MenuItemCollectionGenerator = (
route: RouteLocationNormalizedLoaded,
) => AsyncGenerator<MenuItemCollection, void, unknown>
async function* getMainNavigation() {
const { t } = useI18n()
yield {
title: t('navigation'),
items: [
{
title: t('navigation.shows'),
route: { name: 'shows' },
},
{
title: t('navigation.filesPlaylists'),
route: { name: 'files' },
},
{
title: t('navigation.calendar'),
route: { name: 'calendar' },
},
],
}
}
async function* getEpisodeContextMenu(route: RouteLocationNormalizedLoaded) {
if (!route.params.episodeId) return
const episodeId = parseInt(route.params.episodeId as string)
const timeslotStore = useTimeSlotStore()
const timeslot = await timeslotStore.retrieve(episodeId, { useCached: true })
if (!timeslot) return
const { t } = useI18n()
const start = parseISO(timeslot.start).toLocaleString()
yield {
title: t('navigation.episode._title', { start }),
items: [
{
title: t('navigation.episode.description'),
route: { name: 'show-episode-description', params: route.params },
},
{
title: t('navigation.episode.playlist'),
route: { name: 'show-episode-playlist', params: route.params },
},
],
}
}
async function* getShowContextMenu(route: RouteLocationNormalizedLoaded) {
if (!route.params.showId) return
const showId = parseInt(route.params.showId as string)
const showStore = useShowStore()
const show = await showStore.retrieve(showId, { useCached: true })
if (!show) return
const { t } = useI18n()
yield {
title: show.name,
items: [
{
title: t('navigation.show.episodes'),
route: { name: 'show-episodes', params: route.params },
},
{
title: t('navigation.show.basicData'),
route: { name: 'show-basic-data', params: route.params },
},
],
}
}
function useNavigationData(...menuCollectionGenerators: MenuItemCollectionGenerator[]) {
const route = useRoute()
const menuItemCollections = ref<MenuItemCollection[]>([])
watch(
[route, () => route.params, () => route.name],
async () => {
const result: MenuItemCollection[] = []
for (const generator of menuCollectionGenerators) {
try {
for await (const collection of generator(route)) {
result.push(collection)
}
} catch (e) {
// pass
}
}
menuItemCollections.value = result
},
{ immediate: true },
)
return shallowReadonly(menuItemCollections)
}
export function useMainNavigationData() {
return useNavigationData(getMainNavigation, getEpisodeContextMenu, getShowContextMenu)
}