mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-24 07:05:35 +00:00
Various improvements
This commit is contained in:
@@ -22,6 +22,7 @@ import ContextReferenceButtonComponent
|
||||
import ForwardInfoPanelComponent
|
||||
import MultilineTextComponent
|
||||
import PlainButtonComponent
|
||||
import GlassBackgroundComponent
|
||||
|
||||
private var sharedIsReduceTransparencyEnabled = UIAccessibility.isReduceTransparencyEnabled
|
||||
|
||||
@@ -48,6 +49,7 @@ public final class MessageInputPanelComponent: Component {
|
||||
case story
|
||||
case editor
|
||||
case media
|
||||
case glass
|
||||
}
|
||||
|
||||
public enum InputMode: Hashable {
|
||||
@@ -141,7 +143,7 @@ public final class MessageInputPanelComponent: Component {
|
||||
}
|
||||
|
||||
public final class ExternalState {
|
||||
public fileprivate(set) var isEditing: Bool = false
|
||||
public var isEditing: Bool = false
|
||||
public fileprivate(set) var hasText: Bool = false
|
||||
public fileprivate(set) var isKeyboardHidden: Bool = false
|
||||
|
||||
@@ -154,6 +156,18 @@ public final class MessageInputPanelComponent: Component {
|
||||
}
|
||||
}
|
||||
|
||||
public final class SendActionTransition {
|
||||
public let textSnapshotView: UIView
|
||||
public let globalFrame: CGRect
|
||||
public let cornerRadius: CGFloat
|
||||
|
||||
init(textSnapshotView: UIView, globalFrame: CGRect, cornerRadius: CGFloat) {
|
||||
self.textSnapshotView = textSnapshotView
|
||||
self.globalFrame = globalFrame
|
||||
self.cornerRadius = cornerRadius
|
||||
}
|
||||
}
|
||||
|
||||
public let externalState: ExternalState
|
||||
public let context: AccountContext
|
||||
public let theme: PresentationTheme
|
||||
@@ -170,7 +184,7 @@ public final class MessageInputPanelComponent: Component {
|
||||
public let areVoiceMessagesAvailable: Bool
|
||||
public let presentController: (ViewController) -> Void
|
||||
public let presentInGlobalOverlay: (ViewController) -> Void
|
||||
public let sendMessageAction: () -> Void
|
||||
public let sendMessageAction: (SendActionTransition?) -> Void
|
||||
public let sendMessageOptionsAction: ((UIView, ContextGesture?) -> Void)?
|
||||
public let sendStickerAction: (TelegramMediaFile) -> Void
|
||||
public let setMediaRecordingActive: ((Bool, Bool, Bool, UIView?) -> Void)?
|
||||
@@ -229,7 +243,7 @@ public final class MessageInputPanelComponent: Component {
|
||||
areVoiceMessagesAvailable: Bool,
|
||||
presentController: @escaping (ViewController) -> Void,
|
||||
presentInGlobalOverlay: @escaping (ViewController) -> Void,
|
||||
sendMessageAction: @escaping () -> Void,
|
||||
sendMessageAction: @escaping (SendActionTransition?) -> Void,
|
||||
sendMessageOptionsAction: ((UIView, ContextGesture?) -> Void)?,
|
||||
sendStickerAction: @escaping (TelegramMediaFile) -> Void,
|
||||
setMediaRecordingActive: ((Bool, Bool, Bool, UIView?) -> Void)?,
|
||||
@@ -464,6 +478,7 @@ public final class MessageInputPanelComponent: Component {
|
||||
public final class View: UIView {
|
||||
private let fieldBackgroundView: BlurredBackgroundView
|
||||
private let fieldBackgroundTint: UIView
|
||||
private var fieldGlassBackgroundView: GlassBackgroundView?
|
||||
private let gradientView: UIImageView
|
||||
private let bottomGradientView: UIView
|
||||
|
||||
@@ -773,12 +788,18 @@ public final class MessageInputPanelComponent: Component {
|
||||
insets.right = 41.0
|
||||
}
|
||||
|
||||
var textFieldSideInset = 9.0
|
||||
if case .media = component.style {
|
||||
let textFieldSideInset: CGFloat
|
||||
switch component.style {
|
||||
case .media, .glass:
|
||||
textFieldSideInset = 8.0
|
||||
default:
|
||||
textFieldSideInset = 9.0
|
||||
}
|
||||
|
||||
let mediaInsets = UIEdgeInsets(top: insets.top, left: textFieldSideInset, bottom: insets.bottom, right: 41.0)
|
||||
var mediaInsets = UIEdgeInsets(top: insets.top, left: textFieldSideInset, bottom: insets.bottom, right: 41.0)
|
||||
if case .glass = component.style {
|
||||
mediaInsets.right = 54.0
|
||||
}
|
||||
|
||||
let baseFieldHeight: CGFloat = 40.0
|
||||
|
||||
@@ -1025,6 +1046,8 @@ public final class MessageInputPanelComponent: Component {
|
||||
var fieldBackgroundFrame: CGRect
|
||||
if hasMediaRecording {
|
||||
fieldBackgroundFrame = CGRect(origin: CGPoint(x: mediaInsets.left, y: insets.top), size: CGSize(width: availableSize.width - mediaInsets.left - mediaInsets.right, height: fieldFrame.height))
|
||||
} else if case .glass = component.style {
|
||||
fieldBackgroundFrame = CGRect(origin: CGPoint(x: mediaInsets.left, y: insets.top), size: CGSize(width: availableSize.width - mediaInsets.left - mediaInsets.right, height: fieldFrame.height))
|
||||
} else if isEditing || component.style == .editor || component.style == .media {
|
||||
fieldBackgroundFrame = fieldFrame
|
||||
} else {
|
||||
@@ -1042,6 +1065,25 @@ public final class MessageInputPanelComponent: Component {
|
||||
|
||||
//transition.setFrame(view: self.vibrancyEffectView, frame: CGRect(origin: CGPoint(), size: fieldBackgroundFrame.size))
|
||||
|
||||
switch component.style {
|
||||
case .glass:
|
||||
if self.fieldGlassBackgroundView == nil {
|
||||
let fieldGlassBackgroundView = GlassBackgroundView(frame: fieldBackgroundFrame)
|
||||
self.insertSubview(fieldGlassBackgroundView, aboveSubview: self.fieldBackgroundView)
|
||||
self.fieldGlassBackgroundView = fieldGlassBackgroundView
|
||||
|
||||
self.fieldBackgroundView.isHidden = true
|
||||
self.fieldBackgroundTint.isHidden = true
|
||||
}
|
||||
if let fieldGlassBackgroundView = self.fieldGlassBackgroundView {
|
||||
let backgroundColor = UIColor(rgb: 0x1b1d22)
|
||||
fieldGlassBackgroundView.update(size: fieldBackgroundFrame.size, cornerRadius: baseFieldHeight * 0.5, isDark: true, tintColor: backgroundColor, transition: transition)
|
||||
transition.setFrame(view: fieldGlassBackgroundView, frame: fieldBackgroundFrame)
|
||||
}
|
||||
default:
|
||||
break
|
||||
}
|
||||
|
||||
transition.setFrame(view: self.fieldBackgroundView, frame: fieldBackgroundFrame)
|
||||
self.fieldBackgroundView.update(size: fieldBackgroundFrame.size, cornerRadius: headerHeight > 0.0 ? 18.0 : baseFieldHeight * 0.5, transition: transition.containedViewLayoutTransition)
|
||||
transition.setFrame(view: self.fieldBackgroundTint, frame: fieldBackgroundFrame)
|
||||
@@ -1063,7 +1105,7 @@ public final class MessageInputPanelComponent: Component {
|
||||
transition.setAlpha(view: self.bottomGradientView, alpha: component.displayGradient ? 1.0 : 0.0)
|
||||
|
||||
let placeholderOriginX: CGFloat
|
||||
if isEditing || component.style == .story {
|
||||
if isEditing || component.style == .story || component.style == .glass {
|
||||
placeholderOriginX = 16.0
|
||||
} else {
|
||||
placeholderOriginX = floorToScreenPixels(fieldBackgroundFrame.minX + (fieldBackgroundFrame.width - placeholderSize.width) / 2.0)
|
||||
@@ -1456,6 +1498,7 @@ public final class MessageInputPanelComponent: Component {
|
||||
}
|
||||
}
|
||||
|
||||
var inputActionButtonAvailableSize = CGSize(width: 33.0, height: 33.0)
|
||||
var inputActionButtonAlpha = 1.0
|
||||
let inputActionButtonMode: MessageInputActionButtonComponent.Mode
|
||||
if case .editor = component.style {
|
||||
@@ -1469,12 +1512,19 @@ public final class MessageInputPanelComponent: Component {
|
||||
if !isEditing {
|
||||
inputActionButtonAlpha = 0.0
|
||||
}
|
||||
} else if case .glass = component.style {
|
||||
inputActionButtonAvailableSize = CGSize(width: 40.0, height: 40.0)
|
||||
if self.textFieldExternalState.hasText {
|
||||
inputActionButtonMode = .send
|
||||
} else {
|
||||
inputActionButtonMode = .close
|
||||
}
|
||||
} else {
|
||||
if hasMediaEditing {
|
||||
inputActionButtonMode = .send
|
||||
} else {
|
||||
if self.textFieldExternalState.hasText {
|
||||
if let sendPaidMessageStars = component.sendPaidMessageStars, "".isEmpty {
|
||||
if let sendPaidMessageStars = component.sendPaidMessageStars, !"".isEmpty {
|
||||
inputActionButtonMode = .stars(sendPaidMessageStars.value)
|
||||
} else {
|
||||
inputActionButtonMode = .send
|
||||
@@ -1494,6 +1544,7 @@ public final class MessageInputPanelComponent: Component {
|
||||
transition: transition,
|
||||
component: AnyComponent(MessageInputActionButtonComponent(
|
||||
mode: inputActionButtonMode,
|
||||
style: component.style == .glass ? .glass : .legacy,
|
||||
storyId: component.storyItem?.id,
|
||||
action: { [weak self] mode, action, sendAction in
|
||||
guard let self, let component = self.component else {
|
||||
@@ -1503,19 +1554,29 @@ public final class MessageInputPanelComponent: Component {
|
||||
switch mode {
|
||||
case .none:
|
||||
break
|
||||
case .close:
|
||||
component.sendMessageAction(nil)
|
||||
case .send, .stars:
|
||||
if case .up = action {
|
||||
if component.recordedAudioPreview != nil {
|
||||
component.sendMessageAction()
|
||||
component.sendMessageAction(nil)
|
||||
} else if component.hasRecordedVideoPreview {
|
||||
component.sendMessageAction()
|
||||
component.sendMessageAction(nil)
|
||||
} else if case let .text(string) = self.getSendMessageInput(), string.string.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
|
||||
} else {
|
||||
if let maxLength = component.maxLength, self.textFieldExternalState.textLength > maxLength {
|
||||
self.animateError()
|
||||
component.presentTextLengthLimitTooltip?()
|
||||
} else {
|
||||
component.sendMessageAction()
|
||||
var sendActionTransition: MessageInputPanelComponent.SendActionTransition?
|
||||
if let snapshotView = self.textClippingView.snapshotView(afterScreenUpdates: false), let backgroundView = self.fieldGlassBackgroundView {
|
||||
sendActionTransition = MessageInputPanelComponent.SendActionTransition(
|
||||
textSnapshotView: snapshotView,
|
||||
globalFrame: backgroundView.convert(backgroundView.bounds, to: nil),
|
||||
cornerRadius: baseFieldHeight * 0.5
|
||||
)
|
||||
}
|
||||
component.sendMessageAction(sendActionTransition)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1525,7 +1586,7 @@ public final class MessageInputPanelComponent: Component {
|
||||
self.animateError()
|
||||
component.presentTextLengthLimitTooltip?()
|
||||
} else {
|
||||
component.sendMessageAction()
|
||||
component.sendMessageAction(nil)
|
||||
}
|
||||
}
|
||||
case .voiceInput, .videoInput:
|
||||
@@ -1587,7 +1648,7 @@ public final class MessageInputPanelComponent: Component {
|
||||
hasShadow: component.style == .editor
|
||||
)),
|
||||
environment: {},
|
||||
containerSize: CGSize(width: 33.0, height: 33.0)
|
||||
containerSize: inputActionButtonAvailableSize
|
||||
)
|
||||
|
||||
let hasLikeAction: Bool
|
||||
@@ -1617,8 +1678,13 @@ public final class MessageInputPanelComponent: Component {
|
||||
inputActionButtonOriginX -= 46.0
|
||||
}
|
||||
} else {
|
||||
if component.setMediaRecordingActive != nil || isEditing {
|
||||
inputActionButtonOriginX = fieldBackgroundFrame.maxX + floorToScreenPixels((41.0 - inputActionButtonSize.width) * 0.5)
|
||||
if component.setMediaRecordingActive != nil || isEditing || component.style == .glass {
|
||||
switch component.style {
|
||||
case .glass:
|
||||
inputActionButtonOriginX = fieldBackgroundFrame.maxX + 6.0
|
||||
default:
|
||||
inputActionButtonOriginX = fieldBackgroundFrame.maxX + floorToScreenPixels((41.0 - inputActionButtonSize.width) * 0.5)
|
||||
}
|
||||
} else {
|
||||
inputActionButtonOriginX = size.width
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user