Added translation context

Minor rewording
Added changelog fragment
This commit is contained in:
jovuit 2019-03-01 14:29:58 +01:00 committed by Eliot Berriot
parent 009d3d5f96
commit 3b9fd20d3b
15 changed files with 118 additions and 117 deletions

View File

@ -0,0 +1 @@
Added standardized translation context for all strings in the frontend to give accurate hints to translators.

View File

@ -3,10 +3,10 @@
<section class="ui vertical center aligned stripe segment"> <section class="ui vertical center aligned stripe segment">
<div class="ui text container"> <div class="ui text container">
<h1 class="ui huge header"> <h1 class="ui huge header">
<translate v-if="instance.name.value" :translate-params="{instance: instance.name.value}"> <translate :translate-context="'Content/About/Title/Short, Noun'" v-if="instance.name.value" :translate-params="{instance: instance.name.value}">
About %{ instance } About %{ instance }
</translate> </translate>
<translate v-else>About this instance</translate> <translate :translate-context="'Content/About/Title/Short, Noun'" v-else>About this instance</translate>
</h1> </h1>
<stats></stats> <stats></stats>
</div> </div>
@ -15,12 +15,12 @@
<div <div
class="ui middle aligned stackable text container"> class="ui middle aligned stackable text container">
<p <p
v-if="!instance.short_description.value && !instance.long_description.value"><translate>Unfortunately, owners of this instance did not yet take the time to complete this page.</translate></p> v-if="!instance.short_description.value && !instance.long_description.value"><translate :translate-context="'Content/About/Paragraph'">Unfortunately, the owners of this instance did not yet take the time to complete this page.</translate></p>
<router-link <router-link
class="ui button" class="ui button"
v-if="$store.state.auth.availablePermissions['settings']" v-if="$store.state.auth.availablePermissions['settings']"
:to="{path: '/manage/settings', hash: 'instance'}"> :to="{path: '/manage/settings', hash: 'instance'}">
<i class="pencil icon"></i><translate>Edit instance info</translate> <i class="pencil icon"></i><translate :translate-context="'Content/Settings/Button.Label/Verb'">Edit instance info</translate>
</router-link> </router-link>
<div class="ui hidden divider"></div> <div class="ui hidden divider"></div>
</div> </div>
@ -64,7 +64,7 @@ export default {
}), }),
labels() { labels() {
return { return {
title: this.$gettext("About this instance") title: this.$pgettext('Head/About/Title', "About this instance")
} }
} }
} }

View File

@ -4,22 +4,22 @@
<div class="ui stackable equal height stackable grid"> <div class="ui stackable equal height stackable grid">
<section class="four wide column"> <section class="four wide column">
<h4 class="ui header"> <h4 class="ui header">
<translate :translate-params="{instanceName: instanceHostname}" >About %{instanceName}</translate> <translate :translate-context="'Footer/About/Title'" :translate-params="{instanceName: instanceHostname}" >About %{instanceName}</translate>
</h4> </h4>
<div class="ui link list"> <div class="ui link list">
<router-link class="item" to="/about"> <router-link class="item" to="/about">
<translate>About page</translate> <translate :translate-context="'Footer/About/List item.Link'">About page</translate>
</router-link> </router-link>
<div class="item" v-if="version"> <div class="item" v-if="version">
<translate :translate-params="{version: version}" >Version %{version}</translate> <translate :translate-context="'Footer/*/List item'" :translate-params="{version: version}" >Version %{version}</translate>
</div> </div>
<div role="button" class="item" @click="$emit('show:set-instance-modal')" > <div role="button" class="item" @click="$emit('show:set-instance-modal')" >
<translate>Use another instance</translate> <translate :translate-context="'Footer/*/List item.Link'">Use another instance</translate>
</div> </div>
</div> </div>
<div class="ui form"> <div class="ui form">
<div class="ui field"> <div class="ui field">
<label><translate>Change language</translate></label> <label><translate :translate-context="'Footer/Settings/Dropdown.Label/Short, Verb'">Change language</translate></label>
<select class="ui dropdown" :value="$language.current" @change="$store.commit('ui/currentLanguage', $event.target.value)"> <select class="ui dropdown" :value="$language.current" @change="$store.commit('ui/currentLanguage', $event.target.value)">
<option v-for="(language, key) in $language.available" :key="key" :value="key">{{ language }}</option> <option v-for="(language, key) in $language.available" :key="key" :value="key">{{ language }}</option>
</select> </select>
@ -29,29 +29,29 @@
<section class="four wide column"> <section class="four wide column">
<h4 v-translate class="ui header">Using Funkwhale</h4> <h4 v-translate class="ui header">Using Funkwhale</h4>
<div class="ui link list"> <div class="ui link list">
<a href="https://docs.funkwhale.audio" class="item" target="_blank"><translate>Documentation</translate></a> <a href="https://docs.funkwhale.audio" class="item" target="_blank"><translate :translate-context="'Footer/*/List item.Link/Short, Noun'">Documentation</translate></a>
<a href="https://docs.funkwhale.audio/users/apps.html" class="item" target="_blank"><translate>Mobile and desktop apps</translate></a> <a href="https://docs.funkwhale.audio/users/apps.html" class="item" target="_blank"><translate :translate-context="'Footer/*/List item.Link'">Mobile and desktop apps</translate></a>
<div role="button" class="item" @click="$emit('show:shortcuts-modal')"><translate>Keyboard shortcuts</translate></div> <div role="button" class="item" @click="$emit('show:shortcuts-modal')"><translate :translate-context="'Footer/*/List item.Link/Short, Noun'">Keyboard shortcuts</translate></div>
</div> </div>
</section> </section>
<section class="four wide column"> <section class="four wide column">
<h4 v-translate class="ui header">Getting help</h4> <h4 v-translate class="ui header">Getting help</h4>
<div class="ui link list"> <div class="ui link list">
<a href="https://socialhub.network/c/funkwhale" class="item" target="_blank"><translate>Support forum</translate></a> <a href="https://socialhub.network/c/funkwhale" class="item" target="_blank"><translate :translate-context="'Footer/*/Listitem.Link'">Support forum</translate></a>
<a href="https://riot.im/app/#/room/#funkwhale-troubleshooting:matrix.org" class="item" target="_blank"><translate>Chat room</translate></a> <a href="https://riot.im/app/#/room/#funkwhale-troubleshooting:matrix.org" class="item" target="_blank"><translate :translate-context="'Footer/*/List item.Link'">Chat room</translate></a>
<a href="https://dev.funkwhale.audio/funkwhale/funkwhale/issues" class="item" target="_blank"><translate>Issue tracker</translate></a> <a href="https://dev.funkwhale.audio/funkwhale/funkwhale/issues" class="item" target="_blank"><translate :translate-context="'Footer/*/List item.Link'">Issue tracker</translate></a>
</div> </div>
</section> </section>
<section class="four wide column"> <section class="four wide column">
<h4 v-translate class="ui header">About Funkwhale</h4> <h4 v-translate class="ui header">About Funkwhale</h4>
<div class="ui link list"> <div class="ui link list">
<a href="https://funkwhale.audio" class="item" target="_blank"><translate>Official website</translate></a> <a href="https://funkwhale.audio" class="item" target="_blank"><translate :translate-context="'Footer/*/List item.Link'">Official website</translate></a>
<a href="https://contribute.funkwhale.audio" class="item" target="_blank"><translate>Contribute</translate></a> <a href="https://contribute.funkwhale.audio" class="item" target="_blank"><translate :translate-context="'Footer/*/List item.Link'">Contribute</translate></a>
<a href="https://dev.funkwhale.audio/funkwhale/funkwhale" class="item" target="_blank"><translate>Source code</translate></a> <a href="https://dev.funkwhale.audio/funkwhale/funkwhale" class="item" target="_blank"><translate :translate-context="'Footer/*/List item.Link'">Source code</translate></a>
</div> </div>
<div class="ui hidden divider"></div> <div class="ui hidden divider"></div>
<p> <p>
<translate>The funkwhale logo was kindly designed and provided by Francis Gading.</translate> <translate :translate-context="'Footer/*/List item.Link'">The funkwhale logo was kindly designed and provided by Francis Gading.</translate>
</p> </p>
</section> </section>
</div> </div>

View File

@ -3,15 +3,15 @@
<section class="ui vertical center aligned stripe segment"> <section class="ui vertical center aligned stripe segment">
<div class="ui text container"> <div class="ui text container">
<h1 class="ui huge header"> <h1 class="ui huge header">
<translate>Welcome on Funkwhale</translate> <translate :translate-context="'Content/Home/Title/Verb'">Welcome on Funkwhale</translate>
</h1> </h1>
<p><translate>We think listening to music should be simple.</translate></p> <p><translate :translate-context="'Content/Home/Title'">We think listening to music should be simple.</translate></p>
<router-link class="ui icon button" to="/about"> <router-link class="ui icon button" to="/about">
<i class="info icon"></i> <i class="info icon"></i>
<translate>Learn more about this instance</translate> <translate :translate-context="'Content/Home/Button.Label/Verb'">Learn more about this instance</translate>
</router-link> </router-link>
<router-link class="ui icon teal button" to="/library"> <router-link class="ui icon teal button" to="/library">
<translate>Get me to the library</translate> <translate :translate-context="'Content/Home/Button.Label/Verb'">Get me to the library</translate>
<i class="right arrow icon"></i> <i class="right arrow icon"></i>
</router-link> </router-link>
</div> </div>
@ -22,9 +22,9 @@
<div class="row"> <div class="row">
<div class="eight wide left floated column"> <div class="eight wide left floated column">
<h2 class="ui header"> <h2 class="ui header">
<translate>Why funkwhale?</translate> <translate :translate-context="'Content/Home/Title'">Why funkwhale?</translate>
</h2> </h2>
<p><translate>That's simple: we loved Grooveshark and we want to build something even better.</translate></p> <p><translate :translate-context="'Content/Home/Paragraph'">That's simple: we loved Grooveshark and we want to build something even better.</translate></p>
</div> </div>
<div class="four wide left floated column"> <div class="four wide left floated column">
<img class="ui medium image" src="../assets/logo/logo.png" /> <img class="ui medium image" src="../assets/logo/logo.png" />
@ -35,26 +35,26 @@
<div class="ui middle aligned stackable text container"> <div class="ui middle aligned stackable text container">
<div class="ui hidden divider"></div> <div class="ui hidden divider"></div>
<h2 class="ui header"> <h2 class="ui header">
<translate>Unlimited music</translate> <translate :translate-context="'Content/Home/Title'">Unlimited music</translate>
</h2> </h2>
<p><translate>Funkwhale is designed to make it easy to listen to music you like, or to discover new artists.</translate></p> <p><translate :translate-context="'Content/Home/Paragraph'">Funkwhale is designed to make it easy to listen to music you like, or to discover new artists.</translate></p>
<div class="ui list"> <div class="ui list">
<div class="item"> <div class="item">
<i class="sound icon"></i> <i class="sound icon"></i>
<div class="content"> <div class="content">
<translate>Click once, listen for hours using built-in radios</translate> <translate :translate-context="'Content/Home/List item/Verb'">Click once, listen for hours using built-in radios</translate>
</div> </div>
</div> </div>
<div class="item"> <div class="item">
<i class="heart icon"></i> <i class="heart icon"></i>
<div class="content"> <div class="content">
<translate>Keep a track of your favorite songs</translate> <translate :translate-context="'Content/Home/List item/Verb'">Keep a track of your favorite songs</translate>
</div> </div>
</div> </div>
<div class="item"> <div class="item">
<i class="list icon"></i> <i class="list icon"></i>
<div class="content"> <div class="content">
<translate>Playlists? We got them</translate> <translate :translate-context="'Content/Home/List item'">Playlists? We got them</translate>
</div> </div>
</div> </div>
</div> </div>
@ -62,14 +62,14 @@
<div class="ui middle aligned stackable text container"> <div class="ui middle aligned stackable text container">
<div class="ui hidden divider"></div> <div class="ui hidden divider"></div>
<h2 class="ui header"> <h2 class="ui header">
<translate>Clean library</translate> <translate :translate-context="'Content/Home/Title'">A clean library</translate>
</h2> </h2>
<p><translate>Funkwhale takes care of handling your music</translate>.</p> <p><translate :translate-context="'Content/Home/Paragraph'">Funkwhale takes care of handling your music</translate>.</p>
<div class="ui list"> <div class="ui list">
<div class="item"> <div class="item">
<i class="download icon"></i> <i class="download icon"></i>
<div class="content"> <div class="content">
<translate>Import music from various platforms, such as YouTube or SoundCloud</translate> <translate :translate-context="'Content/Home/List item/Verb'">Import music from various platforms, such as YouTube or SoundCloud</translate>
</div> </div>
</div> </div>
<div class="item"> <div class="item">
@ -83,7 +83,7 @@
<div class="item"> <div class="item">
<i class="plus icon"></i> <i class="plus icon"></i>
<div class="content"> <div class="content">
<translate>Covers, lyrics, our goal is to have them all ;)</translate> <translate :translate-context="'Content/Home/List item'">Covers, lyrics, our goal is to have them all ;)</translate>
</div> </div>
</div> </div>
</div> </div>
@ -91,20 +91,20 @@
<div class="ui middle aligned stackable text container"> <div class="ui middle aligned stackable text container">
<div class="ui hidden divider"></div> <div class="ui hidden divider"></div>
<h2 class="ui header"> <h2 class="ui header">
<translate>Easy to use</translate> <translate :translate-context="'Content/Home/Title'">Easy to use</translate>
</h2> </h2>
<p><translate>Funkwhale is dead simple to use.</translate></p> <p><translate :translate-context="'Content/Home/Paragraph'">Funkwhale is dead simple to use.</translate></p>
<div class="ui list"> <div class="ui list">
<div class="item"> <div class="item">
<i class="book icon"></i> <i class="book icon"></i>
<div class="content"> <div class="content">
<translate>No add-ons, no plugins : you only need a web library</translate> <translate :translate-context="'Content/Home/List item'">No add-ons, no plugins : you only need a web library</translate>
</div> </div>
</div> </div>
<div class="item"> <div class="item">
<i class="wizard icon"></i> <i class="wizard icon"></i>
<div class="content"> <div class="content">
<translate>Access your music from a clean interface that focus on what really matters</translate> <translate :translate-context="'Content/Home/List item'">Access your music from a clean interface that focus on what really matters</translate>
</div> </div>
</div> </div>
</div> </div>
@ -112,26 +112,26 @@
<div class="ui middle aligned stackable text container"> <div class="ui middle aligned stackable text container">
<div class="ui hidden divider"></div> <div class="ui hidden divider"></div>
<h2 class="ui header"> <h2 class="ui header">
<translate>Your music, your way</translate> <translate :translate-context="'Content/Home/Title'">Your music, your way</translate>
</h2> </h2>
<p><translate>Funkwhale is free and gives you control on your music.</translate></p> <p><translate :translate-context="'Content/Home/Paragraph'">Funkwhale is free and gives you control on your music.</translate></p>
<div class="ui list"> <div class="ui list">
<div class="item"> <div class="item">
<i class="smile icon"></i> <i class="smile icon"></i>
<div class="content"> <div class="content">
<translate>The plaform is free and open-source, you can install it and modify it without worries</translate> <translate :translate-context="'Content/Home/List item'">The plaform is free and open-source, you can install it and modify it without worries</translate>
</div> </div>
</div> </div>
<div class="item"> <div class="item">
<i class="protect icon"></i> <i class="protect icon"></i>
<div class="content"> <div class="content">
<translate>We do not track you or bother you with ads</translate> <translate :translate-context="'Content/Home/List item'">We do not track you or bother you with ads</translate>
</div> </div>
</div> </div>
<div class="item"> <div class="item">
<i class="users icon"></i> <i class="users icon"></i>
<div class="content"> <div class="content">
<translate>You can invite friends and family to your instance so they can enjoy your music</translate> <translate :translate-context="'Content/Home/List item'">You can invite friends and family to your instance so they can enjoy your music</translate>
</div> </div>
</div> </div>
</div> </div>
@ -150,7 +150,7 @@ export default {
computed: { computed: {
labels() { labels() {
return { return {
title: this.$gettext("Welcome") title: this.$pgettext('Head/Home/Title', "Welcome")
} }
} }
} }

View File

@ -5,14 +5,14 @@
<h1 class="ui huge header"> <h1 class="ui huge header">
<i class="warning icon"></i> <i class="warning icon"></i>
<div class="content"> <div class="content">
<translate>Page not found!</translate> <translate :translate-context="'Content/*/Title'">Page not found!</translate>
</div> </div>
</h1> </h1>
<p><translate>We're sorry, the page you asked for does not exist:</translate></p> <p><translate :translate-context="'Content/*/Paragraph'">Sorry, the page you asked for does not exist:</translate></p>
<a :href="path">{{ path }}</a> <a :href="path">{{ path }}</a>
<div class="ui hidden divider"></div> <div class="ui hidden divider"></div>
<router-link class="ui icon button" to="/"> <router-link class="ui icon button" to="/">
<translate>Go to home page</translate> <translate :translate-context="'Content/*/Button.Label/Verb'">Go to home page</translate>
<i class="right arrow icon"></i> <i class="right arrow icon"></i>
</router-link> </router-link>
</div> </div>
@ -30,7 +30,7 @@ export default {
computed: { computed: {
labels() { labels() {
return { return {
title: this.$gettext("Page Not Found") title: this.$pgettext('Head/*/Title', "Page Not Found")
} }
} }
} }

View File

@ -36,7 +36,7 @@ export default {
computed: { computed: {
labels() { labels() {
return { return {
pagination: this.$gettext("Pagination") pagination: this.$pgettext('Content/*/Hidden text/Noun', "Pagination")
} }
}, },
pages: function() { pages: function() {

View File

@ -1,7 +1,7 @@
<template> <template>
<modal @update:show="$emit('update:show', $event)" :show="show"> <modal @update:show="$emit('update:show', $event)" :show="show">
<header class="header"> <header class="header">
<translate>Keyboard shortcuts</translate> <translate :translate-context="'Popup/Keyboard shortcuts/Title'">Keyboard shortcuts</translate>
</header> </header>
<section class="scrolling content"> <section class="scrolling content">
<table <table
@ -18,7 +18,7 @@
</table> </table>
</section> </section>
<footer class="actions"> <footer class="actions">
<div class="ui cancel button"><translate>Close</translate></div> <div class="ui cancel button"><translate :translate-context="'Popup/Keyboard shortcuts/Button.Label/Verb'">Close</translate></div>
</footer> </footer>
</modal> </modal>
</template> </template>
@ -35,11 +35,11 @@ export default {
sections () { sections () {
return [ return [
{ {
title: this.$gettext('General shortcuts'), title: this.$pgettext('Popup/Keyboard shortcuts/Title', 'General shortcuts'),
shortcuts: [ shortcuts: [
{ {
key: 'h', key: 'h',
summary: this.$gettext('Show available keyboard shortcuts') summary: this.$pgettext('Popup/Keyboard shortcuts/Table.Label/Verb', 'Show available keyboard shortcuts')
} }
] ]
}, },
@ -52,35 +52,35 @@ export default {
// s.prevent.exact="shuffle" // s.prevent.exact="shuffle"
{ {
title: this.$gettext('Audio player shortcuts'), title: this.$pgettext('Popup/Keyboard shortcuts/Title', 'Audio player shortcuts'),
shortcuts: [ shortcuts: [
{ {
key: 'space', key: 'space',
summary: this.$gettext('Pause/play the current track') summary: this.$pgettext('Popup/Keyboard shortcuts/Table.Label/Verb', 'Pause/play the current track')
}, },
{ {
key: 'ctrl left', key: 'ctrl left',
summary: this.$gettext('Play previous track') summary: this.$pgettext('Popup/Keyboard shortcuts/Table.Label/Verb', 'Play previous track')
}, },
{ {
key: 'ctrl right', key: 'ctrl right',
summary: this.$gettext('Play next track') summary: this.$pgettext('Popup/Keyboard shortcuts/Table.Label/Verb', 'Play next track')
}, },
{ {
key: 'ctrl up', key: 'ctrl up',
summary: this.$gettext('Increase volume') summary: this.$pgettext('Popup/Keyboard shortcuts/Table.Label/Verb', 'Increase volume')
}, },
{ {
key: 'ctrl down', key: 'ctrl down',
summary: this.$gettext('Decrease volume') summary: this.$pgettext('Popup/Keyboard shortcuts/Table.Label/Verb', 'Decrease volume')
}, },
{ {
key: 'l', key: 'l',
summary: this.$gettext('Toggle queue looping') summary: this.$pgettext('Popup/Keyboard shortcuts/Table.Label/Verb', 'Toggle queue looping')
}, },
{ {
key: 's', key: 's',
summary: this.$gettext('Shuffle queue') summary: this.$pgettext('Popup/Keyboard shortcuts/Table.Label/Verb', 'Shuffle queue')
}, },
] ]
} }

View File

@ -16,13 +16,13 @@
<div class="menu-area"> <div class="menu-area">
<div class="ui compact fluid two item inverted menu"> <div class="ui compact fluid two item inverted menu">
<a :class="[{active: selectedTab === 'library'}, 'item']" role="button" @click.prevent.stop="selectedTab = 'library'" data-tab="library"><translate>Browse</translate></a> <a :class="[{active: selectedTab === 'library'}, 'item']" role="button" @click.prevent.stop="selectedTab = 'library'" data-tab="library"><translate :translate-context="'Sidebar/Library/Tab.Title/Verb'">Browse</translate></a>
<a :class="[{active: selectedTab === 'queue'}, 'item']" role="button" @click.prevent.stop="selectedTab = 'queue'" data-tab="queue"> <a :class="[{active: selectedTab === 'queue'}, 'item']" role="button" @click.prevent.stop="selectedTab = 'queue'" data-tab="queue">
<translate>Queue</translate>&nbsp; <translate :translate-context="'Sidebar/Queue/Tab.Title/Noun'">Queue</translate>&nbsp;
<template v-if="queue.tracks.length === 0"> <template v-if="queue.tracks.length === 0">
<translate>(empty)</translate> <translate :translate-context="'Sidebar/Queue/Tab.Title'">(empty)</translate>
</template> </template>
<translate v-else :translate-params="{index: queue.currentIndex + 1, length: queue.tracks.length}"> <translate :translate-context="'Sidebar/Queue/Tab.Title'" v-else :translate-params="{index: queue.currentIndex + 1, length: queue.tracks.length}">
(%{ index } of %{ length }) (%{ index } of %{ length })
</translate> </translate>
</a> </a>
@ -32,76 +32,76 @@
<section :class="['ui', 'bottom', 'attached', {active: selectedTab === 'library'}, 'tab']" :aria-label="labels.mainMenu"> <section :class="['ui', 'bottom', 'attached', {active: selectedTab === 'library'}, 'tab']" :aria-label="labels.mainMenu">
<nav class="ui inverted vertical large fluid menu" role="navigation" :aria-label="labels.mainMenu"> <nav class="ui inverted vertical large fluid menu" role="navigation" :aria-label="labels.mainMenu">
<div class="item"> <div class="item">
<header class="header"><translate>My account</translate></header> <header class="header"><translate :translate-context="'Sidebar/Profile/Title'">My account</translate></header>
<div class="menu"> <div class="menu">
<router-link class="item" v-if="$store.state.auth.authenticated" :to="{name: 'profile', params: {username: $store.state.auth.username}}"> <router-link class="item" v-if="$store.state.auth.authenticated" :to="{name: 'profile', params: {username: $store.state.auth.username}}">
<i class="user icon"></i> <i class="user icon"></i>
<translate :translate-params="{username: $store.state.auth.username}"> <translate :translate-context="'Sidebar/Profile/List item.Link'" :translate-params="{username: $store.state.auth.username}">
Logged in as %{ username } Logged in as %{ username }
</translate> </translate>
<img class="ui right floated circular tiny avatar image" v-if="$store.state.auth.profile.avatar.square_crop" v-lazy="$store.getters['instance/absoluteUrl']($store.state.auth.profile.avatar.square_crop)" /> <img class="ui right floated circular tiny avatar image" v-if="$store.state.auth.profile.avatar.square_crop" v-lazy="$store.getters['instance/absoluteUrl']($store.state.auth.profile.avatar.square_crop)" />
</router-link> </router-link>
<router-link class="item" v-if="$store.state.auth.authenticated" :to="{path: '/settings'}"><i class="setting icon"></i><translate>Settings</translate></router-link> <router-link class="item" v-if="$store.state.auth.authenticated" :to="{path: '/settings'}"><i class="setting icon"></i><translate :translate-context="'Sidebar/Settings/List item.Link/Noun'">Settings</translate></router-link>
<router-link class="item" v-if="$store.state.auth.authenticated" :to="{name: 'notifications'}"> <router-link class="item" v-if="$store.state.auth.authenticated" :to="{name: 'notifications'}">
<i class="feed icon"></i> <i class="feed icon"></i>
<translate>Notifications</translate> <translate :translate-context="'Sidebar/Notifications/List item.Link/Noun'">Notifications</translate>
<div <div
v-if="$store.state.ui.notifications.inbox > 0" v-if="$store.state.ui.notifications.inbox > 0"
:class="['ui', 'teal', 'label']"> :class="['ui', 'teal', 'label']">
{{ $store.state.ui.notifications.inbox }}</div> {{ $store.state.ui.notifications.inbox }}</div>
</router-link> </router-link>
<router-link class="item" v-if="$store.state.auth.authenticated" :to="{name: 'logout'}"><i class="sign out icon"></i><translate>Logout</translate></router-link> <router-link class="item" v-if="$store.state.auth.authenticated" :to="{name: 'logout'}"><i class="sign out icon"></i><translate :translate-context="'Sidebar/Login/List item.Link/Verb'">Logout</translate></router-link>
<template v-else> <template v-else>
<router-link class="item" :to="{name: 'login'}"><i class="sign in icon"></i><translate>Login</translate></router-link> <router-link class="item" :to="{name: 'login'}"><i class="sign in icon"></i><translate :translate-context="'Sidebar/Login/List item.Link/Verb'">Login</translate></router-link>
<router-link class="item" :to="{path: '/signup'}"> <router-link class="item" :to="{path: '/signup'}">
<i class="corner add icon"></i> <i class="corner add icon"></i>
<translate>Create an account</translate> <translate :translate-context="'Sidebar/Login/List item.Link/Verb'">Create an account</translate>
</router-link> </router-link>
</template> </template>
</div> </div>
</div> </div>
<div class="item"> <div class="item">
<header class="header"><translate>Music</translate></header> <header class="header"><translate :translate-context="'Sidebar/Library/Title'">Music</translate></header>
<div class="menu"> <div class="menu">
<router-link class="item" :to="{path: '/library'}"><i class="sound icon"></i><translate>Browse library</translate></router-link> <router-link class="item" :to="{path: '/library'}"><i class="sound icon"></i><translate :translate-context="'Sidebar/Library/List item.Link/Verb'">Browse library</translate></router-link>
<router-link class="item" v-if="$store.state.auth.authenticated" :to="{path: '/favorites'}"><i class="heart icon"></i><translate>Favorites</translate></router-link> <router-link class="item" v-if="$store.state.auth.authenticated" :to="{path: '/favorites'}"><i class="heart icon"></i><translate :translate-context="'Sidebar/Favorites/List item.Link/Noun'">Favorites</translate></router-link>
<a <a
@click="$store.commit('playlists/chooseTrack', null)" @click="$store.commit('playlists/chooseTrack', null)"
v-if="$store.state.auth.authenticated" v-if="$store.state.auth.authenticated"
class="item"> class="item">
<i class="list icon"></i><translate>Playlists</translate> <i class="list icon"></i><translate :translate-context="'Sidebar/Playlist/List item.Link/Noun'">Playlists</translate>
</a> </a>
<router-link <router-link
v-if="$store.state.auth.authenticated" v-if="$store.state.auth.authenticated"
class="item" :to="{name: 'content.index'}"><i class="upload icon"></i><translate>Add content</translate></router-link> class="item" :to="{name: 'content.index'}"><i class="upload icon"></i><translate :translate-context="'Sidebar/Library/List item.Link/Verb'">Add content</translate></router-link>
</div> </div>
</div> </div>
<div class="item" v-if="$store.state.auth.availablePermissions['settings'] || $store.state.auth.availablePermissions['moderation']"> <div class="item" v-if="$store.state.auth.availablePermissions['settings'] || $store.state.auth.availablePermissions['moderation']">
<header class="header"><translate>Administration</translate></header> <header class="header"><translate :translate-context="'Sidebar/Admin/Title/Noun'">Administration</translate></header>
<div class="menu"> <div class="menu">
<router-link <router-link
v-if="$store.state.auth.availablePermissions['settings']" v-if="$store.state.auth.availablePermissions['settings']"
class="item" class="item"
:to="{path: '/manage/settings'}"> :to="{path: '/manage/settings'}">
<i class="settings icon"></i><translate>Settings</translate> <i class="settings icon"></i><translate :translate-context="'Sidebar/Admin/List item.Link/Noun'">Settings</translate>
</router-link> </router-link>
<router-link <router-link
v-if="$store.state.auth.availablePermissions['settings']" v-if="$store.state.auth.availablePermissions['settings']"
class="item" class="item"
:to="{name: 'manage.users.users.list'}"> :to="{name: 'manage.users.users.list'}">
<i class="users icon"></i><translate>Users</translate> <i class="users icon"></i><translate :translate-context="'Sidebar/Admin/List item.Link/Noun'">Users</translate>
</router-link> </router-link>
<router-link <router-link
v-if="$store.state.auth.availablePermissions['moderation']" v-if="$store.state.auth.availablePermissions['moderation']"
class="item" class="item"
:to="{name: 'manage.moderation.domains.list'}"> :to="{name: 'manage.moderation.domains.list'}">
<i class="shield icon"></i><translate>Moderation</translate> <i class="shield icon"></i><translate :translate-context="'Sidebar/Moderation/List item.Link/Noun'">Moderation</translate>
</router-link> </router-link>
<router-link <router-link
v-if="$store.state.auth.availablePermissions['library']" v-if="$store.state.auth.availablePermissions['library']"
class="item" class="item"
:to="{name: 'manage.library.edits', query: {q: 'is_approved:null'}}"> :to="{name: 'manage.library.edits', query: {q: 'is_approved:null'}}">
<i class="book icon"></i><translate>Library</translate> <i class="book icon"></i><translate :translate-context="'Sidebar/Moderation/List item.Link/Noun'">Library</translate>
<div <div
v-if="$store.state.ui.notifications.pendingReviewEdits > 0" v-if="$store.state.ui.notifications.pendingReviewEdits > 0"
:title="labels.pendingReviewEdits" :title="labels.pendingReviewEdits"
@ -116,10 +116,10 @@
<i class="history icon"></i> <i class="history icon"></i>
<div class="content"> <div class="content">
<div class="header"> <div class="header">
<translate>Do you want to restore your previous queue?</translate> <translate :translate-context="'Sidebar/Queue/Message'">Do you want to restore your previous queue?</translate>
</div> </div>
<p> <p>
<translate <translate :translate-context="'Sidebar/Queue/Message'"
translate-plural="%{ count } tracks" translate-plural="%{ count } tracks"
:translate-n="queue.previousQueue.tracks.length" :translate-n="queue.previousQueue.tracks.length"
:translate-params="{count: queue.previousQueue.tracks.length}"> :translate-params="{count: queue.previousQueue.tracks.length}">
@ -127,8 +127,8 @@
</translate> </translate>
</p> </p>
<div class="ui two buttons"> <div class="ui two buttons">
<div @click="queue.restore()" class="ui basic inverted green button"><translate>Yes</translate></div> <div @click="queue.restore()" class="ui basic inverted green button"><translate :translate-context="'*/*/*'">Yes</translate></div>
<div @click="queue.removePrevious()" class="ui basic inverted red button"><translate>No</translate></div> <div @click="queue.removePrevious()" class="ui basic inverted red button"><translate :translate-context="'*/*/*'">No</translate></div>
</div> </div>
</div> </div>
</div> </div>
@ -167,10 +167,10 @@
<div v-if="$store.state.radios.running" class="ui black message"> <div v-if="$store.state.radios.running" class="ui black message">
<div class="content"> <div class="content">
<div class="header"> <div class="header">
<i class="feed icon"></i> <translate>You have a radio playing</translate> <i class="feed icon"></i> <translate :translate-context="'Sidebar/Player/Title'">You have a radio playing</translate>
</div> </div>
<p><translate>New tracks will be appended here automatically.</translate></p> <p><translate :translate-context="'Sidebar/Player/Paragraph'">New tracks will be appended here automatically.</translate></p>
<div @click="$store.dispatch('radios/stop')" class="ui basic inverted red button"><translate>Stop radio</translate></div> <div @click="$store.dispatch('radios/stop')" class="ui basic inverted red button"><translate :translate-context="'Sidebar/Player/Button.Label/Verb'">Stop radio</translate></div>
</div> </div>
</div> </div>
</section> </section>
@ -218,10 +218,10 @@ export default {
url: state => state.route.path url: state => state.route.path
}), }),
labels() { labels() {
let mainMenu = this.$gettext("Main menu") let mainMenu = this.$pgettext('Sidebar/*/Hidden text', "Main menu")
let selectTrack = this.$gettext("Play this track") let selectTrack = this.$pgettext('Sidebar/Player/Hidden text', "Play this track")
let pendingFollows = this.$gettext("Pending follow requests") let pendingFollows = this.$pgettext('Sidebar/Notifications/Hidden text', "Pending follow requests")
let pendingReviewEdits = this.$gettext("Pending review edits") let pendingReviewEdits = this.$pgettext('Sidebar/Moderation/Hidden text', "Pending review edits")
return { return {
pendingFollows, pendingFollows,
mainMenu, mainMenu,

View File

@ -3,13 +3,13 @@
<div class="ui divider" /> <div class="ui divider" />
<h3 class="ui header">{{ group.label }}</h3> <h3 class="ui header">{{ group.label }}</h3>
<div v-if="errors.length > 0" class="ui negative message"> <div v-if="errors.length > 0" class="ui negative message">
<div class="header"><translate>Error while saving settings</translate></div> <div class="header"><translate :translate-context="'Content/Settings/Error message.Title'">Error while saving settings</translate></div>
<ul class="list"> <ul class="list">
<li v-for="error in errors">{{ error }}</li> <li v-for="error in errors">{{ error }}</li>
</ul> </ul>
</div> </div>
<div v-if="result" class="ui positive message"> <div v-if="result" class="ui positive message">
<translate>Settings updated successfully.</translate> <translate :translate-context="'Content/Settings/Paragraph'">Settings updated successfully.</translate>
</div> </div>
<p v-if="group.help">{{ group.help }}</p> <p v-if="group.help">{{ group.help }}</p>
<div v-for="setting in settings" class="ui field"> <div v-for="setting in settings" class="ui field">
@ -65,7 +65,7 @@
<button <button
type="submit" type="submit"
:class="['ui', {'loading': isLoading}, 'right', 'floated', 'green', 'button']"> :class="['ui', {'loading': isLoading}, 'right', 'floated', 'green', 'button']">
<translate>Save</translate> <translate :translate-context="'Content/Settings/Button.Label/Short, Verb'">Save</translate>
</button> </button>
</form> </form>
</template> </template>

View File

@ -4,7 +4,7 @@
<slot name="title"></slot> <slot name="title"></slot>
</h3> </h3>
<p v-if="!isLoading && libraries.length > 0" class="ui subtitle"><slot name="subtitle"></slot></p> <p v-if="!isLoading && libraries.length > 0" class="ui subtitle"><slot name="subtitle"></slot></p>
<p v-if="!isLoading && libraries.length === 0" class="ui subtitle"><translate>No matching library.</translate></p> <p v-if="!isLoading && libraries.length === 0" class="ui subtitle"><translate :translate-context="'Content/Federation/Paragraph'">No matching library.</translate></p>
<i @click="fetchData(previousPage)" :disabled="!previousPage" :class="['ui', {disabled: !previousPage}, 'circular', 'angle left', 'icon']"> <i @click="fetchData(previousPage)" :disabled="!previousPage" :class="['ui', {disabled: !previousPage}, 'circular', 'angle left', 'icon']">
</i> </i>
<i @click="fetchData(nextPage)" :disabled="!nextPage" :class="['ui', {disabled: !nextPage}, 'circular', 'angle right', 'icon']"> <i @click="fetchData(nextPage)" :disabled="!nextPage" :class="['ui', {disabled: !nextPage}, 'circular', 'angle right', 'icon']">

View File

@ -23,7 +23,7 @@ export default {
computed: { computed: {
labels () { labels () {
return { return {
title: this.$gettext('Show/hide password') title: this.$pgettext('Content/Settings/Button.Tooltip/Verb', 'Show/hide password')
} }
}, },
passwordInputType () { passwordInputType () {

View File

@ -3,7 +3,7 @@
<div v-if="stats" class="ui stackable two column grid"> <div v-if="stats" class="ui stackable two column grid">
<div class="column"> <div class="column">
<h3 class="ui left aligned header"> <h3 class="ui left aligned header">
<translate>User activity</translate> <translate :translate-context="'Content/About/Title/Noun'">User activity</translate>
</h3> </h3>
<div v-if="stats" class="ui mini horizontal statistics"> <div v-if="stats" class="ui mini horizontal statistics">
<div class="statistic"> <div class="statistic">
@ -11,48 +11,48 @@
<i class="green user icon"></i> <i class="green user icon"></i>
{{ stats.users }} {{ stats.users }}
</div> </div>
<div class="label"><translate>users</translate></div> <div class="label"><translate :translate-context="'Content/About/Paragraph/Unit'">users</translate></div>
</div> </div>
<div class="statistic"> <div class="statistic">
<div class="value"> <div class="value">
<i class="orange sound icon"></i> {{ stats.listenings }} <i class="orange sound icon"></i> {{ stats.listenings }}
</div> </div>
<div class="label"><translate>tracks listened</translate></div> <div class="label"><translate :translate-context="'Content/About/Paragraph/Unit'">tracks listened</translate></div>
</div> </div>
<div class="statistic"> <div class="statistic">
<div class="value"> <div class="value">
<i class="pink heart icon"></i> {{ stats.trackFavorites }} <i class="pink heart icon"></i> {{ stats.trackFavorites }}
</div> </div>
<div class="label"><translate>Tracks favorited</translate></div> <div class="label"><translate :translate-context="'Content/About/Paragraph/Unit'">Tracks favorited</translate></div>
</div> </div>
</div> </div>
</div> </div>
<div class="column"> <div class="column">
<h3 class="ui left aligned header"><translate>Library</translate></h3> <h3 class="ui left aligned header"><translate :translate-context="'Content/About/Title/Noun'">Library</translate></h3>
<div class="ui mini horizontal statistics"> <div class="ui mini horizontal statistics">
<div class="statistic"> <div class="statistic">
<div class="value"> <div class="value">
{{ parseInt(stats.musicDuration) }} {{ parseInt(stats.musicDuration) }}
</div> </div>
<div class="label"><translate>Hours of music</translate></div> <div class="label"><translate :translate-context="'Content/About/Paragraph/Unit'">Hours of music</translate></div>
</div> </div>
<div class="statistic"> <div class="statistic">
<div class="value"> <div class="value">
{{ stats.artists }} {{ stats.artists }}
</div> </div>
<div class="label"><translate>Artists</translate></div> <div class="label"><translate :translate-context="'Content/About/Paragraph/Unit'">Artists</translate></div>
</div> </div>
<div class="statistic"> <div class="statistic">
<div class="value"> <div class="value">
{{ stats.albums }} {{ stats.albums }}
</div> </div>
<div class="label"><translate>Albums</translate></div> <div class="label"><translate :translate-context="'Content/About/Paragraph/Unit'">Albums</translate></div>
</div> </div>
<div class="statistic"> <div class="statistic">
<div class="value"> <div class="value">
{{ stats.tracks }} {{ stats.tracks }}
</div> </div>
<div class="label"><translate>tracks</translate></div> <div class="label"><translate :translate-context="'Content/About/Paragraph/Unit'">Tracks</translate></div>
</div> </div>
</div> </div>
</div> </div>

View File

@ -36,15 +36,15 @@ export default {
return 'plop' return 'plop'
}, },
labels () { labels () {
let libraryFollowMessage = this.$gettext('%{ username } followed your library "%{ library }"') let libraryFollowMessage = this.$pgettext('Content/Notifications/Paragraph', '%{ username } followed your library "%{ library }"')
let libraryAcceptFollowMessage = this.$gettext('%{ username } accepted your follow on library "%{ library }"') let libraryAcceptFollowMessage = this.$pgettext('Content/Notifications/Paragraph', '%{ username } accepted your follow on library "%{ library }"')
let libraryPendingFollowMessage = this.$gettext('%{ username } wants to follow your library "%{ library }"') let libraryPendingFollowMessage = this.$pgettext('Content/Notifications/Paragraph', '%{ username } wants to follow your library "%{ library }"')
return { return {
libraryFollowMessage, libraryFollowMessage,
libraryAcceptFollowMessage, libraryAcceptFollowMessage,
libraryPendingFollowMessage, libraryPendingFollowMessage,
markRead: this.$gettext('Mark as read'), markRead: this.$pgettext('Content/Notifications/Button.Tooltip/Verb', 'Mark as read'),
markUnread: this.$gettext('Mark as unread'), markUnread: this.$pgettext('Content/Notifications/Button.Tooltip/Verb', 'Mark as unread'),
} }
}, },
@ -63,7 +63,7 @@ export default {
action = { action = {
buttonClass: 'green', buttonClass: 'green',
icon: 'check', icon: 'check',
label: this.$gettext('Approve'), label: this.$pgettext('Content/Notifications/Button.Label/Short, Verb', 'Approve'),
handler: () => { self.approveLibraryFollow(a.related_object) } handler: () => { self.approveLibraryFollow(a.related_object) }
} }
} else { } else {

View File

@ -1,8 +1,8 @@
<template> <template>
<button @click="toggleRadio" :class="['ui', 'blue', {'inverted': running}, 'icon', 'labeled', 'button']"> <button @click="toggleRadio" :class="['ui', 'blue', {'inverted': running}, 'icon', 'labeled', 'button']">
<i class="ui feed icon"></i> <i class="ui feed icon"></i>
<template v-if="running"><translate>Stop radio</translate></template> <template v-if="running"><translate :translate-context="'Content/Radio/Button.Label/Short, Verb'">Stop radio</translate></template>
<template v-else><translate>Start radio</translate></template> <template v-else><translate :translate-context="'Content/Radio/Button.Label/Short, Verb'">Start radio</translate></template>
</button> </button>
</template> </template>

View File

@ -21,7 +21,7 @@
class="ui basic yellow button right floated" class="ui basic yellow button right floated"
v-if="$store.state.auth.authenticated && type === 'custom' && radio.user.id === $store.state.auth.profile.id" v-if="$store.state.auth.authenticated && type === 'custom' && radio.user.id === $store.state.auth.profile.id"
:to="{name: 'library.radios.edit', params: {id: customRadioId }}"> :to="{name: 'library.radios.edit', params: {id: customRadioId }}">
<translate>Edit</translate> <translate :translate-context="'Content/Radio/Card.Button.Label/Short, Verb'">Edit</translate>
</router-link> </router-link>
</div> </div>
</div> </div>