Can now scan and follow library from front-end
This commit is contained in:
parent
fe7ca088c5
commit
f4f75dcb4f
|
@ -159,6 +159,7 @@ class APILibrarySerializer(serializers.ModelSerializer):
|
|||
|
||||
class APILibraryCreateSerializer(serializers.ModelSerializer):
|
||||
actor = serializers.URLField()
|
||||
federation_enabled = serializers.BooleanField()
|
||||
|
||||
class Meta:
|
||||
model = models.Library
|
||||
|
|
|
@ -31,6 +31,9 @@ class User(AbstractUser):
|
|||
'dynamic_preferences.change_globalpreferencemodel': {
|
||||
'external_codename': 'settings.change',
|
||||
},
|
||||
'federation.change_library': {
|
||||
'external_codename': 'federation.manage',
|
||||
},
|
||||
}
|
||||
|
||||
privacy_level = fields.get_privacy_field()
|
||||
|
|
|
@ -45,6 +45,9 @@
|
|||
<router-link
|
||||
v-if="$store.state.auth.authenticated"
|
||||
class="item" :to="{path: '/activity'}"><i class="bell icon"></i> Activity</router-link>
|
||||
<router-link
|
||||
class="item" v-if="$store.state.auth.availablePermissions['federation.manage']"
|
||||
:to="{path: '/manage/federation'}"><i class="sitemap icon"></i> Federation</router-link>
|
||||
</div>
|
||||
|
||||
<player></player>
|
||||
|
|
|
@ -0,0 +1,82 @@
|
|||
<template>
|
||||
<div class="ui card">
|
||||
<div class="content">
|
||||
<div class="header">
|
||||
{{ libraryData.display_name }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="content">
|
||||
<span class="right floated" v-if="libraryData.actor.manuallyApprovesFollowers">
|
||||
<i class="lock icon"></i> Followers only
|
||||
</span>
|
||||
<span>
|
||||
<i class="music icon"></i>
|
||||
{{ libraryData.library.totalItems }} tracks
|
||||
</span>
|
||||
</div>
|
||||
<div class="extra content">
|
||||
<template v-if="libraryData.local.awaiting_approval">
|
||||
<i class="clock icon"></i>
|
||||
Follow request pending approval
|
||||
</template>
|
||||
<template v-else-if="libraryData.local.following">Pending follow request
|
||||
<i class="check icon"></i>
|
||||
Already following this library
|
||||
</template>
|
||||
<div
|
||||
v-else-if="!library"
|
||||
@click="follow"
|
||||
:disabled="isLoading"
|
||||
:class="['ui', 'basic', {loading: isLoading}, 'green', 'button']">
|
||||
<template v-if="libraryData.actor.manuallyApprovesFollowers">
|
||||
Send a follow request
|
||||
</template>
|
||||
<template v-else>
|
||||
Follow
|
||||
</template>
|
||||
</div>
|
||||
<router-link
|
||||
v-else
|
||||
class="ui basic button"
|
||||
:to="{name: 'federation.libraries.detail', params: {id: library.uuid }}">
|
||||
Detail
|
||||
</router-link>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import axios from 'axios'
|
||||
|
||||
export default {
|
||||
props: ['libraryData'],
|
||||
data () {
|
||||
return {
|
||||
isLoading: false,
|
||||
data: null,
|
||||
errors: [],
|
||||
library: null
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
follow () {
|
||||
let params = {
|
||||
'actor': this.libraryData['actor']['id'],
|
||||
'autoimport': false,
|
||||
'download_files': false,
|
||||
'federation_enabled': true
|
||||
}
|
||||
let self = this
|
||||
self.isLoading = true
|
||||
axios.post('/federation/libraries/', params).then((response) => {
|
||||
self.$emit('follow', {data: self.libraryData, library: response.data})
|
||||
self.library = response.data
|
||||
self.isLoading = false
|
||||
}, error => {
|
||||
self.isLoading = false
|
||||
self.errors = error.backendErrors
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
|
@ -0,0 +1,110 @@
|
|||
<template>
|
||||
<form class="ui form" @submit.prevent="fetchInstanceInfo">
|
||||
<h3 class="ui header">Federate with a new instance</h3>
|
||||
<p>Use this form to scan an instance and setup federation.</p>
|
||||
<div v-if="errors.length > 0 || scanErrors.length > 0" class="ui negative message">
|
||||
<div class="header">Error while scanning library</div>
|
||||
<ul class="list">
|
||||
<li v-for="error in errors">{{ error }}</li>
|
||||
<li v-for="error in scanErrors">{{ error }}</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="ui two fields">
|
||||
<div class="ui field">
|
||||
<label>Library name</label>
|
||||
<input v-model="libraryUsername" type="text" placeholder="library@demo.funkwhale.audio" />
|
||||
</div>
|
||||
<div class="ui field">
|
||||
<label> </label>
|
||||
<button
|
||||
type="submit"
|
||||
:disabled="isLoading"
|
||||
:class="['ui', 'icon', {loading: isLoading}, 'button']">
|
||||
<i class="search icon"></i>
|
||||
Launch scan
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import axios from 'axios'
|
||||
import TrackTable from '@/components/audio/track/Table'
|
||||
import RadioButton from '@/components/radios/Button'
|
||||
import Pagination from '@/components/Pagination'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
TrackTable,
|
||||
RadioButton,
|
||||
Pagination
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
isLoading: false,
|
||||
libraryUsername: 'library@node2.funkwhale.test',
|
||||
result: null,
|
||||
errors: []
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
follow () {
|
||||
let params = {
|
||||
'actor': this.result['actor']['id'],
|
||||
'autoimport': false,
|
||||
'download_files': false,
|
||||
'federation_enabled': true
|
||||
}
|
||||
let self = this
|
||||
self.isFollowing = false
|
||||
axios.post('/federation/libraries/', params).then((response) => {
|
||||
self.$emit('follow', {data: self.result, library: response.data})
|
||||
self.result = response.data
|
||||
self.isFollowing = false
|
||||
}, error => {
|
||||
self.isFollowing = false
|
||||
self.errors = error.backendErrors
|
||||
})
|
||||
},
|
||||
fetchInstanceInfo () {
|
||||
let self = this
|
||||
this.isLoading = true
|
||||
self.errors = []
|
||||
self.result = null
|
||||
axios.get('/federation/libraries/scan/', {params: {account: this.libraryUsername}}).then((response) => {
|
||||
self.result = response.data
|
||||
self.result.display_name = self.libraryUsername
|
||||
self.isLoading = false
|
||||
}, error => {
|
||||
self.isLoading = false
|
||||
self.errors = error.backendErrors
|
||||
})
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
scanErrors () {
|
||||
let errors = []
|
||||
if (!this.result) {
|
||||
return errors
|
||||
}
|
||||
let keys = ['webfinger', 'actor', 'library']
|
||||
keys.forEach(k => {
|
||||
if (this.result[k]) {
|
||||
if (this.result[k].errors) {
|
||||
this.result[k].errors.forEach(e => {
|
||||
errors.push(e)
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
return errors
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
result (newValue, oldValue) {
|
||||
this.$emit('scanned', newValue)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
|
@ -25,6 +25,7 @@ import RequestsList from '@/components/requests/RequestsList'
|
|||
import PlaylistDetail from '@/views/playlists/Detail'
|
||||
import PlaylistList from '@/views/playlists/List'
|
||||
import Favorites from '@/components/favorites/List'
|
||||
import Federation from '@/views/federation/Home'
|
||||
|
||||
Vue.use(Router)
|
||||
|
||||
|
@ -83,6 +84,10 @@ export default new Router({
|
|||
defaultPaginateBy: route.query.paginateBy
|
||||
})
|
||||
},
|
||||
{
|
||||
path: '/manage/federation',
|
||||
component: Federation
|
||||
},
|
||||
{
|
||||
path: '/library',
|
||||
component: Library,
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
<template>
|
||||
<div class="main pusher" v-title="'Federation'">
|
||||
<div class="ui vertical stripe segment">
|
||||
<h1 class="ui header">Manage federation</h1>
|
||||
<library-form @scanned="updateLibraryData"></library-form>
|
||||
<library-card v-if="libraryData" :library-data="libraryData"></library-card>
|
||||
</div>
|
||||
<div class="ui vertical stripe segment">
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// import axios from 'axios'
|
||||
import TrackTable from '@/components/audio/track/Table'
|
||||
import RadioButton from '@/components/radios/Button'
|
||||
import Pagination from '@/components/Pagination'
|
||||
import LibraryForm from '@/components/federation/LibraryForm'
|
||||
import LibraryCard from '@/components/federation/LibraryCard'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
TrackTable,
|
||||
RadioButton,
|
||||
Pagination,
|
||||
LibraryForm,
|
||||
LibraryCard
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
libraryData: null
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
updateLibraryData (data) {
|
||||
this.libraryData = data
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
Loading…
Reference in New Issue