Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
interfect
funkwhale
Commits
f4f75dcb
Verified
Commit
f4f75dcb
authored
Apr 11, 2018
by
Eliot Berriot
Browse files
Can now scan and follow library from front-end
parent
fe7ca088
Changes
7
Hide whitespace changes
Inline
Side-by-side
api/funkwhale_api/federation/serializers.py
View file @
f4f75dcb
...
...
@@ -159,6 +159,7 @@ class APILibrarySerializer(serializers.ModelSerializer):
class
APILibraryCreateSerializer
(
serializers
.
ModelSerializer
):
actor
=
serializers
.
URLField
()
federation_enabled
=
serializers
.
BooleanField
()
class
Meta
:
model
=
models
.
Library
...
...
api/funkwhale_api/users/models.py
View file @
f4f75dcb
...
...
@@ -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
()
...
...
front/src/components/Sidebar.vue
View file @
f4f75dcb
...
...
@@ -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>
...
...
front/src/components/federation/LibraryCard.vue
0 → 100644
View file @
f4f75dcb
<
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
>
front/src/components/federation/LibraryForm.vue
0 → 100644
View file @
f4f75dcb
<
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
>
front/src/router/index.js
View file @
f4f75dcb
...
...
@@ -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
,
...
...
front/src/views/federation/Home.vue
0 → 100644
View file @
f4f75dcb
<
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
>
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment