Fixes broken channel page
This commit is contained in:
parent
44e07b5fbd
commit
9528437242
|
@ -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():
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
Fixes channel page (#1729) (1729)
|
|
@ -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 () {
|
||||||
|
|
|
@ -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 () {
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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: [],
|
||||||
|
|
|
@ -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 />
|
||||||
|
|
||||||
|
|
|
@ -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'
|
||||||
|
|
|
@ -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 {}
|
||||||
|
|
|
@ -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,10 +538,8 @@ 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
|
||||||
},
|
},
|
||||||
|
|
|
@ -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}])
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
Loading…
Reference in New Issue