Metadata Fixes (#3533)

Co-authored-by: Midhun Sudhir <60651970+midhun3301@users.noreply.github.com>
This commit is contained in:
Joe Milazzo 2025-02-06 16:47:29 -06:00 committed by GitHub
parent 40bbdcb5f0
commit bb9621a588
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
25 changed files with 151 additions and 56 deletions

View file

@ -37,6 +37,11 @@ export interface ExternalSeriesDetail {
summary?: string;
volumeCount?: number;
chapterCount?: number;
/**
* These are duplicated with volumeCount based on where it's being invoked.
*/
volumes?: number;
chapters?: number;
staff: Array<SeriesStaff>;
tags: Array<MetadataTagDto>;
provider: ScrobbleProvider;

View file

@ -63,7 +63,7 @@
<div class="mb-3">
<app-carousel-reel [items]="webLinks" [title]="t('weblinks-title')">
<ng-template #carouselItem let-item>
<a class="me-1" [href]="item | safeHtml" target="_blank" rel="noopener noreferrer" [title]="item">
<a class="me-1" [href]="item | safeUrl" target="_blank" rel="noopener noreferrer" [title]="item">
<app-image height="24px" width="24px" aria-hidden="true" [imageUrl]="imageService.getWebLinkImage(item)"
[errorImage]="imageService.errorWebLinkImage"></app-image>
</a>

View file

@ -22,6 +22,7 @@ import {SeriesFormatComponent} from "../../shared/series-format/series-format.co
import {MangaFormatPipe} from "../../_pipes/manga-format.pipe";
import {LanguageNamePipe} from "../../_pipes/language-name.pipe";
import {AsyncPipe} from "@angular/common";
import {SafeUrlPipe} from "../../_pipes/safe-url.pipe";
@Component({
selector: 'app-details-tab',
@ -39,7 +40,8 @@ import {AsyncPipe} from "@angular/common";
SeriesFormatComponent,
MangaFormatPipe,
LanguageNamePipe,
AsyncPipe
AsyncPipe,
SafeUrlPipe
],
templateUrl: './details-tab.component.html',
styleUrl: './details-tab.component.scss',

View file

@ -32,9 +32,9 @@
} @else {
<div class="d-flex p-1 justify-content-between">
<span class="me-1"><a (click)="$event.stopPropagation()" [href]="item.series.siteUrl" rel="noreferrer noopener" target="_blank">{{t('details')}}</a></span>
@if ((item.series.volumeCount || 0) > 0 || (item.series.chapterCount || 0) > 0) {
<span class="me-1">{{t('volume-count', {num: item.series.volumeCount})}}</span>
<span class="me-1">{{t('chapter-count', {num: item.series.chapterCount})}}</span>
@if ((item.series.volumes || 0) > 0 || (item.series.chapters || 0) > 0) {
<span class="me-1">{{t('volume-count', {num: item.series.volumes})}}</span>
<span class="me-1">{{t('chapter-count', {num: item.series.chapters})}}</span>
} @else {
<span class="me-1">{{t('releasing')}}</span>
}

View file

@ -4,7 +4,7 @@
<a class="position-absolute custom-position btn btn-primary-outline" [href]="WikiLink.KavitaPlusFAQ" target="_blank" rel="noreferrer nofollow">{{t('faq-title')}}</a>
</div>
<div class="container-fluid">
<div>
<p>{{t('kavita+-desc-part-1')}} <a [href]="WikiLink.KavitaPlus" target="_blank" rel="noreferrer nofollow">{{t('kavita+-desc-part-2')}}</a> {{t('kavita+-desc-part-3')}}</p>
<form [formGroup]="formGroup">

View file

@ -31,6 +31,7 @@ export class ManageLogsComponent implements OnInit, OnDestroy {
constructor(private accountService: AccountService) { }
ngOnInit(): void {
// TODO: Come back and implement this one day
this.accountService.currentUser$.pipe(take(1)).subscribe(user => {
if (user) {
this.hubConnection = new HubConnectionBuilder()

View file

@ -25,7 +25,7 @@ const ValidIpAddress = /^(\s*((([12]?\d{1,2}\.){3}[12]?\d{1,2})|(([\da-f]{0,4}\:
styleUrls: ['./manage-settings.component.scss'],
standalone: true,
changeDetection: ChangeDetectionStrategy.OnPush,
imports: [ReactiveFormsModule, NgbTooltip, TitleCasePipe, TranslocoModule, NgTemplateOutlet, PageLayoutModePipe, SettingItemComponent, SettingSwitchComponent, SafeHtmlPipe]
imports: [ReactiveFormsModule, TitleCasePipe, TranslocoModule, SettingItemComponent, SettingSwitchComponent]
})
export class ManageSettingsComponent implements OnInit {

View file

@ -18,7 +18,6 @@ import {UtcToLocalTimePipe} from "../../_pipes/utc-to-local-time.pipe";
import {takeUntilDestroyed} from "@angular/core/rxjs-interop";
import {SettingItemComponent} from "../../settings/_components/setting-item/setting-item.component";
import {ConfirmService} from "../../shared/confirm.service";
import {SettingButtonComponent} from "../../settings/_components/setting-button/setting-button.component";
import {DefaultModalOptions} from "../../_models/default-modal-options";
import {ColumnMode, NgxDatatableModule} from "@siemens/ngx-datatable";
@ -38,7 +37,8 @@ interface AdhocTask {
standalone: true,
changeDetection: ChangeDetectionStrategy.OnPush,
imports: [ReactiveFormsModule, AsyncPipe, TitleCasePipe, DefaultValuePipe,
TranslocoModule, TranslocoLocaleModule, UtcToLocalTimePipe, SettingItemComponent, SettingButtonComponent, NgxDatatableModule]
TranslocoModule, TranslocoLocaleModule, UtcToLocalTimePipe, SettingItemComponent,
SettingButtonComponent, NgxDatatableModule]
})
export class ManageTasksSettingsComponent implements OnInit {

View file

@ -2,7 +2,7 @@
border-radius: 0.5rem;
}
.blog-content {
:host ::ng-deep .blog-content {
margin-bottom: 1.5rem;
line-height: 1.6;
word-wrap: break-word;

View file

@ -27,4 +27,5 @@ export class ChangelogUpdateItemComponent {
@Input({required:true}) update: UpdateVersionEvent | null = null;
@Input() index: number = 0;
@Input() showExtras: boolean = true;
}

View file

@ -103,9 +103,7 @@ const blackList = [Action.Edit, Action.Info, Action.IncognitoRead, Action.Read,
MangaFormatPipe,
DefaultDatePipe,
TimeAgoPipe,
TagBadgeComponent,
PublicationStatusPipe,
NgbTooltip,
BytesPipe,
ImageComponent,
NgbCollapse,
@ -117,7 +115,6 @@ const blackList = [Action.Edit, Action.Info, Action.IncognitoRead, Action.Read,
EditListComponent,
SettingButtonComponent,
SettingItemComponent,
ReadTimePipe,
],
templateUrl: './edit-series-modal.component.html',
styleUrls: ['./edit-series-modal.component.scss'],
@ -655,6 +652,11 @@ export class EditSeriesModalComponent implements OnInit {
case Action.Download:
this.downloadService.download('series', this.series);
break;
case Action.Match:
this.actionService.matchSeries(this.series, _ => {
this.modal.close({success: true, series: this.series, coverImageUpdate: false, updateExternal: true});
});
break;
}
}
}

View file

@ -7,6 +7,13 @@
<h2 class="title text-break">
<app-card-actionables (actionHandler)="performAction($event)" [actions]="personActions" [labelBy]="person.name" iconClass="fa-ellipsis-v"></app-card-actionables>
<span>{{person.name}}</span>
@if (person.aniListId) {
<a class="ms-1" [href]="anilistUrl | safeUrl" target="_blank" rel="noopener noreferrer">
<app-image height="24px" width="24px" aria-hidden="true" [imageUrl]="imageService.getWebLinkImage(anilistUrl)"
[errorImage]="imageService.errorWebLinkImage"></app-image>
</a>
}
</h2>
</ng-container>
</app-side-nav-companion-bar>
@ -45,6 +52,7 @@
}
</div>
}
</div>
</div>
</div>

View file

@ -41,6 +41,7 @@ import {ThemeService} from "../_services/theme.service";
import {DefaultModalOptions} from "../_models/default-modal-options";
import {ToastrService} from "ngx-toastr";
import {LicenseService} from "../_services/license.service";
import {SafeUrlPipe} from "../_pipes/safe-url.pipe";
@Component({
selector: 'app-person-detail',
@ -49,16 +50,15 @@ import {LicenseService} from "../_services/license.service";
AsyncPipe,
ImageComponent,
SideNavCompanionBarComponent,
NgStyle,
ReadMoreComponent,
TagBadgeComponent,
PersonRolePipe,
CarouselReelComponent,
SeriesCardComponent,
CardItemComponent,
CardActionablesComponent,
TranslocoDirective,
ChapterCardComponent
ChapterCardComponent,
SafeUrlPipe
],
templateUrl: './person-detail.component.html',
styleUrl: './person-detail.component.scss',
@ -93,8 +93,14 @@ export class PersonDetailComponent {
filter: SeriesFilterV2 | null = null;
personActions: Array<ActionItem<Person>> = this.actionService.getPersonActions(this.handleAction.bind(this));
chaptersByRole: any = {};
anilistUrl: string = '';
private readonly personSubject = new BehaviorSubject<Person | null>(null);
protected readonly person$ = this.personSubject.asObservable();
protected readonly person$ = this.personSubject.asObservable().pipe(tap(p => {
if (p?.aniListId) {
this.anilistUrl = translate('person-detail.anilist-url').replace('{AniListId}', p!.aniListId! + '');
this.cdRef.markForCheck();
}
}));
get HasCoverImage() {
return (this.person as Person).coverImage;

View file

@ -1,11 +1,11 @@
<div class="main-container container-fluid">
<ng-container *transloco="let t; read:'settings'">
<app-side-nav-companion-bar>
<h2 title>
<h2 class="container-fluid" title>
{{fragment | settingFragment}}
</h2>
</app-side-nav-companion-bar>
<div class="row col-me-4 pb-3">
<div class="container-fluid row col-me-4 pb-3">
@if (accountService.currentUser$ | async; as user) {
@if (accountService.hasAdminRole(user)) {