From 7368d074409e29bba052d58262a0249ef9816b2b Mon Sep 17 00:00:00 2001 From: Benoit Martins Date: Wed, 8 Feb 2023 15:24:00 +0100 Subject: [PATCH] FloatingScrollDownButton UI update (aligned with Android) --- Classes/ChatConversationTableView.h | 1 + Classes/FloatingScrollDownButton.swift | 52 +++++++--- Classes/LinphoneUI/UICheckBoxTableView.m | 2 - .../Views/ChatConversationViewSwift.swift | 97 +++++++++++++++++++ 4 files changed, 136 insertions(+), 16 deletions(-) diff --git a/Classes/ChatConversationTableView.h b/Classes/ChatConversationTableView.h index 58680dd9c..f62ed074c 100644 --- a/Classes/ChatConversationTableView.h +++ b/Classes/ChatConversationTableView.h @@ -61,6 +61,7 @@ @property(nonatomic) NSTimer *ephemeralDisplayTimer; @property (nullable, nonatomic) UIButton *floatingScrollButton; @property (nullable, nonatomic) UILabel *scrollBadge; +@property (nullable, nonatomic) UIButton *floatingScrollBackground; - (void)addEventEntry:(LinphoneEventLog *)event; - (void)scrollToBottom:(BOOL)animated; diff --git a/Classes/FloatingScrollDownButton.swift b/Classes/FloatingScrollDownButton.swift index 9b6089e07..4c0b3fdfd 100644 --- a/Classes/FloatingScrollDownButton.swift +++ b/Classes/FloatingScrollDownButton.swift @@ -11,26 +11,32 @@ import UIKit public extension ChatConversationTableView { private enum Constants { - static let trailingValue: CGFloat = 20.0 + static let trailingValue: CGFloat = 30.0 static let leadingValue: CGFloat = 85.0 - static let buttonHeight: CGFloat = 40.0 - static let buttonWidth: CGFloat = 40.0 + static let buttonHeight: CGFloat = 16.0 + static let buttonWidth: CGFloat = 16.0 } override func viewDidLoad() { super.viewDidLoad() tableView.tableFooterView = UIView() - createFloatingButton() } + override func viewDidAppear(_ animated: Bool) { + super.viewDidAppear(animated) + createFloatingButton() + } + override func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) { if let lastCellRowIndex = tableView.indexPathsForVisibleRows?.last?.row { if( lastCellRowIndex != self.totalNumberOfItems() - 1) { self.floatingScrollButton?.isHidden = false + self.floatingScrollBackground?.isHidden = false; self.scrollBadge?.isHidden = (self.scrollBadge?.text == nil) } else { self.floatingScrollButton?.isHidden = true + self.floatingScrollBackground?.isHidden = true; self.scrollBadge?.text = nil } } @@ -38,27 +44,45 @@ public extension ChatConversationTableView { private func createFloatingButton() { self.floatingScrollButton = UIButton(type: .custom) + self.floatingScrollBackground = UIButton(type: .custom) self.floatingScrollButton?.translatesAutoresizingMaskIntoConstraints = false + self.floatingScrollBackground?.translatesAutoresizingMaskIntoConstraints = false constrainFloatingButtonToWindow() - self.floatingScrollButton?.setImage(UIImage(named: "scroll_to_bottom_default"), for: .normal) - self.floatingScrollButton?.addTarget(self, action: #selector(scrollToBottomButtonAction(_:)), for: .touchUpInside) + var imageFloatingScrollButton = UIImage() + if #available(iOS 13.0, *) { + imageFloatingScrollButton = UIImage(named: "scroll_to_bottom_default")!.withTintColor(.darkGray) + } else { + imageFloatingScrollButton = UIImage(named: "scroll_to_bottom_default")! + } + self.floatingScrollButton?.setImage(imageFloatingScrollButton, for: .normal) self.floatingScrollButton?.isHidden = true; - addBadgeToButon(badge: nil) + self.floatingScrollBackground?.backgroundColor = .lightGray + self.floatingScrollBackground?.layer.cornerRadius = 25 + self.floatingScrollBackground?.isHidden = true; + + self.floatingScrollButton?.addTarget(self, action: #selector(scrollToBottomButtonAction(_:)), for: .touchUpInside) + self.floatingScrollBackground?.addTarget(self, action: #selector(scrollToBottomButtonAction(_:)), for: .touchUpInside) + addBadgeToButton(badge: nil) } private func constrainFloatingButtonToWindow() { DispatchQueue.main.async { guard let keyWindow = UIApplication.shared.keyWindow, let floatingButton = self.floatingScrollButton else { return } + keyWindow.addSubview(self.floatingScrollBackground!) keyWindow.addSubview(floatingButton) - keyWindow.trailingAnchor.constraint(equalTo: floatingButton.trailingAnchor, - constant: Constants.trailingValue).isActive = true - keyWindow.bottomAnchor.constraint(equalTo: floatingButton.bottomAnchor, - constant: Constants.leadingValue).isActive = true + keyWindow.trailingAnchor.constraint(equalTo: floatingButton.trailingAnchor, constant: Constants.trailingValue).isActive = true + floatingButton.bottomAnchor.constraint(equalTo: self.view.bottomAnchor, constant: -25).isActive = true floatingButton.widthAnchor.constraint(equalToConstant: Constants.buttonWidth).isActive = true floatingButton.heightAnchor.constraint(equalToConstant: Constants.buttonHeight).isActive = true + self.floatingScrollBackground?.centerYAnchor.constraint(equalTo: floatingButton.centerYAnchor).isActive = true + self.floatingScrollBackground?.centerXAnchor.constraint(equalTo: floatingButton.centerXAnchor).isActive = true + self.floatingScrollBackground!.widthAnchor.constraint(equalToConstant: + Constants.buttonHeight*3).isActive = true + self.floatingScrollBackground!.heightAnchor.constraint(equalToConstant: + Constants.buttonHeight*3).isActive = true } } @@ -67,7 +91,7 @@ public extension ChatConversationTableView { } - private func addBadgeToButon(badge: String?) { + private func addBadgeToButton(badge: String?) { self.scrollBadge = UILabel() self.scrollBadge?.text = badge self.scrollBadge?.textColor = UIColor.white @@ -86,8 +110,8 @@ public extension ChatConversationTableView { vertical = Double(badgeInset.top) - Double(badgeInset.bottom) horizontal = Double(badgeInset.left) - Double(badgeInset.right) - let x = (Double(scrollButton.bounds.size.width) - 10 + horizontal!) - let y = -(Double(badgeSize.height) / 2) - 10 + vertical! + let x = (Double(scrollButton.bounds.size.width) + 34 + horizontal!) + let y = -(Double(badgeSize.height) / 2) - 38 + vertical! self.scrollBadge?.frame = CGRect(x: x, y: y, width: width, height: height) self.scrollBadge!.layer.cornerRadius = self.scrollBadge!.frame.height/2 diff --git a/Classes/LinphoneUI/UICheckBoxTableView.m b/Classes/LinphoneUI/UICheckBoxTableView.m index 26a5972e0..a01ed8746 100644 --- a/Classes/LinphoneUI/UICheckBoxTableView.m +++ b/Classes/LinphoneUI/UICheckBoxTableView.m @@ -107,11 +107,9 @@ [checkBoxButton setBackgroundColor:[UIColor clearColor]]; checkBoxButton.accessibilityLabel = NSLocalizedString(@"Checkbox", nil); checkBoxButton.userInteractionEnabled = NO; - cell.userInteractionEnabled = NO; cell.accessoryView = checkBoxButton; } else { cell.accessoryView = nil; - cell.userInteractionEnabled = YES; cell.accessoryType = UITableViewCellAccessoryNone; } _deleteButton.enabled = (_selectedItems.count != 0); diff --git a/Classes/Swift/Chat/Views/ChatConversationViewSwift.swift b/Classes/Swift/Chat/Views/ChatConversationViewSwift.swift index 27fcd31b7..3253359e9 100644 --- a/Classes/Swift/Chat/Views/ChatConversationViewSwift.swift +++ b/Classes/Swift/Chat/Views/ChatConversationViewSwift.swift @@ -153,6 +153,8 @@ import AVFoundation @objc var sharingMedia : Bool = false + var isVoiceRecording : Bool = false + override func viewDidLoad() { super.viewDidLoad( backAction: { @@ -268,6 +270,8 @@ import AVFoundation isComposingTextView.text = "" + tableController.floatingScrollBackground?.isHidden = true; + workItem?.cancel() for progressItem in progress{ progressItem.cancel() @@ -1591,4 +1595,97 @@ import AVFoundation let isBasic = charRoomBasic.hasCapability(mask: Int(LinphoneChatRoomCapabilitiesBasic.rawValue)) return isBasic } + + /* + func onVrStart(_ sender: Any) { + if isVoiceRecording { + stopVoiceRecording() + } else { + startVoiceRecording() + } + } + + func createVoiceRecorder() { + let p = linphone_core_create_recorder_params(LC) + linphone_recorder_params_set_file_format(p, LinphoneRecorderFileFormatMkv) + voiceRecorder = linphone_core_create_recorder(LC, p) + } + + func startVoiceRecording() { + UIApplication.shared.isIdleTimerDisabled = true + + if !voiceRecorder { + createVoiceRecorder() + } + CallManager.instance.activateAudioSession() + toggleRecord.selected = true + vrPlayButton.setImage(UIImage(named: "vr_stop"), for: .normal) + + + showVoiceRecorderView = true + updateFramesInclRecordingAndReplyView() + isVoiceRecording = true + vrWaveMaskPlayer.frame = CGRect.zero + + switch linphone_recorder_get_state(voiceRecorder) { + case LinphoneRecorderClosed: + let filename = "\(LinphoneManager.imagesDirectory())/voice-recording-\(UUID().uuidString).mkv" + linphone_recorder_open(voiceRecorder, filename.utf8CString) + linphone_recorder_start(voiceRecorder) + LOGW("[Chat Message Sending] Recorder is closed opening it with %@", filename) + case LinphoneRecorderRunning: + LOGW("[Chat Message Sending] Recorder is already recording") + case LinphoneRecorderPaused: + LOGW("[Chat Message Sending] Recorder isn't closed, resuming recording") + linphone_recorder_start(voiceRecorder) + default: + break + } + vrWaveMask.frame = vrWave.frame + vrDurationLabel.text = formattedDuration(linphone_recorder_get_duration(voiceRecorder)) + vrRecordTimer = Timer.scheduledTimer( + timeInterval: 1.0, + target: self, + selector: Selector("voiceRecordTimerUpdate"), + userInfo: nil, + repeats: true) + } + + func stopVoiceRecording() { + UIApplication.shared.isIdleTimerDisabled = false + if voiceRecorder && linphone_recorder_get_state(voiceRecorder) == LinphoneRecorderRunning { + LOGI("[Chat Message Sending] Pausing / closing voice recorder") + linphone_recorder_pause(voiceRecorder) + linphone_recorder_close(voiceRecorder) + vrDurationLabel.text = formattedDuration(linphone_recorder_get_duration(voiceRecorder)) + } + isVoiceRecording = false + if LinphoneManager.instance.lpConfigBool(forKey: "voice_recording_send_right_away", withDefault: false) { + onSendClick(nil) + } + vrPlayButton.setImage(UIImage(named: "vr_play"), for: .normal) + toggleRecord.selected = false + vrWaveMask.frame = CGRect.zero + vrRecordTimer.invalidate() + isPendingVoiceRecord = linphone_recorder_get_duration(voiceRecorder) > 0 + setSendButtonState() + + } + + func cancelVoiceRecording() { + UIApplication.shared.isIdleTimerDisabled = false + showVoiceRecorderView = false + toggleRecord.selected = false + updateFramesInclRecordingAndReplyView() + isPendingVoiceRecord = false + isVoiceRecording = false + if voiceRecorder && linphone_recorder_get_state(voiceRecorder) != LinphoneRecorderClosed { + linphone_recorder_close(voiceRecorder) + let recordingFile = linphone_recorder_get_file(voiceRecorder) + if let recordingFile { + AppManager.removeFile(withFile: String(utf8String: recordingFile)) + } + } + setSendButtonState() + }*/ }