diff --git a/changes/changelog.d/715.enhancement b/changes/changelog.d/715.enhancement new file mode 100644 index 0000000000000000000000000000000000000000..faba8a62c1fdcc4aa4b79fe078233a49c24a429e --- /dev/null +++ b/changes/changelog.d/715.enhancement @@ -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. diff --git a/front/src/App.vue b/front/src/App.vue index e06156c182a1f3bbb860d17dab886d6ea2567f0f..e214f2fb4d639c504288329a2249cd085bf6544e 100644 --- a/front/src/App.vue +++ b/front/src/App.vue @@ -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()) } } } diff --git a/front/src/components/Footer.vue b/front/src/components/Footer.vue index 795e9f40aa0eada3866dd39599556a2d7955bbb7..e45a9b47b4d609810aedb16cfad4b63d65b4aa79 100644 --- a/front/src/components/Footer.vue +++ b/front/src/components/Footer.vue @@ -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> diff --git a/front/src/components/Logo.vue b/front/src/components/Logo.vue index ff87dc299885acf39c57a67967d32ab3b3b87193..9785437c975b8e19669eb8da3296553a2fb58224 100644 --- a/front/src/components/Logo.vue +++ b/front/src/components/Logo.vue @@ -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> diff --git a/front/src/components/SetInstanceModal.vue b/front/src/components/SetInstanceModal.vue new file mode 100644 index 0000000000000000000000000000000000000000..220043d9a1f6dcd80b5bf5ba4988c932991cf9fe --- /dev/null +++ b/front/src/components/SetInstanceModal.vue @@ -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> diff --git a/front/src/components/audio/EmbedWizard.vue b/front/src/components/audio/EmbedWizard.vue index a5311d106e819ed21232bb90722af14e41600f67..0022b60df83be1415d65704022a85b2b5d4031c0 100644 --- a/front/src/components/audio/EmbedWizard.vue +++ b/front/src/components/audio/EmbedWizard.vue @@ -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> diff --git a/front/src/components/audio/PlayButton.vue b/front/src/components/audio/PlayButton.vue index 3bcbec9958d12d5e4cf8e142b9dc7e97049b6162..932b79608fb974540703efbdc5877e511d94eb39 100644 --- a/front/src/components/audio/PlayButton.vue +++ b/front/src/components/audio/PlayButton.vue @@ -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" diff --git a/front/src/components/favorites/List.vue b/front/src/components/favorites/List.vue index bf971fab2fd000fa08c8077fd2f161aa7ed1b1af..3db4e2306d7b9439ec02e9c6dc9255aa71f5989d 100644 --- a/front/src/components/favorites/List.vue +++ b/front/src/components/favorites/List.vue @@ -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> diff --git a/front/src/components/library/Album.vue b/front/src/components/library/Album.vue index 2bc508a91b7ea9706d3dee1a4304c5298812b96f..ce6f0abff8af7fc7c1220ac2cced4329c8197002 100644 --- a/front/src/components/library/Album.vue +++ b/front/src/components/library/Album.vue @@ -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> diff --git a/front/src/components/library/FileUpload.vue b/front/src/components/library/FileUpload.vue index dd29fa11d4c63eb326268195d2653c744aa1e114..ec5e0dd23ea1cb30ca3aa25e197f558fe09a5640 100644 --- a/front/src/components/library/FileUpload.vue +++ b/front/src/components/library/FileUpload.vue @@ -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 { diff --git a/front/src/components/library/radios/Builder.vue b/front/src/components/library/radios/Builder.vue index b50d4a55081865a5796f3ed8781bb49643b5ff57..66161d15c276e88ea0f9b150b7ef5a53879e74db 100644 --- a/front/src/components/library/radios/Builder.vue +++ b/front/src/components/library/radios/Builder.vue @@ -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> diff --git a/front/src/components/notifications/NotificationRow.vue b/front/src/components/notifications/NotificationRow.vue index 530e1527063023f9e305a13d08e7d070e904f442..e98be41ec5fc55fbba672968eab87e4fb2fd9674 100644 --- a/front/src/components/notifications/NotificationRow.vue +++ b/front/src/components/notifications/NotificationRow.vue @@ -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}}, diff --git a/front/src/components/radios/Card.vue b/front/src/components/radios/Card.vue index fc87872e8ce5c9e5579bb418e6e02d40345d8a02..9f085484180995a90bfd7bc92a94ef739e3dc523 100644 --- a/front/src/components/radios/Card.vue +++ b/front/src/components/radios/Card.vue @@ -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" diff --git a/front/src/views/admin/moderation/AccountsDetail.vue b/front/src/views/admin/moderation/AccountsDetail.vue index 685c87146b06f209ad61092eedca982a72c3b47f..9632bdb68e8afb4ca65b41a07477d41af679d249 100644 --- a/front/src/views/admin/moderation/AccountsDetail.vue +++ b/front/src/views/admin/moderation/AccountsDetail.vue @@ -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"> diff --git a/front/src/views/playlists/Detail.vue b/front/src/views/playlists/Detail.vue index 48432232ab814df695f1780c8fa9a2407edeb651..c96b8e3816da043e5749a46113b93263d5de4062 100644 --- a/front/src/views/playlists/Detail.vue +++ b/front/src/views/playlists/Detail.vue @@ -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" />