Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix: #94,#97,#99 #95

Open
wants to merge 9 commits into
base: main
Choose a base branch
from
62 changes: 35 additions & 27 deletions Sources/ExyteChat/ChatView/Recording/RecordWaveform.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ struct RecordWaveformWithButtons: View {
@Environment(\.chatTheme) private var theme

@StateObject var recordPlayer = RecordingPlayer()
//160 is screen left-padding/right-padding and playButton's width.
//To ensure that the view does not exceed the screen, need to subtract
static let viewPadding:CGFloat = 160
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how can you guarantee that this will always be 160? you should pass this value using frame getters from wherever it is set in


var recording: Recording

Expand Down Expand Up @@ -53,20 +56,29 @@ struct RecordWaveformWithButtons: View {
}

struct RecordWaveformPlaying: View {

Copy link
Collaborator

@f3dm76 f3dm76 Sep 17, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please preserve the selected code style, namely:

  • do not add extra spaces (Xcode > Preferences > Text Editing > While editing > Automatically trim trailing whitespaces+Including whitespace-only lines)
  • do not add extra \n like here:
var body: some View {

        GeometryReader { g in
  • after // there should be a space
  • after // there is a small letter
    // ensure that the view does not exceed the screen
  • viewPadding:CGFloat - there should be a space here: "viewPadding: CGFloat"
  • there should be a \n between these lines:
@StateObject var recordPlayer = RecordingPlayer()
//160 is screen left-padding/right-padding and playButton's width.

var samples: [CGFloat] // 0...1
var progress: CGFloat
var color: Color
var addExtraDots: Bool

var maxLength: CGFloat {
max((RecordWaveform.spacing + RecordWaveform.width) * CGFloat(samples.count) - RecordWaveform.spacing, 0)
var maxLength: CGFloat = 0.0

private var adjustedSamples: [CGFloat] = []

init(samples: [CGFloat], progress: CGFloat, color: Color, addExtraDots: Bool) {
self.samples = samples
self.progress = progress
self.color = color
self.addExtraDots = addExtraDots
self.adjustedSamples = adjustedSamples(UIScreen.main.bounds.width)
self.maxLength = max((RecordWaveform.spacing + RecordWaveform.width) * CGFloat(self.adjustedSamples.count) - RecordWaveform.spacing, 0)
}

var body: some View {

GeometryReader { g in
ZStack {
let adjusted = adjustedSamples(g.size.width)
let adjusted = addExtraDots ? adjustedSamples(g.size.width) : adjustedSamples
RecordWaveform(samples: adjusted, addExtraDots: addExtraDots)
.foregroundColor(color.opacity(0.4))
RecordWaveform(samples: adjusted, addExtraDots: addExtraDots)
Expand All @@ -77,6 +89,7 @@ struct RecordWaveformPlaying: View {
}
}
.frame(height: RecordWaveform.maxSampleHeight)

}
.frame(height: RecordWaveform.maxSampleHeight)
.applyIf(!addExtraDots) {
Expand All @@ -86,27 +99,22 @@ struct RecordWaveformPlaying: View {
.fixedSize(horizontal: !addExtraDots, vertical: true)
}

func adjustedSamples(_ width: CGFloat) -> [CGFloat] {
let maxWidth = addExtraDots ? width : UIScreen.main.bounds.width
let maxSamples = Int(maxWidth / (RecordWaveform.width + RecordWaveform.spacing))

var adjusted = samples
var temp = [CGFloat]()
while adjusted.count > maxSamples {
var i = 0
while i < adjusted.count {
if i == adjusted.count - 1 {
temp.append(adjusted[i])
break
}

temp.append((adjusted[i] + adjusted[i+1])/2)
i+=2
}
adjusted = temp
temp = []
func adjustedSamples(_ maxWidth: CGFloat) -> [CGFloat] {

let maxSamples = Int((maxWidth - RecordWaveformWithButtons.viewPadding) / (RecordWaveform.width + RecordWaveform.spacing))
let temp = samples

if temp.count <= maxSamples {
return temp
}
//Use ceil to ensure that the adjusted.count will not be greater than maxSamples
let ratio = Int(ceil( Double(temp.count) / Double(maxSamples) ))
let adjusted = stride(from: 0, to: temp.count, by: ratio).map {
temp[$0]
}

return adjusted

}
}

Expand All @@ -126,9 +134,9 @@ struct RecordWaveform: View {
Capsule()
.frame(width: RecordWaveform.width, height: RecordWaveform.maxSampleHeight * CGFloat(s))
}

if addExtraDots {
ForEach(samples.count..<Int(g.size.width / (RecordWaveform.width + RecordWaveform.spacing)), id: \.self) { _ in
let maxSampleCounts = Int((g.size.width) / (RecordWaveform.width + RecordWaveform.spacing))
if addExtraDots && samples.count < maxSampleCounts {
ForEach(samples.count..<maxSampleCounts, id: \.self) { _ in
Capsule()
.viewSize(RecordWaveform.width)
}
Expand Down
10 changes: 10 additions & 0 deletions Sources/ExyteChat/ChatView/Recording/RecordingPlayer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ final class RecordingPlayer: ObservableObject {
try? audioSession.setActive(true)
player?.play()
playing = true
NotificationCenter.default.post(name: .chatAudioIsPlaying, object: self)
}

private func setupPlayer(for url: URL, trackDuration: Double) {
Expand All @@ -83,6 +84,15 @@ final class RecordingPlayer: ObservableObject {

let playerItem = AVPlayerItem(url: url)
player = AVPlayer(playerItem: playerItem)

NotificationCenter.default.addObserver(forName: .chatAudioIsPlaying, object: nil, queue: .main) { notification in
if let sender = notification.object as? RecordingPlayer {
if sender.recording?.url == self.recording?.url {
return
}
self.pause()
}
}

NotificationCenter.default.addObserver(
forName: .AVPlayerItemDidPlayToEndTime,
Expand Down
12 changes: 12 additions & 0 deletions Sources/ExyteChat/Extensions/Notification+.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
//
// File.swift
//
//
// Created by admin on 2024/9/17.
//

import Foundation

extension Notification.Name {
static let chatAudioIsPlaying = Notification.Name("chatAudioIsPlaying")
}