Skip to content
Snippets Groups Projects
Commit a82fb45c authored by Eliot Berriot's avatar Eliot Berriot
Browse files

Merge branch '715-set-instance' into 'develop'

Resolve "Enhancement: improve "use another instance menu""

Closes #715

See merge request !627
parents 8beb08d6 1d7ad697
Branches
Tags
No related merge requests found
Showing
with 205 additions and 103 deletions
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.
<template> <template>
<div id="app"> <div id="app" :key="String($store.state.instance.instanceUrl)">
<!-- here, we display custom stylesheets, if any --> <!-- here, we display custom stylesheets, if any -->
<link <link
v-for="url in customStylesheets" v-for="url in customStylesheets"
...@@ -8,40 +8,16 @@ ...@@ -8,40 +8,16 @@
:href="url" :href="url"
:key="url" :key="url"
> >
<div class="ui main text container instance-chooser" v-if="!$store.state.instance.instanceUrl"> <template>
<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>
<sidebar></sidebar> <sidebar></sidebar>
<set-instance-modal @update:show="showSetInstanceModal = $event" :show="showSetInstanceModal"></set-instance-modal>
<service-messages v-if="messages.length > 0"/> <service-messages v-if="messages.length > 0"/>
<router-view :key="$route.fullPath"></router-view> <router-view :key="$route.fullPath"></router-view>
<div class="ui fitted divider"></div> <div class="ui fitted divider"></div>
<app-footer <app-footer
:version="version" :version="version"
@show:shortcuts-modal="showShortcutsModal = !showShortcutsModal" @show:shortcuts-modal="showShortcutsModal = !showShortcutsModal"
@show:set-instance-modal="showSetInstanceModal = !showSetInstanceModal"
></app-footer> ></app-footer>
<playlist-modal v-if="$store.state.auth.authenticated"></playlist-modal> <playlist-modal v-if="$store.state.auth.authenticated"></playlist-modal>
<filter-modal v-if="$store.state.auth.authenticated"></filter-modal> <filter-modal v-if="$store.state.auth.authenticated"></filter-modal>
...@@ -66,6 +42,7 @@ import locales from './locales' ...@@ -66,6 +42,7 @@ import locales from './locales'
import PlaylistModal from '@/components/playlists/PlaylistModal' import PlaylistModal from '@/components/playlists/PlaylistModal'
import FilterModal from '@/components/moderation/FilterModal' import FilterModal from '@/components/moderation/FilterModal'
import ShortcutsModal from '@/components/ShortcutsModal' import ShortcutsModal from '@/components/ShortcutsModal'
import SetInstanceModal from '@/components/SetInstanceModal'
export default { export default {
name: 'app', name: 'app',
...@@ -76,7 +53,8 @@ export default { ...@@ -76,7 +53,8 @@ export default {
PlaylistModal, PlaylistModal,
ShortcutsModal, ShortcutsModal,
GlobalEvents, GlobalEvents,
ServiceMessages ServiceMessages,
SetInstanceModal,
}, },
data () { data () {
return { return {
...@@ -84,6 +62,7 @@ export default { ...@@ -84,6 +62,7 @@ export default {
nodeinfo: null, nodeinfo: null,
instanceUrl: null, instanceUrl: null,
showShortcutsModal: false, showShortcutsModal: false,
showSetInstanceModal: false,
} }
}, },
created () { created () {
...@@ -131,12 +110,6 @@ export default { ...@@ -131,12 +110,6 @@ export default {
self.nodeinfo = response.data 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 () { autodetectLanguage () {
let userLanguage = navigator.language || navigator.userLanguage let userLanguage = navigator.language || navigator.userLanguage
let available = locales.locales.map(e => { return e.code }) let available = locales.locales.map(e => { return e.code })
...@@ -257,7 +230,6 @@ export default { ...@@ -257,7 +230,6 @@ export default {
console.log('No momentjs locale available for', shortLocale) console.log('No momentjs locale available for', shortLocale)
}) })
}) })
console.log(moment.locales())
} }
} }
} }
......
...@@ -13,9 +13,9 @@ ...@@ -13,9 +13,9 @@
<div class="item" v-if="version"> <div class="item" v-if="version">
<translate :translate-params="{version: version}" >Version %{version}</translate> <translate :translate-params="{version: version}" >Version %{version}</translate>
</div> </div>
<a @click="switchInstance" class="item" > <div role="button" class="item" @click="$emit('show:set-instance-modal')" >
<translate>Use another instance</translate> <translate>Use another instance</translate>
</a> </div>
</div> </div>
<div class="ui form"> <div class="ui form">
<div class="ui field"> <div class="ui field">
...@@ -66,18 +66,6 @@ import axios from 'axios' ...@@ -66,18 +66,6 @@ import axios from 'axios'
export default { export default {
props: ["version"], 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: { computed: {
...mapState({ ...mapState({
messages: state => state.ui.messages messages: state => state.ui.messages
...@@ -88,13 +76,6 @@ export default { ...@@ -88,13 +76,6 @@ export default {
parser.href = url parser.href = url
return parser.hostname return parser.hostname
}, },
suggestedInstances() {
let instances = [
this.$store.getters["instance/defaultUrl"](),
"https://demo.funkwhale.audio"
]
return instances
}
} }
} }
</script> </script>
......
<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 }&nbsp;<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>
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment