Merge branch '930-i18n-fixes' into 'develop'

Resolve "i18n fixes for 0.20"

Closes #930

See merge request funkwhale/funkwhale!912
This commit is contained in:
Eliot Berriot 2019-10-01 15:19:55 +02:00
commit ca468826a0
79 changed files with 2960 additions and 8736 deletions

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

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

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

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

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

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

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -4,7 +4,7 @@ locales_dir="locales"
sources=$(find src -name '*.vue' -o -name '*.html' 2> /dev/null)
js_sources=$(find src -name '*.vue' -o -name '*.js')
touch $locales_dir/app.pot
GENERATE=${GENERATE-true}
# Create a main .pot template, then generate .po files for each available language.
# Extract gettext strings from templates files and create a POT dictionary template.
$(yarn bin)/gettext-extract --attribute v-translate --quiet --output $locales_dir/app.pot $sources
@ -18,12 +18,14 @@ xgettext --language=JavaScript --keyword=npgettext:1c,2,3 \
# Fix broken files path/lines in pot
sed -e 's|#: src/|#: front/src/|' -i $locales_dir/app.pot
# Generate .po files for each available language.
echo $locales
for lang in $locales; do \
po_file=$locales_dir/$lang/LC_MESSAGES/app.po; \
echo "msgmerge --update $po_file "; \
mkdir -p $(dirname $po_file); \
[ -f $po_file ] && msgmerge --lang=$lang --update $po_file $locales_dir/app.pot --no-wrap || msginit --no-wrap --no-translator --locale=$lang --input=$locales_dir/app.pot --output-file=$po_file; \
msgattrib --no-wrap --no-obsolete -o $po_file $po_file; \
done;
if [ $GENERATE = 'true' ]; then
# Generate .po files for each available language.
echo $locales
for lang in $locales; do \
po_file=$locales_dir/$lang/LC_MESSAGES/app.po; \
echo "msgmerge --update $po_file "; \
mkdir -p $(dirname $po_file); \
[ -f $po_file ] && msgmerge --lang=$lang --update $po_file $locales_dir/app.pot --no-wrap || msginit --no-wrap --no-translator --locale=$lang --input=$locales_dir/app.pot --output-file=$po_file; \
msgattrib --no-wrap --no-obsolete -o $po_file $po_file; \
done;
fi

View File

@ -0,0 +1,33 @@
import argparse
import collections
import polib
def print_duplicates(path):
pofile = polib.pofile(path)
contexts_by_id = collections.defaultdict(list)
for e in pofile:
contexts_by_id[e.msgid].append(e.msgctxt)
count = collections.Counter(
[e.msgid for e in pofile]
)
duplicates = [
(k, v) for k, v in count.items()
if v > 1
]
for k, v in sorted(duplicates, key=lambda r: r[1], reverse=True):
print('{} entries - {}:'.format(v, k))
for ctx in contexts_by_id[k]:
print(' - {}'.format(ctx))
print()
total_duplicates = sum([v - 1 for _, v in duplicates])
print('{} total duplicates'.format(total_duplicates))
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument("po", help="Path of the po file to use as a source")
args = parser.parse_args()
print_duplicates(path=args.po)

View File

@ -83,7 +83,7 @@
<div class="ui stackable grid">
<div class="four wide column">
<h3 class="header">
<translate translate-context="Content/Home/Header">About Funkwhale</translate>
<translate translate-context="Footer/*/Title/Short">About Funkwhale</translate>
</h3>
<p v-translate translate-context="Content/Home/Paragraph">This pod runs Funkwhale, a community-driven project that lets you listen and share music and audio within a decentralized, open network.</p>
<p v-translate translate-context="Content/Home/Paragraph">Funkwhale is free and developped by a friendly community of volunteers.</p>

View File

@ -36,7 +36,7 @@
</div>
</section>
<footer class="actions">
<div class="ui cancel button"><translate translate-context="Popup/Keyboard shortcuts/Button.Label/Verb">Close</translate></div>
<div class="ui cancel button"><translate translate-context="*/*/Button.Label/Verb">Close</translate></div>
</footer>
</modal>
</template>

View File

@ -83,7 +83,7 @@
v-if="$store.state.auth.availablePermissions['library']"
class="item"
:to="{name: 'manage.library.edits', query: {q: 'is_approved:null'}}">
<i class="book icon"></i><translate translate-context="*/*/*">Library</translate>
<i class="book icon"></i><translate translate-context="*/*/*/Noun">Library</translate>
<div
v-if="$store.state.ui.notifications.pendingReviewEdits > 0"
:title="labels.pendingReviewEdits"

View File

@ -3,7 +3,7 @@
<div class="ui divider" />
<h3 class="ui header">{{ group.label }}</h3>
<div v-if="errors.length > 0" class="ui negative message">
<div class="header"><translate translate-context="Content/Settings/Error message.Title">Error while saving settings</translate></div>
<div class="header"><translate translate-context="Content/*/Error message.Title">Error while saving settings</translate></div>
<ul class="list">
<li v-for="error in errors">{{ error }}</li>
</ul>

View File

@ -97,7 +97,7 @@ export default {
},
title () {
if (this.playable) {
return this.$pgettext('*/Queue/Button/Title', 'More…')
return this.$pgettext('*/*/Button.Label/Noun', 'More…')
} else {
if (this.track) {
return this.$pgettext('*/Queue/Button/Title', 'This track is not available in any library you have access to')

View File

@ -39,7 +39,7 @@
<translate translate-context="Content/Album/Card.Link/Verb" :translate-params="{count: album.tracks.length - initialTracks}" :translate-n="album.tracks.length - initialTracks" translate-plural="Show %{ count } more tracks">Show %{ count } more track</translate>
</em>
<em v-else @click="showAllTracks = false" class="expand">
<translate translate-context="Content/*/Card.Link/Verb">Collapse</translate>
<translate translate-context="*/*/Button,Label">Collapse</translate>
</em>
</div>
</div>

View File

@ -5,7 +5,7 @@
<tr>
<th></th>
<th></th>
<th colspan="6"><translate translate-context="Content/Track/*/Noun">Title</translate></th>
<th colspan="6"><translate translate-context="*/*/*/Noun">Title</translate></th>
<th colspan="4"><translate translate-context="*/*/*/Noun">Artist</translate></th>
<th colspan="4"><translate translate-context="*/*/*">Album</translate></th>
<th colspan="4"><translate translate-context="Content/*/*">Duration</translate></th>

View File

@ -8,7 +8,7 @@
</ul>
</div>
<div class="ui field">
<label><translate translate-context="Content/Applications/Input.Label/Noun">Name</translate></label>
<label><translate translate-context="*/*/*/Noun">Name</translate></label>
<input name="name" required type="text" v-model="fields.name" />
</div>
<div class="ui field">
@ -21,7 +21,7 @@
</p>
</div>
<div class="ui field">
<label><translate translate-context="Content/Applications/Input.Label/Noun">Scopes</translate></label>
<label><translate translate-context="Content/*/*/Noun">Scopes</translate></label>
<p>
<translate translate-context="Content/Applications/Paragraph/">
Checking the parent "Read" or "Write" scopes implies access to all the corresponding children scopes.

View File

@ -6,7 +6,7 @@
<translate translate-context="Content/Applications/Link">Back to settings</translate>
</router-link>
<h2 class="ui header">
<translate translate-context="Content/Applications/Title">Create a new application</translate>
<translate translate-context="Content/Settings/Button.Label">Create a new application</translate>
</h2>
<application-form
:defaults="defaults"
@ -38,7 +38,7 @@ export default {
computed: {
labels() {
return {
title: this.$pgettext('Content/Applications/Title', "Create a new application")
title: this.$pgettext('Content/Settings/Button.Label', "Create a new application")
}
},
}

View File

@ -30,7 +30,7 @@
</div>
<div class="field">
<label>
<translate translate-context="Content/*/Input.Label">Password</translate> |
<translate translate-context="*/*/*">Password</translate> |
<router-link :to="{name: 'auth.password-reset', query: {email: credentials.username}}">
<translate translate-context="*/Login/*/Verb">Reset your password</translate>
</router-link>

View File

@ -244,7 +244,7 @@
</td>
<td>
<router-link class="ui basic tiny green button" :to="{name: 'settings.applications.edit', params: {id: app.client_id}}">
<translate translate-context="Content/Settings/Button.Label">Edit</translate>
<translate translate-context="Content/*/Button.Label/Verb">Edit</translate>
</router-link>
<dangerous-button
class="ui tiny basic button"
@ -272,7 +272,7 @@
<h2 class="ui header">
<i class="trash icon"></i>
<div class="content">
<translate translate-context="Content/Settings/Title/Verb">Delete my account</translate>
<translate translate-context="*/*/Button.Label">Delete my account</translate>
</div>
</h2>
<p>
@ -300,7 +300,7 @@
<div slot="modal-content">
<p><translate translate-context="Popup/Settings/Paragraph">This is irreversible and will permanently remove your data from our servers. You will we immediatly logged out.</translate></p>
</div>
<div slot="modal-confirm"><translate translate-context="Popup/Settings/Button.Label">Delete my account</translate></div>
<div slot="modal-confirm"><translate translate-context="*/*/Button.Label">Delete my account</translate></div>
</dangerous-button>
</div>
</section>

View File

@ -34,7 +34,7 @@
v-model="email">
</div>
<div class="field">
<label><translate translate-context="Content/*/Input.Label">Password</translate></label>
<label><translate translate-context="*/*/*">Password</translate></label>
<password-input v-model="password" />
</div>
<div class="field" v-if="!$store.state.instance.settings.users.registration_enabled.value">

View File

@ -17,7 +17,7 @@
<template v-else>
<section class="ui vertical stripe segment">
<h2>
<translate translate-context="*/*/*/Noun">Tracks</translate>
<translate translate-context="*/*/*">Tracks</translate>
</h2>
<track-table v-if="object" :artist="object.artist" :display-position="true" :tracks="object.tracks"></track-table>
</section>

View File

@ -92,8 +92,8 @@
<thead>
<tr>
<th><translate translate-context="Content/Library/Table.Label">Filename</translate></th>
<th><translate translate-context="Content/Library/*/in MB">Size</translate></th>
<th><translate translate-context="Content/Library/Table.Label (Value is Uploading/Uploaded/Error)">Status</translate></th>
<th><translate translate-context="Content/*/*/Noun">Size</translate></th>
<th><translate translate-context="*/*/*">Status</translate></th>
</tr>
</thead>
<tbody>

View File

@ -44,7 +44,7 @@
</tr>
<tr>
<td>
<translate translate-context="Popup/Import/Table.Label/Noun">Getting help</translate>
<translate translate-context="Footer/*/Link">Getting help</translate>
</td>
<td>
<ul>
@ -141,7 +141,7 @@ export default {
let detail = payload.detail || {}
d.errorRows = getErrors(detail)
} else {
d.label = this.$pgettext('Popup/Import/Error.Label', 'Unknown error')
d.label = this.$pgettext('*/*/Error', 'Unknown error')
d.detail = this.$pgettext('Popup/Import/Error.Label', 'An unknown error occurred')
}
let debugInfo = {

View File

@ -17,7 +17,7 @@
<artist-widget :controls="false" :filters="{playable: true, ordering: '-creation_date', tag: id}">
<template slot="title">
<router-link :to="{name: 'library.artists.browse', query: {tag: id}}">
<translate translate-context="*/*/*">Artists</translate>
<translate translate-context="*/*/*/Noun">Artists</translate>
</router-link>
</template>
</artist-widget>

View File

@ -9,7 +9,7 @@
<tbody>
<tr>
<td>
<translate translate-context="Content/Track/Table.Label/Noun">Copyright</translate>
<translate translate-context="Content/Track/*/Noun">Copyright</translate>
</td>
<td v-if="track.copyright" :title="track.copyright">{{ track.copyright|truncate(50) }}</td>
<td v-else>
@ -38,7 +38,7 @@
</tr>
<tr>
<td>
<translate translate-context="Content/Library/*/in MB">Size</translate>
<translate translate-context="Content/*/*/Noun">Size</translate>
</td>
<td v-if="upload && upload.size">{{ upload.size | humanSize }}</td>
<td v-else>

View File

@ -23,7 +23,7 @@
<input id="name" name="name" type="text" v-model="radioName" :placeholder="labels.placeholder.name" />
</div>
<div class="field">
<label for="description"><translate translate-context="Content/*/Input.Label/Noun">Description</translate></label>
<label for="description"><translate translate-context="*/*/*/Noun">Description</translate></label>
<textarea rows="2" id="description" type="text" v-model="radioDesc" :placeholder="labels.placeholder.description" />
</div>
<div class="ui toggle checkbox">

View File

@ -37,8 +37,8 @@
action-url="manage/library/albums/action/"
:filters="actionFilters">
<template slot="header-cells">
<th><translate translate-context="*/*/*">Title</translate></th>
<th><translate translate-context="*/*/*">Artist</translate></th>
<th><translate translate-context="*/*/*/Noun">Title</translate></th>
<th><translate translate-context="*/*/*/Noun">Artist</translate></th>
<th><translate translate-context="Content/Moderation/*/Noun">Domain</translate></th>
<th><translate translate-context="*/*/*">Tracks</translate></th>
<th><translate translate-context="Content/*/*/Noun">Release date</translate></th>

View File

@ -10,7 +10,7 @@
</form>
</div>
<div class="field">
<label><translate translate-context="Content/Search/Dropdown.Label (Value is All/Pending review/Approved/Rejected)">Status</translate></label>
<label><translate translate-context="*/*/*">Status</translate></label>
<select class="ui dropdown" @change="addSearchToken('is_approved', $event.target.value)" :value="getTokenValue('is_approved', '')">
<option value="">
<translate translate-context="Content/*/Dropdown">All</translate>

View File

@ -46,12 +46,12 @@
action-url="manage/library/libraries/action/"
:filters="actionFilters">
<template slot="header-cells">
<th><translate translate-context="*/*/*">Name</translate></th>
<th><translate translate-context="*/*/*">Account</translate></th>
<th><translate translate-context="*/*/*/Noun">Name</translate></th>
<th><translate translate-context="*/*/*/Noun">Account</translate></th>
<th><translate translate-context="Content/Moderation/*/Noun">Domain</translate></th>
<th><translate translate-context="*/*/*">Visibility</translate></th>
<th><translate translate-context="Content/*/*/Noun">Uploads</translate></th>
<th><translate translate-context="Content/*/*/Noun">Followers</translate></th>
<th><translate translate-context="*/*/*">Uploads</translate></th>
<th><translate translate-context="Content/Federation/*/Noun">Followers</translate></th>
<th><translate translate-context="Content/*/*/Noun">Creation date</translate></th>
</template>
<template slot="row-cells" slot-scope="scope">

View File

@ -39,8 +39,8 @@
idField="name"
:filters="actionFilters">
<template slot="header-cells">
<th><translate translate-context="*/*/*">Name</translate></th>
<th><translate translate-context="*/*/*">Artists</translate></th>
<th><translate translate-context="*/*/*/Noun">Name</translate></th>
<th><translate translate-context="*/*/*/Noun">Artists</translate></th>
<th><translate translate-context="*/*/*">Albums</translate></th>
<th><translate translate-context="*/*/*">Tracks</translate></th>
<th><translate translate-context="Content/*/*/Noun">Creation date</translate></th>

View File

@ -37,9 +37,9 @@
action-url="manage/library/tracks/action/"
:filters="actionFilters">
<template slot="header-cells">
<th><translate translate-context="*/*/*">Title</translate></th>
<th><translate translate-context="*/*/*/Noun">Title</translate></th>
<th><translate translate-context="*/*/*">Album</translate></th>
<th><translate translate-context="*/*/*">Artist</translate></th>
<th><translate translate-context="*/*/*/Noun">Artist</translate></th>
<th><translate translate-context="Content/Moderation/*/Noun">Domain</translate></th>
<th><translate translate-context="Content/*/*/Noun">License</translate></th>
<th><translate translate-context="Content/*/*/Noun">Creation date</translate></th>

View File

@ -18,7 +18,7 @@
</select>
</div>
<div class="field">
<label><translate translate-context="Content/Library/*/Noun">Import status</translate></label>
<label><translate translate-context="Content/*/*/Noun">Import status</translate></label>
<select class="ui dropdown" @change="addSearchToken('status', $event.target.value)" :value="getTokenValue('status', '')">
<option value=""><translate translate-context="Content/*/Dropdown">All</translate></option>
<option value="pending"><translate translate-context="Content/Library/*/Short">Pending</translate></option>
@ -57,9 +57,9 @@
action-url="manage/library/uploads/action/"
:filters="actionFilters">
<template slot="header-cells">
<th><translate translate-context="*/*/*">Name</translate></th>
<th><translate translate-context="*/*/*">Library</translate></th>
<th><translate translate-context="*/*/*">Account</translate></th>
<th><translate translate-context="*/*/*/Noun">Name</translate></th>
<th><translate translate-context="*/*/*/Noun">Library</translate></th>
<th><translate translate-context="*/*/*/Noun">Account</translate></th>
<th><translate translate-context="Content/Moderation/*/Noun">Domain</translate></th>
<th><translate translate-context="*/*/*">Visibility</translate></th>
<th><translate translate-context="Content/*/*/Noun">Import status</translate></th>

View File

@ -39,7 +39,7 @@
<template slot="header-cells">
<th><translate translate-context="*/*/*/Noun">Name</translate></th>
<th><translate translate-context="Content/Moderation/*/Noun">Domain</translate></th>
<th><translate translate-context="Content/Moderation/Table.Label/Noun">Uploads</translate></th>
<th><translate translate-context="*/*/*">Uploads</translate></th>
<th><translate translate-context="Content/Moderation/Table.Label/Short (Value is a date)">First seen</translate></th>
<th><translate translate-context="Content/Moderation/Table.Label/Noun">Last seen</translate></th>
<th><translate translate-context="Content/Moderation/Table.Label/Short">Under moderation rule</translate></th>

View File

@ -9,7 +9,7 @@
<div class="field" v-if="allowListEnabled">
<label><translate translate-context="Content/Moderation/*/Adjective">Is present on allow-list</translate></label>
<select class="ui dropdown" v-model="allowed">
<option :value="null"><translate translate-context="*/*/*">All</translate></option>
<option :value="null"><translate translate-context="Content/*/Dropdown">All</translate></option>
<option :value="true"><translate translate-context="*/*/*">Yes</translate></option>
<option :value="false"><translate translate-context="*/*/*">No</translate></option>
</select>

View File

@ -6,7 +6,7 @@
<i class="user icon"></i>{{ object.actor }} &nbsp;
<template v-if="object.is_active">
<i class="play icon"></i>
<translate translate-context="*/*/*">Enabled</translate>
<translate translate-context="*/*/*/State of feature">Enabled</translate>
</template>
<template v-if="!object.is_active">
<i class="pause icon"></i>

View File

@ -15,8 +15,8 @@
<div class="ui toggle checkbox">
<input id="policy-is-active" v-model="current.isActive" type="checkbox">
<label for="policy-is-active">
<translate translate-context="*/*/*" v-if="current.isActive" key="1">Enabled</translate>
<translate translate-context="*/*/*" v-else key="2">Disabled</translate>
<translate translate-context="*/*/*/State of feature" v-if="current.isActive" key="1">Enabled</translate>
<translate translate-context="*/*/*/State of feature" v-else key="2">Disabled</translate>
<tooltip :content="labels.isActiveHelp" />
</label>
</div>

View File

@ -41,7 +41,7 @@
</tr>
<tr>
<td>
<translate translate-context="*/*/*/Noun">Creation date</translate>
<translate translate-context="Content/*/*/Noun">Creation date</translate>
</td>
<td>
<human-date :date="obj.creation_date" :icon="true"></human-date>
@ -107,7 +107,7 @@
<div class="ui stackable two column grid">
<div class="column">
<h3>
<translate translate-context="Content/*/*/Short">Message</translate>
<translate translate-context="*/*/Field.Label/Noun">Message</translate>
</h3>
<expandable-div v-if="obj.summary" class="summary" :content="obj.summary">
<div v-html="markdown.makeHtml(obj.summary)"></div>
@ -132,7 +132,7 @@
<tbody>
<tr v-if="target">
<td>
<translate translate-context="*/*/*">Type</translate>
<translate translate-context="Content/Track/Table.Label/Noun">Type</translate>
</td>
<td colspan="2">
<i :class="[configs[target.type].icon, 'icon']"></i>
@ -154,7 +154,7 @@
</tr>
<tr v-if="target && target.type === 'account'">
<td>
<translate translate-context="*/*/*">Account</translate>
<translate translate-context="*/*/*/Noun">Account</translate>
</td>
<td>
<actor-link :admin="true" :actor="obj.target_owner"></actor-link>
@ -208,7 +208,7 @@
</div>
<div class="column">
<h3>
<translate translate-context="*/*/*">Actions</translate>
<translate translate-context="Content/*/*/Noun">Actions</translate>
</h3>
<div class="ui labelled icon basic buttons">
<button

View File

@ -35,7 +35,7 @@
</tr>
</tbody>
</table>
<button class="ui basic button" @click="invitations = []"><translate translate-context="Content/Admin/Button.Label/Verb">Clear</translate></button>
<button class="ui basic button" @click="invitations = []"><translate translate-context="Content/Library/Button.Label">Clear</translate></button>
</div>
</div>
</template>

View File

@ -15,7 +15,7 @@
</select>
</div>
<div class="field">
<label><translate translate-context="Content/Admin/*/Noun (Value is Used/Not used)">Status</translate></label>
<label><translate translate-context="*/*/*">Status</translate></label>
<select class="ui dropdown" v-model="isOpen">
<option :value="null"><translate translate-context="Content/*/Dropdown">All</translate></option>
<option :value="true"><translate translate-context="Content/Admin/Dropdown/Adjective">Open</translate></option>
@ -36,8 +36,8 @@
:action-url="'manage/users/invitations/action/'"
:filters="actionFilters">
<template slot="header-cells">
<th><translate translate-context="Content/Admin/Table.Label">Owner</translate></th>
<th><translate translate-context="Content/Admin/*/Noun (Value is Used/Not used)">Status</translate></th>
<th><translate translate-context="*/*/*">Owner</translate></th>
<th><translate translate-context="*/*/*">Status</translate></th>
<th><translate translate-context="Content/*/*/Noun">Creation date</translate></th>
<th><translate translate-context="Content/Admin/Table.Label/Noun">Expiration date</translate></th>
<th><translate translate-context="Content/Admin/Table.Label/Noun">Code</translate></th>

View File

@ -40,8 +40,8 @@
<th><translate translate-context="Content/Admin/Table.Label/Short, Noun">Account status</translate></th>
<th><translate translate-context="Content/Admin/Table.Label/Short, Noun (Value is a date)">Sign-up</translate></th>
<th><translate translate-context="Content/Profile/Table.Label/Short, Noun (Value is a date)">Last activity</translate></th>
<th><translate translate-context="Content/Admin/Table.Label/Noun">Permissions</translate></th>
<th><translate translate-context="Content/Admin/Table.Label/Noun (Value is Regular user/Admin)">Status</translate></th>
<th><translate translate-context="Content/*/*/Noun">Permissions</translate></th>
<th><translate translate-context="*/*/*">Status</translate></th>
</template>
<template slot="row-cells" slot-scope="scope">
<td>
@ -171,7 +171,7 @@ export default {
return [
{
'code': 'library',
'label': this.$pgettext('*/*/*', 'Library')
'label': this.$pgettext('*/*/*/Noun', 'Library')
},
{
'code': 'moderation',

View File

@ -11,7 +11,7 @@ export default {
type: 'account',
full_username: account.full_username,
label: account.full_username,
typeLabel: this.$pgettext("*/*/*", 'Account'),
typeLabel: this.$pgettext("*/*/*/Noun", 'Account'),
}
})
if (track) {
@ -26,7 +26,7 @@ export default {
type: 'track',
id: track.id,
label: track.title,
typeLabel: this.$pgettext("*/*/*", 'Track'),
typeLabel: this.$pgettext("*/*/*/Noun", 'Track'),
}
})
album = track.album
@ -53,7 +53,7 @@ export default {
type: 'artist',
id: artist.id,
label: artist.name,
typeLabel: this.$pgettext("*/*/*", 'Artist'),
typeLabel: this.$pgettext("*/*/*/Noun", 'Artist'),
}
})
}
@ -75,7 +75,7 @@ export default {
type: 'library',
uuid: library.uuid,
label: library.name,
typeLabel: this.$pgettext("*/*/*", 'Library'),
typeLabel: this.$pgettext("*/*/*/Noun", 'Library'),
}
})
}

