Fixes broken channel page

This commit is contained in:
Marcos 2022-03-22 16:13:19 +01:00 committed by Georg Krause
parent 44e07b5fbd
commit 9528437242
12 changed files with 43 additions and 19 deletions

View File

@ -268,7 +268,7 @@ class ChannelSerializer(serializers.ModelSerializer):
return obj.actor.received_follows.exclude(approved=False).count() return obj.actor.received_follows.exclude(approved=False).count()
def get_downloads_count(self, obj): def get_downloads_count(self, obj):
return getattr(obj, "_downloads_count", None) return getattr(obj, "_downloads_count", None) or 0
def get_actor(self, obj): def get_actor(self, obj):
if obj.attributed_to == actors.get_service_actor(): if obj.attributed_to == actors.get_service_actor():

View File

@ -250,7 +250,7 @@ def test_channel_serializer_external_representation(factories, to_api_date):
"metadata": {}, "metadata": {},
"rss_url": channel.get_rss_url(), "rss_url": channel.get_rss_url(),
"url": channel.actor.url, "url": channel.actor.url,
"downloads_count": None, "downloads_count": 0,
} }
expected["artist"]["description"] = common_serializers.ContentSerializer( expected["artist"]["description"] = common_serializers.ContentSerializer(
content content

View File

@ -0,0 +1 @@
Fixes channel page (#1729) (1729)

View File

@ -67,7 +67,7 @@ export default {
props: { props: {
filters: { type: Object, required: true }, filters: { type: Object, required: true },
limit: { type: Number, default: 10 }, limit: { type: Number, default: 10 },
defaultCover: { type: Object, required: true }, defaultCover: { type: Object, default: () => ({}) },
isPodcast: { type: Boolean, required: true } isPodcast: { type: Boolean, required: true }
}, },
data () { data () {

View File

@ -108,7 +108,7 @@
> >
<pagination <pagination
:total="totalTracks" :total="totalTracks"
:current=" tracks.length > 0 ? page : {currentPage}" :current=" tracks.length > 0 ? page : currentPage"
:paginate-by="paginateBy" :paginate-by="paginateBy"
@page-changed="updatePage" @page-changed="updatePage"
/> />
@ -163,6 +163,7 @@ import axios from 'axios'
import TrackRow from '@/components/audio/track/Row.vue' import TrackRow from '@/components/audio/track/Row.vue'
import TrackMobileRow from '@/components/audio/track/MobileRow.vue' import TrackMobileRow from '@/components/audio/track/MobileRow.vue'
import Pagination from '@/components/Pagination.vue' import Pagination from '@/components/Pagination.vue'
import { unique } from '@/filters'
export default { export default {
components: { components: {
@ -178,7 +179,7 @@ export default {
showPosition: { type: Boolean, required: false, default: false }, showPosition: { type: Boolean, required: false, default: false },
showArt: { type: Boolean, required: false, default: true }, showArt: { type: Boolean, required: false, default: true },
search: { type: Boolean, required: false, default: false }, search: { type: Boolean, required: false, default: false },
filters: { type: Object, required: false, default: null }, filters: { type: Object, required: false, default: () => { return {} } },
nextUrl: { type: String, required: false, default: null }, nextUrl: { type: String, required: false, default: null },
displayActions: { type: Boolean, required: false, default: true }, displayActions: { type: Boolean, required: false, default: true },
showDuration: { type: Boolean, required: false, default: true }, showDuration: { type: Boolean, required: false, default: true },
@ -203,7 +204,8 @@ export default {
}, },
computed: { computed: {
allTracks () { allTracks () {
return (this.tracks || []).concat(this.additionalTracks) const tracks = (this.tracks || []).concat(this.additionalTracks)
return unique(tracks, 'id')
}, },
labels () { labels () {

View File

@ -2,7 +2,7 @@
<div> <div>
<label for="album-dropdown"> <label for="album-dropdown">
<translate <translate
v-if="channel && channel.artist.content_category === 'podcast'" v-if="channel && channel.artist && channel.artist.content_category === 'podcast'"
key="1" key="1"
translate-context="*/*/*" translate-context="*/*/*"
>Series</translate> >Series</translate>
@ -45,8 +45,8 @@ import axios from 'axios'
export default { export default {
props: { props: {
value: { type: String, required: true }, value: { type: Number, default: null },
channel: { type: Object, required: true } channel: { type: Object, default: () => ({}) }
}, },
data () { data () {
return { return {
@ -65,7 +65,7 @@ export default {
methods: { methods: {
async fetchData () { async fetchData () {
this.albums = [] this.albums = []
if (!this.channel) { if (!this.channel || !this.channel.artist) {
return return
} }
this.isLoading = true this.isLoading = true

View File

@ -42,7 +42,7 @@
import axios from 'axios' import axios from 'axios'
export default { export default {
props: { value: { type: String, required: true } }, props: { value: { type: String, default: null } },
data () { data () {
return { return {
availableLicenses: [], availableLicenses: [],

View File

@ -2,7 +2,7 @@
<button <button
:class="[{disabled: disabled}]" :class="[{disabled: disabled}]"
:disabled="disabled" :disabled="disabled"
@click="showModal = true" @click.prevent.stop="showModal = true"
> >
<slot /> <slot />

View File

@ -292,7 +292,7 @@ export default {
return this.object.tracks_count return this.object.tracks_count
}, },
isChannel () { isChannel () {
return this.object.artist.channel return this.object.artist.channel !== null
}, },
isSerie () { isSerie () {
return this.object.artist.content_category === 'podcast' return this.object.artist.content_category === 'podcast'

View File

@ -135,4 +135,13 @@ export function humanSize (bytes) {
Vue.filter('humanSize', humanSize) Vue.filter('humanSize', humanSize)
// Removes duplicates from a list
export function unique (list, property) {
property = property || 'id'
const unique = []
list.map(x => unique.filter(a => a[property] === x[property]).length > 0 ? null : unique.push(x))
return unique
}
Vue.filter('unique', unique)
export default {} export default {}

View File

@ -196,6 +196,7 @@
href="" href=""
@click.stop.prevent="showEditModal = true" @click.stop.prevent="showEditModal = true"
> >
<i class="edit icon" />
<translate translate-context="*/*/*/Verb">Edit</translate> <translate translate-context="*/*/*/Verb">Edit</translate>
</a> </a>
<dangerous-button <dangerous-button
@ -203,6 +204,7 @@
:class="['ui', {loading: isLoading}, 'item']" :class="['ui', {loading: isLoading}, 'item']"
@confirm="remove()" @confirm="remove()"
> >
<i class="ui trash icon" />
<translate translate-context="*/*/*/Verb"> <translate translate-context="*/*/*/Verb">
Delete Delete
</translate> </translate>
@ -505,6 +507,11 @@ export default {
watch: { watch: {
id () { id () {
this.fetchData() this.fetchData()
},
'$store.state.channels.latestPublication' (v) {
if (v && v.uploads && v.channel.uuid === this.object.uuid) {
this.fetchData()
}
} }
}, },
async created () { async created () {
@ -531,11 +538,9 @@ export default {
self.$router.replace({ name: 'channels.detail', params: { id: actor.full_username } }) self.$router.replace({ name: 'channels.detail', params: { id: actor.full_username } })
} }
} }
axios.get('tracks', { params: { channel: response.data.uuid, page_size: 1, playable: true, include_channels: true } }).then(response => { self.totalTracks = response.data.artist.tracks_count
self.totalTracks = response.data.count
self.isLoading = false self.isLoading = false
}) })
})
await channelPromise await channelPromise
}, },
remove () { remove () {

View File

@ -1,6 +1,6 @@
import {expect} from 'chai' import {expect} from 'chai'
import moment from 'moment' import moment from 'moment'
import {truncate, ago, capitalize, year} from '@/filters' import {truncate, ago, capitalize, year, unique} from '@/filters'
describe('filters', () => { describe('filters', () => {
describe('truncate', () => { describe('truncate', () => {
@ -46,7 +46,14 @@ describe('filters', () => {
it('works', () => { it('works', () => {
const input = 'hello world' const input = 'hello world'
let output = capitalize(input) let output = capitalize(input)
expect(output).to.equal('Hello world') expect(output).to.deep.equal('Hello world')
})
})
describe('unique', () => {
it('works', () => {
const list = [{id: 1}, {id: 2}, {id: 3}, {id: 1}]
const dedupedList = unique(list, 'id')
expect(dedupedList).to.have.deep.members([{id: 1}, {id: 3}, {id: 2}])
}) })
}) })
}) })