- Moved audio start button from top-right toolbar to floating bottom-right position
- Only shows floating button when audio player is not active
- Button styled as amber pill with 'Listen' text and play icon
- More accessible placement for quick audio playback start
- Positioned 20pt from bottom and right edges with shadow
- Add safeAreaInset on ChapterReaderView ScrollView so Prev/Next buttons
clear the mini player bar when audio is active
- Fix mini player height reservation (66pt constant via AppLayout)
- Add AsyncCoverImage(isBackground:) to suppress rounded-rect placeholder
showing through blurred hero background (empty square bug)
- Reduce chapter page size 100→50 on iOS
- Fix ChapterRow date/chevron layout: minLength spacer + fixedSize date
- Add String.strippingTrailingDate() extension; apply in MiniPlayer,
FullPlayer, and ChapterReader header to clean up stale concatenated titles
- Make Prev/Next buttons equal-width (maxWidth: .infinity) for easier tapping
- AudioPlayerService: replace loading/generating states with a single
.generating state; presign fast path before triggering TTS; fix URL
resolution for relative paths; cache cover artwork to avoid re-downloads;
fix duration KVO race (durationObserver); use toleranceBefore/After:zero
for accurate seeking; prefetch next chapter unconditionally (not just when
autoNext is on); handle auto-next internally on playback finish
- APIClient: fix URL construction (appendingPathComponent encodes slashes);
add verbose debug logging for all requests/responses/decoding errors;
fix sessions() to unwrap {sessions:[]} envelope; fix BrowseResponse
CodingKey hasNext → camelCase
- AudioGenerateResponse: update to synchronous {url, filename} shape
- Models: remove redundant AudioStatus enum; remove CodingKeys from
UserSettings (server now sends camelCase)
- Views: fix alert bindings (.constant → proper two-way Binding); add
error+retry UI to BrowseView; add pull-to-refresh to browse list;
fix ChapterReaderView to show error state and use dynamic WKWebView
height; fix HomeView HStack alignment; only treat audio as current
if the player isActive; suppress CancellationError from error UI