Various story improvements

This commit is contained in:
Ilya Laktyushin
2023-06-18 18:26:12 +04:00
parent 21b76b0857
commit d968f3aca3
22 changed files with 450 additions and 135 deletions

View File

@@ -30,6 +30,7 @@ public final class MessageInputActionButtonComponent: Component {
case apply
case voiceInput
case videoInput
case unavailableVoiceInput
case delete
case attach
case forward
@@ -213,7 +214,11 @@ public final class MessageInputActionButtonComponent: Component {
guard let self, let component = self.component else {
return
}
component.switchMediaInputMode()
if case .unavailableVoiceInput = component.mode {
component.action(component.mode, .up, false)
} else {
component.switchMediaInputMode()
}
}
micButton.updateCancelTranslation = { [weak self] in
guard let self, let micButton = self.micButton, let component = self.component else {
@@ -223,6 +228,20 @@ public final class MessageInputActionButtonComponent: Component {
}
}
var sendAlpha: CGFloat = 0.0
var microphoneAlpha: CGFloat = 0.0
switch component.mode {
case .none:
break
case .send, .apply, .attach, .delete, .forward:
sendAlpha = 1.0
case .videoInput, .voiceInput:
microphoneAlpha = 1.0
case .unavailableVoiceInput:
microphoneAlpha = 0.4
}
if self.sendIconView.image == nil || previousComponent?.mode.iconName != component.mode.iconName {
if let iconName = component.mode.iconName {
self.sendIconView.image = generateTintedImage(image: UIImage(bundleImageName: iconName), color: .white)
@@ -242,6 +261,21 @@ public final class MessageInputActionButtonComponent: Component {
} else if case .none = component.mode {
self.sendIconView.image = nil
} else {
if !transition.animation.isImmediate {
if let snapshotView = self.sendIconView.snapshotView(afterScreenUpdates: false) {
snapshotView.frame = self.sendIconView.frame
self.addSubview(snapshotView)
transition.setAlpha(view: snapshotView, alpha: 0.0, completion: { [weak snapshotView] _ in
snapshotView?.removeFromSuperview()
})
transition.setScale(view: snapshotView, scale: 0.01)
self.sendIconView.alpha = 0.0
transition.animateAlpha(view: self.sendIconView, from: 0.0, to: sendAlpha)
transition.animateScale(view: self.sendIconView, from: 0.01, to: 1.0)
}
}
self.sendIconView.image = generateImage(CGSize(width: 33.0, height: 33.0), rotatedContext: { size, context in
context.clear(CGRect(origin: CGPoint(), size: size))
context.setFillColor(UIColor.white.cgColor)
@@ -267,18 +301,6 @@ public final class MessageInputActionButtonComponent: Component {
}
}
var sendAlpha: CGFloat = 0.0
var microphoneAlpha: CGFloat = 0.0
switch component.mode {
case .none:
break
case .send, .apply, .attach, .delete, .forward:
sendAlpha = 1.0
case .videoInput, .voiceInput:
microphoneAlpha = 1.0
}
transition.setAlpha(view: self.sendIconView, alpha: sendAlpha)
transition.setScale(view: self.sendIconView, scale: sendAlpha == 0.0 ? 0.01 : 1.0)
@@ -303,7 +325,7 @@ public final class MessageInputActionButtonComponent: Component {
if previousComponent?.mode != component.mode {
switch component.mode {
case .none, .send, .apply, .voiceInput, .attach, .delete, .forward:
case .none, .send, .apply, .voiceInput, .attach, .delete, .forward, .unavailableVoiceInput:
micButton.updateMode(mode: .audio, animated: !transition.animation.isImmediate)
case .videoInput:
micButton.updateMode(mode: .video, animated: !transition.animation.isImmediate)

View File

@@ -30,6 +30,7 @@ public final class MessageInputPanelComponent: Component {
public let style: Style
public let placeholder: String
public let alwaysDarkWhenHasText: Bool
public let areVoiceMessagesAvailable: Bool
public let presentController: (ViewController) -> Void
public let sendMessageAction: () -> Void
public let setMediaRecordingActive: ((Bool, Bool, Bool) -> Void)?
@@ -39,6 +40,7 @@ public final class MessageInputPanelComponent: Component {
public let attachmentAction: (() -> Void)?
public let timeoutAction: ((UIView) -> Void)?
public let forwardAction: (() -> Void)?
public let presentVoiceMessagesUnavailableTooltip: ((UIView) -> Void)?
public let audioRecorder: ManagedAudioRecorder?
public let videoRecordingStatus: InstantVideoControllerRecordingStatus?
public let isRecordingLocked: Bool
@@ -57,6 +59,7 @@ public final class MessageInputPanelComponent: Component {
style: Style,
placeholder: String,
alwaysDarkWhenHasText: Bool,
areVoiceMessagesAvailable: Bool,
presentController: @escaping (ViewController) -> Void,
sendMessageAction: @escaping () -> Void,
setMediaRecordingActive: ((Bool, Bool, Bool) -> Void)?,
@@ -66,6 +69,7 @@ public final class MessageInputPanelComponent: Component {
attachmentAction: (() -> Void)?,
timeoutAction: ((UIView) -> Void)?,
forwardAction: (() -> Void)?,
presentVoiceMessagesUnavailableTooltip: ((UIView) -> Void)?,
audioRecorder: ManagedAudioRecorder?,
videoRecordingStatus: InstantVideoControllerRecordingStatus?,
isRecordingLocked: Bool,
@@ -83,6 +87,7 @@ public final class MessageInputPanelComponent: Component {
self.style = style
self.placeholder = placeholder
self.alwaysDarkWhenHasText = alwaysDarkWhenHasText
self.areVoiceMessagesAvailable = areVoiceMessagesAvailable
self.presentController = presentController
self.sendMessageAction = sendMessageAction
self.setMediaRecordingActive = setMediaRecordingActive
@@ -92,6 +97,7 @@ public final class MessageInputPanelComponent: Component {
self.attachmentAction = attachmentAction
self.timeoutAction = timeoutAction
self.forwardAction = forwardAction
self.presentVoiceMessagesUnavailableTooltip = presentVoiceMessagesUnavailableTooltip
self.audioRecorder = audioRecorder
self.videoRecordingStatus = videoRecordingStatus
self.isRecordingLocked = isRecordingLocked
@@ -125,6 +131,9 @@ public final class MessageInputPanelComponent: Component {
if lhs.alwaysDarkWhenHasText != rhs.alwaysDarkWhenHasText {
return false
}
if lhs.areVoiceMessagesAvailable != rhs.areVoiceMessagesAvailable {
return false
}
if lhs.audioRecorder !== rhs.audioRecorder {
return false
}
@@ -159,7 +168,7 @@ public final class MessageInputPanelComponent: Component {
}
public enum SendMessageInput {
case text(String)
case text(NSAttributedString)
}
public final class View: UIView {
@@ -222,10 +231,10 @@ public final class MessageInputPanelComponent: Component {
public func getSendMessageInput() -> SendMessageInput {
guard let textFieldView = self.textField.view as? TextFieldComponent.View else {
return .text("")
return .text(NSAttributedString())
}
return .text(textFieldView.getText())
return .text(textFieldView.getAttributedText())
}
public func getAttachmentButtonView() -> UIView? {
@@ -237,7 +246,7 @@ public final class MessageInputPanelComponent: Component {
public func clearSendMessageInput() {
if let textFieldView = self.textField.view as? TextFieldComponent.View {
textFieldView.setText(string: "")
textFieldView.setAttributedText(NSAttributedString())
}
}
@@ -308,6 +317,7 @@ public final class MessageInputPanelComponent: Component {
let textFieldSize = self.textField.update(
transition: .immediate,
component: AnyComponent(TextFieldComponent(
strings: component.strings,
externalState: self.textFieldExternalState,
placeholder: ""
)),
@@ -534,7 +544,11 @@ public final class MessageInputPanelComponent: Component {
} else if !self.textFieldExternalState.isEditing && component.forwardAction != nil {
inputActionButtonMode = .forward
} else {
inputActionButtonMode = self.currentMediaInputIsVoice ? .voiceInput : .videoInput
if component.areVoiceMessagesAvailable {
inputActionButtonMode = self.currentMediaInputIsVoice ? .voiceInput : .videoInput
} else {
inputActionButtonMode = .unavailableVoiceInput
}
}
}
}
@@ -554,7 +568,7 @@ public final class MessageInputPanelComponent: Component {
if case .up = action {
if component.recordedAudioPreview != nil {
component.sendMessageAction()
} else if case .text("") = self.getSendMessageInput() {
} else if case let .text(string) = self.getSendMessageInput(), string.string.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
} else {
component.sendMessageAction()
}
@@ -569,6 +583,10 @@ public final class MessageInputPanelComponent: Component {
if case .up = action {
component.forwardAction?()
}
case .unavailableVoiceInput:
if let view = self.inputActionButton.view {
component.presentVoiceMessagesUnavailableTooltip?(view)
}
default:
break
}
@@ -577,6 +595,7 @@ public final class MessageInputPanelComponent: Component {
guard let self else {
return
}
self.currentMediaInputIsVoice = !self.currentMediaInputIsVoice
self.state?.updated(transition: Transition(animation: .curve(duration: 0.4, curve: .spring)))
},