fix(translations): 🌐 Localize more places (#4400)

* Localize a few isolated strings

* Localize paginator

* Localize a few isolated strings

* Make button width dynamic for better i18n

* Localize a few isolated strings

* Fix technical typo
emby-recently-added
sephrat 3 years ago committed by GitHub
parent 22b8a221e9
commit 005529cda8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -65,6 +65,9 @@ import { TooltipModule } from "primeng/tooltip";
import { TranslateHttpLoader } from "@ngx-translate/http-loader"; import { TranslateHttpLoader } from "@ngx-translate/http-loader";
import { UnauthorizedInterceptor } from "./auth/unauthorized.interceptor"; import { UnauthorizedInterceptor } from "./auth/unauthorized.interceptor";
import { environment } from "../environments/environment"; import { environment } from "../environments/environment";
import { MatPaginatorIntl } from "@angular/material/paginator";
import { TranslateService } from "@ngx-translate/core";
import { MatPaginatorI18n } from "./localization/MatPaginatorI18n";
const routes: Routes = [ const routes: Routes = [
{ path: "*", component: PageNotFoundComponent }, { path: "*", component: PageNotFoundComponent },
@ -212,6 +215,10 @@ export function JwtTokenGetter() {
useClass: UnauthorizedInterceptor, useClass: UnauthorizedInterceptor,
multi: true multi: true
}, },
{
provide: MatPaginatorIntl, deps: [TranslateService],
useFactory: (translateService: TranslateService) => new MatPaginatorI18n(translateService).getPaginatorIntl()
},
], ],
bootstrap: [AppComponent], bootstrap: [AppComponent],
}) })

@ -1,6 +1,6 @@
import { Component } from "@angular/core"; import { Component } from "@angular/core";
@Component({ @Component({
template: "<h2>Page not found</h2>", template: "<h2>{{ 'ErrorPages.NotFound' | translate }}</h2>",
}) })
export class PageNotFoundComponent { } export class PageNotFoundComponent { }

@ -1,6 +1,6 @@
<div class="container top-spacing" *ngIf="details"> <div class="container top-spacing" *ngIf="details">
<h1>Issues for {{details.title}}</h1> <h1>{{ 'Issues.IssuesForTitle' | translate: { title: details.title} }}</h1>
<div> <div>
<span>{{'Issues.Requested' | translate}} <span>{{'Issues.Requested' | translate}}
<i *ngIf="!hasRequest" class="far fa-times-circle"></i> <i *ngIf="!hasRequest" class="far fa-times-circle"></i>

@ -0,0 +1,34 @@
import { MatPaginatorIntl } from '@angular/material/paginator';
import { TranslateService } from '@ngx-translate/core';
export class MatPaginatorI18n {
constructor(private translate: TranslateService) { }
getPaginatorIntl(): MatPaginatorIntl {
const paginatorIntl = new MatPaginatorIntl();
paginatorIntl.itemsPerPageLabel = this.translate.instant('Paginator.itemsPerPageLabel');
paginatorIntl.nextPageLabel = this.translate.instant('Paginator.nextPageLabel');
paginatorIntl.previousPageLabel = this.translate.instant('Paginator.previousPageLabel');
paginatorIntl.firstPageLabel = this.translate.instant('Paginator.firstPageLabel');
paginatorIntl.lastPageLabel = this.translate.instant('Paginator.lastPageLabel');
paginatorIntl.getRangeLabel = this.getRangeLabel.bind(this);
return paginatorIntl;
}
private getRangeLabel(page: number, pageSize: number, length: number): string {
if (length == 0 || pageSize == 0) {
return this.translate.instant('Paginator.rangePageLabel1', { length });
}
length = Math.max(length, 0);
const startIndex = page * pageSize;
// If the start index exceeds the list length, do not try and fix the end index to the end.
const endIndex =
startIndex < length ? Math.min(startIndex + pageSize, length) : startIndex + pageSize;
return this.translate.instant('Paginator.rangePageLabel2', { startIndex: startIndex + 1, endIndex, length });
}
}

