Commit Graph

311 Commits

Author SHA1 Message Date
neon 402d1cde5d fix(smart-scope): preserve draft filters while editing (#54)
Keep incomplete root filters visible in the SmartScope editor.

This lets users choose a field before setting an operator or value.

Fixes #52
2026-05-19 10:26:29 -06:00
neon 8abde907d8 feat(reader): add footer modes, wake lock, keyboard shortcuts, and go-to input
- Add tap-to-cycle footer modes (pages, time/session, chapter) along with elapsed reading time and chapter progress on the slider
- Prevent screen dimming during reading using the Wake Lock API
- Add keyboard shortcuts (t/s/b/f/Esc/?/Home/End) with an integrated help modal
- Add go-to-location support (page number or percentage) and a resume-reading toast on book open
2026-05-18 22:02:49 -06:00
neon fabd1747d3 fix: add per-org upload pattern defaults for book_per_folder mode (#33)
* fix(settings): add per-org upload defaults for book_per_folder mode

* ci: add maintainer-gated PR GHCR image publish

---------

Signed-off-by: neon <18559658+neonsolstice@users.noreply.github.com>
2026-05-18 17:12:13 -06:00
neon 8b70c55604 fix(collections): restore add-to-collection from quick view (#39)
Close the quick-view sheet before dispatching add or delete actions.
Ensure the collection sheet opens reliably from the side panel.

Add regression tests for quick-view and table-shell action flow.
Expand collection controller and service edge-case coverage for this path.

Fixes #36
2026-05-18 15:00:22 -06:00
neon 4cb0149380 feat(settings): add series number badge to book cover card overlay (#37)
Series position badge (#N) rendered in the top-right corner of cover
cards, sharing a flex-column container with the existing lock-status
badge. Shown only when seriesIndex is non-null. Whole numbers strip the
decimal (3.0 -> #3); fractional values display as-is (1.5 -> #1.5).
Hovering the badge shows a tooltip with the full series name and position.
Enabled by default in Appearance -> Card Overlays.

Closes #32
2026-05-18 13:48:38 -06:00
neon 5524cd9d0d fix(email): add skip-TLS-verification option and surface provider delete errors (#35)
Node.js inside Docker validates the full TLS certificate chain against its bundled
CA store. When the chain cannot be verified (e.g. outdated CA bundle, self-signed
cert, or Let's Encrypt chain not trusted), nodemailer reports a misleading error
like "certificate has expired". Add a per-provider tlsRejectUnauthorized flag
(default: true) that passes tls.rejectUnauthorized=false to nodemailer when
disabled, letting self-hosted SMTP servers opt out of cert verification. A visible
warning is shown in the provider form whenever the flag is turned off.

The delete provider API already returned a clear 400 message explaining that the
system designation must be removed first, but the frontend threw a hardcoded
"Failed to delete provider" string and never read the response body. Fix the
composable to parse and rethrow the actual API error message. Also disable the
delete button for system providers with a tooltip stating the constraint, so users
cannot trigger the error in the first place.

Adds tlsRejectUnauthorized boolean column (NOT NULL DEFAULT true) to
email_providers via Drizzle migration 0004.

Closes #26
2026-05-18 12:38:22 -06:00
neon 2dea6915d4 chore(server): increase currently reading widget limit to 10
Adjust the currently reading cap to tune dashboard density without changing feature scope.
2026-05-18 04:26:39 +00:00
neon 69f69febb2 feat(book): add highlights tab with filters, export, and pagination 2026-05-18 03:52:17 +00:00
neon 9f15d0955a feat(reading-log): implement end-to-end reading log feature 2026-05-17 01:42:41 -06:00
neon eb9b714ecb feat: add full-stack achievements system
- add achievement schema, migrations, evaluators, APIs, and backfill support on the server
- add achievements UI, composables, toast utilities, and tests on the client
- add shared achievement/auth/notification type updates
2026-05-16 15:50:42 +00:00
neon 9fdb3f46bb chore(book): unify rating star colors across views 2026-05-15 12:20:09 -06:00
neon c4f9b289f6 fix(client): disable pwa service worker in dev 2026-05-14 23:48:20 -06:00
dependabot[bot] 2eb6ee4cee chore(deps): bump the development-dependencies group with 19 updates (#14)
* chore(deps): bump the development-dependencies group with 19 updates

Bumps the development-dependencies group with 19 updates:

| Package | From | To |
| --- | --- | --- |
| [@semantic-release/release-notes-generator](https://github.com/semantic-release/release-notes-generator) | `14.1.0` | `14.1.1` |
| [@types/jsdom](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/jsdom) | `28.0.1` | `28.0.3` |
| [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) | `25.6.0` | `25.8.0` |
| [@vitest/coverage-v8](https://github.com/vitest-dev/vitest/tree/HEAD/packages/coverage-v8) | `4.1.5` | `4.1.6` |
| [@vitest/eslint-plugin](https://github.com/vitest-dev/eslint-plugin-vitest) | `1.6.16` | `1.6.17` |
| [eslint](https://github.com/eslint/eslint) | `10.2.1` | `10.3.0` |
| [eslint-plugin-oxlint](https://github.com/oxc-project/eslint-plugin-oxlint) | `1.62.0` | `1.64.0` |
| [eslint-plugin-vue](https://github.com/vuejs/eslint-plugin-vue) | `10.9.0` | `10.9.1` |
| [jiti](https://github.com/unjs/jiti) | `2.6.1` | `2.7.0` |
| [oxlint](https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint) | `1.62.0` | `1.64.0` |
| [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) | `8.0.10` | `8.0.13` |
| [vite-plugin-vue-devtools](https://github.com/vuejs/devtools/tree/HEAD/packages/vite) | `8.1.1` | `8.1.2` |
| [vitest](https://github.com/vitest-dev/vitest/tree/HEAD/packages/vitest) | `4.1.5` | `4.1.6` |
| [vue-tsc](https://github.com/vuejs/language-tools/tree/HEAD/packages/tsc) | `3.2.7` | `3.2.9` |
| [@nestjs/testing](https://github.com/nestjs/nest/tree/HEAD/packages/testing) | `11.1.19` | `11.1.21` |
| [@swc/core](https://github.com/swc-project/swc/tree/HEAD/packages/core) | `1.15.32` | `1.15.33` |
| [globals](https://github.com/sindresorhus/globals) | `17.5.0` | `17.6.0` |
| [tsx](https://github.com/privatenumber/tsx) | `4.21.0` | `4.22.0` |
| [typescript-eslint](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/typescript-eslint) | `8.59.1` | `8.59.3` |


Updates `@semantic-release/release-notes-generator` from 14.1.0 to 14.1.1
- [Release notes](https://github.com/semantic-release/release-notes-generator/releases)
- [Commits](https://github.com/semantic-release/release-notes-generator/compare/v14.1.0...v14.1.1)

Updates `@types/jsdom` from 28.0.1 to 28.0.3
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/jsdom)

Updates `@types/node` from 25.6.0 to 25.8.0
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

Updates `@vitest/coverage-v8` from 4.1.5 to 4.1.6
- [Release notes](https://github.com/vitest-dev/vitest/releases)
- [Commits](https://github.com/vitest-dev/vitest/commits/v4.1.6/packages/coverage-v8)

Updates `@vitest/eslint-plugin` from 1.6.16 to 1.6.17
- [Release notes](https://github.com/vitest-dev/eslint-plugin-vitest/releases)
- [Commits](https://github.com/vitest-dev/eslint-plugin-vitest/compare/v1.6.16...v1.6.17)

Updates `eslint` from 10.2.1 to 10.3.0
- [Release notes](https://github.com/eslint/eslint/releases)
- [Commits](https://github.com/eslint/eslint/compare/v10.2.1...v10.3.0)

Updates `eslint-plugin-oxlint` from 1.62.0 to 1.64.0
- [Release notes](https://github.com/oxc-project/eslint-plugin-oxlint/releases)
- [Commits](https://github.com/oxc-project/eslint-plugin-oxlint/compare/v1.62.0...v1.64.0)

Updates `eslint-plugin-vue` from 10.9.0 to 10.9.1
- [Release notes](https://github.com/vuejs/eslint-plugin-vue/releases)
- [Changelog](https://github.com/vuejs/eslint-plugin-vue/blob/master/CHANGELOG.md)
- [Commits](https://github.com/vuejs/eslint-plugin-vue/compare/v10.9.0...v10.9.1)

Updates `jiti` from 2.6.1 to 2.7.0
- [Release notes](https://github.com/unjs/jiti/releases)
- [Changelog](https://github.com/unjs/jiti/blob/main/CHANGELOG.md)
- [Commits](https://github.com/unjs/jiti/compare/v2.6.1...v2.7.0)

Updates `oxlint` from 1.62.0 to 1.64.0
- [Release notes](https://github.com/oxc-project/oxc/releases)
- [Changelog](https://github.com/oxc-project/oxc/blob/main/npm/oxlint/CHANGELOG.md)
- [Commits](https://github.com/oxc-project/oxc/commits/oxlint_v1.64.0/npm/oxlint)

Updates `vite` from 8.0.10 to 8.0.13
- [Release notes](https://github.com/vitejs/vite/releases)
- [Changelog](https://github.com/vitejs/vite/blob/main/packages/vite/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite/commits/v8.0.13/packages/vite)

Updates `vite-plugin-vue-devtools` from 8.1.1 to 8.1.2
- [Release notes](https://github.com/vuejs/devtools/releases)
- [Commits](https://github.com/vuejs/devtools/commits/v8.1.2/packages/vite)

Updates `vitest` from 4.1.5 to 4.1.6
- [Release notes](https://github.com/vitest-dev/vitest/releases)
- [Commits](https://github.com/vitest-dev/vitest/commits/v4.1.6/packages/vitest)

Updates `vue-tsc` from 3.2.7 to 3.2.9
- [Release notes](https://github.com/vuejs/language-tools/releases)
- [Changelog](https://github.com/vuejs/language-tools/blob/master/CHANGELOG.md)
- [Commits](https://github.com/vuejs/language-tools/commits/v3.2.9/packages/tsc)

Updates `@nestjs/testing` from 11.1.19 to 11.1.21
- [Release notes](https://github.com/nestjs/nest/releases)
- [Commits](https://github.com/nestjs/nest/commits/v11.1.21/packages/testing)

Updates `@swc/core` from 1.15.32 to 1.15.33
- [Release notes](https://github.com/swc-project/swc/releases)
- [Changelog](https://github.com/swc-project/swc/blob/main/CHANGELOG.md)
- [Commits](https://github.com/swc-project/swc/commits/v1.15.33/packages/core)

Updates `globals` from 17.5.0 to 17.6.0
- [Release notes](https://github.com/sindresorhus/globals/releases)
- [Commits](https://github.com/sindresorhus/globals/compare/v17.5.0...v17.6.0)

Updates `tsx` from 4.21.0 to 4.22.0
- [Release notes](https://github.com/privatenumber/tsx/releases)
- [Changelog](https://github.com/privatenumber/tsx/blob/master/release.config.cjs)
- [Commits](https://github.com/privatenumber/tsx/compare/v4.21.0...v4.22.0)

Updates `typescript-eslint` from 8.59.1 to 8.59.3
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/typescript-eslint/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.59.3/packages/typescript-eslint)

---
updated-dependencies:
- dependency-name: "@semantic-release/release-notes-generator"
  dependency-version: 14.1.1
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: development-dependencies
- dependency-name: "@types/jsdom"
  dependency-version: 28.0.3
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: development-dependencies
- dependency-name: "@types/node"
  dependency-version: 25.8.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: development-dependencies
- dependency-name: "@vitest/coverage-v8"
  dependency-version: 4.1.6
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: development-dependencies
- dependency-name: "@vitest/eslint-plugin"
  dependency-version: 1.6.17
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: development-dependencies
- dependency-name: eslint
  dependency-version: 10.3.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: development-dependencies
- dependency-name: eslint-plugin-oxlint
  dependency-version: 1.64.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: development-dependencies
- dependency-name: eslint-plugin-vue
  dependency-version: 10.9.1
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: development-dependencies
- dependency-name: jiti
  dependency-version: 2.7.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: development-dependencies
- dependency-name: oxlint
  dependency-version: 1.64.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: development-dependencies
- dependency-name: vite
  dependency-version: 8.0.13
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: development-dependencies
- dependency-name: vite-plugin-vue-devtools
  dependency-version: 8.1.2
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: development-dependencies
- dependency-name: vitest
  dependency-version: 4.1.6
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: development-dependencies
- dependency-name: vue-tsc
  dependency-version: 3.2.9
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: development-dependencies
- dependency-name: "@nestjs/testing"
  dependency-version: 11.1.21
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: development-dependencies
- dependency-name: "@swc/core"
  dependency-version: 1.15.33
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: development-dependencies
- dependency-name: globals
  dependency-version: 17.6.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: development-dependencies
- dependency-name: tsx
  dependency-version: 4.22.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: development-dependencies
- dependency-name: typescript-eslint
  dependency-version: 8.59.3
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: development-dependencies
...

Signed-off-by: dependabot[bot] <support@github.com>

* fix(server): narrow fs stat type for strict typecheck

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: neon <18559658+neonsolstice@users.noreply.github.com>
2026-05-14 22:21:12 -06:00
dependabot[bot] 4566a22512 chore(deps): bump the production-dependencies group with 15 updates (#13)
Bumps the production-dependencies group with 15 updates:

| Package | From | To |
| --- | --- | --- |
| [@tailwindcss/vite](https://github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/@tailwindcss-vite) | `4.2.4` | `4.3.0` |
| [dompurify](https://github.com/cure53/DOMPurify) | `3.4.2` | `3.4.3` |
| [reka-ui](https://github.com/unovue/reka-ui) | `2.9.6` | `2.9.7` |
| [tailwind-merge](https://github.com/dcastil/tailwind-merge) | `3.5.0` | `3.6.0` |
| [tailwindcss](https://github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/tailwindcss) | `4.2.4` | `4.3.0` |
| [vue](https://github.com/vuejs/core) | `3.5.33` | `3.5.34` |
| [vue-router](https://github.com/vuejs/router) | `5.0.6` | `5.0.7` |
| [vue-virtual-scroller](https://github.com/Akryum/vue-virtual-scroller) | `3.0.2` | `3.0.3` |
| [@nestjs/common](https://github.com/nestjs/nest/tree/HEAD/packages/common) | `11.1.19` | `11.1.21` |
| [@nestjs/core](https://github.com/nestjs/nest/tree/HEAD/packages/core) | `11.1.19` | `11.1.21` |
| [@nestjs/platform-fastify](https://github.com/nestjs/nest/tree/HEAD/packages/platform-fastify) | `11.1.19` | `11.1.21` |
| [@nestjs/platform-socket.io](https://github.com/nestjs/nest/tree/HEAD/packages/platform-socket.io) | `11.1.19` | `11.1.21` |
| [@nestjs/websockets](https://github.com/nestjs/nest/tree/HEAD/packages/websockets) | `11.1.19` | `11.1.21` |
| [fast-xml-parser](https://github.com/NaturalIntelligence/fast-xml-parser) | `5.7.2` | `5.8.0` |
| [zod](https://github.com/colinhacks/zod) | `4.4.1` | `4.4.3` |


Updates `@tailwindcss/vite` from 4.2.4 to 4.3.0
- [Release notes](https://github.com/tailwindlabs/tailwindcss/releases)
- [Changelog](https://github.com/tailwindlabs/tailwindcss/blob/main/CHANGELOG.md)
- [Commits](https://github.com/tailwindlabs/tailwindcss/commits/v4.3.0/packages/@tailwindcss-vite)

Updates `dompurify` from 3.4.2 to 3.4.3
- [Release notes](https://github.com/cure53/DOMPurify/releases)
- [Commits](https://github.com/cure53/DOMPurify/compare/3.4.2...3.4.3)

Updates `reka-ui` from 2.9.6 to 2.9.7
- [Release notes](https://github.com/unovue/reka-ui/releases)
- [Commits](https://github.com/unovue/reka-ui/compare/v2.9.6...v2.9.7)

Updates `tailwind-merge` from 3.5.0 to 3.6.0
- [Release notes](https://github.com/dcastil/tailwind-merge/releases)
- [Commits](https://github.com/dcastil/tailwind-merge/compare/v3.5.0...v3.6.0)

Updates `tailwindcss` from 4.2.4 to 4.3.0
- [Release notes](https://github.com/tailwindlabs/tailwindcss/releases)
- [Changelog](https://github.com/tailwindlabs/tailwindcss/blob/main/CHANGELOG.md)
- [Commits](https://github.com/tailwindlabs/tailwindcss/commits/v4.3.0/packages/tailwindcss)

Updates `vue` from 3.5.33 to 3.5.34
- [Release notes](https://github.com/vuejs/core/releases)
- [Changelog](https://github.com/vuejs/core/blob/main/CHANGELOG.md)
- [Commits](https://github.com/vuejs/core/compare/v3.5.33...v3.5.34)

Updates `vue-router` from 5.0.6 to 5.0.7
- [Release notes](https://github.com/vuejs/router/releases)
- [Commits](https://github.com/vuejs/router/compare/v5.0.6...v5.0.7)

Updates `vue-virtual-scroller` from 3.0.2 to 3.0.3
- [Release notes](https://github.com/Akryum/vue-virtual-scroller/releases)
- [Changelog](https://github.com/Akryum/vue-virtual-scroller/blob/master/CHANGELOG.md)
- [Commits](https://github.com/Akryum/vue-virtual-scroller/compare/v3.0.2...v3.0.3)

Updates `@nestjs/common` from 11.1.19 to 11.1.21
- [Release notes](https://github.com/nestjs/nest/releases)
- [Commits](https://github.com/nestjs/nest/commits/v11.1.21/packages/common)

Updates `@nestjs/core` from 11.1.19 to 11.1.21
- [Release notes](https://github.com/nestjs/nest/releases)
- [Commits](https://github.com/nestjs/nest/commits/v11.1.21/packages/core)

Updates `@nestjs/platform-fastify` from 11.1.19 to 11.1.21
- [Release notes](https://github.com/nestjs/nest/releases)
- [Commits](https://github.com/nestjs/nest/commits/v11.1.21/packages/platform-fastify)

Updates `@nestjs/platform-socket.io` from 11.1.19 to 11.1.21
- [Release notes](https://github.com/nestjs/nest/releases)
- [Commits](https://github.com/nestjs/nest/commits/v11.1.21/packages/platform-socket.io)

Updates `@nestjs/websockets` from 11.1.19 to 11.1.21
- [Release notes](https://github.com/nestjs/nest/releases)
- [Commits](https://github.com/nestjs/nest/commits/v11.1.21/packages/websockets)

Updates `fast-xml-parser` from 5.7.2 to 5.8.0
- [Release notes](https://github.com/NaturalIntelligence/fast-xml-parser/releases)
- [Changelog](https://github.com/NaturalIntelligence/fast-xml-parser/blob/master/CHANGELOG.md)
- [Commits](https://github.com/NaturalIntelligence/fast-xml-parser/compare/v5.7.2...v5.8.0)

Updates `zod` from 4.4.1 to 4.4.3
- [Release notes](https://github.com/colinhacks/zod/releases)
- [Commits](https://github.com/colinhacks/zod/compare/v4.4.1...v4.4.3)

---
updated-dependencies:
- dependency-name: "@tailwindcss/vite"
  dependency-version: 4.3.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: production-dependencies
- dependency-name: dompurify
  dependency-version: 3.4.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: production-dependencies
- dependency-name: reka-ui
  dependency-version: 2.9.7
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: production-dependencies
- dependency-name: tailwind-merge
  dependency-version: 3.6.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: production-dependencies
- dependency-name: tailwindcss
  dependency-version: 4.3.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: production-dependencies
- dependency-name: vue
  dependency-version: 3.5.34
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: production-dependencies
- dependency-name: vue-router
  dependency-version: 5.0.7
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: production-dependencies
- dependency-name: vue-virtual-scroller
  dependency-version: 3.0.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: production-dependencies
- dependency-name: "@nestjs/common"
  dependency-version: 11.1.21
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: production-dependencies
- dependency-name: "@nestjs/core"
  dependency-version: 11.1.21
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: production-dependencies
- dependency-name: "@nestjs/platform-fastify"
  dependency-version: 11.1.21
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: production-dependencies
- dependency-name: "@nestjs/platform-socket.io"
  dependency-version: 11.1.21
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: production-dependencies
- dependency-name: "@nestjs/websockets"
  dependency-version: 11.1.21
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: production-dependencies
- dependency-name: fast-xml-parser
  dependency-version: 5.8.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: production-dependencies
- dependency-name: zod
  dependency-version: 4.4.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: production-dependencies
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: neon <18559658+neonsolstice@users.noreply.github.com>
2026-05-14 21:44:19 -06:00
neon da5d6cb31f fix(csp): allow Google Fonts, blob workers, and jsDelivr in CSP directives 2026-05-15 01:15:28 +00:00
neon 3138cf3a4d fix(security): complete sanitizeLogValue sweep, DOMParser stripHtml, least-privilege CI permissions, pin Dockerfile image 2026-05-15 00:15:23 +00:00
neon 86147ead2c fix(reader): apply theme bg unconditionally to fix iOS dark mode override
On iOS (Chrome/Safari) in system Dark Mode, the epub iframe's
prefers-color-scheme:dark media query always matched regardless of
the in-app light/dark toggle, forcing a dark background even when the
user selected Light mode.

Three changes in generateCSS():
- Set color-scheme to 'light' or 'dark' (not 'light dark') based on
  isDark, so the browser and epub-internal light-dark() calls respect
  the app setting rather than the OS preference.
- Remove the nested @media (prefers-color-scheme: dark) block that was
  overriding mode.fg/link with OS-based dark values.
- Replace both @media screen and (prefers-color-scheme: light/dark)
  background blocks with a single unconditional forceBg block driven
  by isDark.value, so background colors are always app-controlled.
2026-05-14 22:51:16 +00:00
neon ee1d98386d feat(settings): improve migration source validation workflow
Improve migration setup feedback so operators can validate credentials and media paths with actionable status instead of ambiguous failures. Keep users on their current setup step while saving to avoid accidental context switches during preflight configuration.
2026-05-14 22:11:57 +00:00
neon 57960efecb feat(reader): add in-reader text translation with Google/Azure fallback for EPUB 2026-05-14 10:41:33 -06:00
neon d1d0b7b2c1 feat(reader): add dictionary lookup to epub reader selection popup 2026-05-14 05:46:43 +00:00
neon 0699394f05 fix(authors): fix table viewMode hiding books, add grid/list toggle to author books section, add useAuthorBooks and findBooks tests 2026-05-13 18:15:25 -06:00
neon ca4681b108 feat(table): add read/metadata columns and refine fixed-column UI 2026-05-13 17:57:29 -06:00
neon f9c1e29911 feat: implement version UI and short-sha CI versioning 2026-05-13 22:24:46 +00:00
neon c7a066e4eb fix(client): bust stale covers after bulk refresh via pre-bump and consistent coverUrl usage 2026-05-13 19:51:52 +00:00
neon 7f9a4717a5 fix: prevent stale read status when navigating between similar books 2026-05-13 10:25:31 -06:00
neon 76ac9d3dc1 fix(book-cover): add white shadow to progress bar for contrast on dark placeholder backgrounds
In light mode --primary resolves to oklch(0.21), near-black. Square audiobook
covers without real cover art show the BookCoverPlaceholder whose gradient
bottom edge is also dark (oklch(0.25-0.55)), making the progress bar
invisible by blending in. Portrait ebook covers have real cover images whose
varied bottom edges provide natural contrast so the bar was already visible.

Add a 1px white box-shadow above the bar to create a visible boundary
against any dark background. The shadow is subtle enough to be unnoticeable
on lighter backgrounds where contrast already exists.
2026-05-13 16:11:54 +00:00
neon 266b57c38a chore: reorganize docs, improve README, and add FOSS project hygiene 2026-05-13 15:05:04 +00:00
neon a64013a79d fix(book-cover-card): fix unclickable kebab and quick-view buttons on desktop hover, add comprehensive tests 2026-05-12 23:28:41 +00:00
neon e3d82b53e5 fix(security): resolve 100 CodeQL alerts - sanitizeLogValue helper, kobo-proxy SSRF guard, duckduckgo URL parsing, dismiss false positives 2026-05-12 21:46:55 +00:00
neon 22ac06ecd7 feat(client): add PWA support with installability and cover caching
Add vite-plugin-pwa with Workbox in generateSW mode. Includes a web app
manifest (standalone display, shortcuts for Dashboard/Libraries/Settings),
iOS meta tags, and a service worker that pre-caches the app shell and uses
CacheFirst for book cover and thumbnail endpoints (max 200 entries, 30-day TTL).

Add useInstallPrompt composable that captures the beforeinstallprompt event
and exposes isInstallable/installApp. Wire an install button into SidebarFooter
that appears only when the browser signals the app is installable.

Generate PWA icons (64, 192, 512, maskable-512, apple-touch-icon-180) from a
new pwa-icon-source.svg using @vite-pwa/assets-generator with minimal2023Preset.
Add dev-dist to .gitignore to exclude the dev-mode SW output.
2026-05-12 20:53:21 +00:00
neon 431053e510 feat(reader): replace pdf reader with embedpdf vue viewer
Replace the v1 canvas-based PDF reader (pdfjs-dist) with @embedpdf/vue-pdf-viewer
which renders correctly on iOS Chrome. Configure theme sync with app accent colors
via ACCENT_OPTIONS lookup instead of unreliable DOM oklch resolution, disable unused
toolbar categories, and persist per-book reader settings (scroll, spread, zoom).
2026-05-12 20:25:00 +00:00
neon f79f810c8c fix: mobile UI bugs - overlay touch, sticky header, keyboard sheet, viewport height, reader timeout 2026-05-12 19:30:18 +00:00
neon 6cc9867a63 fix: remove KoreaderBookSyncCard, fix missing initial library load, add mediaSrc CSP, return null from getBookProgress instead of 404 2026-05-12 05:56:38 +00:00
neon 6a78df6597 feat(koreader): add KOReader sync with kosync protocol, device progress tracking, and reading position bridge 2026-05-12 03:36:00 +00:00
neon 31b3460658 feat(kobo): restore read-status thresholds, remove two-way progress sync, fix LAN dev sync, and add fallback fraction positioning for epub/cbz/pdf readers 2026-05-11 21:23:11 +00:00
neon 6b650981da fix(docker): rebuild kepubify with Go 1.26.3, fix read-only fs chmod
Replaced pre-compiled kepubify binaries (built with Go 1.17.8, 53
HIGH/CRITICAL CVEs) with binaries rebuilt from source using Go 1.26.3
and golang.org/x/text upgraded to v0.3.8, resolving all fixable CVEs.

Also fixed KepubifyBinaryService incorrectly falling back to downloading
the binary on every startup in read-only containers. chmod() was throwing
EROFS, and the single catch block treated it as a missing file. Split
stat and chmod into separate try/catch so only a missing-file error
triggers the download fallback.
2026-05-11 18:42:18 +00:00
neon 3fd439289d fix(auth): surface rate-limit error on login and remove dropped background patterns
Show a clear too-many-attempts message on the login page when the server
throttles the request. Remove the nova and golden-ratio background options,
whose CSS definitions were already deleted.
2026-05-11 16:42:38 +00:00
neon 681f684dff fix(reader,dashboard): handle audiobook progress reliably 2026-05-11 00:08:58 -06:00
neon 4fd91b6d1f fix(client): adjust cover defaults and metadata menu/layout 2026-05-10 23:52:15 -06:00
neon 35100a0fd0 fix(demo): block reader storage mode change and font edits for demo accounts 2026-05-11 05:15:43 +00:00
neon 3eed6ee695 fix(user): allow demo accounts to update UI settings via PATCH /users/me/settings 2026-05-11 04:31:39 +00:00
neon 57d91ebea1 feat(cover,metadata): ffprobe extraction, cover placeholders, grid refresh, and audiobook search
- Replace music-metadata and mediainfo with @ffprobe-installer for all audio metadata extraction; remove mediainfo dependency
- Show BookCoverPlaceholder in all missing-cover locations: Similar/Series/Author Books carousel, cover editor panel, metadata search result cards, and metadata diff panel
- Extend BookRecommendation and SeriesBookRecommendation shared types with hasCover and authors; update recommendation and book repositories to supply them via parallel queries
- Fix cover refresh not updating in grid: BookCoverCard now merges refreshed BookDetail into the local BookCard and emits update:book; VirtualBookGrid forwards the event; Home, Series, Author, and Collection views wire the handler so covers update without a page reload
- Add audiobook covers checkbox to the Online Search drawer so users can toggle between square and portrait cover searches; result thumbnails and loading skeletons adapt their aspect ratio to match the selection
2026-05-11 00:06:05 +00:00
neon ea998b8bd2 fix(scanner): batch book emitting 2026-05-10 16:33:29 -06:00
neon cdb9d999d8 fix(client): proxy external images through cover proxy for CSP 2026-05-10 15:30:47 -06:00
neon ce72cfd988 feat(entity-manager): pre-computed duplicate detection for large datasets
Replace the live self-join scan (O(N^2), times out at 100K+ authors) with a
background-computed candidates table served instantly at read time.

Key changes:
- Add entity_duplicate_candidates and entity_duplicate_scan_status tables
- Background job batches 1K authors at a time (~58s total for 200K authors)
- Scan endpoint reads from the indexed table (<10ms regardless of scale)
- Candidates are invalidated after merge/delete, not recomputed from scratch
- Add GET /duplicates/status and POST /duplicates/refresh endpoints
- Frontend updates clusters locally after merge/dismiss (no re-scan)
- Status bar shows last computed time and recompute button with progress
- Author browse in entity manager now shows all authors, not just those with books
2026-05-10 08:12:26 +00:00
neon e59608ceb3 feat(reader,ui): improve mobile reader ergonomics and touch handling
- overhaul EPUB/CBZ/PDF mobile header, footer, toolbar, sidebar, and settings interactions
- add EPUB search minimum query length enforcement with updated unit tests
- improve PDF rendering stability by drawing from an offscreen render canvas
- add app-shell level horizontal overflow/touch constraints to prevent sideways pan and double-tap zoom issues
- make statistics header controls and configure drawer responsive on mobile
2026-05-09 23:48:39 -06:00
neon 6669c4cb51 feat(ui): unify mobile controls and polish authors/series/dashboard UX
- refactor ViewHeader into reusable desktop/mobile subcomponents (desktop search, display controls, mobile menu, mobile search sheet)
- standardize mobile search/sort/filter behavior across Home, Collection, Smart Scope, Authors, and Series
- fix duplicate search clear icons by suppressing native search cancel controls where custom clear buttons are used
- move Authors and Series into contained scroll regions and tighten mobile paddings/margins for better header alignment
- fix author card count/kebab z-index overlap with sticky headers
- clamp author bio to 2 lines on mobile with show more/less toggle
- simplify Series filters by removing separate author filter and support searching series by title or author name
- update series repository query logic to include author-name matching in `q` search
- improve mobile sheet sizing for Customize Dashboard and Notifications; add compact personalized dashboard greeting
- remove sidebar trigger tooltip and prevent action-bar icon/button shrink issues
2026-05-09 21:59:25 -06:00
neon 385b4f12b1 feat: enhance metadata UX and harden backend behavior
- add local provider icon assets and a shared providerIconPath helper for metadata providers
- switch provider links in book details and quick view to use bundled SVG icons
- proxy external metadata cover URLs through /api/v1/books/cover/proxy for display while keeping same-origin/data/blob URLs untouched
- apply proxied display cover URLs in metadata diff/result UI and Book Dock surfaces
- keep raw provider cover URLs in metadata patches and add composable tests for proxy behavior
- add optional CSP_ALLOW_CLOUDFLARE_INSIGHTS env support and document it in server/root env examples and README
- wire conditional Cloudflare Insights script/connect sources into CSP directives
- remove pino HTTP customProps context injection to avoid duplicated context labels
- reduce file-write log noise by using debug level for write start and auto-skipped completions
- tune entity-manager duplicate scans by setting pg_trgm similarity_threshold per query/transaction to align with minSimilarity and prevent scan blowups
2026-05-09 18:03:12 -06:00
neon 838033717c fix(ci,books): resolve GHCR/CVE issues and clean pin/unpin fallbacks
- regenerate lockfile after package version alignment
- remove useless fallback spreads in pin and unpin column
- resolve GHCR push auth and fast-uri CVE
- patch fast-xml-builder CVE in image scan
2026-05-08 19:10:03 -06:00
neon 4e93e20bbb feat(books): add table view, metadata export, and filter builder 2026-05-01 23:59:37 -06:00