traxxx/assets/components/filters/channel-filter.vue

145 lines
3.1 KiB
Vue

<template>
<v-popover class="filter-container">
<div class="filter">
<Icon icon="antenna" />
<div
v-if="selectedChannels.length > 0"
class="filter-applied"
>{{ selectedChannels.length }} {{ selectedChannels.length > 1 ? 'channels' : 'channel' }}</div>
<div
v-else
class="filter-applied empty"
>Channels</div>
</div>
<div slot="popover">
<router-link
class="filter-clear"
:to="{ query: { ...$route.query, channels: undefined } }"
:class="{ active: selectedChannels.length > 0 }"
>clear all<Icon icon="cross2" /></router-link>
<ul class="filter-items nolist">
<li
v-for="channel in channelsPerNetwork"
:key="`channel-${channel.id}`"
class="filter-item"
:class="{ [channel.type]: true, independent: channel.independent }"
>
<router-link
:to="{ query: { ...$route.query, channels: channel.slug, mode }, params: { pageNumber: 1 } }"
class="filter-name"
>
<img
v-if="channel.independent || !channel.parent"
:src="`/img/logos/${channel.slug}/favicon.png`"
class="favicon"
>
{{ channel.name }}
</router-link>
<router-link
:to="{ query: { ...$route.query, ...getNewRange(channel.slug), mode }, params: { pageNumber: 1 } }"
class="filter-include"
:class="{ selected: selectedChannels.includes(channel.slug) }"
>
<Icon
icon="checkmark"
class="filter-add"
/>
<Icon
icon="cross2"
class="filter-remove"
/>
</router-link>
</li>
</ul>
</div>
</v-popover>
</template>
<script>
function getNewRange(channel) {
if (this.selectedChannels.includes(channel)) {
return { channels: this.selectedChannels.filter(selectedTag => selectedTag !== channel).join(',') || undefined };
}
return { channels: this.selectedChannels.concat(channel).join(',') };
}
function selectedChannels() {
return this.$route.query.channels ? this.$route.query.channels.split(',') : [];
}
function channelsPerNetwork() {
const networks = this.availableChannels.reduce((acc, channel) => {
if (channel.independent || !channel.parent) {
acc[channel.slug] = { ...channel, children: [] };
return acc;
}
if (!acc[channel.parent.slug]) {
acc[channel.parent.slug] = { ...channel.parent, children: [] };
}
acc[channel.parent.slug].children.push(channel);
return acc;
}, {});
return Object.values(networks).reduce((acc, network) => [...acc, network, ...(network.children || [])], []);
}
export default {
props: {
filter: {
type: Array,
default: () => [],
},
compact: {
type: Boolean,
default: false,
},
availableChannels: {
type: Array,
default: () => [],
},
},
data() {
return {
mode: this.$route.query.mode || 'all',
};
},
computed: {
channelsPerNetwork,
selectedChannels,
},
methods: {
getNewRange,
},
};
</script>
<style lang="scss" scoped>
.favicon {
width: 1rem;
height: 1rem;
padding: 0 .75rem 0 0;
filter: drop-shadow(0 0 1px var(--darken));
}
.network .filter-name,
.independent .filter-name {
font-weight: bold;
padding: .5rem;
}
.channel:not(.independent) .filter-name {
padding: .5rem .5rem .5rem 2.25rem;
}
</style>