New Year Bugs (#2513)
This commit is contained in:
parent
fcacd67d71
commit
5dfcccba7a
32 changed files with 230 additions and 142 deletions
|
@ -1,7 +1,9 @@
|
|||
<ng-container *transloco="let t; read:'review-card-modal'">
|
||||
<div>
|
||||
<div class="modal-header">
|
||||
<h4 class="modal-title" id="modal-basic-title">{{t('user-review', {username: review.username})}} {{review.isExternal ? t('external-mod') : ''}}</h4>
|
||||
<h4 class="modal-title" id="modal-basic-title">
|
||||
{{t('user-review', {username: review.username})}} @if(review.isExternal) {<img class="me-1" [ngSrc]="review.provider | providerImage" width="20" height="20" alt="">}
|
||||
</h4>
|
||||
<button type="button" class="btn-close" [attr.aria-label]="t('close')" (click)="close()"></button>
|
||||
</div>
|
||||
<div class="modal-body scrollable-modal">
|
||||
|
|
|
@ -1,24 +1,26 @@
|
|||
import {
|
||||
AfterViewInit,
|
||||
ChangeDetectionStrategy,
|
||||
Component,
|
||||
Component, inject,
|
||||
Inject,
|
||||
Input, ViewChild,
|
||||
ViewContainerRef,
|
||||
ViewEncapsulation
|
||||
} from '@angular/core';
|
||||
import {CommonModule, DOCUMENT} from '@angular/common';
|
||||
import {CommonModule, DOCUMENT, NgOptimizedImage} from '@angular/common';
|
||||
import {NgbActiveModal} from "@ng-bootstrap/ng-bootstrap";
|
||||
import {ReactiveFormsModule} from "@angular/forms";
|
||||
import {UserReview} from "../review-card/user-review";
|
||||
import {SpoilerComponent} from "../spoiler/spoiler.component";
|
||||
import {SafeHtmlPipe} from "../../_pipes/safe-html.pipe";
|
||||
import {TranslocoDirective} from "@ngneat/transloco";
|
||||
import {DefaultValuePipe} from "../../_pipes/default-value.pipe";
|
||||
import {ProviderImagePipe} from "../../_pipes/provider-image.pipe";
|
||||
|
||||
@Component({
|
||||
selector: 'app-review-card-modal',
|
||||
standalone: true,
|
||||
imports: [CommonModule, ReactiveFormsModule, SpoilerComponent, SafeHtmlPipe, TranslocoDirective],
|
||||
imports: [CommonModule, ReactiveFormsModule, SpoilerComponent, SafeHtmlPipe, TranslocoDirective, DefaultValuePipe, NgOptimizedImage, ProviderImagePipe],
|
||||
templateUrl: './review-card-modal.component.html',
|
||||
styleUrls: ['./review-card-modal.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
|
@ -26,12 +28,13 @@ import {TranslocoDirective} from "@ngneat/transloco";
|
|||
})
|
||||
export class ReviewCardModalComponent implements AfterViewInit {
|
||||
|
||||
private modal = inject(NgbActiveModal);
|
||||
|
||||
@Input({required: true}) review!: UserReview;
|
||||
@ViewChild('container', { read: ViewContainerRef }) container!: ViewContainerRef;
|
||||
|
||||
|
||||
constructor(private modal: NgbActiveModal, @Inject(DOCUMENT) private document: Document) {
|
||||
}
|
||||
constructor(@Inject(DOCUMENT) private document: Document) {}
|
||||
|
||||
close() {
|
||||
this.modal.close();
|
||||
|
|
|
@ -10,11 +10,8 @@
|
|||
</div>
|
||||
<div class="col-md-10">
|
||||
<div class="card-body">
|
||||
<h6 class="card-title" [title]="review.tagline">
|
||||
<ng-container *ngIf="review.tagline && review.tagline.length > 0; else noTagline">{{review.tagline.substring(0, 29)}}{{review.tagline.length > 29 ? '…' : ''}}</ng-container>
|
||||
<ng-template #noTagline>
|
||||
{{review.isExternal ? t('external-review') : t('local-review')}}
|
||||
</ng-template>
|
||||
<h6 class="card-title">
|
||||
{{review.isExternal ? t('external-review') : t('local-review')}}
|
||||
</h6>
|
||||
<p class="card-text no-images">
|
||||
<app-read-more [text]="(review.isExternal ? review.bodyJustText : review.body) || ''" [maxLength]="100" [showToggle]="false"></app-read-more>
|
||||
|
@ -23,9 +20,11 @@
|
|||
</div>
|
||||
|
||||
<div class="card-footer bg-transparent text-muted">
|
||||
<div class="review-user">
|
||||
<div>
|
||||
<ng-container *ngIf="isMyReview; else normalReview">
|
||||
<i class="d-md-none fa-solid fa-star me-1" aria-hidden="true" [title]="t('your-review')"></i>
|
||||
<img class="me-1" [ngSrc]="ScrobbleProvider.Kavita | providerImage" width="20" height="20" alt="">
|
||||
{{review.username}}
|
||||
</ng-container>
|
||||
<ng-template #normalReview>
|
||||
<img class="me-1" [ngSrc]="review.provider | providerImage" width="20" height="20" alt="">
|
||||
|
|
|
@ -39,7 +39,7 @@
|
|||
.card-footer {
|
||||
font-size: 13px;
|
||||
display: flex;
|
||||
max-width: 305px;
|
||||
max-width: 319px;
|
||||
justify-content: space-between;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ import {DefaultValuePipe} from "../../_pipes/default-value.pipe";
|
|||
import {ImageComponent} from "../../shared/image/image.component";
|
||||
import {ProviderImagePipe} from "../../_pipes/provider-image.pipe";
|
||||
import {TranslocoDirective} from "@ngneat/transloco";
|
||||
import {ScrobbleProvider} from "../../_services/scrobbling.service";
|
||||
|
||||
@Component({
|
||||
selector: 'app-review-card',
|
||||
|
@ -20,9 +21,11 @@ import {TranslocoDirective} from "@ngneat/transloco";
|
|||
changeDetection: ChangeDetectionStrategy.OnPush
|
||||
})
|
||||
export class ReviewCardComponent implements OnInit {
|
||||
private readonly accountService = inject(AccountService);
|
||||
protected readonly ScrobbleProvider = ScrobbleProvider;
|
||||
|
||||
@Input({required: true}) review!: UserReview;
|
||||
private readonly accountService = inject(AccountService);
|
||||
|
||||
isMyReview: boolean = false;
|
||||
|
||||
constructor(private readonly modalService: NgbModal, private readonly cdRef: ChangeDetectorRef) {}
|
||||
|
@ -46,5 +49,4 @@ export class ReviewCardComponent implements OnInit {
|
|||
const ref = this.modalService.open(component, {size: 'lg', fullscreen: 'md'});
|
||||
ref.componentInstance.review = this.review;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -8,14 +8,19 @@
|
|||
</div>
|
||||
<div class="modal-body">
|
||||
<form [formGroup]="reviewGroup">
|
||||
<div class="row g-0">
|
||||
<label for="tagline" class="form-label">{{t('tagline-label')}}</label>
|
||||
<input id="tagline" class="form-control" formControlName="tagline" />
|
||||
</div>
|
||||
|
||||
<div class="row g-0 mt-2">
|
||||
<label for="review" class="form-label">{{t('review-label')}}</label>
|
||||
<textarea id="review" class="form-control" formControlName="reviewBody" rows="3" ></textarea>
|
||||
<textarea id="review" class="form-control" formControlName="reviewBody" rows="3" [minlength]="minLength"
|
||||
[class.is-invalid]="reviewGroup.get('reviewBody')?.invalid && reviewGroup.get('reviewBody')?.touched" aria-describedby="body-validations"
|
||||
></textarea>
|
||||
<div id="body-validations" class="invalid-feedback" *ngIf="reviewGroup.dirty || reviewGroup.touched">
|
||||
@if (reviewGroup.get('reviewBody')?.errors?.required) {
|
||||
<div>{{t('required')}}</div>
|
||||
}
|
||||
@if (reviewGroup.get('reviewBody')?.errors?.minlength) {
|
||||
<div>{{t('min-length', {count: minLength})}}</div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, Input, OnInit } from '@angular/core';
|
||||
import {ChangeDetectionStrategy, ChangeDetectorRef, Component, inject, Input, OnInit} from '@angular/core';
|
||||
import {FormControl, FormGroup, ReactiveFormsModule, Validators} from '@angular/forms';
|
||||
import {NgbActiveModal, NgbRating} from '@ng-bootstrap/ng-bootstrap';
|
||||
import { SeriesService } from 'src/app/_services/series.service';
|
||||
|
@ -9,22 +9,24 @@ import {TranslocoDirective} from "@ngneat/transloco";
|
|||
@Component({
|
||||
selector: 'app-review-series-modal',
|
||||
standalone: true,
|
||||
imports: [CommonModule, NgbRating, ReactiveFormsModule, TranslocoDirective],
|
||||
imports: [CommonModule, NgbRating, ReactiveFormsModule, TranslocoDirective],
|
||||
templateUrl: './review-series-modal.component.html',
|
||||
styleUrls: ['./review-series-modal.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush
|
||||
})
|
||||
export class ReviewSeriesModalComponent implements OnInit {
|
||||
|
||||
protected readonly modal = inject(NgbActiveModal);
|
||||
private readonly seriesService = inject(SeriesService);
|
||||
private readonly cdRef = inject(ChangeDetectorRef);
|
||||
protected readonly minLength = 20;
|
||||
|
||||
@Input({required: true}) review!: UserReview;
|
||||
reviewGroup!: FormGroup;
|
||||
|
||||
constructor(public modal: NgbActiveModal, private seriesService: SeriesService, private readonly cdRef: ChangeDetectorRef) {}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.reviewGroup = new FormGroup({
|
||||
tagline: new FormControl(this.review.tagline || '', [Validators.min(20), Validators.max(120)]),
|
||||
reviewBody: new FormControl(this.review.body, [Validators.min(20)]),
|
||||
reviewBody: new FormControl(this.review.body, [Validators.required, Validators.minLength(this.minLength)]),
|
||||
});
|
||||
this.cdRef.markForCheck();
|
||||
}
|
||||
|
@ -35,7 +37,10 @@ export class ReviewSeriesModalComponent implements OnInit {
|
|||
|
||||
save() {
|
||||
const model = this.reviewGroup.value;
|
||||
this.seriesService.updateReview(this.review.seriesId, model.tagline, model.reviewBody).subscribe(() => {
|
||||
if (model.reviewBody.length < this.minLength) {
|
||||
return;
|
||||
}
|
||||
this.seriesService.updateReview(this.review.seriesId, model.reviewBody).subscribe(() => {
|
||||
this.modal.close({success: true});
|
||||
});
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
<div class="offcanvas-header">
|
||||
<h5 class="offcanvas-title">
|
||||
{{name}}
|
||||
|
||||
</h5>
|
||||
<button type="button" class="btn-close text-reset" [attr.aria-label]="t('common.close')" (click)="close()"></button>
|
||||
</div>
|
||||
|
@ -17,6 +18,14 @@
|
|||
<div *ngIf="(externalSeries.volumeCount || 0) > 0 || (externalSeries.chapterCount || 0) > 0" class="text-muted muted mb-2">
|
||||
{{t('series-preview-drawer.vols-and-chapters', {volCount: externalSeries.volumeCount, chpCount: externalSeries.chapterCount})}}
|
||||
</div>
|
||||
|
||||
@if(isExternalSeries && externalSeries) {
|
||||
<div class="text-muted muted mb-2">
|
||||
{{t('series-preview-drawer.provided-by-label')}}
|
||||
<img class="ms-1" [ngSrc]="externalSeries.provider | providerImage" width="20" height="20" alt="">
|
||||
</div>
|
||||
}
|
||||
|
||||
<app-read-more *ngIf="externalSeries.summary" [maxLength]="300" [text]="externalSeries.summary"></app-read-more>
|
||||
|
||||
<div class="mt-3">
|
||||
|
@ -122,7 +131,7 @@
|
|||
|
||||
<app-loading [loading]="isLoading"></app-loading>
|
||||
|
||||
<a class="btn btn-primary col-12 " [href]="url" target="_blank" rel="noopener noreferrer">
|
||||
<a class="btn btn-primary col-12 mt-2" [href]="url" target="_blank" rel="noopener noreferrer">
|
||||
{{t('series-preview-drawer.view-series')}}
|
||||
</a>
|
||||
</div>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import {ChangeDetectionStrategy, ChangeDetectorRef, Component, inject, Input, OnInit} from '@angular/core';
|
||||
import {CommonModule} from '@angular/common';
|
||||
import {CommonModule, NgOptimizedImage} from '@angular/common';
|
||||
import {TranslocoDirective} from "@ngneat/transloco";
|
||||
import {NgbActiveOffcanvas, NgbTooltip} from "@ng-bootstrap/ng-bootstrap";
|
||||
import {ExternalSeriesDetail, SeriesStaff} from "../../_models/series-detail/external-series-detail";
|
||||
|
@ -16,11 +16,13 @@ import {PublicationStatusPipe} from "../../_pipes/publication-status.pipe";
|
|||
import {SeriesMetadata} from "../../_models/metadata/series-metadata";
|
||||
import {ReadMoreComponent} from "../../shared/read-more/read-more.component";
|
||||
import {ActionService} from "../../_services/action.service";
|
||||
import {ProviderImagePipe} from "../../_pipes/provider-image.pipe";
|
||||
import {ScrobbleProvider} from "../../_services/scrobbling.service";
|
||||
|
||||
@Component({
|
||||
selector: 'app-series-preview-drawer',
|
||||
standalone: true,
|
||||
imports: [CommonModule, TranslocoDirective, ImageComponent, LoadingComponent, SafeHtmlPipe, A11yClickDirective, MetadataDetailComponent, PersonBadgeComponent, TagBadgeComponent, PublicationStatusPipe, ReadMoreComponent, NgbTooltip],
|
||||
imports: [CommonModule, TranslocoDirective, ImageComponent, LoadingComponent, SafeHtmlPipe, A11yClickDirective, MetadataDetailComponent, PersonBadgeComponent, TagBadgeComponent, PublicationStatusPipe, ReadMoreComponent, NgbTooltip, NgOptimizedImage, ProviderImagePipe],
|
||||
templateUrl: './series-preview-drawer.component.html',
|
||||
styleUrls: ['./series-preview-drawer.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush
|
||||
|
@ -59,7 +61,6 @@ export class SeriesPreviewDrawerComponent implements OnInit {
|
|||
if (this.isExternalSeries) {
|
||||
this.seriesService.getExternalSeriesDetails(this.aniListId, this.malId).subscribe(externalSeries => {
|
||||
this.externalSeries = externalSeries;
|
||||
|
||||
this.isLoading = false;
|
||||
if (this.externalSeries.siteUrl) {
|
||||
this.url = this.externalSeries.siteUrl;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue