Moved Modal t set instance url to a separate dedicated file
SetInstanceModal.vue
This commit is contained in:
parent
8beb08d677
commit
1d7ad6978a
|
@ -0,0 +1,3 @@
|
|||
Better workflow for connecting to another instance (#715)
|
||||
|
||||
Changing the instance used is now better integrated in the App, and it is checked that the chosen instance and the suggested instances are valid and running Funkwhale servers.
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<div id="app">
|
||||
<div id="app" :key="String($store.state.instance.instanceUrl)">
|
||||
<!-- here, we display custom stylesheets, if any -->
|
||||
<link
|
||||
v-for="url in customStylesheets"
|
||||
|
@ -8,40 +8,16 @@
|
|||
:href="url"
|
||||
:key="url"
|
||||
>
|
||||
<div class="ui main text container instance-chooser" v-if="!$store.state.instance.instanceUrl">
|
||||
<div class="ui padded segment">
|
||||
<h1 class="ui header">
|
||||
<translate>Choose your instance</translate>
|
||||
</h1>
|
||||
<form class="ui form" @submit.prevent="$store.dispatch('instance/setUrl', instanceUrl)">
|
||||
<p>
|
||||
<translate>You need to select an instance in order to continue</translate>
|
||||
</p>
|
||||
<div class="ui action input">
|
||||
<input type="text" v-model="instanceUrl">
|
||||
<button type="submit" class="ui button">
|
||||
<translate>Submit</translate>
|
||||
</button>
|
||||
</div>
|
||||
<p>
|
||||
<translate>Suggested choices</translate>
|
||||
</p>
|
||||
<div class="ui bulleted list">
|
||||
<div class="ui item" v-for="url in suggestedInstances">
|
||||
<a @click="instanceUrl = url; $store.dispatch('instance/setUrl', url)">{{ url }}</a>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<template v-else>
|
||||
<template>
|
||||
<sidebar></sidebar>
|
||||
<set-instance-modal @update:show="showSetInstanceModal = $event" :show="showSetInstanceModal"></set-instance-modal>
|
||||
<service-messages v-if="messages.length > 0"/>
|
||||
<router-view :key="$route.fullPath"></router-view>
|
||||
<div class="ui fitted divider"></div>
|
||||
<app-footer
|
||||
:version="version"
|
||||
@show:shortcuts-modal="showShortcutsModal = !showShortcutsModal"
|
||||
@show:set-instance-modal="showSetInstanceModal = !showSetInstanceModal"
|
||||
></app-footer>
|
||||
<playlist-modal v-if="$store.state.auth.authenticated"></playlist-modal>
|
||||
<filter-modal v-if="$store.state.auth.authenticated"></filter-modal>
|
||||
|
@ -66,6 +42,7 @@ import locales from './locales'
|
|||
import PlaylistModal from '@/components/playlists/PlaylistModal'
|
||||
import FilterModal from '@/components/moderation/FilterModal'
|
||||
import ShortcutsModal from '@/components/ShortcutsModal'
|
||||
import SetInstanceModal from '@/components/SetInstanceModal'
|
||||
|
||||
export default {
|
||||
name: 'app',
|
||||
|
@ -76,7 +53,8 @@ export default {
|
|||
PlaylistModal,
|
||||
ShortcutsModal,
|
||||
GlobalEvents,
|
||||
ServiceMessages
|
||||
ServiceMessages,
|
||||
SetInstanceModal,
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
|
@ -84,6 +62,7 @@ export default {
|
|||
nodeinfo: null,
|
||||
instanceUrl: null,
|
||||
showShortcutsModal: false,
|
||||
showSetInstanceModal: false,
|
||||
}
|
||||
},
|
||||
created () {
|
||||
|
@ -131,12 +110,6 @@ export default {
|
|||
self.nodeinfo = response.data
|
||||
})
|
||||
},
|
||||
switchInstance () {
|
||||
let confirm = window.confirm(this.$gettext('This will erase your local data and disconnect you, do you want to continue?'))
|
||||
if (confirm) {
|
||||
this.$store.commit('instance/instanceUrl', null)
|
||||
}
|
||||
},
|
||||
autodetectLanguage () {
|
||||
let userLanguage = navigator.language || navigator.userLanguage
|
||||
let available = locales.locales.map(e => { return e.code })
|
||||
|
@ -257,7 +230,6 @@ export default {
|
|||
console.log('No momentjs locale available for', shortLocale)
|
||||
})
|
||||
})
|
||||
console.log(moment.locales())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,9 +13,9 @@
|
|||
<div class="item" v-if="version">
|
||||
<translate :translate-params="{version: version}" >Version %{version}</translate>
|
||||
</div>
|
||||
<a @click="switchInstance" class="item" >
|
||||
<div role="button" class="item" @click="$emit('show:set-instance-modal')" >
|
||||
<translate>Use another instance</translate>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ui form">
|
||||
<div class="ui field">
|
||||
|
@ -66,18 +66,6 @@ import axios from 'axios'
|
|||
|
||||
export default {
|
||||
props: ["version"],
|
||||
methods: {
|
||||
switchInstance() {
|
||||
let confirm = window.confirm(
|
||||
this.$gettext(
|
||||
"This will erase your local data and disconnect you, do you want to continue?"
|
||||
)
|
||||
)
|
||||
if (confirm) {
|
||||
this.$store.commit("instance/instanceUrl", null)
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapState({
|
||||
messages: state => state.ui.messages
|
||||
|
@ -88,13 +76,6 @@ export default {
|
|||
parser.href = url
|
||||
return parser.hostname
|
||||
},
|
||||
suggestedInstances() {
|
||||
let instances = [
|
||||
this.$store.getters["instance/defaultUrl"](),
|
||||
"https://demo.funkwhale.audio"
|
||||
]
|
||||
return instances
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
|
|
@ -1,21 +1,21 @@
|
|||
<template>
|
||||
<svg version="1.1" id="layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 141.7 141.7" enable-background="new 0 0 141.7 141.7" xml:space="preserve">
|
||||
viewBox="0 0 141.7 141.7" enable-background="new 0 0 141.7 141.7" xml:space="preserve">
|
||||
<g>
|
||||
<g>
|
||||
<path :fill="fill" d="M70.9,86.1c11.7,0,21.2-9.5,21.2-21.2c0-0.6-0.5-1.1-1.1-1.1h-8c-0.6,0-1.1,0.5-1.1,1.1c0,6-4.9,11-11,11
|
||||
c-6,0-11-4.9-11-11c0-0.6-0.5-1.1-1.1-1.1h-8c-0.6,0-1.1,0.5-1.1,1.1C49.7,76.6,59.2,86.1,70.9,86.1z"/>
|
||||
<path :fill="fill" d="M70.9,106.1c22.7,0,41.2-18.5,41.2-41.2c0-0.6-0.5-1.1-1.1-1.1h-8c-0.6,0-1.1,0.5-1.1,1.1
|
||||
c0,17.1-13.9,31-31,31c-17.1,0-31-13.9-31-31c0-0.6-0.5-1.1-1.1-1.1h-8c-0.6,0-1.1,0.5-1.1,1.1C29.6,87.6,48.1,106.1,70.9,106.1z"
|
||||
/>
|
||||
<path :fill="fill" d="M131.1,63.8h-8c-0.6,0-1.1,0.5-1.1,1.1C122,93.1,99,116,70.9,116c-28.2,0-51.1-22.9-51.1-51.1
|
||||
c0-0.6-0.5-1.1-1.1-1.1h-8c-0.6,0-1.1,0.5-1.1,1.1c0,33.8,27.5,61.3,61.3,61.3c33.8,0,61.3-27.5,61.3-61.3
|
||||
C132.2,64.3,131.7,63.8,131.1,63.8z"/>
|
||||
</g>
|
||||
<path :fill="fill" d="M43.3,37.3c4.1,2.1,8.5,2.5,12.5,4.8c2.6,1.5,4.2,3.2,5.8,5.7c2.5,3.8,2.4,8.5,2.4,8.5l0.3,5.2
|
||||
c0,0,2,5.2,6.4,5.2c4.7,0,6.4-5.2,6.4-5.2l0.3-5.2c0,0-0.1-4.7,2.4-8.5c1.6-2.5,3.2-4.3,5.8-5.7c4-2.3,8.4-2.7,12.5-4.8
|
||||
c4.1-2.1,8.1-4.8,10.8-8.6c2.7-3.8,4-8.8,2.5-13.2c-7.8-0.4-16.8,0.5-23.7,4.2c-9.6,5.1-15.4,3.3-17.1,10.9h-0.1
|
||||
c-1.7-7.7-7.5-5.8-17.1-10.9c-6.9-3.7-15.9-4.6-23.7-4.2c-1.5,4.4-0.2,9.4,2.5,13.2C35.2,32.5,39.2,35.2,43.3,37.3z"/>
|
||||
<g>
|
||||
<path :fill="fill" d="M70.9,86.1c11.7,0,21.2-9.5,21.2-21.2c0-0.6-0.5-1.1-1.1-1.1h-8c-0.6,0-1.1,0.5-1.1,1.1c0,6-4.9,11-11,11
|
||||
c-6,0-11-4.9-11-11c0-0.6-0.5-1.1-1.1-1.1h-8c-0.6,0-1.1,0.5-1.1,1.1C49.7,76.6,59.2,86.1,70.9,86.1z"/>
|
||||
<path :fill="fill" d="M70.9,106.1c22.7,0,41.2-18.5,41.2-41.2c0-0.6-0.5-1.1-1.1-1.1h-8c-0.6,0-1.1,0.5-1.1,1.1
|
||||
c0,17.1-13.9,31-31,31c-17.1,0-31-13.9-31-31c0-0.6-0.5-1.1-1.1-1.1h-8c-0.6,0-1.1,0.5-1.1,1.1C29.6,87.6,48.1,106.1,70.9,106.1z"
|
||||
/>
|
||||
<path :fill="fill" d="M131.1,63.8h-8c-0.6,0-1.1,0.5-1.1,1.1C122,93.1,99,116,70.9,116c-28.2,0-51.1-22.9-51.1-51.1
|
||||
c0-0.6-0.5-1.1-1.1-1.1h-8c-0.6,0-1.1,0.5-1.1,1.1c0,33.8,27.5,61.3,61.3,61.3c33.8,0,61.3-27.5,61.3-61.3
|
||||
C132.2,64.3,131.7,63.8,131.1,63.8z"/>
|
||||
</g>
|
||||
<path :fill="fill" d="M43.3,37.3c4.1,2.1,8.5,2.5,12.5,4.8c2.6,1.5,4.2,3.2,5.8,5.7c2.5,3.8,2.4,8.5,2.4,8.5l0.3,5.2
|
||||
c0,0,2,5.2,6.4,5.2c4.7,0,6.4-5.2,6.4-5.2l0.3-5.2c0,0-0.1-4.7,2.4-8.5c1.6-2.5,3.2-4.3,5.8-5.7c4-2.3,8.4-2.7,12.5-4.8
|
||||
c4.1-2.1,8.1-4.8,10.8-8.6c2.7-3.8,4-8.8,2.5-13.2c-7.8-0.4-16.8,0.5-23.7,4.2c-9.6,5.1-15.4,3.3-17.1,10.9h-0.1
|
||||
c-1.7-7.7-7.5-5.8-17.1-10.9c-6.9-3.7-15.9-4.6-23.7-4.2c-1.5,4.4-0.2,9.4,2.5,13.2C35.2,32.5,39.2,35.2,43.3,37.3z"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
||||
|
|
|
@ -0,0 +1,146 @@
|
|||
<template>
|
||||
<modal @update:show="$emit('update:show', $event); isError = false" :show="show">
|
||||
<div class="header"><translate :translate-context="'Popup/Instance/Title'">Choose your instance</translate></div>
|
||||
<div class="scrolling content">
|
||||
<div v-if="isError" class="ui negative message">
|
||||
<div class="header"><translate :translate-context="'Popup/Instance/Error message.Title'">It is not possible to connect to the given URL</translate></div>
|
||||
<ul class="list">
|
||||
<li><translate :translate-context="'Popup/Instance/Error message.List item'">The server might be down</translate></li>
|
||||
<li><translate :translate-context="'Popup/Instance/Error message.List item'">The given address is not a Funkwhale server</translate></li>
|
||||
</ul>
|
||||
</div>
|
||||
<form class="ui form" @submit.prevent="checkAndSwitch(instanceUrl)">
|
||||
<p v-if="$store.state.instance.instanceUrl" class="description" :translate-context="'Popup/Login/Paragraph'" v-translate="{url: $store.state.instance.instanceUrl, hostname: instanceHostname }">
|
||||
You are currently connected to <a href="%{ url }" target="_blank">%{ hostname } <i class="external icon"></i></a>. If you continue, you will be disconnected from your current instance and all your local data will be deleted.
|
||||
</p>
|
||||
<p v-else>
|
||||
<translate :translate-context="'Popup/Instance/Paragraph'">To continue, please select the Funkwhale instance you want to connect to. Enter the address directly, or select one of the suggested choices.</translate>
|
||||
</p>
|
||||
<div class="field">
|
||||
<label><translate :translate-context="'Popup/Instance/Input.Label/Noun'">Instance URL</translate></label>
|
||||
<div class="ui action input">
|
||||
<input type="text" v-model="instanceUrl" placeholder="https://funkwhale.server">
|
||||
<button type="submit" :class="['ui', 'icon', {loading: isLoading}, 'button']">
|
||||
<translate :translate-context="'*/*/Button.Label/Verb'">Submit</translate>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
<div class="ui hidden divider"></div>
|
||||
<form class="ui form" @submit.prevent="">
|
||||
<div class="field">
|
||||
<label><translate :translate-context="'Popup/Instance/List.Label'">Suggested choices</translate></label>
|
||||
<button v-for="url in suggestedInstances" @click="checkAndSwitch(url)" class="ui basic button">{{ url }}</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div class="actions">
|
||||
<div class="ui cancel button"><translate :translate-context="'*/*/Button.Label/Verb'">Cancel</translate></div>
|
||||
</div>
|
||||
</modal>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Modal from '@/components/semantic/Modal'
|
||||
import axios from 'axios'
|
||||
|
||||
export default {
|
||||
props: ['show'],
|
||||
components: {
|
||||
Modal,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
instanceUrl: null,
|
||||
nodeinfo: null,
|
||||
isError: false,
|
||||
isLoading: false,
|
||||
path: 'api/v1/instance/nodeinfo/2.0/',
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
fetchNodeInfo () {
|
||||
let self = this
|
||||
axios.get('instance/nodeinfo/2.0/').then(response => {
|
||||
self.nodeinfo = response.data
|
||||
})
|
||||
},
|
||||
fetchUrl (url) {
|
||||
let urlFetch = url
|
||||
if (!urlFetch.endsWith('/')) {
|
||||
urlFetch = `${urlFetch}/${this.path}`
|
||||
} else {
|
||||
urlFetch = `${urlFetch}${this.path}`
|
||||
}
|
||||
if (!urlFetch.startsWith('https://') && !urlFetch.startsWith('http://')) {
|
||||
urlFetch = `https://${urlFetch}`
|
||||
}
|
||||
return urlFetch
|
||||
},
|
||||
requestDistantNodeInfo (url) {
|
||||
var self = this
|
||||
axios.get(this.fetchUrl(url)).then(function (response) {
|
||||
self.isLoading = false
|
||||
if(!url.startsWith('https://') && !url.startsWith('http://')) {
|
||||
url = `https://${url}`
|
||||
}
|
||||
self.switchInstance(url)
|
||||
}).catch(function (error) {
|
||||
self.isLoading = false
|
||||
self.isError = true
|
||||
})
|
||||
},
|
||||
switchInstance (url) {
|
||||
// Here we disconnect from the current instance and reconnect to the new one. No check is performed...
|
||||
this.$emit('update:show', false)
|
||||
this.isError = false
|
||||
let msg = this.$pgettext('*/Instance/Message', 'You are now using the Funkwhale instance at %{ url }')
|
||||
this.$store.commit('ui/addMessage', {
|
||||
content: this.$gettextInterpolate(msg, {url: url}),
|
||||
date: new Date()
|
||||
})
|
||||
let self = this
|
||||
this.$nextTick(() => {
|
||||
self.$store.commit('instance/instanceUrl', null)
|
||||
self.$store.dispatch('instance/setUrl', url)
|
||||
})
|
||||
},
|
||||
checkAndSwitch (url) {
|
||||
// First we have to check if the address is a valid FW server. If yes, we switch:
|
||||
this.isError = false // Clear error message if any...
|
||||
this.isLoading = true
|
||||
this.requestDistantNodeInfo(url)
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
suggestedInstances () {
|
||||
let instances = this.$store.state.instance.knownInstances.slice(0)
|
||||
if (this.$store.state.instance.frontSettings.defaultServerUrl) {
|
||||
let serverUrl = this.$store.state.instance.frontSettings.defaultServerUrl
|
||||
if (!serverUrl.endsWith('/')) {
|
||||
serverUrl = serverUrl + '/'
|
||||
}
|
||||
instances.push(serverUrl)
|
||||
}
|
||||
let self = this
|
||||
instances.push(this.$store.getters['instance/defaultUrl'](), 'https://demo.funkwhale.audio/')
|
||||
return _.uniq(instances.filter((e) => {return e != self.$store.state.instance.instanceUrl}))
|
||||
},
|
||||
instanceHostname() {
|
||||
let url = this.$store.state.instance.instanceUrl
|
||||
let parser = document.createElement("a")
|
||||
parser.href = url
|
||||
return parser.hostname
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
'$store.state.instance.instanceUrl' () {
|
||||
this.$store.dispatch('instance/fetchSettings')
|
||||
this.fetchNodeInfo()
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
</style>
|
|
@ -17,14 +17,14 @@
|
|||
</template>
|
||||
</div>
|
||||
<div class="field">
|
||||
<button @click="copy" class="ui right teal labeled icon floated button"><i class="copy icon"></i><translate :translate-context="'Popup/*/Button.Label/Verb'">Copy</translate></button>
|
||||
<button @click="copy" class="ui right teal labeled icon floated button"><i class="copy icon"></i><translate :translate-context="'Popup/*/Button.Label/Verb'">Copy</translate></button>
|
||||
<label for="embed-width"><translate :translate-context="'Popup/Embed/Input.Label/Noun'">Embed code</translate></label>
|
||||
<p><translate :translate-context="'Popup/Embed/Paragraph'">Copy/paste this code in your website HTML</translate></p>
|
||||
<textarea ref="textarea":value="embedCode" rows="5" readonly>
|
||||
</textarea>
|
||||
<div class="ui right">
|
||||
<p class="message" v-if=copied><translate :translate-context="'Content/*/Paragraph'">Text copied to clipboard!</translate></p>
|
||||
</div>
|
||||
<div class="ui right">
|
||||
<p class="message" v-if=copied><translate :translate-context="'Content/*/Paragraph'">Text copied to clipboard!</translate></p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -44,7 +44,7 @@ export default {
|
|||
width: null,
|
||||
height: 150,
|
||||
minHeight: 100,
|
||||
copied: false
|
||||
copied: false
|
||||
}
|
||||
if (this.type === 'album') {
|
||||
d.height = 330
|
||||
|
@ -73,11 +73,11 @@ export default {
|
|||
copy () {
|
||||
this.$refs.textarea.select()
|
||||
document.execCommand("Copy")
|
||||
let self = this
|
||||
self.copied = true
|
||||
this.timeout = setTimeout(() => {
|
||||
self.copied = false
|
||||
}, 5000)
|
||||
let self = this
|
||||
self.copied = true
|
||||
this.timeout = setTimeout(() => {
|
||||
self.copied = false
|
||||
}, 5000)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -86,8 +86,8 @@ export default {
|
|||
<!-- Add "scoped" attribute to limit CSS to this component only -->
|
||||
<style scoped>
|
||||
.message {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
bottom: -2em;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
bottom: -2em;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<span :title="title" :class="['ui', {'tiny': discrete}, {'icon': !discrete}, {'buttons': !dropdownOnly && !iconOnly}]">
|
||||
<span :title="title" :class="['ui', {'tiny': discrete}, {'icon': !discrete}, {'buttons': !dropdownOnly && !iconOnly}]">
|
||||
<button
|
||||
v-if="!dropdownOnly"
|
||||
:title="labels.playNow"
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
translate-plural="%{ count } favorites"
|
||||
:translate-n="$store.state.favorites.count"
|
||||
:translate-params="{count: results.count}"
|
||||
:translate-context="'Content/Favorites/Title'">
|
||||
:translate-context="'Content/Favorites/Title'">
|
||||
1 favorite
|
||||
</translate>
|
||||
</h2>
|
||||
|
|
|
@ -63,7 +63,7 @@
|
|||
tag="h2"
|
||||
class="left floated"
|
||||
:translate-params="{number: disc_number + 1}"
|
||||
:translate-context="'Content/Album/'"
|
||||
:translate-context="'Content/Album/'"
|
||||
>Volume %{ number }</translate>
|
||||
<play-button class="right floated orange" :tracks="tracks">
|
||||
<translate :translate-context="'Content/*/Button.Label/Verb, Short'">Play all</translate>
|
||||
|
|
|
@ -34,7 +34,7 @@
|
|||
<p><translate :translate-context="'Content/Library/Paragraph'">You are about to upload music to your library. Before proceeding, please ensure that:</translate></p>
|
||||
<ul>
|
||||
<li v-if="library.privacy_level != 'me'">
|
||||
<translate :translate-context="'Content/Library/List item'">You are not uploading copyrighted content in a public library, otherwise you may be infringing the law</translate>
|
||||
<translate :translate-context="'Content/Library/List item'">You are not uploading copyrighted content in a public library, otherwise you may be infringing the law</translate>
|
||||
</li>
|
||||
<li>
|
||||
<translate :translate-context="'Content/Library/List item'">The music files you are uploading are tagged properly.</translate>
|
||||
|
@ -217,17 +217,17 @@ export default {
|
|||
},
|
||||
computed: {
|
||||
labels() {
|
||||
let denied = this.$pgettext('Content/Library/Help text',
|
||||
let denied = this.$pgettext('Content/Library/Help text',
|
||||
"Upload denied, ensure the file is not too big and that you have not reached your quota"
|
||||
);
|
||||
let server = this.$pgettext('Content/Library/Help text',
|
||||
let server = this.$pgettext('Content/Library/Help text',
|
||||
"Cannot upload this file, ensure it is not too big"
|
||||
);
|
||||
let network = this.$pgettext('Content/Library/Help text',
|
||||
let network = this.$pgettext('Content/Library/Help text',
|
||||
"A network error occured while uploading this file"
|
||||
);
|
||||
let timeout = this.$pgettext('Content/Library/Help text', "Upload timeout, please try again");
|
||||
let extension = this.$pgettext('Content/Library/Help text',
|
||||
let extension = this.$pgettext('Content/Library/Help text',
|
||||
"Invalid file type, ensure you are uploading an audio file. Supported file extensions are %{ extensions }"
|
||||
);
|
||||
return {
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
<input id="public" type="checkbox" v-model="isPublic" />
|
||||
<label for="public"><translate :translate-context="'Content/Radio/Checkbox.Label/Verb'">Display publicly</translate></label>
|
||||
</div>
|
||||
<div class="ui hidden divider"></div>
|
||||
<div class="ui hidden divider"></div>
|
||||
<button :disabled="!canSave" @click="save" :class="['ui', 'green', {loading: isLoading}, 'button']">
|
||||
<translate :translate-context="'Content/Radio/Button.Label/Verb'">Save</translate>
|
||||
</button>
|
||||
|
|
|
@ -42,7 +42,7 @@ export default {
|
|||
return {
|
||||
libraryFollowMessage,
|
||||
libraryAcceptFollowMessage,
|
||||
libraryPendingFollowMessage,
|
||||
libraryPendingFollowMessage,
|
||||
markRead: this.$gettext('Mark as read'),
|
||||
markUnread: this.$gettext('Mark as unread'),
|
||||
|
||||
|
@ -57,18 +57,18 @@ export default {
|
|||
if (a.type === 'Follow') {
|
||||
if (a.object && a.object.type === 'music.Library') {
|
||||
let action = null
|
||||
let message = null
|
||||
let message = null
|
||||
if (!a.related_object.approved) {
|
||||
message = this.labels.libraryPendingFollowMessage
|
||||
message = this.labels.libraryPendingFollowMessage
|
||||
action = {
|
||||
buttonClass: 'green',
|
||||
icon: 'check',
|
||||
label: this.$gettext('Approve'),
|
||||
handler: () => { self.approveLibraryFollow(a.related_object) }
|
||||
}
|
||||
} else {
|
||||
message = this.labels.libraryFollowMessage
|
||||
}
|
||||
} else {
|
||||
message = this.labels.libraryFollowMessage
|
||||
}
|
||||
return {
|
||||
action,
|
||||
detailUrl: {name: 'content.libraries.detail', params: {id: a.object.uuid}},
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
</div>
|
||||
<div class="extra content">
|
||||
<user-link v-if="radio.user" :user="radio.user" class="left floated" />
|
||||
<div class="ui hidden divider"></div>
|
||||
<div class="ui hidden divider"></div>
|
||||
<radio-button class="right floated button" :type="type" :custom-radio-id="customRadioId"></radio-button>
|
||||
<router-link
|
||||
class="ui basic yellow button right floated"
|
||||
|
|
|
@ -48,7 +48,7 @@
|
|||
</h3>
|
||||
</header>
|
||||
<p><translate :translate-context="'Content/Moderation/Card.Paragraph'">Moderation policies help you control how your instance interact with a given domain or account.</translate></p>
|
||||
<button @click="showPolicyForm = true" class="ui primary button"><translate :translate-context="'Content/Moderation/Button/Verb'">Add a moderation policy</translate></button>
|
||||
<button @click="showPolicyForm = true" class="ui primary button"><translate :translate-context="'Content/Moderation/Button/Verb'">Add a moderation policy</translate></button>
|
||||
</template>
|
||||
<instance-policy-card v-else-if="policy && !showPolicyForm" :object="policy" @update="showPolicyForm = true">
|
||||
<header class="ui header">
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
translate-plural="Playlist containing %{ count } tracks, by %{ username }"
|
||||
:translate-n="playlist.tracks_count"
|
||||
:translate-params="{count: playlist.tracks_count, username: playlist.user.username}"
|
||||
:translate-context="'Content/Playlist/Header.Subtitle'">
|
||||
:translate-context="'Content/Playlist/Header.Subtitle'">
|
||||
Playlist containing %{ count } track, by %{ username }
|
||||
</translate><br>
|
||||
<duration :seconds="playlist.duration" />
|
||||
|
|
Loading…
Reference in New Issue