Fix audio player

This commit is contained in:
Benoit Martins 2023-03-06 14:13:17 +01:00 committed by QuentinArguillere
parent 2dd4750ba1
commit 46b62bf4a3
8 changed files with 148 additions and 144 deletions

View file

@ -45,7 +45,6 @@ class ChatConversationTableViewModel: ControlsViewModel {
if let chat = event.chatMessage {
//messageListHistory.append(chat)
messageListHistory.insert(chat, at: 0)
print("MultilineMessageCell configure ChatMessage cell \(messageListHistory.count)")
} //linphone_event_log_get_chat_message(event)
/*
if auto_download is available and file transfer in progress, not add event now
@ -79,7 +78,6 @@ class ChatConversationTableViewModel: ControlsViewModel {
if let chat = event.chatMessage {
//messageListHistory.insert(chat, at: 0)
messageListHistory.append(chat)
print("MultilineMessageCell configure ChatMessage cell added \(messageListHistory.count)")
} //linphone_event_log_get_chat_message(event)
/*
if auto_download is available and file transfer in progress, not add event now
@ -102,13 +100,11 @@ class ChatConversationTableViewModel: ControlsViewModel {
*/
func getMessage(index: Int) -> ChatMessage? {
if (chatRoom == nil) {
print("MultilineMessageCell configure ChatMessage cell empty")
return nil
}
let oneToOne = chatRoom!.hasCapability(mask: Int(LinphoneChatRoomCapabilitiesOneToOne.rawValue))
let chatRoomEvents = chatRoom?.getHistoryRangeEvents(begin: index, end: index+1)
print("MultilineMessageCell configure ChatMessage cell message is \(chatRoomEvents?.first?.chatMessage?.contents.first?.utf8Text)")
return chatRoomEvents?.first?.chatMessage
}

View file

@ -48,7 +48,6 @@ class ChatConversationViewModel: ControlsViewModel {
var replyMessage : OpaquePointer? = nil
var vrRecordTimer = Timer()
var vrPlayerTimer = Timer()
var voiceRecorder : Recorder? = nil
@ -505,7 +504,6 @@ class ChatConversationViewModel: ControlsViewModel {
}
func startVoiceRecording() {
UIApplication.shared.isIdleTimerDisabled = true
if (voiceRecorder == nil) {
createVoiceRecorder()
}
@ -531,7 +529,6 @@ class ChatConversationViewModel: ControlsViewModel {
}
func stopVoiceRecording() {
UIApplication.shared.isIdleTimerDisabled = false
if (ChatConversationViewModel.sharedModel.voiceRecorder != nil) && linphone_recorder_get_state(ChatConversationViewModel.sharedModel.voiceRecorder?.getCobject) == LinphoneRecorderRunning {
print("[Chat Message Sending] Pausing / closing voice recorder")
linphone_recorder_pause(ChatConversationViewModel.sharedModel.voiceRecorder?.getCobject)
@ -552,7 +549,6 @@ class ChatConversationViewModel: ControlsViewModel {
}
func cancelVoiceRecordingVM() {
UIApplication.shared.isIdleTimerDisabled = false
showVoiceRecorderView = false
isPendingVoiceRecord = false
isVoiceRecording = false

View file

@ -24,8 +24,6 @@ class ChatConversationTableViewSwift: UIViewController, UICollectionViewDataSour
return collectionView
}()
var isLoaded = false
var basic :Bool = false
override func viewDidLoad() {
@ -84,8 +82,6 @@ class ChatConversationTableViewSwift: UIViewController, UICollectionViewDataSour
override func viewDidAppear(_ animated: Bool) {
self.collectionView.scrollToItem(at: IndexPath(item: 0, section: 0), at: .top, animated: false)
//print("MultilineMessageCell configure ChatMessage cell loaded")
isLoaded = true
}
@ -93,24 +89,10 @@ class ChatConversationTableViewSwift: UIViewController, UICollectionViewDataSour
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: MultilineMessageCell.reuseId, for: indexPath) as! MultilineMessageCell
//cell.configure(message: ChatConversationTableViewModel.sharedModel.messageListHistory[indexPath.row], isBasic: basic)
print("MultilineMessageCell configure ChatMessage cell \(indexPath.row)")
if let message = ChatConversationTableViewModel.sharedModel.getMessage(index: indexPath.row){
print("MultilineMessageCell configure ChatMessage cell inininni\(indexPath.row)")
cell.configure(message: message, isBasic: basic)
}
/*
if(indexPath.row >= ChatConversationTableViewModel.sharedModel.messageListHistory.count-5 && indexPath.row < ChatConversationTableViewModel.sharedModel.messageListHistory.count-4 && isLoaded){
ChatConversationTableViewModel.sharedModel.addData()
//print("MultilineMessageCell configure ChatMessage cell iiiiinnnnn\(indexPath.row)")
}*/
//print("MultilineMessageCell configure ChatMessage cell \(indexPath.row)")
cell.contentView.transform = CGAffineTransform(scaleX: 1, y: -1)
return cell
}

View file

@ -246,7 +246,6 @@ class ChatConversationViewSwift: BackActionsNavigationView, PHPickerViewControll
messageView.sendButton.onClickAction = onSendClick
messageView.pictureButton.onClickAction = alertAction
messageView.voiceRecordButton.onClickAction = onVrStart
recordingStopButton.onClickAction = stopVoiceRecording
recordingDeleteButton.onClickAction = cancelVoiceRecording
recordingPlayButton.onClickAction = onvrPlayPauseStop
recordingStopButton.onClickAction = onvrPlayPauseStop
@ -261,8 +260,6 @@ class ChatConversationViewSwift: BackActionsNavigationView, PHPickerViewControll
handlePendingTransferIfAny()
configureMessageField()
ChatConversationViewModel.sharedModel.shareFile()
ChatConversationViewModel.sharedModel.initSharedPlayer()
}
override func viewDidAppear(_ animated: Bool) {
@ -1327,7 +1324,6 @@ class ChatConversationViewSwift: BackActionsNavigationView, PHPickerViewControll
}
func onVrStart() {
stopVoiceRecordPlayer()
self.recordingWaveImageMask.isHidden = false
recordingWaveView.progress = 0.0
recordingWaveView.setProgress(recordingWaveView.progress, animated: false)
@ -1420,45 +1416,43 @@ class ChatConversationViewSwift: BackActionsNavigationView, PHPickerViewControll
self.recordingPlayButton.isHidden = true
self.recordingStopButton.isHidden = false
ChatConversationViewModel.sharedModel.initSharedPlayer()
AudioPlayer.sharedModel.fileChanged.value = ChatConversationViewModel.sharedModel.voiceRecorder?.file
ChatConversationViewModel.sharedModel.startSharedPlayer(ChatConversationViewModel.sharedModel.voiceRecorder?.file)
self.animPlayerOnce()
ChatConversationViewModel.sharedModel.vrPlayerTimer = Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true) { timer in
self.animPlayerOnce()
}
recordingWaveView.progress = 0.0
ChatConversationViewModel.sharedModel.isPlayingVoiceRecording = true
}
func animPlayerOnce() {
self.recordingWaveView.progress += 1.0 / Float(AudioPlayer.getSharedPlayer()!.duration/1000)
AudioPlayer.sharedModel.fileChanged.observe { file in
if file != ChatConversationViewModel.sharedModel.voiceRecorder?.file {
if (file != ChatConversationViewModel.sharedModel.voiceRecorder?.file && ChatConversationViewModel.sharedModel.isPlayingVoiceRecording) {
self.stopVoiceRecordPlayer()
}
}
UIView.animate(withDuration: 1, delay: 0.0, options: .curveLinear, animations: {
recordingWaveView.progress = 1.0
UIView.animate(withDuration: TimeInterval(Double(AudioPlayer.getSharedPlayer()!.duration) / 1000.00), delay: 0.0, options: .curveLinear, animations: {
self.recordingWaveView.layoutIfNeeded()
}) { Bool in
if(self.recordingWaveView.progress >= 1.0 && ChatConversationViewModel.sharedModel.isPlayingVoiceRecording){
DispatchQueue.main.asyncAfter(deadline: .now() + 1.5) {
if(ChatConversationViewModel.sharedModel.isPlayingVoiceRecording){
self.stopVoiceRecordPlayer()
}else{
}
}
}, completion: { (finished: Bool) in
if (ChatConversationViewModel.sharedModel.isPlayingVoiceRecording) {
self.stopVoiceRecordPlayer()
}
}
})
}
func stopVoiceRecordPlayer() {
ChatConversationViewModel.sharedModel.stopSharedPlayer()
recordingView.subviews.forEach({ view in
view.removeFromSuperview()
})
resetRecordingProgressBar()
self.recordingWaveView.progress = 0.0
self.recordingWaveView.setProgress(self.recordingWaveView.progress, animated: false)
ChatConversationViewModel.sharedModel.stopSharedPlayer()
self.recordingWaveImageMask.isHidden = false
self.recordingPlayButton.isHidden = false
self.recordingStopButton.isHidden = true
ChatConversationViewModel.sharedModel.isPlayingVoiceRecording = false
ChatConversationViewModel.sharedModel.vrPlayerTimer.invalidate()
}
func configureMessageField() {

View file

@ -20,9 +20,6 @@ class MultilineMessageCell: UICollectionViewCell {
let labelInset = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
var isPlayingVoiceRecording = false
var vrPlayerTimer = Timer()
var constraintLeadingBubble : NSLayoutConstraint? = nil
var constraintTrailingBubble : NSLayoutConstraint? = nil
var labelConstraints: [NSLayoutConstraint] = []
@ -37,11 +34,8 @@ class MultilineMessageCell: UICollectionViewCell {
let imagePlayViewBubble = UIImageView(image: UIImage(named: "vr_play"))
let recordingView = UIView()
let recordingPlayButton = CallControlButton(width: 40, height: 40, buttonTheme:VoipTheme.nav_button("vr_play"))
let recordingStopButton = CallControlButton(width: 40, height: 40, buttonTheme:VoipTheme.nav_button("vr_stop"))
let recordingWaveView = UIProgressView()
let recordingDurationTextView = StyledLabel(VoipTheme.chat_conversation_recording_duration)
let recordingWaveImage = UIImageView(image: UIImage(named: "vr_wave.png"))
var isPlayingVoiceRecording = false
override init(frame: CGRect) {
@ -134,6 +128,16 @@ class MultilineMessageCell: UICollectionViewCell {
recordingView.trailingAnchor.constraint(equalTo: contentBubble.trailingAnchor, constant: labelInset.right-10)
]
recordingView.height(50.0).width(280).done()
recordingView.isHidden = true
}
func initPlayerAudio(message: ChatMessage){
let recordingPlayButton = CallControlButton(width: 40, height: 40, buttonTheme:VoipTheme.nav_button("vr_play"))
let recordingStopButton = CallControlButton(width: 40, height: 40, buttonTheme:VoipTheme.nav_button("vr_stop"))
let recordingWaveView = UIProgressView()
let recordingDurationTextView = StyledLabel(VoipTheme.chat_conversation_recording_duration)
let recordingWaveImage = UIImageView(image: UIImage(named: "vr_wave.png"))
recordingView.addSubview(recordingWaveView)
recordingWaveView.translatesAutoresizingMaskIntoConstraints = false
@ -147,8 +151,6 @@ class MultilineMessageCell: UICollectionViewCell {
recordingWaveView.progressViewStyle = .bar
recordingWaveView.layer.cornerRadius = 5
recordingWaveView.clipsToBounds = true
recordingWaveView.layer.sublayers![1].cornerRadius = 5
recordingWaveView.subviews[1].clipsToBounds = true
recordingWaveView.addSubview(recordingPlayButton)
recordingPlayButton.alignParentLeft(withMargin: 10).matchParentHeight().done()
@ -163,8 +165,33 @@ class MultilineMessageCell: UICollectionViewCell {
recordingWaveView.addSubview(recordingDurationTextView)
recordingDurationTextView.alignParentRight(withMargin: 10).matchParentHeight().done()
recordingView.isHidden = true
let img = message.isOutgoing ? UIImage.withColor(UIColor("A")) : UIImage.withColor(UIColor("D"))
recordingWaveView.progressImage = img
//recordingWaveView.progressTintColor = message.isOutgoing ? UIColor("A").withAlphaComponent(1.0) : UIColor("D").withAlphaComponent(1.0)
recordingDurationTextView.text = recordingDuration(message.contents.first?.filePath)
recordingPlayButton.onClickAction = {
self.playRecordedMessage(voiceRecorder: message.contents.first?.filePath, recordingPlayButton: recordingPlayButton, recordingStopButton: recordingStopButton, recordingWaveView: recordingWaveView, message: message)
}
recordingStopButton.onClickAction = {
self.stopVoiceRecordPlayerAfterAnimation(recordingPlayButton: recordingPlayButton, recordingStopButton: recordingStopButton, recordingWaveView: recordingWaveView, message: message)
}
NSLayoutConstraint.deactivate(labelConstraints)
NSLayoutConstraint.deactivate(imageConstraints)
NSLayoutConstraint.deactivate(videoConstraints)
NSLayoutConstraint.deactivate(playButtonConstraints)
NSLayoutConstraint.activate(recordingConstraints)
NSLayoutConstraint.activate(recordingWaveConstraints)
label.isHidden = true
imageViewBubble.isHidden = true
imageVideoViewBubble.isHidden = true
recordingView.isHidden = false
imageViewBubble.image = nil
imageVideoViewBubble.image = nil
}
required init?(coder aDecoder: NSCoder) {
@ -252,30 +279,11 @@ class MultilineMessageCell: UICollectionViewCell {
imageViewBubble.image = nil
}else if message.contents.first?.type == "audio"{
recordingWaveView.progressTintColor = message.isOutgoing ? UIColor("A") : UIColor("D")
recordingDurationTextView.text = recordingDuration(message.contents.first?.filePath)
recordingPlayButton.onClickAction = {
self.playRecordedMessage(recordingPlayButton: self.recordingPlayButton, recordingStopButton: self.recordingStopButton, recordingWaveView: self.recordingWaveView, voiceRecorder: message.contents.first?.filePath)
}
recordingStopButton.onClickAction = {
self.stopVoiceRecordPlayer(recordingPlayButton: self.recordingPlayButton, recordingStopButton: self.recordingStopButton, recordingWaveView: self.recordingWaveView)
}
NSLayoutConstraint.deactivate(labelConstraints)
NSLayoutConstraint.deactivate(imageConstraints)
NSLayoutConstraint.deactivate(videoConstraints)
NSLayoutConstraint.deactivate(playButtonConstraints)
NSLayoutConstraint.activate(recordingConstraints)
NSLayoutConstraint.activate(recordingWaveConstraints)
label.isHidden = true
imageViewBubble.isHidden = true
imageVideoViewBubble.isHidden = true
recordingView.isHidden = false
imageViewBubble.image = nil
imageVideoViewBubble.image = nil
recordingView.subviews.forEach({ view in
view.removeFromSuperview()
})
initPlayerAudio(message: message)
}else{
//createBubbleOthe()
@ -335,17 +343,30 @@ class MultilineMessageCell: UICollectionViewCell {
}
//Audio
func playRecordedMessage(recordingPlayButton: UIButton, recordingStopButton:UIButton, recordingWaveView: UIProgressView, voiceRecorder: String?) {
func playRecordedMessage(voiceRecorder: String?, recordingPlayButton: CallControlButton, recordingStopButton: CallControlButton, recordingWaveView: UIProgressView, message: ChatMessage) {
AudioPlayer.initSharedPlayer()
AudioPlayer.sharedModel.fileChanged.value = voiceRecorder
recordingPlayButton.isHidden = true
recordingStopButton.isHidden = false
AudioPlayer.startSharedPlayer(voiceRecorder)
self.animPlayerOnce(recordingPlayButton: recordingPlayButton, recordingStopButton: recordingStopButton, recordingWaveView: recordingWaveView, voiceRecorder: voiceRecorder)
vrPlayerTimer = Timer.scheduledTimer(withTimeInterval: 1.01, repeats: true) { timer in
self.animPlayerOnce(recordingPlayButton: recordingPlayButton, recordingStopButton: recordingStopButton, recordingWaveView: recordingWaveView, voiceRecorder: voiceRecorder)
}
recordingWaveView.progress = 0.0
isPlayingVoiceRecording = true
AudioPlayer.sharedModel.fileChanged.observe { file in
if (file != voiceRecorder && self.isPlayingVoiceRecording) {
self.stopVoiceRecordPlayerAfterAnimation(recordingPlayButton: recordingPlayButton, recordingStopButton: recordingStopButton, recordingWaveView: recordingWaveView, message: message)
}
}
recordingWaveView.progress = 1.0
UIView.animate(withDuration: TimeInterval(Double(AudioPlayer.getSharedPlayer()!.duration) / 1000.00), delay: 0.0, options: .curveLinear, animations: {
recordingWaveView.layoutIfNeeded()
}, completion: { (finished: Bool) in
if (self.isPlayingVoiceRecording) {
self.stopVoiceRecordPlayerAfterAnimation(recordingPlayButton: recordingPlayButton, recordingStopButton: recordingStopButton, recordingWaveView: recordingWaveView, message: message)
}
})
}
func recordingDuration(_ _voiceRecordingFile: String?) -> String? {
@ -366,32 +387,16 @@ class MultilineMessageCell: UICollectionViewCell {
return String(format: "%02ld:%02ld", valueMs / 60000, (valueMs % 60000) / 1000)
}
func animPlayerOnce(recordingPlayButton: UIButton, recordingStopButton:UIButton, recordingWaveView: UIProgressView, voiceRecorder: String?) {
recordingWaveView.progress += floor(1.0 / Float(AudioPlayer.getSharedPlayer()!.duration/1000) * 10) / 10.0
AudioPlayer.sharedModel.fileChanged.observe { file in
if (file != voiceRecorder && self.isPlayingVoiceRecording) {
self.stopVoiceRecordPlayer(recordingPlayButton: recordingPlayButton, recordingStopButton: recordingStopButton, recordingWaveView: recordingWaveView)
}
}
UIView.animate(withDuration: 1, delay: 0.0, options: .curveLinear, animations: {
recordingWaveView.layoutIfNeeded()
}) { Bool in
if(recordingWaveView.progress >= 1.0 && self.isPlayingVoiceRecording){
UIView.animate(withDuration: 1, delay: 0.0, options: .curveLinear, animations: {
recordingWaveView.layoutIfNeeded()
})
self.stopVoiceRecordPlayer(recordingPlayButton: recordingPlayButton, recordingStopButton: recordingStopButton, recordingWaveView: recordingWaveView)
}
}
}
func stopVoiceRecordPlayer(recordingPlayButton: UIButton, recordingStopButton:UIButton, recordingWaveView: UIProgressView) {
AudioPlayer.stopSharedPlayer()
func stopVoiceRecordPlayerAfterAnimation(recordingPlayButton: CallControlButton, recordingStopButton: CallControlButton, recordingWaveView: UIProgressView, message: ChatMessage) {
recordingView.subviews.forEach({ view in
view.removeFromSuperview()
})
initPlayerAudio(message: message)
recordingWaveView.progress = 0.0
recordingWaveView.setProgress(recordingWaveView.progress, animated: false)
AudioPlayer.stopSharedPlayer()
recordingPlayButton.isHidden = false
recordingStopButton.isHidden = true
isPlayingVoiceRecording = false
vrPlayerTimer.invalidate()
}
}

View file

@ -48,7 +48,7 @@ class BackActionsNavigationView: UIViewController {
let recordingDeleteButton = CallControlButton(width: 40, height: 40, buttonTheme:VoipTheme.nav_button("delete_default"))
let recordingPlayButton = CallControlButton(width: 40, height: 40, buttonTheme:VoipTheme.nav_button("vr_play"))
let recordingStopButton = CallControlButton(width: 40, height: 40, buttonTheme:VoipTheme.nav_button("vr_stop"))
let recordingWaveView = UIProgressView()
var recordingWaveView = UIProgressView()
let recordingDurationTextView = StyledLabel(VoipTheme.chat_conversation_recording_duration)
let recordingWaveImage = UIImageView(image: UIImage(named: "vr_wave.png"))
let recordingWaveImageMask = UIView()
@ -228,35 +228,7 @@ class BackActionsNavigationView: UIViewController {
recordingView.backgroundColor = VoipTheme.voipToolbarBackgroundColor.get()
recordingView.isHidden = true
recordingView.addSubview(recordingDeleteButton)
recordingDeleteButton.alignParentLeft(withMargin: 10).matchParentHeight().done()
recordingView.addSubview(recordingPlayButton)
recordingPlayButton.alignParentRight(withMargin: 10).matchParentHeight().done()
recordingPlayButton.isHidden = true
recordingView.addSubview(recordingStopButton)
recordingStopButton.alignParentRight(withMargin: 10).matchParentHeight().done()
recordingView.addSubview(recordingWaveView)
recordingWaveView.toRightOf(recordingDeleteButton, withLeftMargin: 10).toLeftOf(recordingStopButton, withRightMargin: 10).alignParentTop(withMargin: 10).alignParentBottom(withMargin: 10).done()
recordingWaveView.progressViewStyle = .bar
recordingWaveView.layer.cornerRadius = 5
recordingWaveView.backgroundColor = VoipTheme.backgroundWhiteBlack.get()
recordingWaveView.progressTintColor = UIColor("L")
recordingWaveView.clipsToBounds = true
recordingWaveView.layer.sublayers![1].cornerRadius = 5
recordingWaveView.subviews[1].clipsToBounds = true
recordingWaveView.addSubview(recordingDurationTextView)
recordingDurationTextView.alignParentRight(withMargin: 10).matchParentHeight().done()
recordingWaveView.addSubview(recordingWaveImage)
recordingWaveImage.alignParentTop(withMargin: 10).alignParentBottom(withMargin: 10).alignParentLeft(withMargin: 10).alignParentRight(withMargin: 65).done()
recordingWaveView.addSubview(recordingWaveImageMask)
recordingWaveImageMask.alignParentTop(withMargin: 5).alignParentBottom(withMargin: 5).alignParentLeft(withMargin: 10).alignParentRight(withMargin: 65).done()
recordingWaveImageMask.backgroundColor = VoipTheme.backgroundWhiteBlack.get()
resetRecordingProgressBar()
stackView.addArrangedSubview(mediaSelector)
mediaSelector.height(top_bar_height*2).matchParentSideBorders().done()
@ -301,6 +273,39 @@ class BackActionsNavigationView: UIViewController {
NotificationCenter.default.addObserver(self, selector: #selector(self.rotated), name: UIDevice.orientationDidChangeNotification, object: nil)
}
func resetRecordingProgressBar(){
recordingView.addSubview(recordingDeleteButton)
recordingDeleteButton.alignParentLeft(withMargin: 10).matchParentHeight().done()
recordingView.addSubview(recordingPlayButton)
recordingPlayButton.alignParentRight(withMargin: 10).matchParentHeight().done()
recordingPlayButton.isHidden = true
recordingView.addSubview(recordingStopButton)
recordingStopButton.alignParentRight(withMargin: 10).matchParentHeight().done()
let newRecordingWaveView = UIProgressView()
recordingWaveView = newRecordingWaveView
recordingView.addSubview(recordingWaveView)
recordingWaveView.toRightOf(recordingDeleteButton, withLeftMargin: 10).toLeftOf(recordingStopButton, withRightMargin: 10).alignParentTop(withMargin: 10).alignParentBottom(withMargin: 10).done()
recordingWaveView.progressViewStyle = .bar
recordingWaveView.layer.cornerRadius = 5
recordingWaveView.backgroundColor = VoipTheme.backgroundWhiteBlack.get()
recordingWaveView.progressImage = UIImage.withColor(UIColor("L"))
recordingWaveView.clipsToBounds = true
recordingWaveView.addSubview(recordingDurationTextView)
recordingDurationTextView.alignParentRight(withMargin: 10).matchParentHeight().done()
recordingWaveView.addSubview(recordingWaveImage)
recordingWaveImage.alignParentTop(withMargin: 10).alignParentBottom(withMargin: 10).alignParentLeft(withMargin: 10).alignParentRight(withMargin: 65).done()
recordingWaveView.addSubview(recordingWaveImageMask)
recordingWaveImageMask.alignParentTop(withMargin: 5).alignParentBottom(withMargin: 5).alignParentLeft(withMargin: 10).alignParentRight(withMargin: 65).done()
recordingWaveImageMask.backgroundColor = VoipTheme.backgroundWhiteBlack.get()
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)

View file

@ -0,0 +1,22 @@
//
// UIImageExtension.swift
// linphone
//
// Created by Benoît Martins on 06/03/2023.
//
import Foundation
extension UIImage {
public static func withColor(_ color: UIColor, size: CGSize = CGSize(width: 1, height: 1)) -> UIImage {
let format = UIGraphicsImageRendererFormat()
format.scale = 1
let image = UIGraphicsImageRenderer(size: size, format: format).image { rendererContext in
color.setFill()
rendererContext.fill(CGRect(origin: .zero, size: size))
}
return image
}
}

View file

@ -952,6 +952,7 @@
D779D39A29A4C285007B8087 /* MultilineMessageCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D779D39929A4C285007B8087 /* MultilineMessageCell.swift */; };
D779D39C29A76DE6007B8087 /* ChatConversationTableViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D779D39B29A76DE6007B8087 /* ChatConversationTableViewModel.swift */; };
D779D39E29AC9E93007B8087 /* AudioPlayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = D779D39D29AC9E92007B8087 /* AudioPlayer.swift */; };
D779D3A229B5E365007B8087 /* UIImageExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = D779D3A129B5E365007B8087 /* UIImageExtension.swift */; };
D7A7545029507038005C9D4A /* CustomAlertController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7A7544F29507038005C9D4A /* CustomAlertController.swift */; };
D7C6DE832948CF3100756E03 /* DropDownCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7C6DE812948CF3100756E03 /* DropDownCell.swift */; };
D7C6DE842948CF3100756E03 /* DropDownCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = D7C6DE822948CF3100756E03 /* DropDownCell.xib */; };
@ -2195,6 +2196,7 @@
D779D39929A4C285007B8087 /* MultilineMessageCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MultilineMessageCell.swift; sourceTree = "<group>"; };
D779D39B29A76DE6007B8087 /* ChatConversationTableViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatConversationTableViewModel.swift; sourceTree = "<group>"; };
D779D39D29AC9E92007B8087 /* AudioPlayer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AudioPlayer.swift; sourceTree = "<group>"; };
D779D3A129B5E365007B8087 /* UIImageExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIImageExtension.swift; sourceTree = "<group>"; };
D7A7544F29507038005C9D4A /* CustomAlertController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomAlertController.swift; sourceTree = "<group>"; };
D7C6DE812948CF3100756E03 /* DropDownCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DropDownCell.swift; sourceTree = "<group>"; };
D7C6DE822948CF3100756E03 /* DropDownCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = DropDownCell.xib; sourceTree = "<group>"; };
@ -3463,6 +3465,7 @@
D74A44902923BAF90017D063 /* BackActionsNavigationView.swift */,
D7A7544F29507038005C9D4A /* CustomAlertController.swift */,
D779D39D29AC9E92007B8087 /* AudioPlayer.swift */,
D779D3A129B5E365007B8087 /* UIImageExtension.swift */,
);
path = Util;
sourceTree = "<group>";
@ -5255,6 +5258,7 @@
D7DA18712A02598700FABA0D /* TextViewer.swift in Sources */,
669B140C27A29D140012220A /* FloatingScrollDownButton.swift in Sources */,
C63F7219285A24B10066163B /* ConferenceHistoryDetailsView.swift in Sources */,
D779D3A229B5E365007B8087 /* UIImageExtension.swift in Sources */,
D3A8BB7015A6C7D500F96BE5 /* UIChatBubbleTextCell.m in Sources */,
63D11C531C3D501200E8FCEE /* Log.m in Sources */,
D3128FE115AABC7E00A2147A /* ContactDetailsView.m in Sources */,