using System; using API.DTOs.Update; using API.Extensions; using API.Services.Plus; namespace API.SignalR; public static class MessageFactoryEntityTypes { public const string Library = "library"; public const string Series = "series"; public const string Volume = "volume"; public const string Chapter = "chapter"; public const string CollectionTag = "collection"; public const string ReadingList = "readingList"; } public static class MessageFactory { /// /// An update is available for the Kavita instance /// public const string UpdateAvailable = "UpdateAvailable"; /// /// Used to tell when a scan series completes. This also informs UI to update series metadata /// public const string ScanSeries = "ScanSeries"; /// /// Event sent out during Refresh Metadata for progress tracking /// private const string CoverUpdateProgress = "CoverUpdateProgress"; /// /// Series is added to server /// public const string SeriesAdded = "SeriesAdded"; /// /// Series is removed from server /// public const string SeriesRemoved = "SeriesRemoved"; /// /// When a user is connects/disconnects from server /// public const string OnlineUsers = "OnlineUsers"; /// /// When a series is added to a collection /// public const string SeriesAddedToCollection = "SeriesAddedToCollection"; /// /// Event sent out during backing up the database /// private const string BackupDatabaseProgress = "BackupDatabaseProgress"; /// /// Event sent out during cleaning up temp and cache folders /// private const string CleanupProgress = "CleanupProgress"; /// /// Event sent out during downloading of files /// private const string DownloadProgress = "DownloadProgress"; /// /// A cover was updated /// public const string CoverUpdate = "CoverUpdate"; /// /// A custom site theme was removed or added /// private const string SiteThemeProgress = "SiteThemeProgress"; /// /// A custom book theme was removed or added /// private const string BookThemeProgress = "BookThemeProgress"; /// /// A type of event that has progress (determinate or indeterminate). /// The underlying event will have a name to give details on how to handle. /// /// This is not an Event Name, it is used as the method only public const string NotificationProgress = "NotificationProgress"; /// /// Event sent out when Scan Loop is parsing a file /// private const string FileScanProgress = "FileScanProgress"; /// /// A generic error that can occur in background processing /// public const string Error = "Error"; /// /// When DB updates are occuring during a library/series scan /// private const string ScanProgress = "ScanProgress"; /// /// When a library is created/deleted in the Server /// public const string LibraryModified = "LibraryModified"; /// /// A user's progress was modified /// public const string UserProgressUpdate = "UserProgressUpdate"; /// /// A user's account or preferences were updated and UI needs to refresh to stay in sync /// public const string UserUpdate = "UserUpdate"; /// /// When bulk bookmarks are being converted /// private const string ConvertBookmarksProgress = "ConvertBookmarksProgress"; /// /// When bulk covers are being converted /// private const string ConvertCoversProgress = "ConvertBookmarksProgress"; /// /// When files are being scanned to calculate word count /// private const string WordCountAnalyzerProgress = "WordCountAnalyzerProgress"; /// /// A generic message that can occur in background processing to inform user, but no direct action is needed /// public const string Info = "Info"; /// /// When files are being emailed to a device /// public const string SendingToDevice = "SendingToDevice"; /// /// A Scrobbling Key has expired and needs rotation /// public const string ScrobblingKeyExpired = "ScrobblingKeyExpired"; /// /// Order, Visibility, etc has changed on the Dashboard. UI will refresh the layout /// public const string DashboardUpdate = "DashboardUpdate"; /// /// Order, Visibility, etc has changed on the Sidenav. UI will refresh the layout /// public const string SideNavUpdate = "SideNavUpdate"; public static SignalRMessage DashboardUpdateEvent(int userId) { return new SignalRMessage() { Name = DashboardUpdate, Title = "Dashboard Update", Progress = ProgressType.None, EventType = ProgressEventType.Single, Body = new { UserId = userId } }; } public static SignalRMessage SideNavUpdateEvent(int userId) { return new SignalRMessage() { Name = SideNavUpdate, Title = "SideNav Update", Progress = ProgressType.None, EventType = ProgressEventType.Single, Body = new { UserId = userId } }; } public static SignalRMessage ScanSeriesEvent(int libraryId, int seriesId, string seriesName) { return new SignalRMessage() { Name = ScanSeries, EventType = ProgressEventType.Single, Body = new { LibraryId = libraryId, SeriesId = seriesId, SeriesName = seriesName } }; } public static SignalRMessage SeriesAddedEvent(int seriesId, string seriesName, int libraryId) { return new SignalRMessage() { Name = SeriesAdded, Body = new { SeriesId = seriesId, SeriesName = seriesName, LibraryId = libraryId } }; } public static SignalRMessage SeriesRemovedEvent(int seriesId, string seriesName, int libraryId) { return new SignalRMessage() { Name = SeriesRemoved, Body = new { SeriesId = seriesId, SeriesName = seriesName, LibraryId = libraryId } }; } public static SignalRMessage WordCountAnalyzerProgressEvent(int libraryId, float progress, string eventType, string subtitle = "") { return new SignalRMessage() { Name = WordCountAnalyzerProgress, Title = "Analyzing Word count", SubTitle = subtitle, EventType = eventType, Progress = ProgressType.Determinate, Body = new { LibraryId = libraryId, Progress = progress, EventTime = DateTime.Now } }; } public static SignalRMessage CoverUpdateProgressEvent(int libraryId, float progress, string eventType, string subtitle = "") { return new SignalRMessage() { Name = CoverUpdateProgress, Title = "Refreshing Covers", SubTitle = subtitle, EventType = eventType, Progress = ProgressType.Determinate, Body = new { LibraryId = libraryId, Progress = progress, EventTime = DateTime.Now } }; } public static SignalRMessage BackupDatabaseProgressEvent(float progress, string subtitle = "") { return new SignalRMessage() { Name = BackupDatabaseProgress, Title = "Backing up Database", SubTitle = subtitle, EventType = progress switch { 0f => "started", 1f => "ended", _ => "updated" }, Progress = ProgressType.Determinate, Body = new { Progress = progress } }; } public static SignalRMessage CleanupProgressEvent(float progress, string subtitle = "") { return new SignalRMessage() { Name = CleanupProgress, Title = "Performing Cleanup", SubTitle = subtitle, EventType = progress switch { 0f => "started", 1f => "ended", _ => "updated" }, Progress = ProgressType.Determinate, Body = new { Progress = progress } }; } public static SignalRMessage UpdateVersionEvent(UpdateNotificationDto update) { return new SignalRMessage { Name = UpdateAvailable, Title = "Update Available", SubTitle = update.UpdateTitle, EventType = ProgressEventType.Single, Progress = ProgressType.None, Body = update }; } public static SignalRMessage SendingToDeviceEvent(string subtitle, string eventType) { return new SignalRMessage { Name = SendingToDevice, Title = "Sending files to Device", SubTitle = subtitle, EventType = eventType, Progress = ProgressType.Indeterminate, Body = new { } }; } public static SignalRMessage SeriesAddedToCollectionEvent(int tagId, int seriesId) { return new SignalRMessage { Name = SeriesAddedToCollection, Progress = ProgressType.None, EventType = ProgressEventType.Single, Body = new { TagId = tagId, SeriesId = seriesId } }; } public static SignalRMessage ErrorEvent(string title, string subtitle) { return new SignalRMessage { Name = Error, Title = title, SubTitle = subtitle, Progress = ProgressType.None, EventType = ProgressEventType.Single, Body = new { Title = title, SubTitle = subtitle, } }; } public static SignalRMessage InfoEvent(string title, string subtitle) { return new SignalRMessage { Name = Info, Title = title, SubTitle = subtitle, Progress = ProgressType.None, EventType = ProgressEventType.Single, Body = new { Title = title, SubTitle = subtitle, } }; } public static SignalRMessage LibraryModifiedEvent(int libraryId, string action) { return new SignalRMessage { Name = LibraryModified, Title = "Library modified", Progress = ProgressType.None, EventType = ProgressEventType.Single, Body = new { LibrayId = libraryId, Action = action, } }; } public static SignalRMessage DownloadProgressEvent(string username, string downloadName, float progress, string eventType = "updated") { return new SignalRMessage() { Name = DownloadProgress, Title = $"Downloading {downloadName}", SubTitle = $"Preparing {username.SentenceCase()} the download of {downloadName}", EventType = eventType, Progress = ProgressType.Determinate, Body = new { UserName = username, DownloadName = downloadName, Progress = progress } }; } /// /// Represents a file being scanned by Kavita for processing and grouping /// /// Does not have a progress as it's unknown how many files there are. Instead sends -1 to represent indeterminate /// /// /// /// public static SignalRMessage FileScanProgressEvent(string folderPath, string libraryName, string eventType) { return new SignalRMessage() { Name = FileScanProgress, Title = $"Scanning {libraryName}", SubTitle = folderPath, EventType = eventType, Progress = ProgressType.Indeterminate, Body = new { Title = $"Scanning {libraryName}", Subtitle = folderPath, Filename = folderPath, EventTime = DateTime.Now, } }; } /// /// This informs the UI with details about what is being processed by the Scanner /// /// /// /// /// public static SignalRMessage LibraryScanProgressEvent(string libraryName, string eventType, string seriesName = "") { return new SignalRMessage() { Name = ScanProgress, Title = $"Processing {seriesName}", SubTitle = seriesName, EventType = eventType, Progress = ProgressType.Indeterminate, Body = null }; } public static SignalRMessage CoverUpdateEvent(int id, string entityType) { return new SignalRMessage() { Name = CoverUpdate, Title = "Updating Cover", Progress = ProgressType.None, Body = new { Id = id, EntityType = entityType, } }; } public static SignalRMessage UserProgressUpdateEvent(int userId, string username, int seriesId, int volumeId, int chapterId, int pagesRead) { return new SignalRMessage() { Name = UserProgressUpdate, Title = "Updating User Progress", Progress = ProgressType.None, Body = new { UserId = userId, Username = username, SeriesId = seriesId, VolumeId = volumeId, ChapterId = chapterId, PagesRead = pagesRead, } }; } public static SignalRMessage SiteThemeProgressEvent(string subtitle, string themeName, string eventType) { return new SignalRMessage() { Name = SiteThemeProgress, Title = "Scanning Site Theme", SubTitle = subtitle, EventType = eventType, Progress = ProgressType.Indeterminate, Body = new { ThemeName = themeName, } }; } public static SignalRMessage BookThemeProgressEvent(string subtitle, string themeName, string eventType) { return new SignalRMessage() { Name = BookThemeProgress, Title = "Scanning Book Theme", SubTitle = subtitle, EventType = eventType, Progress = ProgressType.Indeterminate, Body = new { ThemeName = themeName, } }; } public static SignalRMessage UserUpdateEvent(int userId, string userName) { return new SignalRMessage() { Name = UserUpdate, Title = "User Update", Progress = ProgressType.None, Body = new { UserId = userId, UserName = userName } }; } public static SignalRMessage ConvertBookmarksProgressEvent(float progress, string eventType) { return new SignalRMessage() { Name = ConvertBookmarksProgress, Title = "Converting Bookmarks", SubTitle = string.Empty, EventType = eventType, Progress = ProgressType.Determinate, Body = new { Progress = progress, EventTime = DateTime.Now } }; } public static SignalRMessage ConvertCoverProgressEvent(float progress, string eventType) { return new SignalRMessage() { Name = ConvertCoversProgress, Title = "Converting Covers", SubTitle = string.Empty, EventType = eventType, Progress = ProgressType.Determinate, Body = new { Progress = progress, EventTime = DateTime.Now } }; } public static SignalRMessage ScrobblingKeyExpiredEvent(ScrobbleProvider provider) { return new SignalRMessage { Name = ScrobblingKeyExpired, Title = "Scrobbling Key Expired", SubTitle = provider + " expired. Please re-generate on User Account page.", Progress = ProgressType.None, EventType = ProgressEventType.Single, }; } }