diff --git a/API/Controllers/SeriesController.cs b/API/Controllers/SeriesController.cs index b81b65158..28751dbc1 100644 --- a/API/Controllers/SeriesController.cs +++ b/API/Controllers/SeriesController.cs @@ -245,8 +245,7 @@ namespace API.Controllers var userId = await _unitOfWork.UserRepository.GetUserIdByUsernameAsync(User.GetUsername()); var results = await _unitOfWork.SeriesRepository.GetOnDeck(userId, libraryId, userParams, filterDto); - var listResults = results.DistinctBy(s => s.Name).Skip((userParams.PageNumber - 1) * userParams.PageSize) - .Take(userParams.PageSize).ToList(); + var listResults = results.DistinctBy(s => s.Name).Skip((userParams.PageNumber - 1) * userParams.PageSize).Take(userParams.PageSize).ToList(); var pagedList = new PagedList(listResults, listResults.Count, userParams.PageNumber, userParams.PageSize); await _unitOfWork.SeriesRepository.AddSeriesModifiers(userId, pagedList); diff --git a/API/DTOs/Stats/ServerInfoDto.cs b/API/DTOs/Stats/ServerInfoDto.cs index 9176a81ff..45a73236b 100644 --- a/API/DTOs/Stats/ServerInfoDto.cs +++ b/API/DTOs/Stats/ServerInfoDto.cs @@ -1,4 +1,6 @@ -namespace API.DTOs.Stats +using API.Entities.Enums; + +namespace API.DTOs.Stats { public class ServerInfoDto { @@ -10,5 +12,39 @@ public int NumOfCores { get; set; } public int NumberOfLibraries { get; set; } public bool HasBookmarks { get; set; } + /// + /// The site theme the install is using + /// + public string ActiveSiteTheme { get; set; } + + /// + /// The reading mode the main user has as a preference + /// + public ReaderMode MangaReaderMode { get; set; } + + /// + /// Number of users on the install + /// + public int NumberOfUsers { get; set; } + + /// + /// Number of collections on the install + /// + public int NumberOfCollections { get; set; } + + /// + /// Number of reading lists on the install (Sum of all users) + /// + public int NumberOfReadingLists { get; set; } + + /// + /// Is OPDS enabled + /// + public bool OPDSEnabled { get; set; } + + /// + /// Total number of files in the instance + /// + public int TotalFiles { get; set; } } } diff --git a/API/Data/Repositories/LibraryRepository.cs b/API/Data/Repositories/LibraryRepository.cs index 4a3681de3..dd4d5afa9 100644 --- a/API/Data/Repositories/LibraryRepository.cs +++ b/API/Data/Repositories/LibraryRepository.cs @@ -37,6 +37,7 @@ public interface ILibraryRepository Task> GetLibrariesForUserIdAsync(int userId); Task GetLibraryTypeAsync(int libraryId); Task> GetLibraryForIdsAsync(IList libraryIds); + Task GetTotalFiles(); } public class LibraryRepository : ILibraryRepository @@ -116,6 +117,11 @@ public class LibraryRepository : ILibraryRepository .ToListAsync(); } + public async Task GetTotalFiles() + { + return await _context.MangaFile.CountAsync(); + } + public async Task> GetLibraryDtosAsync() { return await _context.Library diff --git a/API/Data/Repositories/ReadingListRepository.cs b/API/Data/Repositories/ReadingListRepository.cs index ca21bf26c..59c6ac5c2 100644 --- a/API/Data/Repositories/ReadingListRepository.cs +++ b/API/Data/Repositories/ReadingListRepository.cs @@ -25,6 +25,7 @@ public interface IReadingListRepository void Remove(ReadingListItem item); void BulkRemove(IEnumerable items); void Update(ReadingList list); + Task Count(); } public class ReadingListRepository : IReadingListRepository @@ -43,6 +44,11 @@ public class ReadingListRepository : IReadingListRepository _context.Entry(list).State = EntityState.Modified; } + public async Task Count() + { + return await _context.ReadingList.CountAsync(); + } + public void Remove(ReadingListItem item) { _context.ReadingListItem.Remove(item); diff --git a/API/Data/Repositories/SeriesRepository.cs b/API/Data/Repositories/SeriesRepository.cs index c772dae1e..3e93abda3 100644 --- a/API/Data/Repositories/SeriesRepository.cs +++ b/API/Data/Repositories/SeriesRepository.cs @@ -276,6 +276,7 @@ public class SeriesRepository : ISeriesRepository { var result = new SearchResultGroupDto(); + var searchQueryNormalized = Parser.Parser.Normalize(searchQuery); var seriesIds = _context.Series .Where(s => libraryIds.Contains(s.LibraryId)) @@ -299,6 +300,7 @@ public class SeriesRepository : ISeriesRepository .Where(s => EF.Functions.Like(s.Name, $"%{searchQuery}%") || EF.Functions.Like(s.OriginalName, $"%{searchQuery}%") || EF.Functions.Like(s.LocalizedName, $"%{searchQuery}%") + || EF.Functions.Like(s.NormalizedName, $"%{searchQueryNormalized}%") || (hasYearInQuery && s.Metadata.ReleaseYear == yearComparison)) .Include(s => s.Library) .OrderBy(s => s.SortName) @@ -317,7 +319,7 @@ public class SeriesRepository : ISeriesRepository result.Collections = await _context.CollectionTag .Where(s => EF.Functions.Like(s.Title, $"%{searchQuery}%") - || EF.Functions.Like(s.NormalizedTitle, $"%{searchQuery}%")) + || EF.Functions.Like(s.NormalizedTitle, $"%{searchQueryNormalized}%")) .Where(s => s.Promoted || isAdmin) .OrderBy(s => s.Title) .AsNoTracking() diff --git a/API/Entities/AppUserProgress.cs b/API/Entities/AppUserProgress.cs index b3e0a5dfd..1704628cb 100644 --- a/API/Entities/AppUserProgress.cs +++ b/API/Entities/AppUserProgress.cs @@ -35,6 +35,14 @@ namespace API.Entities /// on next load /// public string BookScrollId { get; set; } + /// + /// When this was first created + /// + public DateTime Created { get; set; } + /// + /// Last date this was updated + /// + public DateTime LastModified { get; set; } // Relationships /// @@ -45,14 +53,5 @@ namespace API.Entities /// User this progress belongs to /// public int AppUserId { get; set; } - - /// - /// When this was first created - /// - public DateTime Created { get; set; } - /// - /// Last date this was updated - /// - public DateTime LastModified { get; set; } } } diff --git a/API/Services/Tasks/StatsService.cs b/API/Services/Tasks/StatsService.cs index 36a4a5c50..faf0414b0 100644 --- a/API/Services/Tasks/StatsService.cs +++ b/API/Services/Tasks/StatsService.cs @@ -5,6 +5,7 @@ using System.Runtime.InteropServices; using System.Threading.Tasks; using API.Data; using API.DTOs.Stats; +using API.DTOs.Theme; using API.Entities.Enums; using Flurl.Http; using Kavita.Common.EnvironmentInfo; @@ -100,6 +101,12 @@ public class StatsService : IStatsService { var installId = await _unitOfWork.SettingsRepository.GetSettingAsync(ServerSettingKey.InstallId); var installVersion = await _unitOfWork.SettingsRepository.GetSettingAsync(ServerSettingKey.InstallVersion); + + var firstAdminUser = (await _unitOfWork.UserRepository.GetAdminUsersAsync()).First(); + var firstAdminUserPref = (await _unitOfWork.UserRepository.GetPreferencesAsync(firstAdminUser.UserName)); + + var activeTheme = firstAdminUserPref.Theme ?? Seed.DefaultThemes.First(t => t.IsDefault); + var serverInfo = new ServerInfoDto { InstallId = installId.Value, @@ -109,7 +116,14 @@ public class StatsService : IStatsService IsDocker = new OsInfo(Array.Empty()).IsDocker, NumOfCores = Math.Max(Environment.ProcessorCount, 1), HasBookmarks = (await _unitOfWork.UserRepository.GetAllBookmarksAsync()).Any(), - NumberOfLibraries = (await _unitOfWork.LibraryRepository.GetLibrariesAsync()).Count() + NumberOfLibraries = (await _unitOfWork.LibraryRepository.GetLibrariesAsync()).Count(), + ActiveSiteTheme = activeTheme.Name, + NumberOfCollections = (await _unitOfWork.CollectionTagRepository.GetAllTagsAsync()).Count(), + NumberOfReadingLists = await _unitOfWork.ReadingListRepository.Count(), + OPDSEnabled = (await _unitOfWork.SettingsRepository.GetSettingsDtoAsync()).EnableOpds, + NumberOfUsers = (await _unitOfWork.UserRepository.GetAllUsers()).Count(), + TotalFiles = await _unitOfWork.LibraryRepository.GetTotalFiles(), + MangaReaderMode = firstAdminUserPref.ReaderMode }; return serverInfo; diff --git a/UI/Web/package-lock.json b/UI/Web/package-lock.json index cccd8a5ef..279f64bf3 100644 --- a/UI/Web/package-lock.json +++ b/UI/Web/package-lock.json @@ -10498,7 +10498,8 @@ "dependencies": { "ansi-regex": { "version": "5.0.0", - "resolved": "", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", "dev": true }, "strip-ansi": { @@ -10703,7 +10704,8 @@ "dependencies": { "ansi-regex": { "version": "5.0.0", - "resolved": "", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", "dev": true }, "ansi-styles": {