diff --git a/.github/workflows/close_blank_issues.yaml b/.github/workflows/close_blank_issues.yaml
index c7108827..7190546a 100644
--- a/.github/workflows/close_blank_issues.yaml
+++ b/.github/workflows/close_blank_issues.yaml
@@ -14,11 +14,11 @@ jobs:
steps:
- name: Check issue headings
- uses: actions/github-script@v6
+ uses: actions/github-script@v7
with:
script: |
const issueBody = context.payload.issue.body || "";
-
+
// Match Markdown headings (e.g., # Heading, ## Heading)
const headingRegex = /^(#{1,6})\s.+/gm;
const headings = [...issueBody.matchAll(headingRegex)];
@@ -39,4 +39,4 @@ jobs:
issue_number: context.payload.issue.number,
state: "closed"
});
- }
\ No newline at end of file
+ }
diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml
index 8d43311b..2e5f4bce 100644
--- a/.github/workflows/codeql.yml
+++ b/.github/workflows/codeql.yml
@@ -43,7 +43,7 @@ jobs:
steps:
- name: Checkout repository
- uses: actions/checkout@v3
+ uses: actions/checkout@v4
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
diff --git a/.github/workflows/component-tests.yml b/.github/workflows/component-tests.yml
new file mode 100644
index 00000000..fcc2c213
--- /dev/null
+++ b/.github/workflows/component-tests.yml
@@ -0,0 +1,48 @@
+name: Run Component Tests
+
+on:
+ workflow_dispatch:
+ inputs:
+ ref:
+ description: 'Branch/Tag/SHA to test'
+ required: true
+ pull_request:
+ paths:
+ - 'client/**'
+ - '.github/workflows/component-tests.yml'
+ push:
+ paths:
+ - 'client/**'
+ - '.github/workflows/component-tests.yml'
+
+jobs:
+ run-component-tests:
+ name: Run Component Tests
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Checkout (push/pull request)
+ uses: actions/checkout@v4
+ if: github.event_name != 'workflow_dispatch'
+
+ - name: Checkout (workflow_dispatch)
+ uses: actions/checkout@v4
+ with:
+ ref: ${{ inputs.ref }}
+ if: github.event_name == 'workflow_dispatch'
+
+ - name: Set up Node.js
+ uses: actions/setup-node@v4
+ with:
+ node-version: 20
+ cache: 'npm'
+
+ - name: Install dependencies
+ run: |
+ cd client
+ npm ci
+
+ - name: Run tests
+ run: |
+ cd client
+ npm test
diff --git a/.github/workflows/docker-build.yml b/.github/workflows/docker-build.yml
index 846a5563..fdb57fbc 100644
--- a/.github/workflows/docker-build.yml
+++ b/.github/workflows/docker-build.yml
@@ -1,5 +1,4 @@
---
-
name: Build and Push Docker Image
on:
@@ -11,7 +10,7 @@ on:
required: true
default: 'latest'
push:
- branches: [main,master]
+ branches: [main, master]
tags:
- 'v*.*.*'
# Only build when files in these directories have been changed
@@ -23,16 +22,16 @@ on:
jobs:
build:
- if: "!contains(github.event.head_commit.message, 'skip ci')"
- runs-on: ubuntu-20.04
+ if: ${{ !contains(github.event.head_commit.message, 'skip ci') && github.repository == 'advplyr/audiobookshelf' }}
+ runs-on: ubuntu-24.04
steps:
- name: Check out
- uses: actions/checkout@v3
+ uses: actions/checkout@v4
- name: Docker meta
id: meta
- uses: docker/metadata-action@v4
+ uses: docker/metadata-action@v5
with:
images: advplyr/audiobookshelf,ghcr.io/${{ github.repository_owner }}/audiobookshelf
tags: |
@@ -40,13 +39,13 @@ jobs:
type=semver,pattern={{version}}
- name: Setup QEMU
- uses: docker/setup-qemu-action@v2
+ uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
- uses: docker/setup-buildx-action@v2
+ uses: docker/setup-buildx-action@v3
- name: Cache Docker layers
- uses: actions/cache@v3
+ uses: actions/cache@v4
with:
path: /tmp/.buildx-cache
key: ${{ runner.os }}-buildx-${{ github.sha }}
@@ -54,20 +53,20 @@ jobs:
${{ runner.os }}-buildx-
- name: Login to Dockerhub
- uses: docker/login-action@v2
+ uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_PASSWORD }}
- name: Login to ghcr
- uses: docker/login-action@v2
+ uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GHCR_PASSWORD }}
- name: Build image
- uses: docker/build-push-action@v3
+ uses: docker/build-push-action@v6
with:
tags: ${{ github.event.inputs.tags || steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
diff --git a/.github/workflows/i18n-integration.yml b/.github/workflows/i18n-integration.yml
index fc844154..8b3a4678 100644
--- a/.github/workflows/i18n-integration.yml
+++ b/.github/workflows/i18n-integration.yml
@@ -20,7 +20,8 @@ jobs:
- name: Set up node
uses: actions/setup-node@v4
with:
- node-version: '20'
+ node-version: 20
+ cache: 'npm'
# The only argument is the `directory`, which is where the i18n files are
# stored.
diff --git a/.github/workflows/integration-test.yml b/.github/workflows/integration-test.yml
index 580c0f50..18c1d2da 100644
--- a/.github/workflows/integration-test.yml
+++ b/.github/workflows/integration-test.yml
@@ -18,14 +18,15 @@ jobs:
name: build and test
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v3
+ - uses: actions/checkout@v4
- - name: setup nade
- uses: actions/setup-node@v3
+ - name: setup node
+ uses: actions/setup-node@v4
with:
node-version: 20
+ cache: 'npm'
- - name: install pkg (using yao-pkg fork for targetting node20)
+ - name: install pkg (using yao-pkg fork for targeting node20)
run: npm install -g @yao-pkg/pkg
- name: get client dependencies
diff --git a/.github/workflows/lint-openapi.yml b/.github/workflows/lint-openapi.yml
index 817e94b9..ec08ecb3 100644
--- a/.github/workflows/lint-openapi.yml
+++ b/.github/workflows/lint-openapi.yml
@@ -18,15 +18,22 @@ jobs:
# Check out the repository
- name: Checkout
uses: actions/checkout@v4
+
# Set up node to run the javascript
- name: Set up node
uses: actions/setup-node@v4
+ with:
+ node-version: 20
+ cache: 'npm'
+
# Install Redocly CLI
- name: Install Redocly CLI
run: npm install -g @redocly/cli@latest
+
# Perform linting for exploded spec
- name: Run linting for exploded spec
run: redocly lint docs/root.yaml --format=github-actions
+
# Perform linting for bundled spec
- name: Run linting for bundled spec
run: redocly lint docs/openapi.json --format=github-actions
diff --git a/.github/workflows/unit-tests.yml b/.github/workflows/unit-tests.yml
index 695696c6..91a22c71 100644
--- a/.github/workflows/unit-tests.yml
+++ b/.github/workflows/unit-tests.yml
@@ -29,6 +29,7 @@ jobs:
uses: actions/setup-node@v4
with:
node-version: 20
+ cache: 'npm'
- name: Install dependencies
run: npm ci
diff --git a/client/assets/tailwind.css b/client/assets/tailwind.css
index bd6213e1..7883f32f 100644
--- a/client/assets/tailwind.css
+++ b/client/assets/tailwind.css
@@ -1,3 +1,85 @@
-@tailwind base;
-@tailwind components;
-@tailwind utilities;
\ No newline at end of file
+@import 'tailwindcss';
+
+/*
+ The default border color has changed to `currentColor` in Tailwind CSS v4,
+ so we've added these compatibility styles to make sure everything still
+ looks the same as it did with Tailwind CSS v3.
+
+ If we ever want to remove these styles, we need to add an explicit border
+ color utility to any element that depends on these defaults.
+*/
+@layer base {
+ *,
+ ::after,
+ ::before,
+ ::backdrop,
+ ::file-selector-button {
+ border-color: var(--color-gray-200, currentColor);
+ }
+
+ [role='button'],
+ button {
+ cursor: pointer;
+ }
+}
+
+@theme {
+ --spacing-0\.5e: 0.125em;
+ --spacing-1e: 0.25em;
+ --spacing-1\.5e: 0.375em;
+ --spacing-2e: 0.5em;
+ --spacing-2\.5e: 0.625em;
+ --spacing-3e: 0.75em;
+ --spacing-3\.5e: 0.875em;
+ --spacing-4e: 1em;
+ --spacing-5e: 1.25em;
+ --spacing-6e: 1.5em;
+ --spacing-7e: 1.75em;
+ --spacing-8e: 2em;
+ --spacing-9e: 2.25em;
+ --spacing-10e: 2.5em;
+ --spacing-11e: 2.75em;
+ --spacing-12e: 3em;
+ --spacing-14e: 3.5em;
+ --spacing-16e: 4em;
+ --spacing-20e: 5em;
+ --spacing-24e: 6em;
+ --spacing-28e: 7em;
+ --spacing-32e: 8em;
+ --spacing-36e: 9em;
+ --spacing-40e: 10em;
+ --spacing-44e: 11em;
+ --spacing-48e: 12em;
+ --spacing-52e: 13em;
+ --spacing-56e: 14em;
+ --spacing-60e: 15em;
+ --spacing-64e: 16em;
+ --spacing-72e: 18em;
+ --spacing-80e: 20em;
+ --spacing-96e: 24em;
+
+ --color-bg: #373838;
+ --color-primary: #232323;
+ --color-accent: #1ad691;
+ --color-error: #ff5252;
+ --color-info: #2196f3;
+ --color-success: #4caf50;
+ --color-warning: #fb8c00;
+ --color-darkgreen: rgb(34, 127, 35);
+ --color-black-50: #bbbbbb;
+ --color-black-100: #666666;
+ --color-black-200: #555555;
+ --color-black-300: #444444;
+ --color-black-400: #333333;
+ --color-black-500: #222222;
+ --color-black-600: #111111;
+ --color-black-700: #101010;
+
+ --font-sans: 'Source Sans Pro';
+ --font-mono: 'Ubuntu Mono';
+
+ --text-xxs: 0.625rem;
+ --text-1\.5xl: 1.375rem;
+ --text-2\.5xl: 1.6875rem;
+ --text-4\.5xl: 2.625rem;
+}
diff --git a/client/components/app/Appbar.vue b/client/components/app/Appbar.vue
index bb452526..f7413404 100644
--- a/client/components/app/Appbar.vue
+++ b/client/components/app/Appbar.vue
@@ -13,10 +13,10 @@
{{ $getString('MessageXLibraryIsEmpty', [libraryName]) }}
{{ $strings.ButtonHome }}
{{ $strings.ButtonLibrary }}
{{ $strings.ButtonLatest }}
{{ $strings.ButtonSeries }}
{{ $strings.ButtonPlaylists }}
{{ $strings.ButtonCollections }}
{{ $strings.ButtonAuthors }}
{{ $strings.ButtonAdd }}
{{ $strings.ButtonDownloadQueue }}
{{ seriesName }}
-{{ $formatNumber(numShowing) }} {{ entityName }}
- +{{ $strings.MessageSearchResultsFor }} "{{ searchQuery }}"
- +{{ $formatNumber(numShowing) }} {{ entityName }}
- -