From 0c2349f259ee610a96348151cb7fc64287665034 Mon Sep 17 00:00:00 2001 From: Admin Date: Sun, 8 Mar 2026 14:07:55 +0500 Subject: [PATCH] iOS: add floating audio button when player is not active - 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 --- .../ChapterReader/ChapterReaderView.swift | 36 +++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/ios/LibNovel/LibNovel/Views/ChapterReader/ChapterReaderView.swift b/ios/LibNovel/LibNovel/Views/ChapterReader/ChapterReaderView.swift index 873441d..3935c71 100644 --- a/ios/LibNovel/LibNovel/Views/ChapterReader/ChapterReaderView.swift +++ b/ios/LibNovel/LibNovel/Views/ChapterReader/ChapterReaderView.swift @@ -48,7 +48,12 @@ struct ChapterReaderView: View { } .navigationTitle(vm.content.map { "Ch.\($0.chapter.number)" } ?? "") .navigationBarTitleDisplayMode(.inline) - .toolbar { audioToolbarButton } + .overlay(alignment: .bottomTrailing) { + // Floating audio button when player is not active + if !audioPlayer.isActive { + floatingAudioButton + } + } .task { print("[ChapterReaderView] .task fired — calling vm.load()") await vm.load() @@ -140,7 +145,34 @@ struct ChapterReaderView: View { } } - // MARK: - Audio toolbar button + // MARK: - Floating audio button + + @ViewBuilder + private var floatingAudioButton: some View { + Button { + vm.toggleAudio(audioPlayer: audioPlayer, settings: authStore.settings) + } label: { + HStack(spacing: 8) { + Image(systemName: "play.circle.fill") + .font(.system(size: 22)) + Text("Listen") + .font(.subheadline.weight(.semibold)) + } + .foregroundStyle(.white) + .padding(.horizontal, 20) + .padding(.vertical, 12) + .background( + Capsule() + .fill(Color.amber) + .shadow(color: .black.opacity(0.25), radius: 8, y: 4) + ) + } + .buttonStyle(.plain) + .padding(.trailing, 20) + .padding(.bottom, 20) + } + + // MARK: - Audio toolbar button (kept for when player is active) @ToolbarContentBuilder private var audioToolbarButton: some ToolbarContent {