Kavita+ Reviews are Mixed (#2238)
* Remove updating last active on PresenceTracker as we now do it on Token. Should reduce annoying db concurrency errors. * Updated Kavita+ Reviews to give a spread of reviews, positive or not. * Fixed up some styling overlap for different breakpoints for sections like Writers, Authors, Collections, etc. * Refactored code * Fixed jumpbar being broken with no custom sort * Fixed paper background on epub reader not loading under base url
This commit is contained in:
parent
24f5bf1167
commit
d64681b832
8 changed files with 63 additions and 34 deletions
|
@ -67,11 +67,14 @@ public class ReviewController : BaseApiController
|
||||||
var result = await _cacheProvider.GetAsync<IEnumerable<UserReviewDto>>(cacheKey);
|
var result = await _cacheProvider.GetAsync<IEnumerable<UserReviewDto>>(cacheKey);
|
||||||
if (result.HasValue)
|
if (result.HasValue)
|
||||||
{
|
{
|
||||||
externalReviews = result.Value;
|
externalReviews = result.Value.ToList();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
externalReviews = (await _reviewService.GetReviewsForSeries(userId, seriesId)).ToList();
|
var reviews = (await _reviewService.GetReviewsForSeries(userId, seriesId)).ToList();
|
||||||
|
externalReviews = SelectSpectrumOfReviews(reviews);
|
||||||
|
|
||||||
|
|
||||||
await _cacheProvider.SetAsync(cacheKey, externalReviews, TimeSpan.FromHours(10));
|
await _cacheProvider.SetAsync(cacheKey, externalReviews, TimeSpan.FromHours(10));
|
||||||
_logger.LogDebug("Caching external reviews for {Key}", cacheKey);
|
_logger.LogDebug("Caching external reviews for {Key}", cacheKey);
|
||||||
}
|
}
|
||||||
|
@ -80,7 +83,44 @@ public class ReviewController : BaseApiController
|
||||||
// Fetch external reviews and splice them in
|
// Fetch external reviews and splice them in
|
||||||
userRatings.AddRange(externalReviews);
|
userRatings.AddRange(externalReviews);
|
||||||
|
|
||||||
return Ok(userRatings.Take(10));
|
|
||||||
|
return Ok(userRatings);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static IList<UserReviewDto> SelectSpectrumOfReviews(List<UserReviewDto> reviews)
|
||||||
|
{
|
||||||
|
IList<UserReviewDto> externalReviews;
|
||||||
|
var totalReviews = reviews.Count;
|
||||||
|
|
||||||
|
if (totalReviews > 10)
|
||||||
|
{
|
||||||
|
//var stepSize = Math.Max(totalReviews / 10, 1); // Calculate step size, ensuring it's at least 1
|
||||||
|
var stepSize = Math.Max((totalReviews - 4) / 8, 1);
|
||||||
|
|
||||||
|
var selectedReviews = new List<UserReviewDto>()
|
||||||
|
{
|
||||||
|
reviews[0],
|
||||||
|
reviews[1],
|
||||||
|
};
|
||||||
|
for (var i = 2; i < totalReviews - 2; i += stepSize)
|
||||||
|
{
|
||||||
|
selectedReviews.Add(reviews[i]);
|
||||||
|
|
||||||
|
if (selectedReviews.Count >= 8)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
selectedReviews.Add(reviews[totalReviews - 2]);
|
||||||
|
selectedReviews.Add(reviews[totalReviews - 1]);
|
||||||
|
|
||||||
|
externalReviews = selectedReviews;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
externalReviews = reviews;
|
||||||
|
}
|
||||||
|
|
||||||
|
return externalReviews;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
@ -57,18 +57,6 @@ public class PresenceTracker : IPresenceTracker
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update the last active for the user
|
|
||||||
try
|
|
||||||
{
|
|
||||||
user.UpdateLastActive();
|
|
||||||
_unitOfWork.UserRepository.Update(user);
|
|
||||||
await _unitOfWork.CommitAsync();
|
|
||||||
}
|
|
||||||
catch (Exception)
|
|
||||||
{
|
|
||||||
// Swallow the exception
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task UserDisconnected(int userId, string connectionId)
|
public Task UserDisconnected(int userId, string connectionId)
|
||||||
|
|
|
@ -62,7 +62,7 @@
|
||||||
<td>
|
<td>
|
||||||
<ng-container [ngSwitch]="item.scrobbleEventType">
|
<ng-container [ngSwitch]="item.scrobbleEventType">
|
||||||
<ng-container *ngSwitchCase="ScrobbleEventType.ChapterRead">
|
<ng-container *ngSwitchCase="ScrobbleEventType.ChapterRead">
|
||||||
{{t('volume-and-chapter-num', {v: item.volumeNumber, c: item.chapterNumber})}}
|
{{t('volume-and-chapter-num', {v: item.volumeNumber, n: item.chapterNumber})}}
|
||||||
</ng-container>
|
</ng-container>
|
||||||
<ng-container *ngSwitchCase="ScrobbleEventType.ScoreUpdated">
|
<ng-container *ngSwitchCase="ScrobbleEventType.ScoreUpdated">
|
||||||
{{t('rating', {r: item.rating})}}
|
{{t('rating', {r: item.rating})}}
|
||||||
|
|
|
@ -94,7 +94,7 @@ export const BookPaperTheme = `
|
||||||
.reader-container {
|
.reader-container {
|
||||||
color: black !important;
|
color: black !important;
|
||||||
background-color: var(--theme-bg-color) !important;
|
background-color: var(--theme-bg-color) !important;
|
||||||
background: url("/assets/images/paper-bg.png");
|
background: url("assets/images/paper-bg.png");
|
||||||
}
|
}
|
||||||
|
|
||||||
.book-content *:not(input), .book-content *:not(select), .book-content *:not(code), .book-content *:not(:link), .book-content *:not(.ngx-toastr) {
|
.book-content *:not(input), .book-content *:not(select), .book-content *:not(code), .book-content *:not(:link), .book-content *:not(.ngx-toastr) {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { CdkVirtualScrollViewport } from '@angular/cdk/scrolling';
|
import {CdkVirtualScrollViewport} from '@angular/cdk/scrolling';
|
||||||
import {CommonModule, DOCUMENT} from '@angular/common';
|
import {CommonModule, DOCUMENT} from '@angular/common';
|
||||||
import {
|
import {
|
||||||
ChangeDetectionStrategy,
|
ChangeDetectionStrategy,
|
||||||
|
@ -18,18 +18,18 @@ import {
|
||||||
TrackByFunction,
|
TrackByFunction,
|
||||||
ViewChild
|
ViewChild
|
||||||
} from '@angular/core';
|
} from '@angular/core';
|
||||||
import { Router } from '@angular/router';
|
import {Router} from '@angular/router';
|
||||||
import {VirtualScrollerComponent, VirtualScrollerModule} from '@iharbeck/ngx-virtual-scroller';
|
import {VirtualScrollerComponent, VirtualScrollerModule} from '@iharbeck/ngx-virtual-scroller';
|
||||||
import { FilterSettings } from 'src/app/metadata-filter/filter-settings';
|
import {FilterSettings} from 'src/app/metadata-filter/filter-settings';
|
||||||
import { FilterUtilitiesService } from 'src/app/shared/_services/filter-utilities.service';
|
import {FilterUtilitiesService} from 'src/app/shared/_services/filter-utilities.service';
|
||||||
import { Breakpoint, UtilityService } from 'src/app/shared/_services/utility.service';
|
import {Breakpoint, UtilityService} from 'src/app/shared/_services/utility.service';
|
||||||
import { JumpKey } from 'src/app/_models/jumpbar/jump-key';
|
import {JumpKey} from 'src/app/_models/jumpbar/jump-key';
|
||||||
import { Library } from 'src/app/_models/library';
|
import {Library} from 'src/app/_models/library';
|
||||||
import { Pagination } from 'src/app/_models/pagination';
|
import {Pagination} from 'src/app/_models/pagination';
|
||||||
import { FilterEvent, FilterItem } from 'src/app/_models/metadata/series-filter';
|
import {FilterEvent, FilterItem, SortField} from 'src/app/_models/metadata/series-filter';
|
||||||
import { ActionItem } from 'src/app/_services/action-factory.service';
|
import {ActionItem} from 'src/app/_services/action-factory.service';
|
||||||
import { JumpbarService } from 'src/app/_services/jumpbar.service';
|
import {JumpbarService} from 'src/app/_services/jumpbar.service';
|
||||||
import { ScrollService } from 'src/app/_services/scroll.service';
|
import {ScrollService} from 'src/app/_services/scroll.service';
|
||||||
import {LoadingComponent} from "../../shared/loading/loading.component";
|
import {LoadingComponent} from "../../shared/loading/loading.component";
|
||||||
|
|
||||||
|
|
||||||
|
@ -164,7 +164,8 @@ export class CardDetailLayoutComponent implements OnInit, OnChanges {
|
||||||
}
|
}
|
||||||
|
|
||||||
hasCustomSort() {
|
hasCustomSort() {
|
||||||
return this.filter?.sortOptions || this.filterSettings?.presetsV2?.sortOptions;
|
return this.filter.sortOptions?.sortField != SortField.SortName || !this.filter.sortOptions.isAscending
|
||||||
|
|| this.filterSettings.presetsV2?.sortOptions?.sortField != SortField.SortName || !this.filterSettings.presetsV2?.sortOptions?.isAscending;
|
||||||
}
|
}
|
||||||
|
|
||||||
performAction(action: ActionItem<any>) {
|
performAction(action: ActionItem<any>) {
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
<div class="row g-0 mb-1" *ngIf="tags.length > 0">
|
<div class="row g-0 mb-1" *ngIf="tags.length > 0">
|
||||||
<div class="col-md-3">
|
<div class="col-lg-3 col-md-4 col-sm-12">
|
||||||
<h5>{{heading}}</h5>
|
<h5>{{heading}}</h5>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-9">
|
<div class="col-lg-9 col-md-8 col-sm-12">
|
||||||
<app-badge-expander [items]="tags">
|
<app-badge-expander [items]="tags">
|
||||||
<ng-template #badgeExpanderItem let-item let-position="idx">
|
<ng-template #badgeExpanderItem let-item let-position="idx">
|
||||||
<ng-container *ngIf="itemTemplate; else useTitle">
|
<ng-container *ngIf="itemTemplate; else useTitle">
|
||||||
|
|
|
@ -706,7 +706,7 @@
|
||||||
"collections-title": "{{side-nav.collections}}",
|
"collections-title": "{{side-nav.collections}}",
|
||||||
"reading-lists-title": "{{side-nav.reading-lists}}",
|
"reading-lists-title": "{{side-nav.reading-lists}}",
|
||||||
|
|
||||||
"writers-title": "Writers/Authors",
|
"writers-title": "Writers",
|
||||||
"cover-artists-title": "Cover Artists",
|
"cover-artists-title": "Cover Artists",
|
||||||
"characters-title": "Characters",
|
"characters-title": "Characters",
|
||||||
"colorists-title": "Colorists",
|
"colorists-title": "Colorists",
|
||||||
|
|
|
@ -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.7.11"
|
"version": "0.7.7.14"
|
||||||
},
|
},
|
||||||
"servers": [
|
"servers": [
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue