diff --git a/API/Constants/ResponseCacheProfiles.cs b/API/Constants/ResponseCacheProfiles.cs
index 1a092d84e..d7dcaf95b 100644
--- a/API/Constants/ResponseCacheProfiles.cs
+++ b/API/Constants/ResponseCacheProfiles.cs
@@ -16,5 +16,5 @@ public static class ResponseCacheProfiles
public const string Instant = "Instant";
public const string Month = "Month";
public const string LicenseCache = "LicenseCache";
- public const string Recommendation = "Recommendation";
+ public const string KavitaPlus = "KavitaPlus";
}
diff --git a/API/Controllers/LicenseController.cs b/API/Controllers/LicenseController.cs
index b00f6d07f..e0280f78c 100644
--- a/API/Controllers/LicenseController.cs
+++ b/API/Controllers/LicenseController.cs
@@ -65,7 +65,7 @@ public class LicenseController : BaseApiController
}
///
- /// Updates server license. Returns true if updated and valid
+ /// Updates server license
///
/// Caches the result
///
diff --git a/API/Controllers/RatingController.cs b/API/Controllers/RatingController.cs
index accd6ccaa..4b816bab7 100644
--- a/API/Controllers/RatingController.cs
+++ b/API/Controllers/RatingController.cs
@@ -1,7 +1,9 @@
using System;
using System.Collections.Generic;
+using System.Linq;
using System.Threading.Tasks;
using API.Constants;
+using API.Data;
using API.DTOs;
using API.Services.Plus;
using EasyCaching.Core;
@@ -18,15 +20,17 @@ public class RatingController : BaseApiController
private readonly ILicenseService _licenseService;
private readonly IRatingService _ratingService;
private readonly ILogger _logger;
+ private readonly IUnitOfWork _unitOfWork;
private readonly IEasyCachingProvider _cacheProvider;
public const string CacheKey = "rating_";
public RatingController(ILicenseService licenseService, IRatingService ratingService,
- ILogger logger, IEasyCachingProviderFactory cachingProviderFactory)
+ ILogger logger, IEasyCachingProviderFactory cachingProviderFactory, IUnitOfWork unitOfWork)
{
_licenseService = licenseService;
_ratingService = ratingService;
_logger = logger;
+ _unitOfWork = unitOfWork;
_cacheProvider = cachingProviderFactory.GetCachingProvider(EasyCacheProfiles.KavitaPlusRatings);
}
@@ -37,12 +41,13 @@ public class RatingController : BaseApiController
///
///
[HttpGet]
- [ResponseCache(CacheProfileName = ResponseCacheProfiles.Recommendation, VaryByQueryKeys = new []{"seriesId"})]
+ [ResponseCache(CacheProfileName = ResponseCacheProfiles.KavitaPlus, VaryByQueryKeys = new []{"seriesId"})]
public async Task>> GetRating(int seriesId)
{
+
if (!await _licenseService.HasActiveLicense())
{
- return Ok(new List());
+ return Ok(Enumerable.Empty());
}
var cacheKey = CacheKey + seriesId;
@@ -56,6 +61,16 @@ public class RatingController : BaseApiController
await _cacheProvider.SetAsync(cacheKey, ratings, TimeSpan.FromHours(24));
_logger.LogDebug("Caching external rating for {Key}", cacheKey);
return Ok(ratings);
+ }
+ [HttpGet("overall")]
+ public async Task> GetOverallRating(int seriesId)
+ {
+ return Ok(new RatingDto()
+ {
+ Provider = ScrobbleProvider.Kavita,
+ AverageScore = await _unitOfWork.SeriesRepository.GetAverageUserRating(seriesId),
+ FavoriteCount = 0
+ });
}
}
diff --git a/API/Controllers/RecommendedController.cs b/API/Controllers/RecommendedController.cs
index 14c9b7bfc..efadb6d60 100644
--- a/API/Controllers/RecommendedController.cs
+++ b/API/Controllers/RecommendedController.cs
@@ -39,7 +39,7 @@ public class RecommendedController : BaseApiController
///
///
[HttpGet("recommendations")]
- [ResponseCache(CacheProfileName = ResponseCacheProfiles.Recommendation, VaryByQueryKeys = new []{"seriesId"})]
+ [ResponseCache(CacheProfileName = ResponseCacheProfiles.KavitaPlus, VaryByQueryKeys = new []{"seriesId"})]
public async Task> GetRecommendations(int seriesId)
{
var userId = User.GetUserId();
diff --git a/API/Controllers/ReviewController.cs b/API/Controllers/ReviewController.cs
index 938e5fc77..27508f1ce 100644
--- a/API/Controllers/ReviewController.cs
+++ b/API/Controllers/ReviewController.cs
@@ -51,7 +51,7 @@ public class ReviewController : BaseApiController
///
///
[HttpGet]
- [ResponseCache(CacheProfileName = ResponseCacheProfiles.Recommendation, VaryByQueryKeys = new []{"seriesId"})]
+ [ResponseCache(CacheProfileName = ResponseCacheProfiles.KavitaPlus, VaryByQueryKeys = new []{"seriesId"})]
public async Task>> GetReviews(int seriesId)
{
var userId = User.GetUserId();
diff --git a/API/Controllers/ServerController.cs b/API/Controllers/ServerController.cs
index 03b8689f8..22b871529 100644
--- a/API/Controllers/ServerController.cs
+++ b/API/Controllers/ServerController.cs
@@ -241,7 +241,7 @@ public class ServerController : BaseApiController
///
- /// Bust Review and Recommendation Cache
+ /// Bust Kavita+ Cache
///
///
[Authorize("RequireAdminRole")]
@@ -250,12 +250,12 @@ public class ServerController : BaseApiController
{
_logger.LogInformation("Busting Kavita+ Cache");
var provider = _cachingProviderFactory.GetCachingProvider(EasyCacheProfiles.KavitaPlusReviews);
- await provider.FlushAsync();
- provider = _cachingProviderFactory.GetCachingProvider(EasyCacheProfiles.KavitaPlusRecommendations);
- await provider.FlushAsync();
- provider = _cachingProviderFactory.GetCachingProvider(EasyCacheProfiles.KavitaPlusRatings);
- await provider.FlushAsync();
- return Ok();
+ await provider.FlushAsync();
+ provider = _cachingProviderFactory.GetCachingProvider(EasyCacheProfiles.KavitaPlusRecommendations);
+ await provider.FlushAsync();
+ provider = _cachingProviderFactory.GetCachingProvider(EasyCacheProfiles.KavitaPlusRatings);
+ await provider.FlushAsync();
+ return Ok();
}
diff --git a/API/DTOs/SeriesDetail/UserReviewDto.cs b/API/DTOs/SeriesDetail/UserReviewDto.cs
index f4f94ebd7..4f74dadbb 100644
--- a/API/DTOs/SeriesDetail/UserReviewDto.cs
+++ b/API/DTOs/SeriesDetail/UserReviewDto.cs
@@ -1,4 +1,6 @@
-namespace API.DTOs.SeriesDetail;
+using API.Services.Plus;
+
+namespace API.DTOs.SeriesDetail;
///
/// Represents a User Review for a given Series
@@ -48,4 +50,9 @@ public class UserReviewDto
/// The main body with just text, for review preview
///
public string? BodyJustText { get; set; }
+
+ ///
+ /// If this review is External, which Provider did it come from
+ ///
+ public ScrobbleProvider Provider { get; set; } = ScrobbleProvider.Kavita;
}
diff --git a/API/Data/Repositories/SeriesRepository.cs b/API/Data/Repositories/SeriesRepository.cs
index 80b00a8c5..dfa85dcad 100644
--- a/API/Data/Repositories/SeriesRepository.cs
+++ b/API/Data/Repositories/SeriesRepository.cs
@@ -135,8 +135,8 @@ public interface ISeriesRepository
Task> GetLibraryIdsForSeriesAsync();
Task> GetSeriesMetadataForIds(IEnumerable seriesIds);
Task> GetAllWithCoversInDifferentEncoding(EncodeFormat encodeFormat, bool customOnly = true);
-
Task GetSeriesDtoByNamesAndMetadataIdsForUser(int userId, IEnumerable names, LibraryType libraryType, string aniListUrl, string malUrl);
+ Task GetAverageUserRating(int seriesId);
}
public class SeriesRepository : ISeriesRepository
@@ -1658,6 +1658,18 @@ public class SeriesRepository : ISeriesRepository
.FirstOrDefaultAsync(); // Some users may have improperly configured libraries
}
+ ///
+ /// Returns the Average rating for all users within Kavita instance
+ ///
+ ///
+ public async Task GetAverageUserRating(int seriesId)
+ {
+ var avg = (await _context.AppUserRating
+ .Where(r => r.SeriesId == seriesId)
+ .AverageAsync(r => (int?) r.Rating));
+ return avg.HasValue ? (int) avg.Value : 0;
+ }
+
public async Task IsSeriesInWantToRead(int userId, int seriesId)
{
var libraryIds = await _context.Library.GetUserLibraries(userId).ToListAsync();
diff --git a/API/Data/Seed.cs b/API/Data/Seed.cs
index d903496ae..93c01d6ed 100644
--- a/API/Data/Seed.cs
+++ b/API/Data/Seed.cs
@@ -133,6 +133,8 @@ public static class Seed
directoryService.CacheDirectory + string.Empty;
context.ServerSetting.First(s => s.Key == ServerSettingKey.BackupDirectory).Value =
DirectoryService.BackupDirectory + string.Empty;
+ context.ServerSetting.First(s => s.Key == ServerSettingKey.CacheSize).Value =
+ Configuration.CacheSize + string.Empty;
await context.SaveChangesAsync();
}
diff --git a/API/Services/Plus/LicenseService.cs b/API/Services/Plus/LicenseService.cs
index ddd67791e..0a2b25cea 100644
--- a/API/Services/Plus/LicenseService.cs
+++ b/API/Services/Plus/LicenseService.cs
@@ -130,11 +130,13 @@ public class LicenseService : ILicenseService
{
try
{
+ var license = await _unitOfWork.SettingsRepository.GetSettingAsync(ServerSettingKey.LicenseKey);
+ if (string.IsNullOrEmpty(license.Value)) return;
+
_logger.LogInformation("Validating Kavita+ License");
var provider = _cachingProviderFactory.GetCachingProvider(EasyCacheProfiles.License);
await provider.FlushAsync();
- var license = await _unitOfWork.SettingsRepository.GetSettingAsync(ServerSettingKey.LicenseKey);
var isValid = await IsLicenseValid(license.Value);
await provider.SetAsync(CacheKey, isValid, _licenseCacheTimeout);
diff --git a/API/Services/Plus/ScrobblingService.cs b/API/Services/Plus/ScrobblingService.cs
index 61ab9d688..1d1829c3b 100644
--- a/API/Services/Plus/ScrobblingService.cs
+++ b/API/Services/Plus/ScrobblingService.cs
@@ -22,9 +22,17 @@ using Microsoft.Extensions.Logging;
namespace API.Services.Plus;
+///
+/// Misleading name but is the source of data (like a review coming from AniList)
+///
public enum ScrobbleProvider
{
- AniList = 1
+ ///
+ /// For now, this means data comes from within this instance of Kavita
+ ///
+ Kavita = 0,
+ AniList = 1,
+ Mal = 2,
}
public interface IScrobblingService
diff --git a/API/Services/ReviewService.cs b/API/Services/ReviewService.cs
index 597e7bbe9..a0f4d18f5 100644
--- a/API/Services/ReviewService.cs
+++ b/API/Services/ReviewService.cs
@@ -35,6 +35,7 @@ internal class MediaReviewDto
///
public string RawBody { get; set; }
public string Username { get; set; }
+ public ScrobbleProvider Provider { get; set; }
}
public interface IReviewService
@@ -74,6 +75,7 @@ public class ReviewService : IReviewService
LibraryId = series.LibraryId,
SeriesId = series.Id,
IsExternal = true,
+ Provider = r.Provider,
BodyJustText = GetCharacters(r.Body),
ExternalUrl = r.SiteUrl
});
diff --git a/API/Startup.cs b/API/Startup.cs
index 90a104158..64f2a3f73 100644
--- a/API/Startup.cs
+++ b/API/Startup.cs
@@ -116,7 +116,7 @@ public class Startup
Location = ResponseCacheLocation.Client,
NoStore = false
});
- options.CacheProfiles.Add(ResponseCacheProfiles.Recommendation,
+ options.CacheProfiles.Add(ResponseCacheProfiles.KavitaPlus,
new CacheProfile()
{
Duration = TimeSpan.FromDays(30).Seconds,
diff --git a/Kavita.Common/HashUtil.cs b/Kavita.Common/HashUtil.cs
index d3757085d..aace6bd13 100644
--- a/Kavita.Common/HashUtil.cs
+++ b/Kavita.Common/HashUtil.cs
@@ -51,9 +51,7 @@ public static class HashUtil
.AddComponent("ProcessorCount", new DeviceIdComponent($"{Environment.ProcessorCount}"))
.AddComponent("OSPlatform", new DeviceIdComponent($"{Environment.OSVersion.Platform}"))
.OnWindows(windows => windows
- .AddSystemUuid()
- .AddMotherboardSerialNumber()
- .AddSystemDriveSerialNumber())
+ .AddProcessorId())
.OnLinux(linux =>
{
var osInfo = RunAndCapture("uname", "-a");
diff --git a/UI/Web/src/app/_services/scrobbling.service.ts b/UI/Web/src/app/_services/scrobbling.service.ts
index adb974467..e815410f7 100644
--- a/UI/Web/src/app/_services/scrobbling.service.ts
+++ b/UI/Web/src/app/_services/scrobbling.service.ts
@@ -24,8 +24,9 @@ import {UtilityService} from "../shared/_services/utility.service";
import {ReadingList} from "../_models/reading-list";
export enum ScrobbleProvider {
+ Kavita = 0,
AniList= 1,
- Mal = 2
+ Mal = 2,
}
@Injectable({
diff --git a/UI/Web/src/app/_services/series.service.ts b/UI/Web/src/app/_services/series.service.ts
index 3b95e0fa8..b7359a8f6 100644
--- a/UI/Web/src/app/_services/series.service.ts
+++ b/UI/Web/src/app/_services/series.service.ts
@@ -32,12 +32,12 @@ export class SeriesService {
paginatedSeriesForTagsResults: PaginatedResult = new PaginatedResult();
constructor(private httpClient: HttpClient, private imageService: ImageService,
- private utilityService: UtilityService, private filterUtilitySerivce: FilterUtilitiesService) { }
+ private utilityService: UtilityService, private filterUtilityService: FilterUtilitiesService) { }
getAllSeries(pageNum?: number, itemsPerPage?: number, filter?: SeriesFilter) {
let params = new HttpParams();
params = this.utilityService.addPaginationIfExists(params, pageNum, itemsPerPage);
- const data = this.filterUtilitySerivce.createSeriesFilter(filter);
+ const data = this.filterUtilityService.createSeriesFilter(filter);
return this.httpClient.post>(this.baseUrl + 'series/all', data, {observe: 'response', params}).pipe(
map((response: any) => {
@@ -49,7 +49,7 @@ export class SeriesService {
getSeriesForLibrary(libraryId: number, pageNum?: number, itemsPerPage?: number, filter?: SeriesFilter) {
let params = new HttpParams();
params = this.utilityService.addPaginationIfExists(params, pageNum, itemsPerPage);
- const data = this.filterUtilitySerivce.createSeriesFilter(filter);
+ const data = this.filterUtilityService.createSeriesFilter(filter);
return this.httpClient.post>(this.baseUrl + 'series?libraryId=' + libraryId, data, {observe: 'response', params}).pipe(
map((response: any) => {
@@ -103,7 +103,7 @@ export class SeriesService {
}
getRecentlyAdded(libraryId: number = 0, pageNum?: number, itemsPerPage?: number, filter?: SeriesFilter) {
- const data = this.filterUtilitySerivce.createSeriesFilter(filter);
+ const data = this.filterUtilityService.createSeriesFilter(filter);
let params = new HttpParams();
params = this.utilityService.addPaginationIfExists(params, pageNum, itemsPerPage);
@@ -119,7 +119,7 @@ export class SeriesService {
}
getWantToRead(pageNum?: number, itemsPerPage?: number, filter?: SeriesFilter): Observable> {
- const data = this.filterUtilitySerivce.createSeriesFilter(filter);
+ const data = this.filterUtilityService.createSeriesFilter(filter);
let params = new HttpParams();
params = this.utilityService.addPaginationIfExists(params, pageNum, itemsPerPage);
@@ -138,7 +138,7 @@ export class SeriesService {
}
getOnDeck(libraryId: number = 0, pageNum?: number, itemsPerPage?: number, filter?: SeriesFilter) {
- const data = this.filterUtilitySerivce.createSeriesFilter(filter);
+ const data = this.filterUtilityService.createSeriesFilter(filter);
let params = new HttpParams();
params = this.utilityService.addPaginationIfExists(params, pageNum, itemsPerPage);
@@ -223,4 +223,7 @@ export class SeriesService {
getRatings(seriesId: number) {
return this.httpClient.get>(this.baseUrl + 'rating?seriesId=' + seriesId);
}
+ getOverallRating(seriesId: number) {
+ return this.httpClient.get(this.baseUrl + 'rating/overall?seriesId=' + seriesId);
+ }
}
diff --git a/UI/Web/src/app/_single-module/review-card/review-card.component.html b/UI/Web/src/app/_single-module/review-card/review-card.component.html
index 46360a1a6..5e912aba8 100644
--- a/UI/Web/src/app/_single-module/review-card/review-card.component.html
+++ b/UI/Web/src/app/_single-module/review-card/review-card.component.html
@@ -19,9 +19,15 @@
-
+
diff --git a/UI/Web/src/app/_single-module/review-card/review-card.component.scss b/UI/Web/src/app/_single-module/review-card/review-card.component.scss
index f1794eba6..62bf3e443 100644
--- a/UI/Web/src/app/_single-module/review-card/review-card.component.scss
+++ b/UI/Web/src/app/_single-module/review-card/review-card.component.scss
@@ -8,7 +8,10 @@
z-index: 20;
top: 38px;
left: 38px;
- color: var(--review-card-star-color);
+}
+
+.fa-star {
+ color: var(--review-card-star-color);
}
.card-text {
@@ -29,10 +32,6 @@
overflow: hidden;
}
-.card-footer {
- width: 288px;
-}
-
.card {
cursor: pointer;
}
diff --git a/UI/Web/src/app/_single-module/review-card/review-card.component.ts b/UI/Web/src/app/_single-module/review-card/review-card.component.ts
index 13811735f..154f0cd72 100644
--- a/UI/Web/src/app/_single-module/review-card/review-card.component.ts
+++ b/UI/Web/src/app/_single-module/review-card/review-card.component.ts
@@ -1,5 +1,5 @@
import {ChangeDetectionStrategy, ChangeDetectorRef, Component, inject, Input, OnInit} from '@angular/core';
-import {CommonModule} from '@angular/common';
+import {CommonModule, NgOptimizedImage} from '@angular/common';
import {UserReview} from "./user-review";
import {NgbModal} from "@ng-bootstrap/ng-bootstrap";
import {ReviewCardModalComponent} from "../review-card-modal/review-card-modal.component";
@@ -7,11 +7,13 @@ import {AccountService} from "../../_services/account.service";
import {ReviewSeriesModalComponent} from "../review-series-modal/review-series-modal.component";
import {ReadMoreComponent} from "../../shared/read-more/read-more.component";
import {DefaultValuePipe} from "../../pipe/default-value.pipe";
+import {ImageComponent} from "../../shared/image/image.component";
+import {ProviderImagePipe} from "../../pipe/provider-image.pipe";
@Component({
selector: 'app-review-card',
standalone: true,
- imports: [CommonModule, ReadMoreComponent, DefaultValuePipe],
+ imports: [CommonModule, ReadMoreComponent, DefaultValuePipe, ImageComponent, NgOptimizedImage, ProviderImagePipe],
templateUrl: './review-card.component.html',
styleUrls: ['./review-card.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush
diff --git a/UI/Web/src/app/_single-module/review-card/user-review.ts b/UI/Web/src/app/_single-module/review-card/user-review.ts
index 1e0371fc8..f735d9548 100644
--- a/UI/Web/src/app/_single-module/review-card/user-review.ts
+++ b/UI/Web/src/app/_single-module/review-card/user-review.ts
@@ -1,3 +1,5 @@
+import {ScrobbleProvider} from "../../_services/scrobbling.service";
+
export interface UserReview {
seriesId: number;
libraryId: number;
@@ -8,4 +10,5 @@ export interface UserReview {
isExternal: boolean;
bodyJustText?: string;
externalUrl?: string;
+ provider: ScrobbleProvider;
}
diff --git a/UI/Web/src/app/admin/dashboard/dashboard.component.html b/UI/Web/src/app/admin/dashboard/dashboard.component.html
index 72dcdd961..bde8a9633 100644
--- a/UI/Web/src/app/admin/dashboard/dashboard.component.html
+++ b/UI/Web/src/app/admin/dashboard/dashboard.component.html
@@ -36,12 +36,9 @@
- Kavita+ is a premium subscription service which unlocks features for all users on this Kavita instance. Buy a subscription to unlock premium benefits today! FAQ
+ Kavita+ is a premium subscription service which unlocks features for all users on this Kavita instance. Buy a subscription to unlock premium benefits today! FAQ
-
- Nothing here yet. This will be built out in a future update.
-
diff --git a/UI/Web/src/app/admin/manage-settings/manage-settings.component.html b/UI/Web/src/app/admin/manage-settings/manage-settings.component.html
index ae15a31b2..36bdd6dd2 100644
--- a/UI/Web/src/app/admin/manage-settings/manage-settings.component.html
+++ b/UI/Web/src/app/admin/manage-settings/manage-settings.component.html
@@ -100,7 +100,7 @@
Cache Size
-
The amount of memory allowed for caching heavy APIs. Default is 50MB.
+
The amount of memory allowed for caching heavy APIs. Default is 75MB.
The amount of memory allowed for caching heavy APIs. Default is 50MB.
-
+
- {{userRating * 20}}%
+ {{userRating * 20}}
+ 0; else noOverallRating"> + {{overallRating}}%
+ %
-
+
{{rating.averageScore}}%
@@ -23,5 +26,9 @@
0">★
-
+ {{userRating * 20}}%
+
+
+
+ {{rating.favoriteCount}}
diff --git a/UI/Web/src/app/series-detail/_components/external-rating/external-rating.component.scss b/UI/Web/src/app/series-detail/_components/external-rating/external-rating.component.scss
index 816baab5e..bf59d1ef5 100644
--- a/UI/Web/src/app/series-detail/_components/external-rating/external-rating.component.scss
+++ b/UI/Web/src/app/series-detail/_components/external-rating/external-rating.component.scss
@@ -2,3 +2,21 @@
padding-left: 0px;
padding-right: 0px;
}
+
+.sm-popover {
+ width: 150px;
+
+ > .popover-body {
+ padding-top: 0px;
+ }
+}
+
+.md-popover {
+ width: 214px;
+
+ > .popover-body {
+ padding-top: 0px;
+ }
+}
+
+
diff --git a/UI/Web/src/app/series-detail/_components/external-rating/external-rating.component.ts b/UI/Web/src/app/series-detail/_components/external-rating/external-rating.component.ts
index 8471d6090..e4b4d10a4 100644
--- a/UI/Web/src/app/series-detail/_components/external-rating/external-rating.component.ts
+++ b/UI/Web/src/app/series-detail/_components/external-rating/external-rating.component.ts
@@ -1,4 +1,12 @@
-import {ChangeDetectionStrategy, ChangeDetectorRef, Component, inject, Input, OnInit} from '@angular/core';
+import {
+ ChangeDetectionStrategy,
+ ChangeDetectorRef,
+ Component,
+ inject,
+ Input,
+ OnInit,
+ ViewEncapsulation
+} from '@angular/core';
import {CommonModule, NgOptimizedImage} from '@angular/common';
import {SeriesService} from "../../../_services/series.service";
import {Rating} from "../../../_models/rating";
@@ -7,14 +15,16 @@ import {NgbPopover, NgbRating} from "@ng-bootstrap/ng-bootstrap";
import {LoadingComponent} from "../../../shared/loading/loading.component";
import {AccountService} from "../../../_services/account.service";
import {LibraryType} from "../../../_models/library";
+import {ProviderNamePipe} from "../../../pipe/provider-name.pipe";
@Component({
selector: 'app-external-rating',
standalone: true,
- imports: [CommonModule, ProviderImagePipe, NgOptimizedImage, NgbRating, NgbPopover, LoadingComponent],
+ imports: [CommonModule, ProviderImagePipe, NgOptimizedImage, NgbRating, NgbPopover, LoadingComponent, ProviderNamePipe],
templateUrl: './external-rating.component.html',
styleUrls: ['./external-rating.component.scss'],
- changeDetection: ChangeDetectionStrategy.OnPush
+ changeDetection: ChangeDetectionStrategy.OnPush,
+ encapsulation: ViewEncapsulation.None
})
export class ExternalRatingComponent implements OnInit {
@Input({required: true}) seriesId!: number;
@@ -26,10 +36,13 @@ export class ExternalRatingComponent implements OnInit {
ratings: Array = [];
isLoading: boolean = false;
+ overallRating: number = -1;
ngOnInit() {
+ this.seriesService.getOverallRating(this.seriesId).subscribe(r => this.overallRating = r.averageScore);
+
this.accountService.hasValidLicense$.subscribe((res) => {
if (!res) return;
this.isLoading = true;
diff --git a/UI/Web/src/environments/environment.ts b/UI/Web/src/environments/environment.ts
index 05f42e187..11db3c23e 100644
--- a/UI/Web/src/environments/environment.ts
+++ b/UI/Web/src/environments/environment.ts
@@ -6,7 +6,7 @@ export const environment = {
production: false,
apiUrl: 'http://localhost:5000/api/',
hubUrl: 'http://localhost:5000/hubs/',
- buyLink: 'https://buy.stripe.com/test_8wM4ie2dg5j77o4cMO?prefilled_promo_code=FREETRIAL',
+ buyLink: 'https://buy.stripe.com/test_9AQ5mi058h1PcIo3cf?prefilled_promo_code=FREETRIAL',
manageLink: 'https://billing.stripe.com/p/login/test_14kfZocuh6Tz5ag7ss'
};
diff --git a/openapi.json b/openapi.json
index 6fcfd6a94..d5a266433 100644
--- a/openapi.json
+++ b/openapi.json
@@ -7,7 +7,7 @@
"name": "GPL-3.0",
"url": "https://github.com/Kareadita/Kavita/blob/develop/LICENSE"
},
- "version": "0.7.4.1"
+ "version": "0.7.4.2"
},
"servers": [
{
@@ -2827,7 +2827,7 @@
"tags": [
"License"
],
- "summary": "Updates server license. Returns true if updated and valid",
+ "summary": "Updates server license",
"description": "Caches the result",
"requestBody": {
"content": {
@@ -3947,6 +3947,45 @@
}
}
},
+ "/api/Rating/overall": {
+ "get": {
+ "tags": [
+ "Rating"
+ ],
+ "parameters": [
+ {
+ "name": "seriesId",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "format": "int32"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "Success",
+ "content": {
+ "text/plain": {
+ "schema": {
+ "$ref": "#/components/schemas/RatingDto"
+ }
+ },
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/RatingDto"
+ }
+ },
+ "text/json": {
+ "schema": {
+ "$ref": "#/components/schemas/RatingDto"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
"/api/Reader/pdf": {
"get": {
"tags": [
@@ -6525,9 +6564,12 @@
"in": "query",
"schema": {
"enum": [
- 1
+ 0,
+ 1,
+ 2
],
"type": "integer",
+ "description": "Misleading name but is the source of data (like a review coming from AniList)",
"format": "int32"
}
}
@@ -8540,7 +8582,7 @@
"tags": [
"Server"
],
- "summary": "Bust Review and Recommendation Cache",
+ "summary": "Bust Kavita+ Cache",
"responses": {
"200": {
"description": "Success"
@@ -13731,9 +13773,12 @@
},
"provider": {
"enum": [
- 1
+ 0,
+ 1,
+ 2
],
"type": "integer",
+ "description": "Misleading name but is the source of data (like a review coming from AniList)",
"format": "int32"
}
},
@@ -17180,6 +17225,16 @@
"type": "string",
"description": "The main body with just text, for review preview",
"nullable": true
+ },
+ "provider": {
+ "enum": [
+ 0,
+ 1,
+ 2
+ ],
+ "type": "integer",
+ "description": "If this review is External, which Provider did it come from",
+ "format": "int32"
}
},
"additionalProperties": false,