Merge branch 'gettext-output' into 'develop'

Gettext output

See merge request funkwhale/funkwhale!299
This commit is contained in:
Eliot Berriot 2018-07-01 20:21:11 +00:00
commit 644969465c
69 changed files with 1448 additions and 2298 deletions

1
.gitignore vendored
View File

@ -92,3 +92,4 @@ po/*.po
docs/swagger
_build
front/src/translations.json
front/locales/en_US/LC_MESSAGES/app.po

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
<template>
<div class="main pusher" v-title="'About This Instance'">
<div class="main pusher" v-title="labels.title">
<div class="ui vertical center aligned stripe segment">
<div class="ui text container">
<h1 class="ui huge header">
@ -49,7 +49,12 @@ export default {
computed: {
...mapState({
instance: state => state.instance.settings.instance
})
}),
labels () {
return {
title: this.$gettext('About this instance')
}
}
}
}
</script>

View File

@ -1,5 +1,5 @@
<template>
<div class="main pusher" v-title="'Welcome'">
<div class="main pusher" v-title="labels.title">
<div class="ui vertical center aligned stripe segment">
<div class="ui text container">
<h1 class="ui huge header">
@ -146,9 +146,12 @@
<script>
export default {
name: 'home',
data () {
return {}
computed: {
labels () {
return {
title: this.$gettext('Welcome')
}
}
}
}
</script>

View File

@ -1,5 +1,5 @@
<template>
<div class="main pusher" v-title="'Page Not Found'">
<div class="main pusher" :v-title="labels.title">
<div class="ui vertical stripe segment">
<div class="ui text container">
<h1 class="ui huge header">
@ -26,6 +26,13 @@ export default {
return {
path: window.location.href
}
},
computed: {
labels () {
return {
title: this.$gettext('Page Not Found')
}
}
}
}
</script>

View File

@ -70,7 +70,7 @@
<i class="book icon"></i><translate>Library</translate>
<div
:class="['ui', {'teal': $store.state.ui.notifications.importRequests > 0}, 'label']"
:title="$gettext('Pending import requests')">
:title="labels.pendingRequests">
{{ $store.state.ui.notifications.importRequests }}</div>
</router-link>
@ -87,7 +87,7 @@
<i class="sitemap icon"></i><translate>Federation</translate>
<div
:class="['ui', {'teal': $store.state.ui.notifications.federation > 0}, 'label']"
:title="$gettext('Pending follow requests')">
:title="labels.pendingFollows">
{{ $store.state.ui.notifications.federation }}</div>
</router-link>
<router-link
@ -211,6 +211,14 @@ export default {
queue: state => state.queue,
url: state => state.route.path
}),
labels () {
let pendingRequests = this.$gettext('Pending import requests')
let pendingFollows = this.$gettext('Pending follow requests')
return {
pendingRequests,
pendingFollows
}
},
showAdmin () {
let adminPermissions = [
this.$store.state.auth.availablePermissions['federation'],

View File

@ -1,7 +1,7 @@
<template>
<div :title="title" :class="['ui', {'tiny': discrete}, 'buttons']">
<button
:title="$gettext('Add to current queue')"
:title="labels.addToQueue"
@click="addNext(true)"
:disabled="!playable"
:class="['ui', {loading: isLoading}, {'mini': discrete}, {disabled: !playable}, 'button']">
@ -42,6 +42,11 @@ export default {
jQuery(this.$el).find('.ui.dropdown').dropdown()
},
computed: {
labels () {
return {
addToQueue: this.$gettext('Add to current queue')
}
},
title () {
if (this.playable) {
return this.$gettext('Play immediatly')

View File

@ -57,44 +57,50 @@
<div class="two wide column controls ui grid">
<div
:title="$gettext('Previous track')"
:title="labels.previousTrack"
class="two wide column control"
:disabled="emptyQueue">
<i @click="previous" :class="['ui', 'backward', {'disabled': emptyQueue}, 'big', 'icon']"></i>
</div>
<div
v-if="!playing"
:title="$gettext('Play track')"
:title="labels.play"
class="two wide column control">
<i @click="togglePlay" :class="['ui', 'play', {'disabled': !currentTrack}, 'big', 'icon']"></i>
</div>
<div
v-else
:title="$gettext('Pause track')"
:title="labels.pause"
class="two wide column control">
<i @click="togglePlay" :class="['ui', 'pause', {'disabled': !currentTrack}, 'big', 'icon']"></i>
</div>
<div
:title="$gettext('Next track')"
:title="labels.next"
class="two wide column control"
:disabled="!hasNext">
<i @click="next" :class="['ui', {'disabled': !hasNext}, 'step', 'forward', 'big', 'icon']" ></i>
</div>
<div class="two wide column control volume-control">
<i :title="$gettext('Unmute')" @click="$store.commit('player/volume', 1)" v-if="volume === 0" class="volume off secondary icon"></i>
<i :title="$gettext('Mute')" @click="$store.commit('player/volume', 0)" v-else-if="volume < 0.5" class="volume down secondary icon"></i>
<i :title="$gettext('Mute')" @click="$store.commit('player/volume', 0)" v-else class="volume up secondary icon"></i>
<i
:title="labels.unmute"
@click="$store.commit('player/volume', 1)" v-if="volume === 0" class="volume off secondary icon"></i>
<i
:title="labels.mute"
@click="$store.commit('player/volume', 0)" v-else-if="volume < 0.5" class="volume down secondary icon"></i>
<i
:title="labels.mute"
@click="$store.commit('player/volume', 0)" v-else class="volume up secondary icon"></i>
<input type="range" step="0.05" min="0" max="1" v-model="sliderVolume" />
</div>
<div class="two wide column control looping">
<i
:title="$gettext('Looping disabled. Click to switch to single-track looping.')"
:title="labels.loopingDisabled"
v-if="looping === 0"
@click="$store.commit('player/looping', 1)"
:disabled="!currentTrack"
:class="['ui', {'disabled': !currentTrack}, 'step', 'repeat', 'secondary', 'icon']"></i>
<i
:title="$gettext('Looping on a single track. Click to switch to whole queue looping.')"
:title="labels.loopingSingle"
v-if="looping === 1"
@click="$store.commit('player/looping', 2)"
:disabled="!currentTrack"
@ -102,7 +108,7 @@
<span class="ui circular tiny orange label">1</span>
</i>
<i
:title="$gettext('Looping on whole queue. Click to disable looping.')"
:title="labels.loopingWhole"
v-if="looping === 2"
@click="$store.commit('player/looping', 0)"
:disabled="!currentTrack"
@ -111,7 +117,7 @@
</div>
<div
:disabled="queue.tracks.length === 0"
:title="$gettext('Shuffle your queue')"
:title="labels.shuffle"
class="two wide column control">
<div v-if="isShuffling" class="ui inline shuffling inverted small active loader"></div>
<i v-else @click="shuffle()" :class="['ui', 'random', 'secondary', {'disabled': queue.tracks.length === 0}, 'icon']" ></i>
@ -119,7 +125,7 @@
<div class="one wide column"></div>
<div
:disabled="queue.tracks.length === 0"
:title="$gettext('Clear your queue')"
:title="labels.clear"
class="two wide column control">
<i @click="clean()" :class="['ui', 'trash', 'secondary', {'disabled': queue.tracks.length === 0}, 'icon']" ></i>
</div>
@ -236,6 +242,32 @@ export default {
currentTimeFormatted: 'player/currentTimeFormatted',
progress: 'player/progress'
}),
labels () {
let previousTrack = this.$gettext('Previous track')
let play = this.$gettext('Play track')
let pause = this.$gettext('Pause track')
let next = this.$gettext('Next track')
let unmute = this.$gettext('Unmute')
let mute = this.$gettext('Mute')
let loopingDisabled = this.$gettext('Looping disabled. Click to switch to single-track looping.')
let loopingSingle = this.$gettext('Looping on a single track. Click to switch to whole queue looping.')
let loopingWhole = this.$gettext('Looping on whole queue. Click to disable looping.')
let shuffle = this.$gettext('Shuffle your queue')
let clear = this.$gettext('Clear your queue')
return {
previousTrack,
play,
pause,
next,
unmute,
mute,
loopingDisabled,
loopingSingle,
loopingWhole,
shuffle,
clear
}
},
style: function () {
let style = {
'background': this.ambiantGradiant

View File

@ -4,7 +4,7 @@
<div :class="['ui', {'loading': isLoading }, 'search']">
<div class="ui icon big input">
<i class="search icon"></i>
<input ref="search" class="prompt" placeholder="Artist, album, track..." v-model.trim="query" type="text" />
<input ref="search" class="prompt" :placeholder="labels.searchPlaceholder" v-model.trim="query" type="text" />
</div>
</div>
<template v-if="query.length > 0">
@ -59,6 +59,13 @@ export default {
}
this.search()
},
computed: {
labels () {
return {
searchPlaceholder: this.$gettext('Artist, album, track...')
}
}
},
methods: {
search: _.debounce(function () {
if (this.query.length < 1) {

View File

@ -1,7 +1,7 @@
<template>
<div class="ui fluid category search">
<slot></slot><div class="ui icon input">
<input class="prompt" placeholder="Search for artists, albums, tracks..." type="text">
<input class="prompt" :placeholder="labels.placeholder" type="text">
<i class="search icon"></i>
</div>
<div class="results"></div>
@ -14,7 +14,17 @@ import jQuery from 'jquery'
import router from '@/router'
export default {
computed: {
labels () {
return {
placeholder: this.$gettext('Search for artists, albums, tracks...')
}
}
},
mounted () {
let artistLabel = this.$gettext('Artist')
let albumLabel = this.$gettext('Album')
let trackLabel = this.$gettext('Track')
let self = this
jQuery(this.$el).search({
type: 'category',
@ -39,7 +49,7 @@ export default {
{
code: 'artists',
route: 'library.artists.detail',
name: 'Artist',
name: artistLabel,
getTitle (r) {
return r.name
},
@ -50,7 +60,7 @@ export default {
{
code: 'albums',
route: 'library.albums.detail',
name: 'Album',
name: albumLabel,
getTitle (r) {
return r.title
},
@ -61,7 +71,7 @@ export default {
{
code: 'tracks',
route: 'library.tracks.detail',
name: 'Track',
name: trackLabel,
getTitle (r) {
return r.title
},

View File

@ -1,5 +1,5 @@
<template>
<div class="main pusher" v-title="'Log In'">
<div class="main pusher" v-title="labels.title">
<div class="ui vertical stripe segment">
<div class="ui small text container">
<h2><translate>Log in to your Funkwhale account</translate></h2>
@ -24,7 +24,7 @@
required
type="text"
autofocus
placeholder="Enter your username or email"
:placeholder="labels.usernamePlaceholder"
v-model="credentials.username"
>
</div>
@ -72,6 +72,16 @@ export default {
mounted () {
this.$refs.username.focus()
},
computed: {
labels () {
let usernamePlaceholder = this.$gettext('Enter your username or email')
let title = this.$gettext('Log In')
return {
usernamePlaceholder,
title
}
}
},
methods: {
submit () {
var self = this

View File

@ -1,5 +1,5 @@
<template>
<div class="main pusher" v-title="'Log Out'">
<div class="main pusher" v-title="labels.title">
<div class="ui vertical stripe segment">
<div class="ui small text container">
<h2>
@ -14,7 +14,13 @@
<script>
export default {
name: 'logout'
computed: {
labels () {
return {
title: this.$gettext('Log Out')
}
}
}
}
</script>

View File

@ -1,5 +1,5 @@
<template>
<div class="main pusher" v-title="username + '\'s Profile'">
<div class="main pusher" v-title="labels.usernameProfile">
<div v-if="isLoading" class="ui vertical segment">
<div :class="['ui', 'centered', 'active', 'inline', 'loader']"></div>
</div>
@ -39,6 +39,13 @@ export default {
this.$store.dispatch('auth/fetchProfile')
},
computed: {
labels () {
let msg = this.$gettext('%{ username }\'s profile')
let usernameProfile = this.$gettextInterpolate(msg, {username: this.username})
return {
usernameProfile
}
},
signupDate () {
let d = new Date(this.$store.state.auth.profile.date_joined)
return dateFormat(d, 'longDate')

View File

@ -1,5 +1,5 @@
<template>
<div class="main pusher" v-title="'Account Settings'">
<div class="main pusher" v-title="labels.title">
<div class="ui vertical stripe segment">
<div class="ui small text container">
<h2 class="ui header">
@ -63,7 +63,7 @@
<translate>Change password</translate>
<p slot="modal-header"><translate>Change your password?</translate></p>
<div slot="modal-content">
<p>{{ $gettext("Changing your password will have the following consequences") }}</p>
<p><translate>Changing your password will have the following consequences</translate></p>
<ul>
<li><translate>You will be logged out from this session and have to log out with the new one</translate></li>
<li><translate>Your Subsonic password will be changed to a new, random one, logging you out from devices that used the old Subsonic password</translate></li>
@ -175,6 +175,11 @@ export default {
}
},
computed: {
labels () {
return {
title: this.$gettext('Account Settings')
}
},
orderedSettingsFields () {
let self = this
return this.settings.order.map(id => {

View File

@ -1,8 +1,8 @@
<template>
<div class="main pusher" v-title="'Sign Up'">
<div class="main pusher" v-title="labels.title">
<div class="ui vertical stripe segment">
<div class="ui small text container">
<h2>{{ $gettext("Create a funkwhale account") }}</h2>
<h2><translate>Create a funkwhale account</translate></h2>
<form
:class="['ui', {'loading': isLoadingInstanceSetting}, 'form']"
@submit.prevent="submit()">
@ -11,45 +11,45 @@
</p>
<div v-if="errors.length > 0" class="ui negative message">
<div class="header">{{ $gettext("We cannot create your account") }}</div>
<div class="header"><translate>We cannot create your account</translate></div>
<ul class="list">
<li v-for="error in errors">{{ error }}</li>
</ul>
</div>
<div class="field">
<label>{{ $gettext("Username") }}</label>
<label><translate>Username</translate></label>
<input
ref="username"
required
type="text"
autofocus
placeholder="Enter your username"
:placeholder="labels.usernamePlaceholder"
v-model="username">
</div>
<div class="field">
<label>{{ $gettext("Email") }}</label>
<label><translate>Email</translate></label>
<input
ref="email"
required
type="email"
placeholder="Enter your email"
:placeholder="labels.emailPlaceholder"
v-model="email">
</div>
<div class="field">
<label>{{ $gettext("Password") }}</label>
<label><translate>Password</translate></label>
<password-input v-model="password" />
</div>
<div class="field">
<label v-if="!$store.state.instance.settings.users.registration_enabled.value">{{ $gettext("Invitation code") }}</label>
<label v-else>{{ $gettext("Invitation code (optional)") }}</label>
<label v-if="!$store.state.instance.settings.users.registration_enabled.value"><translate>Invitation code</translate></label>
<label v-else><translate>Invitation code (optional)</translate></label>
<input
:required="!$store.state.instance.settings.users.registration_enabled.value"
type="text"
:placeholder="$gettext('Enter your invitation code (case insensitive)')"
:placeholder="labels.placeholder"
v-model="invitation">
</div>
<button :class="['ui', 'green', {'loading': isLoading}, 'button']" type="submit">
{{ $gettext("Create my account") }}
<translate>Create my account</translate>
</button>
</form>
</div>
@ -89,6 +89,20 @@ export default {
}
})
},
computed: {
labels () {
let title = this.$gettext('Sign Up')
let placeholder = this.$gettext('Enter your invitation code (case insensitive)')
let usernamePlaceholder = this.$gettext('Enter your username')
let emailPlaceholder = this.$gettext('Enter your email')
return {
title,
usernamePlaceholder,
emailPlaceholder,
placeholder
}
}
},
methods: {
submit () {
var self = this

View File

@ -35,7 +35,7 @@
</translate>
</p>
<p slot="modal-content">
{{ $gettext('This may affect a lot of elements, please double check this is really what you want.')}}
<translate>This may affect a lot of elements, please double check this is really what you want.</translate>
</p>
<p slot="modal-confirm"><translate>Launch</translate></p>
</dangerous-button>

View File

@ -1,5 +1,5 @@
<template>
<div class="main pusher" v-title="'Your Favorites'">
<div class="main pusher" v-title="labels.title">
<div class="ui vertical center aligned stripe segment">
<div :class="['ui', {'active': isLoading}, 'inverted', 'dimmer']">
<div class="ui text loader">
@ -103,6 +103,13 @@ export default {
mounted () {
$('.ui.dropdown').dropdown()
},
computed: {
labels () {
return {
title: this.$gettext('Your Favorites')
}
}
},
methods: {
updateQueryString: function () {
this.$router.replace({

View File

@ -3,7 +3,7 @@
<div class="ui form">
<div class="fields">
<div class="ui six wide field">
<input type="text" v-model="search" placeholder="Search by username, domain..." />
<input type="text" v-model="search" :placeholder="labels.searchPlaceholder" />
</div>
<div class="ui four wide inline field">
<div class="ui checkbox">
@ -134,6 +134,13 @@ export default {
created () {
this.fetchData()
},
computed: {
labels () {
return {
searchPlaceholder: this.$gettext('Search by username, domain...')
}
}
},
methods: {
fetchData () {
let params = _.merge({

View File

@ -20,7 +20,7 @@
<label>
<translate>Library name</translate>
</label>
<input v-model="libraryUsername" type="text" placeholder="library@demo.funkwhale.audio" />
<input v-model="libraryUsername" type="text" :placeholder="labels.namePlaceholder" />
</div>
<div class="ui field">
<label>&nbsp;</label>
@ -91,6 +91,11 @@ export default {
}
},
computed: {
labels () {
return {
namePlaceholder: this.$gettext('library@demo.funkwhale.audio')
}
},
scanErrors () {
let errors = []
if (!this.result) {

View File

@ -4,7 +4,7 @@
<div class="fields">
<div class="ui field">
<label><translate>Search</translate></label>
<input type="text" v-model="search" placeholder="Search by title, artist, domain..." />
<input type="text" v-model="search" :placeholder="labels.searchPlaceholder" />
</div>
<div class="ui field">
<label><translate>Import status</translate></label>
@ -145,6 +145,11 @@ export default {
}
},
computed: {
labels () {
return {
searchPlaceholder: this.$gettext('Search by title, artist, domain...')
}
},
actionFilters () {
var currentFilters = {
q: this.search

View File

@ -6,7 +6,7 @@
:type="passwordInputType"
@input="$emit('input', $event.target.value)"
:value="value">
<span @click="showPassword = !showPassword" :title="$gettext('Show/hide password')" class="ui icon button">
<span @click="showPassword = !showPassword" :title="labels.title" class="ui icon button">
<i class="eye icon"></i>
</span>
</div>
@ -20,6 +20,11 @@ export default {
}
},
computed: {
labels () {
return {
title: this.$gettext('Show/hide password')
}
},
passwordInputType () {
if (this.showPassword) {
return 'text'

View File

@ -28,7 +28,7 @@
</div>
</div>
<div class="column">
<h3 class="ui left aligned header">Library</h3>
<h3 class="ui left aligned header"><translate>Library</translate></h3>
<div class="ui mini horizontal statistics">
<div class="statistic">
<div class="value">

View File

@ -1,6 +1,6 @@
<template>
<div>
<div v-if="isLoading" class="ui vertical segment" v-title="'Album'">
<div v-if="isLoading" class="ui vertical segment" v-title="">
<div :class="['ui', 'centered', 'active', 'inline', 'loader']"></div>
</div>
<template v-if="album">
@ -86,6 +86,11 @@ export default {
}
},
computed: {
labels () {
return {
title: this.$gettext('Album')
}
},
wikipediaUrl () {
return 'https://en.wikipedia.org/w/index.php?search=' + this.album.title + ' ' + this.album.artist.name
},

View File

@ -1,6 +1,6 @@
<template>
<div>
<div v-if="isLoading" class="ui vertical segment" v-title="'Artist'">
<div v-if="isLoading" class="ui vertical segment" v-title="labels.title">
<div :class="['ui', 'centered', 'active', 'inline', 'loader']"></div>
</div>
<template v-if="artist">
@ -103,6 +103,11 @@ export default {
}
},
computed: {
labels () {
return {
title: this.$gettext('Artist')
}
},
totalTracks () {
return this.albums.map((album) => {
return album.tracks.length

View File

@ -1,5 +1,5 @@
<template>
<div v-title="'Artists'">
<div v-title="labels.title">
<div class="ui vertical stripe segment">
<h2 class="ui header">
<translate>Browsing artists</translate>
@ -10,7 +10,7 @@
<label>
<translate>Search</translate>
</label>
<input type="text" v-model="query" placeholder="Enter an artist name..."/>
<input type="text" v-model="query" :placeholder="labels.searchPlaceholder"/>
</div>
<div class="field">
<label><translate>Ordering</translate></label>
@ -23,8 +23,8 @@
<div class="field">
<label><translate>Ordering direction</translate></label>
<select class="ui dropdown" v-model="orderingDirection">
<option value="+">Ascending</option>
<option value="-">Descending</option>
<option value="+"><translate>Ascending</translate></option>
<option value="-"><translate>Descending</translate></option>
</select>
</div>
<div class="field">
@ -113,6 +113,16 @@ export default {
mounted () {
$('.ui.dropdown').dropdown()
},
computed: {
labels () {
let searchPlaceholder = this.$gettext('Enter an artist name...')
let title = this.$gettext('Artists')
return {
searchPlaceholder,
title
}
}
},
methods: {
updateQueryString: _.debounce(function () {
this.$router.replace({

View File

@ -1,5 +1,5 @@
<template>
<div v-title="'Home'">
<div v-title="labels.title">
<div class="ui vertical stripe segment">
<search :autofocus="true"></search>
</div>
@ -60,6 +60,13 @@ export default {
created () {
this.fetchArtists()
},
computed: {
labels () {
return {
title: this.$gettext('Home')
}
}
},
methods: {
fetchArtists () {
var self = this

View File

@ -1,5 +1,5 @@
<template>
<div v-title="'Radios'">
<div v-title="labels.title">
<div class="ui vertical stripe segment">
<h2 class="ui header">
<translate>Browsing radios</translate>
@ -12,7 +12,7 @@
<div class="fields">
<div class="field">
<label><translate>Search</translate></label>
<input type="text" v-model="query" placeholder="Enter a radio name..."/>
<input type="text" v-model="query" :placeholder="labels.searchPlaceholder"/>
</div>
<div class="field">
<label><translate>Ordering</translate></label>
@ -119,6 +119,16 @@ export default {
mounted () {
$('.ui.dropdown').dropdown()
},
computed: {
labels () {
let searchPlaceholder = this.$gettext('Enter a radio name...')
let title = this.$gettext('Radios')
return {
searchPlaceholder,
title
}
}
},
methods: {
updateQueryString: _.debounce(function () {
this.$router.replace({

View File

@ -1,6 +1,6 @@
<template>
<div>
<div v-if="isLoadingTrack" class="ui vertical segment" v-title="'Track'">
<div v-if="isLoadingTrack" class="ui vertical segment" v-title="labels.title">
<div :class="['ui', 'centered', 'active', 'inline', 'loader']"></div>
</div>
<template v-if="track">
@ -169,6 +169,11 @@ export default {
}
},
computed: {
labels () {
return {
title: this.$gettext('Track')
}
},
wikipediaUrl () {
return 'https://en.wikipedia.org/w/index.php?search=' + this.track.title + ' ' + this.track.artist.name
},

View File

@ -1,7 +1,7 @@
<template>
<div>
<h3 class="ui dividing block header">
<a :href="getMusicbrainzUrl('artist', metadata.id)" target="_blank" title="View on MusicBrainz">{{ metadata.name }}</a>
<a :href="getMusicbrainzUrl('artist', metadata.id)" target="_blank" :title="labels.viewOnMusicbrainz">{{ metadata.name }}</a>
</h3>
<form class="ui form" @submit.prevent="">
<h6 class="ui header">
@ -126,6 +126,11 @@ export default Vue.extend({
}
},
computed: {
labels () {
return {
viewOnMusicbrainz: this.$gettext('View on MusicBrainz')
}
},
type () {
return 'artist'
},

View File

@ -1,5 +1,5 @@
<template>
<div v-title="'Import Batch #' + id">
<div v-title="labels.title">
<div v-if="isLoading && !batch" class="ui vertical segment">
<div :class="['ui', 'centered', 'active', 'inline', 'loader']"></div>
</div>
@ -47,7 +47,7 @@
v-if="stats.errored > 0"
class="ui tiny basic icon button">
<i class="redo icon" />
{{ $gettext('Rerun errored jobs')}}
<translate>Rerun errored jobs</translate>
</button>
</td>
</tr>
@ -61,7 +61,7 @@
<div class="fields">
<div class="ui field">
<label><translate>Search</translate></label>
<input type="text" v-model="jobFilters.search" placeholder="Search by source..." />
<input type="text" v-model="jobFilters.search" :placeholder="labels.searchPlaceholder" />
</div>
<div class="ui field">
<label><translate>Status</translate></label>
@ -103,7 +103,7 @@
<button
@click="rerun({batches: [], jobs: [job.id]})"
v-if="job.status === 'errored'"
:title="$gettext('Rerun job')"
:title="labels.rerun"
class="ui tiny basic icon button">
<i class="redo icon" />
</button>
@ -180,6 +180,19 @@ export default {
clearTimeout(this.timeout)
}
},
computed: {
labels () {
let msg = this.$gettext('Import Batch #%{ id }')
let title = this.$gettextInterpolate(msg, {id: this.id})
let rerun = this.$gettext('Rerun job')
let searchPlaceholder = this.$gettext('Search by source...')
return {
title,
searchPlaceholder,
rerun
}
}
},
methods: {
fetchData () {
var self = this

View File

@ -1,12 +1,12 @@
<template>
<div v-title="'Import Batches'">
<div v-title="labels.title">
<div class="ui vertical stripe segment">
<div v-if="isLoading" :class="['ui', 'centered', 'active', 'inline', 'loader']"></div>
<div class="ui inline form">
<div class="fields">
<div class="ui field">
<label><translate>Search</translate></label>
<input type="text" v-model="filters.search" placeholder="Search by submitter, source..." />
<input type="text" v-model="filters.search" :placeholder="labels.searchPlaceholder" />
</div>
<div class="ui field">
<label><translate>Status</translate></label>
@ -111,6 +111,16 @@ export default {
created () {
this.fetchData()
},
computed: {
labels () {
let searchPlaceholder = this.$gettext('Search by submitter, source...')
let title = this.$gettext('Import Batches')
return {
searchPlaceholder,
title
}
}
},
methods: {
fetchData () {
let params = {

View File

@ -1,5 +1,5 @@
<template>
<div v-title="'Import Music'">
<div v-title="labels.title">
<div class="ui vertical stripe segment">
<div class="ui top three attached ordered steps">
<a @click="currentStep = 0" :class="['step', {'active': currentStep === 0}, {'completed': currentStep > 0}]">
@ -112,7 +112,7 @@
<p><translate>You can also skip this step and enter metadata manually.</translate></p>
</div>
<div class="column">
<h5 class="ui header">What is metadata?</h5>
<h5 class="ui header"><translate>What is metadata?</translate></h5>
<template v-translate>
Metadata is the data related to the music you want to import. This includes all the information about the artists, albums and tracks. In order to have a high quality library, it is recommended to grab data from the
<a href="https://musicbrainz.org" target="_blank">
@ -262,6 +262,11 @@ export default {
}
},
computed: {
labels () {
return {
title: this.$gettext('Import Music')
}
},
metadataComponent () {
if (this.currentType === 'artist') {
return 'ArtistCard'

View File

@ -1,5 +1,5 @@
<template>
<div class="ui vertical stripe segment" v-title="'Radio Builder'">
<div class="ui vertical stripe segment" v-title="labels.title">
<div>
<div>
<h2 class="ui header">
@ -10,7 +10,7 @@
<div class="inline fields">
<div class="field">
<label for="name"><translate>Radio name</translate></label>
<input id="name" type="text" v-model="radioName" placeholder="My awesome radio" />
<input id="name" type="text" v-model="radioName" :placeholder="labels.placeholder" />
</div>
<div class="field">
<input id="public" type="checkbox" v-model="isPublic" />
@ -201,6 +201,14 @@ export default {
}
},
computed: {
labels () {
let title = this.$gettext('Radio Builder')
let placeholder = this.$gettext('My awesome radio')
return {
title,
placeholder
}
},
canSave: function () {
return (
this.radioName.length > 0 && this.checkErrors.length === 0

View File

@ -4,7 +4,7 @@
<div class="fields">
<div class="ui field">
<label><translate>Search</translate></label>
<input type="text" v-model="search" placeholder="Search by title, artist, domain..." />
<input type="text" v-model="search" :placeholder="labels.searchPlaceholder" />
</div>
<div class="field">
<label><translate>Ordering</translate></label>
@ -17,8 +17,8 @@
<div class="field">
<label><translate>Ordering direction</translate></label>
<select class="ui dropdown" v-model="orderingDirection">
<option value="+">Ascending</option>
<option value="-">Descending</option>
<option value="+"><translate>Ascending</translate></option>
<option value="-"><translate>Descending</translate></option>
</select>
</div>
</div>
@ -170,6 +170,11 @@ export default {
}
},
computed: {
labels () {
return {
searchPlaceholder: this.$gettext('Search by title, artist, domain...')
}
},
actionFilters () {
var currentFilters = {
q: this.search

View File

@ -4,7 +4,7 @@
<div class="fields">
<div class="ui field">
<label><translate>Search</translate></label>
<input type="text" v-model="search" placeholder="Search by artist, username, comment..." />
<input type="text" v-model="search" :placeholder="labels.searchPlaceholder" />
</div>
<div class="field">
<label><translate>Ordering</translate></label>
@ -17,12 +17,12 @@
<div class="field">
<label><translate>Ordering direction</translate></label>
<select class="ui dropdown" v-model="orderingDirection">
<option value="+">Ascending</option>
<option value="-">Descending</option>
<option value="+"><translate>Ascending</translate></option>
<option value="-"><translate>Descending</translate></option>
</select>
</div>
<div class="field">
<label>{{ $gettext("Status") }}</label>
<label><translate>Status</translate></label>
<select class="ui dropdown" v-model="status">
<option :value="null"><translate>All</translate></option>
<option :value="'pending'"><translate>Pending</translate></option>
@ -175,6 +175,11 @@ export default {
}
},
computed: {
labels () {
return {
searchPlaceholder: this.$gettext('Search by artist, username, comment...')
}
},
actionFilters () {
var currentFilters = {
q: this.search

View File

@ -9,8 +9,8 @@
</div>
<div class="inline fields">
<div class="ui field">
<label>{{ $gettext('Invitation code')}}</label>
<input type="text" v-model="code" :placeholder="$gettext('Leave empty for a random code')" />
<label><translate>Invitation code</translate></label>
<input type="text" v-model="code" :placeholder="labels.placeholder" />
</div>
<div class="ui field">
<button :class="['ui', {loading: isLoading}, 'button']" :disabled="isLoading" type="submit">
@ -52,6 +52,13 @@ export default {
errors: []
}
},
computed: {
labels () {
return {
placeholder: this.$gettext('Leave empty for a random code')
}
}
},
methods: {
submit () {
let self = this

View File

@ -4,10 +4,10 @@
<div class="fields">
<div class="ui field">
<label><translate>Search</translate></label>
<input type="text" v-model="search" placeholder="Search by username, email, code..." />
<input type="text" v-model="search" :placeholder="labels.searchPlaceholder" />
</div>
<div class="field">
<label>{{ $gettext("Ordering") }}</label>
<label><translate>Ordering</translate></label>
<select class="ui dropdown" v-model="ordering">
<option v-for="option in orderingOptions" :value="option[0]">
{{ option[1] }}
@ -15,7 +15,7 @@
</select>
</div>
<div class="field">
<label>{{ $gettext("Status") }}</label>
<label><translate>Status</translate></label>
<select class="ui dropdown" v-model="isOpen">
<option :value="null"><translate>All</translate></option>
<option :value="true"><translate>Open</translate></option>
@ -147,6 +147,11 @@ export default {
}
},
computed: {
labels () {
return {
searchPlaceholder: this.$gettext('Search by username, email, code...')
}
},
actionFilters () {
var currentFilters = {
q: this.search

View File

@ -4,7 +4,7 @@
<div class="fields">
<div class="ui field">
<label><translate>Search</translate></label>
<input type="text" v-model="search" placeholder="Search by username, email, name..." />
<input type="text" v-model="search" :placeholder="labels.searchPlaceholder" />
</div>
<div class="field">
<label><translate>Ordering</translate></label>
@ -157,6 +157,11 @@ export default {
}
},
computed: {
labels () {
return {
searchPlaceholder: this.$gettext('Search by username, email, name...')
}
},
privacyLevels () {
return {}
},

View File

@ -6,7 +6,7 @@
</div>
<template v-if="data.id">
<div class="header">
<a :href="getMusicbrainzUrl('artist', data.id)" target="_blank" title="View on MusicBrainz">{{ data.name }}</a>
<a :href="getMusicbrainzUrl('artist', data.id)" target="_blank" :title="labels.musicbrainz">{{ data.name }}</a>
</div>
<div class="description">
<table class="ui very basic fixed single line compact table">
@ -16,7 +16,7 @@
{{ group['first-release-date'] }}
</td>
<td colspan="3">
<a :href="getMusicbrainzUrl('release-group', group.id)" class="discrete link" target="_blank" :title="$gettext('View on MusicBrainz')">
<a :href="getMusicbrainzUrl('release-group', group.id)" class="discrete link" target="_blank" :title="labels.musicbrainz">
{{ group.title }}
</a>
</td>
@ -44,6 +44,11 @@ export default Vue.extend({
}
},
computed: {
labels () {
return {
musicbrainz: this.$gettext('View on MusicBrainz')
}
},
type () {
return 'artist'
},

View File

@ -6,10 +6,10 @@
</div>
<template v-if="data.id">
<div class="header">
<a :href="getMusicbrainzUrl('release', data.id)" target="_blank" title="View on MusicBrainz">{{ data.title }}</a>
<a :href="getMusicbrainzUrl('release', data.id)" target="_blank" :title="labels.musicbrainz">{{ data.title }}</a>
</div>
<div class="meta">
<a :href="getMusicbrainzUrl('artist', data['artist-credit'][0]['artist']['id'])" target="_blank" title="View on MusicBrainz">{{ data['artist-credit-phrase'] }}</a>
<a :href="getMusicbrainzUrl('artist', data['artist-credit'][0]['artist']['id'])" target="_blank" :title="labels.musicbrainz">{{ data['artist-credit-phrase'] }}</a>
</div>
<div class="description">
<table class="ui very basic fixed single line compact table">
@ -19,7 +19,7 @@
{{ track.position }}
</td>
<td colspan="3">
<a :href="getMusicbrainzUrl('recording', track.id)" class="discrete link" target="_blank" :title="$gettext('View on MusicBrainz')">
<a :href="getMusicbrainzUrl('recording', track.id)" class="discrete link" target="_blank" :title="labels.musicbrainz">
{{ track.recording.title }}
</a>
</td>
@ -48,6 +48,11 @@ export default Vue.extend({
}
},
computed: {
labels () {
return {
musicbrainz: this.$gettext('View on MusicBrainz')
}
},
type () {
return 'release'
},

View File

@ -12,7 +12,7 @@
</div>
<div class="ui fluid search">
<div class="ui icon input">
<input class="prompt" :placeholder="$gettext('Enter your search query...')" type="text">
<input class="prompt" :placeholder="labels.placeholder" type="text">
<i class="search icon"></i>
</div>
<div class="results"></div>
@ -109,6 +109,11 @@ export default {
}
},
computed: {
labels () {
return {
placeholder: this.$gettext('Enter your search query...')
}
},
currentTypeObject: function () {
let self = this
return this.types.filter(t => {

View File

@ -24,7 +24,7 @@
%{ count} track
</translate>
</span>
<play-button class="mini basic orange right floated" :playlist="playlist">Play all</play-button>
<play-button class="mini basic orange right floated" :playlist="playlist"><translate>Play all</translate></play-button>
</div>
</div>
</template>

View File

@ -27,7 +27,7 @@
@click="insertMany(queueTracks)"
:disabled="queueTracks.length === 0"
:class="['ui', {disabled: queueTracks.length === 0}, 'labeled', 'icon', 'button']"
title="Copy tracks from current queue to playlist">
:title="labels.copyTitle">
<i class="plus icon"></i>
<translate
translate-plural="Insert from queue (%{ count } tracks)"
@ -47,7 +47,7 @@
</dangerous-button>
<div class="ui hidden divider"></div>
<template v-if="plts.length > 0">
<p>Drag and drop rows to reorder tracks in the playlist</p>
<p><translate>Drag and drop rows to reorder tracks in the playlist</translate></p>
<table class="ui compact very basic fixed single line unstackable table">
<draggable v-model="plts" element="tbody" @update="reorder">
<tr v-for="(plt, index) in plts" :key="plt.id">
@ -158,6 +158,11 @@ export default {
...mapState({
queueTracks: state => state.queue.tracks
}),
labels () {
return {
copyTitle: this.$gettext('Copy tracks from current queue to playlist')
}
},
status () {
if (this.isLoading) {
return 'loading'

View File

@ -20,7 +20,7 @@
<div class="three fields">
<div class="field">
<label><translate>Playlist name</translate></label>
<input v-model="name" required type="text" placeholder="My awesome playlist" />
<input v-model="name" required type="text" :placeholder="labels.placeholder" />
</div>
<div class="field">
<label><translate>Playlist visibility</translate></label>
@ -69,6 +69,11 @@ export default {
return d
},
computed: {
labels () {
return {
placeholder: this.$gettext('My awesome playlist')
}
},
privacyLevelChoices: function () {
return [
{

View File

@ -50,7 +50,7 @@
<div
v-if="track"
class="ui green icon basic small right floated button"
:title="$gettext('Add to this playlist')"
:title="labels.addToPlaylist"
@click="addToPlaylist(playlist.id)">
<i class="plus icon"></i> <translate>Add track</translate>
</div>
@ -110,6 +110,11 @@ export default {
playlists: state => state.playlists.playlists,
track: state => state.playlists.modalTrack
}),
labels () {
return {
addToPlaylist: this.$gettext('Add to this playlist')
}
},
sortedPlaylists () {
let p = _.sortBy(this.playlists, [(e) => { return e.modification_date }])
p.reverse()

View File

@ -10,7 +10,7 @@
v-else
@click="$store.commit('playlists/chooseTrack', track)"
:class="['playlist-icon', 'list', 'link', 'icon']"
:title="$gettext('Add to playlist...')">
:title="labels.addToPlaylist">
</i>
</template>
@ -25,6 +25,13 @@ export default {
return {
showModal: false
}
},
computed: {
labels () {
return {
addToPlaylist: this.$gettext('Add to playlist...')
}
}
}
}
</script>

View File

@ -4,21 +4,21 @@
<p><translate>Something's missing in the library? Let us know what you would like to listen!</translate></p>
<div class="required field">
<label><translate>Artist name</translate></label>
<input v-model="currentArtistName" placeholder="The Beatles, Mickael Jackson…" required maxlength="200">
<input v-model="currentArtistName" :placeholder="labels.artistNamePlaceholder" required maxlength="200">
</div>
<div class="field">
<label><translate>Albums</translate></label>
<p><translate>Leave this field empty if you're requesting the whole discography.</translate></p>
<input v-model="currentAlbums" placeholder="The White Album, Thriller…" maxlength="2000">
<input v-model="currentAlbums" :placeholder="labels.albumTitlePlaceholder" maxlength="2000">
</div>
<div class="field">
<label><translate>Comment</translate></label>
<textarea v-model="currentComment" rows="3" placeholder="Use this comment box to add details to your request if needed" maxlength="2000"></textarea>
<textarea v-model="currentComment" rows="3" :placeholder="comentPlaceholder" maxlength="2000"></textarea>
</div>
<button class="ui submit button" type="submit"><translate>Submit</translate></button>
</form>
<div v-else class="ui success message">
<div class="header">Request submitted!</div>
<div class="header"><translate>Request submitted!</translate></div>
<p><translate>We've received your request, you'll get some groove soon ;)</translate></p>
<button @click="reset" class="ui button"><translate>Submit another request</translate></button>
</div>
@ -68,6 +68,18 @@ export default {
requests: []
}
},
computed: {
labels () {
let artistNamePlaceholder = this.$gettext('The Beatles, Mickael Jackson…')
let albumTitlePlaceholder = this.$gettext('The White Album, Thriller…')
let commentPlaceholder = this.$gettext('Use this comment box to add details to your request if needed')
return {
artistNamePlaceholder,
albumTitlePlaceholder,
commentPlaceholder
}
}
},
methods: {
fetchRequests () {
let self = this

View File

@ -1,5 +1,5 @@
<template>
<div class="main pusher" v-title="$gettext('Instance settings')">
<div class="main pusher" v-title="labels.settings">
<div class="ui vertical stripe segment">
<div class="ui text container">
<div :class="['ui', {'loading': isLoading}, 'form']"></div>
@ -70,6 +70,11 @@ export default {
}
},
computed: {
labels () {
return {
settings: this.$gettext('Instance settings')
}
},
groups () {
// somehow, extraction fails if in the return block directly
let instanceLabel = this.$gettext('Instance information')

View File

@ -1,5 +1,5 @@
<template>
<div class="main pusher" v-title="'Manage library'">
<div class="main pusher" v-title="labels.title">
<div class="ui secondary pointing menu">
<router-link
class="ui item"
@ -10,7 +10,7 @@
<translate>Import requests</translate>
<div
:class="['ui', {'teal': $store.state.ui.notifications.importRequests > 0}, 'label']"
:title="$gettext('Pending import requests')">
:title="labels.pendingRequests">
{{ $store.state.ui.notifications.importRequests }}</div>
</router-link>
</div>
@ -19,7 +19,18 @@
</template>
<script>
export default {}
export default {
computed: {
labels () {
let title = this.$gettext('Manage library')
let pendingRequests = this.$gettext('Pending import requests')
return {
title,
pendingRequests
}
}
}
}
</script>
<style lang="scss">

View File

@ -1,5 +1,5 @@
<template>
<div v-title="'Files'">
<div v-title="labels.title">
<div class="ui vertical stripe segment">
<h2 class="ui header"><translate>Library files</translate></h2>
<div class="ui hidden divider"></div>
@ -14,6 +14,13 @@ import LibraryFilesTable from '@/components/manage/library/FilesTable'
export default {
components: {
LibraryFilesTable
},
computed: {
labels () {
return {
title: this.$gettext('Files')
}
}
}
}
</script>

View File

@ -1,5 +1,5 @@
<template>
<div v-title="$gettext('Import requests')">
<div v-title="labels.importRequests">
<div class="ui vertical stripe segment">
<h2 class="ui header"><translate>Import requests</translate></h2>
<div class="ui hidden divider"></div>
@ -14,6 +14,13 @@ import LibraryRequestsTable from '@/components/manage/library/RequestsTable'
export default {
components: {
LibraryRequestsTable
},
computed: {
labels () {
return {
importRequests: this.$gettext('Import requests')
}
}
}
}
</script>

View File

@ -1,5 +1,5 @@
<template>
<div class="main pusher" v-title="$gettext('Manage users')">
<div class="main pusher" v-title="labels.manageUsers">
<div class="ui secondary pointing menu">
<router-link
class="ui item"
@ -13,7 +13,15 @@
</template>
<script>
export default {}
export default {
computed: {
labels () {
return {
manageUsers: this.$gettext('Manage users')
}
}
}
}
</script>
<style lang="scss">

View File

@ -1,5 +1,5 @@
<template>
<div v-title="$gettext('Invitations')">
<div v-title="labels.invitations">
<div class="ui vertical stripe segment">
<h2 class="ui header"><translate>Invitations</translate></h2>
<invitation-form></invitation-form>
@ -17,6 +17,13 @@ export default {
components: {
InvitationForm,
InvitationsTable
},
computed: {
labels () {
return {
invitations: this.$gettext('Invitations')
}
}
}
}
</script>

View File

@ -53,7 +53,7 @@
<tr>
<td>
<translate>Account active</translate>
<span :data-tooltip="$gettext('Determine if the user account is active or not. Inactive users cannot login or user the service.')"><i class="question circle icon"></i></span>
<span :data-tooltip="labels.inactive"><i class="question circle icon"></i></span>
</td>
<td>
<div class="ui toggle checkbox">
@ -141,6 +141,11 @@ export default {
}
},
computed: {
labels () {
return {
inactive: this.$gettext('Determine if the user account is active or not. Inactive users cannot login or user the service.')
}
},
allPermissions () {
return [
{

View File

@ -1,5 +1,5 @@
<template>
<div v-title="$gettext('Users')">
<div v-title="labels.users">
<div class="ui vertical stripe segment">
<h2 class="ui header"><translate>Users</translate></h2>
<div class="ui hidden divider"></div>
@ -14,6 +14,13 @@ import UsersTable from '@/components/manage/users/UsersTable'
export default {
components: {
UsersTable
},
computed: {
labels () {
return {
users: this.$gettext('Users')
}
}
}
}
</script>

View File

@ -1,5 +1,5 @@
<template>
<div class="main pusher" v-title="$gettext('Confirm your email')">
<div class="main pusher" v-title="labels.confirm">
<div class="ui vertical stripe segment">
<div class="ui small text container">
<h2><translate>Confirm your email</translate></h2>
@ -45,6 +45,13 @@ export default {
success: false
}
},
computed: {
labels () {
return {
confirm: this.$gettext('Confirm your email')
}
}
},
methods: {
submit () {
let self = this

View File

@ -1,5 +1,5 @@
<template>
<div class="main pusher" v-title="$gettext('Reset your password')">
<div class="main pusher" v-title="labels.reset">
<div class="ui vertical stripe segment">
<div class="ui small text container">
<h2><translate>Reset your password</translate></h2>
@ -18,7 +18,7 @@
ref="email"
type="email"
autofocus
:placeholder="$gettext('Input the email address binded to your account')"
:placeholder="labels.placeholder"
v-model="email">
</div>
<router-link :to="{path: '/login'}">
@ -47,6 +47,16 @@ export default {
mounted () {
this.$refs.email.focus()
},
computed: {
labels () {
let reset = this.$gettext('Reset your password')
let placeholder = this.$gettext('Input the email address binded to your account')
return {
reset,
placeholder
}
}
},
methods: {
submit () {
let self = this

View File

@ -1,5 +1,5 @@
<template>
<div class="main pusher" v-title="$gettext('Change your password')">
<div class="main pusher" v-title="labels.changePassword">
<div class="ui vertical stripe segment">
<div class="ui small text container">
<h2><translate>Change your password</translate></h2>
@ -56,6 +56,13 @@ export default {
success: false
}
},
computed: {
labels () {
return {
changePassword: this.$gettext('Change your password')
}
}
},
methods: {
submit () {
let self = this

View File

@ -1,5 +1,5 @@
<template>
<div class="main pusher" v-title="'Federation'">
<div class="main pusher" v-title="labels.title">
<div class="ui secondary pointing menu">
<router-link
class="ui item"
@ -12,7 +12,7 @@
class="ui item"
:to="{name: 'federation.followers.list'}">
<translate>Followers</translate>
<div class="ui teal label" :title="$gettext('Pending requests')">{{ requestsCount }}</div>
<div class="ui teal label" :title="labels.pendingRequests">{{ requestsCount }}</div>
</router-link>
</div>
</div>
@ -30,6 +30,16 @@ export default {
created () {
this.fetchRequestsCount()
},
computed: {
labels () {
let title = this.$gettext('Federation')
let pendingRequests = this.$gettext('Pending requests')
return {
title,
pendingRequests
}
}
},
methods: {
fetchRequestsCount () {
let self = this

View File

@ -1,6 +1,6 @@
<template>
<div>
<div v-if="isLoading" class="ui vertical segment" v-title="'Library'">
<div v-if="isLoading" class="ui vertical segment" v-title="labels.title">
<div :class="['ui', 'centered', 'active', 'inline', 'loader']"></div>
</div>
<template v-if="object">
@ -20,7 +20,7 @@
<tr>
<td >
<translate>Follow status</translate>
<span :data-tooltip="$gettext('This indicate if the remote library granted you access')"><i class="question circle icon"></i></span>
<span :data-tooltip="labels.statusTooltip"><i class="question circle icon"></i></span>
</td>
<td>
<template v-if="object.follow.approved === null">
@ -39,7 +39,7 @@
<tr>
<td>
<translate>Federation</translate>
<span :data-tooltip="$gettext('Use this flag to enable/disable federation with this library')"><i class="question circle icon"></i></span>
<span :data-tooltip="labels.federationTooltip"><i class="question circle icon"></i></span>
</td>
<td>
<div class="ui toggle checkbox">
@ -55,7 +55,7 @@
<tr>
<td>
<translate>Auto importing</translate>
<span :data-tooltip="$gettext('When enabled, auto importing will automatically import new tracks published in this library')"><i class="question circle icon"></i></span>
<span :data-tooltip="labels.autoImportTooltip"><i class="question circle icon"></i></span>
</td>
<td>
<div class="ui toggle checkbox">
@ -69,7 +69,7 @@
</tr>
<!-- Disabled until properly implemented on the backend
<tr>
<td>File mirroring</td>
<td><translate>File mirroring</translate></td>
<td>
<div class="ui toggle checkbox">
<input
@ -190,6 +190,18 @@ export default {
}
},
computed: {
labels () {
let title = this.$gettext('Library')
let statusTooltip = this.$gettext('This indicate if the remote library granted you access')
let federationTooltip = this.$gettext('Use this flag to enable/disable federation with this library')
let autoImportTooltip = this.$gettext('When enabled, auto importing will automatically import new tracks published in this library')
return {
title,
statusTooltip,
federationTooltip,
autoImportTooltip
}
},
libraryUsername () {
let actor = this.object.actor
return `${actor.preferred_username}@${actor.domain}`

View File

@ -1,5 +1,5 @@
<template>
<div v-title="'Followers'">
<div v-title="labels.title">
<div class="ui vertical stripe segment">
<h2 class="ui header"><translate>Browsing followers</translate></h2>
<p>
@ -17,6 +17,13 @@ import LibraryFollowTable from '@/components/federation/LibraryFollowTable'
export default {
components: {
LibraryFollowTable
},
computed: {
labels () {
return {
title: this.$gettext('Followers')
}
}
}
}
</script>

View File

@ -1,5 +1,5 @@
<template>
<div v-title="'Libraries'">
<div v-title="labels.title">
<div class="ui vertical stripe segment">
<h2 class="ui header"><translate>Browsing libraries</translate></h2>
<router-link
@ -13,7 +13,7 @@
<div class="fields">
<div class="field">
<label><translate>Search</translate></label>
<input class="search" type="text" v-model="query" placeholder="Enter an library domain name..."/>
<input class="search" type="text" v-model="query" :placeholder="labels.searchPlaceholder"/>
</div>
<div class="field">
<label><translate>Ordering</translate></label>
@ -117,6 +117,16 @@ export default {
$('.ui.dropdown').dropdown()
$(this.$el).find('.field .search').focus()
},
computed: {
labels () {
let searchPlaceholder = this.$gettext('Enter an library domain name...')
let title = this.$gettext('Libraries')
return {
searchPlaceholder,
title
}
}
},
methods: {
updateQueryString: _.debounce(function () {
this.$router.replace({

View File

@ -1,5 +1,5 @@
<template>
<div v-title="'Federated tracks'">
<div v-title="labels.title">
<div class="ui vertical stripe segment">
<h2 class="ui header"><translate>Browsing federated tracks</translate></h2>
<div class="ui hidden divider"></div>
@ -14,6 +14,13 @@ import LibraryTrackTable from '@/components/federation/LibraryTrackTable'
export default {
components: {
LibraryTrackTable
},
computed: {
labels () {
return {
title: this.$gettext('Federated tracks')
}
}
}
}
</script>

View File

@ -1,5 +1,5 @@
<template>
<div class="main pusher" v-title="'Instance Timeline'">
<div class="main pusher" v-title="labels.title">
<div class="ui vertical center aligned stripe segment">
<div v-if="isLoading" :class="['ui', {'active': isLoading}, 'inverted', 'dimmer']">
<div class="ui text loader"><translate>Loading timeline...</translate></div>
@ -51,7 +51,12 @@ export default {
computed: {
...mapState({
events: state => state.instance.events
})
}),
labels () {
return {
title: this.$gettext('Instance Timeline')
}
}
},
methods: {
fetchEvents () {

View File

@ -1,6 +1,6 @@
<template>
<div>
<div v-if="isLoading" class="ui vertical segment" v-title="$gettext('Playlist')">
<div v-if="isLoading" class="ui vertical segment" v-title="labels.playlist">
<div :class="['ui', 'centered', 'active', 'inline', 'loader']"></div>
</div>
<div v-if="!isLoading && playlist" class="ui head vertical center aligned stripe segment" v-title="playlist.name">
@ -47,7 +47,7 @@
:playlist="playlist" :playlist-tracks="playlistTracks"></playlist-editor>
</template>
<template v-else>
<h2>Tracks</h2>
<h2><translate>Tracks</translate></h2>
<track-table :display-position="true" :tracks="tracks"></track-table>
</template>
</div>
@ -83,6 +83,13 @@ export default {
created: function () {
this.fetch()
},
computed: {
labels () {
return {
playlist: this.$gettext('Playlist')
}
}
},
methods: {
updatePlts (v) {
this.playlistTracks = v

View File

@ -1,5 +1,5 @@
<template>
<div v-title="$gettext('Playlists')">
<div v-title="labels.playlists">
<div class="ui vertical stripe segment">
<h2 class="ui header"><translate>Browsing playlists</translate></h2>
<div :class="['ui', {'loading': isLoading}, 'form']">
@ -12,7 +12,7 @@
<div class="fields">
<div class="field">
<label><translate>Search</translate></label>
<input type="text" v-model="query" :placeholder="$gettext('Enter an playlist name...')"/>
<input type="text" v-model="query" :placeholder="labels.searchPlaceholder"/>
</div>
<div class="field">
<label><translate>Ordering</translate></label>
@ -98,6 +98,16 @@ export default {
mounted () {
$('.ui.dropdown').dropdown()
},
computed: {
labels () {
let playlists = this.$gettext('Playlists')
let searchPlaceholder = this.$gettext('Enter an playlist name...')
return {
playlists,
searchPlaceholder
}
}
},
methods: {
updateQueryString: _.debounce(function () {
this.$router.replace({

View File

@ -1,6 +1,6 @@
<template>
<div>
<div v-if="isLoading" class="ui vertical segment" v-title="'Radio'">
<div v-if="isLoading" class="ui vertical segment" v-title="labels.title">
<div :class="['ui', 'centered', 'active', 'inline', 'loader']"></div>
</div>
<div v-if="!isLoading && radio" class="ui head vertical center aligned stripe segment" v-title="radio.name">
@ -24,15 +24,15 @@
</router-link>
<dangerous-button class="labeled icon" :action="deleteRadio">
<i class="trash icon"></i> Delete
<p slot="modal-header">Do you want to delete the radio "{{ radio.name }}"?</p>
<p slot="modal-content">This will completely delete this radio and cannot be undone.</p>
<p slot="modal-confirm">Delete radio</p>
<p slot="modal-header"><translate :translate-params="{radio: radio.name}">Do you want to delete the radio "{{ radio }}"?</translate></p>
<p slot="modal-content"><translate>This will completely delete this radio and cannot be undone.</translate></p>
<p slot="modal-confirm"><translate>Delete radio</translate></p>
</dangerous-button>
</template>
</div>
</div>
<div class="ui vertical stripe segment">
<h2>Tracks</h2>
<h2><translate>Tracks</translate></h2>
<track-table :tracks="tracks"></track-table>
<div class="ui center aligned basic segment">
<pagination
@ -74,6 +74,13 @@ export default {
created: function () {
this.fetch()
},
computed: {
labels () {
return {
title: this.$gettext('Radio')
}
}
},
methods: {
selectPage: function (page) {
this.page = page