diff --git a/Dockerfile b/Dockerfile index 1ba107fd..816bdd3c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,9 @@ +ARG NUSQLITE3_DIR="/usr/local/lib/nusqlite3" +ARG NUSQLITE3_PATH="${NUSQLITE3_DIR}/libnusqlite3.so" + ### STAGE 0: Build client ### FROM node:20-alpine AS build-client + WORKDIR /client COPY /client /client RUN npm ci && npm cache clean --force @@ -8,6 +12,9 @@ RUN npm run generate ### STAGE 1: Build server ### FROM node:20-alpine AS build-server +ARG NUSQLITE3_DIR +ARG TARGETPLATFORM + ENV NODE_ENV=production RUN apk add --no-cache --update \ @@ -21,11 +28,6 @@ WORKDIR /server COPY index.js package* /server COPY /server /server/server -ARG TARGETPLATFORM - -ENV NUSQLITE3_DIR="/usr/local/lib/nusqlite3" -ENV NUSQLITE3_PATH="${NUSQLITE3_DIR}/libnusqlite3.so" - RUN case "$TARGETPLATFORM" in \ "linux/amd64") \ curl -L -o /tmp/library.zip "https://github.com/mikiher/nunicode-sqlite/releases/download/v1.2/libnusqlite3-linux-musl-x64.zip" ;; \ @@ -41,6 +43,9 @@ RUN npm ci --only=production ### STAGE 2: Create minimal runtime image ### FROM node:20-alpine +ARG NUSQLITE3_DIR +ARG NUSQLITE3_PATH + # Install only runtime dependencies RUN apk add --no-cache --update \ tzdata \ @@ -52,13 +57,17 @@ WORKDIR /app # Copy compiled frontend and server from build stages COPY --from=build-client /client/dist /app/client/dist COPY --from=build-server /server /app +COPY --from=build-server ${NUSQLITE3_PATH} ${NUSQLITE3_PATH} EXPOSE 80 ENV PORT=80 +ENV NODE_ENV=production ENV CONFIG_PATH="/config" ENV METADATA_PATH="/metadata" ENV SOURCE="docker" +ENV NUSQLITE3_DIR=${NUSQLITE3_DIR} +ENV NUSQLITE3_PATH=${NUSQLITE3_PATH} ENTRYPOINT ["tini", "--"] CMD ["node", "index.js"] diff --git a/client/components/app/BookShelfCategorized.vue b/client/components/app/BookShelfCategorized.vue index 8c680462..4bf8cfbb 100644 --- a/client/components/app/BookShelfCategorized.vue +++ b/client/components/app/BookShelfCategorized.vue @@ -217,6 +217,16 @@ export default { }) } + if (this.results.episodes?.length) { + shelves.push({ + id: 'episodes', + label: 'Episodes', + labelStringKey: 'LabelEpisodes', + type: 'episode', + entities: this.results.episodes.map((res) => res.libraryItem) + }) + } + if (this.results.series?.length) { shelves.push({ id: 'series', diff --git a/client/components/cards/EpisodeSearchCard.vue b/client/components/cards/EpisodeSearchCard.vue index e69de29b..8be6a3a3 100644 --- a/client/components/cards/EpisodeSearchCard.vue +++ b/client/components/cards/EpisodeSearchCard.vue @@ -0,0 +1,60 @@ + + + + + diff --git a/client/components/controls/GlobalSearch.vue b/client/components/controls/GlobalSearch.vue index bc9a2368..6f3a819b 100644 --- a/client/components/controls/GlobalSearch.vue +++ b/client/components/controls/GlobalSearch.vue @@ -39,6 +39,15 @@ +

{{ $strings.LabelEpisodes }}

+ +

{{ $strings.LabelAuthors }}

@@ -316,6 +316,10 @@ export default { if (this.$refs.trix && this.$refs.trix.blur) { this.$refs.trix.blur() } + }, + handleAttachmentAdd(event) { + // Prevent pasting in images/any files from the browser + event.attachment.remove() } }, mounted() { diff --git a/client/components/widgets/EncoderOptionsCard.vue b/client/components/widgets/EncoderOptionsCard.vue index 9306274d..977d766b 100644 --- a/client/components/widgets/EncoderOptionsCard.vue +++ b/client/components/widgets/EncoderOptionsCard.vue @@ -143,10 +143,18 @@ export default { localStorage.setItem('embedMetadataCodec', val) }, getEncodingOptions() { - return { - codec: this.selectedCodec || 'aac', - bitrate: this.selectedBitrate || '128k', - channels: this.selectedChannels || 2 + if (this.showAdvancedView) { + return { + codec: this.customCodec || this.selectedCodec || 'aac', + bitrate: this.customBitrate || this.selectedBitrate || '128k', + channels: this.customChannels || this.selectedChannels || 2 + } + } else { + return { + codec: this.selectedCodec || 'aac', + bitrate: this.selectedBitrate || '128k', + channels: this.selectedChannels || 2 + } } }, setPreset() { @@ -162,7 +170,7 @@ export default { } else { // Find closest bitrate rounding up const bitratesToMatch = [32, 64, 128, 192] - const closestBitrate = bitratesToMatch.find((bitrate) => bitrate >= this.currentBitrate) + const closestBitrate = bitratesToMatch.find((bitrate) => bitrate >= this.currentBitrate) || 192 this.selectedBitrate = closestBitrate + 'k' } diff --git a/client/components/widgets/LoadingSpinner.vue b/client/components/widgets/LoadingSpinner.vue index a9c4ef47..8f3de84a 100644 --- a/client/components/widgets/LoadingSpinner.vue +++ b/client/components/widgets/LoadingSpinner.vue @@ -248,4 +248,4 @@ export default { transform: scale(0); } } - \ No newline at end of file + diff --git a/client/components/widgets/SeriesInputWidget.vue b/client/components/widgets/SeriesInputWidget.vue index 916b108d..3dab0605 100644 --- a/client/components/widgets/SeriesInputWidget.vue +++ b/client/components/widgets/SeriesInputWidget.vue @@ -2,7 +2,7 @@
- +
@@ -18,6 +18,7 @@ export default { data() { return { selectedSeries: null, + originalSeriesSequence: null, showSeriesForm: false } }, @@ -59,6 +60,7 @@ export default { ..._series } + this.originalSeriesSequence = _series.sequence this.showSeriesForm = true }, addNewSeries() { @@ -68,6 +70,7 @@ export default { sequence: '' } + this.originalSeriesSequence = null this.showSeriesForm = true }, submitSeriesForm() { @@ -106,4 +109,4 @@ export default { } } } - \ No newline at end of file + diff --git a/client/package-lock.json b/client/package-lock.json index 733dc4af..db21b43f 100644 --- a/client/package-lock.json +++ b/client/package-lock.json @@ -1,12 +1,12 @@ { "name": "audiobookshelf-client", - "version": "2.21.0", + "version": "2.25.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "audiobookshelf-client", - "version": "2.21.0", + "version": "2.25.1", "license": "ISC", "dependencies": { "@nuxtjs/axios": "^5.13.6", diff --git a/client/package.json b/client/package.json index ac6edb8f..e8823f1b 100644 --- a/client/package.json +++ b/client/package.json @@ -1,6 +1,6 @@ { "name": "audiobookshelf-client", - "version": "2.21.0", + "version": "2.25.1", "buildNumber": 1, "description": "Self-hosted audiobook and podcast client", "main": "index.js", diff --git a/client/pages/audiobook/_id/manage.vue b/client/pages/audiobook/_id/manage.vue index 7afe12a9..40672af2 100644 --- a/client/pages/audiobook/_id/manage.vue +++ b/client/pages/audiobook/_id/manage.vue @@ -28,14 +28,14 @@
-
{{ $strings.LabelMetaTag }}
-
{{ $strings.LabelValue }}
+
{{ $strings.LabelMetaTag }}
+
{{ $strings.LabelValue }}