diff --git a/booklore-ui/src/app/features/book/components/book-browser/book-card/book-card.component.html b/booklore-ui/src/app/features/book/components/book-browser/book-card/book-card.component.html
index bf9c01d7..79bef988 100644
--- a/booklore-ui/src/app/features/book/components/book-browser/book-card/book-card.component.html
+++ b/booklore-ui/src/app/features/book/components/book-browser/book-card/book-card.component.html
@@ -49,25 +49,36 @@
(onChange)="toggleSelection($event)">
}
-
- @if (progressPercentage !== null) {
-
-
- }
- @if (koProgressPercentage !== null) {
-
-
- }
+
+ @if (progressPercentage !== null) {
+
+
+ }
+ @if (koProgressPercentage !== null) {
+
+
+ }
+ @if (koboProgressPercentage !== null) {
+
+
+ }
+
diff --git a/booklore-ui/src/app/features/book/components/book-browser/book-card/book-card.component.scss b/booklore-ui/src/app/features/book/components/book-browser/book-card/book-card.component.scss
index 773da19d..ae19f77c 100644
--- a/booklore-ui/src/app/features/book/components/book-browser/book-card/book-card.component.scss
+++ b/booklore-ui/src/app/features/book/components/book-browser/book-card/book-card.component.scss
@@ -123,10 +123,19 @@
visibility: visible;
}
-.cover-progress-bar,
-.cover-progress-bar-ko-both,
-.cover-progress-bar-ko-only {
+.cover-progress-bar-container {
position: absolute;
+ bottom: 0;
+ left: 0;
+ right: 0;
+ height: 7.5px;
+ z-index: 2;
+ display: flex;
+ flex-direction: column;
+ justify-content: flex-end;
+}
+
+.cover-progress-bar {
left: 0;
right: 0;
height: 2.5px;
@@ -134,18 +143,6 @@
opacity: 0.9;
}
-.cover-progress-bar {
- bottom: 2.5px;
-}
-
-.cover-progress-bar-ko-both {
- bottom: 0;
-}
-
-.cover-progress-bar-ko-only {
- bottom: 2.5px;
-}
-
.series-number-overlay {
position: absolute;
top: 8px;
@@ -231,7 +228,15 @@
background-color: #8b5cf6;
}
-::ng-deep p-progressbar {
+::ng-deep .progress-incomplete-kobo .p-progressbar-value {
+ background-color: #bf0000;
+}
+
+::ng-deep .progress-complete-kobo .p-progressbar-value {
+ background-color: #f65c9c;
+}
+
+::ng-deep .cover-progress-bar {
--p-progressbar-border-radius: 0 !important;
}
diff --git a/booklore-ui/src/app/features/book/components/book-browser/book-card/book-card.component.ts b/booklore-ui/src/app/features/book/components/book-browser/book-card/book-card.component.ts
index a3ba42b2..bcc39ee6 100644
--- a/booklore-ui/src/app/features/book/components/book-browser/book-card/book-card.component.ts
+++ b/booklore-ui/src/app/features/book/components/book-browser/book-card/book-card.component.ts
@@ -110,6 +110,13 @@ export class BookCardComponent implements OnInit, OnChanges, OnDestroy {
return null;
}
+ get koboProgressPercentage(): number | null {
+ if (this.book.koboProgress?.percentage != null) {
+ return this.book.koboProgress.percentage;
+ }
+ return null;
+ }
+
get displayTitle(): string | undefined {
return (this.isSeriesCollapsed && this.book.metadata?.seriesName) ? this.book.metadata?.seriesName : this.book.metadata?.title;
}
diff --git a/booklore-ui/src/app/features/metadata/component/book-metadata-center/metadata-viewer/metadata-viewer.component.html b/booklore-ui/src/app/features/metadata/component/book-metadata-center/metadata-viewer/metadata-viewer.component.html
index 149ad793..efa1c635 100644
--- a/booklore-ui/src/app/features/metadata/component/book-metadata-center/metadata-viewer/metadata-viewer.component.html
+++ b/booklore-ui/src/app/features/metadata/component/book-metadata-center/metadata-viewer/metadata-viewer.component.html
@@ -19,32 +19,46 @@
}
- @let progress = getProgressPercent(book);
- @if (progress !== null) {
-
- }
+
+ @let progress = getProgressPercent(book);
+ @if (progress !== null) {
+
+ }
- @if (getKoProgressPercent(book) !== null) {
-
-
- }
+ @if (getKoProgressPercent(book) !== null) {
+
+
+ }
+
+ @if (getKoboProgressPercent(book) !== null) {
+
+
+ }
+
@if (navigationState$ | async) {
diff --git a/booklore-ui/src/app/features/metadata/component/book-metadata-center/metadata-viewer/metadata-viewer.component.scss b/booklore-ui/src/app/features/metadata/component/book-metadata-center/metadata-viewer/metadata-viewer.component.scss
index 0bce931e..1f1db605 100644
--- a/booklore-ui/src/app/features/metadata/component/book-metadata-center/metadata-viewer/metadata-viewer.component.scss
+++ b/booklore-ui/src/app/features/metadata/component/book-metadata-center/metadata-viewer/metadata-viewer.component.scss
@@ -63,28 +63,28 @@
z-index: 2;
}
-.cover-progress-bar,
-.cover-progress-bar-ko-both,
-.cover-progress-bar-ko-only {
+.cover-progress-bar-container {
position: absolute;
+ bottom: 0;
left: 0;
right: 0;
z-index: 2;
- pointer-events: none;
+ border-radius: 9999px;
+ overflow: hidden;
+ display: flex;
+ flex-direction: column;
+ height: calc(var(--progress-count, 0) * 6px);
}
.cover-progress-bar {
- bottom: 0;
+ z-index: 2;
+ pointer-events: none;
+ height: 6px;
+ flex-shrink: 0;
}
-.cover-progress-bar-ko-both {
- bottom: 0;
- height: 12px;
- z-index: 3;
-}
-
-.cover-progress-bar-ko-only {
- bottom: 0;
+::ng-deep .cover-progress-bar {
+ --p-progressbar-border-radius: 0 !important;
}
::ng-deep .progress-incomplete .p-progressbar-value {
@@ -96,11 +96,19 @@
}
::ng-deep .progress-incomplete-ko .p-progressbar-value {
- background-color: var(--primary-text-color);
+ background-color: #fbbf24;
}
::ng-deep .progress-complete-ko .p-progressbar-value {
- background-color: var(--primary-hover-color);
+ background-color: #8b5cf6;
+}
+
+::ng-deep .progress-incomplete-kobo .p-progressbar-value {
+ background-color: #bf0000;
+}
+
+::ng-deep .progress-complete-kobo .p-progressbar-value {
+ background-color: #f65c9c;
}
.info-section {
diff --git a/booklore-ui/src/app/features/metadata/component/book-metadata-center/metadata-viewer/metadata-viewer.component.ts b/booklore-ui/src/app/features/metadata/component/book-metadata-center/metadata-viewer/metadata-viewer.component.ts
index 462779b5..8a379004 100644
--- a/booklore-ui/src/app/features/metadata/component/book-metadata-center/metadata-viewer/metadata-viewer.component.ts
+++ b/booklore-ui/src/app/features/metadata/component/book-metadata-center/metadata-viewer/metadata-viewer.component.ts
@@ -659,6 +659,21 @@ export class MetadataViewerComponent implements OnInit, OnChanges {
return null;
}
+ getKoboProgressPercent(book: Book): number | null {
+ if (book.koboProgress?.percentage != null) {
+ return book.koboProgress.percentage;
+ }
+ return null;
+ }
+
+ getProgressCount(book: Book): number {
+ let count = 0;
+ if (this.getProgressPercent(book) !== null) count++;
+ if (this.getKoProgressPercent(book) !== null) count++;
+ if (this.getKoboProgressPercent(book) !== null) count++;
+ return count;
+ }
+
getFileExtension(filePath?: string): string | null {
if (!filePath) return null;
const parts = filePath.split('.');
diff --git a/booklore-ui/src/app/features/stats/service/reading-dna-chart.service.ts b/booklore-ui/src/app/features/stats/service/reading-dna-chart.service.ts
index 3bb51bf4..8246de8b 100644
--- a/booklore-ui/src/app/features/stats/service/reading-dna-chart.service.ts
+++ b/booklore-ui/src/app/features/stats/service/reading-dna-chart.service.ts
@@ -390,7 +390,8 @@ export class ReadingDNAChartService implements OnDestroy {
book.epubProgress?.percentage || 0,
book.pdfProgress?.percentage || 0,
book.cbxProgress?.percentage || 0,
- book.koreaderProgress?.percentage || 0
+ book.koreaderProgress?.percentage || 0,
+ book.koboProgress?.percentage || 0
);
return progress > 50;
});
diff --git a/booklore-ui/src/app/features/stats/service/reading-habits-chart.service.ts b/booklore-ui/src/app/features/stats/service/reading-habits-chart.service.ts
index fcc98080..9b3a60e1 100644
--- a/booklore-ui/src/app/features/stats/service/reading-habits-chart.service.ts
+++ b/booklore-ui/src/app/features/stats/service/reading-habits-chart.service.ts
@@ -309,7 +309,8 @@ export class ReadingHabitsChartService implements OnDestroy {
book.epubProgress?.percentage || 0,
book.pdfProgress?.percentage || 0,
book.cbxProgress?.percentage || 0,
- book.koreaderProgress?.percentage || 0
+ book.koreaderProgress?.percentage || 0,
+ book.koboProgress?.percentage || 0
);
return progress > 0 && progress < 100;
});
diff --git a/booklore-ui/src/app/features/stats/service/reading-progress-chart-service.ts b/booklore-ui/src/app/features/stats/service/reading-progress-chart-service.ts
index 07e0ad9b..90794933 100644
--- a/booklore-ui/src/app/features/stats/service/reading-progress-chart-service.ts
+++ b/booklore-ui/src/app/features/stats/service/reading-progress-chart-service.ts
@@ -228,6 +228,7 @@ export class ReadingProgressChartService implements OnDestroy {
if (book.epubProgress?.percentage) return book.epubProgress.percentage;
if (book.cbxProgress?.percentage) return book.cbxProgress.percentage;
if (book.koreaderProgress?.percentage) return book.koreaderProgress.percentage;
+ if (book.koboProgress?.percentage) return book.koboProgress.percentage;
return 0;
}
diff --git a/booklore-ui/src/app/features/stats/service/reading-velocity-chart.service.ts b/booklore-ui/src/app/features/stats/service/reading-velocity-chart.service.ts
index 09f842a7..250c93f2 100644
--- a/booklore-ui/src/app/features/stats/service/reading-velocity-chart.service.ts
+++ b/booklore-ui/src/app/features/stats/service/reading-velocity-chart.service.ts
@@ -283,8 +283,9 @@ export class ReadingVelocityChartService implements OnDestroy {
const pdfProgress = book.pdfProgress?.percentage || 0;
const cbxProgress = book.cbxProgress?.percentage || 0;
const koreaderProgress = book.koreaderProgress?.percentage || 0;
+ const koboProgress = book.koboProgress?.percentage || 0;
- return Math.max(epubProgress, pdfProgress, cbxProgress, koreaderProgress) / 100;
+ return Math.max(epubProgress, pdfProgress, cbxProgress, koreaderProgress, koboProgress) / 100;
}
private calculateAverageRating(books: Book[]): number {