{"version":3,"file":"main.f4689814a804b7af.js","mappings":"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","names":["y","g","constructor","u","o","this","canActivate","accountService","currentUser$","pipe","hasAdminRole","toastr","error","d","factory","p","a","l","toasts","filter","message","length","localStorage","setItem","urlKey","window","location","pathname","router","navigateByUrl","C","i","parseInt","url","split","isNaN","memberService","hasLibraryAccess","e","r","reset","libraries","series","collections","readingLists","persons","genres","tags","files","chapters","title","value","selected","v","M","x","D","k","K","currentUserSource","asObservable","messages$","G","event","payload","userName","z","currentUser","username","refreshToken","subscribe","ngOnDestroy","onDestroy","next","complete","roles","includes","hasChangePasswordRole","hasDownloadRole","getRoles","httpClient","get","baseUrl","login","post","setCurrentUser","messageHub","createHubConnection","getDecodedToken","token","role","Array","isArray","push","userKey","JSON","stringify","lastLoginKey","themeService","setTheme","preferences","theme","name","defaultTheme","startRefreshTokenTimer","stopRefreshTokenTimer","logout","removeItem","stopHubConnection","register","migrateUser","responseType","confirmMigrationEmail","resendConfirmationEmail","inviteUser","confirmEmail","getInviteUrl","parse","atob","requestResetPasswordEmail","encodeURIComponent","confirmResetPasswordEmail","resetPassword","password","oldPassword","update","getPreferences","updatePreferences","getUserFromLocalStorage","getItem","resetApiKey","apiKey","refreshTokenTimeout","Date","exp","getTime","now","setTimeout","clearTimeout","isAdmin","_resetActions","collectionTagActions","action","Edit","callback","dummyCallback","requiresAdmin","seriesActions","Scan","RefreshMetadata","AnalyzeFiles","Delete","AddToCollection","libraryActions","chapterActions","volumeActions","Download","getLibraryActions","map","Object","forEach","getSeriesActions","getVolumeActions","getChapterActions","getCollectionTagActions","getReadingListActions","readingListActions","getBookmarkActions","bookmarkActions","MarkAsRead","MarkAsUnread","AddToReadingList","AddToWantToReadList","RemoveFromWantToReadList","IncognitoRead","ViewSeries","DownloadBookmark","R","b","L","h","f","B","V","toLowerCase","indexOf","listForm","filterQuery","ngOnInit","addControl","loading","cdRef","markForCheck","collectionService","allTags","lists","ngAfterViewInit","inputElem","nativeElement","select","close","modal","create","addByMultiple","seriesIds","success","addToCollection","id","selectors","E","O","readingListService","getReadingLists","result","createList","addToList","type","Multiple_Series","updateByMultipleSeries","seriesId","Series","updateBySeries","Volume","volumeId","updateByVolume","Chapter","chapterId","updateByChapter","Multiple","volumeIds","chapterIds","updateByMultiple","ee","disabled","tabs","Breakpoint","S","reviewGroup","readingList","summary","imageUrls","imageService","randomize","getReadingListCoverImage","ngModal","dismiss","save","trim","readingListId","promoted","coverImageLocked","selectedCover","uploadService","updateReadingListCoverImage","togglePromotion","updateSelectedIndex","coverImageIndex","updateSelectedImage","handleReset","pe","te","scanLibrary","hasOwnProperty","libraryService","scan","info","refreshMetadata","confirmService","confirm","analyzeFiles","alert","analyze","markSeriesAsRead","seriesService","markRead","pagesRead","pages","markSeriesAsUnread","markUnread","scanSeries","libraryId","analyzeFilesForSeries","refreshMetdata","markVolumeAsRead","readerService","markVolumeRead","markVolumeAsUnread","markVolumeUnread","markChapterAsRead","saveProgress","markChapterAsUnread","markMultipleAsRead","markMultipleRead","markMultipleAsUnread","markMultipleUnread","markMultipleSeriesAsRead","markMultipleSeriesRead","markMultipleSeriesAsUnread","markMultipleSeriesUnread","addMultipleToReadingList","readingListModalRef","modalService","open","scrollable","size","componentInstance","closed","dismissed","addMultipleSeriesToWantToReadList","addSeriesToWantToRead","removeMultipleSeriesFromWantToReadList","removeSeriesToWantToRead","addMultipleSeriesToReadingList","addMultipleSeriesToCollectionTag","collectionModalRef","windowClass","addSeriesToReadingList","addVolumeToReadingList","addChapterToReadingList","editReadingList","deleteMultipleSeries","deleteSeries","delete","promptIfForce","defaultConfirm","header","buttons","text","search","coverImage","getCollectionCoverImage","updateTag","updateSeriesForTag","tag","seriesIdsToRemove","collectionTagId","collectionTagTitle","currentTheme$","isDarkTheme","placeholderImage","errorImage","getRecentlyAddedItem","getVolumeCoverImage","getChapterCoverImage","getEntityTypeFromUrl","substring","replace","getSeriesCoverImage","getBookmarkedImage","getCoverUploadImage","updateErroredImage","target","src","Math","round","random","getLibraryNames","libraryNames","getLibraryName","listDirectories","getJumpBar","getLibraries","getLibrariesForMember","updateLibrariesForMember","selectedLibraries","getLibraryType","libraryTypes","getMembers","getMemberNames","adminExists","deleteMember","hasReadingProgress","getPendingInvites","UpdateAvailable","A","messagesSource","onlineUsersSource","isEventType","NotificationProgress","eventType","hubConnection","withUrl","hubUrl","accessTokenFactory","withAutomaticReconnect","build","start","catch","console","on","OnlineUsers","ScanSeries","body","ScanLibraryProgress","ConvertBookmarksProgress","WordCountAnalyzerProgress","LibraryModified","SiteThemeProgress","SeriesAddedToCollection","UserProgressUpdate","UserUpdate","Error","Info","SeriesAdded","SeriesRemoved","CoverUpdate","stop","sendMessage","invoke","navbarVisibleSource","sideNavCollapseSource","sideNavVisibilitySource","renderer","createRenderer","showNavBar","localStorageSideNavKey","showSideNav","setStyle","document","querySelector","hideNavBar","removeStyle","hideSideNav","toggleSideNav","getNavigationArray","downloadPdf","bookmark","page","unbookmark","getAllBookmarks","getBookmarks","getBookmarksForVolume","getBookmarksForSeries","clearBookmarks","clearMultipleBookmarks","getBookmarkInfo","getProgress","getPageUrl","getBookmarkPageUrl","getChapterInfo","P","pageNum","bookScrollId","getNextChapter","getPrevChapter","hasSeriesProgress","getCurrentChapter","getTimeLeft","setOverrideStyles","originalBodyColor","style","background","setAttribute","resetOverrideStyles","imageUrlToPageNum","getNextChapterUrl","lastIndexOf","getQueryParams","getQueryParamsObject","incognitoMode","enterFullscreen","fullscreenElement","requestFullscreen","then","exitFullscreen","checkFullscreenMode","closeReader","back","getReadingList","utilityService","addPaginationIfExists","observe","params","createPaginatedResult","getReadingListsForSeries","getListItems","updatePosition","readingListItemId","fromPosition","toPosition","deleteItem","removeRead","actionListFilter","scrollContainerSource","events","scrollPosition","pageYOffset","documentElement","scrollTop","scrollTo","scroll","top","behavior","scrollToX","left","setScrollContainer","getAllSeries","createSeriesFilter","paginatedResults","getSeriesForLibrary","getAllSeriesByIds","getSeries","getVolumes","getVolume","getChapter","getChapterMetadata","getSeriesForMangaFile","getSeriesForChapter","updateRating","userRating","userReview","updateSeries","getRecentlyAdded","getRecentlyUpdatedSeries","getWantToRead","getOnDeck","forceUpdate","getMetadata","collectionTags","updateMetadata","seriesMetadata","getSeriesForTag","paginatedSeriesForTagsResults","getRelatedForSeries","updateRelationships","adaptations","characters","sequels","prequels","contains","others","sideStories","spinOffs","alternativeSettings","alternativeVersions","doujinshis","getSeriesDetail","formats","writers","artists","penciller","inker","colorist","letterer","coverArtist","editor","publisher","character","translators","rating","readStatus","read","inProgress","notRead","sortOptions","ageRating","languages","publicationStatus","seriesNameQuery","Q","j","currentThemeSource","themesSource","getThemes","U","getColorScheme","getComputedStyle","getPropertyValue","getCssVariable","themeCache","clearThemes","unsetThemes","setDefault","themeId","setBookTheme","unsetBookThemes","addClass","clearBookTheme","find","selector","provider","hasThemeInHead","fetchThemeContent","createElement","appendChild","createTextNode","head","from","children","tagName","domSantizer","sanitize","classList","remove","startsWith","uploadByUrl","updateSeriesCoverImage","_cleanBase64Url","updateCollectionCoverImage","updateChapterCoverImage","resetChapterCoverLock","nonAdminActions","actions","adminActions","preventClick","stopPropagation","preventDefault","performAction","actionHandler","emit","F","w","join","form","fb","group","coverImageUrl","getBase64Image","width","height","getContext","alpha","drawImage","toDataURL","selectImage","selectedIndex","imageSelected","selectedBase64Url","applyImage","showApplyButton","applyCover","appliedIndex","resetImage","resetCover","loadImage","Image","crossOrigin","onload","handleUrlImageAdd","onerror","W","setValue","changeMode","mode","setupEnterHandler","focus","dropped","fileEntry","isFile","file","FileReader","handleFileImageAdd","readAsDataURL","imageUrlsChange","fileOver","fileLeave","resetClicked","key","transform","pure","dom","charAt","toUpperCase","substr","progress","total","loaded","state","content","headers","filename","downloadsSource","downloadSubtitle","number","download","downloadSeriesSize","downloadSeries","downloadVolumeSize","downloadVolume","downloadChapterSize","downloadChapter","downloadBookmarks","downloadLogs","Y","promptForDownloadSize","confirmSize","reportProgress","leading","trailing","updateDownloadState","finalizeDownloadState","getValue","entityType","subTitle","findIndex","SIZE_WARNING","humanFileSize","bookmarks","abs","$","toFixed","Format","updateUrlFromFilter","currentPage","urlFromFilter","href","history","replaceState","replacePaginationOnUrl","updateUrlFromPagination","pagination","queryParamMap","itemsPerPage","totalItems","totalPages","joinFilter","Genres","AgeRating","PublicationStatus","Tags","Languages","CollectionTags","Libraries","Writers","Artists","Character","Colorist","CoverArtists","Editor","Inker","Letterer","Penciller","Publisher","Translator","ReadStatus","sortField","isAscending","SortBy","Rating","Name","filterPresetsFromUrl","J","oe","Number","decodeURIComponent","RIGHT_ARROW","parseFloat","mangaFormatToText","mangaFormatKeys","keys","formatChapterName","cleanSpecialTitle","isVolume","isChapter","isSeries","asVolume","asChapter","asSeries","getActiveBreakpoint","innerWidth","Mobile","Tablet","Desktop","isInViewport","getBoundingClientRect","bottom","innerHeight","clientHeight","right","clientWidth","deepEqual","isObject","append","getWindowDimensions","getJumpKeys","test","sort","config","_button_sort","clickButton","defaultAlert","_type","Promise","hubService","processEvents","imageUrl","changeDetectionRef","ngOnChanges","imgElem","maxWidth","maxHeight","borderRadius","objectFit","production","apiUrl","path","loadChildren","s","AdminModule","CollectionsModule","UserSettingsModule","ReadingListModule","n","RegistrationModule","AnnouncementsModule","BookmarkModule","AllSeriesModule","DashboardModule","WantToReadModule","runGuardsAndResolvers","pathMatch","LibraryDetailModule","SeriesDetailModule","MangaReaderModule","BookReaderModule","PdfReaderModule","redirectTo","scrollPositionRestoration","preloadingStrategy","t","c","_","T","updateHightlight","link","highlighted","endsWith","comparisonMethod","Z","X","ie","se","re","ne","navService","sideNavCollapsed$","ge","actionFactoryService","handleAction","bind","actionService","getLibraryTypeIcon","toggleNavBar","Se","fe","MangaFormat","ft","ae","progressEventsSource","singleUpdateSource","errorSource","infoSource","EVENTS","processNotificationProgressEvent","activeEvents","isAdmin$","mergeOrUpdate","max","handleUpdateAvailableClick","updateNotificationModalRef","Le","updateData","seeMore","Re","removeErrorOrInfo","clearAllErrorOrInfos","prettyPrintProgress","trunc","qt","searchTerm","typeaheadForm","hasData","noResultsTemplate","grouppedData","handleDocumentClick","handleKeyPress","hasFocus","initialValue","valueChanges","debounceTime","minQueryLength","prevSearchTerm","inputChanged","onInputFocus","openDropdown","handleResultlick","resetField","clearField","focusChanged","clear","en","Un","me","_e","Hn","Yn","originalName","zn","localizedName","scrollElem","scrollService","scrollContainer$","checkBackToTopNeeded","backToTopNeeded","moveFocus","getElementById","onChangeSearch","isLoading","searchResults","goTo","clearSearch","navigate","queryParams","goToPerson","searchViewRef","clickSeriesSearchResult","clickFileSearchResult","clickChapterSearchResult","clickLibraryResult","clickCollectionSearchResult","clickReadingListSearchResult","scrollToTop","focusUpdate","searchFocused","kn","resettable","ngbModal","hasOpenModals","dismissAll","setDocHeight","setProperty","Fn","intercept","clone","setHeaders","Authorization","handle","wn","status","handleValidationError","handleAuthError","handleNotFound","handleServerException","previousToastMessage","details","description","flat","errors","statusText","Blob","Wn","ye","Jn","Qn","Kn","bootstrap","provide","he","useClass","multi","be","useFactory","imports","Bn","Nn","Ce","positionClass","preventDuplicates","timeOut","countDuplicates","autoDismiss","N","bootstrapModule"],"sourceRoot":"webpack:///","sources":["./src/app/_guards/admin.guard.ts","./src/app/_guards/auth.guard.ts","./src/app/_guards/library-access.guard.ts","./src/app/_models/library.ts","./src/app/_models/manga-format.ts","./src/app/_models/pagination.ts","./src/app/_models/person.ts","./src/app/_models/preferences/site-theme.ts","./src/app/_models/search/search-result-group.ts","./src/app/_models/series-filter.ts","./src/app/_services/account.service.ts","./src/app/_services/action-factory.service.ts","./src/app/cards/_modals/bulk-add-to-collection/bulk-add-to-collection.component.html","./src/app/cards/_modals/bulk-add-to-collection/bulk-add-to-collection.component.ts","./src/app/reading-list/_modals/add-to-list-modal/add-to-list-modal.component.html","./src/app/reading-list/_modals/add-to-list-modal/add-to-list-modal.component.ts","./src/app/reading-list/_modals/edit-reading-list-modal/edit-reading-list-modal.component.html","./src/app/reading-list/_modals/edit-reading-list-modal/edit-reading-list-modal.component.ts","./src/app/_services/action.service.ts","./src/app/_services/collection-tag.service.ts","./src/app/_services/image.service.ts","./src/app/_services/library.service.ts","./src/app/_services/member.service.ts","./src/app/_services/message-hub.service.ts","./src/app/_services/nav.service.ts","./src/app/_services/reader.service.ts","./src/app/_services/reading-list.service.ts","./src/app/_services/scroll.service.ts","./src/app/_services/series.service.ts","./src/app/_services/theme.service.ts","./src/app/_services/upload.service.ts","./src/app/cards/card-item/card-actionables/card-actionables.component.html","./src/app/cards/card-item/card-actionables/card-actionables.component.ts","./src/app/metadata-filter/metadata-filter.module.ts","./src/app/cards/cards.module.ts","./src/app/cards/cover-image-chooser/cover-image-chooser.component.html","./src/app/cards/cover-image-chooser/cover-image-chooser.component.ts","./src/app/pipe/filter.pipe.ts","./src/app/pipe/manga-format-icon.pipe.ts","./src/app/pipe/manga-format.pipe.ts","./src/app/pipe/pipe.module.ts","./src/app/pipe/safe-html.pipe.ts","./src/app/pipe/sentence-case.pipe.ts","./src/app/shared/_providers/saver.provider.ts","./src/app/shared/_models/download.ts","./src/app/shared/_services/download.service.ts","./src/app/shared/_services/filter-utilities.service.ts","./src/app/shared/_services/utility.service.ts","./src/app/shared/circular-loader/circular-loader.component.html","./src/app/shared/circular-loader/circular-loader.component.ts","./src/app/shared/confirm-dialog/_models/confirm-config.ts","./src/app/shared/confirm-dialog/confirm-dialog.component.html","./src/app/shared/confirm-dialog/confirm-dialog.component.ts","./src/app/shared/confirm.service.ts","./src/app/shared/image/image.component.ts","./src/app/shared/image/image.component.html","./src/app/shared/shared.module.ts","./src/app/shared/update-notification/update-notification-modal.component.html","./src/app/shared/update-notification/update-notification-modal.component.ts","./src/app/sidenav/sidenav.module.ts","./src/app/typeahead/typeahead.module.ts","./src/environments/environment.prod.ts","./src/app/app-routing.module.ts","./src/app/sidenav/side-nav-item/side-nav-item.component.html","./src/app/sidenav/side-nav-item/side-nav-item.component.ts","./src/app/sidenav/side-nav/side-nav.component.html","./src/app/sidenav/side-nav/side-nav.component.ts","./src/app/shared/series-format/series-format.component.html","./src/app/shared/series-format/series-format.component.ts","./src/app/nav/events-widget/events-widget.component.html","./src/app/nav/events-widget/events-widget.component.ts","./src/app/nav/grouped-typeahead/grouped-typeahead.component.html","./src/app/nav/grouped-typeahead/grouped-typeahead.component.ts","./src/app/pipe/person-role.pipe.ts","./src/app/nav/nav-header/nav-header.component.html","./src/app/nav/nav-header/nav-header.component.ts","./src/app/app.component.html","./src/app/app.component.ts","./src/app/_interceptors/jwt.interceptor.ts","./src/app/_interceptors/error.interceptor.ts","./src/app/nav/nav.module.ts","./src/app/app.module.ts","./src/main.ts"],"sourcesContent":["import { Injectable } from '@angular/core';\nimport { CanActivate } from '@angular/router';\nimport { ToastrService } from 'ngx-toastr';\nimport { Observable } from 'rxjs';\nimport { map, take } from 'rxjs/operators';\nimport { AccountService } from '../_services/account.service';\n\n@Injectable({\n providedIn: 'root'\n})\nexport class AdminGuard implements CanActivate {\n constructor(private accountService: AccountService, private toastr: ToastrService) {}\n\n canActivate(): Observable {\n // this automaticallys subs due to being router guard\n return this.accountService.currentUser$.pipe(take(1),\n map((user) => {\n if (user && this.accountService.hasAdminRole(user)) {\n return true;\n }\n \n this.toastr.error('You are not authorized to view this page.');\n return false;\n })\n );\n }\n}\n","import { Injectable } from '@angular/core';\nimport { CanActivate, Router } from '@angular/router';\nimport { ToastrService } from 'ngx-toastr';\nimport { Observable } from 'rxjs';\nimport { map, take } from 'rxjs/operators';\nimport { AccountService } from '../_services/account.service';\n\n@Injectable({\n providedIn: 'root'\n})\nexport class AuthGuard implements CanActivate {\n public urlKey: string = 'kavita--auth-intersection-url';\n constructor(private accountService: AccountService, private router: Router, private toastr: ToastrService) {}\n\n canActivate(): Observable {\n return this.accountService.currentUser$.pipe(take(1),\n map((user) => {\n if (user) {\n return true;\n }\n if (this.toastr.toasts.filter(toast => toast.message === 'Unauthorized' || toast.message === 'You are not authorized to view this page.').length === 0) {\n this.toastr.error('You are not authorized to view this page.');\n }\n localStorage.setItem(this.urlKey, window.location.pathname);\n this.router.navigateByUrl('/login');\n return false;\n })\n );\n }\n}\n","import { Injectable } from '@angular/core';\nimport { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';\nimport { Observable, of } from 'rxjs';\nimport { MemberService } from '../_services/member.service';\n\n@Injectable({\n providedIn: 'root'\n})\nexport class LibraryAccessGuard implements CanActivate {\n\n constructor(private memberService: MemberService) {}\n\n canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable {\n const libraryId = parseInt(state.url.split('library/')[1], 10);\n if (isNaN(libraryId)) return of(false);\n return this.memberService.hasLibraryAccess(libraryId);\n }\n}\n","export enum LibraryType {\n Manga = 0,\n Comic = 1,\n Book = 2,\n}\n\nexport interface Library {\n id: number;\n name: string;\n lastScanned: string;\n type: LibraryType;\n folders: string[];\n}","export enum MangaFormat {\n IMAGE = 0,\n ARCHIVE = 1,\n UNKNOWN = 2,\n EPUB = 3,\n PDF = 4\n}","export interface Pagination {\n currentPage: number;\n itemsPerPage: number;\n totalItems: number;\n totalPages: number;\n}\n\nexport class PaginatedResult {\n result!: T;\n pagination!: Pagination;\n}\n","export enum PersonRole {\n Other = 1,\n Artist = 2,\n Writer = 3,\n Penciller = 4,\n Inker = 5,\n Colorist = 6,\n Letterer = 7,\n CoverArtist = 8,\n Editor = 9,\n Publisher = 10,\n Character = 11,\n Translator = 12\n}\n\nexport interface Person {\n id: number;\n name: string;\n role: PersonRole;\n}","/**\n * Where does the theme come from\n */\n export enum ThemeProvider {\n System = 1,\n User = 2\n }\n \n /**\n * Theme for the whole instance\n */\n export interface SiteTheme {\n id: number;\n name: string;\n filePath: string;\n isDefault: boolean;\n provider: ThemeProvider;\n /**\n * The actual class the root is defined against. It is generated at the backend.\n */\n selector: string;\n }","import { Chapter } from \"../chapter\";\nimport { Library } from \"../library\";\nimport { MangaFile } from \"../manga-file\";\nimport { SearchResult } from \"../search-result\";\nimport { Tag } from \"../tag\";\n\nexport class SearchResultGroup {\n libraries: Array = [];\n series: Array = [];\n collections: Array = [];\n readingLists: Array = [];\n persons: Array = [];\n genres: Array = [];\n tags: Array = [];\n files: Array = [];\n chapters: Array = [];\n\n reset() {\n this.libraries = [];\n this.series = [];\n this.collections = [];\n this.readingLists = [];\n this.persons = [];\n this.genres = [];\n this.tags = [];\n this.files = [];\n this.chapters = []; \n }\n}","import { MangaFormat } from \"./manga-format\";\n\nexport interface FilterItem {\n title: string;\n value: T;\n selected: boolean;\n}\n\nexport interface SeriesFilter {\n formats: Array;\n libraries: Array,\n readStatus: ReadStatus;\n genres: Array;\n writers: Array;\n artists: Array;\n penciller: Array;\n inker: Array;\n colorist: Array;\n letterer: Array;\n coverArtist: Array;\n editor: Array;\n publisher: Array;\n character: Array;\n translators: Array;\n collectionTags: Array;\n rating: number;\n ageRating: Array;\n sortOptions: SortOptions | null;\n tags: Array;\n languages: Array;\n publicationStatus: Array;\n seriesNameQuery: string;\n}\n\nexport interface SortOptions {\n sortField: SortField;\n isAscending: boolean;\n}\n\nexport enum SortField {\n SortName = 1,\n Created = 2,\n LastModified = 3,\n LastChapterAdded = 4,\n TimeToRead = 5\n}\n\nexport interface ReadStatus {\n notRead: boolean,\n inProgress: boolean,\n read: boolean,\n}\n\nexport const mangaFormatFilters = [\n {\n title: 'Images',\n value: MangaFormat.IMAGE,\n selected: false\n },\n {\n title: 'EPUB',\n value: MangaFormat.EPUB,\n selected: false\n },\n {\n title: 'PDF',\n value: MangaFormat.PDF,\n selected: false\n },\n {\n title: 'ARCHIVE',\n value: MangaFormat.ARCHIVE,\n selected: false\n }\n];\n\nexport interface FilterEvent {\n filter: SeriesFilter;\n isFirst: boolean;\n}\n\n","import { HttpClient } from '@angular/common/http';\nimport { Injectable, OnDestroy } from '@angular/core';\nimport { Observable, of, ReplaySubject, Subject } from 'rxjs';\nimport { filter, map, switchMap, takeUntil } from 'rxjs/operators';\nimport { environment } from 'src/environments/environment';\nimport { Preferences } from '../_models/preferences/preferences';\nimport { User } from '../_models/user';\nimport { Router } from '@angular/router';\nimport { EVENTS, MessageHubService } from './message-hub.service';\nimport { ThemeService } from './theme.service';\nimport { InviteUserResponse } from '../_models/invite-user-response';\nimport { UserUpdateEvent } from '../_models/events/user-update-event';\n\n@Injectable({\n providedIn: 'root'\n})\nexport class AccountService implements OnDestroy {\n\n baseUrl = environment.apiUrl;\n userKey = 'kavita-user';\n public lastLoginKey = 'kavita-lastlogin';\n currentUser: User | undefined;\n\n // Stores values, when someone subscribes gives (1) of last values seen.\n private currentUserSource = new ReplaySubject(1);\n currentUser$ = this.currentUserSource.asObservable();\n\n /**\n * SetTimeout handler for keeping track of refresh token call\n */\n private refreshTokenTimeout: ReturnType | undefined;\n\n private readonly onDestroy = new Subject();\n\n constructor(private httpClient: HttpClient, private router: Router, \n private messageHub: MessageHubService, private themeService: ThemeService) {\n messageHub.messages$.pipe(filter(evt => evt.event === EVENTS.UserUpdate), \n map(evt => evt.payload as UserUpdateEvent),\n filter(userUpdateEvent => userUpdateEvent.userName === this.currentUser?.username), \n switchMap(() => this.refreshToken()))\n .subscribe(() => {});\n }\n \n ngOnDestroy(): void {\n this.onDestroy.next();\n this.onDestroy.complete();\n }\n\n hasAdminRole(user: User) {\n return user && user.roles.includes('Admin');\n }\n\n hasChangePasswordRole(user: User) {\n return user && user.roles.includes('Change Password');\n }\n\n hasDownloadRole(user: User) {\n return user && user.roles.includes('Download');\n }\n\n getRoles() {\n return this.httpClient.get(this.baseUrl + 'account/roles');\n }\n\n login(model: {username: string, password: string}): Observable {\n return this.httpClient.post(this.baseUrl + 'account/login', model).pipe(\n map((response: User) => {\n const user = response;\n if (user) {\n this.setCurrentUser(user);\n this.messageHub.createHubConnection(user, this.hasAdminRole(user));\n }\n }),\n takeUntil(this.onDestroy)\n );\n }\n\n setCurrentUser(user?: User) {\n if (user) {\n user.roles = [];\n const roles = this.getDecodedToken(user.token).role;\n Array.isArray(roles) ? user.roles = roles : user.roles.push(roles);\n\n localStorage.setItem(this.userKey, JSON.stringify(user));\n localStorage.setItem(this.lastLoginKey, user.username);\n if (user.preferences && user.preferences.theme) {\n this.themeService.setTheme(user.preferences.theme.name);\n } else {\n this.themeService.setTheme(this.themeService.defaultTheme);\n }\n } else {\n this.themeService.setTheme(this.themeService.defaultTheme);\n }\n\n this.currentUser = user;\n this.currentUserSource.next(user);\n \n if (this.currentUser !== undefined) {\n this.startRefreshTokenTimer();\n } else {\n this.stopRefreshTokenTimer();\n }\n }\n\n logout() {\n localStorage.removeItem(this.userKey);\n this.currentUserSource.next(undefined);\n this.currentUser = undefined;\n this.stopRefreshTokenTimer();\n // Upon logout, perform redirection\n this.router.navigateByUrl('/login');\n this.messageHub.stopHubConnection();\n }\n\n\n /**\n * Registers the first admin on the account. Only used for that. All other registrations must occur through invite\n * @param model \n * @returns \n */\n register(model: {username: string, password: string, email: string}) {\n return this.httpClient.post(this.baseUrl + 'account/register', model).pipe(\n map((user: User) => {\n return user;\n }),\n takeUntil(this.onDestroy)\n );\n }\n\n migrateUser(model: {email: string, username: string, password: string, sendEmail: boolean}) {\n return this.httpClient.post(this.baseUrl + 'account/migrate-email', model, {responseType: 'text' as 'json'});\n }\n\n confirmMigrationEmail(model: {email: string, token: string}) {\n return this.httpClient.post(this.baseUrl + 'account/confirm-migration-email', model);\n }\n\n resendConfirmationEmail(userId: number) {\n return this.httpClient.post(this.baseUrl + 'account/resend-confirmation-email?userId=' + userId, {}, {responseType: 'text' as 'json'});\n }\n\n inviteUser(model: {email: string, roles: Array, libraries: Array}) {\n return this.httpClient.post(this.baseUrl + 'account/invite', model);\n }\n\n confirmEmail(model: {email: string, username: string, password: string, token: string}) {\n return this.httpClient.post(this.baseUrl + 'account/confirm-email', model);\n }\n\n /**\n * Given a user id, returns a full url for setting up the user account\n * @param userId \n * @returns \n */\n getInviteUrl(userId: number, withBaseUrl: boolean = true) {\n return this.httpClient.get(this.baseUrl + 'account/invite-url?userId=' + userId + '&withBaseUrl=' + withBaseUrl, {responseType: 'text' as 'json'});\n }\n\n getDecodedToken(token: string) {\n return JSON.parse(atob(token.split('.')[1]));\n }\n\n requestResetPasswordEmail(email: string) {\n return this.httpClient.post(this.baseUrl + 'account/forgot-password?email=' + encodeURIComponent(email), {}, {responseType: 'text' as 'json'});\n }\n\n confirmResetPasswordEmail(model: {email: string, token: string, password: string}) {\n return this.httpClient.post(this.baseUrl + 'account/confirm-password-reset', model, {responseType: 'json' as 'text'});\n }\n\n resetPassword(username: string, password: string, oldPassword: string) {\n return this.httpClient.post(this.baseUrl + 'account/reset-password', {username, password, oldPassword}, {responseType: 'json' as 'text'});\n }\n\n update(model: {email: string, roles: Array, libraries: Array, userId: number}) {\n return this.httpClient.post(this.baseUrl + 'account/update', model);\n }\n\n /**\n * This will get latest preferences for a user and cache them into user store\n * @returns \n */\n getPreferences() {\n return this.httpClient.get(this.baseUrl + 'users/get-preferences').pipe(map(pref => {\n if (this.currentUser !== undefined || this.currentUser != null) {\n this.currentUser.preferences = pref;\n this.setCurrentUser(this.currentUser);\n }\n return pref;\n }), takeUntil(this.onDestroy));\n }\n\n updatePreferences(userPreferences: Preferences) {\n return this.httpClient.post(this.baseUrl + 'users/update-preferences', userPreferences).pipe(map(settings => {\n if (this.currentUser !== undefined || this.currentUser != null) {\n this.currentUser.preferences = settings;\n this.setCurrentUser(this.currentUser);\n }\n return settings;\n }), takeUntil(this.onDestroy));\n }\n\n getUserFromLocalStorage(): User | undefined {\n\n const userString = localStorage.getItem(this.userKey);\n \n if (userString) {\n return JSON.parse(userString)\n };\n\n return undefined;\n }\n\n resetApiKey() {\n return this.httpClient.post(this.baseUrl + 'account/reset-api-key', {}, {responseType: 'text' as 'json'}).pipe(map(key => {\n const user = this.getUserFromLocalStorage();\n if (user) {\n user.apiKey = key;\n\n localStorage.setItem(this.userKey, JSON.stringify(user));\n \n this.currentUserSource.next(user);\n this.currentUser = user;\n }\n return key;\n }));\n }\n\n private refreshToken() {\n if (this.currentUser === null || this.currentUser === undefined) return of();\n \n return this.httpClient.post<{token: string, refreshToken: string}>(this.baseUrl + 'account/refresh-token', {token: this.currentUser.token, refreshToken: this.currentUser.refreshToken}).pipe(map(user => {\n if (this.currentUser) {\n this.currentUser.token = user.token;\n this.currentUser.refreshToken = user.refreshToken;\n }\n \n this.setCurrentUser(this.currentUser);\n return user;\n }));\n }\n\n private startRefreshTokenTimer() {\n if (this.currentUser === null || this.currentUser === undefined) return;\n\n if (this.refreshTokenTimeout !== undefined) {\n this.stopRefreshTokenTimer();\n }\n\n const jwtToken = JSON.parse(atob(this.currentUser.token.split('.')[1]));\n // set a timeout to refresh the token a minute before it expires\n const expires = new Date(jwtToken.exp * 1000);\n const timeout = expires.getTime() - Date.now() - (60 * 1000);\n this.refreshTokenTimeout = setTimeout(() => this.refreshToken().subscribe(() => {}), timeout);\n }\n\n private stopRefreshTokenTimer() {\n if (this.refreshTokenTimeout !== undefined) {\n clearTimeout(this.refreshTokenTimeout);\n }\n }\n\n\n\n}\n","import { Injectable } from '@angular/core';\nimport { Chapter } from '../_models/chapter';\nimport { CollectionTag } from '../_models/collection-tag';\nimport { Library } from '../_models/library';\nimport { MangaFormat } from '../_models/manga-format';\nimport { ReadingList } from '../_models/reading-list';\nimport { Series } from '../_models/series';\nimport { Volume } from '../_models/volume';\nimport { AccountService } from './account.service';\n\nexport enum Action {\n /**\n * Mark entity as read\n */\n MarkAsRead = 0,\n /**\n * Mark entity as unread\n */\n MarkAsUnread = 1,\n /**\n * Invoke a Scan on Series/Library\n */\n Scan = 2,\n /**\n * Delete the entity\n */\n Delete = 3,\n /**\n * Open edit modal\n */\n Edit = 4,\n /**\n * Open details modal\n */\n Info = 5,\n /**\n * Invoke a refresh covers\n */\n RefreshMetadata = 6,\n /**\n * Download the entity\n */\n Download = 7,\n /**\n * Invoke an Analyze Files which calculates word count\n */\n AnalyzeFiles = 8,\n /**\n * Read in incognito mode aka no progress tracking\n */\n IncognitoRead = 9,\n /**\n * Add to reading list\n */\n AddToReadingList = 10,\n /**\n * Add to collection\n */\n AddToCollection = 11,\n /**\n * Essentially a download, but handled differently. Needed so card bubbles it up for handling\n */\n DownloadBookmark = 12,\n /**\n * Open Series detail page for said series\n */\n ViewSeries = 13,\n /**\n * Open the reader for entity\n */\n Read = 14,\n /**\n * Add to user's Want to Read List\n */\n AddToWantToReadList = 15,\n /**\n * Remove from user's Want to Read List\n */\n RemoveFromWantToReadList = 16,\n}\n\nexport interface ActionItem {\n title: string;\n action: Action;\n callback: (action: Action, data: T) => void;\n requiresAdmin: boolean;\n}\n\n@Injectable({\n providedIn: 'root'\n})\nexport class ActionFactoryService {\n\n libraryActions: Array> = [];\n\n seriesActions: Array> = [];\n\n volumeActions: Array> = [];\n\n chapterActions: Array> = [];\n\n collectionTagActions: Array> = [];\n\n readingListActions: Array> = [];\n\n bookmarkActions: Array> = [];\n\n isAdmin = false;\n hasDownloadRole = false;\n\n constructor(private accountService: AccountService) {\n this.accountService.currentUser$.subscribe(user => {\n if (user) {\n this.isAdmin = this.accountService.hasAdminRole(user);\n this.hasDownloadRole = this.accountService.hasDownloadRole(user);\n } else {\n this._resetActions();\n return; // If user is logged out, we don't need to do anything\n }\n\n this._resetActions();\n\n if (this.isAdmin) {\n this.collectionTagActions.push({\n action: Action.Edit,\n title: 'Edit',\n callback: this.dummyCallback,\n requiresAdmin: true\n });\n\n this.seriesActions.push({\n action: Action.Scan,\n title: 'Scan Series',\n callback: this.dummyCallback,\n requiresAdmin: true\n });\n\n this.seriesActions.push({\n action: Action.RefreshMetadata,\n title: 'Refresh Covers',\n callback: this.dummyCallback,\n requiresAdmin: true\n });\n\n this.seriesActions.push({\n action: Action.AnalyzeFiles,\n title: 'Analyze Files',\n callback: this.dummyCallback,\n requiresAdmin: true\n });\n\n this.seriesActions.push({\n action: Action.Delete,\n title: 'Delete',\n callback: this.dummyCallback,\n requiresAdmin: true\n });\n\n this.seriesActions.push({\n action: Action.AddToCollection,\n title: 'Add to Collection',\n callback: this.dummyCallback,\n requiresAdmin: true\n });\n\n this.seriesActions.push({\n action: Action.Edit,\n title: 'Edit',\n callback: this.dummyCallback,\n requiresAdmin: true\n });\n\n this.libraryActions.push({\n action: Action.Scan,\n title: 'Scan Library',\n callback: this.dummyCallback,\n requiresAdmin: true\n });\n\n this.libraryActions.push({\n action: Action.RefreshMetadata,\n title: 'Refresh Covers',\n callback: this.dummyCallback,\n requiresAdmin: true\n });\n\n this.libraryActions.push({\n action: Action.AnalyzeFiles,\n title: 'Analyze Files',\n callback: this.dummyCallback,\n requiresAdmin: true\n });\n \n this.chapterActions.push({\n action: Action.Edit,\n title: 'Details',\n callback: this.dummyCallback,\n requiresAdmin: false\n });\n }\n\n if (this.hasDownloadRole || this.isAdmin) {\n this.volumeActions.push({\n action: Action.Download,\n title: 'Download',\n callback: this.dummyCallback,\n requiresAdmin: false\n });\n\n this.chapterActions.push({\n action: Action.Download,\n title: 'Download',\n callback: this.dummyCallback,\n requiresAdmin: false\n });\n }\n });\n }\n\n getLibraryActions(callback: (action: Action, library: Library) => void) {\n const actions = this.libraryActions.map(a => {return {...a}});\n actions.forEach(action => action.callback = callback);\n return actions;\n }\n\n getSeriesActions(callback: (action: Action, series: Series) => void) {\n const actions = this.seriesActions.map(a => {return {...a}});\n actions.forEach(action => action.callback = callback);\n return actions;\n }\n\n getVolumeActions(callback: (action: Action, volume: Volume) => void) {\n const actions = this.volumeActions.map(a => {return {...a}});\n actions.forEach(action => action.callback = callback);\n return actions;\n }\n\n getChapterActions(callback: (action: Action, chapter: Chapter) => void) {\n const actions = this.chapterActions.map(a => {return {...a}});\n actions.forEach(action => action.callback = callback);\n return actions;\n }\n\n getCollectionTagActions(callback: (action: Action, collectionTag: CollectionTag) => void) {\n const actions = this.collectionTagActions.map(a => {return {...a}});\n actions.forEach(action => action.callback = callback);\n return actions;\n }\n\n getReadingListActions(callback: (action: Action, readingList: ReadingList) => void) {\n const actions = this.readingListActions.map(a => {return {...a}});\n actions.forEach(action => action.callback = callback);\n return actions;\n }\n\n getBookmarkActions(callback: (action: Action, series: Series) => void) {\n const actions = this.bookmarkActions.map(a => {return {...a}});\n actions.forEach(action => action.callback = callback);\n return actions;\n }\n\n dummyCallback(action: Action, data: any) {}\n\n _resetActions() {\n this.libraryActions = [];\n\n this.collectionTagActions = [];\n \n this.seriesActions = [\n {\n action: Action.MarkAsRead,\n title: 'Mark as Read',\n callback: this.dummyCallback,\n requiresAdmin: false\n },\n {\n action: Action.MarkAsUnread,\n title: 'Mark as Unread',\n callback: this.dummyCallback,\n requiresAdmin: false\n }, \n {\n action: Action.AddToReadingList,\n title: 'Add to Reading List',\n callback: this.dummyCallback,\n requiresAdmin: false\n },\n {\n action: Action.AddToWantToReadList,\n title: 'Add to Want To Read',\n callback: this.dummyCallback,\n requiresAdmin: false\n },\n {\n action: Action.RemoveFromWantToReadList,\n title: 'Remove from Want To Read',\n callback: this.dummyCallback,\n requiresAdmin: false\n }\n ];\n\n this.volumeActions = [\n {\n action: Action.MarkAsRead,\n title: 'Mark as Read',\n callback: this.dummyCallback,\n requiresAdmin: false\n },\n {\n action: Action.MarkAsUnread,\n title: 'Mark as Unread',\n callback: this.dummyCallback,\n requiresAdmin: false\n },\n {\n action: Action.AddToReadingList,\n title: 'Add to Reading List',\n callback: this.dummyCallback,\n requiresAdmin: false\n },\n {\n action: Action.IncognitoRead,\n title: 'Read Incognito',\n callback: this.dummyCallback,\n requiresAdmin: false\n },\n {\n action: Action.Edit,\n title: 'Details',\n callback: this.dummyCallback,\n requiresAdmin: false\n }\n ];\n\n this.chapterActions = [\n {\n action: Action.MarkAsRead,\n title: 'Mark as Read',\n callback: this.dummyCallback,\n requiresAdmin: false\n },\n {\n action: Action.MarkAsUnread,\n title: 'Mark as Unread',\n callback: this.dummyCallback,\n requiresAdmin: false\n },\n {\n action: Action.IncognitoRead,\n title: 'Read Incognito',\n callback: this.dummyCallback,\n requiresAdmin: false\n },\n {\n action: Action.AddToReadingList,\n title: 'Add to Reading List',\n callback: this.dummyCallback,\n requiresAdmin: false\n },\n ];\n\n this.readingListActions = [\n {\n action: Action.Edit,\n title: 'Edit',\n callback: this.dummyCallback,\n requiresAdmin: false\n },\n {\n action: Action.Delete,\n title: 'Delete',\n callback: this.dummyCallback,\n requiresAdmin: false\n },\n ];\n\n this.bookmarkActions = [\n {\n action: Action.ViewSeries,\n title: 'View Series',\n callback: this.dummyCallback,\n requiresAdmin: false\n },\n {\n action: Action.DownloadBookmark,\n title: 'Download',\n callback: this.dummyCallback,\n requiresAdmin: false\n },\n {\n action: Action.Delete,\n title: 'Clear',\n callback: this.dummyCallback,\n requiresAdmin: false\n },\n ]\n }\n}\n","\n
\n

Add to Collection

\n \n
\n
\n
\n
= 5\">\n \n
\n \n \n
\n
\n
    \n
  • \n {{collectionTag.title}} \n
  • \n
  • No collections created yet
  • \n
  • \n
    \n Loading...\n
    \n
  • \n
\n
\n
\n
\n
\n
\n \n \n
\n
\n \n
\n
\n
\n
\n
\n\n\n","import { ChangeDetectionStrategy, ChangeDetectorRef, Component, ElementRef, Input, OnInit, ViewChild, ViewEncapsulation } from '@angular/core';\nimport { FormGroup, FormControl } from '@angular/forms';\nimport { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';\nimport { ToastrService } from 'ngx-toastr';\nimport { CollectionTag } from 'src/app/_models/collection-tag';\nimport { ReadingList } from 'src/app/_models/reading-list';\nimport { CollectionTagService } from 'src/app/_services/collection-tag.service';\n\n@Component({\n selector: 'app-bulk-add-to-collection',\n templateUrl: './bulk-add-to-collection.component.html',\n encapsulation: ViewEncapsulation.None, // This is needed as per the bootstrap modal documentation to get styles to work.\n styleUrls: ['./bulk-add-to-collection.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class BulkAddToCollectionComponent implements OnInit {\n\n @Input() title!: string;\n /**\n * Series Ids to add to Collection Tag\n */\n @Input() seriesIds: Array = [];\n\n /**\n * All existing collections sorted by recent use date\n */\n lists: Array = [];\n loading: boolean = false;\n listForm: FormGroup = new FormGroup({});\n\n collectionTitleTrackby = (index: number, item: CollectionTag) => `${item.title}`;\n\n @ViewChild('title') inputElem!: ElementRef;\n\n\n constructor(private modal: NgbActiveModal, private collectionService: CollectionTagService, \n private toastr: ToastrService, private readonly cdRef: ChangeDetectorRef) { }\n\n ngOnInit(): void {\n\n this.listForm.addControl('title', new FormControl(this.title, []));\n this.listForm.addControl('filterQuery', new FormControl('', []));\n \n this.loading = true;\n this.cdRef.markForCheck();\n this.collectionService.allTags().subscribe(tags => {\n this.lists = tags;\n this.loading = false;\n this.cdRef.markForCheck();\n });\n }\n\n ngAfterViewInit() {\n // Shift focus to input\n if (this.inputElem) {\n this.inputElem.nativeElement.select();\n this.cdRef.markForCheck();\n }\n }\n\n close() {\n this.modal.close();\n }\n\n create() {\n const tagName = this.listForm.value.title;\n this.collectionService.addByMultiple(0, this.seriesIds, tagName).subscribe(() => {\n this.toastr.success('Series added to ' + tagName + ' collection');\n this.modal.close();\n });\n }\n\n addToCollection(tag: CollectionTag) {\n if (this.seriesIds.length === 0) return;\n\n this.collectionService.addByMultiple(tag.id, this.seriesIds, '').subscribe(() => {\n this.toastr.success('Series added to ' + tag.title + ' collection');\n this.modal.close();\n });\n \n }\n\n filterList = (listItem: ReadingList) => {\n return listItem.title.toLowerCase().indexOf((this.listForm.value.filterQuery || '').toLowerCase()) >= 0;\n }\n\n}\n","\n
\n

Add to Reading List

\n \n
\n
\n
\n
= 5\">\n \n
\n \n \n
\n
\n
    \n
  • \n {{readingList.title}} \n
  • \n
  • No lists created yet
  • \n
  • \n
    \n Loading...\n
    \n
  • \n
\n
\n
\n
\n
\n
\n \n \n
\n
\n \n
\n
\n
\n
\n
\n\n\n","import { AfterViewInit, Component, ElementRef, Input, OnInit, ViewChild } from '@angular/core';\nimport { FormControl, FormGroup } from '@angular/forms';\nimport { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';\nimport { ToastrService } from 'ngx-toastr';\nimport { ReadingList } from 'src/app/_models/reading-list';\nimport { ReadingListService } from 'src/app/_services/reading-list.service';\n\nexport enum ADD_FLOW {\n Series = 0,\n Volume = 1,\n Chapter = 2,\n Multiple = 3,\n Multiple_Series\n}\n\n@Component({\n selector: 'app-add-to-list-modal',\n templateUrl: './add-to-list-modal.component.html',\n styleUrls: ['./add-to-list-modal.component.scss']\n})\nexport class AddToListModalComponent implements OnInit, AfterViewInit {\n\n @Input() title!: string;\n /**\n * Only used in Series flow\n */\n @Input() seriesId?: number;\n /**\n * Only used in Volume flow\n */\n @Input() volumeId?: number;\n /**\n * Only used in Chapter flow\n */\n @Input() chapterId?: number;\n /**\n * Only used in Multiple flow\n */\n @Input() volumeIds?: Array;\n /**\n * Only used in Multiple flow\n */\n @Input() chapterIds?: Array;\n /**\n * Only used in Multiple_Series flow\n */\n @Input() seriesIds?: Array;\n\n /**\n * Determines which Input is required and which API is used to associate to the Reading List\n */\n @Input() type!: ADD_FLOW;\n\n /**\n * All existing reading lists sorted by recent use date\n */\n lists: Array = [];\n loading: boolean = false;\n listForm: FormGroup = new FormGroup({});\n\n @ViewChild('title') inputElem!: ElementRef;\n\n\n constructor(private modal: NgbActiveModal, private readingListService: ReadingListService, private toastr: ToastrService) { }\n\n ngOnInit(): void {\n\n this.listForm.addControl('title', new FormControl(this.title, []));\n this.listForm.addControl('filterQuery', new FormControl('', []));\n \n this.loading = true;\n this.readingListService.getReadingLists(false).subscribe(lists => {\n this.lists = lists.result;\n this.loading = false;\n });\n\n \n }\n\n ngAfterViewInit() {\n // Shift focus to input\n if (this.inputElem) {\n this.inputElem.nativeElement.select();\n }\n }\n\n close() {\n this.modal.close();\n }\n\n create() {\n this.readingListService.createList(this.listForm.value.title).subscribe(list => {\n this.addToList(list);\n });\n }\n\n addToList(readingList: ReadingList) {\n\n if (this.type === ADD_FLOW.Multiple_Series && this.seriesIds !== undefined) {\n this.readingListService.updateByMultipleSeries(readingList.id, this.seriesIds).subscribe(() => {\n this.toastr.success('Series added to reading list');\n this.modal.close();\n });\n }\n\n if (this.seriesId === undefined) return;\n\n if (this.type === ADD_FLOW.Series && this.seriesId !== undefined) {\n this.readingListService.updateBySeries(readingList.id, this.seriesId).subscribe(() => {\n this.toastr.success('Series added to reading list');\n this.modal.close();\n });\n } else if (this.type === ADD_FLOW.Volume && this.volumeId !== undefined) {\n this.readingListService.updateByVolume(readingList.id, this.seriesId, this.volumeId).subscribe(() => {\n this.toastr.success('Volumes added to reading list');\n this.modal.close();\n });\n } else if (this.type === ADD_FLOW.Chapter && this.chapterId !== undefined) {\n this.readingListService.updateByChapter(readingList.id, this.seriesId, this.chapterId).subscribe(() => {\n this.toastr.success('Chapter added to reading list');\n this.modal.close();\n });\n } else if (this.type === ADD_FLOW.Multiple && this.volumeIds !== undefined && this.chapterIds !== undefined) {\n this.readingListService.updateByMultiple(readingList.id, this.seriesId, this.volumeIds, this.chapterIds).subscribe(() => {\n this.toastr.success('Chapters and Volumes added to reading list');\n this.modal.close();\n });\n }\n \n }\n\n filterList = (listItem: ReadingList) => {\n return listItem.title.toLowerCase().indexOf((this.listForm.value.filterQuery || '').toLowerCase()) >= 0;\n }\n\n}\n","\n
\n

Edit {{readingList.title}} Reading List

\n \n
\n
\n
    \n
  • \n {{tabs[0].title}}\n \n

    \n This list is currently {{readingList.promoted ? 'promoted' : 'not promoted'}} (). \n Promotion means that the list can be seen server-wide, not just for admin users. All series that are within this list will still have user-access restrictions placed on them.\n

    \n
    \n
    \n \n \n
    \n \n
    \n \n \n
    \n
    \n
    \n
  • \n
  • \n {{tabs[1].title}}\n \n

    \n Upload and choose a new cover image. Press Save to upload and override the cover.\n

    \n \n
    \n
  • \n
\n
\n
\n
\n \n \n \n
\n\n\n","import { Component, Input, OnInit } from '@angular/core';\nimport { FormGroup, FormControl, Validators } from '@angular/forms';\nimport { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';\nimport { ToastrService } from 'ngx-toastr';\nimport { forkJoin } from 'rxjs';\nimport { Breakpoint, UtilityService } from 'src/app/shared/_services/utility.service';\nimport { ReadingList } from 'src/app/_models/reading-list';\nimport { ImageService } from 'src/app/_services/image.service';\nimport { ReadingListService } from 'src/app/_services/reading-list.service';\nimport { UploadService } from 'src/app/_services/upload.service';\n\n\n@Component({\n selector: 'app-edit-reading-list-modal',\n templateUrl: './edit-reading-list-modal.component.html',\n styleUrls: ['./edit-reading-list-modal.component.scss']\n})\nexport class EditReadingListModalComponent implements OnInit {\n\n @Input() readingList!: ReadingList;\n reviewGroup!: FormGroup;\n\n coverImageIndex: number = 0;\n /**\n * Url of the selected cover\n */\n selectedCover: string = '';\n coverImageLocked: boolean = false;\n\n imageUrls: Array = [];\n\n tabs = [{title: 'General', disabled: false}, {title: 'Cover', disabled: false}];\n active = this.tabs[0];\n\n get Breakpoint() {\n return Breakpoint;\n }\n\n constructor(private ngModal: NgbActiveModal, private readingListService: ReadingListService, \n public utilityService: UtilityService, private uploadService: UploadService, private toastr: ToastrService, \n private imageService: ImageService) { }\n\n ngOnInit(): void {\n this.reviewGroup = new FormGroup({\n title: new FormControl(this.readingList.title, [Validators.required]),\n summary: new FormControl(this.readingList.summary, [])\n });\n\n this.imageUrls.push(this.imageService.randomize(this.imageService.getReadingListCoverImage(this.readingList.id)));\n }\n\n close() {\n this.ngModal.dismiss(undefined);\n }\n\n save() {\n if (this.reviewGroup.value.title.trim() === '') return;\n\n\n const model = {...this.reviewGroup.value, readingListId: this.readingList.id, promoted: this.readingList.promoted, coverImageLocked: this.coverImageLocked};\n\n const apis = [this.readingListService.update(model)];\n \n if (this.selectedCover !== '') {\n apis.push(this.uploadService.updateReadingListCoverImage(this.readingList.id, this.selectedCover))\n }\n \n forkJoin(apis).subscribe(results => {\n this.readingList.title = model.title;\n this.readingList.summary = model.summary;\n this.readingList.coverImageLocked = this.coverImageLocked;\n this.ngModal.close(this.readingList);\n this.toastr.success('Reading List updated');\n });\n }\n\n togglePromotion() {\n const originalPromotion = this.readingList.promoted;\n this.readingList.promoted = !this.readingList.promoted;\n const model = {readingListId: this.readingList.id, promoted: this.readingList.promoted};\n this.readingListService.update(model).subscribe(res => {\n /* No Operation */\n }, err => {\n this.readingList.promoted = originalPromotion;\n });\n }\n\n updateSelectedIndex(index: number) {\n this.coverImageIndex = index;\n }\n\n updateSelectedImage(url: string) {\n this.selectedCover = url;\n }\n\n handleReset() {\n this.coverImageLocked = false;\n }\n\n}\n","import { Injectable, OnDestroy } from '@angular/core';\nimport { NgbModal, NgbModalRef } from '@ng-bootstrap/ng-bootstrap';\nimport { ToastrService } from 'ngx-toastr';\nimport { Subject } from 'rxjs';\nimport { take } from 'rxjs/operators';\nimport { BulkAddToCollectionComponent } from '../cards/_modals/bulk-add-to-collection/bulk-add-to-collection.component';\nimport { AddToListModalComponent, ADD_FLOW } from '../reading-list/_modals/add-to-list-modal/add-to-list-modal.component';\nimport { EditReadingListModalComponent } from '../reading-list/_modals/edit-reading-list-modal/edit-reading-list-modal.component';\nimport { ConfirmService } from '../shared/confirm.service';\nimport { Chapter } from '../_models/chapter';\nimport { Library } from '../_models/library';\nimport { ReadingList } from '../_models/reading-list';\nimport { Series } from '../_models/series';\nimport { Volume } from '../_models/volume';\nimport { LibraryService } from './library.service';\nimport { MemberService } from './member.service';\nimport { ReaderService } from './reader.service';\nimport { SeriesService } from './series.service';\n\nexport type LibraryActionCallback = (library: Partial) => void;\nexport type SeriesActionCallback = (series: Series) => void;\nexport type VolumeActionCallback = (volume: Volume) => void;\nexport type ChapterActionCallback = (chapter: Chapter) => void;\nexport type ReadingListActionCallback = (readingList: ReadingList) => void;\nexport type VoidActionCallback = () => void;\nexport type BooleanActionCallback = (result: boolean) => void;\n\n/**\n * Responsible for executing actions\n */\n@Injectable({\n providedIn: 'root'\n})\nexport class ActionService implements OnDestroy {\n\n private readonly onDestroy = new Subject();\n private readingListModalRef: NgbModalRef | null = null;\n private collectionModalRef: NgbModalRef | null = null;\n\n constructor(private libraryService: LibraryService, private seriesService: SeriesService, \n private readerService: ReaderService, private toastr: ToastrService, private modalService: NgbModal,\n private confirmService: ConfirmService, private memberService: MemberService) { }\n\n ngOnDestroy() {\n this.onDestroy.next();\n this.onDestroy.complete();\n }\n\n /**\n * Request a file scan for a given Library\n * @param library Partial Library, must have id and name populated\n * @param callback Optional callback to perform actions after API completes\n * @returns \n */\n async scanLibrary(library: Partial, callback?: LibraryActionCallback) {\n if (!library.hasOwnProperty('id') || library.id === undefined) {\n return;\n }\n\n // Prompt user if we should do a force or not\n const force = false; // await this.promptIfForce();\n\n this.libraryService.scan(library.id, force).pipe(take(1)).subscribe((res: any) => {\n this.toastr.info('Scan queued for ' + library.name);\n if (callback) {\n callback(library);\n }\n });\n }\n\n\n /**\n * Request a refresh of Metadata for a given Library\n * @param library Partial Library, must have id and name populated\n * @param callback Optional callback to perform actions after API completes\n * @returns \n */\n async refreshMetadata(library: Partial, callback?: LibraryActionCallback) {\n if (!library.hasOwnProperty('id') || library.id === undefined) {\n return;\n }\n\n if (!await this.confirmService.confirm('Refresh covers will force all cover images to be recalculated. This is a heavy operation. Are you sure you don\\'t want to perform a Scan instead?')) {\n if (callback) {\n callback(library);\n }\n return;\n }\n\n const forceUpdate = true; //await this.promptIfForce();\n\n this.libraryService.refreshMetadata(library?.id, forceUpdate).pipe(take(1)).subscribe((res: any) => {\n this.toastr.info('Scan queued for ' + library.name);\n if (callback) {\n callback(library);\n }\n });\n }\n\n /**\n * Request an analysis of files for a given Library (currently just word count)\n * @param library Partial Library, must have id and name populated\n * @param callback Optional callback to perform actions after API completes\n * @returns \n */\n async analyzeFiles(library: Partial, callback?: LibraryActionCallback) {\n if (!library.hasOwnProperty('id') || library.id === undefined) {\n return;\n }\n\n if (!await this.confirmService.alert('This is a long running process. Please give it the time to complete before invoking again.')) {\n if (callback) {\n callback(library);\n }\n return;\n }\n\n this.libraryService.analyze(library?.id).pipe(take(1)).subscribe((res: any) => {\n this.toastr.info('Library file analysis queued for ' + library.name);\n if (callback) {\n callback(library);\n }\n });\n }\n\n /**\n * Mark a series as read; updates the series pagesRead\n * @param series Series, must have id and name populated\n * @param callback Optional callback to perform actions after API completes\n */\n markSeriesAsRead(series: Series, callback?: SeriesActionCallback) {\n this.seriesService.markRead(series.id).pipe(take(1)).subscribe(res => {\n series.pagesRead = series.pages;\n this.toastr.success(series.name + ' is now read');\n if (callback) {\n callback(series);\n }\n });\n }\n\n /**\n * Mark a series as unread; updates the series pagesRead\n * @param series Series, must have id and name populated\n * @param callback Optional callback to perform actions after API completes\n */\n markSeriesAsUnread(series: Series, callback?: SeriesActionCallback) {\n this.seriesService.markUnread(series.id).pipe(take(1)).subscribe(res => {\n series.pagesRead = 0;\n this.toastr.success(series.name + ' is now unread');\n if (callback) {\n callback(series);\n }\n });\n }\n\n /**\n * Start a file scan for a Series\n * @param series Series, must have libraryId and name populated\n * @param callback Optional callback to perform actions after API completes\n */\n async scanSeries(series: Series, callback?: SeriesActionCallback) {\n this.seriesService.scan(series.libraryId, series.id).pipe(take(1)).subscribe((res: any) => {\n this.toastr.info('Scan queued for ' + series.name);\n if (callback) {\n callback(series);\n }\n });\n }\n\n /**\n * Start a file scan for analyze files for a Series\n * @param series Series, must have libraryId and name populated\n * @param callback Optional callback to perform actions after API completes\n */\n analyzeFilesForSeries(series: Series, callback?: SeriesActionCallback) {\n this.seriesService.analyzeFiles(series.libraryId, series.id).pipe(take(1)).subscribe((res: any) => {\n this.toastr.info('Scan queued for ' + series.name);\n if (callback) {\n callback(series);\n }\n });\n }\n\n /**\n * Start a metadata refresh for a Series\n * @param series Series, must have libraryId, id and name populated\n * @param callback Optional callback to perform actions after API completes\n */\n async refreshMetdata(series: Series, callback?: SeriesActionCallback) {\n if (!await this.confirmService.confirm('Refresh covers will force all cover images and metadata to be recalculated. This is a heavy operation. Are you sure you don\\'t want to perform a Scan instead?')) {\n if (callback) {\n callback(series);\n }\n return;\n }\n\n this.seriesService.refreshMetadata(series).pipe(take(1)).subscribe((res: any) => {\n this.toastr.info('Refresh covers queued for ' + series.name);\n if (callback) {\n callback(series);\n }\n });\n }\n\n /**\n * Mark all chapters and the volume as Read\n * @param seriesId Series Id\n * @param volume Volume, should have id, chapters and pagesRead populated\n * @param callback Optional callback to perform actions after API completes\n */\n markVolumeAsRead(seriesId: number, volume: Volume, callback?: VolumeActionCallback) {\n this.readerService.markVolumeRead(seriesId, volume.id).pipe(take(1)).subscribe(() => {\n volume.pagesRead = volume.pages;\n volume.chapters?.forEach(c => c.pagesRead = c.pages);\n this.toastr.success('Marked as Read');\n\n if (callback) {\n callback(volume);\n }\n });\n }\n\n /**\n * Mark all chapters and the volume as unread\n * @param seriesId Series Id\n * @param volume Volume, should have id, chapters and pagesRead populated\n * @param callback Optional callback to perform actions after API completes\n */\n markVolumeAsUnread(seriesId: number, volume: Volume, callback?: VolumeActionCallback) {\n this.readerService.markVolumeUnread(seriesId, volume.id).subscribe(() => {\n volume.pagesRead = 0;\n volume.chapters?.forEach(c => c.pagesRead = 0);\n this.toastr.success('Marked as Unread');\n if (callback) {\n callback(volume);\n }\n });\n }\n\n /**\n * Mark a chapter as read\n * @param seriesId Series Id\n * @param chapter Chapter, should have id, pages, volumeId populated\n * @param callback Optional callback to perform actions after API completes\n */\n markChapterAsRead(seriesId: number, chapter: Chapter, callback?: ChapterActionCallback) {\n this.readerService.saveProgress(seriesId, chapter.volumeId, chapter.id, chapter.pages).pipe(take(1)).subscribe(results => {\n chapter.pagesRead = chapter.pages;\n this.toastr.success('Marked as Read');\n if (callback) {\n callback(chapter);\n }\n });\n }\n\n /**\n * Mark a chapter as unread\n * @param seriesId Series Id\n * @param chapter Chapter, should have id, pages, volumeId populated\n * @param callback Optional callback to perform actions after API completes\n */\n markChapterAsUnread(seriesId: number, chapter: Chapter, callback?: ChapterActionCallback) {\n this.readerService.saveProgress(seriesId, chapter.volumeId, chapter.id, 0).pipe(take(1)).subscribe(results => {\n chapter.pagesRead = 0;\n this.toastr.success('Marked as unread');\n if (callback) {\n callback(chapter);\n }\n });\n }\n\n /**\n * Mark all chapters and the volumes as Read. All volumes and chapters must belong to a series\n * @param seriesId Series Id\n * @param volumes Volumes, should have id, chapters and pagesRead populated\n * @param chapters? Chapters, should have id\n * @param callback Optional callback to perform actions after API completes \n */\n markMultipleAsRead(seriesId: number, volumes: Array, chapters?: Array, callback?: VoidActionCallback) {\n this.readerService.markMultipleRead(seriesId, volumes.map(v => v.id), chapters?.map(c => c.id)).pipe(take(1)).subscribe(() => {\n volumes.forEach(volume => {\n volume.pagesRead = volume.pages;\n volume.chapters?.forEach(c => c.pagesRead = c.pages);\n });\n chapters?.forEach(c => c.pagesRead = c.pages);\n this.toastr.success('Marked as Read');\n\n if (callback) {\n callback();\n }\n });\n }\n\n /**\n * Mark all chapters and the volumes as Unread. All volumes must belong to a series\n * @param seriesId Series Id\n * @param volumes Volumes, should have id, chapters and pagesRead populated\n * @param callback Optional callback to perform actions after API completes \n */\n markMultipleAsUnread(seriesId: number, volumes: Array, chapters?: Array, callback?: VoidActionCallback) {\n this.readerService.markMultipleUnread(seriesId, volumes.map(v => v.id), chapters?.map(c => c.id)).pipe(take(1)).subscribe(() => {\n volumes.forEach(volume => {\n volume.pagesRead = 0;\n volume.chapters?.forEach(c => c.pagesRead = 0);\n });\n chapters?.forEach(c => c.pagesRead = 0);\n this.toastr.success('Marked as Read');\n\n if (callback) {\n callback();\n }\n });\n }\n\n /**\n * Mark all series as Read.\n * @param series Series, should have id, pagesRead populated\n * @param callback Optional callback to perform actions after API completes \n */\n markMultipleSeriesAsRead(series: Array, callback?: VoidActionCallback) {\n this.readerService.markMultipleSeriesRead(series.map(v => v.id)).pipe(take(1)).subscribe(() => {\n series.forEach(s => {\n s.pagesRead = s.pages;\n });\n this.toastr.success('Marked as Read');\n\n if (callback) {\n callback();\n }\n });\n }\n\n /**\n * Mark all series as Unread. \n * @param series Series, should have id, pagesRead populated\n * @param callback Optional callback to perform actions after API completes \n */\n markMultipleSeriesAsUnread(series: Array, callback?: VoidActionCallback) {\n this.readerService.markMultipleSeriesUnread(series.map(v => v.id)).pipe(take(1)).subscribe(() => {\n series.forEach(s => {\n s.pagesRead = s.pages;\n });\n this.toastr.success('Marked as Unread');\n\n if (callback) {\n callback();\n }\n });\n }\n\n addMultipleToReadingList(seriesId: number, volumes: Array, chapters?: Array, callback?: BooleanActionCallback) {\n if (this.readingListModalRef != null) { return; }\n this.readingListModalRef = this.modalService.open(AddToListModalComponent, { scrollable: true, size: 'md' });\n this.readingListModalRef.componentInstance.seriesId = seriesId;\n this.readingListModalRef.componentInstance.volumeIds = volumes.map(v => v.id);\n this.readingListModalRef.componentInstance.chapterIds = chapters?.map(c => c.id);\n this.readingListModalRef.componentInstance.title = 'Multiple Selections';\n this.readingListModalRef.componentInstance.type = ADD_FLOW.Multiple;\n\n\n this.readingListModalRef.closed.pipe(take(1)).subscribe(() => {\n this.readingListModalRef = null;\n if (callback) {\n callback(true);\n }\n });\n this.readingListModalRef.dismissed.pipe(take(1)).subscribe(() => {\n this.readingListModalRef = null;\n if (callback) {\n callback(false);\n }\n });\n }\n\n addMultipleSeriesToWantToReadList(seriesIds: Array, callback?: VoidActionCallback) {\n this.memberService.addSeriesToWantToRead(seriesIds).subscribe(() => {\n this.toastr.success('Series added to Want to Read list');\n if (callback) {\n callback();\n }\n });\n }\n\n removeMultipleSeriesFromWantToReadList(seriesIds: Array, callback?: VoidActionCallback) {\n this.memberService.removeSeriesToWantToRead(seriesIds).subscribe(() => {\n this.toastr.success('Series removed from Want to Read list');\n if (callback) {\n callback();\n }\n });\n }\n\n addMultipleSeriesToReadingList(series: Array, callback?: BooleanActionCallback) {\n if (this.readingListModalRef != null) { return; }\n this.readingListModalRef = this.modalService.open(AddToListModalComponent, { scrollable: true, size: 'md' });\n this.readingListModalRef.componentInstance.seriesIds = series.map(v => v.id);\n this.readingListModalRef.componentInstance.title = 'Multiple Selections';\n this.readingListModalRef.componentInstance.type = ADD_FLOW.Multiple_Series;\n\n\n this.readingListModalRef.closed.pipe(take(1)).subscribe(() => {\n this.readingListModalRef = null;\n if (callback) {\n callback(true);\n }\n });\n this.readingListModalRef.dismissed.pipe(take(1)).subscribe(() => {\n this.readingListModalRef = null;\n if (callback) {\n callback(false);\n }\n });\n }\n\n /**\n * Adds a set of series to a collection tag\n * @param series \n * @param callback \n * @returns \n */\n addMultipleSeriesToCollectionTag(series: Array, callback?: BooleanActionCallback) {\n if (this.collectionModalRef != null) { return; }\n this.collectionModalRef = this.modalService.open(BulkAddToCollectionComponent, { scrollable: true, size: 'md', windowClass: 'collection' });\n this.collectionModalRef.componentInstance.seriesIds = series.map(v => v.id);\n this.collectionModalRef.componentInstance.title = 'New Collection';\n\n this.collectionModalRef.closed.pipe(take(1)).subscribe(() => {\n this.collectionModalRef = null;\n if (callback) {\n callback(true);\n }\n });\n this.collectionModalRef.dismissed.pipe(take(1)).subscribe(() => {\n this.collectionModalRef = null;\n if (callback) {\n callback(false);\n }\n });\n }\n\n addSeriesToReadingList(series: Series, callback?: SeriesActionCallback) {\n if (this.readingListModalRef != null) { return; }\n this.readingListModalRef = this.modalService.open(AddToListModalComponent, { scrollable: true, size: 'md' });\n this.readingListModalRef.componentInstance.seriesId = series.id; \n this.readingListModalRef.componentInstance.title = series.name;\n this.readingListModalRef.componentInstance.type = ADD_FLOW.Series;\n\n\n this.readingListModalRef.closed.pipe(take(1)).subscribe(() => {\n this.readingListModalRef = null;\n if (callback) {\n callback(series);\n }\n });\n this.readingListModalRef.dismissed.pipe(take(1)).subscribe(() => {\n this.readingListModalRef = null;\n if (callback) {\n callback(series);\n }\n });\n }\n\n addVolumeToReadingList(volume: Volume, seriesId: number, callback?: VolumeActionCallback) {\n if (this.readingListModalRef != null) { return; }\n this.readingListModalRef = this.modalService.open(AddToListModalComponent, { scrollable: true, size: 'md' });\n this.readingListModalRef.componentInstance.seriesId = seriesId; \n this.readingListModalRef.componentInstance.volumeId = volume.id;\n this.readingListModalRef.componentInstance.type = ADD_FLOW.Volume;\n\n\n this.readingListModalRef.closed.pipe(take(1)).subscribe(() => {\n this.readingListModalRef = null;\n if (callback) {\n callback(volume);\n }\n });\n this.readingListModalRef.dismissed.pipe(take(1)).subscribe(() => {\n this.readingListModalRef = null;\n if (callback) {\n callback(volume);\n }\n });\n }\n\n addChapterToReadingList(chapter: Chapter, seriesId: number, callback?: ChapterActionCallback) {\n if (this.readingListModalRef != null) { return; }\n this.readingListModalRef = this.modalService.open(AddToListModalComponent, { scrollable: true, size: 'md' });\n this.readingListModalRef.componentInstance.seriesId = seriesId; \n this.readingListModalRef.componentInstance.chapterId = chapter.id;\n this.readingListModalRef.componentInstance.type = ADD_FLOW.Chapter;\n\n\n this.readingListModalRef.closed.pipe(take(1)).subscribe(() => {\n this.readingListModalRef = null;\n if (callback) {\n callback(chapter);\n }\n });\n this.readingListModalRef.dismissed.pipe(take(1)).subscribe(() => {\n this.readingListModalRef = null;\n if (callback) {\n callback(chapter);\n }\n });\n }\n\n editReadingList(readingList: ReadingList, callback?: ReadingListActionCallback) {\n const readingListModalRef = this.modalService.open(EditReadingListModalComponent, { scrollable: true, size: 'lg' });\n readingListModalRef.componentInstance.readingList = readingList; \n readingListModalRef.closed.pipe(take(1)).subscribe((list) => {\n if (callback && list !== undefined) {\n callback(readingList);\n }\n });\n readingListModalRef.dismissed.pipe(take(1)).subscribe((list) => {\n if (callback && list !== undefined) {\n callback(readingList);\n }\n });\n }\n\n /**\n * Mark all chapters and the volumes as Read. All volumes and chapters must belong to a series\n * @param seriesId Series Id\n * @param volumes Volumes, should have id, chapters and pagesRead populated\n * @param chapters? Chapters, should have id\n * @param callback Optional callback to perform actions after API completes \n */\n deleteMultipleSeries(seriesIds: Array, callback?: VoidActionCallback) {\n this.seriesService.deleteMultipleSeries(seriesIds.map(s => s.id)).pipe(take(1)).subscribe(() => {\n this.toastr.success('Series deleted');\n\n if (callback) {\n callback();\n }\n });\n }\n\n async deleteSeries(series: Series, callback?: BooleanActionCallback) {\n if (!await this.confirmService.confirm('Are you sure you want to delete this series? It will not modify files on disk.')) {\n if (callback) {\n callback(false);\n }\n return;\n }\n\n this.seriesService.delete(series.id).subscribe((res: boolean) => {\n if (callback) {\n this.toastr.success('Series deleted');\n callback(res);\n }\n });\n }\n\n private async promptIfForce(extraContent: string = '') {\n // Prompt user if we should do a force or not\n const config = this.confirmService.defaultConfirm;\n config.header = 'Force Scan';\n config.buttons = [\n {text: 'Yes', type: 'secondary'},\n {text: 'No', type: 'primary'},\n ];\n const msg = 'Do you want to force this scan? This is will ignore optimizations that reduce processing and I/O. ' + extraContent;\n return !await this.confirmService.confirm(msg, config); // Not because primary is the false state\n }\n}\n","import { HttpClient } from '@angular/common/http';\nimport { Injectable } from '@angular/core';\nimport { map } from 'rxjs/operators';\nimport { environment } from 'src/environments/environment';\nimport { CollectionTag } from '../_models/collection-tag';\nimport { ImageService } from './image.service';\n\n@Injectable({\n providedIn: 'root'\n})\nexport class CollectionTagService {\n\n baseUrl = environment.apiUrl;\n\n constructor(private httpClient: HttpClient, private imageService: ImageService) { }\n\n allTags() {\n return this.httpClient.get(this.baseUrl + 'collection/');\n }\n\n search(query: string) {\n return this.httpClient.get(this.baseUrl + 'collection/search?queryString=' + encodeURIComponent(query)).pipe(map(tags => {\n tags.forEach(s => s.coverImage = this.imageService.randomize(this.imageService.getCollectionCoverImage(s.id)));\n return tags;\n }));\n }\n\n updateTag(tag: CollectionTag) {\n return this.httpClient.post(this.baseUrl + 'collection/update', tag, {responseType: 'text' as 'json'});\n }\n\n updateSeriesForTag(tag: CollectionTag, seriesIdsToRemove: Array) {\n return this.httpClient.post(this.baseUrl + 'collection/update-series', {tag, seriesIdsToRemove}, {responseType: 'text' as 'json'});\n }\n\n addByMultiple(tagId: number, seriesIds: Array, tagTitle: string = '') {\n return this.httpClient.post(this.baseUrl + 'collection/update-for-series', {collectionTagId: tagId, collectionTagTitle: tagTitle, seriesIds}, {responseType: 'text' as 'json'});\n }\n}\n","import { Injectable, OnDestroy } from '@angular/core';\nimport { Subject } from 'rxjs';\nimport { takeUntil } from 'rxjs/operators';\nimport { environment } from 'src/environments/environment';\nimport { ThemeService } from './theme.service';\nimport { RecentlyAddedItem } from '../_models/recently-added-item';\nimport { AccountService } from './account.service';\n\n@Injectable({\n providedIn: 'root'\n})\nexport class ImageService implements OnDestroy {\n\n baseUrl = environment.apiUrl;\n apiKey: string = '';\n public placeholderImage = 'assets/images/image-placeholder-min.png';\n public errorImage = 'assets/images/error-placeholder2-min.png';\n public resetCoverImage = 'assets/images/image-reset-cover-min.png';\n\n private onDestroy: Subject = new Subject();\n\n constructor(private accountService: AccountService, private themeService: ThemeService) {\n this.themeService.currentTheme$.pipe(takeUntil(this.onDestroy)).subscribe(theme => {\n if (this.themeService.isDarkTheme()) {\n this.placeholderImage = 'assets/images/image-placeholder.dark-min.png';\n this.errorImage = 'assets/images/error-placeholder2.dark-min.png';\n } else {\n this.placeholderImage = 'assets/images/image-placeholder-min.png';\n this.errorImage = 'assets/images/error-placeholder2-min.png';\n }\n });\n\n this.accountService.currentUser$.pipe(takeUntil(this.onDestroy)).subscribe(user => {\n if (user) {\n this.apiKey = user.apiKey;\n }\n });\n }\n\n ngOnDestroy(): void {\n this.onDestroy.next();\n this.onDestroy.complete();\n }\n\n getRecentlyAddedItem(item: RecentlyAddedItem) {\n if (item.chapterId === 0) {\n return this.getVolumeCoverImage(item.volumeId);\n }\n return this.getChapterCoverImage(item.chapterId);\n }\n\n /**\n * Returns the entity type from a cover image url. Undefied if not applicable\n * @param url \n * @returns \n */\n getEntityTypeFromUrl(url: string) {\n if (url.indexOf('?') < 0) return undefined;\n const part = url.split('?')[1];\n const equalIndex = part.indexOf('=');\n return part.substring(0, equalIndex).replace('Id', '');\n }\n\n getVolumeCoverImage(volumeId: number) {\n return this.baseUrl + 'image/volume-cover?volumeId=' + volumeId;\n }\n\n getSeriesCoverImage(seriesId: number) {\n return this.baseUrl + 'image/series-cover?seriesId=' + seriesId;\n }\n\n getCollectionCoverImage(collectionTagId: number) {\n return this.baseUrl + 'image/collection-cover?collectionTagId=' + collectionTagId;\n }\n\n getReadingListCoverImage(readingListId: number) {\n return this.baseUrl + 'image/readinglist-cover?readingListId=' + readingListId;\n }\n\n getChapterCoverImage(chapterId: number) {\n return this.baseUrl + 'image/chapter-cover?chapterId=' + chapterId;\n }\n\n getBookmarkedImage(chapterId: number, pageNum: number) {\n return this.baseUrl + 'image/bookmark?chapterId=' + chapterId + '&pageNum=' + pageNum + '&apiKey=' + encodeURIComponent(this.apiKey);\n }\n\n getCoverUploadImage(filename: string) {\n return this.baseUrl + 'image/cover-upload?filename=' + encodeURIComponent(filename);\n }\n\n updateErroredImage(event: any) {\n event.target.src = this.placeholderImage;\n }\n\n /**\n * Used to refresh an existing loaded image (lazysizes). If random already attached, will append another number onto it.\n * @param url Existing request url from ImageService only\n * @returns Url with a random parameter attached\n */\n randomize(url: string) {\n const r = Math.round(Math.random() * 100 + 1);\n if (url.indexOf('&random') >= 0) {\n return url + 1;\n }\n return url + '&random=' + r;\n }\n}\n","import { HttpClient } from '@angular/common/http';\nimport { Injectable } from '@angular/core';\nimport { of } from 'rxjs';\nimport { map, take } from 'rxjs/operators';\nimport { environment } from 'src/environments/environment';\nimport { JumpKey } from '../_models/jumpbar/jump-key';\nimport { Library, LibraryType } from '../_models/library';\nimport { SearchResultGroup } from '../_models/search/search-result-group';\nimport { DirectoryDto } from '../_models/system/directory-dto';\n\n\n@Injectable({\n providedIn: 'root'\n})\nexport class LibraryService {\n\n baseUrl = environment.apiUrl;\n\n private libraryNames: {[key:number]: string} | undefined = undefined;\n private libraryTypes: {[key: number]: LibraryType} | undefined = undefined;\n\n constructor(private httpClient: HttpClient) {}\n\n getLibraryNames() {\n if (this.libraryNames != undefined) {\n return of(this.libraryNames);\n }\n return this.httpClient.get(this.baseUrl + 'library').pipe(map(l => {\n this.libraryNames = {};\n l.forEach(lib => {\n if (this.libraryNames !== undefined) {\n this.libraryNames[lib.id] = lib.name;\n } \n });\n return this.libraryNames;\n }));\n }\n\n getLibraryName(libraryId: number) {\n if (this.libraryNames != undefined && this.libraryNames.hasOwnProperty(libraryId)) {\n return of(this.libraryNames[libraryId]);\n }\n return this.httpClient.get(this.baseUrl + 'library').pipe(map(l => {\n this.libraryNames = {};\n l.forEach(lib => {\n if (this.libraryNames !== undefined) {\n this.libraryNames[lib.id] = lib.name;\n } \n });\n return this.libraryNames[libraryId];\n }));\n }\n\n listDirectories(rootPath: string) {\n let query = '';\n if (rootPath !== undefined && rootPath.length > 0) {\n query = '?path=' + encodeURIComponent(rootPath);\n }\n\n return this.httpClient.get(this.baseUrl + 'library/list' + query);\n }\n\n getJumpBar(libraryId: number) {\n return this.httpClient.get(this.baseUrl + 'library/jump-bar?libraryId=' + libraryId);\n }\n\n getLibraries() {\n return this.httpClient.get(this.baseUrl + 'library');\n }\n\n getLibrariesForMember() {\n return this.httpClient.get(this.baseUrl + 'library/libraries');\n }\n\n updateLibrariesForMember(username: string, selectedLibraries: Library[]) {\n return this.httpClient.post(this.baseUrl + 'library/grant-access', {username, selectedLibraries});\n }\n\n scan(libraryId: number, force = false) {\n return this.httpClient.post(this.baseUrl + 'library/scan?libraryId=' + libraryId + '&force=' + force, {});\n }\n\n analyze(libraryId: number) {\n return this.httpClient.post(this.baseUrl + 'library/analyze?libraryId=' + libraryId, {});\n }\n\n refreshMetadata(libraryId: number, forceUpdate = false) {\n return this.httpClient.post(this.baseUrl + 'library/refresh-metadata?libraryId=' + libraryId + '&force=' + forceUpdate, {});\n }\n\n create(model: {name: string, type: number, folders: string[]}) {\n return this.httpClient.post(this.baseUrl + 'library/create', model);\n }\n\n delete(libraryId: number) {\n return this.httpClient.delete(this.baseUrl + 'library/delete?libraryId=' + libraryId, {});\n }\n\n update(model: {name: string, folders: string[], id: number}) {\n return this.httpClient.post(this.baseUrl + 'library/update', model);\n }\n\n getLibraryType(libraryId: number) {\n if (this.libraryTypes != undefined && this.libraryTypes.hasOwnProperty(libraryId)) {\n return of(this.libraryTypes[libraryId]);\n }\n return this.httpClient.get(this.baseUrl + 'library/type?libraryId=' + libraryId).pipe(map(l => {\n if (this.libraryTypes === undefined) {\n this.libraryTypes = {};\n }\n\n this.libraryTypes[libraryId] = l;\n return this.libraryTypes[libraryId];\n }));\n }\n\n search(term: string) {\n if (term === '') {\n return of(new SearchResultGroup());\n }\n return this.httpClient.get(this.baseUrl + 'library/search?queryString=' + encodeURIComponent(term));\n }\n\n}\n","import { HttpClient } from '@angular/common/http';\nimport { Injectable } from '@angular/core';\nimport { environment } from 'src/environments/environment';\nimport { Member } from '../_models/member';\n\n@Injectable({\n providedIn: 'root'\n})\nexport class MemberService {\n\n baseUrl = environment.apiUrl;\n\n constructor(private httpClient: HttpClient) { }\n\n getMembers() {\n return this.httpClient.get(this.baseUrl + 'users');\n }\n\n getMemberNames() {\n return this.httpClient.get(this.baseUrl + 'users/names');\n }\n\n adminExists() {\n return this.httpClient.get(this.baseUrl + 'admin/exists');\n }\n\n deleteMember(username: string) {\n return this.httpClient.delete(this.baseUrl + 'users/delete-user?username=' + encodeURIComponent(username));\n }\n\n hasLibraryAccess(libraryId: number) {\n return this.httpClient.get(this.baseUrl + 'users/has-library-access?libraryId=' + libraryId);\n }\n\n hasReadingProgress(librayId: number) {\n return this.httpClient.get(this.baseUrl + 'users/has-reading-progress?libraryId=' + librayId);\n }\n\n getPendingInvites() {\n return this.httpClient.get>(this.baseUrl + 'users/pending');\n }\n\n addSeriesToWantToRead(seriesIds: Array) {\n return this.httpClient.post>(this.baseUrl + 'want-to-read/add-series', {seriesIds});\n }\n\n removeSeriesToWantToRead(seriesIds: Array) {\n return this.httpClient.post>(this.baseUrl + 'want-to-read/remove-series', {seriesIds});\n }\n \n}\n","import { Injectable } from '@angular/core';\nimport { Router } from '@angular/router';\nimport { HubConnection, HubConnectionBuilder } from '@microsoft/signalr';\nimport { ToastrService } from 'ngx-toastr';\nimport { BehaviorSubject, ReplaySubject } from 'rxjs';\nimport { environment } from 'src/environments/environment';\nimport { LibraryModifiedEvent } from '../_models/events/library-modified-event';\nimport { NotificationProgressEvent } from '../_models/events/notification-progress-event';\nimport { ThemeProgressEvent } from '../_models/events/theme-progress-event';\nimport { UserUpdateEvent } from '../_models/events/user-update-event';\nimport { User } from '../_models/user';\n\nexport enum EVENTS {\n UpdateAvailable = 'UpdateAvailable',\n ScanSeries = 'ScanSeries',\n SeriesAdded = 'SeriesAdded',\n SeriesRemoved = 'SeriesRemoved',\n ScanLibraryProgress = 'ScanLibraryProgress',\n OnlineUsers = 'OnlineUsers',\n SeriesAddedToCollection = 'SeriesAddedToCollection',\n /**\n * A generic error that occurs during operations on the server\n */\n Error = 'Error',\n BackupDatabaseProgress = 'BackupDatabaseProgress',\n /**\n * A subtype of NotificationProgress that represents maintenance cleanup on server-owned resources\n */\n CleanupProgress = 'CleanupProgress',\n /**\n * A subtype of NotificationProgress that represnts a user downloading a file or group of files.\n * Note: In v0.5.5, this is being replaced by an inbrowser experience. The message is changed and this will be moved to dashboard view once built\n */\n DownloadProgress = 'DownloadProgress',\n /**\n * A generic progress event\n */\n NotificationProgress = 'NotificationProgress',\n /**\n * A subtype of NotificationProgress that represents the underlying file being processed during a scan\n */\n FileScanProgress = 'FileScanProgress',\n /**\n * A custom user site theme is added or removed during a scan\n */\n SiteThemeProgress = 'SiteThemeProgress',\n /**\n * A cover is updated\n */\n CoverUpdate = 'CoverUpdate',\n /**\n * A subtype of NotificationProgress that represents a file being processed for cover image extraction\n */\n CoverUpdateProgress = 'CoverUpdateProgress',\n /**\n * A library is created or removed from the instance\n */\n LibraryModified = 'LibraryModified',\n /**\n * A user updates an entities read progress\n */\n UserProgressUpdate = 'UserProgressUpdate',\n /**\n * A user updates account or preferences\n */\n UserUpdate = 'UserUpdate',\n /**\n * When bulk bookmarks are being converted\n */\n ConvertBookmarksProgress = 'ConvertBookmarksProgress',\n /**\n * When files are being scanned to calculate word count\n */\n WordCountAnalyzerProgress = 'WordCountAnalyzerProgress',\n /**\n * When the user needs to be informed, but it's not a big deal\n */\n Info = 'Info',\n}\n\nexport interface Message {\n event: EVENTS;\n payload: T;\n}\n\n\n@Injectable({\n providedIn: 'root'\n})\nexport class MessageHubService {\n hubUrl = environment.hubUrl;\n private hubConnection!: HubConnection;\n\n private messagesSource = new ReplaySubject>(1);\n private onlineUsersSource = new BehaviorSubject([]);\n\n /**\n * Any events that come from the backend\n */\n public messages$ = this.messagesSource.asObservable();\n /**\n * Users that are online\n */\n public onlineUsers$ = this.onlineUsersSource.asObservable();\n\n\n isAdmin: boolean = false;\n\n constructor(private toastr: ToastrService, private router: Router) {\n\n }\n\n /**\n * Tests that an event is of the type passed\n * @param event\n * @param eventType\n * @returns\n */\n public isEventType(event: Message, eventType: EVENTS) {\n if (event.event == EVENTS.NotificationProgress) {\n const notification = event.payload as NotificationProgressEvent;\n return notification.eventType.toLowerCase() == eventType.toLowerCase();\n }\n return event.event === eventType;\n }\n\n createHubConnection(user: User, isAdmin: boolean) {\n this.isAdmin = isAdmin;\n\n this.hubConnection = new HubConnectionBuilder()\n .withUrl(this.hubUrl + 'messages', {\n accessTokenFactory: () => user.token\n })\n .withAutomaticReconnect()\n .build();\n\n this.hubConnection\n .start()\n .catch(err => console.error(err));\n\n this.hubConnection.on(EVENTS.OnlineUsers, (usernames: string[]) => {\n this.onlineUsersSource.next(usernames);\n });\n\n\n this.hubConnection.on(EVENTS.ScanSeries, resp => {\n this.messagesSource.next({\n event: EVENTS.ScanSeries,\n payload: resp.body\n });\n });\n\n this.hubConnection.on(EVENTS.ScanLibraryProgress, resp => {\n this.messagesSource.next({\n event: EVENTS.ScanLibraryProgress,\n payload: resp.body\n });\n });\n\n this.hubConnection.on(EVENTS.ConvertBookmarksProgress, resp => {\n this.messagesSource.next({\n event: EVENTS.ConvertBookmarksProgress,\n payload: resp.body\n });\n });\n\n this.hubConnection.on(EVENTS.WordCountAnalyzerProgress, resp => {\n this.messagesSource.next({\n event: EVENTS.WordCountAnalyzerProgress,\n payload: resp.body\n });\n });\n\n this.hubConnection.on(EVENTS.LibraryModified, resp => {\n this.messagesSource.next({\n event: EVENTS.LibraryModified,\n payload: resp.body as LibraryModifiedEvent\n });\n });\n\n\n this.hubConnection.on(EVENTS.NotificationProgress, (resp: NotificationProgressEvent) => {\n this.messagesSource.next({\n event: EVENTS.NotificationProgress,\n payload: resp\n });\n });\n\n this.hubConnection.on(EVENTS.SiteThemeProgress, resp => {\n this.messagesSource.next({\n event: EVENTS.SiteThemeProgress,\n payload: resp.body as ThemeProgressEvent\n });\n });\n\n this.hubConnection.on(EVENTS.SeriesAddedToCollection, resp => {\n this.messagesSource.next({\n event: EVENTS.SeriesAddedToCollection,\n payload: resp.body\n });\n });\n\n this.hubConnection.on(EVENTS.UserProgressUpdate, resp => {\n this.messagesSource.next({\n event: EVENTS.UserProgressUpdate,\n payload: resp.body\n });\n });\n\n this.hubConnection.on(EVENTS.UserUpdate, resp => {\n this.messagesSource.next({\n event: EVENTS.UserUpdate,\n payload: resp.body as UserUpdateEvent\n });\n });\n\n this.hubConnection.on(EVENTS.Error, resp => {\n this.messagesSource.next({\n event: EVENTS.Error,\n payload: resp.body\n });\n });\n\n this.hubConnection.on(EVENTS.Info, resp => {\n this.messagesSource.next({\n event: EVENTS.Info,\n payload: resp.body\n });\n });\n\n this.hubConnection.on(EVENTS.SeriesAdded, resp => {\n this.messagesSource.next({\n event: EVENTS.SeriesAdded,\n payload: resp.body\n });\n });\n\n this.hubConnection.on(EVENTS.SeriesRemoved, resp => {\n this.messagesSource.next({\n event: EVENTS.SeriesRemoved,\n payload: resp.body\n });\n });\n\n this.hubConnection.on(EVENTS.CoverUpdate, resp => {\n this.messagesSource.next({\n event: EVENTS.CoverUpdate,\n payload: resp.body\n });\n });\n\n this.hubConnection.on(EVENTS.UpdateAvailable, resp => {\n this.messagesSource.next({\n event: EVENTS.UpdateAvailable,\n payload: resp.body\n });\n });\n }\n\n stopHubConnection() {\n if (this.hubConnection) {\n this.hubConnection.stop().catch(err => console.error(err));\n }\n }\n\n sendMessage(methodName: string, body?: any) {\n return this.hubConnection.invoke(methodName, body);\n }\n\n}\n","import { DOCUMENT } from '@angular/common';\nimport { Inject, Injectable, Renderer2, RendererFactory2 } from '@angular/core';\nimport { ReplaySubject, take } from 'rxjs';\n\n@Injectable({\n providedIn: 'root'\n})\nexport class NavService {\n public localStorageSideNavKey = 'kavita--sidenav--expanded';\n\n private navbarVisibleSource = new ReplaySubject(1);\n /**\n * If the top Nav bar is rendered or not\n */\n navbarVisible$ = this.navbarVisibleSource.asObservable();\n\n private sideNavCollapseSource = new ReplaySubject(1);\n /**\n * If the Side Nav is in a collapsed state or not.\n */\n sideNavCollapsed$ = this.sideNavCollapseSource.asObservable();\n\n private sideNavVisibilitySource = new ReplaySubject(1);\n /**\n * If the side nav is rendered or not into the DOM.\n */\n sideNavVisibility$ = this.sideNavVisibilitySource.asObservable();\n\n private renderer: Renderer2;\n\n constructor(@Inject(DOCUMENT) private document: Document, rendererFactory: RendererFactory2) {\n this.renderer = rendererFactory.createRenderer(null, null);\n this.showNavBar();\n const sideNavState = (localStorage.getItem(this.localStorageSideNavKey) === 'true') || false;\n this.sideNavCollapseSource.next(sideNavState);\n this.showSideNav();\n }\n \n /**\n * Shows the top nav bar. This should be visible on all pages except the reader.\n */\n showNavBar() {\n this.renderer.setStyle(this.document.querySelector('body'), 'margin-top', '56px');\n this.renderer.setStyle(this.document.querySelector('body'), 'height', 'calc(var(--vh)*100 - 56px)');\n this.renderer.setStyle(this.document.querySelector('html'), 'height', 'calc(var(--vh)*100 - 56px)');\n this.navbarVisibleSource.next(true);\n }\n\n /**\n * Hides the top nav bar. \n */\n hideNavBar() {\n this.renderer.setStyle(this.document.querySelector('body'), 'margin-top', '0px');\n this.renderer.removeStyle(this.document.querySelector('body'), 'height');\n this.renderer.removeStyle(this.document.querySelector('html'), 'height');\n this.navbarVisibleSource.next(false);\n }\n\n /**\n * Shows the side nav. When being visible, the side nav will automatically return to previous collapsed state.\n */\n showSideNav() {\n this.sideNavVisibilitySource.next(true);\n }\n\n /**\n * Hides the side nav. This is useful for the readers and login page.\n */\n hideSideNav() {\n this.sideNavVisibilitySource.next(false);\n }\n\n toggleSideNav() {\n this.sideNavCollapseSource.pipe(take(1)).subscribe(val => {\n if (val === undefined) val = false;\n const newVal = !(val || false);\n this.sideNavCollapseSource.next(newVal);\n localStorage.setItem(this.localStorageSideNavKey, newVal + '');\n });\n }\n}\n","import { HttpClient } from '@angular/common/http';\nimport { Injectable } from '@angular/core';\nimport { Location } from '@angular/common';\nimport { Router } from '@angular/router';\nimport { environment } from 'src/environments/environment';\nimport { ChapterInfo } from '../manga-reader/_models/chapter-info';\nimport { Chapter } from '../_models/chapter';\nimport { HourEstimateRange } from '../_models/hour-estimate-range';\nimport { MangaFormat } from '../_models/manga-format';\nimport { BookmarkInfo } from '../_models/manga-reader/bookmark-info';\nimport { PageBookmark } from '../_models/page-bookmark';\nimport { ProgressBookmark } from '../_models/progress-bookmark';\n\nexport const CHAPTER_ID_DOESNT_EXIST = -1;\nexport const CHAPTER_ID_NOT_FETCHED = -2;\n\n@Injectable({\n providedIn: 'root'\n})\nexport class ReaderService {\n\n baseUrl = environment.apiUrl;\n\n // Override background color for reader and restore it onDestroy\n private originalBodyColor!: string;\n\n constructor(private httpClient: HttpClient, private router: Router, private location: Location) { }\n\n getNavigationArray(libraryId: number, seriesId: number, chapterId: number, format: MangaFormat) {\n if (format === undefined) format = MangaFormat.ARCHIVE;\n\n if (format === MangaFormat.EPUB) {\n return ['library', libraryId, 'series', seriesId, 'book', chapterId];\n } else if (format === MangaFormat.PDF) {\n return ['library', libraryId, 'series', seriesId, 'pdf', chapterId];\n } else {\n return ['library', libraryId, 'series', seriesId, 'manga', chapterId];\n }\n }\n\n downloadPdf(chapterId: number) {\n return this.baseUrl + 'reader/pdf?chapterId=' + chapterId;\n }\n\n bookmark(seriesId: number, volumeId: number, chapterId: number, page: number) {\n return this.httpClient.post(this.baseUrl + 'reader/bookmark', {seriesId, volumeId, chapterId, page});\n }\n\n unbookmark(seriesId: number, volumeId: number, chapterId: number, page: number) {\n return this.httpClient.post(this.baseUrl + 'reader/unbookmark', {seriesId, volumeId, chapterId, page});\n }\n\n getAllBookmarks() {\n return this.httpClient.get(this.baseUrl + 'reader/get-all-bookmarks');\n }\n\n getBookmarks(chapterId: number) {\n return this.httpClient.get(this.baseUrl + 'reader/get-bookmarks?chapterId=' + chapterId);\n }\n\n getBookmarksForVolume(volumeId: number) {\n return this.httpClient.get(this.baseUrl + 'reader/get-volume-bookmarks?volumeId=' + volumeId);\n }\n\n getBookmarksForSeries(seriesId: number) {\n return this.httpClient.get(this.baseUrl + 'reader/get-series-bookmarks?seriesId=' + seriesId);\n }\n\n clearBookmarks(seriesId: number) {\n return this.httpClient.post(this.baseUrl + 'reader/remove-bookmarks', {seriesId}, {responseType: 'text' as 'json'});\n }\n clearMultipleBookmarks(seriesIds: Array) {\n return this.httpClient.post(this.baseUrl + 'reader/bulk-remove-bookmarks', {seriesIds}, {responseType: 'text' as 'json'});\n }\n\n /**\n * Used exclusively for reading multiple bookmarks from a series\n * @param seriesId\n */\n getBookmarkInfo(seriesId: number) {\n return this.httpClient.get(this.baseUrl + 'reader/bookmark-info?seriesId=' + seriesId);\n }\n\n getProgress(chapterId: number) {\n return this.httpClient.get(this.baseUrl + 'reader/get-progress?chapterId=' + chapterId);\n }\n\n getPageUrl(chapterId: number, page: number) {\n return this.baseUrl + 'reader/image?chapterId=' + chapterId + '&page=' + page;\n }\n\n getBookmarkPageUrl(seriesId: number, apiKey: string, page: number) {\n return this.baseUrl + 'reader/bookmark-image?seriesId=' + seriesId + '&page=' + page + '&apiKey=' + encodeURIComponent(apiKey);\n }\n\n getChapterInfo(chapterId: number) {\n return this.httpClient.get(this.baseUrl + 'reader/chapter-info?chapterId=' + chapterId);\n }\n\n saveProgress(seriesId: number, volumeId: number, chapterId: number, page: number, bookScrollId: string | null = null) {\n return this.httpClient.post(this.baseUrl + 'reader/progress', {seriesId, volumeId, chapterId, pageNum: page, bookScrollId});\n }\n\n markVolumeRead(seriesId: number, volumeId: number) {\n return this.httpClient.post(this.baseUrl + 'reader/mark-volume-read', {seriesId, volumeId});\n }\n\n markMultipleRead(seriesId: number, volumeIds: Array, chapterIds?: Array) {\n return this.httpClient.post(this.baseUrl + 'reader/mark-multiple-read', {seriesId, volumeIds, chapterIds});\n }\n\n markMultipleUnread(seriesId: number, volumeIds: Array, chapterIds?: Array) {\n return this.httpClient.post(this.baseUrl + 'reader/mark-multiple-unread', {seriesId, volumeIds, chapterIds});\n }\n\n markMultipleSeriesRead(seriesIds: Array) {\n return this.httpClient.post(this.baseUrl + 'reader/mark-multiple-series-read', {seriesIds});\n }\n\n markMultipleSeriesUnread(seriesIds: Array) {\n return this.httpClient.post(this.baseUrl + 'reader/mark-multiple-series-unread', {seriesIds});\n }\n\n markVolumeUnread(seriesId: number, volumeId: number) {\n return this.httpClient.post(this.baseUrl + 'reader/mark-volume-unread', {seriesId, volumeId});\n }\n\n\n getNextChapter(seriesId: number, volumeId: number, currentChapterId: number, readingListId: number = -1) {\n if (readingListId > 0) {\n return this.httpClient.get(this.baseUrl + 'readinglist/next-chapter?seriesId=' + seriesId + '¤tChapterId=' + currentChapterId + '&readingListId=' + readingListId);\n }\n return this.httpClient.get(this.baseUrl + 'reader/next-chapter?seriesId=' + seriesId + '&volumeId=' + volumeId + '¤tChapterId=' + currentChapterId);\n }\n\n getPrevChapter(seriesId: number, volumeId: number, currentChapterId: number, readingListId: number = -1) {\n if (readingListId > 0) {\n return this.httpClient.get(this.baseUrl + 'readinglist/prev-chapter?seriesId=' + seriesId + '¤tChapterId=' + currentChapterId + '&readingListId=' + readingListId);\n }\n return this.httpClient.get(this.baseUrl + 'reader/prev-chapter?seriesId=' + seriesId + '&volumeId=' + volumeId + '¤tChapterId=' + currentChapterId);\n }\n\n hasSeriesProgress(seriesId: number) {\n return this.httpClient.get(this.baseUrl + 'reader/has-progress?seriesId=' + seriesId);\n }\n\n getCurrentChapter(seriesId: number) {\n return this.httpClient.get(this.baseUrl + 'reader/continue-point?seriesId=' + seriesId);\n }\n\n getTimeLeft(seriesId: number) {\n return this.httpClient.get(this.baseUrl + 'reader/time-left?seriesId=' + seriesId);\n }\n\n /**\n * Captures current body color and forces background color to be black. Call @see resetOverrideStyles() on destroy of component to revert changes\n */\n setOverrideStyles(backgroundColor: string = 'black') {\n const bodyNode = document.querySelector('body');\n if (bodyNode !== undefined && bodyNode !== null) {\n this.originalBodyColor = bodyNode.style.background;\n bodyNode.setAttribute('style', 'background-color: ' + backgroundColor + ' !important');\n }\n }\n\n resetOverrideStyles() {\n const bodyNode = document.querySelector('body');\n if (bodyNode !== undefined && bodyNode !== null && this.originalBodyColor !== undefined) {\n bodyNode.style.background = this.originalBodyColor;\n }\n }\n\n /**\n * Parses out the page number from a Image src url\n * @param imageSrc Src attribute of Image\n * @returns\n */\n imageUrlToPageNum(imageSrc: string) {\n if (imageSrc === undefined || imageSrc === '') { return -1; }\n return parseInt(imageSrc.split('&page=')[1], 10);\n }\n\n getNextChapterUrl(url: string, nextChapterId: number, incognitoMode: boolean = false, readingListMode: boolean = false, readingListId: number = -1) {\n const lastSlashIndex = url.lastIndexOf('/');\n let newRoute = url.substring(0, lastSlashIndex + 1) + nextChapterId + '';\n newRoute += this.getQueryParams(incognitoMode, readingListMode, readingListId);\n return newRoute;\n }\n\n\n getQueryParamsObject(incognitoMode: boolean = false, readingListMode: boolean = false, readingListId: number = -1) {\n let params: {[key: string]: any} = {};\n if (incognitoMode) {\n params['incognitoMode'] = true;\n }\n if (readingListMode) {\n params['readingListId'] = readingListId;\n }\n return params;\n }\n\n getQueryParams(incognitoMode: boolean = false, readingListMode: boolean = false, readingListId: number = -1) {\n let params = '';\n if (incognitoMode) {\n params += '?incognitoMode=true';\n }\n if (readingListMode) {\n if (params.indexOf('?') > 0) {\n params += '&readingListId=' + readingListId;\n } else {\n params += '?readingListId=' + readingListId;\n }\n }\n return params;\n }\n\n enterFullscreen(el: Element, callback?: VoidFunction) {\n if (!document.fullscreenElement) {\n if (el.requestFullscreen) {\n el.requestFullscreen().then(() => {\n if (callback) {\n callback();\n }\n });\n }\n }\n }\n\n exitFullscreen(callback?: VoidFunction) {\n if (document.exitFullscreen && this.checkFullscreenMode()) {\n document.exitFullscreen().then(() => {\n if (callback) {\n callback();\n }\n });\n }\n }\n\n /**\n *\n * @returns If document is in fullscreen mode\n */\n checkFullscreenMode() {\n return document.fullscreenElement != null;\n }\n\n /**\n * Closes the reader and causes a redirection\n */\n closeReader(readingListMode: boolean = false, readingListId: number = 0) {\n if (readingListMode) {\n this.router.navigateByUrl('lists/' + readingListId);\n } else {\n this.location.back();\n }\n }\n}\n","import { HttpClient, HttpParams } from '@angular/common/http';\nimport { Injectable } from '@angular/core';\nimport { map } from 'rxjs/operators';\nimport { environment } from 'src/environments/environment';\nimport { UtilityService } from '../shared/_services/utility.service';\nimport { PaginatedResult } from '../_models/pagination';\nimport { ReadingList, ReadingListItem } from '../_models/reading-list';\nimport { ActionItem } from './action-factory.service';\n\n@Injectable({\n providedIn: 'root'\n})\nexport class ReadingListService {\n\n baseUrl = environment.apiUrl;\n\n constructor(private httpClient: HttpClient, private utilityService: UtilityService) { }\n\n getReadingList(readingListId: number) {\n return this.httpClient.get(this.baseUrl + 'readinglist?readingListId=' + readingListId);\n }\n\n getReadingLists(includePromoted: boolean = true, pageNum?: number, itemsPerPage?: number) {\n let params = new HttpParams();\n params = this.utilityService.addPaginationIfExists(params, pageNum, itemsPerPage);\n\n return this.httpClient.post>(this.baseUrl + 'readinglist/lists?includePromoted=' + includePromoted, {}, {observe: 'response', params}).pipe(\n map((response: any) => {\n return this.utilityService.createPaginatedResult(response, new PaginatedResult());\n })\n );\n }\n\n getReadingListsForSeries(seriesId: number) {\n return this.httpClient.get(this.baseUrl + 'readinglist/lists-for-series?seriesId=' + seriesId);\n }\n\n getListItems(readingListId: number) {\n return this.httpClient.get(this.baseUrl + 'readinglist/items?readingListId=' + readingListId);\n }\n\n createList(title: string) {\n return this.httpClient.post(this.baseUrl + 'readinglist/create', {title});\n }\n\n update(model: {readingListId: number, title?: string, summary?: string, promoted: boolean}) {\n return this.httpClient.post(this.baseUrl + 'readinglist/update', model, { responseType: 'text' as 'json' });\n }\n\n updateByMultiple(readingListId: number, seriesId: number, volumeIds: Array, chapterIds?: Array) {\n return this.httpClient.post(this.baseUrl + 'readinglist/update-by-multiple', {readingListId, seriesId, volumeIds, chapterIds}, { responseType: 'text' as 'json' });\n }\n\n updateByMultipleSeries(readingListId: number, seriesIds: Array) {\n return this.httpClient.post(this.baseUrl + 'readinglist/update-by-multiple-series', {readingListId, seriesIds}, { responseType: 'text' as 'json' });\n }\n\n updateBySeries(readingListId: number, seriesId: number) {\n return this.httpClient.post(this.baseUrl + 'readinglist/update-by-series', {readingListId, seriesId}, { responseType: 'text' as 'json' });\n }\n\n updateByVolume(readingListId: number, seriesId: number, volumeId: number) {\n return this.httpClient.post(this.baseUrl + 'readinglist/update-by-volume', {readingListId, seriesId, volumeId}, { responseType: 'text' as 'json' });\n }\n\n updateByChapter(readingListId: number, seriesId: number, chapterId: number) {\n return this.httpClient.post(this.baseUrl + 'readinglist/update-by-chapter', {readingListId, seriesId, chapterId}, { responseType: 'text' as 'json' });\n }\n\n delete(readingListId: number) {\n return this.httpClient.delete(this.baseUrl + 'readinglist?readingListId=' + readingListId, { responseType: 'text' as 'json' });\n }\n\n updatePosition(readingListId: number, readingListItemId: number, fromPosition: number, toPosition: number) {\n return this.httpClient.post(this.baseUrl + 'readinglist/update-position', {readingListId, readingListItemId, fromPosition, toPosition}, { responseType: 'text' as 'json' });\n }\n\n deleteItem(readingListId: number, readingListItemId: number) {\n return this.httpClient.post(this.baseUrl + 'readinglist/delete-item', {readingListId, readingListItemId}, { responseType: 'text' as 'json' });\n }\n\n removeRead(readingListId: number) {\n return this.httpClient.post(this.baseUrl + 'readinglist/remove-read?readingListId=' + readingListId, {}, { responseType: 'text' as 'json' });\n }\n\n actionListFilter(action: ActionItem, readingList: ReadingList, isAdmin: boolean) {\n if (readingList?.promoted && !isAdmin) return false;\n return true;\n }\n}\n","import { ElementRef, Injectable } from '@angular/core';\nimport { NavigationEnd, Router } from '@angular/router';\nimport { filter, ReplaySubject } from 'rxjs';\n\n@Injectable({\n providedIn: 'root'\n})\nexport class ScrollService {\n\n private scrollContainerSource = new ReplaySubject>(1);\n /**\n * Exposes the current container on the active screen that is our primary overlay area. Defaults to 'body' and changes to 'body' on page loads\n */\n public scrollContainer$ = this.scrollContainerSource.asObservable();\n\n constructor(router: Router) {\n\n router.events\n .pipe(filter(event => event instanceof NavigationEnd))\n .subscribe(() => {\n this.scrollContainerSource.next('body');\n });\n this.scrollContainerSource.next('body');\n }\n\n get scrollPosition() {\n return (window.pageYOffset \n || document.documentElement.scrollTop \n || document.body.scrollTop || 0);\n }\n\n scrollTo(top: number, el: Element | Window = window) {\n el.scroll({\n top: top,\n behavior: 'smooth' \n });\n }\n \n scrollToX(left: number, el: Element | Window = window) {\n el.scroll({\n left: left,\n behavior: 'auto'\n });\n }\n\n setScrollContainer(elem: ElementRef | undefined) {\n if (elem !== undefined) {\n this.scrollContainerSource.next(elem);\n }\n }\n}\n","import { HttpClient, HttpParams } from '@angular/common/http';\nimport { Injectable } from '@angular/core';\nimport { Observable, of } from 'rxjs';\nimport { map } from 'rxjs/operators';\nimport { environment } from 'src/environments/environment';\nimport { UtilityService } from '../shared/_services/utility.service';\nimport { Chapter } from '../_models/chapter';\nimport { ChapterMetadata } from '../_models/chapter-metadata';\nimport { CollectionTag } from '../_models/collection-tag';\nimport { PaginatedResult } from '../_models/pagination';\nimport { Series } from '../_models/series';\nimport { RelatedSeries } from '../_models/series-detail/related-series';\nimport { SeriesDetail } from '../_models/series-detail/series-detail';\nimport { SeriesFilter } from '../_models/series-filter';\nimport { SeriesGroup } from '../_models/series-group';\nimport { SeriesMetadata } from '../_models/series-metadata';\nimport { Volume } from '../_models/volume';\nimport { ImageService } from './image.service';\n\n@Injectable({\n providedIn: 'root'\n})\nexport class SeriesService {\n\n baseUrl = environment.apiUrl;\n paginatedResults: PaginatedResult = new PaginatedResult();\n paginatedSeriesForTagsResults: PaginatedResult = new PaginatedResult();\n\n constructor(private httpClient: HttpClient, private imageService: ImageService, private utilityService: UtilityService) { }\n\n getAllSeries(pageNum?: number, itemsPerPage?: number, filter?: SeriesFilter) {\n let params = new HttpParams();\n params = this.utilityService.addPaginationIfExists(params, pageNum, itemsPerPage);\n const data = this.createSeriesFilter(filter);\n\n return this.httpClient.post>(this.baseUrl + 'series/all', data, {observe: 'response', params}).pipe(\n map((response: any) => {\n return this.utilityService.createPaginatedResult(response, this.paginatedResults);\n })\n );\n }\n\n getSeriesForLibrary(libraryId: number, pageNum?: number, itemsPerPage?: number, filter?: SeriesFilter) {\n let params = new HttpParams();\n params = this.utilityService.addPaginationIfExists(params, pageNum, itemsPerPage);\n const data = this.createSeriesFilter(filter);\n\n return this.httpClient.post>(this.baseUrl + 'series?libraryId=' + libraryId, data, {observe: 'response', params}).pipe(\n map((response: any) => {\n return this.utilityService.createPaginatedResult(response, this.paginatedResults);\n })\n );\n }\n\n getAllSeriesByIds(seriesIds: Array) {\n return this.httpClient.post(this.baseUrl + 'series/series-by-ids', {seriesIds: seriesIds});\n }\n\n getSeries(seriesId: number) {\n return this.httpClient.get(this.baseUrl + 'series/' + seriesId);\n }\n\n getVolumes(seriesId: number) {\n return this.httpClient.get(this.baseUrl + 'series/volumes?seriesId=' + seriesId);\n }\n\n getVolume(volumeId: number) {\n return this.httpClient.get(this.baseUrl + 'series/volume?volumeId=' + volumeId);\n }\n\n getChapter(chapterId: number) {\n return this.httpClient.get(this.baseUrl + 'series/chapter?chapterId=' + chapterId);\n }\n\n getChapterMetadata(chapterId: number) {\n return this.httpClient.get(this.baseUrl + 'series/chapter-metadata?chapterId=' + chapterId);\n }\n\n getSeriesForMangaFile(mangaFileId: number) {\n return this.httpClient.get(this.baseUrl + 'series/series-for-mangafile?mangaFileId=' + mangaFileId);\n }\n\n getSeriesForChapter(chapterId: number) {\n return this.httpClient.get(this.baseUrl + 'series/series-for-chapter?chapterId=' + chapterId);\n }\n\n delete(seriesId: number) {\n return this.httpClient.delete(this.baseUrl + 'series/' + seriesId);\n }\n\n deleteMultipleSeries(seriesIds: Array) {\n return this.httpClient.post(this.baseUrl + 'series/delete-multiple', {seriesIds});\n }\n\n updateRating(seriesId: number, userRating: number, userReview: string) {\n return this.httpClient.post(this.baseUrl + 'series/update-rating', {seriesId, userRating, userReview});\n }\n\n updateSeries(model: any) {\n return this.httpClient.post(this.baseUrl + 'series/update', model);\n }\n\n markRead(seriesId: number) {\n return this.httpClient.post(this.baseUrl + 'reader/mark-read', {seriesId});\n }\n\n markUnread(seriesId: number) {\n return this.httpClient.post(this.baseUrl + 'reader/mark-unread', {seriesId});\n }\n\n getRecentlyAdded(libraryId: number = 0, pageNum?: number, itemsPerPage?: number, filter?: SeriesFilter) {\n const data = this.createSeriesFilter(filter);\n let params = new HttpParams();\n params = this.utilityService.addPaginationIfExists(params, pageNum, itemsPerPage);\n\n return this.httpClient.post(this.baseUrl + 'series/recently-added?libraryId=' + libraryId, data, {observe: 'response', params}).pipe(\n map(response => {\n return this.utilityService.createPaginatedResult(response, new PaginatedResult());\n })\n );\n }\n\n getRecentlyUpdatedSeries() {\n return this.httpClient.post(this.baseUrl + 'series/recently-updated-series', {});\n }\n\n getWantToRead(pageNum?: number, itemsPerPage?: number, filter?: SeriesFilter): Observable> {\n const data = this.createSeriesFilter(filter);\n\n let params = new HttpParams();\n params = this.utilityService.addPaginationIfExists(params, pageNum, itemsPerPage);\n\n return this.httpClient.post(this.baseUrl + 'want-to-read/', data, {observe: 'response', params}).pipe(\n map(response => {\n return this.utilityService.createPaginatedResult(response, new PaginatedResult());\n }));\n }\n\n getOnDeck(libraryId: number = 0, pageNum?: number, itemsPerPage?: number, filter?: SeriesFilter) {\n const data = this.createSeriesFilter(filter);\n\n let params = new HttpParams();\n params = this.utilityService.addPaginationIfExists(params, pageNum, itemsPerPage);\n\n return this.httpClient.post(this.baseUrl + 'series/on-deck?libraryId=' + libraryId, data, {observe: 'response', params}).pipe(\n map(response => {\n return this.utilityService.createPaginatedResult(response, new PaginatedResult());\n }));\n }\n\n\n refreshMetadata(series: Series) {\n return this.httpClient.post(this.baseUrl + 'series/refresh-metadata', {libraryId: series.libraryId, seriesId: series.id});\n }\n\n scan(libraryId: number, seriesId: number, force = false) {\n return this.httpClient.post(this.baseUrl + 'series/scan', {libraryId: libraryId, seriesId: seriesId, forceUpdate: force});\n }\n\n analyzeFiles(libraryId: number, seriesId: number) {\n return this.httpClient.post(this.baseUrl + 'series/analyze', {libraryId: libraryId, seriesId: seriesId});\n }\n\n getMetadata(seriesId: number) {\n return this.httpClient.get(this.baseUrl + 'series/metadata?seriesId=' + seriesId).pipe(map(items => {\n items?.collectionTags.forEach(tag => tag.coverImage = this.imageService.getCollectionCoverImage(tag.id));\n return items;\n }));\n }\n\n updateMetadata(seriesMetadata: SeriesMetadata, collectionTags: CollectionTag[]) {\n const data = {\n seriesMetadata,\n collectionTags,\n };\n return this.httpClient.post(this.baseUrl + 'series/metadata', data, {responseType: 'text' as 'json'});\n }\n\n getSeriesForTag(collectionTagId: number, pageNum?: number, itemsPerPage?: number) {\n let params = new HttpParams();\n\n params = this.utilityService.addPaginationIfExists(params, pageNum, itemsPerPage);\n\n return this.httpClient.get>(this.baseUrl + 'series/series-by-collection?collectionId=' + collectionTagId, {observe: 'response', params}).pipe(\n map((response: any) => {\n return this.utilityService.createPaginatedResult(response, this.paginatedSeriesForTagsResults);\n })\n );\n }\n\n getRelatedForSeries(seriesId: number) {\n return this.httpClient.get(this.baseUrl + 'series/all-related?seriesId=' + seriesId);\n }\n\n updateRelationships(seriesId: number, adaptations: Array, characters: Array, \n contains: Array, others: Array, prequels: Array, \n sequels: Array, sideStories: Array, spinOffs: Array,\n alternativeSettings: Array, alternativeVersions: Array, doujinshis: Array) {\n return this.httpClient.post(this.baseUrl + 'series/update-related?seriesId=' + seriesId, \n {seriesId, adaptations, characters, sequels, prequels, contains, others, sideStories, spinOffs,\n alternativeSettings, alternativeVersions, doujinshis}); \n }\n\n getSeriesDetail(seriesId: number) {\n return this.httpClient.get(this.baseUrl + 'series/series-detail?seriesId=' + seriesId);\n }\n\n \n\n createSeriesFilter(filter?: SeriesFilter) {\n if (filter !== undefined) return filter;\n const data: SeriesFilter = {\n formats: [],\n libraries: [],\n genres: [],\n writers: [],\n artists: [],\n penciller: [],\n inker: [],\n colorist: [],\n letterer: [],\n coverArtist: [],\n editor: [],\n publisher: [],\n character: [],\n translators: [],\n collectionTags: [],\n rating: 0,\n readStatus: {\n read: true,\n inProgress: true,\n notRead: true\n },\n sortOptions: null,\n ageRating: [],\n tags: [],\n languages: [],\n publicationStatus: [],\n seriesNameQuery: '',\n };\n\n return data;\n }\n}\n","import { DOCUMENT } from '@angular/common';\nimport { HttpClient } from '@angular/common/http';\nimport { Inject, Injectable, OnDestroy, Renderer2, RendererFactory2, SecurityContext } from '@angular/core';\nimport { DomSanitizer } from '@angular/platform-browser';\nimport { ToastrService } from 'ngx-toastr';\nimport { map, ReplaySubject, Subject, takeUntil, take } from 'rxjs';\nimport { environment } from 'src/environments/environment';\nimport { ConfirmService } from '../shared/confirm.service';\nimport { NotificationProgressEvent } from '../_models/events/notification-progress-event';\nimport { SiteTheme, ThemeProvider } from '../_models/preferences/site-theme';\nimport { EVENTS, MessageHubService } from './message-hub.service';\n\n\n@Injectable({\n providedIn: 'root'\n})\nexport class ThemeService implements OnDestroy {\n\n public defaultTheme: string = 'dark';\n public defaultBookTheme: string = 'Dark';\n\n private currentThemeSource = new ReplaySubject(1);\n public currentTheme$ = this.currentThemeSource.asObservable();\n\n private themesSource = new ReplaySubject(1);\n public themes$ = this.themesSource.asObservable();\n\n /**\n * Maintain a cache of themes. SignalR will inform us if we need to refresh cache\n */\n private themeCache: Array = [];\n\n private readonly onDestroy = new Subject();\n private renderer: Renderer2;\n private baseUrl = environment.apiUrl;\n\n\n constructor(rendererFactory: RendererFactory2, @Inject(DOCUMENT) private document: Document, private httpClient: HttpClient,\n messageHub: MessageHubService, private domSantizer: DomSanitizer, private confirmService: ConfirmService, private toastr: ToastrService) {\n this.renderer = rendererFactory.createRenderer(null, null);\n\n this.getThemes();\n\n messageHub.messages$.pipe(takeUntil(this.onDestroy)).subscribe(message => {\n\n if (message.event !== EVENTS.NotificationProgress) return;\n const notificationEvent = (message.payload as NotificationProgressEvent);\n if (notificationEvent.name !== EVENTS.SiteThemeProgress) return;\n\n if (notificationEvent.eventType === 'ended') {\n if (notificationEvent.name === EVENTS.SiteThemeProgress) this.getThemes().subscribe(() => {\n\n });\n }\n });\n }\n\n ngOnDestroy(): void {\n this.onDestroy.next();\n this.onDestroy.complete();\n }\n\n getColorScheme() {\n return getComputedStyle(this.document.body).getPropertyValue('--color-scheme').trim();\n }\n\n getCssVariable(variable: string) {\n return getComputedStyle(this.document.body).getPropertyValue(variable).trim();\n }\n\n isDarkTheme() {\n return this.getColorScheme().toLowerCase() === 'dark';\n }\n\n getThemes() {\n return this.httpClient.get(this.baseUrl + 'theme').pipe(map(themes => {\n this.themeCache = themes;\n this.themesSource.next(themes);\n this.currentTheme$.pipe(take(1)).subscribe(theme => {\n if (!themes.includes(theme)) {\n this.setTheme(this.defaultTheme);\n this.toastr.info('The active theme no longer exists. Please refresh the page.');\n }\n });\n return themes;\n }));\n }\n\n /**\n * Used in book reader to remove all themes so book reader can provide custom theming options\n */\n clearThemes() {\n this.unsetThemes();\n }\n\n setDefault(themeId: number) {\n return this.httpClient.post(this.baseUrl + 'theme/update-default', {themeId: themeId}).pipe(map(() => {\n // Refresh the cache when a default state is changed\n this.getThemes().subscribe(() => {});\n }));\n }\n\n scan() {\n return this.httpClient.post(this.baseUrl + 'theme/scan', {});\n }\n\n /**\n * Sets the book theme on the body tag so css variable overrides can take place\n * @param selector brtheme- prefixed string\n */\n setBookTheme(selector: string) {\n this.unsetBookThemes();\n this.renderer.addClass(this.document.querySelector('body'), selector);\n }\n\n clearBookTheme() {\n this.unsetBookThemes();\n }\n\n\n /**\n * Sets the theme as active. Will inject a style tag into document to load a custom theme and apply the selector to the body\n * @param themeName\n */\n setTheme(themeName: string) {\n const theme = this.themeCache.find(t => t.name.toLowerCase() === themeName.toLowerCase());\n if (theme) {\n this.unsetThemes();\n this.renderer.addClass(this.document.querySelector('body'), theme.selector);\n\n if (theme.provider === ThemeProvider.User && !this.hasThemeInHead(theme.name)) {\n // We need to load the styles into the browser\n this.fetchThemeContent(theme.id).subscribe(async (content) => {\n if (content === null) {\n await this.confirmService.alert('There is invalid or unsafe css in the theme. Please reach out to your admin to have this corrected. Defaulting to dark theme.');\n this.setTheme('dark');\n return;\n }\n const styleElem = document.createElement('style');\n styleElem.id = 'theme-' + theme.name;\n styleElem.appendChild(this.document.createTextNode(content));\n\n this.renderer.appendChild(this.document.head, styleElem);\n this.currentThemeSource.next(theme);\n });\n } else {\n this.currentThemeSource.next(theme);\n }\n } else {\n // Only time themes isn't already loaded is on first load\n this.getThemes().subscribe(themes => {\n this.setTheme(themeName);\n });\n }\n }\n\n private hasThemeInHead(themeName: string) {\n const id = 'theme-' + themeName.toLowerCase();\n return Array.from(this.document.head.children).filter(el => el.tagName === 'STYLE' && el.id.toLowerCase() === id).length > 0;\n }\n\n private fetchThemeContent(themeId: number) {\n // TODO: Refactor {responseType: 'text' as 'json'} into a type so i don't have to retype it\n return this.httpClient.get(this.baseUrl + 'theme/download-content?themeId=' + themeId, {responseType: 'text' as 'json'}).pipe(map(encodedCss => {\n return this.domSantizer.sanitize(SecurityContext.STYLE, encodedCss);\n }));\n }\n\n private unsetThemes() {\n this.themeCache.forEach(theme => this.document.body.classList.remove(theme.selector));\n }\n\n private unsetBookThemes() {\n Array.from(this.document.body.classList).filter(cls => cls.startsWith('brtheme-')).forEach(c => this.document.body.classList.remove(c));\n }\n\n\n}\n","import { HttpClient } from '@angular/common/http';\nimport { Injectable } from '@angular/core';\nimport { environment } from 'src/environments/environment';\n\n@Injectable({\n providedIn: 'root'\n})\nexport class UploadService {\n\n private baseUrl = environment.apiUrl;\n\n constructor(private httpClient: HttpClient) { }\n\n\n uploadByUrl(url: string) {\n return this.httpClient.post(this.baseUrl + 'upload/upload-by-url', {url}, {responseType: 'text' as 'json'});\n }\n\n /**\n * \n * @param seriesId Series to overwrite cover image for\n * @param url A base64 encoded url\n * @returns \n */\n updateSeriesCoverImage(seriesId: number, url: string) {\n return this.httpClient.post(this.baseUrl + 'upload/series', {id: seriesId, url: this._cleanBase64Url(url)});\n }\n\n updateCollectionCoverImage(tagId: number, url: string) {\n return this.httpClient.post(this.baseUrl + 'upload/collection', {id: tagId, url: this._cleanBase64Url(url)});\n }\n\n updateReadingListCoverImage(readingListId: number, url: string) {\n return this.httpClient.post(this.baseUrl + 'upload/reading-list', {id: readingListId, url: this._cleanBase64Url(url)});\n }\n\n updateChapterCoverImage(chapterId: number, url: string) {\n return this.httpClient.post(this.baseUrl + 'upload/chapter', {id: chapterId, url: this._cleanBase64Url(url)});\n }\n\n resetChapterCoverLock(chapterId: number, ) {\n return this.httpClient.post(this.baseUrl + 'upload/reset-chapter-lock', {id: chapterId, url: ''});\n }\n\n _cleanBase64Url(url: string) {\n if (url.startsWith('data')) {\n url = url.split(',')[1];\n }\n return url;\n }\n}\n"," 0\">\n
\n \n
\n \n
1 && adminActions.length > 1\">
\n \n
\n
\n \n
","import { ChangeDetectionStrategy, ChangeDetectorRef, Component, EventEmitter, Input, OnInit, Output } from '@angular/core';\nimport { ActionItem } from 'src/app/_services/action-factory.service';\n\n@Component({\n selector: 'app-card-actionables',\n templateUrl: './card-actionables.component.html',\n styleUrls: ['./card-actionables.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class CardActionablesComponent implements OnInit {\n\n @Input() iconClass = 'fa-ellipsis-v';\n @Input() btnClass = '';\n @Input() actions: ActionItem[] = [];\n @Input() labelBy = 'card';\n @Input() disabled: boolean = false;\n @Output() actionHandler = new EventEmitter>();\n\n adminActions: ActionItem[] = [];\n nonAdminActions: ActionItem[] = [];\n\n\n constructor(private readonly cdRef: ChangeDetectorRef) { }\n\n ngOnInit(): void {\n this.nonAdminActions = this.actions.filter(item => !item.requiresAdmin);\n this.adminActions = this.actions.filter(item => item.requiresAdmin);\n this.cdRef.markForCheck();\n }\n\n preventClick(event: any) {\n event.stopPropagation();\n event.preventDefault();\n }\n\n performAction(event: any, action: ActionItem) {\n this.preventClick(event);\n\n if (typeof action.callback === 'function') {\n this.actionHandler.emit(action);\n }\n }\n\n}\n","import { NgModule } from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { MetadataFilterComponent } from './metadata-filter.component';\nimport { NgbCollapseModule, NgbRatingModule, NgbTooltipModule } from '@ng-bootstrap/ng-bootstrap';\nimport { FormsModule, ReactiveFormsModule } from '@angular/forms';\nimport { SharedModule } from '../shared/shared.module';\nimport { TypeaheadModule } from '../typeahead/typeahead.module';\n\n@NgModule({\n declarations: [\n MetadataFilterComponent\n ],\n imports: [\n CommonModule,\n FormsModule,\n ReactiveFormsModule,\n NgbTooltipModule, \n NgbRatingModule,\n NgbCollapseModule,\n SharedModule,\n TypeaheadModule\n ],\n exports: [\n MetadataFilterComponent\n ]\n})\nexport class MetadataFilterModule { }\n","import { NgModule } from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { SeriesCardComponent } from './series-card/series-card.component';\nimport { CoverImageChooserComponent } from './cover-image-chooser/cover-image-chooser.component';\nimport { EditSeriesModalComponent } from './_modals/edit-series-modal/edit-series-modal.component';\nimport { EditCollectionTagsComponent } from './_modals/edit-collection-tags/edit-collection-tags.component';\nimport { NgbTooltipModule, NgbCollapseModule, NgbPaginationModule, NgbDropdownModule, NgbProgressbarModule, NgbNavModule, NgbRatingModule, NgbOffcanvasModule } from '@ng-bootstrap/ng-bootstrap';\nimport { CardActionablesComponent } from './card-item/card-actionables/card-actionables.component';\nimport { FormsModule, ReactiveFormsModule } from '@angular/forms';\nimport { NgxFileDropModule } from 'ngx-file-drop';\nimport { CardItemComponent } from './card-item/card-item.component';\nimport { SharedModule } from '../shared/shared.module';\nimport { RouterModule } from '@angular/router';\nimport { TypeaheadModule } from '../typeahead/typeahead.module';\nimport { CardDetailLayoutComponent } from './card-detail-layout/card-detail-layout.component';\nimport { BulkOperationsComponent } from './bulk-operations/bulk-operations.component';\nimport { BulkAddToCollectionComponent } from './_modals/bulk-add-to-collection/bulk-add-to-collection.component';\nimport { PipeModule } from '../pipe/pipe.module';\nimport { ChapterMetadataDetailComponent } from './chapter-metadata-detail/chapter-metadata-detail.component';\nimport { MetadataFilterModule } from '../metadata-filter/metadata-filter.module';\nimport { EditSeriesRelationComponent } from './edit-series-relation/edit-series-relation.component';\nimport { CardDetailDrawerComponent } from './card-detail-drawer/card-detail-drawer.component';\nimport { EntityTitleComponent } from './entity-title/entity-title.component';\nimport { EntityInfoCardsComponent } from './entity-info-cards/entity-info-cards.component';\nimport { ListItemComponent } from './list-item/list-item.component';\nimport { VirtualScrollerModule } from '@iharbeck/ngx-virtual-scroller';\nimport { SeriesInfoCardsComponent } from './series-info-cards/series-info-cards.component';\nimport { DownloadIndicatorComponent } from './download-indicator/download-indicator.component';\n\n\n\n\n@NgModule({\n declarations: [\n CardItemComponent,\n SeriesCardComponent,\n CoverImageChooserComponent,\n EditSeriesModalComponent,\n EditCollectionTagsComponent,\n CardActionablesComponent,\n CardDetailLayoutComponent,\n BulkOperationsComponent,\n BulkAddToCollectionComponent,\n ChapterMetadataDetailComponent,\n EditSeriesRelationComponent,\n CardDetailDrawerComponent,\n EntityTitleComponent,\n EntityInfoCardsComponent,\n ListItemComponent,\n SeriesInfoCardsComponent,\n DownloadIndicatorComponent,\n ],\n imports: [\n CommonModule,\n RouterModule,\n ReactiveFormsModule,\n FormsModule, // EditCollectionsModal\n\n PipeModule,\n SharedModule,\n TypeaheadModule, // edit series modal\n\n MetadataFilterModule,\n\n NgbTooltipModule, // Card item\n NgbCollapseModule,\n NgbRatingModule,\n \n VirtualScrollerModule,\n\n\n NgbOffcanvasModule, // Series Detail, action of cards\n NgbNavModule, //Series Detail\n NgbPaginationModule, // EditCollectionTagsComponent \n NgbDropdownModule,\n NgbProgressbarModule,\n NgxFileDropModule, // Cover Chooser\n PipeModule, // filter for BulkAddToCollectionComponent\n\n \n \n\n SharedModule, // IconAndTitleComponent\n ],\n exports: [\n CardItemComponent,\n SeriesCardComponent,\n SeriesCardComponent,\n CoverImageChooserComponent,\n EditSeriesModalComponent,\n EditCollectionTagsComponent,\n CardActionablesComponent,\n CardDetailLayoutComponent,\n BulkOperationsComponent,\n ChapterMetadataDetailComponent,\n EditSeriesRelationComponent,\n\n EntityTitleComponent,\n EntityInfoCardsComponent,\n ListItemComponent,\n\n NgbOffcanvasModule,\n\n VirtualScrollerModule,\n SeriesInfoCardsComponent\n\n\n ]\n})\nexport class CardsModule { }\n","
\n
\n \n \n
\n
\n
\n \n
\n\n
\n
\n Enter a Url\n •\n Drag and drop\n •\n Upload an image\n
\n
\n
\n
\n \n\n \n
\n
\n \n \n \n
\n \n
\n \n
\n \n
\n
\n\n \n\n \n
\n\n
\n
\n 0\">\n \n
\n \n
\n
\n
\n \n \n
\n \n
\n \n
\n
\n\n
\n\n","import { ChangeDetectionStrategy, ChangeDetectorRef, Component, EventEmitter, Inject, Input, OnDestroy, OnInit, Output } from '@angular/core';\nimport { FormBuilder, FormControl, FormGroup } from '@angular/forms';\nimport { NgxFileDropEntry, FileSystemFileEntry } from 'ngx-file-drop';\nimport { fromEvent, Subject } from 'rxjs';\nimport { takeWhile } from 'rxjs/operators';\nimport { ToastrService } from 'ngx-toastr';\nimport { ImageService } from 'src/app/_services/image.service';\nimport { KEY_CODES } from 'src/app/shared/_services/utility.service';\nimport { UploadService } from 'src/app/_services/upload.service';\nimport { DOCUMENT } from '@angular/common';\n\nexport type SelectCoverFunction = (selectedCover: string) => void;\n\n@Component({\n selector: 'app-cover-image-chooser',\n templateUrl: './cover-image-chooser.component.html',\n styleUrls: ['./cover-image-chooser.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class CoverImageChooserComponent implements OnInit, OnDestroy {\n\n /**\n * If buttons show under images to allow immediate selection of cover images.\n */\n @Input() showApplyButton: boolean = false;\n /**\n * When a cover image is selected, this will be called with a base url representation of the file.\n */\n @Output() applyCover: EventEmitter = new EventEmitter();\n /**\n * When a cover image is reset, this will be called.\n */\n @Output() resetCover: EventEmitter = new EventEmitter();\n\n @Input() imageUrls: Array = [];\n @Output() imageUrlsChange: EventEmitter> = new EventEmitter>();\n\n /**\n * Should the control give the ability to select an image that emits the reset status for cover image\n */\n @Input() showReset: boolean = false;\n @Output() resetClicked: EventEmitter = new EventEmitter();\n\n /**\n * Emits the selected index. Used usually to check if something other than the default image was selected.\n */\n @Output() imageSelected: EventEmitter = new EventEmitter();\n /**\n * Emits a base64 encoded image\n */\n @Output() selectedBase64Url: EventEmitter = new EventEmitter();\n\n\n\n selectedIndex: number = 0;\n /**\n * Only applies for showApplyButton. Used to track which image is applied.\n */\n appliedIndex: number = 0;\n form!: FormGroup;\n files: NgxFileDropEntry[] = [];\n acceptableExtensions = ['.png', '.jpg', '.jpeg', '.gif', '.webp'].join(',');\n\n mode: 'file' | 'url' | 'all' = 'all';\n private readonly onDestroy = new Subject();\n\n constructor(public imageService: ImageService, private fb: FormBuilder, private toastr: ToastrService, private uploadService: UploadService,\n @Inject(DOCUMENT) private document: Document, private readonly cdRef: ChangeDetectorRef) { }\n\n ngOnInit(): void {\n this.form = this.fb.group({\n coverImageUrl: new FormControl('', [])\n });\n this.cdRef.markForCheck();\n }\n\n ngOnDestroy() {\n this.onDestroy.next();\n this.onDestroy.complete();\n }\n\n getBase64Image(img: HTMLImageElement) {\n const canvas = document.createElement(\"canvas\");\n canvas.width = img.width;\n canvas.height = img.height;\n const ctx = canvas.getContext(\"2d\", {alpha: false});\n if (!ctx) {\n return '';\n }\n\n ctx.drawImage(img, 0, 0);\n const dataURL = canvas.toDataURL(\"image/png\");\n return dataURL;\n }\n\n selectImage(index: number) {\n if (this.selectedIndex === index) { return; }\n this.selectedIndex = index;\n this.cdRef.markForCheck();\n this.imageSelected.emit(this.selectedIndex);\n this.selectedBase64Url.emit(this.imageUrls[this.selectedIndex]);\n }\n\n applyImage(index: number) {\n if (this.showApplyButton) {\n this.applyCover.emit(this.imageUrls[index]);\n this.appliedIndex = index;\n this.cdRef.markForCheck();\n }\n }\n\n resetImage() {\n if (this.showApplyButton) {\n this.resetCover.emit();\n }\n }\n\n loadImage() {\n const url = this.form.get('coverImageUrl')?.value.trim();\n if (!url && url === '') return;\n\n this.uploadService.uploadByUrl(url).subscribe(filename => {\n const img = new Image();\n img.crossOrigin = 'Anonymous';\n img.src = this.imageService.getCoverUploadImage(filename);\n img.onload = (e) => this.handleUrlImageAdd(img);\n img.onerror = (e) => {\n this.toastr.error('The image could not be fetched due to server refusing request. Please download and upload from file instead.');\n this.form.get('coverImageUrl')?.setValue('');\n this.cdRef.markForCheck();\n };\n this.form.get('coverImageUrl')?.setValue('');\n this.cdRef.markForCheck();\n });\n }\n\n changeMode(mode: 'url') {\n this.mode = mode;\n this.setupEnterHandler();\n this.cdRef.markForCheck();\n\n setTimeout(() => (this.document.querySelector('#load-image') as HTMLInputElement)?.focus(), 10);\n }\n\n public dropped(files: NgxFileDropEntry[]) {\n this.files = files;\n for (const droppedFile of files) {\n\n // Is it a file?\n if (droppedFile.fileEntry.isFile) {\n const fileEntry = droppedFile.fileEntry as FileSystemFileEntry;\n fileEntry.file((file: File) => {\n const reader = new FileReader();\n reader.onload = (e) => this.handleFileImageAdd(e);\n reader.readAsDataURL(file);\n });\n }\n }\n }\n\n handleFileImageAdd(e: any) {\n if (e.target == null) return;\n\n this.imageUrls.push(e.target.result);\n this.imageUrlsChange.emit(this.imageUrls);\n this.selectedIndex += 1;\n this.imageSelected.emit(this.selectedIndex); // Auto select newly uploaded image\n this.selectedBase64Url.emit(e.target.result);\n this.cdRef.markForCheck();\n }\n\n handleUrlImageAdd(img: HTMLImageElement) {\n const url = this.getBase64Image(img);\n this.imageUrls.push(url);\n this.imageUrlsChange.emit(this.imageUrls);\n this.cdRef.markForCheck();\n\n setTimeout(() => {\n // Auto select newly uploaded image and tell parent of new base64 url\n this.selectImage(this.selectedIndex + 1);\n });\n }\n\n public fileOver(event: any){\n }\n\n public fileLeave(event: any){\n }\n\n reset() {\n this.resetClicked.emit();\n this.selectedIndex = -1;\n }\n\n setupEnterHandler() {\n setTimeout(() => {\n const elem = document.querySelector('input[id=\"load-image\"]');\n if (elem == null) return;\n fromEvent(elem, 'keydown')\n .pipe(takeWhile(() => this.mode === 'url')).subscribe((event) => {\n const evt = event;\n switch(evt.key) {\n case KEY_CODES.ENTER:\n {\n this.loadImage();\n break;\n }\n\n case KEY_CODES.ESC_KEY:\n this.mode = 'all';\n event.stopPropagation();\n break;\n default:\n break;\n }\n });\n });\n }\n\n}\n","import { Pipe, PipeTransform } from '@angular/core';\n\n@Pipe({\n name: 'filter',\n pure: false\n})\nexport class FilterPipe implements PipeTransform {\n\n transform(items: any[], callback: (item: any) => boolean): any {\n if (!items || !callback) {\n return items;\n }\n return items.filter(item => callback(item));\n}\n\n}\n","import { Pipe, PipeTransform } from '@angular/core';\nimport { MangaFormat } from '../_models/manga-format';\n\n/**\n * Returns the icon class representing the format\n */\n@Pipe({\n name: 'mangaFormatIcon'\n})\nexport class MangaFormatIconPipe implements PipeTransform {\n\n transform(format: MangaFormat): string {\n switch (format) {\n case MangaFormat.EPUB:\n return 'fa-book';\n case MangaFormat.ARCHIVE:\n return 'fa-file-archive';\n case MangaFormat.IMAGE:\n return 'fa-image';\n case MangaFormat.PDF:\n return 'fa-file-pdf';\n case MangaFormat.UNKNOWN:\n return 'fa-question';\n }\n }\n\n}\n","import { Pipe, PipeTransform } from '@angular/core';\nimport { MangaFormat } from '../_models/manga-format';\n\n/**\n * Returns the string name for the format\n */\n@Pipe({\n name: 'mangaFormat'\n})\nexport class MangaFormatPipe implements PipeTransform {\n\n transform(format: MangaFormat): string {\n switch (format) {\n case MangaFormat.EPUB:\n return 'EPUB';\n case MangaFormat.ARCHIVE:\n return 'Archive';\n case MangaFormat.IMAGE:\n return 'Image';\n case MangaFormat.PDF:\n return 'PDF';\n case MangaFormat.UNKNOWN:\n return 'Unknown';\n }\n }\n\n}\n","import { NgModule } from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { FilterPipe } from './filter.pipe';\nimport { PublicationStatusPipe } from './publication-status.pipe';\nimport { SentenceCasePipe } from './sentence-case.pipe';\nimport { PersonRolePipe } from './person-role.pipe';\nimport { SafeHtmlPipe } from './safe-html.pipe';\nimport { RelationshipPipe } from './relationship.pipe';\nimport { DefaultValuePipe } from './default-value.pipe';\nimport { CompactNumberPipe } from './compact-number.pipe';\nimport { LanguageNamePipe } from './language-name.pipe';\nimport { AgeRatingPipe } from './age-rating.pipe';\nimport { MangaFormatPipe } from './manga-format.pipe';\nimport { MangaFormatIconPipe } from './manga-format-icon.pipe';\nimport { LibraryTypePipe } from './library-type.pipe';\nimport { SafeStylePipe } from './safe-style.pipe';\nimport { DefaultDatePipe } from './default-date.pipe';\n\n\n\n@NgModule({\n declarations: [\n FilterPipe,\n PersonRolePipe,\n PublicationStatusPipe,\n SentenceCasePipe,\n SafeHtmlPipe,\n RelationshipPipe,\n DefaultValuePipe,\n CompactNumberPipe,\n LanguageNamePipe,\n AgeRatingPipe,\n MangaFormatPipe,\n MangaFormatIconPipe,\n LibraryTypePipe,\n SafeStylePipe,\n DefaultDatePipe\n ],\n imports: [\n CommonModule,\n ],\n exports: [\n FilterPipe,\n PersonRolePipe,\n PublicationStatusPipe,\n SentenceCasePipe,\n SafeHtmlPipe,\n RelationshipPipe,\n DefaultValuePipe,\n CompactNumberPipe,\n LanguageNamePipe,\n AgeRatingPipe,\n MangaFormatPipe,\n MangaFormatIconPipe,\n LibraryTypePipe,\n SafeStylePipe,\n DefaultDatePipe\n ]\n})\nexport class PipeModule { }\n","import { Pipe, PipeTransform, SecurityContext } from '@angular/core';\nimport { DomSanitizer } from '@angular/platform-browser';\n\n@Pipe({\n name: 'safeHtml'\n})\nexport class SafeHtmlPipe implements PipeTransform {\n\n constructor(private dom: DomSanitizer) {}\n\n transform(value: string): unknown {\n return this.dom.sanitize(SecurityContext.HTML, value);\n }\n\n}\n","import { Pipe, PipeTransform } from '@angular/core';\n\n@Pipe({\n name: 'sentenceCase'\n})\nexport class SentenceCasePipe implements PipeTransform {\n\n transform(value: string | null): string {\n if (value === null || value === undefined) return '';\n \n return value.charAt(0).toUpperCase() + value.substr(1);\n }\n\n}\n","import {InjectionToken} from '@angular/core'\nimport { saveAs } from 'file-saver';\n\nexport type Saver = (blob: Blob, filename?: string) => void\n\nexport const SAVER = new InjectionToken('saver')\n\nexport function getSaver(): Saver {\n return saveAs;\n}","import {\n HttpEvent,\n HttpEventType,\n HttpHeaders,\n HttpProgressEvent,\n HttpResponse\n } from \"@angular/common/http\";\n import { Observable } from \"rxjs\";\n import { scan } from \"rxjs/operators\";\n \n function isHttpResponse(event: HttpEvent): event is HttpResponse {\n return event.type === HttpEventType.Response;\n }\n \n function isHttpProgressEvent(\n event: HttpEvent\n ): event is HttpProgressEvent {\n return (\n event.type === HttpEventType.DownloadProgress ||\n event.type === HttpEventType.UploadProgress\n );\n }\n\n/**\n * Encapsulates an inprogress download of a Blob with progress reporting activated\n */ \nexport interface Download {\n content: Blob | null;\n progress: number;\n state: \"PENDING\" | \"IN_PROGRESS\" | \"DONE\";\n filename?: string;\n loaded?: number;\n total?: number\n}\n \nexport function download(saver?: (b: Blob, filename: string) => void): (source: Observable>) => Observable {\n return (source: Observable>) =>\n source.pipe(\n scan((previous: Download, event: HttpEvent): Download => {\n if (isHttpProgressEvent(event)) {\n return {\n progress: event.total\n ? Math.round((100 * event.loaded) / event.total)\n : previous.progress,\n state: 'IN_PROGRESS',\n content: null,\n loaded: event.loaded,\n total: event.total\n }\n }\n if (isHttpResponse(event)) {\n if (saver && event.body) {\n saver(event.body, getFilename(event.headers, ''))\n }\n return {\n progress: 100,\n state: 'DONE',\n content: event.body,\n filename: getFilename(event.headers, ''),\n }\n }\n return previous;\n },\n {state: 'PENDING', progress: 0, content: null}\n )\n )\n }\n\n\nfunction getFilename(headers: HttpHeaders, defaultName: string) {\n const tokens = (headers.get('content-disposition') || '').split(';');\n let filename = tokens[1].replace('filename=', '').replace(/\"/ig, '').trim(); \n if (filename.startsWith('download_') || filename.startsWith('kavita_download_')) {\n const ext = filename.substring(filename.lastIndexOf('.'), filename.length);\n if (defaultName !== '') {\n return defaultName + ext;\n }\n return filename.replace('kavita_', '').replace('download_', '');\n //return defaultName + ext;\n }\n return filename;\n }","import { HttpClient, HttpErrorResponse, HttpEventType } from '@angular/common/http';\nimport { Inject, Injectable } from '@angular/core';\nimport { Series } from 'src/app/_models/series';\nimport { environment } from 'src/environments/environment';\nimport { ConfirmService } from '../confirm.service';\nimport { Chapter } from 'src/app/_models/chapter';\nimport { Volume } from 'src/app/_models/volume';\nimport { ToastrService } from 'ngx-toastr';\nimport { asyncScheduler, BehaviorSubject, Observable, tap, finalize, of, filter } from 'rxjs';\nimport { SAVER, Saver } from '../_providers/saver.provider';\nimport { download, Download } from '../_models/download';\nimport { PageBookmark } from 'src/app/_models/page-bookmark';\nimport { switchMap, takeWhile, throttleTime } from 'rxjs/operators';\nimport { AccountService } from 'src/app/_services/account.service';\n\nexport const DEBOUNCE_TIME = 100;\n\nexport interface DownloadEvent {\n /**\n * Type of entity being downloaded\n */\n entityType: DownloadEntityType;\n /**\n * What to show user. For example, for Series, we might show series name.\n */\n subTitle: string;\n /**\n * Progress of the download itself\n */\n progress: number; \n}\n\n/**\n * Valid entity types for downloading\n */\nexport type DownloadEntityType = 'volume' | 'chapter' | 'series' | 'bookmark' | 'logs';\n/**\n * Valid entities for downloading. Undefined exclusively for logs. \n */\nexport type DownloadEntity = Series | Volume | Chapter | PageBookmark[] | undefined;\n\n@Injectable({\n providedIn: 'root'\n})\nexport class DownloadService {\n\n private baseUrl = environment.apiUrl;\n /**\n * Size in bytes in which to inform the user for confirmation before download starts. Defaults to 100 MB.\n */\n public SIZE_WARNING = 104_857_600;\n\n private downloadsSource: BehaviorSubject = new BehaviorSubject([]);\n public activeDownloads$ = this.downloadsSource.asObservable();\n\n constructor(private httpClient: HttpClient, private confirmService: ConfirmService, \n private toastr: ToastrService, @Inject(SAVER) private save: Saver, \n private accountService: AccountService) { }\n\n /**\n * Returns the entity subtitle (for the event widget) for a given entity\n * @param downloadEntityType \n * @param downloadEntity \n * @returns \n */\n downloadSubtitle(downloadEntityType: DownloadEntityType, downloadEntity: DownloadEntity | undefined) {\n switch (downloadEntityType) {\n case 'series':\n return (downloadEntity as Series).name;\n case 'volume':\n return (downloadEntity as Volume).number + '';\n case 'chapter':\n return (downloadEntity as Chapter).number;\n case 'bookmark':\n return '';\n case 'logs':\n return '';\n }\n }\n\n /**\n * Downloads the entity to the user's system. This handles everything around downloads. This will prompt the user based on size checks and UserPreferences.PromptForDownload.\n * This will perform the download at a global level, if you need a handle to the download in question, use downloadService.activeDownloads$ and perform a filter on it. \n * @param entityType \n * @param entity \n * @param callback Optional callback. Returns the download or undefined (if the download is complete).\n */\n download(entityType: DownloadEntityType, entity: DownloadEntity, callback?: (d: Download | undefined) => void) {\n let sizeCheckCall: Observable; \n let downloadCall: Observable;\n switch (entityType) {\n case 'series':\n sizeCheckCall = this.downloadSeriesSize((entity as Series).id);\n downloadCall = this.downloadSeries(entity as Series);\n break;\n case 'volume':\n sizeCheckCall = this.downloadVolumeSize((entity as Volume).id);\n downloadCall = this.downloadVolume(entity as Volume);\n break;\n case 'chapter':\n sizeCheckCall = this.downloadChapterSize((entity as Chapter).id);\n downloadCall = this.downloadChapter(entity as Chapter);\n break;\n case 'bookmark':\n sizeCheckCall = of(0);\n downloadCall = this.downloadBookmarks(entity as PageBookmark[]);\n break;\n case 'logs':\n sizeCheckCall = of(0);\n downloadCall = this.downloadLogs();\n break;\n default:\n return;\n }\n\n\n this.accountService.currentUser$.pipe(switchMap(user => {\n if (user && user.preferences.promptForDownloadSize) {\n return sizeCheckCall;\n }\n return of(0);\n }), switchMap(async (size) => {\n return await this.confirmSize(size, entityType);\n })\n ).pipe(filter(wantsToDownload => {\n return wantsToDownload;\n }), switchMap(() => {\n return downloadCall.pipe(\n tap((d) => {\n if (callback) callback(d);\n }),\n takeWhile((val: Download) => {\n return val.state != 'DONE';\n }),\n finalize(() => {\n if (callback) callback(undefined);\n }))\n })).subscribe(() => {});\n }\n\n private downloadSeriesSize(seriesId: number) {\n return this.httpClient.get(this.baseUrl + 'download/series-size?seriesId=' + seriesId);\n }\n\n private downloadVolumeSize(volumeId: number) {\n return this.httpClient.get(this.baseUrl + 'download/volume-size?volumeId=' + volumeId);\n }\n\n private downloadChapterSize(chapterId: number) {\n return this.httpClient.get(this.baseUrl + 'download/chapter-size?chapterId=' + chapterId);\n }\n\n private downloadLogs() {\n const downloadType = 'logs';\n const subtitle = this.downloadSubtitle(downloadType, undefined);\n return this.httpClient.get(this.baseUrl + 'server/logs', \n {observe: 'events', responseType: 'blob', reportProgress: true}\n ).pipe(\n throttleTime(DEBOUNCE_TIME, asyncScheduler, { leading: true, trailing: true }), \n download((blob, filename) => {\n this.save(blob, filename);\n }),\n tap((d) => this.updateDownloadState(d, downloadType, subtitle)),\n finalize(() => this.finalizeDownloadState(downloadType, subtitle))\n );\n }\n\n private downloadSeries(series: Series) {\n const downloadType = 'series';\n const subtitle = this.downloadSubtitle(downloadType, series);\n return this.httpClient.get(this.baseUrl + 'download/series?seriesId=' + series.id, \n {observe: 'events', responseType: 'blob', reportProgress: true}\n ).pipe(\n throttleTime(DEBOUNCE_TIME, asyncScheduler, { leading: true, trailing: true }), \n download((blob, filename) => {\n this.save(blob, filename);\n }),\n tap((d) => this.updateDownloadState(d, downloadType, subtitle)),\n finalize(() => this.finalizeDownloadState(downloadType, subtitle))\n );\n }\n\n private finalizeDownloadState(entityType: DownloadEntityType, entitySubtitle: string) {\n let values = this.downloadsSource.getValue();\n values = values.filter(v => !(v.entityType === entityType && v.subTitle === entitySubtitle));\n this.downloadsSource.next(values);\n }\n\n private updateDownloadState(d: Download, entityType: DownloadEntityType, entitySubtitle: string) {\n let values = this.downloadsSource.getValue();\n if (d.state === 'PENDING') {\n const index = values.findIndex(v => v.entityType === entityType && v.subTitle === entitySubtitle);\n if (index >= 0) return; // Don't let us duplicate add\n values.push({entityType: entityType, subTitle: entitySubtitle, progress: 0});\n } else if (d.state === 'IN_PROGRESS') {\n const index = values.findIndex(v => v.entityType === entityType && v.subTitle === entitySubtitle);\n if (index >= 0) {\n values[index].progress = d.progress;\n }\n } else if (d.state === 'DONE') {\n values = values.filter(v => !(v.entityType === entityType && v.subTitle === entitySubtitle));\n }\n this.downloadsSource.next(values);\n\n }\n\n private downloadChapter(chapter: Chapter) {\n const downloadType = 'chapter';\n const subtitle = this.downloadSubtitle(downloadType, chapter);\n return this.httpClient.get(this.baseUrl + 'download/chapter?chapterId=' + chapter.id, \n {observe: 'events', responseType: 'blob', reportProgress: true}\n ).pipe(\n throttleTime(DEBOUNCE_TIME, asyncScheduler, { leading: true, trailing: true }), \n download((blob, filename) => {\n this.save(blob, filename);\n }),\n tap((d) => this.updateDownloadState(d, downloadType, subtitle)),\n finalize(() => this.finalizeDownloadState(downloadType, subtitle))\n );\n }\n\n private downloadVolume(volume: Volume): Observable {\n const downloadType = 'volume';\n const subtitle = this.downloadSubtitle(downloadType, volume);\n return this.httpClient.get(this.baseUrl + 'download/volume?volumeId=' + volume.id, \n {observe: 'events', responseType: 'blob', reportProgress: true}\n ).pipe(\n throttleTime(DEBOUNCE_TIME, asyncScheduler, { leading: true, trailing: true }), \n download((blob, filename) => {\n this.save(blob, filename);\n }),\n tap((d) => this.updateDownloadState(d, downloadType, subtitle)),\n finalize(() => this.finalizeDownloadState(downloadType, subtitle))\n );\n }\n\n private async confirmSize(size: number, entityType: DownloadEntityType) {\n return (size < this.SIZE_WARNING || await this.confirmService.confirm('The ' + entityType + ' is ' + this.humanFileSize(size) + '. Are you sure you want to continue?'));\n }\n\n private downloadBookmarks(bookmarks: PageBookmark[]) {\n const downloadType = 'bookmark';\n const subtitle = this.downloadSubtitle(downloadType, bookmarks);\n\n return this.httpClient.post(this.baseUrl + 'download/bookmarks', {bookmarks}, \n {observe: 'events', responseType: 'blob', reportProgress: true}\n ).pipe(\n throttleTime(DEBOUNCE_TIME, asyncScheduler, { leading: true, trailing: true }), \n download((blob, filename) => {\n this.save(blob, filename);\n }),\n tap((d) => this.updateDownloadState(d, downloadType, subtitle)),\n finalize(() => this.finalizeDownloadState(downloadType, subtitle))\n );\n }\n\n /**\n * Format bytes as human-readable text.\n * \n * @param bytes Number of bytes.\n * @param si True to use metric (SI) units, aka powers of 1000. False to use \n * binary (IEC), aka powers of 1024.\n * @param dp Number of decimal places to display.\n * \n * @return Formatted string.\n * \n * Credit: https://stackoverflow.com/questions/10420352/converting-file-size-in-bytes-to-human-readable-string\n */\n private humanFileSize(bytes: number, si=true, dp=0) {\n const thresh = si ? 1000 : 1024;\n\n if (Math.abs(bytes) < thresh) {\n return bytes + ' B';\n }\n\n const units = si \n ? ['kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'] \n : ['KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB'];\n let u = -1;\n const r = 10**dp;\n\n do {\n bytes /= thresh;\n ++u;\n } while (Math.round(Math.abs(bytes) * r) / r >= thresh && u < units.length - 1);\n\n\n return bytes.toFixed(dp) + ' ' + units[u];\n }\n}\n","import { Injectable } from '@angular/core';\nimport { ActivatedRoute, ActivatedRouteSnapshot } from '@angular/router';\nimport { Pagination } from 'src/app/_models/pagination';\nimport { SeriesFilter, SortField } from 'src/app/_models/series-filter';\nimport { SeriesService } from 'src/app/_services/series.service';\n\n/**\n * Used to pass state between the filter and the url\n */\nexport enum FilterQueryParam {\n Format = 'format',\n Genres = 'genres',\n AgeRating = 'ageRating',\n PublicationStatus = 'publicationStatus',\n Tags = 'tags',\n Languages = 'languages',\n CollectionTags = 'collectionTags',\n Libraries = 'libraries',\n Writers = 'writers',\n Artists = 'artists',\n Character = 'character',\n Colorist = 'colorist',\n CoverArtists = 'coverArtists',\n Editor = 'editor',\n Inker = 'inker',\n Letterer = 'letterer',\n Penciller = 'penciller',\n Publisher = 'publisher',\n Translator = 'translators',\n ReadStatus = 'readStatus',\n SortBy = 'sortBy',\n Rating = 'rating',\n Name = 'name',\n /**\n * This is a pagination control\n */\n Page = 'page'\n}\n\n@Injectable({\n providedIn: 'root'\n})\nexport class FilterUtilitiesService {\n\n constructor(private route: ActivatedRoute, private seriesService: SeriesService) { }\n\n /**\n * Updates the window location with a custom url based on filter and pagination objects\n * @param pagination \n * @param filter \n */\n updateUrlFromFilter(pagination: Pagination, filter: SeriesFilter | undefined) {\n const params = '?page=' + pagination.currentPage;\n \n const url = this.urlFromFilter(window.location.href.split('?')[0] + params, filter);\n window.history.replaceState(window.location.href, '', this.replacePaginationOnUrl(url, pagination));\n }\n\n /**\n * Patches the page query param in the window location. \n * @param pagination \n */\n updateUrlFromPagination(pagination: Pagination) {\n window.history.replaceState(window.location.href, '', this.replacePaginationOnUrl(window.location.href, pagination));\n }\n\n private replacePaginationOnUrl(url: string, pagination: Pagination) {\n return url.replace(/page=\\d+/i, 'page=' + pagination.currentPage);\n }\n\n /**\n * Will fetch current page from route if present\n * @param ActivatedRouteSnapshot to fetch page from. Must be from component else may get stale data\n * @param itemsPerPage If you want pagination, pass non-zero number\n * @returns A default pagination object\n */\n pagination(snapshot: ActivatedRouteSnapshot, itemsPerPage: number = 0): Pagination {\n return {currentPage: parseInt(snapshot.queryParamMap.get('page') || '1', 10), itemsPerPage, totalItems: 0, totalPages: 1};\n }\n\n\n /**\n * Returns the current url with query params for the filter\n * @param currentUrl Full url, with ?page=1 as a minimum\n * @param filter Filter to build url off\n * @returns current url with query params added\n */\n urlFromFilter(currentUrl: string, filter: SeriesFilter | undefined) {\n if (filter === undefined) return currentUrl;\n let params = '';\n\n params += this.joinFilter(filter.formats, FilterQueryParam.Format);\n params += this.joinFilter(filter.genres, FilterQueryParam.Genres);\n params += this.joinFilter(filter.ageRating, FilterQueryParam.AgeRating);\n params += this.joinFilter(filter.publicationStatus, FilterQueryParam.PublicationStatus);\n params += this.joinFilter(filter.tags, FilterQueryParam.Tags);\n params += this.joinFilter(filter.languages, FilterQueryParam.Languages);\n params += this.joinFilter(filter.collectionTags, FilterQueryParam.CollectionTags);\n params += this.joinFilter(filter.libraries, FilterQueryParam.Libraries);\n\n params += this.joinFilter(filter.writers, FilterQueryParam.Writers);\n params += this.joinFilter(filter.artists, FilterQueryParam.Artists);\n params += this.joinFilter(filter.character, FilterQueryParam.Character);\n params += this.joinFilter(filter.colorist, FilterQueryParam.Colorist);\n params += this.joinFilter(filter.coverArtist, FilterQueryParam.CoverArtists);\n params += this.joinFilter(filter.editor, FilterQueryParam.Editor);\n params += this.joinFilter(filter.inker, FilterQueryParam.Inker);\n params += this.joinFilter(filter.letterer, FilterQueryParam.Letterer);\n params += this.joinFilter(filter.penciller, FilterQueryParam.Penciller);\n params += this.joinFilter(filter.publisher, FilterQueryParam.Publisher);\n params += this.joinFilter(filter.translators, FilterQueryParam.Translator);\n\n // readStatus (we need to do an additonal check as there is a default case)\n if (filter.readStatus && filter.readStatus.inProgress !== true && filter.readStatus.notRead !== true && filter.readStatus.read !== true) {\n params += `&${FilterQueryParam.ReadStatus}=${filter.readStatus.inProgress},${filter.readStatus.notRead},${filter.readStatus.read}`;\n }\n\n // sortBy (additional check to not save to url if default case)\n if (filter.sortOptions && !(filter.sortOptions.sortField === SortField.SortName && filter.sortOptions.isAscending === true)) {\n params += `&${FilterQueryParam.SortBy}=${filter.sortOptions.sortField},${filter.sortOptions.isAscending}`;\n }\n\n if (filter.rating > 0) {\n params += `&${FilterQueryParam.Rating}=${filter.rating}`;\n }\n\n if (filter.seriesNameQuery !== '') {\n params += `&${FilterQueryParam.Name}=${encodeURIComponent(filter.seriesNameQuery)}`;\n }\n \n return currentUrl + params;\n }\n\n private joinFilter(filterProp: Array, key: string) {\n let params = '';\n if (filterProp.length > 0) {\n params += `&${key}=${filterProp.join(',')}`;\n }\n return params;\n }\n\n /**\n * Returns a new instance of a filterSettings that is populated with filter presets from URL\n * @param ActivatedRouteSnapshot to fetch page from. Must be from component else may get stale data\n * @returns The Preset filter and if something was set within\n */\n filterPresetsFromUrl(snapshot: ActivatedRouteSnapshot): [SeriesFilter, boolean] {\n const filter = this.seriesService.createSeriesFilter();\n let anyChanged = false;\n\n const format = snapshot.queryParamMap.get(FilterQueryParam.Format);\n if (format !== undefined && format !== null) {\n filter.formats = [...filter.formats, ...format.split(',').map(item => parseInt(item, 10))];\n anyChanged = true;\n }\n\n const genres = snapshot.queryParamMap.get(FilterQueryParam.Genres);\n if (genres !== undefined && genres !== null) {\n filter.genres = [...filter.genres, ...genres.split(',').map(item => parseInt(item, 10))];\n anyChanged = true;\n }\n\n const ageRating = snapshot.queryParamMap.get(FilterQueryParam.AgeRating);\n if (ageRating !== undefined && ageRating !== null) {\n filter.ageRating = [...filter.ageRating, ...ageRating.split(',').map(item => parseInt(item, 10))];\n anyChanged = true;\n }\n\n const publicationStatus = snapshot.queryParamMap.get(FilterQueryParam.PublicationStatus);\n if (publicationStatus !== undefined && publicationStatus !== null) {\n filter.publicationStatus = [...filter.publicationStatus, ...publicationStatus.split(',').map(item => parseInt(item, 10))];\n anyChanged = true;\n }\n\n const tags = snapshot.queryParamMap.get(FilterQueryParam.Tags);\n if (tags !== undefined && tags !== null) {\n filter.tags = [...filter.tags, ...tags.split(',').map(item => parseInt(item, 10))];\n anyChanged = true;\n }\n\n const languages = snapshot.queryParamMap.get(FilterQueryParam.Languages);\n if (languages !== undefined && languages !== null) {\n filter.languages = [...filter.languages, ...languages.split(',')];\n anyChanged = true;\n }\n\n const writers = snapshot.queryParamMap.get(FilterQueryParam.Writers);\n if (writers !== undefined && writers !== null) {\n filter.writers = [...filter.writers, ...writers.split(',').map(item => parseInt(item, 10))];\n anyChanged = true;\n }\n\n const artists = snapshot.queryParamMap.get(FilterQueryParam.Artists);\n if (artists !== undefined && artists !== null) {\n filter.artists = [...filter.artists, ...artists.split(',').map(item => parseInt(item, 10))];\n anyChanged = true;\n }\n\n const character = snapshot.queryParamMap.get(FilterQueryParam.Character);\n if (character !== undefined && character !== null) {\n filter.character = [...filter.character, ...character.split(',').map(item => parseInt(item, 10))];\n anyChanged = true;\n }\n\n const colorist = snapshot.queryParamMap.get(FilterQueryParam.Colorist);\n if (colorist !== undefined && colorist !== null) {\n filter.colorist = [...filter.colorist, ...colorist.split(',').map(item => parseInt(item, 10))];\n anyChanged = true;\n }\n\n const coverArtists = snapshot.queryParamMap.get(FilterQueryParam.CoverArtists);\n if (coverArtists !== undefined && coverArtists !== null) {\n filter.coverArtist = [...filter.coverArtist, ...coverArtists.split(',').map(item => parseInt(item, 10))];\n anyChanged = true;\n }\n\n const editor = snapshot.queryParamMap.get(FilterQueryParam.Editor);\n if (editor !== undefined && editor !== null) {\n filter.editor = [...filter.editor, ...editor.split(',').map(item => parseInt(item, 10))];\n anyChanged = true;\n }\n\n const inker = snapshot.queryParamMap.get(FilterQueryParam.Inker);\n if (inker !== undefined && inker !== null) {\n filter.inker = [...filter.inker, ...inker.split(',').map(item => parseInt(item, 10))];\n anyChanged = true;\n }\n\n const letterer = snapshot.queryParamMap.get(FilterQueryParam.Letterer);\n if (letterer !== undefined && letterer !== null) {\n filter.letterer = [...filter.letterer, ...letterer.split(',').map(item => parseInt(item, 10))];\n anyChanged = true;\n }\n\n const penciller = snapshot.queryParamMap.get(FilterQueryParam.Penciller);\n if (penciller !== undefined && penciller !== null) {\n filter.penciller = [...filter.penciller, ...penciller.split(',').map(item => parseInt(item, 10))];\n anyChanged = true;\n }\n\n const publisher = snapshot.queryParamMap.get(FilterQueryParam.Publisher);\n if (publisher !== undefined && publisher !== null) {\n filter.publisher = [...filter.publisher, ...publisher.split(',').map(item => parseInt(item, 10))];\n anyChanged = true;\n }\n\n const translators = snapshot.queryParamMap.get(FilterQueryParam.Translator);\n if (translators !== undefined && translators !== null) {\n filter.translators = [...filter.translators, ...translators.split(',').map(item => parseInt(item, 10))];\n anyChanged = true;\n }\n\n const libraries = snapshot.queryParamMap.get(FilterQueryParam.Libraries);\n if (libraries !== undefined && libraries !== null) {\n filter.libraries = [...filter.libraries, ...libraries.split(',').map(item => parseInt(item, 10))];\n anyChanged = true;\n }\n\n const collectionTags = snapshot.queryParamMap.get(FilterQueryParam.CollectionTags);\n if (collectionTags !== undefined && collectionTags !== null) {\n filter.collectionTags = [...filter.collectionTags, ...collectionTags.split(',').map(item => parseInt(item, 10))];\n anyChanged = true;\n }\n\n // Rating, seriesName, \n const rating = snapshot.queryParamMap.get(FilterQueryParam.Rating);\n if (rating !== undefined && rating !== null && parseInt(rating, 10) > 0) {\n filter.rating = parseInt(rating, 10);\n anyChanged = true;\n }\n\n /// Read status is encoded as true,true,true\n const readStatus = snapshot.queryParamMap.get(FilterQueryParam.ReadStatus);\n if (readStatus !== undefined && readStatus !== null) {\n const values = readStatus.split(',').map(i => i === 'true');\n if (values.length === 3) {\n filter.readStatus.inProgress = values[0];\n filter.readStatus.notRead = values[1];\n filter.readStatus.read = values[2];\n anyChanged = true;\n }\n }\n\n const sortBy = snapshot.queryParamMap.get(FilterQueryParam.SortBy);\n if (sortBy !== undefined && sortBy !== null) {\n const values = sortBy.split(',');\n if (values.length === 1) {\n values.push('true');\n }\n if (values.length === 2) {\n filter.sortOptions = {\n isAscending: values[1] === 'true',\n sortField: Number(values[0])\n }\n anyChanged = true;\n }\n }\n\n const searchNameQuery = snapshot.queryParamMap.get(FilterQueryParam.Name);\n if (searchNameQuery !== undefined && searchNameQuery !== null && searchNameQuery !== '') {\n filter.seriesNameQuery = decodeURIComponent(searchNameQuery);\n anyChanged = true;\n }\n \n\n return [filter, false]; // anyChanged. Testing out if having a filter active but keep drawer closed by default works better\n }\n}\n","import { HttpParams } from '@angular/common/http';\nimport { Injectable } from '@angular/core';\nimport { Chapter } from 'src/app/_models/chapter';\nimport { LibraryType } from 'src/app/_models/library';\nimport { MangaFormat } from 'src/app/_models/manga-format';\nimport { PaginatedResult } from 'src/app/_models/pagination';\nimport { Series } from 'src/app/_models/series';\nimport { Volume } from 'src/app/_models/volume';\n\nexport enum KEY_CODES {\n RIGHT_ARROW = 'ArrowRight',\n LEFT_ARROW = 'ArrowLeft',\n DOWN_ARROW = 'ArrowDown',\n UP_ARROW = 'ArrowUp',\n ESC_KEY = 'Escape',\n SPACE = ' ',\n ENTER = 'Enter',\n G = 'g',\n B = 'b',\n F = 'f',\n H = 'h',\n BACKSPACE = 'Backspace',\n DELETE = 'Delete',\n SHIFT = 'Shift'\n}\n\nexport enum Breakpoint {\n Mobile = 768,\n Tablet = 1280,\n Desktop = 1440\n}\n\n\n@Injectable({\n providedIn: 'root'\n})\nexport class UtilityService {\n\n mangaFormatKeys: string[] = [];\n\n constructor() { }\n\n sortVolumes = (a: Volume, b: Volume) => {\n if (a === b) { return 0; }\n else if (a.number === 0) { return 1; }\n else if (b.number === 0) { return -1; }\n else {\n return a.number < b.number ? -1 : 1;\n }\n }\n\n sortChapters = (a: Chapter, b: Chapter) => {\n return parseFloat(a.number) - parseFloat(b.number);\n }\n\n mangaFormatToText(format: MangaFormat): string {\n if (this.mangaFormatKeys === undefined || this.mangaFormatKeys.length === 0) {\n this.mangaFormatKeys = Object.keys(MangaFormat);\n }\n\n return this.mangaFormatKeys.filter(item => MangaFormat[format] === item)[0];\n }\n\n /**\n * Formats a Chapter name based on the library it's in\n * @param libraryType \n * @param includeHash For comics only, includes a # which is used for numbering on cards\n * @param includeSpace Add a space at the end of the string. if includeHash and includeSpace are true, only hash will be at the end.\n * @returns \n */\n formatChapterName(libraryType: LibraryType, includeHash: boolean = false, includeSpace: boolean = false) {\n switch(libraryType) {\n case LibraryType.Book:\n return 'Book' + (includeSpace ? ' ' : '');\n case LibraryType.Comic:\n if (includeHash) {\n return 'Issue #';\n }\n return 'Issue' + (includeSpace ? ' ' : '');\n case LibraryType.Manga:\n return 'Chapter' + (includeSpace ? ' ' : '');\n }\n }\n\n cleanSpecialTitle(title: string) {\n let cleaned = title.replace(/_/g, ' ').replace(/SP\\d+/g, '').trim();\n cleaned = cleaned.substring(0, cleaned.lastIndexOf('.'));\n if (cleaned.trim() === '') {\n return title;\n }\n return cleaned;\n }\n\n filter(input: string, filter: string): boolean {\n if (input === null || filter === null) return false;\n const reg = /[_\\.\\-]/gi;\n return input.toUpperCase().replace(reg, '').includes(filter.toUpperCase().replace(reg, ''));\n }\n\n isVolume(d: any) {\n return d != null && d.hasOwnProperty('chapters');\n }\n\n isChapter(d: any) {\n return d != null && d.hasOwnProperty('volumeId');\n }\n\n isSeries(d: any) {\n return d != null && d.hasOwnProperty('originalName');\n }\n\n asVolume(d: any) {\n return d;\n }\n\n asChapter(d: any) {\n return d;\n }\n\n asSeries(d: any) {\n return d;\n }\n\n getActiveBreakpoint(): Breakpoint {\n if (window.innerWidth <= Breakpoint.Mobile) return Breakpoint.Mobile;\n else if (window.innerWidth > Breakpoint.Mobile && window.innerWidth <= Breakpoint.Tablet) return Breakpoint.Tablet;\n else if (window.innerWidth > Breakpoint.Tablet) return Breakpoint.Desktop\n \n return Breakpoint.Desktop;\n }\n\n isInViewport(element: Element, additionalTopOffset: number = 0) {\n const rect = element.getBoundingClientRect();\n return (\n rect.top >= additionalTopOffset &&\n rect.left >= 0 &&\n rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) &&\n rect.right <= (window.innerWidth || document.documentElement.clientWidth)\n );\n }\n\n deepEqual(object1: any, object2: any) {\n if ((object1 === null || object1 === undefined) && (object2 !== null || object2 !== undefined)) return false;\n if ((object2 === null || object2 === undefined) && (object1 !== null || object1 !== undefined)) return false;\n if (object1 === null && object2 === null) return true;\n if (object1 === undefined && object2 === undefined) return true;\n \n\n const keys1 = Object.keys(object1);\n const keys2 = Object.keys(object2);\n if (keys1.length !== keys2.length) {\n return false;\n }\n for (const key of keys1) {\n const val1 = object1[key];\n const val2 = object2[key];\n const areObjects = this.isObject(val1) && this.isObject(val2);\n if (\n areObjects && !this.deepEqual(val1, val2) ||\n !areObjects && val1 !== val2\n ) {\n return false;\n }\n }\n return true;\n }\n private isObject(object: any) {\n return object != null && typeof object === 'object';\n }\n\n addPaginationIfExists(params: HttpParams, pageNum?: number, itemsPerPage?: number) {\n if (pageNum !== null && pageNum !== undefined && itemsPerPage !== null && itemsPerPage !== undefined) {\n params = params.append('pageNumber', pageNum + '');\n params = params.append('pageSize', itemsPerPage + '');\n }\n return params;\n }\n\n createPaginatedResult(response: any, paginatedVariable: PaginatedResult | undefined = undefined) {\n if (paginatedVariable === undefined) {\n paginatedVariable = new PaginatedResult();\n }\n if (response.body === null) {\n paginatedVariable.result = [];\n } else {\n paginatedVariable.result = response.body;\n }\n\n const pageHeader = response.headers?.get('Pagination');\n if (pageHeader !== null) {\n paginatedVariable.pagination = JSON.parse(pageHeader);\n }\n\n return paginatedVariable;\n }\n\n getWindowDimensions() {\n const windowWidth = window.innerWidth\n || document.documentElement.clientWidth\n || document.body.clientWidth;\n const windowHeight = window.innerHeight\n || document.documentElement.clientHeight\n || document.body.clientHeight;\n return [windowWidth, windowHeight];\n }\n\n /**\n * \n * @param data An array of objects\n * @param keySelector A method to fetch a string from the object, which is used to classify the JumpKey\n * @returns \n */\n getJumpKeys(data :Array, keySelector: (data: any) => string) {\n const keys: {[key: string]: number} = {};\n data.forEach(obj => {\n let ch = keySelector(obj).charAt(0);\n if (/\\d|\\#|!|%|@|\\(|\\)|\\^|\\.|_|\\*/g.test(ch)) {\n ch = '#';\n }\n if (!keys.hasOwnProperty(ch)) {\n keys[ch] = 0;\n }\n keys[ch] += 1;\n });\n return Object.keys(keys).map(k => {\n return {\n key: k,\n size: keys[k],\n title: k.toUpperCase()\n }\n }).sort((a, b) => {\n if (a.key < b.key) return -1;\n if (a.key > b.key) return 1;\n return 0;\n });\n }\n\n}\n"," 0\">\n
\n \n
\n
\n \n
\n
\n","import { ChangeDetectionStrategy, Component, Input } from '@angular/core';\n\n@Component({\n selector: 'app-circular-loader',\n templateUrl: './circular-loader.component.html',\n styleUrls: ['./circular-loader.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class CircularLoaderComponent {\n\n @Input() currentValue: number = 0;\n @Input() maxValue: number = 0;\n @Input() animation: boolean = true;\n @Input() innerStrokeColor: string = 'transparent';\n @Input() fontSize: string = '36px';\n @Input() showIcon: boolean = true;\n /**\n * The width in pixels of the loader\n */\n @Input() width: string = '100px';\n /**\n * The height in pixels of the loader\n */\n @Input() height: string = '100px';\n /**\n * Centers the icon in the middle of the loader. Best for card use. \n */\n @Input() center: boolean = true;\n}\n","import { ConfirmButton } from './confirm-button';\n\nexport class ConfirmConfig {\n _type: string = 'confirm'; // internal only: confirm or alert (todo: use enum)\n header: string = 'Confirm';\n content: string = '';\n buttons: Array = [];\n /**\n * If the close button shouldn't be rendered\n */\n disableEscape: boolean = false;\n}\n","\n\n
\n

{{config.header}}

\n \n
\n
\n
\n
\n
\n \n
\n
\n","import { Component, OnInit } from '@angular/core';\nimport { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';\nimport { ConfirmButton } from './_models/confirm-button';\nimport { ConfirmConfig } from './_models/confirm-config';\n\n@Component({\n selector: 'app-confirm-dialog',\n templateUrl: './confirm-dialog.component.html',\n styleUrls: ['./confirm-dialog.component.scss']\n})\nexport class ConfirmDialogComponent implements OnInit {\n\n config!: ConfirmConfig;\n\n constructor(public modal: NgbActiveModal) {}\n\n ngOnInit(): void {\n if (this.config) {\n this.config.buttons.sort(this._button_sort);\n }\n }\n\n private _button_sort(x: ConfirmButton, y: ConfirmButton) {\n const xIsSecondary = x.type === 'secondary';\n const yIsSecondary = y.type === 'secondary';\n if (xIsSecondary && !yIsSecondary) {\n return -1;\n } else if (!xIsSecondary && yIsSecondary) {\n return 1;\n }\n return 0;\n }\n\n clickButton(button: ConfirmButton) {\n this.modal.close(button.type === 'primary');\n }\n\n close() {\n this.modal.close(false);\n }\n\n}\n","import { Injectable } from '@angular/core';\nimport { NgbModal } from '@ng-bootstrap/ng-bootstrap';\nimport { take } from 'rxjs/operators';\nimport { ConfirmDialogComponent } from './confirm-dialog/confirm-dialog.component';\nimport { ConfirmConfig } from './confirm-dialog/_models/confirm-config';\n\n@Injectable({\n providedIn: 'root'\n})\nexport class ConfirmService {\n\n defaultConfirm = new ConfirmConfig();\n defaultAlert = new ConfirmConfig();\n\n constructor(private modalService: NgbModal) {\n this.defaultConfirm.buttons.push({text: 'Cancel', type: 'secondary'});\n this.defaultConfirm.buttons.push({text: 'Confirm', type: 'primary'});\n\n this.defaultAlert._type = 'alert';\n this.defaultAlert.header = 'Alert';\n this.defaultAlert.buttons.push({text: 'Ok', type: 'primary'});\n\n }\n\n public async confirm(content?: string, config?: ConfirmConfig): Promise {\n\n return new Promise((resolve, reject) => {\n if (content === undefined && config === undefined) {\n console.error('Confirm must have either text or a config object passed');\n return reject(false);\n }\n\n if (content !== undefined && config === undefined) {\n config = this.defaultConfirm;\n config.content = content;\n }\n if (content !== undefined && content !== '' && config!.content === '') {\n config!.content = content;\n }\n\n const modalRef = this.modalService.open(ConfirmDialogComponent);\n modalRef.componentInstance.config = config;\n modalRef.closed.pipe(take(1)).subscribe(result => {\n return resolve(result);\n });\n modalRef.dismissed.pipe(take(1)).subscribe(() => {\n return resolve(false);\n });\n });\n\n }\n\n public async alert(content?: string, config?: ConfirmConfig): Promise {\n return new Promise((resolve, reject) => {\n if (content === undefined && config === undefined) {\n console.error('Alert must have either text or a config object passed');\n return reject(false);\n }\n\n if (content !== undefined && config === undefined) {\n config = this.defaultConfirm;\n config.content = content;\n }\n\n const modalRef = this.modalService.open(ConfirmDialogComponent);\n modalRef.componentInstance.config = config;\n modalRef.closed.pipe(take(1)).subscribe(result => {\n return resolve(result);\n });\n modalRef.dismissed.pipe(take(1)).subscribe(() => {\n return resolve(false);\n });\n })\n }\n}\n","import { ChangeDetectionStrategy, ChangeDetectorRef, Component, ElementRef, Input, OnChanges, OnDestroy, Renderer2, ViewChild } from '@angular/core';\nimport { Subject } from 'rxjs';\nimport { takeUntil } from 'rxjs/operators';\nimport { CoverUpdateEvent } from 'src/app/_models/events/cover-update-event';\nimport { ImageService } from 'src/app/_services/image.service';\nimport { EVENTS, MessageHubService } from 'src/app/_services/message-hub.service';\n\n/**\n * This is used for images with placeholder fallback.\n */\n@Component({\n selector: 'app-image',\n templateUrl: './image.component.html',\n styleUrls: ['./image.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class ImageComponent implements OnChanges, OnDestroy {\n\n /**\n * Source url to load image\n */\n @Input() imageUrl!: string;\n /**\n * Width of the image. If not defined, will not be applied\n */\n @Input() width: string = '';\n /**\n * Height of the image. If not defined, will not be applied\n */\n @Input() height: string = '';\n /**\n * Max Width of the image. If not defined, will not be applied\n */\n @Input() maxWidth: string = '';\n /**\n * Max Height of the image. If not defined, will not be applied\n */\n @Input() maxHeight: string = '';\n /**\n * Border Radius of the image. If not defined, will not be applied\n */\n @Input() borderRadius: string = '';\n /**\n * Object fit of the image. If not defined, will not be applied\n */\n @Input() objectFit: string = '';\n /**\n * Background of the image. If not defined, will not be applied\n */\n @Input() background: string = '';\n /**\n * If the image component should respond to cover updates\n */\n @Input() processEvents: boolean = true;\n\n @ViewChild('img', {static: true}) imgElem!: ElementRef;\n\n private readonly onDestroy = new Subject();\n\n constructor(public imageService: ImageService, private renderer: Renderer2, private hubService: MessageHubService, private changeDetectionRef: ChangeDetectorRef) {\n this.hubService.messages$.pipe(takeUntil(this.onDestroy)).subscribe(res => {\n if (!this.processEvents) return;\n if (res.event === EVENTS.CoverUpdate) {\n const updateEvent = res.payload as CoverUpdateEvent;\n if (this.imageUrl === undefined || this.imageUrl === null || this.imageUrl === '') return;\n const enityType = this.imageService.getEntityTypeFromUrl(this.imageUrl);\n if (enityType === updateEvent.entityType) {\n const tokens = this.imageUrl.split('?')[1].split('&');\n\n //...seriesId=123&random=\n let id = tokens[0].replace(enityType + 'Id=', '');\n if (id.includes('&')) {\n id = id.split('&')[0];\n }\n if (id === (updateEvent.id + '')) {\n this.imageUrl = this.imageService.randomize(this.imageUrl);\n this.changeDetectionRef.markForCheck();\n }\n }\n }\n });\n }\n\n ngOnChanges(): void {\n if (this.width != '') {\n this.renderer.setStyle(this.imgElem.nativeElement, 'width', this.width);\n }\n\n if (this.height != '') {\n this.renderer.setStyle(this.imgElem.nativeElement, 'height', this.height);\n }\n\n if (this.maxWidth != '') {\n this.renderer.setStyle(this.imgElem.nativeElement, 'max-width', this.maxWidth);\n }\n\n if (this.maxHeight != '') {\n this.renderer.setStyle(this.imgElem.nativeElement, 'max-height', this.maxHeight);\n }\n\n if (this.borderRadius != '') {\n this.renderer.setStyle(this.imgElem.nativeElement, 'border-radius', this.borderRadius);\n }\n\n if (this.objectFit != '') {\n this.renderer.setStyle(this.imgElem.nativeElement, 'object-fit', this.objectFit);\n }\n\n if (this.background != '') {\n this.renderer.setStyle(this.imgElem.nativeElement, 'background', this.background);\n }\n }\n\n ngOnDestroy() {\n this.onDestroy.next();\n this.onDestroy.complete();\n }\n\n}\n","","import { NgModule } from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { ReactiveFormsModule } from '@angular/forms';\nimport { NgbCollapseModule, NgbTooltipModule } from '@ng-bootstrap/ng-bootstrap';\nimport { ConfirmDialogComponent } from './confirm-dialog/confirm-dialog.component';\nimport { ReadMoreComponent } from './read-more/read-more.component';\nimport { RouterModule } from '@angular/router';\nimport { DrawerComponent } from './drawer/drawer.component';\nimport { TagBadgeComponent } from './tag-badge/tag-badge.component';\nimport { ShowIfScrollbarDirective } from './show-if-scrollbar.directive';\nimport { A11yClickDirective } from './a11y-click.directive';\nimport { SeriesFormatComponent } from './series-format/series-format.component';\nimport { UpdateNotificationModalComponent } from './update-notification/update-notification-modal.component';\nimport { CircularLoaderComponent } from './circular-loader/circular-loader.component';\nimport { NgCircleProgressModule } from 'ng-circle-progress';\nimport { PersonBadgeComponent } from './person-badge/person-badge.component';\nimport { BadgeExpanderComponent } from './badge-expander/badge-expander.component';\nimport { ImageComponent } from './image/image.component';\nimport { PipeModule } from '../pipe/pipe.module';\nimport { IconAndTitleComponent } from './icon-and-title/icon-and-title.component';\n\n@NgModule({\n declarations: [\n ConfirmDialogComponent,\n ReadMoreComponent,\n DrawerComponent,\n TagBadgeComponent,\n ShowIfScrollbarDirective,\n A11yClickDirective,\n SeriesFormatComponent,\n UpdateNotificationModalComponent,\n CircularLoaderComponent,\n PersonBadgeComponent,\n BadgeExpanderComponent,\n ImageComponent,\n IconAndTitleComponent,\n ],\n imports: [\n CommonModule,\n RouterModule,\n ReactiveFormsModule,\n NgbCollapseModule,\n NgbTooltipModule, // TODO: Validate if we still need this\n PipeModule,\n NgCircleProgressModule.forRoot(),\n ],\n exports: [\n ReadMoreComponent, // Used globably\n DrawerComponent, // Can be replaced with boostrap offscreen canvas (v5) (also used in book reader and series metadata filter)\n A11yClickDirective, // Used globally\n SeriesFormatComponent, // Used globally\n TagBadgeComponent, // Used globally\n CircularLoaderComponent, // Used in Cards only\n ImageComponent, // Used globally\n\n ShowIfScrollbarDirective, // Used book reader only?\n\n PersonBadgeComponent, // Used Series Detail\n BadgeExpanderComponent, // Used Series Detail/Metadata\n\n IconAndTitleComponent // Used in Series Detail/Metadata\n \n ],\n})\nexport class SharedModule { }\n","
\n

New Update Available!

\n \n
\n
\n
{{updateData.updateTitle}}
\n
\n
\n\n
\n \n Download\n
","import { ChangeDetectionStrategy, Component, Input } from '@angular/core';\nimport { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';\nimport { UpdateVersionEvent } from 'src/app/_models/events/update-version-event';\n\n\n\n@Component({\n selector: 'app-update-notification-modal',\n templateUrl: './update-notification-modal.component.html',\n styleUrls: ['./update-notification-modal.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class UpdateNotificationModalComponent {\n\n @Input() updateData!: UpdateVersionEvent;\n\n constructor(public modal: NgbActiveModal) { }\n\n close() {\n this.modal.close({success: false, series: undefined});\n }\n}\n","import { NgModule } from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { SideNavCompanionBarComponent } from './side-nav-companion-bar/side-nav-companion-bar.component';\nimport { SideNavItemComponent } from './side-nav-item/side-nav-item.component';\nimport { SideNavComponent } from './side-nav/side-nav.component';\nimport { PipeModule } from '../pipe/pipe.module';\nimport { CardsModule } from '../cards/cards.module';\nimport { FormsModule } from '@angular/forms';\nimport { NgbTooltipModule } from '@ng-bootstrap/ng-bootstrap';\nimport { RouterModule } from '@angular/router';\n\n\n\n@NgModule({\n declarations: [\n SideNavCompanionBarComponent,\n SideNavItemComponent,\n SideNavComponent\n ],\n imports: [\n CommonModule,\n RouterModule,\n PipeModule,\n CardsModule,\n FormsModule,\n NgbTooltipModule,\n ],\n exports: [\n SideNavCompanionBarComponent,\n SideNavItemComponent,\n SideNavComponent\n ]\n})\nexport class SidenavModule { }\n","import { NgModule } from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { TypeaheadComponent } from './typeahead.component';\nimport { FormsModule, ReactiveFormsModule } from '@angular/forms';\nimport { SharedModule } from '../shared/shared.module';\nimport { PipeModule } from '../pipe/pipe.module';\n\n\n\n@NgModule({\n declarations: [\n TypeaheadComponent\n ],\n imports: [\n CommonModule,\n SharedModule,\n FormsModule,\n ReactiveFormsModule,\n PipeModule\n ],\n exports: [\n TypeaheadComponent\n ]\n})\nexport class TypeaheadModule { }\n","export const environment = {\n production: true,\n apiUrl: '/api/',\n hubUrl: '/hubs/'\n};\n","import { NgModule } from '@angular/core';\nimport { Routes, RouterModule, PreloadAllModules } from '@angular/router';\nimport { AuthGuard } from './_guards/auth.guard';\nimport { LibraryAccessGuard } from './_guards/library-access.guard';\nimport { AdminGuard } from './_guards/admin.guard';\n\nconst routes: Routes = [\n {\n path: 'admin',\n canActivate: [AdminGuard],\n loadChildren: () => import('./admin/admin.module').then(m => m.AdminModule)\n },\n {\n path: 'collections',\n canActivate: [AuthGuard],\n loadChildren: () => import('./collections/collections.module').then(m => m.CollectionsModule)\n },\n {\n path: 'preferences',\n canActivate: [AuthGuard],\n loadChildren: () => import('./user-settings/user-settings.module').then(m => m.UserSettingsModule)\n },\n {\n path: 'lists',\n canActivate: [AuthGuard],\n loadChildren: () => import('./reading-list/reading-list.module').then(m => m.ReadingListModule)\n },\n {\n path: 'registration',\n loadChildren: () => import('../app/registration/registration.module').then(m => m.RegistrationModule)\n },\n {\n path: 'announcements',\n loadChildren: () => import('../app/announcements/announcements.module').then(m => m.AnnouncementsModule)\n },\n {\n path: 'bookmarks',\n loadChildren: () => import('../app/bookmark/bookmark.module').then(m => m.BookmarkModule)\n },\n {\n path: 'all-series',\n loadChildren: () => import('../app/all-series/all-series.module').then(m => m.AllSeriesModule)\n },\n {\n path: 'libraries',\n loadChildren: () => import('../app/dashboard/dashboard.module').then(m => m.DashboardModule)\n },\n {\n path: 'want-to-read',\n loadChildren: () => import('../app/want-to-read/want-to-read.module').then(m => m.WantToReadModule)\n },\n {\n path: 'library',\n runGuardsAndResolvers: 'always',\n canActivate: [AuthGuard, LibraryAccessGuard],\n children: [\n {\n path: ':libraryId', \n pathMatch: 'full',\n loadChildren: () => import('../app/library-detail/library-detail.module').then(m => m.LibraryDetailModule)\n },\n {\n path: ':libraryId/series/:seriesId', \n pathMatch: 'full',\n loadChildren: () => import('../app/series-detail/series-detail.module').then(m => m.SeriesDetailModule)\n },\n {\n path: ':libraryId/series/:seriesId/manga',\n loadChildren: () => import('../app/manga-reader/manga-reader.module').then(m => m.MangaReaderModule)\n },\n {\n path: ':libraryId/series/:seriesId/book',\n loadChildren: () => import('../app/book-reader/book-reader.module').then(m => m.BookReaderModule)\n },\n {\n path: ':libraryId/series/:seriesId/pdf',\n loadChildren: () => import('../app/pdf-reader/pdf-reader.module').then(m => m.PdfReaderModule)\n },\n ]\n },\n {path: 'login', loadChildren: () => import('../app/registration/registration.module').then(m => m.RegistrationModule)},\n {path: '**', pathMatch: 'full', redirectTo: 'libraries'},\n {path: '**', pathMatch: 'prefix', redirectTo: 'libraries'},\n];\n\n@NgModule({\n imports: [RouterModule.forRoot(routes, {scrollPositionRestoration: 'enabled', preloadingStrategy: PreloadAllModules})],\n exports: [RouterModule]\n})\nexport class AppRoutingModule { }\n","\n
\n \n
\n
\n\n\n \n \n \n\n\n\n\n
\n \n
\n \n
\n
\n \n
\n {{title}}\n
\n
\n \n \n \n
","import { ChangeDetectionStrategy, ChangeDetectorRef, Component, Input, OnDestroy, OnInit } from '@angular/core';\nimport { NavigationEnd, Router } from '@angular/router';\nimport { filter, map, Subject, takeUntil } from 'rxjs';\nimport { NavService } from '../../_services/nav.service';\n\n@Component({\n selector: 'app-side-nav-item',\n templateUrl: './side-nav-item.component.html',\n styleUrls: ['./side-nav-item.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class SideNavItemComponent implements OnInit, OnDestroy {\n /**\n * Icon to display next to item. ie) 'fa-home'\n */\n @Input() icon: string = '';\n /**\n * Text for the item\n */\n @Input() title: string = '';\n\n /**\n * If a link should be generated when clicked. By default (undefined), no link will be generated\n */\n @Input() link: string | undefined;\n\n @Input() comparisonMethod: 'startsWith' | 'equals' = 'equals';\n\n\n highlighted = false;\n private onDestroy: Subject = new Subject();\n \n constructor(public navService: NavService, private router: Router, private readonly cdRef: ChangeDetectorRef) {\n router.events\n .pipe(filter(event => event instanceof NavigationEnd), \n takeUntil(this.onDestroy),\n map(evt => evt as NavigationEnd))\n .subscribe((evt: NavigationEnd) => {\n this.updateHightlight(evt.url.split('?')[0]);\n \n });\n }\n\n ngOnInit(): void {\n setTimeout(() => {\n this.updateHightlight(this.router.url.split('?')[0]);\n }, 100);\n \n }\n\n ngOnDestroy(): void {\n this.onDestroy.next();\n this.onDestroy.complete();\n }\n\n updateHightlight(page: string) {\n if (this.link === undefined) {\n this.highlighted = false;\n this.cdRef.markForCheck();\n return;\n }\n\n if (!page.endsWith('/')) {\n page = page + '/';\n }\n\n if (this.comparisonMethod === 'equals' && page === this.link) {\n this.highlighted = true;\n this.cdRef.markForCheck();\n return;\n }\n if (this.comparisonMethod === 'startsWith' && page.startsWith(this.link)) {\n this.highlighted = true;\n this.cdRef.markForCheck();\n return;\n }\n\n this.highlighted = false;\n this.cdRef.markForCheck();\n }\n\n}\n","\n
\n \n\n \n \n \n \n \n 0\">\n
10 && !(navService?.sideNavCollapsed$ | async)\">\n \n
\n \n \n
\n
\n \n \n \n \n \n
\n
\n
","import { ChangeDetectionStrategy, ChangeDetectorRef, Component, OnDestroy, OnInit } from '@angular/core';\nimport { NavigationEnd, Router } from '@angular/router';\nimport { Subject } from 'rxjs';\nimport { filter, map, shareReplay, take, takeUntil } from 'rxjs/operators';\nimport { EVENTS, MessageHubService } from 'src/app/_services/message-hub.service';\nimport { Breakpoint, UtilityService } from '../../shared/_services/utility.service';\nimport { Library, LibraryType } from '../../_models/library';\nimport { AccountService } from '../../_services/account.service';\nimport { Action, ActionFactoryService, ActionItem } from '../../_services/action-factory.service';\nimport { ActionService } from '../../_services/action.service';\nimport { LibraryService } from '../../_services/library.service';\nimport { NavService } from '../../_services/nav.service';\n\n@Component({\n selector: 'app-side-nav',\n templateUrl: './side-nav.component.html',\n styleUrls: ['./side-nav.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class SideNavComponent implements OnInit, OnDestroy {\n\n libraries: Library[] = [];\n actions: ActionItem[] = [];\n\n filterQuery: string = '';\n filterLibrary = (library: Library) => {\n return library.name.toLowerCase().indexOf((this.filterQuery || '').toLowerCase()) >= 0;\n }\n\n private onDestroy: Subject = new Subject();\n\n\n constructor(public accountService: AccountService, private libraryService: LibraryService,\n public utilityService: UtilityService, private messageHub: MessageHubService,\n private actionFactoryService: ActionFactoryService, private actionService: ActionService, \n public navService: NavService, private router: Router, private readonly cdRef: ChangeDetectorRef) {\n\n this.router.events.pipe(\n filter(event => event instanceof NavigationEnd), \n takeUntil(this.onDestroy),\n map(evt => evt as NavigationEnd),\n filter(() => this.utilityService.getActiveBreakpoint() < Breakpoint.Tablet))\n .subscribe((evt: NavigationEnd) => {\n // Collapse side nav on mobile\n this.navService.sideNavCollapsed$.pipe(take(1)).subscribe(collapsed => {\n if (!collapsed) {\n this.navService.toggleSideNav();\n this.cdRef.markForCheck();\n }\n });\n });\n }\n\n ngOnInit(): void {\n this.accountService.currentUser$.pipe(take(1)).subscribe(user => {\n if (user) {\n this.libraryService.getLibrariesForMember().pipe(take(1), shareReplay()).subscribe((libraries: Library[]) => {\n this.libraries = libraries;\n this.cdRef.markForCheck();\n });\n }\n this.actions = this.actionFactoryService.getLibraryActions(this.handleAction.bind(this));\n this.cdRef.markForCheck();\n });\n\n this.messageHub.messages$.pipe(takeUntil(this.onDestroy), filter(event => event.event === EVENTS.LibraryModified)).subscribe(event => {\n this.libraryService.getLibrariesForMember().pipe(take(1), shareReplay()).subscribe((libraries: Library[]) => {\n this.libraries = libraries;\n this.cdRef.markForCheck();\n });\n });\n }\n\n ngOnDestroy(): void {\n this.onDestroy.next();\n this.onDestroy.complete();\n }\n\n handleAction(action: Action, library: Library) {\n switch (action) {\n case(Action.Scan):\n this.actionService.scanLibrary(library);\n break;\n case(Action.RefreshMetadata):\n this.actionService.refreshMetadata(library);\n break;\n case (Action.AnalyzeFiles):\n this.actionService.analyzeFiles(library);\n break;\n default:\n break;\n }\n }\n\n\n performAction(action: ActionItem, library: Library) {\n if (typeof action.callback === 'function') {\n action.callback(action.action, library);\n }\n }\n\n getLibraryTypeIcon(format: LibraryType) {\n switch (format) {\n case LibraryType.Book:\n return 'fa-book';\n case LibraryType.Comic:\n case LibraryType.Manga:\n return 'fa-book-open';\n }\n }\n\n toggleNavBar() {\n this.navService.toggleSideNav();\n }\n\n}","\n  \n \n","import { ChangeDetectionStrategy, Component, Input } from '@angular/core';\nimport { MangaFormat } from 'src/app/_models/manga-format';\n\n@Component({\n selector: 'app-series-format',\n templateUrl: './series-format.component.html',\n styleUrls: ['./series-format.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class SeriesFormatComponent {\n\n @Input() format: MangaFormat = MangaFormat.UNKNOWN;\n\n get MangaFormat(): typeof MangaFormat {\n return MangaFormat;\n }\n}\n","\n \n \n \n \n \n \n \n \n\n \n\n
    \n \n \n
  • 0 || infos.length > 0\" (click)=\"clearAllErrorOrInfos()\">\n Dismiss All\n
  • \n
    \n
    \n \n
  • \n
    Title goes here
    \n
    Subtitle goes here
    \n
    \n
    \n
    \n
    \n
    \n
  • \n
  • \n
    Title goes here
    \n
    Subtitle goes here
    \n
  • \n
  • \n
    \n
    Scanning Books
    \n
    E:\\\\Books\\\\Demon King Daimaou\\\\Demon King Daimaou - Volume 11.epub
    \n
    \n
    {{prettyPrintProgress(0.1)}}%
    \n
    \n
    \n
    \n
    \n\n
    \n
  • \n
  • \n
    \n
    There was some library scan error
    \n
    Click for more information
    \n
    \n \n
  • \n
  • \n
    \n
    Scan didn't run becasuse nothing to do
    \n
    Click for more information
    \n
    \n \n
  • \n
  • \n
    \n \n \n \n 10% downloaded\n \n \n Downloading {{'series' | sentenceCase}}\n
    \n
    PDFs
    \n
  • \n
    \n\n \n \n \n
  • \n
    {{message.title}}
    \n
    {{message.subTitle}}
    \n
    \n
    \n
    \n
    \n
    \n
  • \n \n
  • \n
    {{message.title}}
    \n
    {{message.subTitle}}
    \n
    \n
    {{prettyPrintProgress(message.body.progress) + '%'}}
    \n
    \n
    \n
    \n
    \n
  • \n
    \n
    \n
    \n\n \n \n \n
  • \n  Update available\n
  • \n
  • \n
    {{singleUpdate.title}}
    \n
    {{singleUpdate.subTitle}}
    \n
  • \n
    \n
    \n\n \n \n \n
  • \n
    Downloading {{download.entityType | sentenceCase}}
    \n
    {{download.subTitle}}
    \n
    \n
    {{download.progress}}%
    \n
    \n
    \n
    \n
    \n
  • \n
    \n
    \n \n\n \n \n \n
  • \n
    \n
    {{error.title}}
    \n
    Click for more information
    \n
    \n \n
  • \n
    \n
    \n\n \n \n \n
  • \n
    \n
    {{info.title}}
    \n
    Click for more information
    \n
    \n \n
  • \n
    \n
    \n\n \n \n
  • 1\">\n
    {{onlineUsers.length}} Users online
    \n
  • \n
  • Not much going on here
  • \n
  • Active Events: {{activeEvents}}
  • \n
    \n
\n
\n
","import { ChangeDetectionStrategy, ChangeDetectorRef, Component, Input, OnDestroy, OnInit } from '@angular/core';\nimport { NgbModal, NgbModalRef } from '@ng-bootstrap/ng-bootstrap';\nimport { BehaviorSubject, Observable, of, Subject } from 'rxjs';\nimport { map, shareReplay, takeUntil } from 'rxjs/operators';\nimport { ConfirmConfig } from 'src/app/shared/confirm-dialog/_models/confirm-config';\nimport { ConfirmService } from 'src/app/shared/confirm.service';\nimport { UpdateNotificationModalComponent } from 'src/app/shared/update-notification/update-notification-modal.component';\nimport { DownloadService } from 'src/app/shared/_services/download.service';\nimport { ErrorEvent } from 'src/app/_models/events/error-event';\nimport { InfoEvent } from 'src/app/_models/events/info-event';\nimport { NotificationProgressEvent } from 'src/app/_models/events/notification-progress-event';\nimport { UpdateVersionEvent } from 'src/app/_models/events/update-version-event';\nimport { User } from 'src/app/_models/user';\nimport { AccountService } from 'src/app/_services/account.service';\nimport { EVENTS, Message, MessageHubService } from 'src/app/_services/message-hub.service';\n\n@Component({\n selector: 'app-nav-events-toggle',\n templateUrl: './events-widget.component.html',\n styleUrls: ['./events-widget.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class EventsWidgetComponent implements OnInit, OnDestroy {\n @Input() user!: User;\n\n isAdmin$: Observable = of(false);\n\n private readonly onDestroy = new Subject();\n\n /**\n * Progress events (Event Type: 'started', 'ended', 'updated' that have progress property)\n */\n progressEventsSource = new BehaviorSubject([]);\n progressEvents$ = this.progressEventsSource.asObservable();\n\n singleUpdateSource = new BehaviorSubject([]);\n singleUpdates$ = this.singleUpdateSource.asObservable();\n\n errorSource = new BehaviorSubject([]);\n errors$ = this.errorSource.asObservable();\n\n infoSource = new BehaviorSubject([]);\n infos$ = this.infoSource.asObservable();\n\n private updateNotificationModalRef: NgbModalRef | null = null;\n\n activeEvents: number = 0;\n\n debugMode: boolean = false;\n\n\n get EVENTS() {\n return EVENTS;\n }\n\n constructor(public messageHub: MessageHubService, private modalService: NgbModal, \n private accountService: AccountService, private confirmService: ConfirmService,\n private readonly cdRef: ChangeDetectorRef, public downloadService: DownloadService) { }\n\n ngOnDestroy(): void {\n this.onDestroy.next();\n this.onDestroy.complete();\n this.progressEventsSource.complete();\n this.singleUpdateSource.complete();\n this.errorSource.complete();\n }\n\n ngOnInit(): void {\n this.messageHub.messages$.pipe(takeUntil(this.onDestroy)).subscribe(event => {\n if (event.event === EVENTS.NotificationProgress) {\n this.processNotificationProgressEvent(event);\n } else if (event.event === EVENTS.Error) {\n const values = this.errorSource.getValue();\n values.push(event.payload as ErrorEvent);\n this.errorSource.next(values);\n this.activeEvents += 1;\n this.cdRef.markForCheck();\n } else if (event.event === EVENTS.Info) {\n const values = this.infoSource.getValue();\n values.push(event.payload as InfoEvent);\n this.infoSource.next(values);\n this.activeEvents += 1;\n this.cdRef.markForCheck();\n }\n });\n\n this.isAdmin$ = this.accountService.currentUser$.pipe(\n takeUntil(this.onDestroy), \n map(user => (user && this.accountService.hasAdminRole(user)) || false), \n shareReplay()\n );\n }\n\n processNotificationProgressEvent(event: Message) {\n const message = event.payload as NotificationProgressEvent;\n let data;\n switch (event.payload.eventType) {\n case 'single':\n const values = this.singleUpdateSource.getValue();\n values.push(message);\n this.singleUpdateSource.next(values);\n this.activeEvents += 1;\n this.cdRef.markForCheck();\n break;\n case 'started':\n // Sometimes we can receive 2 started on long running scans, so better to just treat as a merge then.\n data = this.mergeOrUpdate(this.progressEventsSource.getValue(), message);\n this.progressEventsSource.next(data);\n break;\n case 'updated':\n data = this.mergeOrUpdate(this.progressEventsSource.getValue(), message);\n this.progressEventsSource.next(data);\n break;\n case 'ended':\n data = this.progressEventsSource.getValue();\n data = data.filter(m => m.name !== message.name);\n this.progressEventsSource.next(data);\n this.activeEvents = Math.max(this.activeEvents - 1, 0);\n this.cdRef.markForCheck();\n break;\n default:\n break;\n }\n }\n\n private mergeOrUpdate(data: NotificationProgressEvent[], message: NotificationProgressEvent) {\n const index = data.findIndex(m => m.name === message.name);\n // Sometimes we can receive 2 started on long running scans, so better to just treat as a merge then.\n if (index < 0) {\n data.push(message);\n this.activeEvents += 1;\n this.cdRef.markForCheck();\n } else {\n data[index] = message;\n }\n return data;\n }\n\n\n handleUpdateAvailableClick(message: NotificationProgressEvent) {\n if (this.updateNotificationModalRef != null) { return; }\n this.updateNotificationModalRef = this.modalService.open(UpdateNotificationModalComponent, { scrollable: true, size: 'lg' });\n this.updateNotificationModalRef.componentInstance.updateData = message.body as UpdateVersionEvent;\n this.updateNotificationModalRef.closed.subscribe(() => {\n this.updateNotificationModalRef = null;\n });\n this.updateNotificationModalRef.dismissed.subscribe(() => {\n this.updateNotificationModalRef = null;\n });\n }\n\n async seeMore(event: ErrorEvent | InfoEvent) {\n const config = new ConfirmConfig();\n if (event.name === EVENTS.Error) {\n config.buttons = [\n {text: 'Ok', type: 'secondary'},\n {text: 'Dismiss', type: 'primary'}\n ];\n } else {\n config.buttons = [\n {text: 'Ok', type: 'primary'},\n ];\n }\n config.header = event.title;\n config.content = event.subTitle;\n var result = await this.confirmService.alert(event.subTitle || event.title, config);\n if (result) {\n this.removeErrorOrInfo(event);\n }\n }\n\n clearAllErrorOrInfos() {\n const infoCount = this.infoSource.getValue().length;\n const errorCount = this.errorSource.getValue().length;\n this.infoSource.next([]);\n this.errorSource.next([]);\n this.activeEvents -= Math.max(infoCount + errorCount, 0);\n this.cdRef.markForCheck();\n }\n\n removeErrorOrInfo(messageEvent: ErrorEvent | InfoEvent, event?: MouseEvent) {\n if (event) {\n event.stopPropagation();\n event.preventDefault();\n }\n let data = [];\n if (messageEvent.name === EVENTS.Info) {\n data = this.infoSource.getValue();\n data = data.filter(m => m !== messageEvent); \n this.infoSource.next(data);\n } else {\n data = this.errorSource.getValue();\n data = data.filter(m => m !== messageEvent); \n this.errorSource.next(data);\n }\n this.activeEvents = Math.max(this.activeEvents - 1, 0);\n this.cdRef.markForCheck();\n }\n\n prettyPrintProgress(progress: number) {\n return Math.trunc(progress * 100);\n }\n}\n","
\n
\n
\n \n
\n Loading...\n
\n \n
\n
\n
\n
    \n 0\">\n
  • Series
  • \n
      \n
    • \n \n
    • \n
    \n
    \n\n 0\">\n
  • Collections
  • \n
      \n
    • \n \n
    • \n
    \n
    \n\n 0\">\n
  • Reading Lists
  • \n
      \n
    • \n \n
    • \n
    \n
    \n\n 0\">\n
  • Libraries
  • \n
      \n
    • \n \n
    • \n
    \n
    \n\n 0\">\n
  • Genres
  • \n
      \n
    • \n \n
    • \n
    \n
    \n\n 0\">\n
  • Tags
  • \n
      \n
    • \n \n
    • \n
    \n
    \n\n 0\">\n
  • People
  • \n
      \n
    • \n \n
    • \n
    \n
    \n\n 0\">\n
  • Chapters
  • \n
      \n
    • \n \n
    • \n
    \n
    \n\n 0\">\n
  • Files
  • \n
      \n
    • \n \n
    • \n
    \n
    \n\n 0\">\n
      \n
    • \n \n
    • \n
    \n\n
    \n
\n
\n\n
\n","import { ChangeDetectionStrategy, ChangeDetectorRef, Component, ContentChild, ElementRef, EventEmitter, HostListener, Input, OnDestroy, OnInit, Output, TemplateRef, ViewChild } from '@angular/core';\nimport { FormControl, FormGroup } from '@angular/forms';\nimport { Subject } from 'rxjs';\nimport { debounceTime, takeUntil } from 'rxjs/operators';\nimport { KEY_CODES } from '../../shared/_services/utility.service';\nimport { SearchResultGroup } from '../../_models/search/search-result-group';\n\n@Component({\n selector: 'app-grouped-typeahead',\n templateUrl: './grouped-typeahead.component.html',\n styleUrls: ['./grouped-typeahead.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class GroupedTypeaheadComponent implements OnInit, OnDestroy {\n /**\n * Unique id to tie with a label element\n */\n @Input() id: string = 'grouped-typeahead';\n /**\n * Minimum number of characters in input to trigger a search\n */\n @Input() minQueryLength: number = 0;\n /**\n * Initial value of the search model\n */\n @Input() initialValue: string = '';\n @Input() grouppedData: SearchResultGroup = new SearchResultGroup();\n /**\n * Placeholder for the input\n */\n @Input() placeholder: string = '';\n /**\n * Number of milliseconds after typing before triggering inputChanged for data fetching\n */\n @Input() debounceTime: number = 200;\n /**\n * Emits when the input changes from user interaction\n */\n @Output() inputChanged: EventEmitter = new EventEmitter();\n /**\n * Emits when something is clicked/selected\n */\n @Output() selected: EventEmitter = new EventEmitter();\n /**\n * Emits an event when the field is cleared\n */\n @Output() clearField: EventEmitter = new EventEmitter();\n /**\n * Emits when a change in the search field looses/gains focus\n */\n @Output() focusChanged: EventEmitter = new EventEmitter();\n\n @ViewChild('input') inputElem!: ElementRef;\n @ContentChild('itemTemplate') itemTemplate!: TemplateRef;\n @ContentChild('seriesTemplate') seriesTemplate: TemplateRef | undefined;\n @ContentChild('collectionTemplate') collectionTemplate: TemplateRef | undefined;\n @ContentChild('tagTemplate') tagTemplate: TemplateRef | undefined;\n @ContentChild('personTemplate') personTemplate: TemplateRef | undefined;\n @ContentChild('genreTemplate') genreTemplate!: TemplateRef;\n @ContentChild('noResultsTemplate') noResultsTemplate!: TemplateRef;\n @ContentChild('libraryTemplate') libraryTemplate!: TemplateRef;\n @ContentChild('readingListTemplate') readingListTemplate!: TemplateRef;\n @ContentChild('fileTemplate') fileTemplate!: TemplateRef;\n @ContentChild('chapterTemplate') chapterTemplate!: TemplateRef;\n \n\n hasFocus: boolean = false;\n isLoading: boolean = false;\n typeaheadForm: FormGroup = new FormGroup({});\n\n prevSearchTerm: string = '';\n\n private onDestroy: Subject = new Subject();\n\n get searchTerm() {\n return this.typeaheadForm.get('typeahead')?.value || '';\n }\n\n get hasData() {\n return !(this.noResultsTemplate != undefined && !this.grouppedData.persons.length && !this.grouppedData.collections.length \n && !this.grouppedData.series.length && !this.grouppedData.persons.length && !this.grouppedData.tags.length && !this.grouppedData.genres.length && !this.grouppedData.libraries.length\n && !this.grouppedData.files.length && !this.grouppedData.chapters.length);\n }\n\n\n constructor(private readonly cdRef: ChangeDetectorRef) { }\n\n @HostListener('window:click', ['$event'])\n handleDocumentClick(event: any) {\n this.close();\n\n }\n\n @HostListener('window:keydown', ['$event'])\n handleKeyPress(event: KeyboardEvent) { \n if (!this.hasFocus) { return; }\n\n switch(event.key) {\n case KEY_CODES.ESC_KEY:\n this.close();\n event.stopPropagation();\n break;\n default:\n break;\n }\n }\n\n ngOnInit(): void {\n this.typeaheadForm.addControl('typeahead', new FormControl(this.initialValue, []));\n this.cdRef.markForCheck();\n\n this.typeaheadForm.valueChanges.pipe(debounceTime(this.debounceTime), takeUntil(this.onDestroy)).subscribe(change => {\n const value = this.typeaheadForm.get('typeahead')?.value;\n\n if (value != undefined && value != '' && !this.hasFocus) {\n this.hasFocus = true;\n this.cdRef.markForCheck();\n }\n\n if (value != undefined && value.length >= this.minQueryLength) {\n\n if (this.prevSearchTerm === value) return;\n this.inputChanged.emit(value);\n this.prevSearchTerm = value;\n this.cdRef.markForCheck();\n }\n });\n }\n\n ngOnDestroy(): void {\n this.onDestroy.next();\n this.onDestroy.complete();\n }\n\n onInputFocus(event: any) {\n if (event) {\n event.stopPropagation();\n event.preventDefault();\n }\n \n this.openDropdown();\n return this.hasFocus;\n }\n\n openDropdown() {\n setTimeout(() => {\n const model = this.typeaheadForm.get('typeahead');\n if (model) {\n model.setValue(model.value);\n }\n });\n }\n\n handleResultlick(item: any) {\n this.selected.emit(item);\n }\n\n resetField() {\n this.prevSearchTerm = '';\n this.typeaheadForm.get('typeahead')?.setValue(this.initialValue);\n this.clearField.emit();\n this.cdRef.markForCheck();\n }\n\n\n close(event?: FocusEvent) {\n if (event) {\n // If the user is tabbing out of the input field, check if there are results first before closing\n if (this.hasData) {\n return;\n }\n }\n if (this.searchTerm === '') {\n this.resetField();\n }\n this.hasFocus = false;\n this.cdRef.markForCheck();\n this.focusChanged.emit(this.hasFocus);\n }\n\n open(event?: FocusEvent) {\n this.hasFocus = true;\n this.focusChanged.emit(this.hasFocus);\n this.cdRef.markForCheck();\n }\n\n public clear() {\n this.prevSearchTerm = '';\n this.typeaheadForm.get('typeahead')?.setValue(this.initialValue);\n this.cdRef.markForCheck();\n }\n\n}\n","import { Pipe, PipeTransform } from '@angular/core';\nimport { PersonRole } from '../_models/person';\n\n@Pipe({\n name: 'personRole'\n})\nexport class PersonRolePipe implements PipeTransform {\n\n transform(value: PersonRole): string {\n switch (value) {\n case PersonRole.Artist: return 'Artist';\n case PersonRole.Character: return 'Character';\n case PersonRole.Colorist: return 'Colorist';\n case PersonRole.CoverArtist: return 'Cover Artist';\n case PersonRole.Editor: return 'Editor';\n case PersonRole.Inker: return 'Inker';\n case PersonRole.Letterer: return 'Letterer';\n case PersonRole.Penciller: return 'Penciller';\n case PersonRole.Publisher: return 'Publisher';\n case PersonRole.Writer: return 'Writer';\n case PersonRole.Other: return '';\n default: return '';\n }\n }\n\n}\n","\n ","import { DOCUMENT } from '@angular/common';\nimport { ChangeDetectionStrategy, ChangeDetectorRef, Component, ElementRef, HostListener, Inject, OnDestroy, OnInit, ViewChild } from '@angular/core';\nimport { NavigationEnd, Router } from '@angular/router';\nimport { fromEvent, Subject } from 'rxjs';\nimport { debounceTime, distinctUntilChanged, filter, takeUntil, takeWhile, tap } from 'rxjs/operators';\nimport { Chapter } from 'src/app/_models/chapter';\nimport { MangaFile } from 'src/app/_models/manga-file';\nimport { ScrollService } from 'src/app/_services/scroll.service';\nimport { SeriesService } from 'src/app/_services/series.service';\nimport { FilterQueryParam } from '../../shared/_services/filter-utilities.service';\nimport { CollectionTag } from '../../_models/collection-tag';\nimport { Library } from '../../_models/library';\nimport { PersonRole } from '../../_models/person';\nimport { ReadingList } from '../../_models/reading-list';\nimport { SearchResult } from '../../_models/search-result';\nimport { SearchResultGroup } from '../../_models/search/search-result-group';\nimport { AccountService } from '../../_services/account.service';\nimport { ImageService } from '../../_services/image.service';\nimport { LibraryService } from '../../_services/library.service';\nimport { NavService } from '../../_services/nav.service';\n\n@Component({\n selector: 'app-nav-header',\n templateUrl: './nav-header.component.html',\n styleUrls: ['./nav-header.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class NavHeaderComponent implements OnInit, OnDestroy {\n\n @ViewChild('search') searchViewRef!: any;\n\n isLoading = false;\n debounceTime = 300;\n imageStyles = {width: '24px', 'margin-top': '5px'};\n searchResults: SearchResultGroup = new SearchResultGroup();\n searchTerm = '';\n customFilter: (items: SearchResult[], query: string) => SearchResult[] = (items: SearchResult[], query: string) => {\n const normalizedQuery = query.trim().toLowerCase();\n const matches = items.filter(item => {\n const normalizedSeriesName = item.name.toLowerCase().trim();\n const normalizedOriginalName = item.originalName.toLowerCase().trim();\n const normalizedLocalizedName = item.localizedName.toLowerCase().trim();\n return normalizedSeriesName.indexOf(normalizedQuery) >= 0 || normalizedOriginalName.indexOf(normalizedQuery) >= 0 || normalizedLocalizedName.indexOf(normalizedQuery) >= 0;\n });\n return matches;\n };\n\n\n backToTopNeeded = false;\n searchFocused: boolean = false;\n scrollElem: HTMLElement;\n private readonly onDestroy = new Subject();\n\n constructor(public accountService: AccountService, private router: Router, public navService: NavService,\n private libraryService: LibraryService, public imageService: ImageService, @Inject(DOCUMENT) private document: Document,\n private scrollService: ScrollService, private seriesService: SeriesService, private readonly cdRef: ChangeDetectorRef) {\n this.scrollElem = this.document.body;\n }\n\n ngOnInit(): void {\n this.scrollService.scrollContainer$.pipe(distinctUntilChanged(), takeUntil(this.onDestroy), tap((scrollContainer) => {\n if (scrollContainer === 'body' || scrollContainer === undefined) {\n this.scrollElem = this.document.body;\n fromEvent(this.document.body, 'scroll').pipe(debounceTime(20)).subscribe(() => this.checkBackToTopNeeded(this.document.body));\n } else {\n const elem = scrollContainer as ElementRef;\n this.scrollElem = elem.nativeElement;\n fromEvent(elem.nativeElement, 'scroll').pipe(debounceTime(20)).subscribe(() => this.checkBackToTopNeeded(elem.nativeElement));\n }\n })).subscribe();\n }\n\n checkBackToTopNeeded(elem: HTMLElement) {\n const offset = elem.scrollTop || 0;\n if (offset > 100) {\n this.backToTopNeeded = true;\n } else if (offset < 40) {\n this.backToTopNeeded = false;\n }\n this.cdRef.markForCheck();\n }\n\n ngOnDestroy() {\n this.onDestroy.next();\n this.onDestroy.complete();\n }\n\n logout() {\n this.accountService.logout();\n this.navService.hideNavBar();\n this.navService.hideSideNav();\n this.router.navigateByUrl('/login');\n }\n\n moveFocus() {\n this.document.getElementById('content')?.focus();\n }\n\n\n\n onChangeSearch(val: string) {\n this.isLoading = true;\n this.searchTerm = val.trim();\n this.cdRef.markForCheck();\n\n this.libraryService.search(val.trim()).pipe(takeUntil(this.onDestroy)).subscribe(results => {\n this.searchResults = results;\n this.isLoading = false;\n this.cdRef.markForCheck();\n }, err => {\n this.searchResults.reset();\n this.isLoading = false;\n this.searchTerm = '';\n this.cdRef.markForCheck();\n });\n }\n\n goTo(queryParamName: string, filter: any) {\n let params: any = {};\n params[queryParamName] = filter;\n params[FilterQueryParam.Page] = 1;\n this.clearSearch();\n this.router.navigate(['all-series'], {queryParams: params});\n }\n\n goToPerson(role: PersonRole, filter: any) {\n this.clearSearch();\n switch(role) {\n case PersonRole.Writer:\n this.goTo(FilterQueryParam.Writers, filter);\n break;\n case PersonRole.Artist:\n this.goTo(FilterQueryParam.Artists, filter);\n break;\n case PersonRole.Character:\n this.goTo(FilterQueryParam.Character, filter);\n break;\n case PersonRole.Colorist:\n this.goTo(FilterQueryParam.Colorist, filter);\n break;\n case PersonRole.Editor:\n this.goTo(FilterQueryParam.Editor, filter);\n break;\n case PersonRole.Inker:\n this.goTo(FilterQueryParam.Inker, filter);\n break;\n case PersonRole.CoverArtist:\n this.goTo(FilterQueryParam.CoverArtists, filter);\n break;\n case PersonRole.Letterer:\n this.goTo(FilterQueryParam.Letterer, filter);\n break;\n case PersonRole.Penciller:\n this.goTo(FilterQueryParam.Penciller, filter);\n break;\n case PersonRole.Publisher:\n this.goTo(FilterQueryParam.Publisher, filter);\n break;\n case PersonRole.Translator:\n this.goTo(FilterQueryParam.Translator, filter);\n break;\n }\n }\n\n clearSearch() {\n this.searchViewRef.clear();\n this.searchTerm = '';\n this.searchResults = new SearchResultGroup();\n this.cdRef.markForCheck();\n }\n\n clickSeriesSearchResult(item: SearchResult) {\n this.clearSearch();\n const libraryId = item.libraryId;\n const seriesId = item.seriesId;\n this.router.navigate(['library', libraryId, 'series', seriesId]);\n }\n\n clickFileSearchResult(item: MangaFile) {\n this.clearSearch();\n this.seriesService.getSeriesForMangaFile(item.id).subscribe(series => {\n if (series !== undefined && series !== null) {\n this.router.navigate(['library', series.libraryId, 'series', series.id]);\n }\n });\n }\n\n clickChapterSearchResult(item: Chapter) {\n this.clearSearch();\n this.seriesService.getSeriesForChapter(item.id).subscribe(series => {\n if (series !== undefined && series !== null) {\n this.router.navigate(['library', series.libraryId, 'series', series.id]);\n }\n });\n }\n\n clickLibraryResult(item: Library) {\n this.clearSearch();\n this.router.navigate(['library', item.id]);\n }\n\n clickCollectionSearchResult(item: CollectionTag) {\n this.clearSearch();\n this.router.navigate(['collections', item.id]);\n }\n\n clickReadingListSearchResult(item: ReadingList) {\n this.clearSearch();\n this.router.navigate(['lists', item.id]);\n }\n\n\n scrollToTop() {\n this.scrollService.scrollTo(0, this.scrollElem);\n }\n\n focusUpdate(searchFocused: boolean) {\n this.searchFocused = searchFocused;\n this.cdRef.markForCheck();\n }\n\n hideSideNav() {\n this.navService.toggleSideNav();\n }\n}\n","\n
\n \n \n
\n
\n
\n \n
\n
\n \n \n \n
\n \n
\n","import { Component, HostListener, Inject, OnInit } from '@angular/core';\nimport { NavigationStart, Router } from '@angular/router';\nimport { take } from 'rxjs/operators';\nimport { AccountService } from './_services/account.service';\nimport { LibraryService } from './_services/library.service';\nimport { MessageHubService } from './_services/message-hub.service';\nimport { NavService } from './_services/nav.service';\nimport { filter } from 'rxjs/operators';\nimport { NgbModal, NgbRatingConfig } from '@ng-bootstrap/ng-bootstrap';\nimport { DOCUMENT } from '@angular/common';\n\n@Component({\n selector: 'app-root',\n templateUrl: './app.component.html',\n styleUrls: ['./app.component.scss']\n})\nexport class AppComponent implements OnInit {\n\n constructor(private accountService: AccountService, public navService: NavService, \n private messageHub: MessageHubService, private libraryService: LibraryService, \n router: Router, private ngbModal: NgbModal, ratingConfig: NgbRatingConfig, \n @Inject(DOCUMENT) private document: Document) {\n\n // Setup default rating config\n ratingConfig.max = 5;\n ratingConfig.resettable = true;\n \n // Close any open modals when a route change occurs\n router.events\n .pipe(filter(event => event instanceof NavigationStart))\n .subscribe((event) => {\n if (this.ngbModal.hasOpenModals()) {\n this.ngbModal.dismissAll();\n }\n });\n\n }\n\n @HostListener('window:resize', ['$event'])\n @HostListener('window:orientationchange', ['$event'])\n setDocHeight() {\n // Sets a CSS variable for the actual device viewport height. Needed for mobile dev.\n const vh = window.innerHeight * 0.01;\n this.document.documentElement.style.setProperty('--vh', `${vh}px`);\n }\n\n ngOnInit(): void {\n this.setCurrentUser();\n this.setDocHeight();\n }\n\n setCurrentUser() {\n const user = this.accountService.getUserFromLocalStorage();\n this.accountService.setCurrentUser(user);\n\n if (user) {\n this.messageHub.createHubConnection(user, this.accountService.hasAdminRole(user));\n this.libraryService.getLibraryNames().pipe(take(1)).subscribe(() => {/* No Operation */});\n } \n }\n}\n","import { Injectable } from '@angular/core';\nimport {\n HttpRequest,\n HttpHandler,\n HttpEvent,\n HttpInterceptor\n} from '@angular/common/http';\nimport { Observable } from 'rxjs';\nimport { AccountService } from '../_services/account.service';\nimport { take } from 'rxjs/operators';\n\n@Injectable()\nexport class JwtInterceptor implements HttpInterceptor {\n\n constructor(private accountService: AccountService) {}\n\n intercept(request: HttpRequest, next: HttpHandler): Observable> {\n\n // Take 1 means we don't have to unsubscribe because we take 1 then complete\n this.accountService.currentUser$.pipe(take(1)).subscribe(user => {\n if (user) {\n request = request.clone({\n setHeaders: {\n Authorization: `Bearer ${user.token}`\n }\n });\n }\n });\n\n return next.handle(request);\n }\n}\n","import { Injectable } from '@angular/core';\nimport {\n HttpRequest,\n HttpHandler,\n HttpEvent,\n HttpInterceptor\n} from '@angular/common/http';\nimport { Observable, throwError } from 'rxjs';\nimport { Router } from '@angular/router';\nimport { ToastrService } from 'ngx-toastr';\nimport { catchError } from 'rxjs/operators';\nimport { AccountService } from '../_services/account.service';\n\n@Injectable()\nexport class ErrorInterceptor implements HttpInterceptor {\n\n constructor(private router: Router, private toastr: ToastrService, private accountService: AccountService) {}\n\n\n intercept(request: HttpRequest, next: HttpHandler): Observable> {\n return next.handle(request).pipe(\n catchError(error => {\n if (error === undefined || error === null) {\n return throwError(error);\n }\n\n switch (error.status) {\n case 400:\n this.handleValidationError(error);\n break;\n case 401:\n this.handleAuthError(error);\n break;\n case 404:\n this.handleNotFound(error);\n break;\n case 500:\n this.handleServerException(error);\n break;\n default:\n // Don't throw multiple Something undexpected went wrong\n if (this.toastr.previousToastMessage !== 'Something unexpected went wrong.') {\n this.toastr.error('Something unexpected went wrong.');\n }\n break;\n }\n return throwError(error);\n })\n );\n }\n\n private handleValidationError(error: any) {\n // This 400 can also be a bad request \n if (Array.isArray(error.error)) {\n const modalStateErrors: any[] = [];\n if (error.error.length > 0 && error.error[0].hasOwnProperty('message')) {\n if (error.error[0].details === null) {\n error.error.forEach((issue: {status: string, details: string, message: string}) => {\n modalStateErrors.push(issue.message);\n });\n } else {\n error.error.forEach((issue: {status: string, details: string, message: string}) => {\n modalStateErrors.push(issue.details);\n });\n }\n } else {\n error.error.forEach((issue: {code: string, description: string}) => {\n modalStateErrors.push(issue.description);\n });\n }\n throw modalStateErrors.flat();\n } else if (error.error.errors) {\n // Validation error\n const modalStateErrors = [];\n for (const key in error.error.errors) {\n if (error.error.errors[key]) {\n modalStateErrors.push(error.error.errors[key]);\n }\n }\n throw modalStateErrors.flat();\n } else {\n console.error('error:', error);\n if (error.statusText === 'Bad Request') {\n if (error.error instanceof Blob) {\n this.toastr.error('There was an issue downloading this file or you do not have permissions', error.status); \n return; \n }\n this.toastr.error(error.error, error.status + ' Error');\n } else {\n this.toastr.error(error.statusText === 'OK' ? error.error : error.statusText, error.status + ' Error');\n }\n }\n }\n\n private handleNotFound(error: any) {\n this.toastr.error('That url does not exist.'); \n }\n\n private handleServerException(error: any) {\n const err = error.error;\n if (err.hasOwnProperty('message') && err.message.trim() !== '') {\n if (err.message != 'User is not authenticated') {\n console.error('500 error: ', error);\n }\n this.toastr.error(err.message);\n } else if (error.hasOwnProperty('message') && error.message.trim() !== '') {\n if (error.message != 'User is not authenticated') {\n console.error('500 error: ', error);\n }\n this.toastr.error(error.message);\n }\n else {\n this.toastr.error('There was an unknown critical error.');\n console.error('500 error:', error);\n }\n }\n\n private handleAuthError(error: any) {\n\n // Special hack for register url, to not care about auth\n if (location.href.includes('/registration/confirm-email?token=')) {\n return;\n }\n // NOTE: Signin has error.error or error.statusText available. \n // if statement is due to http/2 spec issue: https://github.com/angular/angular/issues/23334\n this.accountService.logout();\n this.router.navigateByUrl('/login');\n }\n}\n","import { NgModule } from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { EventsWidgetComponent } from './events-widget/events-widget.component';\nimport { GroupedTypeaheadComponent } from './grouped-typeahead/grouped-typeahead.component';\nimport { NavHeaderComponent } from './nav-header/nav-header.component';\nimport { NgbDropdownModule, NgbPopoverModule, NgbNavModule } from '@ng-bootstrap/ng-bootstrap';\nimport { SharedModule } from '../shared/shared.module';\nimport { PipeModule } from '../pipe/pipe.module';\nimport { TypeaheadModule } from '../typeahead/typeahead.module';\nimport { ReactiveFormsModule } from '@angular/forms';\nimport { RouterModule } from '@angular/router';\n\n\n\n@NgModule({\n declarations: [\n NavHeaderComponent,\n EventsWidgetComponent,\n GroupedTypeaheadComponent,\n ],\n imports: [\n CommonModule,\n ReactiveFormsModule,\n RouterModule,\n\n NgbDropdownModule,\n NgbPopoverModule,\n NgbNavModule,\n\n SharedModule, // app image, series-format\n PipeModule,\n TypeaheadModule,\n ],\n exports: [\n NavHeaderComponent,\n SharedModule\n ]\n})\nexport class NavModule { }\n","import { BrowserModule, Title } from '@angular/platform-browser';\nimport { NgModule } from '@angular/core';\n\nimport { AppRoutingModule } from './app-routing.module';\nimport { AppComponent } from './app.component';\nimport { BrowserAnimationsModule } from '@angular/platform-browser/animations';\nimport { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http';\nimport { JwtInterceptor } from './_interceptors/jwt.interceptor';\nimport { ToastrModule } from 'ngx-toastr';\nimport { ErrorInterceptor } from './_interceptors/error.interceptor';\n\nimport { SAVER, getSaver } from './shared/_providers/saver.provider';\nimport { SidenavModule } from './sidenav/sidenav.module';\nimport { NavModule } from './nav/nav.module';\n\n\n\n\n@NgModule({\n declarations: [\n AppComponent,\n ],\n imports: [\n HttpClientModule,\n BrowserModule,\n AppRoutingModule,\n BrowserAnimationsModule,\n SidenavModule,\n NavModule,\n ToastrModule.forRoot({\n positionClass: 'toast-bottom-right',\n preventDuplicates: true,\n timeOut: 6000,\n countDuplicates: true,\n autoDismiss: true\n }),\n ],\n providers: [\n { provide: HTTP_INTERCEPTORS, useClass: ErrorInterceptor, multi: true },\n { provide: HTTP_INTERCEPTORS, useClass: JwtInterceptor, multi: true },\n Title,\n { provide: SAVER, useFactory: getSaver },\n ],\n bootstrap: [AppComponent]\n})\nexport class AppModule { }\n","import { enableProdMode } from '@angular/core';\nimport { platformBrowserDynamic } from '@angular/platform-browser-dynamic';\nimport { AppModule } from './app/app.module';\nimport { environment } from './environments/environment';\n\nif (environment.production) {\n enableProdMode();\n}\n\n// function fetchConfig(): Promise {\n// return fetch(environment.apiUrl + 'settings/base-url')\n// .then(response => response.text())\n// .then(response => new ConfigData(response));\n// }\n\n// fetchConfig().then(config => {\n \n// });\nplatformBrowserDynamic().bootstrapModule(AppModule)\n .catch(err => console.error(err));"],"x_google_ignoreList":[]}