Readme Change (#2190)

* Implemented the ability to login to the app by passing apiKey to the login. This is for an upcoming feature (but currently blocked by another story)

* Added a comment

* Ensure locales are sorted

* Added a new status badge that shows how many active installs we have via users that use stats.

* Bump all GA to latest versions

* Bumped dependencies

* Bumped backend notifications

* Updated ngx-pdf-reader to upcoming beta which fixes some PDFs taking time to load. PDF reader will use browser locale to load localization rather than Kavita locale for now.

* Downgraded pdf viewer as beta has lots of bugs.
This commit is contained in:
Joe Milazzo 2023-08-08 14:06:53 -05:00 committed by GitHub
parent d4e1e08b4f
commit 9f17f5daa7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 93 additions and 76 deletions

View File

@ -35,13 +35,13 @@ jobs:
distribution: 'zulu' distribution: 'zulu'
java-version: '17' java-version: '17'
- uses: actions/upload-artifact@v2 - uses: actions/upload-artifact@v3
with: with:
name: csproj name: csproj
path: Kavita.Common/Kavita.Common.csproj path: Kavita.Common/Kavita.Common.csproj
- name: Cache SonarCloud packages - name: Cache SonarCloud packages
uses: actions/cache@v1 uses: actions/cache@v3
with: with:
path: ~\sonar\cache path: ~\sonar\cache
key: ${{ runner.os }}-sonar key: ${{ runner.os }}-sonar
@ -49,7 +49,7 @@ jobs:
- name: Cache SonarCloud scanner - name: Cache SonarCloud scanner
id: cache-sonar-scanner id: cache-sonar-scanner
uses: actions/cache@v1 uses: actions/cache@v3
with: with:
path: .\.sonar\scanner path: .\.sonar\scanner
key: ${{ runner.os }}-sonar-scanner key: ${{ runner.os }}-sonar-scanner
@ -107,7 +107,7 @@ jobs:
if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/develop' }} if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/develop' }}
steps: steps:
- name: Find Current Pull Request - name: Find Current Pull Request
uses: jwalton/gh-find-current-pr@v1.0.2 uses: jwalton/gh-find-current-pr@v1.3.2
id: findPr id: findPr
with: with:
github-token: ${{ secrets.GITHUB_TOKEN }} github-token: ${{ secrets.GITHUB_TOKEN }}

View File

@ -10,8 +10,8 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="BenchmarkDotNet" Version="0.13.6" /> <PackageReference Include="BenchmarkDotNet" Version="0.13.7" />
<PackageReference Include="BenchmarkDotNet.Annotations" Version="0.13.6" /> <PackageReference Include="BenchmarkDotNet.Annotations" Version="0.13.7" />
<PackageReference Include="NSubstitute" Version="5.0.0" /> <PackageReference Include="NSubstitute" Version="5.0.0" />
</ItemGroup> </ItemGroup>

View File

@ -6,12 +6,12 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="7.0.9" /> <PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="7.0.10" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.6.3" /> <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.7.0" />
<PackageReference Include="Moq" Version="4.18.4" /> <PackageReference Include="Moq" Version="4.20.1" />
<PackageReference Include="NSubstitute" Version="5.0.0" /> <PackageReference Include="NSubstitute" Version="5.0.0" />
<PackageReference Include="System.IO.Abstractions.TestingHelpers" Version="19.2.29" /> <PackageReference Include="System.IO.Abstractions.TestingHelpers" Version="19.2.51" />
<PackageReference Include="TestableIO.System.IO.Abstractions.Wrappers" Version="19.2.29" /> <PackageReference Include="TestableIO.System.IO.Abstractions.Wrappers" Version="19.2.51" />
<PackageReference Include="xunit" Version="2.5.0" /> <PackageReference Include="xunit" Version="2.5.0" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.5.0"> <PackageReference Include="xunit.runner.visualstudio" Version="2.5.0">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>

View File

