diff --git a/.gitignore b/.gitignore index d375bae08..12ebec1c2 100644 --- a/.gitignore +++ b/.gitignore @@ -23,3 +23,4 @@ sw.* .DS_STORE .idea/* tailwind.compiled.css +tailwind.config.js diff --git a/Dockerfile b/Dockerfile index 4e110a619..f9c461174 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,34 +1,32 @@ +ARG NUSQLITE3_DIR="/usr/local/lib/nusqlite3" +ARG NUSQLITE3_PATH="${NUSQLITE3_DIR}/libnusqlite3.so" + ### STAGE 0: Build client ### -FROM node:20-alpine AS build +FROM node:20-alpine AS build-client + WORKDIR /client COPY /client /client RUN npm ci && npm cache clean --force RUN npm run generate ### STAGE 1: Build server ### -FROM node:20-alpine +FROM node:20-alpine AS build-server + +ARG NUSQLITE3_DIR +ARG TARGETPLATFORM ENV NODE_ENV=production -RUN apk update && \ - apk add --no-cache --update \ +RUN apk add --no-cache --update \ curl \ - tzdata \ - ffmpeg \ make \ python3 \ g++ \ - tini \ unzip -COPY --from=build /client/dist /client/dist -COPY index.js package* / -COPY server server - -ARG TARGETPLATFORM - -ENV NUSQLITE3_DIR="/usr/local/lib/nusqlite3" -ENV NUSQLITE3_PATH="${NUSQLITE3_DIR}/libnusqlite3.so" +WORKDIR /server +COPY index.js package* /server +COPY /server /server/server RUN case "$TARGETPLATFORM" in \ "linux/amd64") \ @@ -42,14 +40,34 @@ RUN case "$TARGETPLATFORM" in \ RUN npm ci --only=production -RUN apk del make python3 g++ +### 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 \ + ffmpeg \ + tini + +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 /usr/local/lib/nusqlite3 /usr/local/lib/nusqlite3 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 8c6804625..4bf8cfbbf 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/app/BookShelfToolbar.vue b/client/components/app/BookShelfToolbar.vue index 01ab4fa78..95e7c378c 100644 --- a/client/components/app/BookShelfToolbar.vue +++ b/client/components/app/BookShelfToolbar.vue @@ -274,15 +274,10 @@ export default { isAuthorsPage() { return this.page === 'authors' }, - isAlbumsPage() { - return this.page === 'albums' - }, numShowing() { return this.totalEntities }, entityName() { - if (this.isAlbumsPage) return 'Albums' - if (this.isPodcastLibrary) return this.$strings.LabelPodcasts if (!this.page) return this.$strings.LabelBooks if (this.isSeriesPage) return this.$strings.LabelSeries diff --git a/client/components/cards/EpisodeSearchCard.vue b/client/components/cards/EpisodeSearchCard.vue index e69de29bb..8be6a3a3b 100644 --- a/client/components/cards/EpisodeSearchCard.vue +++ b/client/components/cards/EpisodeSearchCard.vue @@ -0,0 +1,60 @@ + + + + + diff --git a/client/components/cards/LazyAlbumCard.vue b/client/components/cards/LazyAlbumCard.vue deleted file mode 100644 index 9b7227953..000000000 --- a/client/components/cards/LazyAlbumCard.vue +++ /dev/null @@ -1,142 +0,0 @@ - - - diff --git a/client/components/controls/GlobalSearch.vue b/client/components/controls/GlobalSearch.vue index bc9a23681..6f3a819bf 100644 --- a/client/components/controls/GlobalSearch.vue +++ b/client/components/controls/GlobalSearch.vue @@ -39,6 +39,15 @@ +

{{ $strings.LabelEpisodes }}

+ +

{{ $strings.LabelAuthors }}