Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
55df88c3e5 | ||
|
|
eb137fdbf5 |
@@ -171,6 +171,13 @@ jobs:
|
||||
SENTRY_ORG: libnovel
|
||||
SENTRY_PROJECT: ui
|
||||
|
||||
- name: Upload injected build (for docker-ui)
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: ui-build-injected
|
||||
path: build
|
||||
retention-days: 1
|
||||
|
||||
- name: Create GlitchTip release
|
||||
run: sentry-cli releases new ${{ steps.ver.outputs.version }}
|
||||
env:
|
||||
@@ -226,6 +233,12 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Download injected build (debug IDs already embedded)
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: ui-build-injected
|
||||
path: ui/build
|
||||
|
||||
- uses: docker/setup-buildx-action@v3
|
||||
|
||||
- name: Log in to Docker Hub
|
||||
@@ -255,6 +268,7 @@ jobs:
|
||||
BUILD_VERSION=${{ steps.meta.outputs.version }}
|
||||
BUILD_COMMIT=${{ gitea.sha }}
|
||||
BUILD_TIME=${{ gitea.event.head_commit.timestamp }}
|
||||
PREBUILT=1
|
||||
cache-from: type=registry,ref=${{ secrets.DOCKER_USER }}/libnovel-ui:latest
|
||||
cache-to: type=inline
|
||||
|
||||
|
||||
@@ -21,7 +21,11 @@ ENV PUBLIC_BUILD_VERSION=$BUILD_VERSION
|
||||
ENV PUBLIC_BUILD_COMMIT=$BUILD_COMMIT
|
||||
ENV PUBLIC_BUILD_TIME=$BUILD_TIME
|
||||
|
||||
RUN npm run build
|
||||
# PREBUILT=1 skips npm run build — used in CI when the build/ directory has
|
||||
# already been compiled (and debug IDs injected) by a prior job. The caller
|
||||
# must copy the pre-built build/ into the Docker context before building.
|
||||
ARG PREBUILT=0
|
||||
RUN [ "$PREBUILT" = "1" ] || npm run build
|
||||
|
||||
# ── Runtime image ──────────────────────────────────────────────────────────────
|
||||
# adapter-node bundles most server-side code, but packages with dynamic
|
||||
|
||||
@@ -857,12 +857,6 @@
|
||||
aria-label={audioStore.chapters.length > 0 ? m.player_toggle_chapter_list() : undefined}
|
||||
title={audioStore.chapters.length > 0 ? m.player_chapter_list_label() : undefined}
|
||||
>
|
||||
{#if audioStore.chapterTitle}
|
||||
<p class="text-xs text-(--color-text) truncate leading-tight">{audioStore.chapterTitle}</p>
|
||||
{/if}
|
||||
{#if audioStore.bookTitle}
|
||||
<p class="text-xs text-(--color-muted) truncate leading-tight">{audioStore.bookTitle}</p>
|
||||
{/if}
|
||||
{#if audioStore.status === 'generating'}
|
||||
<p class="text-xs text-(--color-brand) leading-tight">
|
||||
{m.player_generating({ percent: String(Math.round(audioStore.progress)) })}
|
||||
|
||||
@@ -471,18 +471,28 @@
|
||||
</button>
|
||||
{#if audioExpanded}
|
||||
<div class="border border-t-0 border-(--color-border) rounded-b-lg overflow-hidden">
|
||||
<AudioPlayer
|
||||
slug={data.book.slug}
|
||||
chapter={data.chapter.number}
|
||||
chapterTitle={data.chapter.title || m.reader_chapter_n({ n: String(data.chapter.number) })}
|
||||
bookTitle={data.book.title}
|
||||
cover={data.book.cover}
|
||||
nextChapter={data.next}
|
||||
chapters={data.chapters}
|
||||
voices={data.voices}
|
||||
playerStyle={layout.playerStyle}
|
||||
onProRequired={() => { audioProRequired = true; }}
|
||||
/>
|
||||
{#if audioStore.slug === data.book.slug && audioStore.chapter === data.chapter.number && audioStore.active}
|
||||
<!-- Mini-player is already playing this chapter — don't duplicate controls -->
|
||||
<div class="px-4 py-3 flex items-center gap-2 text-sm text-(--color-muted)">
|
||||
<svg class="w-4 h-4 text-(--color-brand) shrink-0" fill="currentColor" viewBox="0 0 24 24">
|
||||
<path d="M12 3v10.55A4 4 0 1014 17V7h4V3h-6z"/>
|
||||
</svg>
|
||||
<span>Controls are in the player bar below.</span>
|
||||
</div>
|
||||
{:else}
|
||||
<AudioPlayer
|
||||
slug={data.book.slug}
|
||||
chapter={data.chapter.number}
|
||||
chapterTitle={data.chapter.title || m.reader_chapter_n({ n: String(data.chapter.number) })}
|
||||
bookTitle={data.book.title}
|
||||
cover={data.book.cover}
|
||||
nextChapter={data.next}
|
||||
chapters={data.chapters}
|
||||
voices={data.voices}
|
||||
playerStyle={layout.playerStyle}
|
||||
onProRequired={() => { audioProRequired = true; }}
|
||||
/>
|
||||
{/if}
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user