@ -60,23 +60,23 @@
<PackageReference Include="ExCSS" Version="4.2.1" /> <PackageReference Include="ExCSS" Version="4.2.1" />
<PackageReference Include="Flurl" Version="3.0.7" /> <PackageReference Include="Flurl" Version="3.0.7" />
<PackageReference Include="Flurl.Http" Version="3.2.4" /> <PackageReference Include="Flurl.Http" Version="3.2.4" />
<PackageReference Include="Hangfire" Version="1.8.3" /> <PackageReference Include="Hangfire" Version="1.8.4" />
<PackageReference Include="Hangfire.AspNetCore" Version="1.8.3" /> <PackageReference Include="Hangfire.AspNetCore" Version="1.8.4" />
<PackageReference Include="Hangfire.InMemory" Version="0.5.1" /> <PackageReference Include="Hangfire.InMemory" Version="0.5.1" />
<PackageReference Include="Hangfire.MaximumConcurrentExecutions" Version="1.1.0" /> <PackageReference Include="Hangfire.MaximumConcurrentExecutions" Version="1.1.0" />
<PackageReference Include="Hangfire.MemoryStorage.Core" Version="1.4.0" /> <PackageReference Include="Hangfire.MemoryStorage.Core" Version="1.4.0" />
<PackageReference Include="Hangfire.Storage.SQLite" Version="0.3.4" /> <PackageReference Include="Hangfire.Storage.SQLite" Version="0.3.4" />
<PackageReference Include="HtmlAgilityPack" Version="1.11.50" /> <PackageReference Include="HtmlAgilityPack" Version="1.11.51" />
<PackageReference Include="MarkdownDeep.NET.Core" Version="1.5.0.4" /> <PackageReference Include="MarkdownDeep.NET.Core" Version="1.5.0.4" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="7.0.9" /> <PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="7.0.10" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.OpenIdConnect" Version="7.0.9" /> <PackageReference Include="Microsoft.AspNetCore.Authentication.OpenIdConnect" Version="7.0.10" />
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="7.0.9" /> <PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="7.0.10" />
<PackageReference Include="Microsoft.AspNetCore.SignalR" Version="1.1.0" /> <PackageReference Include="Microsoft.AspNetCore.SignalR" Version="1.1.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="7.0.9"> <PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="7.0.10">
<PrivateAssets>all</PrivateAssets> <PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference> </PackageReference>
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="7.0.9" /> <PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="7.0.10" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="7.0.0" /> <PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="7.0.0" />
<PackageReference Include="Microsoft.IO.RecyclableMemoryStream" Version="2.3.2" /> <PackageReference Include="Microsoft.IO.RecyclableMemoryStream" Version="2.3.2" />
<PackageReference Include="MimeTypeMapOfficial" Version="1.0.17" /> <PackageReference Include="MimeTypeMapOfficial" Version="1.0.17" />
@ -95,14 +95,14 @@
<PackageReference Include="Serilog.Sinks.SignalR.Core" Version="0.1.2" /> <PackageReference Include="Serilog.Sinks.SignalR.Core" Version="0.1.2" />
<PackageReference Include="SharpCompress" Version="0.33.0" /> <PackageReference Include="SharpCompress" Version="0.33.0" />
<PackageReference Include="SixLabors.ImageSharp" Version="3.0.1" /> <PackageReference Include="SixLabors.ImageSharp" Version="3.0.1" />
<PackageReference Include="SonarAnalyzer.CSharp" Version="9.5.0.73987"> <PackageReference Include="SonarAnalyzer.CSharp" Version="9.7.0.75501">
<PrivateAssets>all</PrivateAssets> <PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference> </PackageReference>
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.5.0" /> <PackageReference Include="Swashbuckle.AspNetCore" Version="6.5.0" />
<PackageReference Include="Swashbuckle.AspNetCore.Filters" Version="7.0.8" /> <PackageReference Include="Swashbuckle.AspNetCore.Filters" Version="7.0.8" />
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="6.32.0" /> <PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="6.32.1" />
<PackageReference Include="System.IO.Abstractions" Version="19.2.29" /> <PackageReference Include="System.IO.Abstractions" Version="19.2.51" />
<PackageReference Include="System.Drawing.Common" Version="7.0.0" /> <PackageReference Include="System.Drawing.Common" Version="7.0.0" />
<PackageReference Include="VersOne.Epub" Version="3.3.1" /> <PackageReference Include="VersOne.Epub" Version="3.3.1" />
</ItemGroup> </ItemGroup>

View File

