Verified Commit f4f75dcb authored by Eliot Berriot's avatar Eliot Berriot
Browse files

Can now scan and follow library from front-end

parent fe7ca088
......@@ -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>
......
<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>
<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>&nbsp;</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,
......
<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>
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment