mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-11-29 19:35:08 +00:00
Emoji improvements
This commit is contained in:
parent
cb83ca4ec8
commit
6fd38af0fe
@ -1200,7 +1200,7 @@ class ChatListItemNode: ItemListRevealOptionsItemNode {
|
||||
let draftText = stringWithAppliedEntities(draftState.text, entities: draftState.entities, baseColor: theme.messageTextColor, linkColor: theme.messageTextColor, baseFont: textFont, linkFont: textFont, boldFont: textFont, italicFont: textFont, boldItalicFont: textFont, fixedFont: textFont, blockQuoteFont: textFont, message: nil)
|
||||
|
||||
attributedText = foldLineBreaks(draftText)
|
||||
} else if let message = messages.last {
|
||||
} else if let message = messages.first {
|
||||
var composedString: NSMutableAttributedString
|
||||
|
||||
if let peerText = peerText {
|
||||
|
||||
@ -64,7 +64,7 @@ private final class PendingUpdateMessageManagerImpl {
|
||||
}
|
||||
}
|
||||
|
||||
func add(messageId: MessageId, text: String, media: RequestEditMessageMedia, entities: TextEntitiesMessageAttribute?, disableUrlPreview: Bool) {
|
||||
func add(messageId: MessageId, text: String, media: RequestEditMessageMedia, entities: TextEntitiesMessageAttribute?, inlineStickers: [MediaId: TelegramMediaFile], disableUrlPreview: Bool) {
|
||||
if let context = self.contexts[messageId] {
|
||||
self.contexts.removeValue(forKey: messageId)
|
||||
context.disposable.dispose()
|
||||
@ -75,7 +75,7 @@ private final class PendingUpdateMessageManagerImpl {
|
||||
self.contexts[messageId] = context
|
||||
|
||||
let queue = self.queue
|
||||
disposable.set((requestEditMessage(postbox: self.postbox, network: self.network, stateManager: self.stateManager, transformOutgoingMessageMedia: self.transformOutgoingMessageMedia, messageMediaPreuploadManager: self.messageMediaPreuploadManager, mediaReferenceRevalidationContext: self.mediaReferenceRevalidationContext, messageId: messageId, text: text, media: media, entities: entities, disableUrlPreview: disableUrlPreview, scheduleTime: nil)
|
||||
disposable.set((requestEditMessage(postbox: self.postbox, network: self.network, stateManager: self.stateManager, transformOutgoingMessageMedia: self.transformOutgoingMessageMedia, messageMediaPreuploadManager: self.messageMediaPreuploadManager, mediaReferenceRevalidationContext: self.mediaReferenceRevalidationContext, messageId: messageId, text: text, media: media, entities: entities, inlineStickers: inlineStickers, disableUrlPreview: disableUrlPreview, scheduleTime: nil)
|
||||
|> deliverOn(self.queue)).start(next: { [weak self, weak context] value in
|
||||
queue.async {
|
||||
guard let strongSelf = self, let initialContext = context else {
|
||||
@ -163,9 +163,9 @@ public final class PendingUpdateMessageManager {
|
||||
})
|
||||
}
|
||||
|
||||
public func add(messageId: MessageId, text: String, media: RequestEditMessageMedia, entities: TextEntitiesMessageAttribute? = nil, disableUrlPreview: Bool = false) {
|
||||
public func add(messageId: MessageId, text: String, media: RequestEditMessageMedia, entities: TextEntitiesMessageAttribute?, inlineStickers: [MediaId: TelegramMediaFile], disableUrlPreview: Bool = false) {
|
||||
self.impl.with { impl in
|
||||
impl.add(messageId: messageId, text: text, media: media, entities: entities, disableUrlPreview: disableUrlPreview)
|
||||
impl.add(messageId: messageId, text: text, media: media, entities: entities, inlineStickers: inlineStickers, disableUrlPreview: disableUrlPreview)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -27,15 +27,15 @@ public enum RequestEditMessageError {
|
||||
case invalidGrouping
|
||||
}
|
||||
|
||||
func _internal_requestEditMessage(account: Account, messageId: MessageId, text: String, media: RequestEditMessageMedia, entities: TextEntitiesMessageAttribute? = nil, disableUrlPreview: Bool = false, scheduleTime: Int32? = nil) -> Signal<RequestEditMessageResult, RequestEditMessageError> {
|
||||
return requestEditMessage(postbox: account.postbox, network: account.network, stateManager: account.stateManager, transformOutgoingMessageMedia: account.transformOutgoingMessageMedia, messageMediaPreuploadManager: account.messageMediaPreuploadManager, mediaReferenceRevalidationContext: account.mediaReferenceRevalidationContext, messageId: messageId, text: text, media: media, entities: entities, disableUrlPreview: disableUrlPreview, scheduleTime: scheduleTime)
|
||||
func _internal_requestEditMessage(account: Account, messageId: MessageId, text: String, media: RequestEditMessageMedia, entities: TextEntitiesMessageAttribute?, inlineStickers: [MediaId: TelegramMediaFile], disableUrlPreview: Bool = false, scheduleTime: Int32? = nil) -> Signal<RequestEditMessageResult, RequestEditMessageError> {
|
||||
return requestEditMessage(postbox: account.postbox, network: account.network, stateManager: account.stateManager, transformOutgoingMessageMedia: account.transformOutgoingMessageMedia, messageMediaPreuploadManager: account.messageMediaPreuploadManager, mediaReferenceRevalidationContext: account.mediaReferenceRevalidationContext, messageId: messageId, text: text, media: media, entities: entities, inlineStickers: inlineStickers, disableUrlPreview: disableUrlPreview, scheduleTime: scheduleTime)
|
||||
}
|
||||
|
||||
func requestEditMessage(postbox: Postbox, network: Network, stateManager: AccountStateManager, transformOutgoingMessageMedia: TransformOutgoingMessageMedia?, messageMediaPreuploadManager: MessageMediaPreuploadManager, mediaReferenceRevalidationContext: MediaReferenceRevalidationContext, messageId: MessageId, text: String, media: RequestEditMessageMedia, entities: TextEntitiesMessageAttribute?, disableUrlPreview: Bool, scheduleTime: Int32?) -> Signal<RequestEditMessageResult, RequestEditMessageError> {
|
||||
return requestEditMessageInternal(postbox: postbox, network: network, stateManager: stateManager, transformOutgoingMessageMedia: transformOutgoingMessageMedia, messageMediaPreuploadManager: messageMediaPreuploadManager, mediaReferenceRevalidationContext: mediaReferenceRevalidationContext, messageId: messageId, text: text, media: media, entities: entities, disableUrlPreview: disableUrlPreview, scheduleTime: scheduleTime, forceReupload: false)
|
||||
func requestEditMessage(postbox: Postbox, network: Network, stateManager: AccountStateManager, transformOutgoingMessageMedia: TransformOutgoingMessageMedia?, messageMediaPreuploadManager: MessageMediaPreuploadManager, mediaReferenceRevalidationContext: MediaReferenceRevalidationContext, messageId: MessageId, text: String, media: RequestEditMessageMedia, entities: TextEntitiesMessageAttribute?, inlineStickers: [MediaId: TelegramMediaFile], disableUrlPreview: Bool, scheduleTime: Int32?) -> Signal<RequestEditMessageResult, RequestEditMessageError> {
|
||||
return requestEditMessageInternal(postbox: postbox, network: network, stateManager: stateManager, transformOutgoingMessageMedia: transformOutgoingMessageMedia, messageMediaPreuploadManager: messageMediaPreuploadManager, mediaReferenceRevalidationContext: mediaReferenceRevalidationContext, messageId: messageId, text: text, media: media, entities: entities, inlineStickers: inlineStickers, disableUrlPreview: disableUrlPreview, scheduleTime: scheduleTime, forceReupload: false)
|
||||
|> `catch` { error -> Signal<RequestEditMessageResult, RequestEditMessageInternalError> in
|
||||
if case .invalidReference = error {
|
||||
return requestEditMessageInternal(postbox: postbox, network: network, stateManager: stateManager, transformOutgoingMessageMedia: transformOutgoingMessageMedia, messageMediaPreuploadManager: messageMediaPreuploadManager, mediaReferenceRevalidationContext: mediaReferenceRevalidationContext, messageId: messageId, text: text, media: media, entities: entities, disableUrlPreview: disableUrlPreview, scheduleTime: scheduleTime, forceReupload: true)
|
||||
return requestEditMessageInternal(postbox: postbox, network: network, stateManager: stateManager, transformOutgoingMessageMedia: transformOutgoingMessageMedia, messageMediaPreuploadManager: messageMediaPreuploadManager, mediaReferenceRevalidationContext: mediaReferenceRevalidationContext, messageId: messageId, text: text, media: media, entities: entities, inlineStickers: inlineStickers, disableUrlPreview: disableUrlPreview, scheduleTime: scheduleTime, forceReupload: true)
|
||||
} else {
|
||||
return .fail(error)
|
||||
}
|
||||
@ -50,7 +50,7 @@ func requestEditMessage(postbox: Postbox, network: Network, stateManager: Accoun
|
||||
}
|
||||
}
|
||||
|
||||
private func requestEditMessageInternal(postbox: Postbox, network: Network, stateManager: AccountStateManager, transformOutgoingMessageMedia: TransformOutgoingMessageMedia?, messageMediaPreuploadManager: MessageMediaPreuploadManager, mediaReferenceRevalidationContext: MediaReferenceRevalidationContext, messageId: MessageId, text: String, media: RequestEditMessageMedia, entities: TextEntitiesMessageAttribute?, disableUrlPreview: Bool, scheduleTime: Int32?, forceReupload: Bool) -> Signal<RequestEditMessageResult, RequestEditMessageInternalError> {
|
||||
private func requestEditMessageInternal(postbox: Postbox, network: Network, stateManager: AccountStateManager, transformOutgoingMessageMedia: TransformOutgoingMessageMedia?, messageMediaPreuploadManager: MessageMediaPreuploadManager, mediaReferenceRevalidationContext: MediaReferenceRevalidationContext, messageId: MessageId, text: String, media: RequestEditMessageMedia, entities: TextEntitiesMessageAttribute?, inlineStickers: [MediaId: TelegramMediaFile], disableUrlPreview: Bool, scheduleTime: Int32?, forceReupload: Bool) -> Signal<RequestEditMessageResult, RequestEditMessageInternalError> {
|
||||
let uploadedMedia: Signal<PendingMessageUploadedContentResult?, NoError>
|
||||
switch media {
|
||||
case .keep:
|
||||
@ -96,6 +96,10 @@ private func requestEditMessageInternal(postbox: Postbox, network: Network, stat
|
||||
return (nil, nil, SimpleDictionary())
|
||||
}
|
||||
|
||||
for (_, file) in inlineStickers {
|
||||
transaction.storeMediaIfNotPresent(media: file)
|
||||
}
|
||||
|
||||
if text.isEmpty {
|
||||
for media in message.media {
|
||||
switch media {
|
||||
|
||||
@ -85,8 +85,8 @@ public extension TelegramEngine {
|
||||
return _internal_clearAuthorHistory(account: self.account, peerId: peerId, memberId: memberId)
|
||||
}
|
||||
|
||||
public func requestEditMessage(messageId: MessageId, text: String, media: RequestEditMessageMedia, entities: TextEntitiesMessageAttribute? = nil, disableUrlPreview: Bool = false, scheduleTime: Int32? = nil) -> Signal<RequestEditMessageResult, RequestEditMessageError> {
|
||||
return _internal_requestEditMessage(account: self.account, messageId: messageId, text: text, media: media, entities: entities, disableUrlPreview: disableUrlPreview, scheduleTime: scheduleTime)
|
||||
public func requestEditMessage(messageId: MessageId, text: String, media: RequestEditMessageMedia, entities: TextEntitiesMessageAttribute?, inlineStickers: [MediaId: TelegramMediaFile], disableUrlPreview: Bool = false, scheduleTime: Int32? = nil) -> Signal<RequestEditMessageResult, RequestEditMessageError> {
|
||||
return _internal_requestEditMessage(account: self.account, messageId: messageId, text: text, media: media, entities: entities, inlineStickers: inlineStickers, disableUrlPreview: disableUrlPreview, scheduleTime: scheduleTime)
|
||||
}
|
||||
|
||||
public func requestEditLiveLocation(messageId: MessageId, stop: Bool, coordinate: (latitude: Double, longitude: Double, accuracyRadius: Int32?)?, heading: Int32?, proximityNotificationRadius: Int32?) -> Signal<Void, NoError> {
|
||||
|
||||
@ -1284,7 +1284,7 @@ public struct PresentationResourcesChat {
|
||||
|
||||
public static func chatEntityKeyboardLock(_ theme: PresentationTheme, color: UIColor) -> UIImage? {
|
||||
return theme.image(PresentationResourceParameterKey.chatEntityKeyboardLock(color: color.argb), { theme in
|
||||
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Stickers/SmallLock"), color: color)
|
||||
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Input/Media/PanelSectionLockIcon"), color: color)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@ -579,7 +579,7 @@ private final class GroupHeaderLayer: UIView {
|
||||
cache: AnimationCache,
|
||||
renderer: MultiAnimationRenderer,
|
||||
attemptSynchronousLoad: Bool
|
||||
) -> CGSize {
|
||||
) -> (size: CGSize, centralContentWidth: CGFloat) {
|
||||
var themeUpdated = false
|
||||
if self.theme !== theme {
|
||||
self.theme = theme
|
||||
@ -606,48 +606,8 @@ private final class GroupHeaderLayer: UIView {
|
||||
|
||||
let titleHorizontalOffset: CGFloat
|
||||
if isPremiumLocked {
|
||||
let lockIconLayer: SimpleLayer
|
||||
if let current = self.lockIconLayer {
|
||||
lockIconLayer = current
|
||||
} else {
|
||||
lockIconLayer = SimpleLayer()
|
||||
self.lockIconLayer = lockIconLayer
|
||||
self.layer.addSublayer(lockIconLayer)
|
||||
}
|
||||
if let image = PresentationResourcesChat.chatEntityKeyboardLock(theme, color: color) {
|
||||
let imageSize = image.size.aspectFitted(CGSize(width: 16.0, height: 16.0))
|
||||
lockIconLayer.contents = image.cgImage
|
||||
titleHorizontalOffset = imageSize.width + 2.0
|
||||
lockIconLayer.frame = CGRect(origin: CGPoint(x: 0.0, y: 0.0), size: imageSize)
|
||||
} else {
|
||||
lockIconLayer.contents = nil
|
||||
titleHorizontalOffset = 0.0
|
||||
}
|
||||
|
||||
let tintLockIconLayer: SimpleLayer
|
||||
if let current = self.tintLockIconLayer {
|
||||
tintLockIconLayer = current
|
||||
} else {
|
||||
tintLockIconLayer = SimpleLayer()
|
||||
self.tintLockIconLayer = tintLockIconLayer
|
||||
self.tintContentLayer.addSublayer(tintLockIconLayer)
|
||||
}
|
||||
if let image = PresentationResourcesChat.chatEntityKeyboardLock(theme, color: .white) {
|
||||
let imageSize = image.size.aspectFitted(CGSize(width: 16.0, height: 16.0))
|
||||
tintLockIconLayer.contents = image.cgImage
|
||||
tintLockIconLayer.frame = CGRect(origin: CGPoint(x: 0.0, y: 0.0), size: imageSize)
|
||||
} else {
|
||||
tintLockIconLayer.contents = nil
|
||||
}
|
||||
titleHorizontalOffset = 10.0 + 2.0
|
||||
} else {
|
||||
if let lockIconLayer = self.lockIconLayer {
|
||||
self.lockIconLayer = nil
|
||||
lockIconLayer.removeFromSuperlayer()
|
||||
}
|
||||
if let tintLockIconLayer = self.tintLockIconLayer {
|
||||
self.tintLockIconLayer = nil
|
||||
tintLockIconLayer.removeFromSuperlayer()
|
||||
}
|
||||
titleHorizontalOffset = 0.0
|
||||
}
|
||||
|
||||
@ -712,15 +672,53 @@ private final class GroupHeaderLayer: UIView {
|
||||
}
|
||||
|
||||
let textFrame: CGRect
|
||||
if (layoutType == .compact && hasClear) || subtitle != nil {
|
||||
textFrame = CGRect(origin: CGPoint(x: titleHorizontalOffset, y: textOffsetY), size: textSize)
|
||||
} else {
|
||||
textFrame = CGRect(origin: CGPoint(x: floor((constrainedSize.width - textSize.width) / 2.0), y: textOffsetY), size: textSize)
|
||||
}
|
||||
textFrame = CGRect(origin: CGPoint(x: titleHorizontalOffset + floor((constrainedSize.width - titleHorizontalOffset - textSize.width) / 2.0), y: textOffsetY), size: textSize)
|
||||
self.textLayer.frame = textFrame
|
||||
self.tintTextLayer.frame = textFrame
|
||||
self.tintTextLayer.isHidden = !needsTintText
|
||||
|
||||
if isPremiumLocked {
|
||||
let lockIconLayer: SimpleLayer
|
||||
if let current = self.lockIconLayer {
|
||||
lockIconLayer = current
|
||||
} else {
|
||||
lockIconLayer = SimpleLayer()
|
||||
self.lockIconLayer = lockIconLayer
|
||||
self.layer.addSublayer(lockIconLayer)
|
||||
}
|
||||
if let image = PresentationResourcesChat.chatEntityKeyboardLock(theme, color: color) {
|
||||
let imageSize = image.size
|
||||
lockIconLayer.contents = image.cgImage
|
||||
lockIconLayer.frame = CGRect(origin: CGPoint(x: textFrame.minX - imageSize.width - 3.0, y: 2.0 + UIScreenPixel), size: imageSize)
|
||||
} else {
|
||||
lockIconLayer.contents = nil
|
||||
}
|
||||
|
||||
let tintLockIconLayer: SimpleLayer
|
||||
if let current = self.tintLockIconLayer {
|
||||
tintLockIconLayer = current
|
||||
} else {
|
||||
tintLockIconLayer = SimpleLayer()
|
||||
self.tintLockIconLayer = tintLockIconLayer
|
||||
self.tintContentLayer.addSublayer(tintLockIconLayer)
|
||||
}
|
||||
if let image = PresentationResourcesChat.chatEntityKeyboardLock(theme, color: .white) {
|
||||
tintLockIconLayer.contents = image.cgImage
|
||||
tintLockIconLayer.frame = lockIconLayer.frame
|
||||
} else {
|
||||
tintLockIconLayer.contents = nil
|
||||
}
|
||||
} else {
|
||||
if let lockIconLayer = self.lockIconLayer {
|
||||
self.lockIconLayer = nil
|
||||
lockIconLayer.removeFromSuperlayer()
|
||||
}
|
||||
if let tintLockIconLayer = self.tintLockIconLayer {
|
||||
self.tintLockIconLayer = nil
|
||||
tintLockIconLayer.removeFromSuperlayer()
|
||||
}
|
||||
}
|
||||
|
||||
let subtitleSize: CGSize
|
||||
if let subtitle = subtitle {
|
||||
var updateSubtitleContents: UIImage?
|
||||
@ -836,11 +834,7 @@ private final class GroupHeaderLayer: UIView {
|
||||
}
|
||||
|
||||
var size: CGSize
|
||||
if layoutType == .compact && hasClear {
|
||||
size = CGSize(width: titleHorizontalOffset + textSize.width + clearWidth, height: constrainedSize.height)
|
||||
} else {
|
||||
size = CGSize(width: constrainedSize.width, height: constrainedSize.height)
|
||||
}
|
||||
size = CGSize(width: constrainedSize.width, height: constrainedSize.height)
|
||||
|
||||
if let embeddedItems = embeddedItems {
|
||||
let groupEmbeddedView: GroupEmbeddedView
|
||||
@ -908,7 +902,7 @@ private final class GroupHeaderLayer: UIView {
|
||||
}
|
||||
}
|
||||
|
||||
return size
|
||||
return (size, titleHorizontalOffset + textSize.width + clearWidth)
|
||||
}
|
||||
|
||||
override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
|
||||
@ -1552,14 +1546,14 @@ public final class EmojiPagerContentComponent: Component {
|
||||
|
||||
if width >= 420.0 {
|
||||
self.itemInsets = UIEdgeInsets(top: containerInsets.top, left: containerInsets.left + 5.0, bottom: containerInsets.bottom, right: containerInsets.right + 5.0)
|
||||
self.headerInsets = UIEdgeInsets(top: containerInsets.top, left: containerInsets.left + 5.0, bottom: containerInsets.bottom, right: containerInsets.right + 5.0)
|
||||
minSpacing = 2.0
|
||||
} else {
|
||||
self.itemInsets = UIEdgeInsets(top: containerInsets.top, left: containerInsets.left + 7.0, bottom: containerInsets.bottom, right: containerInsets.right + 7.0)
|
||||
self.headerInsets = UIEdgeInsets(top: containerInsets.top, left: containerInsets.left + 7.0, bottom: containerInsets.bottom, right: containerInsets.right + 7.0)
|
||||
minSpacing = 9.0
|
||||
}
|
||||
|
||||
self.headerInsets = UIEdgeInsets(top: containerInsets.top, left: containerInsets.left + 16.0, bottom: containerInsets.bottom, right: containerInsets.right + 16.0)
|
||||
|
||||
self.itemDefaultHeaderHeight = 24.0
|
||||
self.itemFeaturedHeaderHeight = self.itemDefaultHeaderHeight
|
||||
case .detailed:
|
||||
@ -3039,7 +3033,7 @@ public final class EmojiPagerContentComponent: Component {
|
||||
assignTopVisibleSubgroupId = true
|
||||
}
|
||||
|
||||
var headerSize: CGSize?
|
||||
var headerCentralContentWidth: CGFloat?
|
||||
var headerSizeUpdated = false
|
||||
if let title = itemGroup.title {
|
||||
validGroupHeaderIds.insert(itemGroup.groupId)
|
||||
@ -3076,7 +3070,7 @@ public final class EmojiPagerContentComponent: Component {
|
||||
|
||||
let hasTopSeparator = false
|
||||
|
||||
let groupHeaderSize = groupHeaderView.update(
|
||||
let (groupHeaderSize, centralContentWidth) = groupHeaderView.update(
|
||||
context: component.context,
|
||||
theme: theme,
|
||||
layoutType: itemLayout.layoutType,
|
||||
@ -3097,11 +3091,11 @@ public final class EmojiPagerContentComponent: Component {
|
||||
if groupHeaderView.bounds.size != groupHeaderSize {
|
||||
headerSizeUpdated = true
|
||||
}
|
||||
headerCentralContentWidth = centralContentWidth
|
||||
|
||||
let groupHeaderFrame = CGRect(origin: CGPoint(x: floor((itemLayout.contentSize.width - groupHeaderSize.width) / 2.0), y: itemGroupLayout.frame.minY + 1.0), size: groupHeaderSize)
|
||||
groupHeaderView.bounds = CGRect(origin: CGPoint(), size: groupHeaderFrame.size)
|
||||
groupHeaderTransition.setPosition(view: groupHeaderView, position: CGPoint(x: groupHeaderFrame.midX, y: groupHeaderFrame.midY))
|
||||
headerSize = CGSize(width: groupHeaderSize.width, height: groupHeaderSize.height)
|
||||
}
|
||||
|
||||
let groupBorderRadius: CGFloat = 16.0
|
||||
@ -3134,8 +3128,8 @@ public final class EmojiPagerContentComponent: Component {
|
||||
|
||||
if groupBorderLayer.bounds.size != groupBorderFrame.size || headerSizeUpdated {
|
||||
let headerWidth: CGFloat
|
||||
if let headerSize = headerSize {
|
||||
headerWidth = headerSize.width + 14.0
|
||||
if let headerCentralContentWidth = headerCentralContentWidth {
|
||||
headerWidth = headerCentralContentWidth + 14.0
|
||||
} else {
|
||||
headerWidth = 0.0
|
||||
}
|
||||
|
||||
@ -185,9 +185,14 @@ final class EntityKeyboardAnimationTopPanelComponent: Component {
|
||||
} else if let titleView = self.titleView {
|
||||
self.titleView = nil
|
||||
if let view = titleView.view {
|
||||
transition.setAlpha(view: view, alpha: 0.0, completion: { [weak view] _ in
|
||||
view?.removeFromSuperview()
|
||||
})
|
||||
if !transition.animation.isImmediate {
|
||||
view.alpha = 0.0
|
||||
view.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.08, completion: { [weak view] _ in
|
||||
view?.removeFromSuperview()
|
||||
})
|
||||
} else {
|
||||
view.removeFromSuperview()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -392,9 +397,14 @@ final class EntityKeyboardIconTopPanelComponent: Component {
|
||||
} else if let titleView = self.titleView {
|
||||
self.titleView = nil
|
||||
if let view = titleView.view {
|
||||
transition.setAlpha(view: view, alpha: 0.0, completion: { [weak view] _ in
|
||||
view?.removeFromSuperview()
|
||||
})
|
||||
if !transition.animation.isImmediate {
|
||||
view.alpha = 0.0
|
||||
view.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.08, completion: { [weak view] _ in
|
||||
view?.removeFromSuperview()
|
||||
})
|
||||
} else {
|
||||
view.removeFromSuperview()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -724,9 +734,14 @@ final class EntityKeyboardStaticStickersPanelComponent: Component {
|
||||
} else if let titleView = self.titleView {
|
||||
self.titleView = nil
|
||||
if let view = titleView.view {
|
||||
transition.setAlpha(view: view, alpha: 0.0, completion: { [weak view] _ in
|
||||
view?.removeFromSuperview()
|
||||
})
|
||||
if !transition.animation.isImmediate {
|
||||
view.alpha = 0.0
|
||||
view.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.08, completion: { [weak view] _ in
|
||||
view?.removeFromSuperview()
|
||||
})
|
||||
} else {
|
||||
view.removeFromSuperview()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -0,0 +1,12 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "Locked.svg",
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,4 @@
|
||||
<svg width="7" height="10" viewBox="0 0 7 10" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M3.5 0.835039C2.02816 0.835039 0.835 2.0282 0.835 3.50004V4.67699C0.548874 4.82654 0.316237 5.06149 0.169545 5.34939C0 5.68214 0 6.11774 0 6.98893V7.51115C0 8.38234 0 8.81794 0.169545 9.15069C0.318682 9.44339 0.556652 9.68136 0.849348 9.83049C1.1821 10 1.6177 10 2.48889 10H4.51111C5.3823 10 5.8179 10 6.15065 9.83049C6.44335 9.68136 6.68132 9.44339 6.83045 9.15069C7 8.81794 7 8.38234 7 7.51115V6.98893C7 6.11774 7 5.68214 6.83045 5.34939C6.68376 5.06149 6.45113 4.82654 6.165 4.67699V3.50004C6.165 2.0282 4.97184 0.835039 3.5 0.835039ZM4.835 4.50043V3.50004C4.835 2.76274 4.2373 2.16504 3.5 2.16504C2.7627 2.16504 2.165 2.76274 2.165 3.50004V4.50043C2.26584 4.50004 2.37355 4.50004 2.48889 4.50004H4.51111C4.62645 4.50004 4.73416 4.50004 4.835 4.50043Z" fill="black" style="mix-blend-mode:overlay"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M3.5 0.835039C2.02816 0.835039 0.835 2.0282 0.835 3.50004V4.67699C0.548874 4.82654 0.316237 5.06149 0.169545 5.34939C0 5.68214 0 6.11774 0 6.98893V7.51115C0 8.38234 0 8.81794 0.169545 9.15069C0.318682 9.44339 0.556652 9.68136 0.849348 9.83049C1.1821 10 1.6177 10 2.48889 10H4.51111C5.3823 10 5.8179 10 6.15065 9.83049C6.44335 9.68136 6.68132 9.44339 6.83045 9.15069C7 8.81794 7 8.38234 7 7.51115V6.98893C7 6.11774 7 5.68214 6.83045 5.34939C6.68376 5.06149 6.45113 4.82654 6.165 4.67699V3.50004C6.165 2.0282 4.97184 0.835039 3.5 0.835039ZM4.835 4.50043V3.50004C4.835 2.76274 4.2373 2.16504 3.5 2.16504C2.7627 2.16504 2.165 2.76274 2.165 3.50004V4.50043C2.26584 4.50004 2.37355 4.50004 2.48889 4.50004H4.51111C4.62645 4.50004 4.73416 4.50004 4.835 4.50043Z" fill="black" fill-opacity="0.15"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.8 KiB |
@ -3090,7 +3090,9 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
break
|
||||
}
|
||||
}
|
||||
strongSelf.editMessageDisposable.set((strongSelf.context.engine.messages.requestEditMessage(messageId: messageId, text: message.text, media: .keep, entities: entities, disableUrlPreview: false, scheduleTime: time) |> deliverOnMainQueue).start(next: { result in
|
||||
|
||||
let inlineStickers: [MediaId: TelegramMediaFile] = [:]
|
||||
strongSelf.editMessageDisposable.set((strongSelf.context.engine.messages.requestEditMessage(messageId: messageId, text: message.text, media: .keep, entities: entities, inlineStickers: inlineStickers, disableUrlPreview: false, scheduleTime: time) |> deliverOnMainQueue).start(next: { result in
|
||||
}, error: { error in
|
||||
}))
|
||||
}
|
||||
@ -7105,6 +7107,44 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
entitiesAttribute = TextEntitiesMessageAttribute(entities: entities)
|
||||
}
|
||||
|
||||
var inlineStickers: [MediaId: TelegramMediaFile] = [:]
|
||||
var firstLockedPremiumEmoji: TelegramMediaFile?
|
||||
text.enumerateAttribute(ChatTextInputAttributes.customEmoji, in: NSRange(location: 0, length: text.length), using: { value, _, _ in
|
||||
if let value = value as? ChatTextInputTextCustomEmojiAttribute {
|
||||
if let file = value.file {
|
||||
inlineStickers[file.fileId] = file
|
||||
if file.isPremiumEmoji && !strongSelf.presentationInterfaceState.isPremium {
|
||||
if firstLockedPremiumEmoji == nil {
|
||||
firstLockedPremiumEmoji = file
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
if let firstLockedPremiumEmoji = firstLockedPremiumEmoji {
|
||||
//let presentationData = self.context.sharedContext.currentPresentationData.with { $0 }
|
||||
//TODO:localize
|
||||
strongSelf.controllerInteraction?.displayUndo(.sticker(context: strongSelf.context, file: firstLockedPremiumEmoji, title: nil, text: "Subscribe to Telegram Premium to unlock premium emoji.", undoText: "More", customAction: {
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
strongSelf.chatDisplayNode.dismissTextInput()
|
||||
|
||||
var replaceImpl: ((ViewController) -> Void)?
|
||||
let controller = PremiumDemoScreen(context: strongSelf.context, subject: .animatedEmoji, action: {
|
||||
let controller = PremiumIntroScreen(context: strongSelf.context, source: .animatedEmoji)
|
||||
replaceImpl?(controller)
|
||||
})
|
||||
replaceImpl = { [weak controller] c in
|
||||
controller?.replace(with: c)
|
||||
}
|
||||
strongSelf.present(controller, in: .window(.root), with: nil)
|
||||
}))
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
var updatingMedia = false
|
||||
let media: RequestEditMessageMedia
|
||||
if let editMediaReference = strongSelf.presentationInterfaceState.editMessageState?.mediaReference {
|
||||
@ -7121,7 +7161,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
if let currentMessage = currentMessage {
|
||||
let currentEntities = currentMessage.textEntitiesAttribute?.entities ?? []
|
||||
if currentMessage.text != text.string || currentEntities != entities || updatingMedia {
|
||||
strongSelf.context.account.pendingUpdateMessageManager.add(messageId: editMessage.messageId, text: text.string, media: media, entities: entitiesAttribute, disableUrlPreview: disableUrlPreview)
|
||||
strongSelf.context.account.pendingUpdateMessageManager.add(messageId: editMessage.messageId, text: text.string, media: media, entities: entitiesAttribute, inlineStickers: inlineStickers, disableUrlPreview: disableUrlPreview)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1374,6 +1374,7 @@ class ChatControllerNode: ASDisplayNode, UIScrollViewDelegate {
|
||||
case .overPanels:
|
||||
self.inputContextPanelContainer.addSubnode(inputContextPanelNode)
|
||||
case .overTextInput:
|
||||
inputContextPanelNode.view.disablesInteractiveKeyboardGestureRecognizer = true
|
||||
self.inputContextOverTextPanelContainer.addSubnode(inputContextPanelNode)
|
||||
}
|
||||
immediatelyLayoutInputContextPanelAndAnimateAppearance = true
|
||||
|
||||
@ -945,6 +945,8 @@ final class ChatEntityKeyboardInputNode: ChatInputNode {
|
||||
fileprivate var emojiInputInteraction: EmojiPagerContentComponent.InputInteraction?
|
||||
private var stickerInputInteraction: EmojiPagerContentComponent.InputInteraction?
|
||||
|
||||
private weak var currentUndoOverlayController: UndoOverlayController?
|
||||
|
||||
init(context: AccountContext, currentInputData: InputData, updatedInputData: Signal<InputData, NoError>, defaultToEmojiTab: Bool, controllerInteraction: ChatControllerInteraction?, interfaceInteraction: ChatPanelInterfaceInteraction?, chatPeerId: PeerId?) {
|
||||
self.context = context
|
||||
self.currentInputData = currentInputData
|
||||
@ -973,9 +975,9 @@ final class ChatEntityKeyboardInputNode: ChatInputNode {
|
||||
|> distinctUntilChanged
|
||||
|
||||
self.emojiInputInteraction = EmojiPagerContentComponent.InputInteraction(
|
||||
performItemAction: { [weak interfaceInteraction, weak controllerInteraction] _, item, _, _, _ in
|
||||
performItemAction: { [weak self, weak interfaceInteraction, weak controllerInteraction] _, item, _, _, _ in
|
||||
let _ = (hasPremium |> take(1) |> deliverOnMainQueue).start(next: { hasPremium in
|
||||
guard let controllerInteraction = controllerInteraction, let interfaceInteraction = interfaceInteraction else {
|
||||
guard let strongSelf = self, let controllerInteraction = controllerInteraction, let interfaceInteraction = interfaceInteraction else {
|
||||
return
|
||||
}
|
||||
|
||||
@ -994,10 +996,17 @@ final class ChatEntityKeyboardInputNode: ChatInputNode {
|
||||
}
|
||||
|
||||
if file.isPremiumEmoji && !hasPremium {
|
||||
var animateInAsReplacement = false
|
||||
if let currentUndoOverlayController = strongSelf.currentUndoOverlayController {
|
||||
currentUndoOverlayController.dismissWithCommitActionAndReplacementAnimation()
|
||||
strongSelf.currentUndoOverlayController = nil
|
||||
animateInAsReplacement = true
|
||||
}
|
||||
|
||||
//TODO:localize
|
||||
|
||||
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||
controllerInteraction.presentController(UndoOverlayController(presentationData: presentationData, content: .sticker(context: context, file: file, title: nil, text: "Subscribe to Telegram Premium to unlock this emoji.", undoText: "More", customAction: { [weak controllerInteraction] in
|
||||
let controller = UndoOverlayController(presentationData: presentationData, content: .sticker(context: context, file: file, title: nil, text: "Subscribe to Telegram Premium to unlock this emoji.", undoText: "More", customAction: { [weak controllerInteraction] in
|
||||
guard let controllerInteraction = controllerInteraction else {
|
||||
return
|
||||
}
|
||||
@ -1014,7 +1023,9 @@ final class ChatEntityKeyboardInputNode: ChatInputNode {
|
||||
|
||||
/*let controller = PremiumIntroScreen(context: context, source: .stickers)
|
||||
controllerInteraction.navigationController()?.pushViewController(controller)*/
|
||||
}), elevatedLayout: false, animateInAsReplacement: false, action: { _ in return false }), nil)
|
||||
}), elevatedLayout: false, animateInAsReplacement: animateInAsReplacement, action: { _ in return false })
|
||||
strongSelf.currentUndoOverlayController = controller
|
||||
controllerInteraction.presentController(controller, nil)
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user