@ -177,14 +177,27 @@ public class AccountController : BaseApiController
[HttpPost("login")] [HttpPost("login")]
public async Task<ActionResult<UserDto>> Login(LoginDto loginDto) public async Task<ActionResult<UserDto>> Login(LoginDto loginDto)
{ {
var user = await _userManager.Users AppUser? user;
if (!string.IsNullOrEmpty(loginDto.ApiKey))
{
user = await _userManager.Users
.Include(u => u.UserPreferences)
.SingleOrDefaultAsync(x => x.ApiKey == loginDto.ApiKey);
}
else
{
user = await _userManager.Users
.Include(u => u.UserPreferences) .Include(u => u.UserPreferences)
.SingleOrDefaultAsync(x => x.NormalizedUserName == loginDto.Username.ToUpper()); .SingleOrDefaultAsync(x => x.NormalizedUserName == loginDto.Username.ToUpper());
}
if (user == null) return Unauthorized(await _localizationService.Get("en", "bad-credentials")); if (user == null) return Unauthorized(await _localizationService.Get("en", "bad-credentials"));
var roles = await _userManager.GetRolesAsync(user); var roles = await _userManager.GetRolesAsync(user);
if (!roles.Contains(PolicyConstants.LoginRole)) return Unauthorized(await _localizationService.Translate(user.Id, "disabled-account")); if (!roles.Contains(PolicyConstants.LoginRole)) return Unauthorized(await _localizationService.Translate(user.Id, "disabled-account"));
if (string.IsNullOrEmpty(loginDto.ApiKey))
{
var result = await _signInManager var result = await _signInManager
.CheckPasswordSignInAsync(user, loginDto.Password, true); .CheckPasswordSignInAsync(user, loginDto.Password, true);
@ -198,6 +211,7 @@ public class AccountController : BaseApiController
{ {
return Unauthorized(await _localizationService.Translate(user.Id, result.IsNotAllowed ? "confirm-email" : "bad-credentials")); return Unauthorized(await _localizationService.Translate(user.Id, result.IsNotAllowed ? "confirm-email" : "bad-credentials"));
} }
}
// Update LastActive on account // Update LastActive on account
user.UpdateLastActive(); user.UpdateLastActive();

View File

@ -24,7 +24,9 @@ public class LocaleController : BaseApiController
{ {
Title = c.DisplayName, Title = c.DisplayName,
IsoCode = c.IetfLanguageTag IsoCode = c.IetfLanguageTag
}).Where(l => !string.IsNullOrEmpty(l.IsoCode)); })
.Where(l => !string.IsNullOrEmpty(l.IsoCode))
.OrderBy(d => d.Title);
return Ok(languages); return Ok(languages);
} }
} }

View File

@ -4,4 +4,8 @@ public class LoginDto
{ {
public string Username { get; init; } = default!; public string Username { get; init; } = default!;
public string Password { get; set; } = default!; public string Password { get; set; } = default!;
/// <summary>
/// If ApiKey is passed, will ignore username/password for validation
/// </summary>
public string? ApiKey { get; set; } = default!;
} }

View File

@ -14,7 +14,7 @@
<PackageReference Include="Flurl.Http" Version="3.2.4" /> <PackageReference Include="Flurl.Http" Version="3.2.4" />
<PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="7.0.0" /> <PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="7.0.0" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="7.0.1" /> <PackageReference Include="Microsoft.Extensions.Hosting" Version="7.0.1" />
<PackageReference Include="SonarAnalyzer.CSharp" Version="9.5.0.73987"> <PackageReference Include="SonarAnalyzer.CSharp" Version="9.7.0.75501">
<PrivateAssets>all</PrivateAssets> <PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference> </PackageReference>

View File

@ -17,8 +17,10 @@ your reading collection with your friends and family!
<a href="https://hosted.weblate.org/engage/kavita/"> <a href="https://hosted.weblate.org/engage/kavita/">
<img src="https://hosted.weblate.org/widgets/kavita/-/ui/svg-badge.svg" alt="Translation status" /> <img src="https://hosted.weblate.org/widgets/kavita/-/ui/svg-badge.svg" alt="Translation status" />
</a> </a>
<img src="https://img.shields.io/endpoint?url=https://stats.kavitareader.com/api/ui/shield-badge"/>
</div> </div>
## What Kavita Provides ## What Kavita Provides
- Serve up Manga/Webtoons/Comics (cbr, cbz, zip/rar/rar5, 7zip, raw images) and Books (epub, pdf) - Serve up Manga/Webtoons/Comics (cbr, cbz, zip/rar/rar5, 7zip, raw images) and Books (epub, pdf)
- First class responsive readers that work great on any device (phone, tablet, desktop) - First class responsive readers that work great on any device (phone, tablet, desktop)