@ -143,7 +143,7 @@
<div class="row" *ngIf="movie.videos?.results?.length > 0"> <div class="row" *ngIf="movie.videos?.results?.length > 0">
<div class="col-12"> <div class="col-12">
<mat-card class="mat-elevation-z8"> <mat-card class="mat-elevation-z8">
<mat-card-header>Trailers</mat-card-header> <mat-card-header>{{'MediaDetails.Trailers' | translate}}</mat-card-header>
<mat-card-content> <mat-card-content>
<p-carousel class="no-indicator" [numVisible]="2" [numScroll]="10" [page]="0" [value]="movie.videos?.results"> <p-carousel class="no-indicator" [numVisible]="2" [numScroll]="10" [page]="0" [value]="movie.videos?.results">
<ng-template let-result pTemplate="item"> <ng-template let-result pTemplate="item">

@ -104,7 +104,7 @@
<hr /> <hr />
<div class="genre-button-container" *ngIf="movie.genres"> <div class="genre-button-container" *ngIf="movie.genres">
<span class="label">{{'MediaDetails.Genres' | translate }}</span> <span class="label">{{'MediaDetails.GenresLabel' | translate }}</span>
<div> <div>
<mat-chip-list> <mat-chip-list>
<mat-chip selected *ngFor="let genre of movie.genres"> <mat-chip selected *ngFor="let genre of movie.genres">

@ -58,7 +58,7 @@
<div class="genre-button-container" *ngIf="tv.genres"> <div class="genre-button-container" *ngIf="tv.genres">
<span class="label">{{'MediaDetails.Genres' | translate }}</span> <span class="label">{{'MediaDetails.GenresLabel' | translate }}</span>
<div> <div>
<mat-chip-list> <mat-chip-list>
<mat-chip selected *ngFor="let genre of tv.genres"> <mat-chip selected *ngFor="let genre of tv.genres">
@ -70,7 +70,7 @@
<hr /> <hr />
<div class="keyword-button-container" *ngIf="tv?.keywords?.keywordsValue?.length > 0"> <div class="keyword-button-container" *ngIf="tv?.keywords?.keywordsValue?.length > 0">
<span class="label">{{'MediaDetails.Keywords' | translate }}:</span> <span class="label">{{'MediaDetails.Keywords' | translate }}</span>
<mat-chip-list> <mat-chip-list>
<mat-chip selected *ngFor="let keyword of tv.keywords.keywordsValue"> <mat-chip selected *ngFor="let keyword of tv.keywords.keywordsValue">
{{keyword.name}} {{keyword.name}}

@ -5,8 +5,9 @@
<div> {{ request.requestStatus | translate }}</div> <div> {{ request.requestStatus | translate }}</div>
</mat-panel-title> </mat-panel-title>
<mat-panel-description> <mat-panel-description>
{{'Requests.RequestedBy' | translate}} '{{request.requestedUser.userAlias}}' on {{'Requests.RequestedByOn' | translate: {
{{request.requestedDate | amLocal | amUserLocale | amDateFormat: 'LL' }} user: request.requestedUser.userAlias,
date: request.requestedDate | amLocal | amUserLocale | amDateFormat: 'LL' } }}
<span *ngIf="request.denied"> - {{request.deniedReason}}</span> <span *ngIf="request.denied"> - {{request.deniedReason}}</span>
</mat-panel-description> </mat-panel-description>
</mat-expansion-panel-header> </mat-expansion-panel-header>

@ -323,8 +323,7 @@
} }
.media-row .mat-raised-button{ .media-row .mat-raised-button{
padding:2px 1.5em;; padding:2px 1.5em;
width:170px;
margin-top:10px; margin-top:10px;
margin-left:10px; margin-left:10px;
} }

@ -1,6 +1,6 @@
<div class="form-group"> <div class="form-group">
<div class="input-group"> <div class="input-group">
<input type="text" id="search" class="form-control form-control-custom searchwidth" placeholder="Search" <input type="text" id="search" class="form-control form-control-custom searchwidth" [placeholder]="'Search.Search' | translate"
(keyup)="search($event)"> (keyup)="search($event)">
<span class="input-group-btn"> <span class="input-group-btn">
<button id="filterBtn" class="btn btn-sm btn-info-outline" (click)="filterDisplay = !filterDisplay"> <button id="filterBtn" class="btn btn-sm btn-info-outline" (click)="filterDisplay = !filterDisplay">

