diff --git a/src/Ombi.Core/Engine/BaseMediaEngine.cs b/src/Ombi.Core/Engine/BaseMediaEngine.cs index ce1713bb8..fc9847c7d 100644 --- a/src/Ombi.Core/Engine/BaseMediaEngine.cs +++ b/src/Ombi.Core/Engine/BaseMediaEngine.cs @@ -162,16 +162,21 @@ namespace Ombi.Core.Engine } } - private string defaultLangCode; protected async Task DefaultLanguageCode(string currentCode) { if (currentCode.HasValue()) { return currentCode; } + var user = await GetUser(); - var s = await GetOmbiSettings(); - return s.DefaultLanguageCode; + if (string.IsNullOrEmpty(user.Language)) + { + var s = await GetOmbiSettings(); + return s.DefaultLanguageCode; + } + + return user.Language; } private OmbiSettings ombiSettings; diff --git a/src/Ombi.Core/Engine/V2/IMultiSearchEngine.cs b/src/Ombi.Core/Engine/V2/IMultiSearchEngine.cs index fdfcb06e6..e2313016b 100644 --- a/src/Ombi.Core/Engine/V2/IMultiSearchEngine.cs +++ b/src/Ombi.Core/Engine/V2/IMultiSearchEngine.cs @@ -8,6 +8,6 @@ namespace Ombi.Core.Engine.V2 { public interface IMultiSearchEngine { - Task> MultiSearch(string searchTerm, CancellationToken cancellationToken, string lang = "en"); + Task> MultiSearch(string searchTerm, CancellationToken cancellationToken); } } \ No newline at end of file diff --git a/src/Ombi.Core/Engine/V2/MultiSearchEngine.cs b/src/Ombi.Core/Engine/V2/MultiSearchEngine.cs index d99d33a76..adcf27924 100644 --- a/src/Ombi.Core/Engine/V2/MultiSearchEngine.cs +++ b/src/Ombi.Core/Engine/V2/MultiSearchEngine.cs @@ -36,8 +36,9 @@ namespace Ombi.Core.Engine.V2 private readonly IMusicBrainzApi _musicApi; - public async Task> MultiSearch(string searchTerm, CancellationToken cancellationToken, string lang = "en") + public async Task> MultiSearch(string searchTerm, CancellationToken cancellationToken) { + var lang = await DefaultLanguageCode(null); var model = new List(); var movieDbData = (await _movieDbApi.MultiSearch(searchTerm, lang, cancellationToken)).results; diff --git a/src/Ombi.Core/Models/UI/UserViewModel.cs b/src/Ombi.Core/Models/UI/UserViewModel.cs index ca40c2ec5..e74e5037d 100644 --- a/src/Ombi.Core/Models/UI/UserViewModel.cs +++ b/src/Ombi.Core/Models/UI/UserViewModel.cs @@ -13,6 +13,7 @@ namespace Ombi.Core.Models.UI public string EmailAddress { get; set; } public string Password { get; set; } public DateTime? LastLoggedIn { get; set; } + public string Language { get; set; } public bool HasLoggedIn { get; set; } public UserType UserType { get; set; } public int MovieRequestLimit { get; set; } diff --git a/src/Ombi/ClientApp/src/app/app.component.ts b/src/Ombi/ClientApp/src/app/app.component.ts index 957bbe7aa..14899f56c 100644 --- a/src/Ombi/ClientApp/src/app/app.component.ts +++ b/src/Ombi/ClientApp/src/app/app.component.ts @@ -5,7 +5,7 @@ import { NavigationStart, Router } from "@angular/router"; import { TranslateService } from "@ngx-translate/core"; import { AuthService } from "./auth/auth.service"; import { ILocalUser } from "./auth/IUserLogin"; -import { NotificationService, CustomPageService } from "./services"; +import { NotificationService, CustomPageService, IdentityService } from "./services"; import { SettingsService } from "./services"; import { MatSnackBar } from '@angular/material/snack-bar'; @@ -49,21 +49,26 @@ export class AppComponent implements OnInit { private storage: StorageService, private signalrNotification: SignalRNotificationService, private readonly snackBar: MatSnackBar, - @Inject(DOCUMENT) private document: HTMLDocument) { + private readonly identity: IdentityService, + @Inject(DOCUMENT) private document: HTMLDocument) { this.translate.addLangs(["en", "de", "fr", "da", "es", "it", "nl", "sk", "sv", "no", "pl", "pt"]); - const selectedLang = this.storage.get("Language"); + if (this.authService.loggedIn()) { + this.identity.getUser().subscribe(u => { + if (u.language) { + this.translate.use(u.language); + } + }); + } // this language will be used as a fallback when a translation isn't found in the current language this.translate.setDefaultLang("en"); - if (selectedLang) { - this.translate.use(selectedLang); - } else { - // See if we can match the supported langs with the current browser lang - const browserLang: string = translate.getBrowserLang(); - this.translate.use(browserLang.match(/en|fr|da|de|es|it|nl|sk|sv|no|pl|pt/) ? browserLang : "en"); - } + + // See if we can match the supported langs with the current browser lang + const browserLang: string = translate.getBrowserLang(); + this.translate.use(browserLang.match(/en|fr|da|de|es|it|nl|sk|sv|no|pl|pt/) ? browserLang : "en"); + } public ngOnInit() { diff --git a/src/Ombi/ClientApp/src/app/interfaces/IUser.ts b/src/Ombi/ClientApp/src/app/interfaces/IUser.ts index d3b6c783a..f3a07145b 100644 --- a/src/Ombi/ClientApp/src/app/interfaces/IUser.ts +++ b/src/Ombi/ClientApp/src/app/interfaces/IUser.ts @@ -15,6 +15,7 @@ export interface IUser { episodeRequestLimit: number; musicRequestLimit: number; userAccessToken: string; + language: string; userQualityProfiles: IUserQualityProfiles; // FOR UI diff --git a/src/Ombi/ClientApp/src/app/media-details/components/movie/movie-details.component.ts b/src/Ombi/ClientApp/src/app/media-details/components/movie/movie-details.component.ts index bc31afc7d..65ac449aa 100644 --- a/src/Ombi/ClientApp/src/app/media-details/components/movie/movie-details.component.ts +++ b/src/Ombi/ClientApp/src/app/media-details/components/movie/movie-details.component.ts @@ -9,6 +9,7 @@ import { AuthService } from "../../../auth/auth.service"; import { IMovieRequests, RequestType, IAdvancedData } from "../../../interfaces"; import { DenyDialogComponent } from "../shared/deny-dialog/deny-dialog.component"; import { NewIssueComponent } from "../shared/new-issue/new-issue.component"; +import { StorageService } from "../../../shared/storage/storage-service"; @Component({ templateUrl: "./movie-details.component.html", @@ -29,7 +30,8 @@ export class MovieDetailsComponent { constructor(private searchService: SearchV2Service, private route: ActivatedRoute, private sanitizer: DomSanitizer, private imageService: ImageService, public dialog: MatDialog, private requestService: RequestService, - public messageService: MessageService, private auth: AuthService) { + public messageService: MessageService, private auth: AuthService, + private storage: StorageService) { this.route.params.subscribe((params: any) => { debugger; if (typeof params.movieDbId === 'string' || params.movieDbId instanceof String) { diff --git a/src/Ombi/ClientApp/src/app/services/identity.service.ts b/src/Ombi/ClientApp/src/app/services/identity.service.ts index 37e8afbda..9d2b4f8c6 100644 --- a/src/Ombi/ClientApp/src/app/services/identity.service.ts +++ b/src/Ombi/ClientApp/src/app/services/identity.service.ts @@ -75,7 +75,12 @@ export class IdentityService extends ServiceHelpers { public getNotificationPreferences(): Observable { return this.http.get(`${this.url}notificationpreferences`, {headers: this.headers}); } + public getNotificationPreferencesForUser(userId: string): Observable { return this.http.get(`${this.url}notificationpreferences/${userId}`, {headers: this.headers}); } + + public updateLanguage(lang: string): Observable { + return this.http.post(`${this.url}language`, {lang: lang}, {headers: this.headers}); + } } diff --git a/src/Ombi/ClientApp/src/app/user-preferences/components/user-preference/user-preference.component.ts b/src/Ombi/ClientApp/src/app/user-preferences/components/user-preference/user-preference.component.ts index f302f454f..3fe4359eb 100644 --- a/src/Ombi/ClientApp/src/app/user-preferences/components/user-preference/user-preference.component.ts +++ b/src/Ombi/ClientApp/src/app/user-preferences/components/user-preference/user-preference.component.ts @@ -4,6 +4,7 @@ import { TranslateService } from "@ngx-translate/core"; import { AvailableLanguages, ILanguage } from "./user-preference.constants"; import { StorageService } from "../../../shared/storage/storage-service"; import { IdentityService, SettingsService } from "../../../services"; +import { IUser } from "../../../interfaces"; @Component({ templateUrl: "./user-preference.component.html", @@ -17,6 +18,8 @@ export class UserPreferenceComponent implements OnInit { public qrCode: string; public qrCodeEnabled: boolean; + private user: IUser; + constructor(private authService: AuthService, private readonly translate: TranslateService, private storage: StorageService, @@ -39,14 +42,14 @@ export class UserPreferenceComponent implements OnInit { this.qrCodeEnabled = true; } - const selectedLang = this.storage.get("Language"); - if (selectedLang) { - this.selectedLang = selectedLang; + this.user = await this.identityService.getUser().toPromise(); + if (this.user.language) { + this.selectedLang = this.user.language; } } public languageSelected() { - this.storage.save("Language", this.selectedLang); + this.identityService.updateLanguage(this.selectedLang).subscribe(); this.translate.use(this.selectedLang); } diff --git a/src/Ombi/ClientApp/src/app/usermanagement/usermanagement-user.component.ts b/src/Ombi/ClientApp/src/app/usermanagement/usermanagement-user.component.ts index ffb02db17..7d3896372 100644 --- a/src/Ombi/ClientApp/src/app/usermanagement/usermanagement-user.component.ts +++ b/src/Ombi/ClientApp/src/app/usermanagement/usermanagement-user.component.ts @@ -71,6 +71,7 @@ export class UserManagementUserComponent implements OnInit { musicRequestLimit: 0, episodeRequestQuota: null, movieRequestQuota: null, + language: null, userQualityProfiles: { radarrQualityProfile: 0, radarrRootPath: 0, diff --git a/src/Ombi/Controllers/V1/IdentityController.cs b/src/Ombi/Controllers/V1/IdentityController.cs index d83b26c63..af10b33fd 100644 --- a/src/Ombi/Controllers/V1/IdentityController.cs +++ b/src/Ombi/Controllers/V1/IdentityController.cs @@ -330,6 +330,7 @@ namespace Ombi.Controllers.V1 EpisodeRequestLimit = user.EpisodeRequestLimit ?? 0, MovieRequestLimit = user.MovieRequestLimit ?? 0, MusicRequestLimit = user.MusicRequestLimit ?? 0, + Language = user.Language }; foreach (var role in userRoles)