mirror of
https://github.com/Kareadita/Kavita.git
synced 2025-05-31 20:24:27 -04:00
Bugfix/misc cleanup (#745)
* Change update check to be between noon and 6pm. * Added a UI change that was missed * Fixed an issue on register user where input boxes were not styled correctly * Fixed renaming a series to an existing series name of a different format. * Change webtoon reader debug mode
This commit is contained in:
parent
46b2bebeb6
commit
dd4aedc323
@ -180,7 +180,7 @@ namespace API.Controllers
|
|||||||
|
|
||||||
if (series == null) return BadRequest("Series does not exist");
|
if (series == null) return BadRequest("Series does not exist");
|
||||||
|
|
||||||
if (series.Name != updateSeries.Name && await _unitOfWork.SeriesRepository.DoesSeriesNameExistInLibrary(updateSeries.Name))
|
if (series.Name != updateSeries.Name && await _unitOfWork.SeriesRepository.DoesSeriesNameExistInLibrary(updateSeries.Name, series.Format))
|
||||||
{
|
{
|
||||||
return BadRequest("A series already exists in this library with this name. Series Names must be unique to a library.");
|
return BadRequest("A series already exists in this library with this name. Series Names must be unique to a library.");
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,7 @@ using API.DTOs;
|
|||||||
using API.DTOs.CollectionTags;
|
using API.DTOs.CollectionTags;
|
||||||
using API.DTOs.Filtering;
|
using API.DTOs.Filtering;
|
||||||
using API.Entities;
|
using API.Entities;
|
||||||
|
using API.Entities.Enums;
|
||||||
using API.Extensions;
|
using API.Extensions;
|
||||||
using API.Helpers;
|
using API.Helpers;
|
||||||
using API.Interfaces.Repositories;
|
using API.Interfaces.Repositories;
|
||||||
@ -47,16 +48,22 @@ namespace API.Data.Repositories
|
|||||||
_context.Series.RemoveRange(series);
|
_context.Series.RemoveRange(series);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<bool> DoesSeriesNameExistInLibrary(string name)
|
/// <summary>
|
||||||
|
/// Returns if a series name and format exists already in a library
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="name">Name of series</param>
|
||||||
|
/// <param name="format">Format of series</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public async Task<bool> DoesSeriesNameExistInLibrary(string name, MangaFormat format)
|
||||||
{
|
{
|
||||||
var libraries = _context.Series
|
var libraries = _context.Series
|
||||||
.AsNoTracking()
|
.AsNoTracking()
|
||||||
.Where(x => x.Name == name)
|
.Where(x => x.Name.Equals(name) && x.Format == format)
|
||||||
.Select(s => s.LibraryId);
|
.Select(s => s.LibraryId);
|
||||||
|
|
||||||
return await _context.Series
|
return await _context.Series
|
||||||
.AsNoTracking()
|
.AsNoTracking()
|
||||||
.Where(s => libraries.Contains(s.LibraryId) && s.Name == name)
|
.Where(s => libraries.Contains(s.LibraryId) && s.Name.Equals(name) && s.Format == format)
|
||||||
.CountAsync() > 1;
|
.CountAsync() > 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,7 +41,7 @@ namespace API.Data
|
|||||||
|
|
||||||
IList<ServerSetting> defaultSettings = new List<ServerSetting>()
|
IList<ServerSetting> defaultSettings = new List<ServerSetting>()
|
||||||
{
|
{
|
||||||
new() {Key = ServerSettingKey.CacheDirectory, Value = DirectoryService.CacheDirectory},
|
new () {Key = ServerSettingKey.CacheDirectory, Value = DirectoryService.CacheDirectory},
|
||||||
new () {Key = ServerSettingKey.TaskScan, Value = "daily"},
|
new () {Key = ServerSettingKey.TaskScan, Value = "daily"},
|
||||||
new () {Key = ServerSettingKey.LoggingLevel, Value = "Information"}, // Not used from DB, but DB is sync with appSettings.json
|
new () {Key = ServerSettingKey.LoggingLevel, Value = "Information"}, // Not used from DB, but DB is sync with appSettings.json
|
||||||
new () {Key = ServerSettingKey.TaskBackup, Value = "weekly"},
|
new () {Key = ServerSettingKey.TaskBackup, Value = "weekly"},
|
||||||
@ -51,6 +51,7 @@ namespace API.Data
|
|||||||
new () {Key = ServerSettingKey.EnableOpds, Value = "false"},
|
new () {Key = ServerSettingKey.EnableOpds, Value = "false"},
|
||||||
new () {Key = ServerSettingKey.EnableAuthentication, Value = "true"},
|
new () {Key = ServerSettingKey.EnableAuthentication, Value = "true"},
|
||||||
new () {Key = ServerSettingKey.BaseUrl, Value = "/"},
|
new () {Key = ServerSettingKey.BaseUrl, Value = "/"},
|
||||||
|
new () {Key = ServerSettingKey.InstallId, Value = HashUtil.AnonymousToken()},
|
||||||
};
|
};
|
||||||
|
|
||||||
foreach (var defaultSetting in defaultSettings)
|
foreach (var defaultSetting in defaultSettings)
|
||||||
|
@ -4,26 +4,61 @@ namespace API.Entities.Enums
|
|||||||
{
|
{
|
||||||
public enum ServerSettingKey
|
public enum ServerSettingKey
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Cron format for how often full library scans are performed.
|
||||||
|
/// </summary>
|
||||||
[Description("TaskScan")]
|
[Description("TaskScan")]
|
||||||
TaskScan = 0,
|
TaskScan = 0,
|
||||||
|
/// <summary>
|
||||||
|
/// Where files are cached. Not currently used.
|
||||||
|
/// </summary>
|
||||||
[Description("CacheDirectory")]
|
[Description("CacheDirectory")]
|
||||||
CacheDirectory = 1,
|
CacheDirectory = 1,
|
||||||
|
/// <summary>
|
||||||
|
/// Cron format for how often backups are taken.
|
||||||
|
/// </summary>
|
||||||
[Description("TaskBackup")]
|
[Description("TaskBackup")]
|
||||||
TaskBackup = 2,
|
TaskBackup = 2,
|
||||||
|
/// <summary>
|
||||||
|
/// Logging level for Server. Not managed in DB. Managed in appsettings.json and synced to DB.
|
||||||
|
/// </summary>
|
||||||
[Description("LoggingLevel")]
|
[Description("LoggingLevel")]
|
||||||
LoggingLevel = 3,
|
LoggingLevel = 3,
|
||||||
|
/// <summary>
|
||||||
|
/// Port server listens on. Not managed in DB. Managed in appsettings.json and synced to DB.
|
||||||
|
/// </summary>
|
||||||
[Description("Port")]
|
[Description("Port")]
|
||||||
Port = 4,
|
Port = 4,
|
||||||
|
/// <summary>
|
||||||
|
/// Where the backups are stored.
|
||||||
|
/// </summary>
|
||||||
[Description("BackupDirectory")]
|
[Description("BackupDirectory")]
|
||||||
BackupDirectory = 5,
|
BackupDirectory = 5,
|
||||||
|
/// <summary>
|
||||||
|
/// Allow anonymous data to be reported to KavitaStats
|
||||||
|
/// </summary>
|
||||||
[Description("AllowStatCollection")]
|
[Description("AllowStatCollection")]
|
||||||
AllowStatCollection = 6,
|
AllowStatCollection = 6,
|
||||||
|
/// <summary>
|
||||||
|
/// Is OPDS enabled for the server
|
||||||
|
/// </summary>
|
||||||
[Description("EnableOpds")]
|
[Description("EnableOpds")]
|
||||||
EnableOpds = 7,
|
EnableOpds = 7,
|
||||||
|
/// <summary>
|
||||||
|
/// Is Authentication needed for non-admin accounts
|
||||||
|
/// </summary>
|
||||||
[Description("EnableAuthentication")]
|
[Description("EnableAuthentication")]
|
||||||
EnableAuthentication = 8,
|
EnableAuthentication = 8,
|
||||||
|
/// <summary>
|
||||||
|
/// Base Url for the server. Not Implemented.
|
||||||
|
/// </summary>
|
||||||
[Description("BaseUrl")]
|
[Description("BaseUrl")]
|
||||||
BaseUrl = 9
|
BaseUrl = 9,
|
||||||
|
/// <summary>
|
||||||
|
/// Represents this installation of Kavita. Is tied to Stat reporting but has no information about user or files.
|
||||||
|
/// </summary>
|
||||||
|
[Description("InstallId")]
|
||||||
|
InstallId = 10
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,7 @@ namespace API.Entities
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public string SortName { get; set; }
|
public string SortName { get; set; }
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Name in Japanese. By default, will be same as Name.
|
/// Name in original language (Japanese for Manga). By default, will be same as Name.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string LocalizedName { get; set; }
|
public string LocalizedName { get; set; }
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -4,6 +4,7 @@ using API.Data.Scanner;
|
|||||||
using API.DTOs;
|
using API.DTOs;
|
||||||
using API.DTOs.Filtering;
|
using API.DTOs.Filtering;
|
||||||
using API.Entities;
|
using API.Entities;
|
||||||
|
using API.Entities.Enums;
|
||||||
using API.Helpers;
|
using API.Helpers;
|
||||||
|
|
||||||
namespace API.Interfaces.Repositories
|
namespace API.Interfaces.Repositories
|
||||||
@ -14,7 +15,7 @@ namespace API.Interfaces.Repositories
|
|||||||
void Update(Series series);
|
void Update(Series series);
|
||||||
void Remove(Series series);
|
void Remove(Series series);
|
||||||
void Remove(IEnumerable<Series> series);
|
void Remove(IEnumerable<Series> series);
|
||||||
Task<bool> DoesSeriesNameExistInLibrary(string name);
|
Task<bool> DoesSeriesNameExistInLibrary(string name, MangaFormat format);
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Adds user information like progress, ratings, etc
|
/// Adds user information like progress, ratings, etc
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -26,6 +26,7 @@ namespace API.Services
|
|||||||
private const string SendDataTask = "finalize-stats";
|
private const string SendDataTask = "finalize-stats";
|
||||||
|
|
||||||
public static BackgroundJobServer Client => new BackgroundJobServer();
|
public static BackgroundJobServer Client => new BackgroundJobServer();
|
||||||
|
private static readonly Random Rnd = new Random();
|
||||||
|
|
||||||
|
|
||||||
public TaskScheduler(ICacheService cacheService, ILogger<TaskScheduler> logger, IScannerService scannerService,
|
public TaskScheduler(ICacheService cacheService, ILogger<TaskScheduler> logger, IScannerService scannerService,
|
||||||
@ -73,7 +74,8 @@ namespace API.Services
|
|||||||
|
|
||||||
RecurringJob.AddOrUpdate("cleanup", () => _cleanupService.Cleanup(), Cron.Daily, TimeZoneInfo.Local);
|
RecurringJob.AddOrUpdate("cleanup", () => _cleanupService.Cleanup(), Cron.Daily, TimeZoneInfo.Local);
|
||||||
|
|
||||||
RecurringJob.AddOrUpdate("check-for-updates", () => _scannerService.ScanLibraries(), Cron.Daily, TimeZoneInfo.Local);
|
// Schedule update check between noon and 6pm local time
|
||||||
|
RecurringJob.AddOrUpdate("check-for-updates", () => _scannerService.ScanLibraries(), Cron.Daily(Rnd.Next(12, 18)), TimeZoneInfo.Local);
|
||||||
}
|
}
|
||||||
|
|
||||||
#region StatsTasks
|
#region StatsTasks
|
||||||
|
@ -75,7 +75,7 @@ export class LibraryComponent implements OnInit, OnDestroy {
|
|||||||
|
|
||||||
reloadSeries() {
|
reloadSeries() {
|
||||||
this.loadRecentlyAdded();
|
this.loadRecentlyAdded();
|
||||||
this.loadInProgress();
|
this.loadOnDeck();
|
||||||
}
|
}
|
||||||
|
|
||||||
reloadInProgress(series: Series | boolean) {
|
reloadInProgress(series: Series | boolean) {
|
||||||
@ -88,10 +88,10 @@ export class LibraryComponent implements OnInit, OnDestroy {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.loadInProgress();
|
this.loadOnDeck();
|
||||||
}
|
}
|
||||||
|
|
||||||
loadInProgress() {
|
loadOnDeck() {
|
||||||
this.seriesService.getOnDeck().pipe(takeUntil(this.onDestroy)).subscribe((updatedSeries) => {
|
this.seriesService.getOnDeck().pipe(takeUntil(this.onDestroy)).subscribe((updatedSeries) => {
|
||||||
this.inProgress = updatedSeries.result;
|
this.inProgress = updatedSeries.result;
|
||||||
});
|
});
|
||||||
|
@ -251,6 +251,7 @@ export class InfiniteScrollerComponent implements OnInit, OnChanges, OnDestroy {
|
|||||||
if (totalScroll === totalHeight && !this.atBottom) {
|
if (totalScroll === totalHeight && !this.atBottom) {
|
||||||
this.atBottom = true;
|
this.atBottom = true;
|
||||||
this.setPageNum(this.totalPages);
|
this.setPageNum(this.totalPages);
|
||||||
|
this.debugLog('At last page, saving last page ', this.totalPages);
|
||||||
// Scroll user back to original location
|
// Scroll user back to original location
|
||||||
this.previousScrollHeightMinusTop = this.getScrollTop();
|
this.previousScrollHeightMinusTop = this.getScrollTop();
|
||||||
requestAnimationFrame(() => document.documentElement.scrollTop = this.previousScrollHeightMinusTop + (SPACER_SCROLL_INTO_PX / 2));
|
requestAnimationFrame(() => document.documentElement.scrollTop = this.previousScrollHeightMinusTop + (SPACER_SCROLL_INTO_PX / 2));
|
||||||
|
@ -14,4 +14,5 @@
|
|||||||
|
|
||||||
input {
|
input {
|
||||||
background-color: #fff !important;
|
background-color: #fff !important;
|
||||||
|
color: black !important;
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user