Merge pull request #1306 from omnivore-app/fix/audio-player-crash

Dont instantiate TabView with zero items
This commit is contained in:
Satindar Dhillon 2022-10-13 12:08:36 -07:00 committed by GitHub
commit 22a5850c1e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 42 additions and 34 deletions

View file

@ -153,27 +153,29 @@
var audioCards: some View {
ZStack {
let textItems = self.audioController.textItems ?? []
TabView(selection: $tabIndex) {
ForEach(0 ..< textItems.count, id: \.self) { id in
SpeechCard(id: id)
.tag(id)
}
}
.tabViewStyle(PageTabViewStyle(indexDisplayMode: .never))
.onChange(of: tabIndex, perform: { index in
if index != audioController.currentAudioIndex, index < (audioController.textItems?.count ?? 0) {
audioController.seek(toUtterance: index)
}
})
.onChange(of: audioController.currentAudioIndex, perform: { index in
if index >= textItems.count {
return
if textItems.count > 0 {
TabView(selection: $tabIndex) {
ForEach(0 ..< textItems.count, id: \.self) { id in
SpeechCard(id: id)
.tag(id)
}
}
.tabViewStyle(PageTabViewStyle(indexDisplayMode: .never))
.onChange(of: tabIndex, perform: { index in
if index != audioController.currentAudioIndex, index < (audioController.textItems?.count ?? 0) {
audioController.seek(toUtterance: index)
}
})
.onChange(of: audioController.currentAudioIndex, perform: { index in
if index >= textItems.count {
return
}
if self.audioController.state != .reachedEnd {
tabIndex = index
}
})
if self.audioController.state != .reachedEnd {
tabIndex = index
}
})
}
if audioController.state == .reachedEnd {
// If we have reached the end display a replay button with an overlay behind
@ -279,7 +281,7 @@
Group {
ScrubberView(value: $audioController.timeElapsed,
minValue: 0, maxValue: self.audioController.duration,
maxValue: $audioController.duration,
onEditingChanged: { scrubStarted in
if scrubStarted {
self.audioController.scrubState = .scrubStarted
@ -359,6 +361,12 @@
.shadow(color: expanded ? .clear : .gray.opacity(0.33), radius: 8, x: 0, y: 4)
.mask(Rectangle().padding(.top, -20))
)
.onChange(of: audioController.state, perform: { state in
// Reset the tabIndex when we load a new audio item
if state == .loading {
tabIndex = 0
}
})
.onTapGesture {
withAnimation(.easeIn(duration: 0.08)) { expanded = true }
}.sheet(isPresented: $showVoiceSheet) {
@ -432,7 +440,7 @@
Button(action: {
audioController.currentVoice = voice.key
self.showVoiceSheet = false
}) {
}, label: {
HStack {
Text(voice.name)
@ -443,8 +451,7 @@
}
}
.contentShape(Rectangle())
}
.buttonStyle(PlainButtonStyle())
}).buttonStyle(PlainButtonStyle())
}
}
.padding(.top, 32)
@ -453,11 +460,11 @@
}
.navigationBarTitle("Voice")
.navigationBarTitleDisplayMode(.inline)
.navigationBarItems(leading: Button(action: { self.showVoiceSheet = false }) {
.navigationBarItems(leading: Button(action: { self.showVoiceSheet = false }, label: {
Image(systemName: "chevron.backward")
.font(.appNavbarIcon)
.tint(.appGrayTextContrast)
})
}))
}
}

View file

@ -7,20 +7,18 @@
typealias UIViewType = UISlider
@Binding var value: Double
var minValue: Double
var maxValue: Double
@Binding var maxValue: Double
var onEditingChanged: (Bool) -> Void
init(value: Binding<Double>, minValue: Double, maxValue: Double, onEditingChanged: @escaping (Bool) -> Void) {
init(value: Binding<Double>, maxValue: Binding<Double>, onEditingChanged: @escaping (Bool) -> Void) {
self._value = value
self.minValue = minValue
self.maxValue = maxValue
self._maxValue = maxValue
self.onEditingChanged = onEditingChanged
}
func makeUIView(context: Context) -> UISlider {
let slider = UISlider(frame: .zero)
slider.maximumValue = Float(minValue)
slider.minimumValue = Float(0.0)
slider.maximumValue = Float(maxValue)
let tintColor = UIColor(Color.appCtaYellow)
@ -43,6 +41,7 @@
func updateUIView(_ uiView: UISlider, context _: Context) {
uiView.value = Float(value)
uiView.maximumValue = Float(maxValue)
}
func makeCoordinator() -> Coordinator {

View file

@ -207,6 +207,8 @@
@Published public var durationString: String?
@Published public var voiceList: [(name: String, key: String, category: VoiceCategory, selected: Bool)]?
@Published public var textItems: [String]?
let dataService: DataService
var timer: Timer?
@ -266,6 +268,7 @@
timeElapsed = 0
duration = 1
durations = nil
currentAudioIndex = 0
if let stoppedId = stoppedId {
EventTracker.track(
@ -480,8 +483,6 @@
let body: String
}
public var textItems: [String]?
func setTextItems() {
if let document = self.document {
textItems = document.utterances.map { utterance in
@ -491,6 +492,7 @@
}
return ""
}
currentAudioIndex = 0
} else {
textItems = nil
}
@ -940,7 +942,7 @@
let str = String(decoding: data, as: UTF8.self)
print("result speech file: ", str)
let document = try? JSONDecoder().decode(SpeechDocument.self, from: data)
document = try? JSONDecoder().decode(SpeechDocument.self, from: data)
// Cache the file - if it exists
if let document = document {