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

Add the left time in the Voice Broadcast tile recorder #7103

Merged
merged 7 commits into from
Nov 25, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Config/BuildSettings.swift
Original file line number Diff line number Diff line change
Expand Up @@ -409,7 +409,7 @@ final class BuildSettings: NSObject {

// MARK: - Voice Broadcast
static let voiceBroadcastChunkLength: Int = 120
static let voiceBroadcastMaxLength: UInt64 = 144000
static let voiceBroadcastMaxLength: UInt = 14400 // 240min.

// MARK: - MXKAppSettings
static let enableBotCreation: Bool = false
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"images" : [
{
"filename" : "voice_broadcast_time_left.svg",
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions Riot/Assets/en.lproj/Vector.strings
Original file line number Diff line number Diff line change
Expand Up @@ -2196,6 +2196,7 @@ Tap the + to start adding people.";
"voice_broadcast_playback_loading_error" = "Unable to play this voice broadcast.";
"voice_broadcast_live" = "Live";
"voice_broadcast_tile" = "Voice broadcast";
"voice_broadcast_time_left" = "%@ left";

// Mark: - Version check

Expand Down
1 change: 1 addition & 0 deletions Riot/Generated/Images.swift
Original file line number Diff line number Diff line change
Expand Up @@ -347,6 +347,7 @@ internal class Asset: NSObject {
internal static let voiceBroadcastStop = ImageAsset(name: "voice_broadcast_stop")
internal static let voiceBroadcastTileLive = ImageAsset(name: "voice_broadcast_tile_live")
internal static let voiceBroadcastTileMic = ImageAsset(name: "voice_broadcast_tile_mic")
internal static let voiceBroadcastTimeLeft = ImageAsset(name: "voice_broadcast_time_left")
internal static let launchScreenLogo = ImageAsset(name: "launch_screen_logo")
}
@objcMembers
Expand Down
4 changes: 4 additions & 0 deletions Riot/Generated/Strings.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9139,6 +9139,10 @@ public class VectorL10n: NSObject {
public static var voiceBroadcastTile: String {
return VectorL10n.tr("Vector", "voice_broadcast_tile")
}
/// %@ left
public static func voiceBroadcastTimeLeft(_ p1: String) -> String {
return VectorL10n.tr("Vector", "voice_broadcast_time_left", p1)
}
/// Can't start a new voice broadcast
public static var voiceBroadcastUnauthorizedTitle: String {
return VectorL10n.tr("Vector", "voice_broadcast_unauthorized_title")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,12 @@ class SizableBaseRoomCell: BaseRoomCell, SizableBaseRoomCellType {

return self.height(for: roomBubbleCellData, fitting: maxWidth)
}

override func prepareForReuse() {
cleanContentVC()

super.prepareForReuse()
}

// MARK - SizableBaseRoomCellType

Expand Down Expand Up @@ -173,10 +179,21 @@ class SizableBaseRoomCell: BaseRoomCell, SizableBaseRoomCellType {
}

return height
}

}

private func cleanContentVC() {
contentVC?.removeFromParent()
contentVC?.view.removeFromSuperview()
contentVC?.didMove(toParent: nil)
contentVC = nil
}

// MARK: - Public

func addContentViewController(_ controller: UIViewController, on contentView: UIView) {
controller.view.invalidateIntrinsicContentSize()

cleanContentVC()

let parent = vc_parentViewController
parent?.addChild(controller)
Expand All @@ -185,13 +202,4 @@ class SizableBaseRoomCell: BaseRoomCell, SizableBaseRoomCellType {

contentVC = controller
}

override func prepareForReuse() {
contentVC?.removeFromParent()
contentVC?.view.removeFromSuperview()
contentVC?.didMove(toParent: nil)
contentVC = nil

super.prepareForReuse()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,13 @@ class VoiceBroadcastRecorderService: VoiceBroadcastRecorderServiceProtocol {
private var chunkFile: AVAudioFile! = nil
private var chunkFrames: AVAudioFrameCount = 0
private var chunkFileNumber: Int = 0


private var currentElapsedTime: UInt = 0 // Time in seconds.
private var currentRemainingTime: UInt { // Time in seconds.
BuildSettings.voiceBroadcastMaxLength - currentElapsedTime
}
private var elapsedTimeTimer: Timer?

// MARK: Public

weak var serviceDelegate: VoiceBroadcastRecorderServiceDelegate?
Expand Down Expand Up @@ -67,12 +73,14 @@ class VoiceBroadcastRecorderService: VoiceBroadcastRecorderServiceProtocol {
}

try audioEngine.start()
startTimer()

// Disable the sleep mode during the recording until we are able to handle it
UIApplication.shared.isIdleTimerDisabled = true
} catch {
MXLog.debug("[VoiceBroadcastRecorderService] startRecordingVoiceBroadcast error", context: error)
stopRecordingVoiceBroadcast()
invalidateTimer()
}
}

Expand All @@ -81,6 +89,7 @@ class VoiceBroadcastRecorderService: VoiceBroadcastRecorderServiceProtocol {
audioEngine.stop()
audioEngine.inputNode.removeTap(onBus: audioNodeBus)
UIApplication.shared.isIdleTimerDisabled = false
invalidateTimer()

voiceBroadcastService?.stopVoiceBroadcast(success: { [weak self] _ in
MXLog.debug("[VoiceBroadcastRecorderService] Stopped")
Expand Down Expand Up @@ -110,6 +119,7 @@ class VoiceBroadcastRecorderService: VoiceBroadcastRecorderServiceProtocol {
func pauseRecordingVoiceBroadcast() {
audioEngine.pause()
UIApplication.shared.isIdleTimerDisabled = false
invalidateTimer()

voiceBroadcastService?.pauseVoiceBroadcast(success: { [weak self] _ in
guard let self = self else { return }
Expand All @@ -126,6 +136,7 @@ class VoiceBroadcastRecorderService: VoiceBroadcastRecorderServiceProtocol {

func resumeRecordingVoiceBroadcast() {
try? audioEngine.start()
startTimer()

voiceBroadcastService?.resumeVoiceBroadcast(success: { [weak self] _ in
guard let self = self else { return }
Expand All @@ -143,12 +154,14 @@ class VoiceBroadcastRecorderService: VoiceBroadcastRecorderServiceProtocol {
private func resetValues() {
chunkFrames = 0
chunkFileNumber = 0
currentElapsedTime = 0
}

/// Release the service
private func tearDownVoiceBroadcastService() {
resetValues()
session.tearDownVoiceBroadcastService()
invalidateTimer()

do {
try AVAudioSession.sharedInstance().setActive(false)
Expand All @@ -157,6 +170,31 @@ class VoiceBroadcastRecorderService: VoiceBroadcastRecorderServiceProtocol {
}
}

/// Start ElapsedTimeTimer.
private func startTimer() {
elapsedTimeTimer = Timer.scheduledTimer(timeInterval: 1.0,
target: self,
selector: #selector(updateCurrentElapsedTimeValue),
userInfo: nil,
repeats: true)
}

/// Invalidate ElapsedTimeTimer.
private func invalidateTimer() {
elapsedTimeTimer?.invalidate()
elapsedTimeTimer = nil
}

/// Update currentElapsedTime value.
@objc private func updateCurrentElapsedTimeValue() {
guard currentRemainingTime > 0 else {
stopRecordingVoiceBroadcast()
return
}
currentElapsedTime += 1
serviceDelegate?.voiceBroadcastRecorderService(self, didUpdateRemainingTime: self.currentRemainingTime)
}

/// Write audio buffer to chunk file.
private func writeBuffer(_ buffer: AVAudioPCMBuffer) {
let sampleRate = buffer.format.sampleRate
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import Foundation

protocol VoiceBroadcastRecorderServiceDelegate: AnyObject {
func voiceBroadcastRecorderService(_ service: VoiceBroadcastRecorderServiceProtocol, didUpdateState state: VoiceBroadcastRecorderState)
func voiceBroadcastRecorderService(_ service: VoiceBroadcastRecorderServiceProtocol, didUpdateRemainingTime remainingTime: UInt)
}

protocol VoiceBroadcastRecorderServiceProtocol {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,14 @@ struct VoiceBroadcastRecorderView: View {
} icon: {
Image(uiImage: Asset.Images.voiceBroadcastTileLive.image)
}

Label {
Text(viewModel.viewState.currentRecordingState.remainingTimeLabel)
.foregroundColor(theme.colors.secondaryContent)
.font(theme.fonts.caption1)
} icon: {
Image(uiImage: Asset.Images.voiceBroadcastTimeLeft.image)
}
}.frame(maxWidth: .infinity, alignment: .leading)

Label {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,15 @@ struct VoiceBroadcastRecorderDetails {
let avatarData: AvatarInputProtocol
}

struct VoiceBroadcastRecordingState {
var remainingTime: UInt
var remainingTimeLabel: String
}

struct VoiceBroadcastRecorderViewState: BindableState {
var details: VoiceBroadcastRecorderDetails
var recordingState: VoiceBroadcastRecorderState
var currentRecordingState: VoiceBroadcastRecordingState
var bindings: VoiceBroadcastRecorderViewStateBindings
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ enum MockVoiceBroadcastRecorderScreenState: MockScreenState, CaseIterable {

var screenView: ([Any], AnyView) {
let details = VoiceBroadcastRecorderDetails(senderDisplayName: "", avatarData: AvatarInput(mxContentUri: "", matrixItemId: "!fakeroomid:matrix.org", displayName: "The name of the room"))
let viewModel = MockVoiceBroadcastRecorderViewModel(initialViewState: VoiceBroadcastRecorderViewState(details: details, recordingState: .started, bindings: VoiceBroadcastRecorderViewStateBindings()))
let recordingState = VoiceBroadcastRecordingState(remainingTime: BuildSettings.voiceBroadcastMaxLength, remainingTimeLabel: "1h 20m 47s left")
let viewModel = MockVoiceBroadcastRecorderViewModel(initialViewState: VoiceBroadcastRecorderViewState(details: details, recordingState: .started, currentRecordingState: recordingState, bindings: VoiceBroadcastRecorderViewStateBindings()))

return (
[false, viewModel],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,10 @@ class VoiceBroadcastRecorderViewModel: VoiceBroadcastRecorderViewModelType, Voic
init(details: VoiceBroadcastRecorderDetails,
recorderService: VoiceBroadcastRecorderServiceProtocol) {
self.voiceBroadcastRecorderService = recorderService
let currentRecordingState = VoiceBroadcastRecorderViewModel.currentRecordingState(from: BuildSettings.voiceBroadcastMaxLength)
super.init(initialViewState: VoiceBroadcastRecorderViewState(details: details,
recordingState: .stopped,
currentRecordingState: currentRecordingState,
bindings: VoiceBroadcastRecorderViewStateBindings()))

self.voiceBroadcastRecorderService.serviceDelegate = self
Expand Down Expand Up @@ -77,10 +79,27 @@ class VoiceBroadcastRecorderViewModel: VoiceBroadcastRecorderViewModelType, Voic
self.state.recordingState = .resumed
voiceBroadcastRecorderService.resumeRecordingVoiceBroadcast()
}

private func updateRemainingTime(_ remainingTime: UInt) {
state.currentRecordingState = VoiceBroadcastRecorderViewModel.currentRecordingState(from: remainingTime)
}

private static func currentRecordingState(from remainingTime: UInt) -> VoiceBroadcastRecordingState {
let time = TimeInterval(Double(remainingTime))
let formatter = DateComponentsFormatter()
formatter.unitsStyle = .abbreviated

return VoiceBroadcastRecordingState(remainingTime: remainingTime,
remainingTimeLabel: VectorL10n.voiceBroadcastTimeLeft(formatter.string(from: time) ?? "0s"))
}
}

extension VoiceBroadcastRecorderViewModel: VoiceBroadcastRecorderServiceDelegate {
func voiceBroadcastRecorderService(_ service: VoiceBroadcastRecorderServiceProtocol, didUpdateState state: VoiceBroadcastRecorderState) {
self.state.recordingState = state
}

func voiceBroadcastRecorderService(_ service: VoiceBroadcastRecorderServiceProtocol, didUpdateRemainingTime remainingTime: UInt) {
self.updateRemainingTime(remainingTime)
}
}
1 change: 1 addition & 0 deletions changelog.d/pr-7103.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Add the left time in the Voice Broadcast tile recorder.
1 change: 1 addition & 0 deletions changelog.d/pr-7105.bugfix
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fix scroll issues with VoiceBroadcast and Poll cells