diff --git a/front/src/App.vue b/front/src/App.vue index a0fd361b2..51bdf2a03 100644 --- a/front/src/App.vue +++ b/front/src/App.vue @@ -109,7 +109,7 @@ store.dispatch('auth/fetchUser') diff --git a/front/src/components/auth/ApplicationForm.vue b/front/src/components/auth/ApplicationForm.vue index 9ad4a5a04..f34001d88 100644 --- a/front/src/components/auth/ApplicationForm.vue +++ b/front/src/components/auth/ApplicationForm.vue @@ -202,16 +202,16 @@ const allScopes = computed(() => { :class="['ui', {'loading': isLoading}, 'success', 'button']" type="submit" > - {{ $t('components.auth.ApplicationForm.updateButtonLabel') }} - - + {{ $t('components.auth.ApplicationForm.createButtonLabel') }} - + diff --git a/front/src/components/auth/Settings.vue b/front/src/components/auth/Settings.vue index 6aecd8e41..5c5d4b38f 100644 --- a/front/src/components/auth/Settings.vue +++ b/front/src/components/auth/Settings.vue @@ -384,7 +384,7 @@ fetchOwnedApps() {{ $t('components.auth.Settings.changePasswordHeader') }}
- {{ $t('components.auth.Settings.changePasswordMessage') }} + {{ $t('components.auth.Settings.changePasswordMessage') }} {{ $t('components.auth.Settings.changePasswordMessageContinued') }}

- {{ $t('components.auth.SubsonicTokenForm.subsonicApiDescription') }} + {{ $t('components.auth.SubsonicTokenForm.subsonicApiDescription') }} {{ $t('components.auth.SubsonicTokenForm.subsonicApiDescriptionContinued') }}

{{ $t('components.auth.SubsonicTokenForm.subsonicPasswordInfo') }} diff --git a/front/src/components/channels/AlbumModal.vue b/front/src/components/channels/AlbumModal.vue index 098bf3f4b..d1ce60380 100644 --- a/front/src/components/channels/AlbumModal.vue +++ b/front/src/components/channels/AlbumModal.vue @@ -33,16 +33,16 @@ const albumForm = ref() class="small" >

- {{ $t('components.channels.AlbumModal.newSeriesHeader') }} - - + {{ $t('components.channels.AlbumModal.newAlbumHeader') }} - +

{ } if (statusData.value.totalFiles) { - const msg = t('components.channels.UploadModal.fileCount', statusData.value.totalFiles) - info.push(t(msg, { count: statusData.value.totalFiles })) + const msg = t('components.channels.UploadModal.fileCount', { count: statusData.value.totalFiles }) + info.push(msg) } if (statusData.value.progress) { diff --git a/front/src/components/library/FileUpload.vue b/front/src/components/library/FileUpload.vue index b39283b4f..4bae31256 100644 --- a/front/src/components/library/FileUpload.vue +++ b/front/src/components/library/FileUpload.vue @@ -363,7 +363,7 @@ useEventListener(window, 'beforeunload', (event) => { {{ $t('components.library.FileUpload.localUploadCopyright') }}
  • - {{ $t('components.library.FileUpload.localUploadTag') }} + {{ $t('components.library.FileUpload.localUploadTag') }} 

    - {{ $t('components.library.TrackEdit.editTrackHeader') }} - - + {{ $t('components.library.TrackEdit.suggestEditHeader') }} - +

    { {{ humanSize(scope.obj.size) }} - {{ $t('components.manage.library.UploadsTable.notApplicable') }} - + @@ -358,11 +358,11 @@ const getPrivacyLevelChoice = (privacyLevel: PrivacyLevel) => { v-if="scope.obj.accessed_date" :date="scope.obj.accessed_date" /> - {{ $t('components.manage.library.UploadsTable.notApplicable') }} - + diff --git a/front/src/components/playlists/PlaylistModal.vue b/front/src/components/playlists/PlaylistModal.vue index cdbe3dc8c..87b91682b 100644 --- a/front/src/components/playlists/PlaylistModal.vue +++ b/front/src/components/playlists/PlaylistModal.vue @@ -93,11 +93,11 @@ store.dispatch('playlists/fetchOwn')
    - {{ $t('components.playlists.PlaylistModal.managePlaylistsHeader') }} - +
    { } store.commit('ui/addMessage', { - content: t('%{ count } tracks were added to your queue | %{ count } track was added to your queue | %{ count } tracks were added to your queue', tracks.length), + content: t('composables.audio.usePlayOptions.addToQueueMessage', { count: tracks.length }), date: new Date() }) } diff --git a/front/src/composables/locale/useSharedLabels.ts b/front/src/composables/locale/useSharedLabels.ts index 3c4d5f182..fcbf13c7d 100644 --- a/front/src/composables/locale/useSharedLabels.ts +++ b/front/src/composables/locale/useSharedLabels.ts @@ -8,143 +8,143 @@ const { t } = i18n.global export default () => ({ fields: { privacy_level: { - label: t('Activity visibility'), - help: t('Determine the visibility level of your activity'), + label: t('composables.locale.useSharedLabels.fields.privacyLevel.label'), + help: t('composables.locale.useSharedLabels.fields.privacyLevel.help'), choices: { - me: t('Nobody except me'), - instance: t('Everyone on this instance'), - everyone: t('Everyone, across all instances') + me: t('composables.locale.useSharedLabels.fields.privacyLevel.choices.private'), + instance: t('composables.locale.useSharedLabels.fields.privacyLevel.choices.instance'), + everyone: t('composables.locale.useSharedLabels.fields.privacyLevel.choices.public') } as Record, shortChoices: { - me: t('Private'), - instance: t('Instance'), - everyone: t('Everyone') + me: t('composables.locale.useSharedLabels.fields.privacyLevel.shortChoices.private'), + instance: t('composables.locale.useSharedLabels.fields.privacyLevel.shortChoices.instance'), + everyone: t('composables.locale.useSharedLabels.fields.privacyLevel.shortChoices.public') } as Record }, import_status: { - label: t('Click to display more information about the import process for this upload'), + label: t('composables.locale.useSharedLabels.fields.importStatus.label'), choices: { skipped: { - label: t('Skipped'), - help: t('This track is already present in one of your libraries') + label: t('composables.locale.useSharedLabels.fields.importStatus.choices.skipped.label'), + help: t('composables.locale.useSharedLabels.fields.importStatus.choices.skipped.help') }, draft: { - label: t('Draft'), - help: t('This track has been uploaded, but hasn\'t been scheduled for processing yet') + label: t('composables.locale.useSharedLabels.fields.importStatus.choices.draft.label'), + help: t('composables.locale.useSharedLabels.fields.importStatus.choices.draft.help') }, pending: { - label: t('Pending'), - help: t('This track has been uploaded, but hasn\'t been processed by the server yet') + label: t('composables.locale.useSharedLabels.fields.importStatus.choices.pending.label'), + help: t('composables.locale.useSharedLabels.fields.importStatus.choices.pending.help') }, errored: { - label: t('Errored'), - help: t('This track could not be processed, please make sure it is tagged correctly') + label: t('composables.locale.useSharedLabels.fields.importStatus.choices.errored.label'), + help: t('composables.locale.useSharedLabels.fields.importStatus.choices.errored.help') }, finished: { - label: t('Finished'), - help: t('Imported') + label: t('composables.locale.useSharedLabels.fields.importStatus.choices.finished.label'), + help: t('composables.locale.useSharedLabels.fields.importStatus.choices.finished.help') } } as Record }, report_type: { - label: t('Category'), + label: t('composables.locale.useSharedLabels.fields.reportType.label'), choices: { - takedown_request: t('Takedown request'), - invalid_metadata: t('Invalid metadata'), - illegal_content: t('Illegal content'), - offensive_content: t('Offensive content'), - other: t('Other') + takedown_request: t('composables.locale.useSharedLabels.fields.reportType.choices.takedownRequest'), + invalid_metadata: t('composables.locale.useSharedLabels.fields.reportType.choices.invalidMetadata'), + illegal_content: t('composables.locale.useSharedLabels.fields.reportType.choices.illegalContent'), + offensive_content: t('composables.locale.useSharedLabels.fields.reportType.choices.offensiveContent'), + other: t('composables.locale.useSharedLabels.fields.reportType.choices.other') } }, summary: { - label: t('Bio'), + label: t('composables.locale.useSharedLabels.fields.summary.label'), help: undefined }, content_category: { - label: t('Content category'), + label: t('composables.locale.useSharedLabels.fields.contentCategory.label'), choices: { - podcast: t('Podcast'), - music: t('Music'), - other: t('Other') + podcast: t('composables.locale.useSharedLabels.fields.contentCategory.choices.podcast'), + music: t('composables.locale.useSharedLabels.fields.contentCategory.choices.music'), + other: t('composables.locale.useSharedLabels.fields.contentCategory.choices.other') } } }, filters: { - creation_date: t('Creation date'), - release_date: t('Release date'), - accessed_date: t('Accessed date'), - applied_date: t('Applied date'), - handled_date: t('Handled date'), - first_seen: t('First seen date'), - last_seen: t('Last seen date'), - modification_date: t('Modification date'), - expiration_date: t('Expiration date'), - track_title: t('Track name'), - album_title: t('Album name'), - artist_name: t('Artist name'), - name: t('Name'), - length: t('Duration'), - items_count: t('Items'), - size: t('Size'), - bitrate: t('Bitrate'), - duration: t('Duration'), - date_joined: t('Sign-up date'), - last_activity: t('Last activity'), - username: t('Username'), - domain: t('Domain'), - users: t('Users'), - received_messages: t('Received messages'), - uploads: t('Uploads'), - followers: t('Followers') + creation_date: t('composables.locale.useSharedLabels.filters.creationDate'), + release_date: t('composables.locale.useSharedLabels.filters.releaseDate'), + accessed_date: t('composables.locale.useSharedLabels.filters.accessedDate'), + applied_date: t('composables.locale.useSharedLabels.filters.appliedDate'), + handled_date: t('composables.locale.useSharedLabels.filters.handledDate'), + first_seen: t('composables.locale.useSharedLabels.filters.firstSeen'), + last_seen: t('composables.locale.useSharedLabels.filters.lastSeen'), + modification_date: t('composables.locale.useSharedLabels.filters.modificationDate'), + expiration_date: t('composables.locale.useSharedLabels.filters.expirationDate'), + track_title: t('composables.locale.useSharedLabels.filters.trackTitle'), + album_title: t('composables.locale.useSharedLabels.filters.albumTitle'), + artist_name: t('composables.locale.useSharedLabels.filters.artistName'), + name: t('composables.locale.useSharedLabels.filters.name'), + length: t('composables.locale.useSharedLabels.filters.duration'), + items_count: t('composables.locale.useSharedLabels.filters.itemsCount'), + size: t('composables.locale.useSharedLabels.filters.size'), + bitrate: t('composables.locale.useSharedLabels.filters.bitrate'), + duration: t('composables.locale.useSharedLabels.filters.duration'), + date_joined: t('composables.locale.useSharedLabels.filters.dateJoined'), + last_activity: t('composables.locale.useSharedLabels.filters.lastActivity'), + username: t('composables.locale.useSharedLabels.filters.username'), + domain: t('composables.locale.useSharedLabels.filters.domain'), + users: t('composables.locale.useSharedLabels.filters.users'), + received_messages: t('composables.locale.useSharedLabels.filters.receivedMessages'), + uploads: t('composables.locale.useSharedLabels.filters.uploads'), + followers: t('composables.locale.useSharedLabels.filters.followers') }, scopes: { profile: { - label: t('Profile'), - description: t('Access to e-mail, username, and profile information') + label: t('composables.locale.useSharedLabels.scopes.profile.label'), + description: t('composables.locale.useSharedLabels.scopes.profile.description') }, libraries: { - label: t('Libraries and uploads'), - description: t('Access to audio files, libraries, artists, albums and tracks') + label: t('composables.locale.useSharedLabels.scopes.libraries.label'), + description: t('composables.locale.useSharedLabels.scopes.libraries.description') }, favorites: { - label: t('Favorites'), - description: t('Access to favorites') + label: t('composables.locale.useSharedLabels.scopes.favorites.label'), + description: t('composables.locale.useSharedLabels.scopes.favorites.description') }, listenings: { - label: t('Listenings'), - description: t('Access to listening history') + label: t('composables.locale.useSharedLabels.scopes.listenings.label'), + description: t('composables.locale.useSharedLabels.scopes.listenings.description') }, follows: { - label: t('Follows'), - description: t('Access to follows') + label: t('composables.locale.useSharedLabels.scopes.follows.label'), + description: t('composables.locale.useSharedLabels.scopes.follows.description') }, playlists: { - label: t('Playlists'), - description: t('Access to playlists') + label: t('composables.locale.useSharedLabels.scopes.playlists.label'), + description: t('composables.locale.useSharedLabels.scopes.playlists.description') }, radios: { - label: t('Radios'), - description: t('Access to radios') + label: t('composables.locale.useSharedLabels.scopes.radios.label'), + description: t('composables.locale.useSharedLabels.scopes.radios.description') }, filters: { - label: t('Content filters'), - description: t('Access to content filters') + label: t('composables.locale.useSharedLabels.scopes.filters.label'), + description: t('composables.locale.useSharedLabels.scopes.filters.description') }, notifications: { - label: t('Notifications'), - description: t('Access to notifications') + label: t('composables.locale.useSharedLabels.scopes.notifications.label'), + description: t('composables.locale.useSharedLabels.scopes.notifications.description') }, edits: { - label: t('Edits'), - description: t('Access to edits') + label: t('composables.locale.useSharedLabels.scopes.edits.label'), + description: t('composables.locale.useSharedLabels.scopes.edits.description') }, security: { - label: t('Security'), - description: t('Access to security settings such as password and authorization') + label: t('composables.locale.useSharedLabels.scopes.security.label'), + description: t('composables.locale.useSharedLabels.scopes.security.description') }, reports: { - label: t('Reports'), - description: t('Access to moderation reports') + label: t('composables.locale.useSharedLabels.scopes.reports.label'), + description: t('composables.locale.useSharedLabels.scopes.reports.description') } } as Record }) diff --git a/front/src/composables/moderation/useEditConfigs.ts b/front/src/composables/moderation/useEditConfigs.ts index 5d6190bce..07b6f362c 100644 --- a/front/src/composables/moderation/useEditConfigs.ts +++ b/front/src/composables/moderation/useEditConfigs.ts @@ -27,7 +27,7 @@ const description: ConfigField = { id: 'description', type: 'content', required: true, - label: t('Description'), + label: t('composables.moderation.useEditConfigs.description.label'), getValue: (obj) => obj.description ?? { text: '', content_type: 'text/markdown' }, getValueRepr: getContentValueRepr } @@ -36,7 +36,7 @@ const cover: ConfigField = { id: 'cover', type: 'attachment', required: false, - label: t('Cover'), + label: t('composables.moderation.useEditConfigs.cover.label'), getValue: (obj) => obj.cover?.uuid ?? null } @@ -44,7 +44,7 @@ const tags: ConfigField = { id: 'tags', type: 'tags', required: true, - label: t('Tags'), + label: t('composables.moderation.useEditConfigs.tags.label'), getValue: (obj) => { return obj.tags }, getValueRepr: (tags: string[]) => tags.slice().sort().join('\n') } @@ -57,7 +57,7 @@ export default (): Configs => ({ id: 'name', type: 'text', required: true, - label: t('Name'), + label: t('composables.moderation.useEditConfigs.artist.name'), getValue: (artist) => (artist as Artist).name }, description, @@ -71,7 +71,7 @@ export default (): Configs => ({ id: 'title', type: 'text', required: true, - label: t('Title'), + label: t('composables.moderation.useEditConfigs.album.title'), getValue: (album) => (album as Album).title }, description, @@ -79,7 +79,7 @@ export default (): Configs => ({ id: 'release_date', type: 'text', required: false, - label: t('Release date'), + label: t('composables.moderation.useEditConfigs.album.releaseDate'), getValue: (album) => (album as Album).release_date }, cover, @@ -92,7 +92,7 @@ export default (): Configs => ({ id: 'title', type: 'text', required: true, - label: t('Title'), + label: t('composables.moderation.useEditConfigs.track.title'), getValue: (track) => (track as Track).title }, description, @@ -102,21 +102,21 @@ export default (): Configs => ({ type: 'text', inputType: 'number', required: false, - label: t('Position'), + label: t('composables.moderation.useEditConfigs.track.position'), getValue: (track) => (track as Track).position }, { id: 'copyright', type: 'text', required: false, - label: t('Copyright'), + label: t('composables.moderation.useEditConfigs.track.copyright'), getValue: (track) => (track as Track).copyright }, { id: 'license', type: 'license', required: false, - label: t('License'), + label: t('composables.moderation.useEditConfigs.track.license'), getValue: (track) => (track as Track).license }, tags diff --git a/front/src/composables/moderation/useReport.ts b/front/src/composables/moderation/useReport.ts index 432405cfb..edac6ad07 100644 --- a/front/src/composables/moderation/useReport.ts +++ b/front/src/composables/moderation/useReport.ts @@ -35,26 +35,26 @@ const getReportableObjects = ({ track, album, artist, playlist, account, library if (account) { reportableObjs.push({ - label: t('Report @%{ username }…', { username: account.preferred_username }), + label: t('composables.moderation.useReport.account.label', { username: account.preferred_username }), target: { type: 'account', _obj: account, full_username: account.full_username, label: account.full_username, - typeLabel: t('Account') + typeLabel: t('composables.moderation.useReport.account.typeLabel') } }) } if (track) { reportableObjs.push({ - label: t('Report this track…'), + label: t('composables.moderation.useReport.track.label'), target: { type: 'track', id: track.id, _obj: track, label: track.title, - typeLabel: t('Track') + typeLabel: t('composables.moderation.useReport.track.typeLabel') } }) @@ -64,13 +64,13 @@ const getReportableObjects = ({ track, album, artist, playlist, account, library if (album) { reportableObjs.push({ - label: t('Report this album…'), + label: t('composables.moderation.useReport.album.label'), target: { type: 'album', id: album.id, label: album.title, _obj: album, - typeLabel: t('Album') + typeLabel: t('composables.moderation.useReport.album.typeLabel') } }) @@ -81,50 +81,50 @@ const getReportableObjects = ({ track, album, artist, playlist, account, library if (channel) { reportableObjs.push({ - label: t('Report this channel…'), + label: t('composables.moderation.useReport.channel.label'), target: { type: 'channel', uuid: channel.uuid, - label: channel.artist?.name ?? t('Unknown artist'), + label: channel.artist?.name ?? t('composables.moderation.useReport.artist.unknownLabel'), _obj: channel, - typeLabel: t('Channel') + typeLabel: t('composables.moderation.useReport.channel.typeLabel') } }) } else if (artist) { reportableObjs.push({ - label: t('Report this artist…'), + label: t('composables.moderation.useReport.artist.label'), target: { type: 'artist', id: artist.id, label: artist.name, _obj: artist, - typeLabel: t('Artist') + typeLabel: t('composables.moderation.useReport.artist.typeLabel') } }) } if (playlist) { reportableObjs.push({ - label: t('Report this playlist…'), + label: t('composables.moderation.useReport.playlist.label'), target: { type: 'playlist', id: playlist.id, label: playlist.name, _obj: playlist, - typeLabel: t('Playlist') + typeLabel: t('composables.moderation.useReport.playlist.typeLabel') } }) } if (library) { reportableObjs.push({ - label: t('Report this library…'), + label: t('composables.moderation.useReport.library.label'), target: { type: 'library', uuid: library.uuid, label: library.name, _obj: library, - typeLabel: t('Library') + typeLabel: t('composables.moderation.useReport.library.typeLabel') } }) } diff --git a/front/src/composables/moderation/useReportConfigs.ts b/front/src/composables/moderation/useReportConfigs.ts index 15b2b0067..25f38203a 100644 --- a/front/src/composables/moderation/useReportConfigs.ts +++ b/front/src/composables/moderation/useReportConfigs.ts @@ -26,33 +26,33 @@ const { t } = useI18n() const tags: ModeratedField = { id: 'tags', - label: t('Tags'), + label: t('composables.moderation.useReportConfigs.tags.label'), getValueRepr: (tags: string[]) => tags.slice().sort().join('\n') } const name: ModeratedField = { id: 'name', - label: t('Name') + label: t('composables.moderation.useReportConfigs.name.label') } const creationDate: ModeratedField = { id: 'creation_date', - label: t('Creation date') + label: t('composables.moderation.useReportConfigs.creationDate.label') } const musicBrainzId: ModeratedField = { id: 'mbid', - label: t('MusicBrainz ID') + label: t('composables.moderation.useReportConfigs.musicbrainzId.label') } const visibility: ModeratedField = { id: 'privacy_level', - label: t('Visibility') + label: t('composables.moderation.useReportConfigs.visibility.label') } export default (): Configs => ({ artist: { - label: t('Artist'), + label: t('composables.moderation.useReportConfigs.artist.label'), icon: 'users', getDeleteUrl: (obj) => { return `manage/library/artists/${obj.id}/` @@ -69,7 +69,7 @@ export default (): Configs => ({ ] }, album: { - label: t('Album'), + label: t('composables.moderation.useReportConfigs.album.label'), icon: 'play', getDeleteUrl: (obj) => { return `manage/library/albums/${obj.id}/` @@ -81,19 +81,19 @@ export default (): Configs => ({ moderatedFields: [ { id: 'title', - label: t('Title') + label: t('composables.moderation.useReportConfigs.album.title') }, creationDate, { id: 'release_date', - label: t('Release date') + label: t('composables.moderation.useReportConfigs.album.releaseDate') }, tags, musicBrainzId ] }, track: { - label: t('Track'), + label: t('composables.moderation.useReportConfigs.track.label'), icon: 'music', getDeleteUrl: (obj) => { return `manage/library/tracks/${obj.id}/` @@ -105,26 +105,26 @@ export default (): Configs => ({ moderatedFields: [ { id: 'title', - label: t('Title') + label: t('composables.moderation.useReportConfigs.track.title') }, { id: 'position', - label: t('Position') + label: t('composables.moderation.useReportConfigs.track.position') }, { id: 'copyright', - label: t('Copyright') + label: t('composables.moderation.useReportConfigs.track.copyright') }, { id: 'license', - label: t('License') + label: t('composables.moderation.useReportConfigs.track.license') }, tags, musicBrainzId ] }, library: { - label: t('Library'), + label: t('composables.moderation.useReportConfigs.library.label'), icon: 'book', getDeleteUrl: (obj) => { return `manage/library/libraries/${obj.uuid}/` @@ -136,13 +136,13 @@ export default (): Configs => ({ name, { id: 'description', - label: t('Description') + label: t('composables.moderation.useReportConfigs.library.description') }, visibility ] }, playlist: { - label: t('Playlist'), + label: t('composables.moderation.useReportConfigs.playlist.label'), icon: 'list', urls: { getDetail: (obj) => ({ name: 'library.playlists.detail', params: { id: obj.id } }) @@ -154,7 +154,7 @@ export default (): Configs => ({ ] }, account: { - label: t('Account'), + label: t('composables.moderation.useReportConfigs.account.label'), icon: 'user', urls: { getDetail: (obj) => ({ name: 'profile.full.overview', params: { username: obj.preferred_username, domain: obj.domain } }), @@ -164,12 +164,12 @@ export default (): Configs => ({ name, { id: 'summary', - label: t('Bio') + label: t('composables.moderation.useReportConfigs.account.summary') } ] }, channel: { - label: t('Channel'), + label: t('composables.moderation.useReportConfigs.channel.label'), icon: 'stream', urls: { getDetail: (obj) => ({ name: 'channels.detail', params: { id: obj.uuid } }), diff --git a/front/src/composables/useErrorHandler.ts b/front/src/composables/useErrorHandler.ts index 05331bbee..ad8ec2307 100644 --- a/front/src/composables/useErrorHandler.ts +++ b/front/src/composables/useErrorHandler.ts @@ -16,7 +16,7 @@ async function useErrorHandler (error: Error | BackendError, eventId?: string): ? 'Unexpected API error' : 'Unexpected error' - let content = t('An unexpected error occured.') + let content = t('composables.useErrorHandler.unexpectedError') if ('backendErrors' in error) { logger.error(title, error, error.backendErrors) @@ -35,7 +35,7 @@ async function useErrorHandler (error: Error | BackendError, eventId?: string): const { get } = useCookies() if (get(COOKIE) === 'yes') { - content = t('An unexpected error occurred.
    To help us understand why it happened, please attach a detailed description of what you did that has triggered the error.') + content = t('composables.useErrorHandler.errorReport') const user = store.state.auth.authenticated ? { name: store.state.auth.username, @@ -44,7 +44,7 @@ async function useErrorHandler (error: Error | BackendError, eventId?: string): : undefined actions.push({ - text: t('Leave feedback'), + text: t('composables.useErrorHandler.leaveFeedback'), class: 'basic red', click: () => Sentry.showReportDialog({ eventId: eventId ?? Sentry.captureException(error), diff --git a/front/src/composables/useThemeList.ts b/front/src/composables/useThemeList.ts index d940f25a3..1dae1682e 100644 --- a/front/src/composables/useThemeList.ts +++ b/front/src/composables/useThemeList.ts @@ -7,17 +7,17 @@ const { t } = i18n.global const themeList: ThemeEntry[] = [ { icon: 'palette icon', - name: t('Browser default'), + name: t('composables.useThemeList.browserDefault'), key: 'auto' }, { icon: 'sun icon', - name: t('Light'), + name: t('composables.useThemeList.lightTheme'), key: 'light' }, { icon: 'moon icon', - name: t('Dark'), + name: t('composables.useThemeList.darkTheme'), key: 'dark' } ] diff --git a/front/src/init/axios.ts b/front/src/init/axios.ts index 55fcc597f..88a90621d 100644 --- a/front/src/init/axios.ts +++ b/front/src/init/axios.ts @@ -75,9 +75,9 @@ export const install: InitModule = ({ store, router }) => { if (rateLimitStatus.availableSeconds) { const tryAgain = moment().add(rateLimitStatus.availableSeconds, 's').toNow(true) - message = t('You sent too many requests and have been rate limited, please try again in %{ delay }', { delay: tryAgain }) + message = t('init.axios.rateLimitDelay', { delay: tryAgain }) } else { - message = t('You sent too many requests and have been rate limited, please try again later') + message = t('init.axios.rateLimitLater') } error.backendErrors.push(message) diff --git a/front/src/init/sentry.ts b/front/src/init/sentry.ts index 4d2d2db29..b1f6f58a1 100644 --- a/front/src/init/sentry.ts +++ b/front/src/init/sentry.ts @@ -90,11 +90,11 @@ export const install: InitModule = async ({ app, router, store }) => { return store.commit('ui/addMessage', { content: hostname === 'am.funkwhale.audio' ? t( - 'To enhance the quality of our services, we would like to collect information about crashes during your session.
    The stack traces will be shared to
    Funkwhale\'s official Glitchtip instance in order to help us understand how and when the errors occur.', - { hostname, origin } + 'init.sentry.funkwhaleGlitchtipMessage', + { origin } ) : t( - 'To enhance the quality of our services, we would like to collect information about crashes during your session.
    The stack traces will be shared to %{hostname} in order to help us understand how and when the errors occur.', + 'init.sentry.ownGlitchtipMessage', { hostname, origin } ), date: new Date(), @@ -103,7 +103,7 @@ export const install: InitModule = async ({ app, router, store }) => { classActions: 'bottom attached opaque', actions: [ { - text: t('Allow'), + text: t('init.sentry.allow'), class: 'primary', click: () => { set(COOKIE, 'yes') @@ -111,7 +111,7 @@ export const install: InitModule = async ({ app, router, store }) => { } }, { - text: t('Deny'), + text: t('init.sentry.deny'), class: 'basic', click: () => set(COOKIE, 'no') } diff --git a/front/src/init/serviceWorker.ts b/front/src/init/serviceWorker.ts index 78adace67..264b76e5d 100644 --- a/front/src/init/serviceWorker.ts +++ b/front/src/init/serviceWorker.ts @@ -21,19 +21,19 @@ export const install: InitModule = ({ store }) => { }, onNeedRefresh () { store.commit('ui/addMessage', { - content: t('A new version of the app is available.'), + content: t('init.serviceWorker.newAppVersion'), date: new Date(), key: 'refreshApp', displayTime: 0, classActions: 'bottom attached opaque', actions: [ { - text: t('Update'), + text: t('init.serviceWorker.actions.update'), class: 'primary', click: () => updateSW() }, { - text: t('Later'), + text: t('init.serviceWorker.actions.later'), class: 'basic' } ] diff --git a/front/src/locales/en.json b/front/src/locales/en.json index 0410ad5a2..342269f00 100644 --- a/front/src/locales/en.json +++ b/front/src/locales/en.json @@ -1,4 +1,7 @@ { + "App": { + "loading": "Loading..." + }, "components": { "About": { "title": "About", @@ -503,7 +506,8 @@ "avatarSaveFailureHeader": "Your avatar cannot be saved", "avatarInputLabel": "Avatar", "changePasswordHeader": "Change my password", - "changePasswordMessage": "Changing your password will also change your Subsonic API password if you have requested one \n You will have to update your password on your clients that use this password.", + "changePasswordMessage": "Changing your password will also change your Subsonic API password if you have requested one.", + "changePasswordMessageContinued": "You will have to update your password on your clients that use this password.", "changePasswordFailureMessage": "Your password cannot be changed", "changePasswordHelp": "Please double-check your password is correct", "currentPasswordLabel": "Current password", @@ -584,7 +588,8 @@ "disabledMessage": "Access disabled", "subsonicHeader": "Subsonic API password", "unavailableMessage": "The Subsonic API is not available on this Funkwhale instance.", - "subsonicApiDescription": "Funkwhale is compatible with other music players that support the Subsonic API.\n You can use those to enjoy your playlist and music in offline mode, on your smartphone or tablet, for instance.", + "subsonicApiDescription": "Funkwhale is compatible with other music players that support the Subsonic API.", + "subsonicApiDescriptionContinued": "You can use those to enjoy your playlist and music in offline mode, on your smartphone or tablet, for instance.", "subsonicPasswordInfo": "However, accessing Funkwhale from those clients requires a separate password you can set below.", "appsLink": "Discover how to use Funkwhale from other apps", "errorHeader": "Error", @@ -982,7 +987,7 @@ "localUploadHeader": "Upload music from '~/your local storage", "localUploadMessage": "You are about to upload music to your library. Before proceeding, please ensure that:", "localUploadCopyright": "You are not uploading copyrighted content in a public library, otherwise you may be infringing the law", - "localUploadTag": "The music files you are uploading are tagged properly. ", + "localUploadTag": "The music files you are uploading are tagged properly.", "localUploadPicardLink": "We recommend using Picard for that purpose.", "localUploadSupportedFormats": "The music files you are uploading are in OGG, Flac, MP3 or AIFF format", "uploadWidgetLabel": "Click to select files to upload or drag and drop files or directories", @@ -1659,6 +1664,273 @@ } } }, + "composables": { + "useErrorHandler": { + "unexpectedError": "An unexpected error occurred.", + "errorReport": "An unexpected error occured.
    To help us understand why it happened, please attach a detailed description of what you did that has triggered the error.", + "leaveFeedback": "Leave feedback" + }, + "useThemeList": { + "browserDefault": "Browser default", + "lightTheme": "Light", + "darkTheme": "Dark" + }, + "audio": { + "usePlayOptions": { + "addToQueueMessage": "{count} tracks were added to your queue | {count} track was added to your queue | {count} tracks were added to your queue" + }, + "useQueue": { + "queueShuffled": "Queue shuffled!" + } + }, + "locale": { + "useSharedLabels": { + "fields": { + "privacyLevel": { + "label": "Activity visibility", + "help": "Determine the visiblity level of your activity", + "choices": { + "private": "Nobody except me", + "instance": "Everyone on this instance", + "public": "Everyone, across all instances" + }, + "shortChoices": { + "private": "Private", + "instance": "Instance", + "public": "Everyone" + } + }, + "importStatus": { + "label": "Click to display more information about the import process for this upload", + "choices": { + "skipped": { + "label": "Skipped", + "help": "This track is already present in one of your libraries" + }, + "draft": { + "label": "Draft", + "help": "This track has been uploaded, but hasn't been scheduled for processing yet" + }, + "pending": { + "label": "Pending", + "help": "This track has been uploaded, but hasn't been processed by the server yet" + }, + "errored": { + "label": "Errored", + "help": "This track could not be processed, please make sure it is tagged correctly" + }, + "finished": { + "label": "Finished", + "help": "Imported" + } + } + }, + "reportType": { + "label": "Category", + "choices": { + "takedownRequest": "Takedown request", + "invalidMetadata": "Invalid metadata", + "illegalContent": "Illegal content", + "offensiveContent": "Offensive content", + "other": "Other" + } + }, + "summary": { + "label": "Bio" + }, + "contentCategory": { + "label": "Content category", + "choices": { + "podcast": "Podcast", + "music": "Music", + "other": "Other" + } + } + }, + "filters": { + "creationDate": "Creation date", + "releaseDate": "Release date", + "accessedDate": "'Accessed date", + "appliedDate": "'Applied date", + "handledDate": "'Handled date", + "firstSeen": "'First seen date", + "lastSeen": "'Last seen date", + "modificationDate": "'Modification date", + "expirationDate": "'Expiration date", + "trackTitle": "'Track name", + "albumTitle": "'Album name", + "artistName": "'Artist name", + "name": "'Name", + "length": "'Duration", + "itemsCount": "'Items", + "size": "'Size", + "bitrate": "'Bitrate", + "duration": "'Duration", + "dateJoined": "'Sign-up date", + "lastActivity": "'Last activity", + "username": "'Username", + "domain": "'Domaimn", + "users": "'Users", + "receivedMessages": "'Received messages", + "uploads": "'Uploads", + "followers": "'Followers" + }, + "scopes": { + "profile": { + "label": "Profile", + "description": "Access to e-mail, username, and profile information" + }, + "libraries": { + "label": "Libraries and uploads", + "description": "Access to audio files, libraries, artists, albums and tracks" + }, + "favorites": { + "label": "Favorites", + "description": "Access to favorites" + }, + "listenings": { + "label": "Listenings", + "description": "Access to listening history" + }, + "follows": { + "label": "Follows", + "description": "Access to follows" + }, + "playlists": { + "label": "Playlists", + "description": "Access to playlists" + }, + "radios": { + "label": "Radios", + "description": "Access to radios" + }, + "filters": { + "label": "Content filters", + "description": "Access to content filters" + }, + "notifications": { + "label": "Notifications", + "description": "Access to notifications" + }, + "edits": { + "label": "Edits", + "description": "Access to edits" + }, + "security": { + "label": "Security", + "description": "Access to security settings such as password and authorization" + }, + "reports": { + "label": "Reports", + "description": "Access to moderation reports" + } + } + } + }, + "moderation": { + "useEditConfigs": { + "description": { + "label": "Description" + }, + "cover": { + "label": "Cover" + }, + "tags": { + "label": "Tags" + }, + "artist": { + "name": "Name" + }, + "album": { + "title": "Title", + "releaseDate": "Release date" + }, + "track": { + "title": "Title", + "position": "Position", + "copyright": "Copyright", + "license": "Licence" + } + }, + "useReport": { + "account": { + "label": "Report {'@'}{username}", + "typeLabel": "Account" + }, + "track": { + "label": "Report this track…", + "typeLabel": "Track" + }, + "album": { + "label": "Report this album…", + "typeLabel": "Album" + }, + "channel": { + "label": "Report this channel…", + "typeLabel": "Channel" + }, + "artist": { + "label": "Report this artist…", + "typeLabel": "Artist", + "unknownLabel": "Unknown artist" + }, + "playlist": { + "label": "Report this playlist…", + "typeLabel": "Playlist" + }, + "library": { + "label": "Report this library…", + "typeLabel": "Library" + } + }, + "useReportConfigs": { + "tags": { + "label": "Tags" + }, + "name": { + "label": "Name" + }, + "creationDate": { + "label": "Creation date" + }, + "musicbrainzId": { + "label": "MusicBrainz ID" + }, + "visibility": { + "label": "Visibility" + }, + "artist": { + "label": "Artist" + }, + "album": { + "label": "Album", + "title": "Title", + "releaseDate": "Release date" + }, + "track": { + "label": "Track", + "title": "Title", + "position": "Position", + "copyright": "Copyright", + "license": "Licence" + }, + "library": { + "label": "Library", + "description": "Description" + }, + "playlist": { + "label": "Playlist" + }, + "account": { + "label": "Account", + "summary": "Bio" + }, + "channel": { + "label": "Channel" + } + } + } + }, "embed": { "EmbedFrame": { "badResource": "idget improperly configured (bad resource type {type}).", @@ -1670,6 +1942,25 @@ "unknownTrackError": "An unknown error occurred while loading track data." } }, + "init": { + "axios": { + "rateLimitDelay": "You sent too many requests and have been rate limited, please try again in {delay}", + "rateLimitLater": "You sent too many requests and have been rate limited, please try again later" + }, + "sentry": { + "funkwhaleGlitchtipMessage": "To enhance the quality of our services, we would like to collect information about crashes during your session.
    The stack traces will be shared to Funkwhale's official Glitchtip instance in order to help us understand how and when the errors occur.", + "ownGlitchtipMessage": "To enhance the quality of our services, we would like to collect information about crashes during your session.
    The stack traces will be shared to {hostname} in order to help us understand how and when the errors occur.", + "allow": "Allow", + "deny": "Deny" + }, + "serviceWorker": { + "newAppVersion": "A new version of the app is available.", + "actions": { + "update": "Update", + "later": "Later" + } + } + }, "views": { "Notifications": { "title": "Notifications", @@ -1731,14 +2022,14 @@ "descriptionLabel": "Description", "urlLabel": "URL", "rssLabel": "RSS feed", - "activityHeader": "Activity ", + "activityHeader": "Activity", "firstSeenLabel": "First seen", "listeningsLabel": "Listenings", "favoritedLabel": "Favorited tracks", "playlistsLabel": "Playlists", "linkedReportsLabel": "Linked reports", "editsLabel": "Edits", - "audioContentHeader": "Audio content ", + "audioContentHeader": "Audio content;", "cachedSizeLabel": "Cached size", "totalSizeLabel": "Total size", "uploadsLabel": "Uploads", @@ -1790,14 +2081,14 @@ "artistLabel": "Artist", "domainLabel": "Domain", "descriptionLabel": "Description", - "activityHeader": "Activity ", + "activityHeader": "Activity;", "firstSeenLabel": "First seen", "listeningsLabel": "Listenings", "favoritedLabel": "Favorited tracks", "playlistsLabel": "Playlists", "linkedReportsLabel": "Linked reports", "editsLabel": "Edits", - "audioContentHeader": "Audio content ", + "audioContentHeader": "Audio content", "cachedSizeLabel": "Cached size", "totalSizeLabel": "Total size", "librariesLabel": "Libraries", @@ -1821,14 +2112,14 @@ "categoryLabel": "Category", "domainLabel": "Domain", "descriptionLabel": "Description", - "activityHeader": "Activity ", + "activityHeader": "Activity", "firstSeenLabel": "First seen", "listeningsLabel": "Listenings", "favoritedLabel": "Favorited tracks", "playlistsLabel": "Playlists", "linkedReportsLabel": "Linked reports", "editsLabel": "Edits", - "audioContentHeader": "Audio content ", + "audioContentHeader": "Audio content", "cachedSizeLabel": "Cached size", "totalSizeLabel": "Total size", "librariesLabel": "Libraries", @@ -1866,11 +2157,11 @@ "accountLabel": "Account", "domainLabel": "Domain", "descriptionLabel": "Description", - "activityHeader": "Activity ", + "activityHeader": "Activity", "firstSeenLabel": "First seen", "followersLabel": "Followers", "linkedReportsLabel": "Linked reports", - "audioContentHeader": "Audio content ", + "audioContentHeader": "Audio content", "cachedSizeLabel": "Cached size", "totalSizeLabel": "Total size", "artistsLabel": "Artists", @@ -1886,9 +2177,9 @@ "deleteModalMessage": "The tag will be removed and unlinked from any existing entity. This action is irreversible.", "tagDataHeader": "Tag data", "nameLabel": "Name", - "activityHeader": "Activity ", + "activityHeader": "Activity", "firstSeenLabel": "First seen", - "audioContentHeader": "Audio content ", + "audioContentHeader": "Audio content", "artistsLabel": "Artists", "albumsLabel": "Albums", "tracksLabel": "Tracks" @@ -1916,14 +2207,13 @@ "licenseLabel": "License", "domainLabel": "Domain", "descriptionLabel": "Description", - "activityHeader": "Activity ", + "activityHeader": "Activity", "firstSeenLabel": "First seen", "listeningsLabel": "Listenings", "favoritedLabel": "Favorited tracks", "playlistsLabel": "Playlists", "linkedReportsLabel": "Linked reports", "editsLabel": "Edits", - "audioContentHeader": "Audio content ", "cachedSizeLabel": "Cached size", "totalSizeLabel": "Total size", "librariesLabel": "Libraries", @@ -1944,11 +2234,11 @@ "domainLabel": "Domain", "importStatusLabel": "Import status", "libraryLabel": "Library", - "activityHeader": "Activity ", + "activityHeader": "Activity", "firstSeenLabel": "First seen", "accessedDateLabel": "Accessed date", "notApplicable": "N/A", - "audioContentHeader": "Audio content ", + "audioContentHeader": "Audio content", "trackLabel": "Track", "cachedSizeLabel": "Cached size", "sizeLabel": "Size", @@ -1957,6 +2247,504 @@ "durationLabel": "Duration", "typeLabel": "Type" } + }, + "moderation": { + "AccountsDetail": { + "statsWarning": "Statistics are computed from known activity and content on your instance, and do not reflect general activity for this object", + "uploadQuota": "Determine how much content the user can upload. Leave empty to use the default value of the instance.", + "libraryPermission": "Library", + "moderationPermission": "Moderation", + "settingsPermission": "Settings", + "localAccountLabel": "Local account", + "openProfileLink": "Open profile", + "djangoLink": "View in Django's admin", + "remoteProfileLink": "Open remote profile", + "noPolicyHeader": "You don't have any rule in place for this account.", + "policyDescription": "Moderation policies help you control how your instance interact with a given domain or account", + "addPolicyButton": "Add a moderation policy", + "activePolicyHeader": "This domain is subject to specific moderation rules", + "accountDataHeader": "Account data", + "usernameLabel": "Username", + "domainLabel": "Domain", + "displayNameLabel": "Display name", + "emailLabel": "Email address", + "loginStatusLabel": "Login status", + "enabledStatus": "Enabled", + "disabledStatus": "Disabled", + "permissionsLabel": "Permissions", + "userTypeLabel": "Type", + "lastCheckedLabel": "Last checked", + "notApplicable": "N/A", + "signupDateLabel": "Sign-up date", + "lastActivityLabel": "Last activity", + "activityHeader": "Activty", + "firstSeenLabel": "First seen", + "emittedMessagesLabel": "Emitted messages", + "receivedFollowsLabel": "Received library follows", + "emittedFollowsLabel": "Emitted library follows", + "linkedReportsLabel": "Linked reports", + "requestsLabel": "Requests", + "audioContentHeader": "Audio content", + "cachedSizeLabel": "Cached size", + "uploadQuotaLabel": "Upload quota", + "megabyteLabel": "MB", + "totalSizeLabel": "Total size", + "channelsLabel": "Channels", + "librariesLabel": "Libraries", + "uploadsLabel": "Uploads", + "artistsLabel": "Artists", + "albumsLabel": "Albums", + "tracksLabel": "Tracks" + }, + "Base": { + "moderation": "Moderation", + "secondaryMenu": "Secondary menu", + "reportsLink": "Reports", + "userRequestsLink": "User Requests", + "domainsLink": "Domains", + "accountsLink": "Accounts" + }, + "DomainsDetail": { + "statsWarning": "Statistics are computed from known activity and content on your instance, and do not reflect general activity for this object", + "websiteLink": "Open website", + "djangoLink": "View in Django's admin", + "removeFromAllowList": "Remove from allow-list", + "addToAllowList": "Add to allow-list", + "noPolicyHeader": "You don't have any rule in place for this domain.", + "policyDescription": "Moderation policies help you control how your instance interact with a given domain or account", + "addPolicyButton": "Add a moderation policy", + "activePolicyHeader": "This domain is subject to specific moderation rules", + "instanceDataHeader": "Instance data", + "inAllowListLabel": "Is present on allow-list", + "inAllowListTrue": "Yes", + "inAllowListFalse": "No", + "lastCheckedLabel": "Last checked", + "notApplicable": "N/A", + "softwareLabel": "Software", + "softwareValue": "{name} ({version})", + "domainNameLabel": "Name", + "totalUsersLabel": "Total users", + "nodeInfoStatusLabel": "Status", + "nodeInfoFailureMessage": "Error while fetching node info", + "refreshNodeInfoButton": "Refresh node info", + "activityHeader": "Activty", + "firstSeenLabel": "First seen", + "knownAccountsLink": "Known accounts", + "emittedMessagesLabel": "Emitted messages", + "receivedFollowsLabel": "Received library follows", + "emittedFollowsLabel": "Emitted library follows", + "audioContentHeader": "Audio content", + "cachedSizeLabel": "Cached size", + "totalSizeLabel": "Total size", + "channelsLabel": "Channels", + "librariesLabel": "Libraries", + "uploadsLabel": "Uploads", + "artistsLabel": "Artists", + "albumsLabel": "Albums", + "tracksLabel": "Tracks" + }, + "DomainsList": { + "title": "Domains", + "failureHeader": "Error while creating domain", + "addDomainLabel": "Add a domain", + "addToAllowListLabel": "Add to allow-list", + "addButton": "Add" + }, + "ReportsList": { + "title": "Reports", + "searchPlaceholder": "Search by account, summary, domain…", + "searchLabel": "Search", + "statusLabel": "Status", + "allOption": "All", + "resolvedStatus": "Resolved", + "unresolvedStatus": "Unresolved", + "orderingLabel": "Ordering", + "orderingDirectionLabel": "Order", + "ascendingOrdering": "Ascending", + "descendingOrdering": "Descending" + }, + "RequestsList": { + "title": "User Requests", + "searchPlaceholder": "Search by username", + "searchLabel": "Search", + "statusLabel": "Status", + "allOption": "All", + "pendingStatus": "Pending", + "approvedStatus": "Approved", + "refusedStatus": "Refused", + "orderingLabel": "Ordering", + "orderingDirectionLabel": "Order", + "ascendingOrdering": "Ascending", + "descendingOrdering": "Descending" + } + }, + "users": { + "Base": { + "title": "Manage users", + "secondaryMenu": "Secondary menu", + "usersLink": "Users", + "invitationsLink": "Invitations" + } + } + }, + "auth": { + "Callback": { + "loggingInHeader": "Logging in…" + }, + "EmailConfirm": { + "confirm": "Confirm your e-mail address", + "confirmFailureHeader": "Could not confirm your e-mail address", + "confirmationCodeLabel": "Confirmation code", + "backToLoginLink": "Return to login", + "confirmSuccessHeader": "E-mail address confirmed", + "confirmSuccessMessage": "You can now use the service without limitations", + "goToLoginLink": "Proceed to login" + }, + "Login": { + "title": "Log in", + "loginHeader": "Log in to your Funkwhale account" + }, + "PasswordReset": { + "placeholder": "Enter the e-mail address linked to your account", + "title": "Reset your password", + "resetFailureHeader": "Error while asking for a password reset", + "resetFormDescription": "Use this form to request a password reset. We will send an e-mail to the given address with instructions to reset your password.", + "emailLabel": "Account's e-mail address", + "backToLoginLink": "Back to login", + "requestResetButton": "Ask for a password reset" + }, + "PasswordResetConfirm": { + "title": "Change your password", + "changeFailureHeader": "Error while changing your password", + "newPasswordLabel": "New password", + "backToLoginLink": "Back to login", + "updatePasswordButton": "Update your password", + "requestSentMessage": "If the e-mail address provided in the previous step is valid and linked to a user account, you should receive an e-mail with reset instructions in the next couple of minutes.", + "changeSuccessHeader": "Password updated successfully", + "changeSuccessMessage": "Your password has been updated successfully.", + "goToLoginLink": "Proceed to login" + }, + "Plugins": { + "title": "Manage plugins" + }, + "ProfileActivity": { + "recentlyListened": "Recently listened", + "recentlyFavorited": "Recently favorited", + "playlistsHeader": "Playlists" + }, + "ProfileBase": { + "title": "{username}'s profile", + "domainViewLink": "View on {domain}", + "moderationLink": "Open in moderation interface", + "ownUserLabel": "This is you!", + "overviewLink": "Overview", + "activityLink": "Activity" + }, + "ProfileOverview": { + "channelsHeader": "Channels", + "addNewLink": "Add New", + "librariesHeader": "User Libraries", + "sharedLibraries": "This user shared the following libraries", + "createChannelModalHeader": "Create channel", + "podcastChannelHeader": "Podcast channel", + "artistChannelHeader": "Artist channel", + "cancelButton": "Cancel", + "previousButton": "Previous step", + "nextButton": "Next step", + "createChannelButton": "Create channel" + }, + "Signup": { + "title": "Sign up", + "createAccountHeader": "Create a Funkwhale account" + } + }, + "channels": { + "DetailBase": { + "title": "Channel", + "episodeCount": "No episodes | {count} episode | {count} episodes", + "trackCount": "No tracks | {count} track | {count} tracks", + "subscriberCount": "No subscribers | {count} subscriber | {count} subscribers", + "listeningsCount": "No listenings | {count} listening | {count} listenings", + "subscribeModalHeader": "Subscribe to this channel", + "subscribeOnFunkwhale": "Subscribe on Funkwhale", + "subscribeRss": "Subscribe via RSS", + "copyUrl": "Copy paste the following URL in your favorite podcatcher:", + "subscribeOnFediverse": "Subscribe on the Fediverse", + "subscribeOnFediverseDescription": "If you're using Mastodon or other fediverse applications, you can subscribe to this account:", + "cancelButton": "Cancel", + "embedButton": "Embed", + "domainViewLink": "View on {domain}", + "editButton": "Edit…", + "deleteButton": "Delete…", + "deleteModalHeader": "Delete this Channel?", + "deleteModalMessage": "The channel will be deleted, as well as any related files and data. This action is irreversible.", + "deleteModalConfirm": "Delete", + "moderationLink": "Open in moderation interface", + "mirroredLink": "Mirrored from {domain}", + "uploadButton": "Upload", + "playButton": "Play", + "embedModalHeader": "Embed this artist work on your website", + "podcastChannelHeader": "Podcast channel", + "artistChannelHeader": "Artist channel", + "updateChannelButton": "Update channel", + "channelOverview": "Overview", + "channelEpisodes": "All episodes", + "channelTracks": "Tracks" + }, + "DetailOverview": { + "uploadsSuccessHeader": "Uploads published successfully", + "uploadsProgress": "Processed uploads: {finished}/{total}", + "uploadsFailureHeader": "Some uploads couldn't be published", + "skippedUploadsLink": "View skipped uploads", + "erroredUploadsLink": "View errored uploads", + "uploadsProcessingHeader": "Uploads are being processed", + "uploadsProcessingMessage": "Your uploads are being processed by Funkwhale and will be live very soon.", + "latestEpisodes": "Latest episodes", + "latestTracks": "Latest tracks", + "seriesHeader": "Series", + "albumsHeader": "Albums", + "addAlbumLink": "Add new" + }, + "SubscriptionsList": { + "title": "Subscribed Channels", + "searchPlaceholder": "Filter by name…", + "addNewLink": "Add new", + "subscriptionModalHeader": "Subscription", + "cancelButton": "Cancel", + "subscribeButton": "Subscribe" + } + }, + "content": { + "Base": { + "title": "Add content", + "secondaryMenu": "Secondary menu", + "librariesLink": "Libraries", + "tracksLink": "Tracks" + }, + "Home": { + "title": "Add and manage content", + "uploadQuota": "This instance offers up to {quota} of storage space for every user.", + "channelHeader": "Publish your work in a channel", + "channelDescription": "If you are a musician or a podcaster, channels are designed for you!", + "channelDescriptionContinued": "Share your work publicly and get subscribers on Funkwhale, the Fediverse or any podcasting application.", + "getStartedButton": "Get started", + "libraryUploadHeader": "Upload third-party content in a library", + "libraryUploadDescription": "Upload your personal music library to Funkwhale to enjoy it from anywhere and share it with friends and family.", + "followLibrariesHeader": "Follow remote libraries", + "followLibrariesDescription": "Follow libraries from other users to get access to new music. Public libraries can be followed immediately, while following a private library requires approval from its owner." + }, + "libraries": { + "Card": { + "sizeLabel": "Total size of the files in this library", + "trackCount":"No tracks | {count} track | {count} tracks", + "uploadButton": "Upload", + "detailsLink": "Library Details" + }, + "FilesTable": { + "deleteLabel": "Delete", + "restartImportLabel": "Restart import", + "searchPlaceholder": "Search by domain, title, artist, album…", + "showStatus": "Show information about the upload status for this track", + "searchLabel": "Search", + "importStatusLabel": "Import status", + "allOption": "All", + "draftStatus": "Draft", + "pendingStatus": "Pending", + "skippedStatus": "Skipped", + "failedStatus": "Failed", + "finishedStatus": "Finished", + "orderingLabel": "Ordering", + "orderingDirectionLabel": "Ordering direction", + "ascendingOrdering": "Ascending", + "descendingOrdering": "Descending", + "emptyState": "No tracks have been added to this libray yet", + "titleTableHeader": "Title", + "artistTableHeader": "Artist", + "albumTableHeader": "Album", + "uploadDateTableHeader": "Upload date", + "importStatusTableHeader": "Import status", + "durationTableHeader": "Duration", + "sizeTableHeader": "Size", + "notApplicable": "N/A", + "resultsDisplay":"Showing results {start}-{end} on {total}" + }, + "Form": { + "descriptionPlaceholder": "This library contains my personal music, I hope you like it.", + "namePlaceholder": "My awesome library", + "libraryUpdateMessage": "Library updated", + "libraryCreateMessage": "Library created", + "libraryDeleteMessage": "LIbrary deleted", + "libraryHelp": "Libraries help you organize and share your music collections. You can upload your own music collection to Funkwhale and share it with your friends and family.", + "failureHeader": "Error", + "nameLabel": "Name", + "descriptionLabel" :"Description", + "visibilityLabel": "Visibility", + "visibilityDescription": "You are able to share your library with other people, regardless of its visibilty.", + "updateButton": "Update library", + "createButton": "Create library", + "deleteButton": "Delete", + "deleteModalHeader": "Delete this library?", + "deleteModalMessage": "The library and all its tracks will be deleted. This can not be undone.", + "deleteModalConfirm": "Delete library" + }, + "Home": { + "loadingLibraries": "Loading libraries…", + "ownLibrariesHeader": "My libraries", + "emptyState": "Looks like you don't have a library, it's time to create one.", + "createLibraryLink": "Create a new library" + }, + "Quota": { + "currentUsageHeader": "Current usage", + "loadingMessage": "Loading usage data…", + "percentUsed": "{progress}%", + "currentUsage": "{amount} used on {max} allowed", + "pendingLabel": "Pending files", + "viewFilesLink": "View files", + "purgeButton": "Purge", + "purgePendingModalHeader": "Purge pending files?", + "purgePendingModalMessage": "Removes uploaded but yet to be processed tracks completely, adding the corresponding data to your quota.", + "skippedLabel": "Skipped files", + "purgeSkippedModalHeader": "Purge skipped files?", + "purgeSkippedModalMessage": "Removes uploaded tracks skipped during the import processes completely, adding the corresponding data to your quota.", + "erroredLabel": "Errored files", + "purgeErroredModalHeader": "Purge errored files?", + "purgeErroredModalMessage": "Removes uploaded tracks that could not be processed by the server completely, adding the corresponding data to your quota." + + } + }, + "remote": { + "Card": { + "privateTooltip": "This library is private and your approval from its owner is needed to access its content", + "publicTooltip": "This library is public and you can access its content freely", + "scanSkipped": "Scan skipped (previous scan is too recent)", + "scanLaunched": "Scan launched", + "followError": "Cannot follow remote library: {error}", + "unfollowError": "Cannot unfollow remote library: {error}", + "trackCount": "No tracks | {count} track | {count} tracks", + "scanPending": "Scan pending", + "scanProgress": "Scanning ({progress})", + "scanFailure": "Problem during scanning", + "scanSuccess": "Scanned", + "scanPartialSuccess": "Scanned with errors", + "scanDetails": "Details", + "lastUpdate": "Last update: ", + "failedTracks": "Failed tracks: {tracks}", + "scanNowButton": "Scan now ", + "sharingLinkLabel": "Sharing link", + "followButton": "Follow", + "pendingApprovalButton": "Follow request pending approval", + "cancelFollowButton": "Cancel follow request", + "unfollowButton": "Unfollow", + "unfollowModalHeader": "Unfollow this libary?", + "unfollowModalMessage": "By unfollowing this library, you loose access to its content." + }, + "Home": { + "loadingMessage": "Loading remote libraries…", + "remoteLibrariesHeader": "Remote libraries", + "remoteLibrariesDescription": "Remote libraries are owned by other users on the network. You can access them as long as they are public or you are granted access.", + "knownLibrariesHeader": "Known libraries", + "refreshButton": "Refresh" + }, + "ScanForm": { + "placeholder": "Enter a library URL", + "submitLibrarySearch": "Submit search", + "failureHeader": "Could not fetch remote library", + "searchLabel": "Search a remote library" + } + } + }, + "library": { + "DetailAlbums": { + "ownerEmptyState": "This library is empty, you should upload something in it!", + "viewerEmptyState": "You may need to follow this library to see its content." + }, + "DetailOverview": { + "ownerEmptyState": "This library is empty, you should upload something in it!", + "viewerEmptyState": "You may need to follow this library to see its content." + }, + "DetailTracks": { + "ownerEmptyState": "This library is empty, you should upload something in it!", + "viewerEmptyState": "You may need to follow this library to see its content." + }, + "Edit": { + "libraryContentsHeader": "Library contents", + "followersHeader": "Followers", + "loadingFollowers": "Loading followers…", + "userTableHeader": "User", + "dateTableHeader": "Date", + "statusTableHeader": "Status", + "actionTableHeader": "Action", + "pendingStatus": "Pending approval", + "acceptedStatus": "Accepted", + "rejectedStatus": "Rejected", + "acceptButton": "Accept", + "rejectButton": "Reject", + "noFollowers": "Nobody is following this library" + }, + "LibraryBase": { + "title": "Library", + "privateVisibility": "Private", + "instanceVisibility": "Restricted", + "publicVisibility": "Public", + "privateTooltip": "This library is private and your approval from its owner is needed to access its content", + "instanceTooltip": "This library is restricted to users on this pod only", + "publicTooltip": "This library is public and you can access its content freely", + "domainViewLink": "View on {domain}", + "moderationLink": "Open in moderation interface", + "ownerLink": "Owned by {username}", + "trackCount": "No tracks | {count} track | {count} tracks", + "sharingLinkLabel": "Sharing link", + "sharingLinkDescription": "Share this link with other users so they can request access to this library by copy-pasting it in their pod search bar.", + "artistsLink": "Artists", + "albumsLink": "Albums", + "tracksLink": "Tracks", + "uploadButton": "Upload", + "editButton": "Edit" + } + }, + "playlists": { + "Detail": { + "title": "Playlist", + "trackCount": "Playlist containing {count} track, by {username} | Playlist containing {count} tracks, by {username}", + "playAllButton": "Play all", + "stopEditButton": "Stop Editing", + "editButton": "Edit", + "embedButton": "Embed", + "deleteButton": "Delete", + "deleteModalHeader": "Do you want to delete the playlist {playlist}?", + "deleteModalMessage": "This will completely delete this playlist and cannot be undone.", + "deleteModalConfirm": "Delete playlist", + "embedModalHeader": "Embed this playlist on your website", + "cancelButton": "Cancel", + "tracksHeader": "Tracks", + "emptyState": "There are no tracks in this playlist yet" + }, + "List": { + "playlistsHeader": "Playlists", + "searchPlaceholder": "Enter playlist name…", + "browsePlaylistsHeader": "Browsing playlists", + "manageButton": "Manage your playlists", + "searchLabel": "Search", + "orderingLabel": "Ordering", + "orderingDirectionLabel": "Order", + "ascendingOrdering": "Ascending", + "descendingOrdering": "Descending", + "resultsPerPage": "Results per page", + "emptyState": "No results matching your query", + "createPlaylistButton": "Create a playlist" + } + }, + "radios": { + "Detail": { + "title": "Radio", + "radioSubheader": "Radio containing {tracks} tracks, by ", + "editButton": "Edit…", + "deleteButton": "Delete", + "deleteModalHeader": "Do you want to delete the radio {radio}?", + "deleteModalMessage": "This will completely delete this radio and cannot be undone.", + "deleteModalConfirm": "Delete radio", + "tracksHeader": "Tracks", + "emptyState": "No tracks have been hadded to this radio yet" } } } diff --git a/front/src/views/admin/ChannelDetail.vue b/front/src/views/admin/ChannelDetail.vue index 3b7e43884..fafebd227 100644 --- a/front/src/views/admin/ChannelDetail.vue +++ b/front/src/views/admin/ChannelDetail.vue @@ -290,7 +290,7 @@ const getQuery = (field: string, value: string) => `${field}:"${value}"`

    - {{ $t('views.admin.ChannelDetail.activityHeader') }} + {{ $t('views.admin.ChannelDetail.activityHeader') }} 

    @@ -369,7 +369,7 @@ const getQuery = (field: string, value: string) => `${field}:"${value}"`

    - {{ $t('views.admin.ChannelDetail.audioContentHeader') }} + {{ $t('views.admin.ChannelDetail.audioContentHeader') }} 

    diff --git a/front/src/views/admin/library/AlbumDetail.vue b/front/src/views/admin/library/AlbumDetail.vue index aed53dca2..c00d17f2a 100644 --- a/front/src/views/admin/library/AlbumDetail.vue +++ b/front/src/views/admin/library/AlbumDetail.vue @@ -277,7 +277,7 @@ const getQuery = (field: string, value: string) => `${field}:"${value}"`

    - {{ $t('views.admin.library.AlbumDetail.activityHeader') }} + {{ $t('views.admin.library.AlbumDetail.activityHeader') }} 

    @@ -356,7 +356,7 @@ const getQuery = (field: string, value: string) => `${field}:"${value}"`

    - {{ $t('views.admin.library.AlbumDetail.audioContentHeader') }} + {{ $t('views.admin.library.AlbumDetail.audioContentHeader') }} 

    diff --git a/front/src/views/admin/library/ArtistDetail.vue b/front/src/views/admin/library/ArtistDetail.vue index 1b539ffef..71a883541 100644 --- a/front/src/views/admin/library/ArtistDetail.vue +++ b/front/src/views/admin/library/ArtistDetail.vue @@ -276,7 +276,7 @@ const getQuery = (field: string, value: string) => `${field}:"${value}"`

    - {{ $t('views.admin.library.ArtistDetail.activityHeader') }} + {{ $t('views.admin.library.ArtistDetail.activityHeader') }} 

    @@ -355,7 +355,7 @@ const getQuery = (field: string, value: string) => `${field}:"${value}"`

    - {{ $t('views.admin.library.ArtistDetail.audioContentHeader') }} + {{ $t('views.admin.library.ArtistDetail.audioContentHeader') }} 

    diff --git a/front/src/views/admin/library/LibraryDetail.vue b/front/src/views/admin/library/LibraryDetail.vue index 417cc4533..e607e2c11 100644 --- a/front/src/views/admin/library/LibraryDetail.vue +++ b/front/src/views/admin/library/LibraryDetail.vue @@ -278,7 +278,7 @@ const updateObj = async (attr: string) => {

    - {{ $t('views.admin.library.LibraryDetail.activityHeader') }} + {{ $t('views.admin.library.LibraryDetail.activityHeader') }} 

    @@ -331,7 +331,7 @@ const updateObj = async (attr: string) => {

    - {{ $t('views.admin.library.LibraryDetail.audioContentHeader') }} + {{ $t('views.admin.library.LibraryDetail.audioContentHeader') }} 

    diff --git a/front/src/views/admin/library/TagDetail.vue b/front/src/views/admin/library/TagDetail.vue index f888eda9e..0a3d20ee9 100644 --- a/front/src/views/admin/library/TagDetail.vue +++ b/front/src/views/admin/library/TagDetail.vue @@ -157,7 +157,7 @@ const getQuery = (field: string, value: string) => `${field}:"${value}"`

    - {{ $t('views.admin.library.TagDetail.activityHeader') }} + {{ $t('views.admin.library.TagDetail.activityHeader') }} 

    @@ -179,7 +179,7 @@ const getQuery = (field: string, value: string) => `${field}:"${value}"`

    - {{ $t('views.admin.library.TagDetail.audioContentHeader') }} + {{ $t('views.admin.library.TagDetail.audioContentHeader') }} 

    diff --git a/front/src/views/admin/library/TrackDetail.vue b/front/src/views/admin/library/TrackDetail.vue index 0417de1cc..8b485a564 100644 --- a/front/src/views/admin/library/TrackDetail.vue +++ b/front/src/views/admin/library/TrackDetail.vue @@ -329,7 +329,7 @@ const getQuery = (field: string, value: string) => `${field}:"${value}"`

    - {{ $t('views.admin.library.TrackDetail.activityHeader') }} + {{ $t('views.admin.library.TrackDetail.activityHeader') }} 

    @@ -408,7 +408,7 @@ const getQuery = (field: string, value: string) => `${field}:"${value}"`

    - {{ $t('views.admin.library.TrackDetail.trackDataHeader') }} + {{ $t('views.admin.library.TrackDetail.trackDataHeader') }} 

    diff --git a/front/src/views/admin/library/UploadDetail.vue b/front/src/views/admin/library/UploadDetail.vue index 953d36a24..6c10ec8a6 100644 --- a/front/src/views/admin/library/UploadDetail.vue +++ b/front/src/views/admin/library/UploadDetail.vue @@ -264,7 +264,7 @@ const showUploadDetailModal = ref(false)

    - {{ $t('views.admin.library.UploadDetail.activityHeader') }} + {{ $t('views.admin.library.UploadDetail.activityHeader') }} 

    @@ -286,11 +286,11 @@ const showUploadDetailModal = ref(false) v-if="object.accessed_date" :date="object.accessed_date" /> - {{ $t('views.admin.library.UploadDetail.notApplicable') }} - + @@ -302,7 +302,7 @@ const showUploadDetailModal = ref(false)

    - {{ $t('views.admin.library.UploadDetail.audioContentHeader') }} + {{ $t('views.admin.library.UploadDetail.audioContentHeader') }} 

    @@ -325,11 +325,11 @@ const showUploadDetailModal = ref(false) - {{ $t('views.admin.library.UploadDetail.notApplicable') }} - + @@ -348,11 +348,11 @@ const showUploadDetailModal = ref(false) - {{ $t('views.admin.library.UploadDetail.notApplicable') }} - + @@ -363,11 +363,11 @@ const showUploadDetailModal = ref(false) - {{ $t('views.admin.library.UploadDetail.notApplicable') }} - + @@ -380,11 +380,11 @@ const showUploadDetailModal = ref(false) - {{ $t('views.admin.library.UploadDetail.notApplicable') }} - + diff --git a/front/src/views/admin/moderation/AccountsDetail.vue b/front/src/views/admin/moderation/AccountsDetail.vue index b2d4f7417..454152c06 100644 --- a/front/src/views/admin/moderation/AccountsDetail.vue +++ b/front/src/views/admin/moderation/AccountsDetail.vue @@ -26,14 +26,14 @@ const { t } = useI18n() const logger = useLogger() const labels = computed(() => ({ - statsWarning: t('Statistics are computed from known activity and content on your instance, and do not reflect general activity for this object'), - uploadQuota: t('Determine how much content the user can upload. Leave empty to use the default value of the instance.') + statsWarning: t('views.admin.moderation.AccountsDetail.statsWarning'), + uploadQuota: t('views.admin.moderation.AccountsDetail.uploadQuota') })) const allPermissions = computed(() => [ - { code: 'library', label: t('Library') }, - { code: 'moderation', label: t('Moderation') }, - { code: 'settings', label: t('Settings') } + { code: 'library', label: t('views.admin.moderation.AccountsDetail.libraryPermission') }, + { code: 'moderation', label: t('views.admin.moderation.AccountsDetail.moderationPermission') }, + { code: 'settings', label: t('views.admin.moderation.AccountsDetail.settingsPermission') } ]) const isLoadingPolicy = ref(false) @@ -167,7 +167,7 @@ const updatePolicy = (newPolicy: InstancePolicy) => { @@ -176,7 +176,7 @@ const updatePolicy = (newPolicy: InstancePolicy) => { target="_blank" rel="noopener noreferrer" > - Open profile  + {{ $t('views.admin.moderation.AccountsDetail.openProfileLink') }}  @@ -192,7 +192,7 @@ const updatePolicy = (newPolicy: InstancePolicy) => { rel="noopener noreferrer" > - View in Django's admin  + {{ $t('views.admin.moderation.AccountsDetail.djangoLink') }}  { rel="noopener noreferrer" > - View in Django's admin  + {{ $t('views.admin.moderation.AccountsDetail.djangoLink') }}  @@ -243,17 +243,17 @@ const updatePolicy = (newPolicy: InstancePolicy) => {

    - You don't have any rule in place for this account. + {{ $t('views.admin.moderation.AccountsDetail.noPolicyHeader') }}

    - Moderation policies help you control how your instance interact with a given domain or account. + {{ $t('views.admin.moderation.AccountsDetail.policyDescription') }}

    { >

    - This domain is subject to specific moderation rules + {{ $t('views.admin.moderation.AccountsDetail.activePolicyHeader') }}

    @@ -287,14 +287,14 @@ const updatePolicy = (newPolicy: InstancePolicy) => {

    - Account data + {{ $t('views.admin.moderation.AccountsDetail.accountDataHeader') }}

    - Username + {{ $t('views.admin.moderation.AccountsDetail.usernameLabel') }} {{ object.preferred_username }} @@ -303,7 +303,7 @@ const updatePolicy = (newPolicy: InstancePolicy) => {
    - Domain + {{ $t('views.admin.moderation.AccountsDetail.domainLabel') }} @@ -312,7 +312,7 @@ const updatePolicy = (newPolicy: InstancePolicy) => {
    - Display name + {{ $t('views.admin.moderation.AccountsDetail.displayNameLabel') }} {{ object.name }} @@ -320,7 +320,7 @@ const updatePolicy = (newPolicy: InstancePolicy) => {
    - Email address + {{ $t('views.admin.moderation.AccountsDetail.emailLabel') }} {{ object.user.email }} @@ -328,7 +328,7 @@ const updatePolicy = (newPolicy: InstancePolicy) => {
    - Login status + {{ $t('views.admin.moderation.AccountsDetail.loginStatusLabel') }}
    { @change="updateUser('is_active')" >
    - - Enabled - - + - Disabled - + {{ $t('views.admin.moderation.AccountsDetail.disabledStatus') }} +
    - Permissions + {{ $t('views.admin.moderation.AccountsDetail.permissionsLabel') }}
    - Type + {{ $t('views.admin.moderation.AccountsDetail.userTypeLabel') }} {{ object.type }} @@ -394,23 +394,23 @@ const updatePolicy = (newPolicy: InstancePolicy) => {
    - Last checked + {{ $t('views.admin.moderation.AccountsDetail.lastCheckedLabel') }} - - N/A - + {{ $t('views.admin.moderation.AccountsDetail.notApplicable') }} +
    - Sign-up date + {{ $t('views.admin.moderation.AccountsDetail.signupDateLabel') }} @@ -418,7 +418,7 @@ const updatePolicy = (newPolicy: InstancePolicy) => {
    - Last activity + {{ $t('views.admin.moderation.AccountsDetail.lastActivityLabel') }} @@ -433,7 +433,7 @@ const updatePolicy = (newPolicy: InstancePolicy) => {

    - Activity  + {{ $t('views.admin.moderation.AccountsDetail.activityHeader') }} 

    @@ -453,7 +453,7 @@ const updatePolicy = (newPolicy: InstancePolicy) => {
    - First seen + {{ $t('views.admin.moderation.AccountsDetail.firstSeenLabel') }} @@ -461,7 +461,7 @@ const updatePolicy = (newPolicy: InstancePolicy) => {
    - Emitted messages + {{ $t('views.admin.moderation.AccountsDetail.emittedMessagesLabel') }} {{ stats.outbox_activities }} @@ -469,7 +469,7 @@ const updatePolicy = (newPolicy: InstancePolicy) => {
    - Received library follows + {{ $t('views.admin.moderation.AccountsDetail.receivedFollowsLabel') }} {{ stats.received_library_follows }} @@ -477,7 +477,7 @@ const updatePolicy = (newPolicy: InstancePolicy) => {
    - Emitted library follows + {{ $t('views.admin.moderation.AccountsDetail.emittedFollowsLabel') }} {{ stats.emitted_library_follows }} @@ -486,7 +486,7 @@ const updatePolicy = (newPolicy: InstancePolicy) => {
    - Linked reports + {{ $t('views.admin.moderation.AccountsDetail.linkedReportsLabel') }} @@ -496,7 +496,7 @@ const updatePolicy = (newPolicy: InstancePolicy) => {
    - Requests + {{ $t('views.admin.moderation.AccountsDetail.requestsLabel') }} @@ -512,7 +512,7 @@ const updatePolicy = (newPolicy: InstancePolicy) => {

    - Audio content  + {{ $t('views.admin.moderation.AccountsDetail.audioContentHeader') }} 

    @@ -532,7 +532,7 @@ const updatePolicy = (newPolicy: InstancePolicy) => {
    - Cached size + {{ $t('views.admin.moderation.AccountsDetail.cachedSizeLabel') }} {{ humanSize(stats.media_downloaded_size) }} @@ -540,7 +540,7 @@ const updatePolicy = (newPolicy: InstancePolicy) => {
    - Upload quota + {{ $t('views.admin.moderation.AccountsDetail.uploadQuotaLabel') }} @@ -553,7 +553,7 @@ const updatePolicy = (newPolicy: InstancePolicy) => { @change="updateUser('upload_quota', true)" >
    - MB + {{ $t('views.admin.moderation.AccountsDetail.megabyteLabel') }}
    {
    - Total size + {{ $t('views.admin.moderation.AccountsDetail.totalSizeLabel') }} {{ humanSize(stats.media_total_size) }} @@ -574,7 +574,7 @@ const updatePolicy = (newPolicy: InstancePolicy) => {
    - Channels + {{ $t('views.admin.moderation.AccountsDetail.channelsLabel') }} @@ -584,7 +584,7 @@ const updatePolicy = (newPolicy: InstancePolicy) => {
    - Libraries + {{ $t('views.admin.moderation.AccountsDetail.librariesLabel') }} @@ -594,7 +594,7 @@ const updatePolicy = (newPolicy: InstancePolicy) => {
    - Uploads + {{ $t('views.admin.moderation.AccountsDetail.uploadsLabel') }} @@ -603,7 +603,7 @@ const updatePolicy = (newPolicy: InstancePolicy) => {
    - Artists + {{ $t('views.admin.moderation.AccountsDetail.artistsLabel') }} {{ stats.artists }} @@ -611,7 +611,7 @@ const updatePolicy = (newPolicy: InstancePolicy) => {
    - Albums + {{ $t('views.admin.moderation.AccountsDetail.albumsLabel') }} {{ stats.albums }} @@ -619,7 +619,7 @@ const updatePolicy = (newPolicy: InstancePolicy) => {
    - Tracks + {{ $t('views.admin.moderation.AccountsDetail.tracksLabel') }} {{ stats.tracks }} diff --git a/front/src/views/admin/moderation/Base.vue b/front/src/views/admin/moderation/Base.vue index a1b561f6e..2739cc84a 100644 --- a/front/src/views/admin/moderation/Base.vue +++ b/front/src/views/admin/moderation/Base.vue @@ -9,8 +9,8 @@ const { t } = useI18n() const allowListEnabled = ref(false) const labels = computed(() => ({ - moderation: t('Moderation'), - secondaryMenu: t('Secondary menu') + moderation: t('views.admin.moderation.Base.moderation'), + secondaryMenu: t('views.admin.moderation.Base.secondaryMenu') })) const fetchNodeInfo = async () => { @@ -35,7 +35,7 @@ fetchNodeInfo() class="ui item" :to="{name: 'manage.moderation.reports.list', query: {q: 'resolved:no'}}" > - Reports + {{ $t('views.admin.moderation.Base.reportsLink') }}
    - User Requests + {{ $t('views.admin.moderation.Base.userRequestsLink') }}
    - Domains + {{ $t('views.admin.moderation.Base.domainsLink') }} - Accounts + {{ $t('views.admin.moderation.Base.accountsLink') }} () const { t } = useI18n() const labels = computed(() => ({ - statsWarning: t('Statistics are computed from known activity and content on your instance, and do not reflect general activity for this object') + statsWarning: t('views.admin.moderation.DomainsDetail.statsWarning') })) const isLoadingPolicy = ref(false) @@ -133,7 +133,7 @@ const setAllowList = async (value: boolean) => { rel="noopener noreferrer" class="logo-wrapper" > - Open website  + {{ $t('views.admin.moderation.DomainsDetail.websiteLink') }} 
    @@ -149,7 +149,7 @@ const setAllowList = async (value: boolean) => { rel="noopener noreferrer" > - View in Django's admin  + {{ $t('views.admin.moderation.DomainsDetail.djangoLink') }} 
    { @click.prevent="setAllowList(false)" > - Remove from allow-list + {{ $t('views.admin.moderation.DomainsDetail.removeFromAllowList') }}
    @@ -191,17 +191,17 @@ const setAllowList = async (value: boolean) => {

    - You don't have any rule in place for this domain. + {{ $t('views.admin.moderation.DomainsDetail.noPolicyHeader') }}

    - Moderation policies help you control how your instance interact with a given domain or account. + {{ $t('views.admin.moderation.DomainsDetail.policyDescription') }}

    { >

    - This domain is subject to specific moderation rules + {{ $t('views.admin.moderation.DomainsDetail.activePolicyHeader') }}

    @@ -235,78 +235,78 @@ const setAllowList = async (value: boolean) => {

    - Instance data + {{ $t('views.admin.moderation.DomainsDetail.instanceDataHeader') }}

    - Is present on allow-list + {{ $t('views.admin.moderation.DomainsDetail.inAllowListLabel') }} - - Yes - - + - No - + {{ $t('views.admin.moderation.DomainsDetail.inAllowListFalse') }} +
    - Last checked + {{ $t('views.admin.moderation.DomainsDetail.lastCheckedLabel') }} - - N/A - + {{ $t('views.admin.moderation.DomainsDetail.notApplicable') }} +