@ -1,6 +1,6 @@
<div class="form-group"> <div class="form-group">
<div class="input-group"> <div class="input-group">
<input type="text" id="search" class="form-control form-control-custom searchwidth" placeholder="Search" <input type="text" id="search" class="form-control form-control-custom searchwidth" [placeholder]="'Search.Search' | translate"
(keyup)="search($event)"> (keyup)="search($event)">
<span class="input-group-btn"> <span class="input-group-btn">
<button id="filterBtn" class="btn btn-sm btn-info-outline" (click)="filterDisplay = !filterDisplay"> <button id="filterBtn" class="btn btn-sm btn-info-outline" (click)="filterDisplay = !filterDisplay">

@ -1,6 +1,6 @@
<div class="form-group"> <div class="form-group">
<div> <div>
<input type="text" id="search" class="form-control form-control-custom" placeholder="Search" (keyup)="search($event)"> <input type="text" id="search" class="form-control form-control-custom" [placeholder]="'Common.Search' | translate" (keyup)="search($event)">
</div> </div>
</div> </div>
<br /> <br />

@ -1,7 +1,7 @@
<div class='container'> <div class='container'>
<div class='chatbox'> <div class='chatbox'>
<div class='chatbox__user-list'> <div class='chatbox__user-list'>
<h1>Users</h1> <h1>{{ "Issues.UserManagement" | translate }}</h1>
<div class='chatbox__user--active' *ngFor="let user of userList"> <div class='chatbox__user--active' *ngFor="let user of userList">
<p>{{user}}</p> <p>{{user}}</p>
</div> </div>
@ -19,7 +19,7 @@
</div> </div>
</div> </div>
<div class="form"> <div class="form">
<input type="text" [(ngModel)]="currentMessage" placeholder="Enter your message"> <input type="text" [(ngModel)]="currentMessage" [placeholder]="'Issues.EnterYourMessage' | translate">
<button mat-raised-button class="add-message" (click)="addMessage()">Send</button> <button mat-raised-button class="add-message" (click)="addMessage()">{{ "Issues.SendMessageButton" | translate }}</button>
</div> </div>
</div> </div>

@ -10,7 +10,7 @@
<mat-icon matChipRemove>cancel</mat-icon> <mat-icon matChipRemove>cancel</mat-icon>
</mat-chip> </mat-chip>
<input <input
placeholder="Search Keyword" [placeholder]="'Search.SearchGenre' | translate"
#keywordInput #keywordInput
[formControl]="control" [formControl]="control"
[matAutocomplete]="auto" [matAutocomplete]="auto"

@ -9,7 +9,7 @@
<mat-icon matChipRemove>cancel</mat-icon> <mat-icon matChipRemove>cancel</mat-icon>
</mat-chip> </mat-chip>
<input <input
placeholder="Search Keyword" [placeholder]="'Search.SearchKeyword' | translate"
#keywordInput #keywordInput
[formControl]="control" [formControl]="control"
[matAutocomplete]="auto" [matAutocomplete]="auto"

@ -9,7 +9,7 @@
<mat-icon matChipRemove>cancel</mat-icon> <mat-icon matChipRemove>cancel</mat-icon>
</mat-chip> </mat-chip>
<input <input
placeholder="Search Keyword" [placeholder]="'Search.SearchProvider' | translate"
#keywordInput #keywordInput
[formControl]="control" [formControl]="control"
[matAutocomplete]="auto" [matAutocomplete]="auto"

@ -1,3 +1,3 @@
<div class="wizard-background"> <div class="wizard-background">
<h2 style="color:white">Unsubscribed!</h2> <h2 style="color:white">{{ 'UserPreferences.Unsubscribed' | translate }}</h2>
</div> </div>