View File

@ -21,8 +21,8 @@
"@fortawesome/fontawesome-free": "^6.4.2", "@fortawesome/fontawesome-free": "^6.4.2",
"@iharbeck/ngx-virtual-scroller": "^16.0.0", "@iharbeck/ngx-virtual-scroller": "^16.0.0",
"@iplab/ngx-file-upload": "^16.0.1", "@iplab/ngx-file-upload": "^16.0.1",
"@microsoft/signalr": "^7.0.9", "@microsoft/signalr": "^7.0.10",
"@ng-bootstrap/ng-bootstrap": "^15.1.0", "@ng-bootstrap/ng-bootstrap": "^15.1.1",
"@ngneat/transloco": "^5.0.6", "@ngneat/transloco": "^5.0.6",
"@ngneat/transloco-locale": "^5.1.1", "@ngneat/transloco-locale": "^5.1.1",
"@ngneat/transloco-persist-lang": "^5.0.0", "@ngneat/transloco-persist-lang": "^5.0.0",
@ -3141,9 +3141,9 @@
"dev": true "dev": true
}, },
"node_modules/@microsoft/signalr": { "node_modules/@microsoft/signalr": {
"version": "7.0.9", "version": "7.0.10",
"resolved": "https://registry.npmjs.org/@microsoft/signalr/-/signalr-7.0.9.tgz", "resolved": "https://registry.npmjs.org/@microsoft/signalr/-/signalr-7.0.10.tgz",
"integrity": "sha512-aGfBLAYTh+6ydYvLXV/jcocWr8KKmTOgWyl/mDx5Hzrii1aAfrn+bpBNzrl5sto5ehsHCdTIzTCuOCT3baIjOw==", "integrity": "sha512-tOEn32i5EatAx4sZbzmLgcBc2VbKQmx+F4rI2/Ioq2MnBaYcFxbDzOoZgISIS4IR9H1ij/sKoU8zQOAFC8GJKg==",
"dependencies": { "dependencies": {
"abort-controller": "^3.0.0", "abort-controller": "^3.0.0",
"eventsource": "^2.0.2", "eventsource": "^2.0.2",
@ -3153,9 +3153,9 @@
} }
}, },
"node_modules/@ng-bootstrap/ng-bootstrap": { "node_modules/@ng-bootstrap/ng-bootstrap": {
"version": "15.1.0", "version": "15.1.1",
"resolved": "https://registry.npmjs.org/@ng-bootstrap/ng-bootstrap/-/ng-bootstrap-15.1.0.tgz", "resolved": "https://registry.npmjs.org/@ng-bootstrap/ng-bootstrap/-/ng-bootstrap-15.1.1.tgz",
"integrity": "sha512-4Z/sXYcAq22D15jtlnZV7qztuSnlSlOgO7EVp6rJ8dyGi3CPzX9PqMfetoM6K5sKQTiSW8IfsbdXCWN7rnzxWQ==", "integrity": "sha512-nZlIMMggtI3IHkGs0XPrUIUdpeEzQvfGV9M4I9IvCqiS2n4RwWoUvWK1ICo4csZqFNBDlCQx956gO6ZZUSL2mw==",
"dependencies": { "dependencies": {
"tslib": "^2.3.0" "tslib": "^2.3.0"
}, },

View File

@ -26,8 +26,8 @@
"@fortawesome/fontawesome-free": "^6.4.2", "@fortawesome/fontawesome-free": "^6.4.2",
"@iharbeck/ngx-virtual-scroller": "^16.0.0", "@iharbeck/ngx-virtual-scroller": "^16.0.0",
"@iplab/ngx-file-upload": "^16.0.1", "@iplab/ngx-file-upload": "^16.0.1",
"@microsoft/signalr": "^7.0.9", "@microsoft/signalr": "^7.0.10",
"@ng-bootstrap/ng-bootstrap": "^15.1.0", "@ng-bootstrap/ng-bootstrap": "^15.1.1",
"@ngneat/transloco": "^5.0.6", "@ngneat/transloco": "^5.0.6",
"@ngneat/transloco-locale": "^5.1.1", "@ngneat/transloco-locale": "^5.1.1",
"@ngneat/transloco-persist-lang": "^5.0.0", "@ngneat/transloco-persist-lang": "^5.0.0",

View File

@ -50,14 +50,6 @@ export class AppComponent implements OnInit {
if (!user) return false; if (!user) return false;
return user.preferences.noTransitions; return user.preferences.noTransitions;
}), takeUntilDestroyed(this.destroyRef)); }), takeUntilDestroyed(this.destroyRef));
this.translocoService.events$.subscribe(event => {
if (event.type === 'translationLoadSuccess') {
console.log('Language has fully loaded!', translate('login.title'));
}
console.log('language event: ', event.type, translate('login.title'));
});
} }
@HostListener('window:resize', ['$event']) @HostListener('window:resize', ['$event'])

