feat(cover): give books with both media separate ebook and audiobook covers

Keep one cover slot per medium and show the one each surface needs: the
library's shape for the face, square art on audio screens, the ebook slot
for Kobo and OPDS. Legacy covers convert on upgrade or on first read, and a
write that names no slot keeps working for released iOS builds. Also read
the dev client origin from one constant.
This commit is contained in:
neon
2026-09-23 19:55:25 +00:00
parent 4b86ff73cf
commit e28bd67fa3
298 changed files with 34879 additions and 2448 deletions
+40
View File
@@ -51,6 +51,8 @@ export const E2E_SUITES = Object.freeze({
prepareDedicatedDatabase: true,
useDedicatedDatabase: true,
changedPaths: [
"server/src/modules/book-cover-store/**",
"server/src/modules/metadata/cover-slot-reconciler.service.ts",
"server/src/modules/scanner/**",
"server/test/scanner-scenarios.e2e-spec.ts",
"server/test/e2e/scanner/**",
@@ -69,6 +71,8 @@ export const E2E_SUITES = Object.freeze({
prepareDedicatedDatabase: true,
useDedicatedDatabase: true,
changedPaths: [
"server/src/modules/book-cover-store/**",
"server/src/modules/metadata/cover-slot-reconciler.service.ts",
"server/src/modules/scanner/**",
"server/test/scanner-file-operations.e2e-spec.ts",
"server/test/e2e/scanner/**",
@@ -133,6 +137,7 @@ export const E2E_SUITES = Object.freeze({
prepareDedicatedDatabase: true,
useDedicatedDatabase: true,
changedPaths: [
"server/src/modules/book-cover-store/**",
"server/src/modules/book-dock/**",
"server/src/modules/upload/**",
"server/src/modules/metadata/**",
@@ -152,6 +157,7 @@ export const E2E_SUITES = Object.freeze({
prepareDedicatedDatabase: true,
useDedicatedDatabase: true,
changedPaths: [
"server/src/modules/book-cover-store/**",
"server/src/modules/book/**",
"server/src/modules/library/**",
"server/src/modules/file-write/**",
@@ -180,6 +186,7 @@ export const E2E_SUITES = Object.freeze({
"server/src/modules/metadata-fetch/**",
"server/src/modules/metadata-preferences/**",
"server/src/modules/cover/**",
"server/src/modules/book-cover-store/**",
"server/src/modules/scanner/**",
"server/src/modules/library/**",
"server/src/modules/auth/**",
@@ -203,6 +210,7 @@ export const E2E_SUITES = Object.freeze({
useDedicatedDatabase: true,
changedPaths: [
"server/src/modules/migration/**",
"server/src/modules/book-cover-store/**",
"server/test/migration-booklore.e2e-spec.ts",
"server/test/e2e/migration-booklore/**",
".github/workflows/e2e-runner.yml",
@@ -259,7 +267,9 @@ export const E2E_SUITES = Object.freeze({
useDedicatedDatabase: true,
changedPaths: [
"server/src/**",
"server/src/modules/book-cover-store/**",
"server/test/authorization-matrix.e2e-spec.ts",
"server/test/e2e/slot-cover-artifacts.ts",
"server/test/e2e/authorization-matrix/**",
".github/workflows/e2e-runner.yml",
...SHARED_TYPES_PATHS,
@@ -442,11 +452,13 @@ export const E2E_SUITES = Object.freeze({
useDedicatedDatabase: true,
changedPaths: [
"server/src/modules/book/**",
"server/src/modules/book-cover-store/**",
"server/src/modules/library/**",
"server/src/modules/collection/**",
"server/src/modules/auth/**",
"server/src/modules/user/**",
"server/test/book-api-contract.e2e-spec.ts",
"server/test/e2e/slot-cover-artifacts.ts",
"server/test/e2e/book-api-contract/**",
...SHARED_TYPES_PATHS,
...SHARED_DB_AND_HELPER_PATHS,
@@ -504,15 +516,38 @@ export const E2E_SUITES = Object.freeze({
useDedicatedDatabase: true,
changedPaths: [
"server/src/modules/library/**",
"server/src/modules/book-cover-store/**",
"server/src/modules/auth/**",
"server/src/modules/user/**",
"server/src/modules/role/**",
"server/test/library-admin-workflows.e2e-spec.ts",
"server/test/e2e/slot-cover-artifacts.ts",
"server/test/e2e/library/**",
...SHARED_TYPES_PATHS,
...SHARED_DB_AND_HELPER_PATHS,
],
},
"missing-resources": {
id: "missing-resources",
name: "Missing Resources",
timeout: 60,
lane: "full",
description: "Missing Resources cover sweep and cleanup suite",
vitestTarget: "test/missing-resources.e2e-spec.ts",
junitOutput: `${TEST_RESULTS_DIR}/missing-resources-e2e-junit.xml`,
prepareDedicatedDatabase: true,
useDedicatedDatabase: true,
changedPaths: [
"server/src/modules/maintenance/**",
"server/src/modules/book-cover-store/**",
"server/src/modules/book/**",
"server/src/modules/library/**",
"server/test/missing-resources.e2e-spec.ts",
"server/test/e2e/metadata-write/**",
...SHARED_TYPES_PATHS,
...SHARED_DB_AND_HELPER_PATHS,
],
},
"reader-format-delivery": {
id: "reader-format-delivery",
name: "Reader Format Delivery",
@@ -548,6 +583,7 @@ export const E2E_SUITES = Object.freeze({
changedPaths: [
"server/src/modules/opds/**",
"server/src/modules/book/**",
"server/src/modules/book-cover-store/**",
"server/src/modules/library/**",
"server/src/modules/collection/**",
"server/src/modules/lens/**",
@@ -578,6 +614,7 @@ export const E2E_SUITES = Object.freeze({
"server/src/modules/library/**",
"server/src/modules/auth/**",
"server/src/modules/cover/**",
"server/src/modules/book-cover-store/**",
"server/src/modules/scanner/**",
"server/src/modules/seed/**",
"server/test/email-lifecycle.e2e-spec.ts",
@@ -848,6 +885,7 @@ export const E2E_SUITES = Object.freeze({
changedPaths: [
"server/src/modules/kobo/**",
"server/src/modules/cover/**",
"server/src/modules/book-cover-store/**",
"server/src/modules/metadata/**",
"server/test/kobo-cover-identity.e2e-spec.ts",
"server/test/e2e/reader-state-isolation/**",
@@ -888,6 +926,8 @@ export const E2E_SUITES = Object.freeze({
prepareDedicatedDatabase: true,
useDedicatedDatabase: true,
changedPaths: [
"server/src/modules/book-cover-store/**",
"server/src/modules/metadata/cover-slot-reconciler.service.ts",
"server/src/modules/library/**",
"server/src/modules/file-write/**",
"server/src/modules/scanner/**",