@ -55,6 +55,9 @@
"OfflineParagraph": "The media server is currently offline.", "OfflineParagraph": "The media server is currently offline.",
"CheckPageForUpdates": "Check this page for continuous site updates." "CheckPageForUpdates": "Check this page for continuous site updates."
}, },
"ErrorPages": {
"NotFound": "Page not found"
},
"NavigationBar": { "NavigationBar": {
"Discover": "Discover", "Discover": "Discover",
"Search": "Search", "Search": "Search",
@ -131,6 +134,9 @@
}, },
"AdvancedSearchInstructions": "Please choose what type of media you are searching for:", "AdvancedSearchInstructions": "Please choose what type of media you are searching for:",
"YearOfRelease": "Year of Release", "YearOfRelease": "Year of Release",
"SearchGenre": "Search Genre",
"SearchKeyword": "Search Keyword",
"SearchProvider": "Search Provider",
"KeywordSearchingDisclaimer": "Please note that Keyword Searching is very hit and miss due to the inconsistent data in TheMovieDb" "KeywordSearchingDisclaimer": "Please note that Keyword Searching is very hit and miss due to the inconsistent data in TheMovieDb"
}, },
"Requests": { "Requests": {
@ -224,6 +230,7 @@
}, },
"Issues": { "Issues": {
"Title": "Issues", "Title": "Issues",
"IssuesForTitle": "Issues for {{title}}",
"PendingTitle": "Pending Issues", "PendingTitle": "Pending Issues",
"InProgressTitle": "In Progress Issues", "InProgressTitle": "In Progress Issues",
"ResolvedTitle": "Resolved Issues", "ResolvedTitle": "Resolved Issues",
@ -256,6 +263,7 @@
"Delete": "Delete issue", "Delete": "Delete issue",
"DeletedIssue": "Issue has been deleted", "DeletedIssue": "Issue has been deleted",
"Chat":"Chat", "Chat":"Chat",
"EnterYourMessage":"Enter Your Message",
"Requested":"Requested", "Requested":"Requested",
"UserOnDate": "{{user}} on {{date}}" "UserOnDate": "{{user}} on {{date}}"
}, },
@ -282,6 +290,7 @@
}, },
"MediaDetails": { "MediaDetails": {
"Denied": "Denied", "Denied": "Denied",
"Trailers": "Trailers",
"RecommendationsTitle": "Recommendations", "RecommendationsTitle": "Recommendations",
"SimilarTitle": "Similar", "SimilarTitle": "Similar",
"VideosTitle": "Videos", "VideosTitle": "Videos",
@ -318,7 +327,8 @@
"RootFolderOverride":"Root Folder Override:", "RootFolderOverride":"Root Folder Override:",
"QualityOverride":"Quality Override:", "QualityOverride":"Quality Override:",
"Network":"Network:", "Network":"Network:",
"Genres":"Genres:", "GenresLabel":"Genres:",
"Genres":"Genres",
"FirstAired":"First Aired:", "FirstAired":"First Aired:",
"TheatricalRelease":"Release:", "TheatricalRelease":"Release:",
"DigitalRelease":"Digital Release:", "DigitalRelease":"Digital Release:",
@ -344,6 +354,7 @@
"PleaseSelectUser": "Please select a user", "PleaseSelectUser": "Please select a user",
"StreamingOn": "Streaming On:", "StreamingOn": "Streaming On:",
"RequestedBy": "Requested By:", "RequestedBy": "Requested By:",
"RequestedByOn": "Requested By {{user}} on {{date}}",
"RequestDate": "Request Date:", "RequestDate": "Request Date:",
"DeniedReason": "Denied Reason:", "DeniedReason": "Denied Reason:",
"ReProcessRequest": "Re-Process Request", "ReProcessRequest": "Re-Process Request",
@ -397,7 +408,8 @@
"NewPasswordConfirm": "New Password Confirm", "NewPasswordConfirm": "New Password Confirm",
"Security": "Security", "Security": "Security",
"Profile": "Profile", "Profile": "Profile",
"UpdatedYourInformation": "Updated your information" "UpdatedYourInformation": "Updated your information",
"Unsubscribed": "Unsubscribed!"
}, },
"UserTypeLabel": { "UserTypeLabel": {
"1": "Local User", "1": "Local User",
@ -405,6 +417,15 @@
"3": "Emby User", "3": "Emby User",
"4": "Emby Connect User", "4": "Emby Connect User",
"5": "Jellyfin User" "5": "Jellyfin User"
},
"Paginator": {
"itemsPerPageLabel": "Items per page:",
"nextPageLabel": "Next page",
"previousPageLabel": "Previous page",
"firstPageLabel": "First page",
"lastPageLabel": "Last page",
"rangePageLabel1": "0 of {{length}}",
"rangePageLabel2": "{{startIndex}} {{endIndex}} of {{length}}"
} }
} }

Loading…
Cancel
Save