View File

@ -43,7 +43,7 @@ export default {
label: this.$pgettext('*/*/*', 'Category'),
choices: {
takedown_request: this.$pgettext("Content/Moderation/Dropdown", "Takedown request"),
invalid_metadata: this.$pgettext("Content/Moderation/Dropdown", "Invalid metadata"),
invalid_metadata: this.$pgettext("Popup/Import/Error.Label", "Invalid metadata"),
illegal_content: this.$pgettext("Content/Moderation/Dropdown", "Illegal content"),
offensive_content: this.$pgettext("Content/Moderation/Dropdown", "Offensive content"),
other: this.$pgettext("Content/Moderation/Dropdown", "Other"),
@ -64,7 +64,7 @@ export default {
name: this.$pgettext('*/*/*/Noun', 'Name'),
length: this.$pgettext('*/*/*/Noun', 'Length'),
items_count: this.$pgettext('*/*/*/Noun', 'Items'),
size: this.$pgettext('Content/Library/*/in MB', 'Size'),
size: this.$pgettext('Content/*/*/Noun', 'Size'),
bitrate: this.$pgettext('Content/Track/*/Noun', 'Bitrate'),
duration: this.$pgettext('Content/*/*', 'Duration'),
date_joined: this.$pgettext('Content/Admin/Table.Label/Noun', 'Sign-up date'),
@ -73,7 +73,7 @@ export default {
domain: this.$pgettext('Content/Moderation/*/Noun', 'Domain'),
users: this.$pgettext('*/*/*/Noun', 'Users'),
received_messages: this.$pgettext('Content/Moderation/*/Noun', 'Received messages'),
uploads: this.$pgettext('Content/Moderation/Table.Label/Noun', 'Uploads'),
uploads: this.$pgettext('*/*/*', 'Uploads'),
followers: this.$pgettext('Content/Federation/*/Noun', 'Followers'),
},
scopes: {
@ -86,11 +86,11 @@ export default {
description: this.$pgettext('Content/OAuth Scopes/Paragraph', 'Access to audio files, libraries, artists, albums and tracks'),
},
favorites: {
label: this.$pgettext('Content/OAuth Scopes/Label', 'Favorites'),
label: this.$pgettext('Sidebar/Favorites/List item.Link/Noun', 'Favorites'),
description: this.$pgettext('Content/OAuth Scopes/Paragraph', 'Access to favorites'),
},
listenings: {
label: this.$pgettext('Content/OAuth Scopes/Label', 'Listenings'),
label: this.$pgettext('*/*/*/Noun', 'Listenings'),
description: this.$pgettext('Content/OAuth Scopes/Paragraph', 'Access to listening history'),
},
follows: {
@ -98,23 +98,23 @@ export default {
description: this.$pgettext('Content/OAuth Scopes/Paragraph', 'Access to follows'),
},
playlists: {
label: this.$pgettext('Content/OAuth Scopes/Label', 'Playlists'),
label: this.$pgettext('*/*/*', 'Playlists'),
description: this.$pgettext('Content/OAuth Scopes/Paragraph', 'Access to playlists'),
},
radios: {
label: this.$pgettext('Content/OAuth Scopes/Label', 'Radios'),
label: this.$pgettext('*/*/*', 'Radios'),
description: this.$pgettext('Content/OAuth Scopes/Paragraph', 'Access to radios'),
},
filters: {
label: this.$pgettext('Content/OAuth Scopes/Label', 'Content filters'),
label: this.$pgettext('Content/Settings/Title/Noun', 'Content filters'),
description: this.$pgettext('Content/OAuth Scopes/Paragraph', 'Access to content filters'),
},
notifications: {
label: this.$pgettext('Content/OAuth Scopes/Label', 'Notifications'),
label: this.$pgettext('*/Notifications/*', 'Notifications'),
description: this.$pgettext('Content/OAuth Scopes/Paragraph', 'Access to notifications'),
},
edits: {
label: this.$pgettext('Content/OAuth Scopes/Label', 'Edits'),
label: this.$pgettext('*/Admin/*/Noun', 'Edits'),
description: this.$pgettext('Content/OAuth Scopes/Paragraph', 'Access to edits'),
}
}

View File

@ -45,7 +45,7 @@
<th></th>
<th><translate translate-context="*/*/*/Noun">Name</translate></th>
<th class="sorted descending"><translate translate-context="Popup/Playlist/Table.Label/Short">Last modification</translate></th>
<th><translate translate-context="*/*/*/Noun">Tracks</translate></th>
<th><translate translate-context="*/*/*">Tracks</translate></th>
<th></th>
</tr>
</thead>

View File

@ -9,7 +9,7 @@ export default {
getConfigs () {
return {
artist: {
label: this.$pgettext('*/*/*', 'Artist'),
label: this.$pgettext('*/*/*/Noun', 'Artist'),
icon: 'users',
getDeleteUrl: (obj) => {
return `manage/library/artists/${obj.id}/`
@ -26,7 +26,7 @@ export default {
},
{
id: 'creation_date',
label: this.$pgettext('*/*/*/Noun', 'Creation date'),
label: this.$pgettext('Content/*/*/Noun', 'Creation date'),
getValue: (obj) => { return obj.creation_date }
},
{
@ -61,7 +61,7 @@ export default {
},
{
id: 'creation_date',
label: this.$pgettext('*/*/*/Noun', 'Creation date'),
label: this.$pgettext('Content/*/*/Noun', 'Creation date'),
getValue: (obj) => { return obj.creation_date }
},
{
@ -85,7 +85,7 @@ export default {
]
},
track: {
label: this.$pgettext('*/*/*', 'Track'),
label: this.$pgettext('*/*/*/Noun', 'Track'),
icon: 'music',
getDeleteUrl: (obj) => {
return `manage/library/tracks/${obj.id}/`
@ -129,7 +129,7 @@ export default {
]
},
library: {
label: this.$pgettext('*/*/*', 'Library'),
label: this.$pgettext('*/*/*/Noun', 'Library'),
icon: 'book',
getDeleteUrl: (obj) => {
return `manage/library/libraries/${obj.uuid}/`
@ -176,7 +176,7 @@ export default {
]
},
account: {
label: this.$pgettext('*/*/*', 'Account'),
label: this.$pgettext('*/*/*/Noun', 'Account'),
icon: 'user',
urls: {
getAdminDetail: (obj) => { return {name: 'manage.moderation.accounts.detail', params: {id: `${obj.preferred_username}@${obj.domain}`}}}

View File

@ -81,10 +81,10 @@ export default {
let usersLabel = this.$pgettext('*/*/*/Noun', 'Users')
let musicLabel = this.$pgettext('*/*/*/Noun', 'Music')
let playlistsLabel = this.$pgettext('*/*/*', 'Playlists')
let federationLabel = this.$pgettext('Content/Admin/Menu', 'Federation')
let moderationLabel = this.$pgettext('Content/Admin/Menu', 'Moderation')
let federationLabel = this.$pgettext('*/*/*', 'Federation')
let moderationLabel = this.$pgettext('*/Moderation/*', 'Moderation')
let subsonicLabel = this.$pgettext('Content/Admin/Menu', 'Subsonic')
let statisticsLabel = this.$pgettext('Content/Admin/Menu', 'Statistics')
let statisticsLabel = this.$pgettext('Content/Home/Header', 'Statistics')
let uiLabel = this.$pgettext('Content/Admin/Menu', 'User Interface')
let errorLabel = this.$pgettext('Content/Admin/Menu', 'Error reporting')
return [

View File

@ -256,7 +256,7 @@
<tr>
<td>
<router-link :to="{name: 'manage.library.uploads', query: {q: getQuery('album_id', object.id) }}">
<translate translate-context="Content/Moderation/Table.Label/Noun">Uploads</translate>
<translate translate-context="*/*/*">Uploads</translate>
</router-link>
</td>
<td>

View File

@ -244,7 +244,7 @@
<tr>
<td>
<router-link :to="{name: 'manage.library.uploads', query: {q: getQuery('artist_id', object.id) }}">
<translate translate-context="Content/Moderation/Table.Label/Noun">Uploads</translate>
<translate translate-context="*/*/*">Uploads</translate>
</router-link>
</td>
<td>

View File

@ -21,7 +21,7 @@ export default {
computed: {
labels() {
return {
title: this.$pgettext('*/*/*', 'Artists')
title: this.$pgettext('*/*/*/Noun', 'Artists')
}
}
}

View File

@ -6,7 +6,7 @@
:to="{name: 'manage.library.edits'}"><translate translate-context="*/Admin/*/Noun">Edits</translate></router-link>
<router-link
class="ui item"
:to="{name: 'manage.library.artists'}"><translate translate-context="*/*/*">Artists</translate></router-link>
:to="{name: 'manage.library.artists'}"><translate translate-context="*/*/*/Noun">Artists</translate></router-link>
<router-link
class="ui item"
:to="{name: 'manage.library.albums'}"><translate translate-context="*/*/*">Albums</translate></router-link>
@ -15,13 +15,13 @@
:to="{name: 'manage.library.tracks'}"><translate translate-context="*/*/*">Tracks</translate></router-link>
<router-link
class="ui item"
:to="{name: 'manage.library.libraries'}"><translate translate-context="*/*/*">Libraries</translate></router-link>
:to="{name: 'manage.library.libraries'}"><translate translate-context="*/*/*/Noun">Libraries</translate></router-link>
<router-link
class="ui item"
:to="{name: 'manage.library.uploads'}"><translate translate-context="*/*/*">Uploads</translate></router-link>
<router-link
class="ui item"
:to="{name: 'manage.library.tags'}"><translate translate-context="*/*/*">Tags</translate></router-link>
:to="{name: 'manage.library.tags'}"><translate translate-context="*/*/*/Noun">Tags</translate></router-link>
</nav>
<router-view :key="$route.fullPath"></router-view>
</div>

View File

@ -21,7 +21,7 @@ export default {
computed: {
labels() {
return {
title: this.$pgettext('*/*/*', 'Libraries')
title: this.$pgettext('*/*/*/Noun', 'Libraries')
}
}
}

View File

@ -226,7 +226,7 @@
<tr>
<td>
<router-link :to="{name: 'manage.library.artists', query: {q: getQuery('library_id', object.id) }}">
<translate translate-context="*/*/*">Artists</translate>
<translate translate-context="*/*/*/Noun">Artists</translate>
</router-link>
</td>
<td>
@ -256,7 +256,7 @@
<tr>
<td>
<router-link :to="{name: 'manage.library.uploads', query: {q: getQuery('library_id', object.id) }}">
<translate translate-context="Content/Moderation/Table.Label/Noun">Uploads</translate>
<translate translate-context="*/*/*">Uploads</translate>
</router-link>
</td>
<td>

View File

@ -121,7 +121,7 @@
<tr>
<td>
<router-link :to="{name: 'manage.library.artists', query: {q: getQuery('tag', object.name) }}">
<translate translate-context="*/*/*">Artists</translate>
<translate translate-context="*/*/*/Noun">Artists</translate>
</router-link>
</td>
<td>

View File

@ -21,7 +21,7 @@ export default {
computed: {
labels() {
return {
title: this.$pgettext('*/*/*', 'Tags')
title: this.$pgettext('*/*/*/Noun', 'Tags')
}
}
}

View File

@ -111,7 +111,7 @@
<tr>
<td>
<router-link :to="{name: 'manage.library.albums.detail', params: {id: object.album.id }}">
<translate translate-context="*/*/*/Noun">Album</translate>
<translate translate-context="*/*/*">Album</translate>
</router-link>
</td>
<td>
@ -141,7 +141,7 @@
</tr>
<tr>
<td>
<translate translate-context="*/*/*/Noun">Position</translate>
<translate translate-context="*/*/*/Short, Noun">Position</translate>
</td>
<td>
{{ object.position }}
@ -157,7 +157,7 @@
</tr>
<tr v-if="object.copyright">
<td>
<translate translate-context="Content/Track/Table.Label/Noun">Copyright</translate>
<translate translate-context="Content/Track/*/Noun">Copyright</translate>
</td>
<td>{{ object.copyright }}</td>
</tr>
@ -308,7 +308,7 @@
<tr>
<td>
<router-link :to="{name: 'manage.library.uploads', query: {q: getQuery('track_id', object.id) }}">
<translate translate-context="Content/Moderation/Table.Label/Noun">Uploads</translate>
<translate translate-context="*/*/*">Uploads</translate>
</router-link>
</td>
<td>

View File

@ -142,7 +142,7 @@
<tr>
<td>
<router-link :to="{name: 'manage.library.libraries.detail', params: {id: object.library.uuid }}">
<translate translate-context="*/*/*">Library</translate>
<translate translate-context="*/*/*/Noun">Library</translate>
</router-link>
</td>
<td>
@ -197,7 +197,7 @@
<tr v-if="object.track">
<td>
<router-link :to="{name: 'manage.library.tracks.detail', params: {id: object.track.id }}">
<translate translate-context="*/*/*">Track</translate>
<translate translate-context="*/*/*/Noun">Track</translate>
</router-link>
</td>
<td>

View File

@ -154,17 +154,17 @@
@change="updateUser('is_active')"
v-model="object.user.is_active" type="checkbox">
<label>
<translate v-if="object.user.is_active" key="1" translate-context="*/*/*">Enabled</translate>
<translate v-else key="2" translate-context="*/*/*">Disabled</translate>
<translate v-if="object.user.is_active" key="1" translate-context="*/*/*/State of feature">Enabled</translate>
<translate v-else key="2" translate-context="*/*/*/State of feature">Disabled</translate>
</label>
</div>
<translate v-else-if="object.user.is_active" key="1" translate-context="*/*/*">Enabled</translate>
<translate v-else key="2" translate-context="*/*/*">Disabled</translate>
<translate v-else-if="object.user.is_active" key="1" translate-context="*/*/*/State of feature">Enabled</translate>
<translate v-else key="2" translate-context="*/*/*/State of feature">Disabled</translate>
</td>
</tr>
<tr v-if="object.user">
<td>
<translate translate-context="Content/Admin/Table.Label/Noun">Permissions</translate>
<translate translate-context="Content/*/*/Noun">Permissions</translate>
</td>
<td>
<select
@ -179,7 +179,7 @@
</tr>
<tr>
<td>
<translate translate-context="Content/Moderation/Table.Label/Noun">Type</translate>
<translate translate-context="Content/Track/Table.Label/Noun">Type</translate>
</td>
<td>
{{ object.type }}
@ -307,7 +307,7 @@
</tr>
<tr v-if="object.user">
<td>
<translate translate-context="Content/Moderation/Table.Label/Noun" >Upload quota</translate>
<translate translate-context="*/*/*" >Upload quota</translate>
<span :data-tooltip="labels.uploadQuota"><i class="question circle icon"></i></span>
</td>
<td>
@ -347,7 +347,7 @@
<tr>
<td>
<router-link :to="{name: 'manage.library.uploads', query: {q: getQuery('account', object.full_username) }}">
<translate translate-context="Content/Moderation/Table.Label/Noun">Uploads</translate>
<translate translate-context="*/*/*">Uploads</translate>
</router-link>
</td>
<td>
@ -372,7 +372,7 @@
</tr>
<tr>
<td>
<translate translate-context="*/*/*/Noun">Tracks</translate>
<translate translate-context="*/*/*">Tracks</translate>
</td>
<td>
{{ stats.tracks }}
@ -515,7 +515,7 @@ export default {
return [
{
code: "library",
label: this.$pgettext('*/*/*', "Library")
label: this.$pgettext('*/*/*/Noun', "Library")
},
{
code: "moderation",

View File

@ -37,14 +37,14 @@
@click.prevent="setAllowList(false)"
:class="['ui', 'labeled', {loading: isLoadingAllowList}, 'icon', 'button']">
<i class="x icon"></i>
<translate translate-context="Content/Moderation/Link/Verb">Remove from allow-list</translate>
<translate translate-context="Content/Moderation/Action/Verb">Remove from allow-list</translate>
</button>
<button
v-else
@click.prevent="setAllowList(true)"
:class="['ui', 'labeled', {loading: isLoadingAllowList}, 'icon', 'button']">
<i class="check icon"></i>
<translate translate-context="Content/Moderation/Link/Verb">Add to allow-list</translate>
<translate translate-context="Content/Moderation/Action/Verb">Add to allow-list</translate>
</button>
</div>
</div>
@ -150,7 +150,7 @@
<template v-if="object.nodeinfo && object.nodeinfo.status === 'error'">
<tr>
<td>
<translate translate-context="Content/Moderation/Table.Label (Value is Error message)">Status</translate>
<translate translate-context="*/*/*">Status</translate>
</td>
<td>
<translate translate-context="Content/Moderation/Table">Error while fetching node info</translate>&nbsp;
@ -279,7 +279,7 @@
<tr>
<td>
<router-link :to="{name: 'manage.library.uploads', query: {q: getQuery('domain', object.name) }}">
<translate translate-context="Content/Moderation/Table.Label/Noun">Uploads</translate>
<translate translate-context="*/*/*">Uploads</translate>
</router-link>
</td>
<td>
@ -309,7 +309,7 @@
<tr>
<td>
<router-link :to="{name: 'manage.library.tracks', query: {q: getQuery('domain', object.name) }}">
<translate translate-context="*/*/*/Noun">Tracks</translate>
<translate translate-context="*/*/*">Tracks</translate>
</router-link>
</td>
<td>

View File

@ -16,7 +16,7 @@
</div>
<div class="field" v-if="allowListEnabled">
<input type="checkbox" name="allowed" id="allowed" v-model="domainAllowed">
<label for="allowed"><translate translate-context="Content/Moderation/Form.Label/Verb">Add to allow-list</translate></label>
<label for="allowed"><translate translate-context="Content/Moderation/Action/Verb">Add to allow-list</translate></label>
</div>
<div class="field">
<button :class="['ui', {'loading': isCreating}, 'green', 'button']" type="submit" :disabled="isCreating">

View File

@ -1,7 +1,7 @@
<template>
<main v-title="labels.accounts">
<section class="ui vertical stripe segment">
<h2 class="ui header"><translate translate-context="*/Moderation/Title,Name">Reports</translate></h2>
<h2 class="ui header"><translate translate-context="*/Moderation/*/Noun">Reports</translate></h2>
<div class="ui hidden divider"></div>
<div class="ui inline form">
<div class="fields">
@ -12,7 +12,7 @@
</form>
</div>
<div class="field">
<label><translate translate-context="Content/Search/Dropdown.Label (Value is All/Resolved/Unresolved)">Status</translate></label>
<label><translate translate-context="*/*/*">Status</translate></label>
<select class="ui dropdown" @change="addSearchToken('resolved', $event.target.value)" :value="getTokenValue('resolved', '')">
<option value="">
<translate translate-context="Content/*/Dropdown">All</translate>
@ -205,7 +205,7 @@ export default {
labels () {
return {
searchPlaceholder: this.$pgettext('Content/Search/Input.Placeholder', 'Search by account, summary, domain…'),
reports: this.$pgettext('*/Moderation/Title,Name', "Reports"),
reports: this.$pgettext('*/Moderation/*/Noun', "Reports"),
}
},
},

View File

@ -6,7 +6,7 @@
:to="{name: 'content.libraries.index'}"><translate translate-context="*/*/*/Noun">Libraries</translate></router-link>
<router-link
class="ui item"
:to="{name: 'content.libraries.files'}"><translate translate-context="*/*/*/Noun">Tracks</translate></router-link>
:to="{name: 'content.libraries.files'}"><translate translate-context="*/*/*">Tracks</translate></router-link>
</nav>
<router-view :key="$route.fullPath"></router-view>
</main>

View File

@ -6,7 +6,7 @@
<detail-area v-else :library="library">
<div class="ui top attached tabular menu">
<a :class="['item', {active: currentTab === 'follows'}]" @click="currentTab = 'follows'"><translate translate-context="Content/Federation/*/Noun">Followers</translate></a>
<a :class="['item', {active: currentTab === 'tracks'}]" @click="currentTab = 'tracks'"><translate translate-context="*/*/*/Noun">Tracks</translate></a>
<a :class="['item', {active: currentTab === 'tracks'}]" @click="currentTab = 'tracks'"><translate translate-context="*/*/*">Tracks</translate></a>
<a :class="['item', {active: currentTab === 'edit'}]" @click="currentTab = 'edit'"><translate translate-context="Content/*/Button.Label/Verb">Edit</translate></a>
</div>
<div :class="['ui', 'bottom', 'attached', 'segment', {hidden: currentTab != 'follows'}]">
@ -26,7 +26,7 @@
<tr>
<th><translate translate-context="Content/Library/Table.Label">User</translate></th>
<th><translate translate-context="Content/Library/Table.Label">Date</translate></th>
<th><translate translate-context="Content/Library.Federation/Table.Label (Value is Approved/Rejected)">Status</translate></th>
<th><translate translate-context="*/*/*">Status</translate></th>
<th><translate translate-context="Content/Library/Table.Label">Action</translate></th>
</tr>
</thead>

View File

@ -9,7 +9,7 @@
</form>
</div>
<div class="field">
<label><translate translate-context="Content/Library/*/Noun">Import status</translate></label>
<label><translate translate-context="Content/*/*/Noun">Import status</translate></label>
<select class="ui dropdown" @change="addSearchToken('status', $event.target.value)" :value="getTokenValue('status', '')">
<option value=""><translate translate-context="Content/*/Dropdown">All</translate></option>
<option value="pending"><translate translate-context="Content/Library/*/Short">Pending</translate></option>
@ -53,13 +53,13 @@
@refresh="fetchData"
:filters="actionFilters">
<template slot="header-cells">
<th><translate translate-context="Content/Track/*/Noun">Title</translate></th>
<th><translate translate-context="*/*/*/Noun">Title</translate></th>
<th><translate translate-context="*/*/*/Noun">Artist</translate></th>
<th><translate translate-context="*/*/*">Album</translate></th>
<th><translate translate-context="*/*/*/Noun">Upload date</translate></th>
<th><translate translate-context="Content/Library/*/Noun">Import status</translate></th>
<th><translate translate-context="Content/*/*/Noun">Import status</translate></th>
<th><translate translate-context="Content/*/*">Duration</translate></th>
<th><translate translate-context="Content/Library/*/in MB">Size</translate></th>
<th><translate translate-context="Content/*/*/Noun">Size</translate></th>
</template>
<template slot="row-cells" slot-scope="scope">
<template v-if="scope.obj.track">

View File

@ -12,11 +12,11 @@
<input name="name" v-model="currentName" :placeholder="labels.namePlaceholder" required maxlength="100">
</div>
<div class="field">
<label><translate translate-context="Content/*/Input.Label/Noun">Description</translate></label>
<label><translate translate-context="*/*/*/Noun">Description</translate></label>
<textarea v-model="currentDescription" :placeholder="labels.descriptionPlaceholder" maxlength="2000"></textarea>
</div>
<div class="field">
<label><translate translate-context="Content/Library/Dropdown.Label">Visibility</translate></label>
<label><translate translate-context="*/*/*">Visibility</translate></label>
<p><translate translate-context="Content/Library/Paragraph">You are able to share your library with other people, regardless of its visibility.</translate></p>
<select class="ui dropdown" v-model="currentVisibilityLevel">
<option :value="c" v-for="c in ['me', 'instance', 'everyone']">{{ sharedLabels.fields.privacy_level.choices[c] }}</option>

View File

@ -74,7 +74,7 @@
:playlist="playlist" :playlist-tracks="playlistTracks"></playlist-editor>
</template>
<template v-else>
<h2><translate translate-context="*/*/*/Noun">Tracks</translate></h2>
<h2><translate translate-context="*/*/*">Tracks</translate></h2>
<track-table :display-position="true" :tracks="tracks"></track-table>
</template>
</section>
@ -118,7 +118,7 @@ export default {
computed: {
labels() {
return {
playlist: this.$pgettext('Head/Playlist/Title', 'Playlist')
playlist: this.$pgettext('*/*/*', 'Playlist')
}
}
},

View File

@ -32,7 +32,7 @@
</div>
</section>
<section class="ui vertical stripe segment">
<h2><translate translate-context="*/*/*/Noun">Tracks</translate></h2>
<h2><translate translate-context="*/*/*">Tracks</translate></h2>
<track-table :tracks="tracks"></track-table>
<div class="ui center aligned basic segment">
<pagination