View File

@ -19,7 +19,7 @@
height="100vh" height="100vh"
[(page)]="currentPage" [(page)]="currentPage"
[textLayer]="true" [textLayer]="true"
[useBrowserLocale]="false" [useBrowserLocale]="true"
[showHandToolButton]="true" [showHandToolButton]="true"
[showOpenFileButton]="false" [showOpenFileButton]="false"
[showPrintButton]="false" [showPrintButton]="false"
@ -30,7 +30,6 @@
[showSecondaryToolbarButton]="true" [showSecondaryToolbarButton]="true"
[showBorders]="true" [showBorders]="true"
[theme]="theme" [theme]="theme"
[formTheme]="theme"
[backgroundColor]="backgroundColor" [backgroundColor]="backgroundColor"
[customToolbar]="multiToolbar" [customToolbar]="multiToolbar"
[language]="user.preferences.locale" [language]="user.preferences.locale"

View File

@ -1,6 +1,6 @@
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, OnInit } from '@angular/core'; import {AfterViewInit, ChangeDetectionStrategy, ChangeDetectorRef, Component, OnInit} from '@angular/core';
import { FormGroup, FormControl, Validators, ReactiveFormsModule } from '@angular/forms'; import { FormGroup, FormControl, Validators, ReactiveFormsModule } from '@angular/forms';
import { Router, RouterLink } from '@angular/router'; import {ActivatedRoute, Router, RouterLink} from '@angular/router';
import { NgbModal } from '@ng-bootstrap/ng-bootstrap'; import { NgbModal } from '@ng-bootstrap/ng-bootstrap';
import { ToastrService } from 'ngx-toastr'; import { ToastrService } from 'ngx-toastr';
import { take } from 'rxjs/operators'; import { take } from 'rxjs/operators';
@ -18,17 +18,10 @@ import {TRANSLOCO_SCOPE, TranslocoDirective} from "@ngneat/transloco";
styleUrls: ['./user-login.component.scss'], styleUrls: ['./user-login.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush, changeDetection: ChangeDetectionStrategy.OnPush,
standalone: true, standalone: true,
imports: [SplashContainerComponent, NgIf, ReactiveFormsModule, RouterLink, TranslocoDirective], imports: [SplashContainerComponent, NgIf, ReactiveFormsModule, RouterLink, TranslocoDirective]
providers: [
{
provide: TRANSLOCO_SCOPE,
useValue: 'login'
}
]
}) })
export class UserLoginComponent implements OnInit { export class UserLoginComponent implements OnInit {
//model: any = {username: '', password: ''};
loginForm: FormGroup = new FormGroup({ loginForm: FormGroup = new FormGroup({
username: new FormControl('', [Validators.required]), username: new FormControl('', [Validators.required]),
password: new FormControl('', [Validators.required, Validators.maxLength(32), Validators.minLength(6), Validators.pattern("^.{6,32}$")]) password: new FormControl('', [Validators.required, Validators.maxLength(32), Validators.minLength(6), Validators.pattern("^.{6,32}$")])
@ -45,8 +38,8 @@ export class UserLoginComponent implements OnInit {
isSubmitting = false; isSubmitting = false;
constructor(private accountService: AccountService, private router: Router, private memberService: MemberService, constructor(private accountService: AccountService, private router: Router, private memberService: MemberService,
private toastr: ToastrService, private navService: NavService, private modalService: NgbModal, private toastr: ToastrService, private navService: NavService,
private readonly cdRef: ChangeDetectorRef) { private readonly cdRef: ChangeDetectorRef, private route: ActivatedRoute) {
this.navService.showNavBar(); this.navService.showNavBar();
this.navService.hideSideNav(); this.navService.hideSideNav();
} }
@ -76,11 +69,21 @@ export class UserLoginComponent implements OnInit {
this.cdRef.markForCheck(); this.cdRef.markForCheck();
}); });
this.route.queryParamMap.subscribe(params => {
const val = params.get('apiKey');
console.log('key: ', val);
if (val != null && val.length > 0) {
this.login(val);
}
});
} }
login() {
login(apiKey: string = '') {
const model = this.loginForm.getRawValue(); const model = this.loginForm.getRawValue();
model.apiKey = apiKey;
this.isSubmitting = true; this.isSubmitting = true;
this.cdRef.markForCheck(); this.cdRef.markForCheck();
this.accountService.login(model).subscribe(() => { this.accountService.login(model).subscribe(() => {

View File

@ -1,7 +1,6 @@
import {Injectable} from "@angular/core"; import {Injectable} from "@angular/core";
import {HttpClient} from "@angular/common/http"; import {HttpClient} from "@angular/common/http";
import {Translation, TranslocoLoader} from "@ngneat/transloco"; import {Translation, TranslocoLoader} from "@ngneat/transloco";
import {tap} from "rxjs/operators";
@Injectable({ providedIn: 'root' }) @Injectable({ providedIn: 'root' })
@ -10,7 +9,6 @@ export class HttpLoader implements TranslocoLoader {
getTranslation(langPath: string) { getTranslation(langPath: string) {
const tokens = langPath.split('/'); const tokens = langPath.split('/');
return this.http.get<Translation>(`assets/langs/${tokens[tokens.length - 1]}.json`) return this.http.get<Translation>(`assets/langs/${tokens[tokens.length - 1]}.json`);
.pipe(tap(d => console.log('translations: ', d)));
} }
} }

View File

@ -34,14 +34,12 @@ export function preloadUser(userService: AccountService, transloco: TranslocoSer
return function() { return function() {
return userService.currentUser$.pipe(switchMap((user) => { return userService.currentUser$.pipe(switchMap((user) => {
if (user && user.preferences.locale) { if (user && user.preferences.locale) {
console.log('preloaded locale: ', user.preferences.locale)
transloco.setActiveLang(user.preferences.locale); transloco.setActiveLang(user.preferences.locale);
return transloco.load(user.preferences.locale) return transloco.load(user.preferences.locale)
} }
// If no user or locale is available, fallback to the default language ('en') // If no user or locale is available, fallback to the default language ('en')
const localStorageLocale = localStorage.getItem(AccountService.localeKey) || 'en'; const localStorageLocale = localStorage.getItem(AccountService.localeKey) || 'en';
console.log('preloaded locale: ', localStorageLocale)
transloco.setActiveLang(localStorageLocale); transloco.setActiveLang(localStorageLocale);
return transloco.load(localStorageLocale) return transloco.load(localStorageLocale)
})).subscribe(); })).subscribe();

View File

@ -7,7 +7,7 @@
"name": "GPL-3.0", "name": "GPL-3.0",
"url": "https://github.com/Kareadita/Kavita/blob/develop/LICENSE" "url": "https://github.com/Kareadita/Kavita/blob/develop/LICENSE"
}, },
"version": "0.7.6.11" "version": "0.7.6.13"
}, },
"servers": [ "servers": [
{ {
@ -13625,6 +13625,11 @@
"password": { "password": {
"type": "string", "type": "string",
"nullable": true "nullable": true
},
"apiKey": {
"type": "string",
"description": "If ApiKey is passed, will ignore username/password for validation",
"nullable": true
} }
}, },
"additionalProperties": false "additionalProperties": false