mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-10-08 19:10:53 +00:00
Merge commit '8007e25fc4c1f5646a39de54a6d3d9532384e4f3' into beta
This commit is contained in:
commit
85c81a107d
@ -11336,12 +11336,10 @@ Sorry for the inconvenience.";
|
||||
"Premium.Business.Location.Text" = "Display the location of your business on your account.";
|
||||
|
||||
"Premium.Business.Hours.Title" = "Opening Hours";
|
||||
"Premium.Business.Hours.Text" = "Show to your customers when you are
|
||||
open for business.";
|
||||
"Premium.Business.Hours.Text" = "Show to your customers when you are open for business.";
|
||||
|
||||
"Premium.Business.Replies.Title" = "Quick Replies";
|
||||
"Premium.Business.Replies.Text" = "Set up shortcuts with rich text and media
|
||||
to respond to messages faster.";
|
||||
"Premium.Business.Replies.Text" = "Set up shortcuts with rich text and media to respond to messages faster.";
|
||||
|
||||
"Premium.Business.Greetings.Title" = "Greeting Messages";
|
||||
"Premium.Business.Greetings.Text" = "Create greetings that will be automatically sent to new customers.";
|
||||
|
@ -519,7 +519,7 @@ final class ChatSendMessageActionSheetControllerNode: ViewControllerTracingNode,
|
||||
}
|
||||
|
||||
var clipDelta = delta
|
||||
if inputHeight.isZero || layout.isNonExclusive {
|
||||
if inputHeight < 70.0 || layout.isNonExclusive {
|
||||
clipDelta -= self.contentContainerNode.frame.height + 16.0
|
||||
}
|
||||
|
||||
@ -642,7 +642,7 @@ final class ChatSendMessageActionSheetControllerNode: ViewControllerTracingNode,
|
||||
}
|
||||
|
||||
var clipDelta = delta
|
||||
if inputHeight.isZero || layout.isNonExclusive {
|
||||
if inputHeight < 70.0 || layout.isNonExclusive {
|
||||
clipDelta -= self.contentContainerNode.frame.height + 16.0
|
||||
}
|
||||
|
||||
@ -714,7 +714,7 @@ final class ChatSendMessageActionSheetControllerNode: ViewControllerTracingNode,
|
||||
} else {
|
||||
contentOrigin = CGPoint(x: layout.size.width - sideInset - contentSize.width - layout.safeInsets.right, y: layout.size.height - 6.0 - insets.bottom - contentSize.height)
|
||||
}
|
||||
if inputHeight > 0.0 && !layout.isNonExclusive && self.animateInputField {
|
||||
if inputHeight > 70.0 && !layout.isNonExclusive && self.animateInputField {
|
||||
contentOrigin.y += menuHeightWithInset
|
||||
}
|
||||
contentOrigin.y = min(contentOrigin.y + contentOffset, layout.size.height - 6.0 - layout.intrinsicInsets.bottom - contentSize.height)
|
||||
@ -728,7 +728,7 @@ final class ChatSendMessageActionSheetControllerNode: ViewControllerTracingNode,
|
||||
}
|
||||
|
||||
var sendButtonFrame = CGRect(origin: CGPoint(x: layout.size.width - initialSendButtonFrame.width + 1.0 - UIScreenPixel - layout.safeInsets.right, y: layout.size.height - insets.bottom - initialSendButtonFrame.height), size: initialSendButtonFrame.size)
|
||||
if (inputHeight.isZero || layout.isNonExclusive) && self.animateInputField {
|
||||
if (inputHeight < 70.0 || layout.isNonExclusive) && self.animateInputField {
|
||||
sendButtonFrame.origin.y -= menuHeightWithInset
|
||||
}
|
||||
sendButtonFrame.origin.y = min(sendButtonFrame.origin.y + contentOffset, layout.size.height - layout.intrinsicInsets.bottom - initialSendButtonFrame.height)
|
||||
@ -741,7 +741,7 @@ final class ChatSendMessageActionSheetControllerNode: ViewControllerTracingNode,
|
||||
|
||||
let messageHeightAddition: CGFloat = max(0.0, 35.0 - messageFrame.size.height)
|
||||
|
||||
if inputHeight.isZero || layout.isNonExclusive {
|
||||
if inputHeight < 70.0 || layout.isNonExclusive {
|
||||
messageFrame.origin.y += menuHeightWithInset
|
||||
}
|
||||
|
||||
|
@ -243,7 +243,6 @@ public final class WindowKeyboardGestureRecognizerDelegate: NSObject, UIGestureR
|
||||
public class Window1 {
|
||||
public let hostView: WindowHostView
|
||||
public let badgeView: UIImageView
|
||||
private let customProximityDimView: UIView
|
||||
|
||||
private var deviceMetrics: DeviceMetrics
|
||||
|
||||
@ -331,10 +330,6 @@ public class Window1 {
|
||||
self.badgeView.image = UIImage(bundleImageName: "Components/AppBadge")
|
||||
self.badgeView.isHidden = true
|
||||
|
||||
self.customProximityDimView = UIView()
|
||||
self.customProximityDimView.backgroundColor = .black
|
||||
self.customProximityDimView.isHidden = true
|
||||
|
||||
self.systemUserInterfaceStyle = hostView.systemUserInterfaceStyle
|
||||
|
||||
let boundsSize = self.hostView.eventView.bounds.size
|
||||
@ -673,7 +668,6 @@ public class Window1 {
|
||||
self.windowPanRecognizer = recognizer
|
||||
self.hostView.containerView.addGestureRecognizer(recognizer)
|
||||
self.hostView.containerView.addSubview(self.badgeView)
|
||||
self.hostView.containerView.addSubview(self.customProximityDimView)
|
||||
}
|
||||
|
||||
public required init(coder aDecoder: NSCoder) {
|
||||
@ -707,11 +701,18 @@ public class Window1 {
|
||||
self.updateBadgeVisibility()
|
||||
}
|
||||
|
||||
private var proximityDimController: CustomDimController?
|
||||
public func setProximityDimHidden(_ hidden: Bool) {
|
||||
guard hidden != self.customProximityDimView.isHidden else {
|
||||
return
|
||||
if !hidden {
|
||||
if self.proximityDimController == nil {
|
||||
let proximityDimController = CustomDimController(navigationBarPresentationData: nil)
|
||||
self.proximityDimController = proximityDimController
|
||||
(self.viewController as? NavigationController)?.presentOverlay(controller: proximityDimController, inGlobal: true, blockInteraction: false)
|
||||
}
|
||||
} else if let proximityDimController = self.proximityDimController {
|
||||
self.proximityDimController = nil
|
||||
proximityDimController.dismiss()
|
||||
}
|
||||
self.customProximityDimView.isHidden = hidden
|
||||
}
|
||||
|
||||
private func updateBadgeVisibility() {
|
||||
@ -1170,8 +1171,6 @@ public class Window1 {
|
||||
self.updateBadgeVisibility()
|
||||
self.badgeView.frame = CGRect(origin: CGPoint(x: floorToScreenPixels((self.windowLayout.size.width - image.size.width) / 2.0), y: 5.0), size: image.size)
|
||||
}
|
||||
|
||||
self.customProximityDimView.frame = CGRect(origin: .zero, size: self.windowLayout.size)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1383,3 +1382,25 @@ public class Window1 {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class CustomDimController: ViewController {
|
||||
class Node: ASDisplayNode {
|
||||
override init() {
|
||||
super.init()
|
||||
|
||||
self.backgroundColor = .black
|
||||
}
|
||||
}
|
||||
override init(navigationBarPresentationData: NavigationBarPresentationData?) {
|
||||
super.init(navigationBarPresentationData: nil)
|
||||
}
|
||||
|
||||
required public init(coder aDecoder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
override func loadDisplayNode() {
|
||||
let node = Node()
|
||||
self.displayNode = node
|
||||
}
|
||||
}
|
||||
|
@ -70,7 +70,7 @@ private final class HeaderComponent: Component {
|
||||
transition: .immediate,
|
||||
component: AnyComponent(
|
||||
MultilineTextComponent(
|
||||
text: .plain(NSAttributedString(string: component.strings.Premium_Business_Description, font: Font.regular(15.0), textColor: .black)),
|
||||
text: .plain(NSAttributedString(string: component.strings.Premium_Business_Description, font: Font.regular(15.0), textColor: component.theme.list.itemPrimaryTextColor)),
|
||||
horizontalAlignment: .center,
|
||||
maximumNumberOfLines: 0,
|
||||
lineSpacing: 0.2
|
||||
|
@ -3141,10 +3141,14 @@ private final class PremiumIntroScreenComponent: CombinedComponent {
|
||||
let secondaryTitleText: String
|
||||
var isAnonymous = false
|
||||
if var otherPeerName = state.otherPeerName {
|
||||
if case let .emojiStatus(_, _, file, maybeEmojiPack) = context.component.source, let emojiPack = maybeEmojiPack, case let .result(info, _, _) = emojiPack {
|
||||
if case let .emojiStatus(peerId, _, file, maybeEmojiPack) = context.component.source, let emojiPack = maybeEmojiPack, case let .result(info, _, _) = emojiPack {
|
||||
loadedEmojiPack = maybeEmojiPack
|
||||
highlightableLinks = true
|
||||
|
||||
if peerId.isGroupOrChannel, otherPeerName.count > 20 {
|
||||
otherPeerName = otherPeerName.prefix(20).trimmingCharacters(in: .whitespacesAndNewlines) + "\u{2026}"
|
||||
}
|
||||
|
||||
var packReference: StickerPackReference?
|
||||
if let file = file {
|
||||
for attribute in file.attributes {
|
||||
|
@ -228,6 +228,8 @@ public class PremiumLimitsListScreen: ViewController {
|
||||
if scrollView.contentSize.width > scrollView.contentSize.height || scrollView.contentSize.height > 1500.0 {
|
||||
return false
|
||||
}
|
||||
} else if otherGestureRecognizer.view is PremiumCoinComponent.View {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
@ -17,6 +17,12 @@ public final class AudioTranscriptionButtonComponent: Component {
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
case let .custom(lhsBackgroundColor, lhsForegroundColor):
|
||||
if case let .custom(rhsBackgroundColor, rhsForegroundColor) = rhs {
|
||||
return lhsBackgroundColor == rhsBackgroundColor && lhsForegroundColor == rhsForegroundColor
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
case let .freeform(lhsFreeform, lhsForeground):
|
||||
if case let .freeform(rhsFreeform, rhsForeground) = rhs, lhsFreeform == rhsFreeform, lhsForeground == rhsForeground {
|
||||
return true
|
||||
@ -27,6 +33,7 @@ public final class AudioTranscriptionButtonComponent: Component {
|
||||
}
|
||||
|
||||
case bubble(PresentationThemePartedColors)
|
||||
case custom(UIColor, UIColor)
|
||||
case freeform((UIColor, Bool), UIColor)
|
||||
}
|
||||
|
||||
@ -101,6 +108,9 @@ public final class AudioTranscriptionButtonComponent: Component {
|
||||
case let .bubble(theme):
|
||||
foregroundColor = theme.bubble.withWallpaper.reactionActiveBackground
|
||||
backgroundColor = theme.bubble.withWallpaper.reactionInactiveBackground
|
||||
case let .custom(backgroundColorValue, foregroundColorValue):
|
||||
foregroundColor = foregroundColorValue
|
||||
backgroundColor = backgroundColorValue
|
||||
case let .freeform(colorAndBlur, color):
|
||||
foregroundColor = color
|
||||
backgroundColor = .clear
|
||||
|
@ -728,7 +728,7 @@ public final class ChatMessageAttachedContentNode: ASDisplayNode {
|
||||
|
||||
let contentFileSizeAndApply: (CGSize, ChatMessageInteractiveFileNode.Apply)?
|
||||
if let contentFileFinalizeLayout {
|
||||
let (size, apply) = contentFileFinalizeLayout(resultingWidth - insets.left - insets.right)
|
||||
let (size, apply) = contentFileFinalizeLayout(resultingWidth - insets.left - insets.right - 6.0)
|
||||
contentFileSizeAndApply = (size, apply)
|
||||
} else {
|
||||
contentFileSizeAndApply = nil
|
||||
@ -846,7 +846,7 @@ public final class ChatMessageAttachedContentNode: ASDisplayNode {
|
||||
offsetY: actualSize.height
|
||||
))
|
||||
|
||||
actualSize.height += contentFileSize.height
|
||||
actualSize.height += contentFileSize.height + 9.0
|
||||
}
|
||||
case .actionButton:
|
||||
if let (actionButtonSize, _) = actionButtonSizeAndApply {
|
||||
|
@ -1329,10 +1329,16 @@ public final class ChatMessageInteractiveFileNode: ASDisplayNode {
|
||||
strongSelf.view.addSubview(audioTranscriptionButton)
|
||||
added = true
|
||||
}
|
||||
let buttonTheme: AudioTranscriptionButtonComponent.Theme
|
||||
if let customTintColor = arguments.customTintColor {
|
||||
buttonTheme = .custom(customTintColor.withMultipliedAlpha(0.1), customTintColor)
|
||||
} else {
|
||||
buttonTheme = .bubble(arguments.incoming ? arguments.presentationData.theme.theme.chat.message.incoming : arguments.presentationData.theme.theme.chat.message.outgoing)
|
||||
}
|
||||
let audioTranscriptionButtonSize = audioTranscriptionButton.update(
|
||||
transition: animation.isAnimated ? .easeInOut(duration: 0.3) : .immediate,
|
||||
component: AnyComponent(AudioTranscriptionButtonComponent(
|
||||
theme: .bubble(arguments.incoming ? arguments.presentationData.theme.theme.chat.message.incoming : arguments.presentationData.theme.theme.chat.message.outgoing),
|
||||
theme: buttonTheme,
|
||||
transcriptionState: effectiveAudioTranscriptionState,
|
||||
pressed: {
|
||||
guard let strongSelf = self else {
|
||||
|
@ -427,6 +427,10 @@ final class ShareWithPeersScreenComponent: Component {
|
||||
}
|
||||
}
|
||||
|
||||
func scrollViewWillBeginDragging(_ scrollView: UIScrollView) {
|
||||
self.endEditing(true)
|
||||
}
|
||||
|
||||
func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) {
|
||||
guard let itemLayout = self.itemLayout, let topOffsetDistance = self.topOffsetDistance else {
|
||||
return
|
||||
@ -801,7 +805,7 @@ final class ShareWithPeersScreenComponent: Component {
|
||||
}
|
||||
|
||||
private func updateModalOverlayTransition(transition: Transition) {
|
||||
guard let component = self.component, let environment = self.environment, let itemLayout = self.itemLayout else {
|
||||
guard let component = self.component, let environment = self.environment, let itemLayout = self.itemLayout, !self.isDismissed else {
|
||||
return
|
||||
}
|
||||
|
||||
@ -2071,6 +2075,14 @@ final class ShareWithPeersScreenComponent: Component {
|
||||
self.selectedCategories.insert(.everyone)
|
||||
}
|
||||
self.state?.updated(transition: Transition(animation: .curve(duration: 0.35, curve: .spring)))
|
||||
},
|
||||
isFocusedUpdated: { [weak self] isFocused in
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
if isFocused {
|
||||
self.scrollView.setContentOffset(CGPoint(x: 0.0, y: -self.scrollView.contentInset.top), animated: true)
|
||||
}
|
||||
}
|
||||
)),
|
||||
environment: {},
|
||||
@ -2122,11 +2134,11 @@ final class ShareWithPeersScreenComponent: Component {
|
||||
|
||||
transition.setFrame(view: self.dimView, frame: CGRect(origin: CGPoint(), size: availableSize))
|
||||
if case .members = component.stateContext.subject {
|
||||
self.dimView .isHidden = true
|
||||
self.dimView.isHidden = true
|
||||
} else if case .channels = component.stateContext.subject {
|
||||
self.dimView .isHidden = true
|
||||
self.dimView.isHidden = true
|
||||
} else {
|
||||
self.dimView .isHidden = false
|
||||
self.dimView.isHidden = false
|
||||
}
|
||||
|
||||
let categoryItemSize = self.categoryTemplateItem.update(
|
||||
|
@ -88,6 +88,7 @@ public final class TokenListTextField: Component {
|
||||
public let tokens: [Token]
|
||||
public let sideInset: CGFloat
|
||||
public let deleteToken: (AnyHashable) -> Void
|
||||
public let isFocusedUpdated: (Bool) -> Void
|
||||
|
||||
public init(
|
||||
externalState: ExternalState,
|
||||
@ -96,7 +97,8 @@ public final class TokenListTextField: Component {
|
||||
placeholder: String,
|
||||
tokens: [Token],
|
||||
sideInset: CGFloat,
|
||||
deleteToken: @escaping (AnyHashable) -> Void
|
||||
deleteToken: @escaping (AnyHashable) -> Void,
|
||||
isFocusedUpdated: @escaping (Bool) -> Void = { _ in }
|
||||
) {
|
||||
self.externalState = externalState
|
||||
self.context = context
|
||||
@ -105,6 +107,7 @@ public final class TokenListTextField: Component {
|
||||
self.tokens = tokens
|
||||
self.sideInset = sideInset
|
||||
self.deleteToken = deleteToken
|
||||
self.isFocusedUpdated = isFocusedUpdated
|
||||
}
|
||||
|
||||
public static func ==(lhs: TokenListTextField, rhs: TokenListTextField) -> Bool {
|
||||
@ -191,6 +194,7 @@ public final class TokenListTextField: Component {
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
self.component?.isFocusedUpdated(self.tokenListNode?.isFocused ?? false)
|
||||
self.componentState?.updated(transition: Transition(animation: .curve(duration: 0.35, curve: .spring)))
|
||||
}
|
||||
|
||||
|
@ -302,7 +302,7 @@ func openResolvedUrlImpl(
|
||||
})
|
||||
dismissInput()
|
||||
case let .share(url, text, to):
|
||||
let continueWithPeer: (PeerId) -> Void = { peerId in
|
||||
let continueWithPeer: (PeerId, Int64?) -> Void = { peerId, threadId in
|
||||
let textInputState: ChatTextInputState?
|
||||
if let text = text, !text.isEmpty {
|
||||
if let url = url, !url.isEmpty {
|
||||
@ -320,15 +320,42 @@ func openResolvedUrlImpl(
|
||||
textInputState = nil
|
||||
}
|
||||
|
||||
let updateControllers = { [weak navigationController] in
|
||||
guard let navigationController else {
|
||||
return
|
||||
}
|
||||
let chatController: Signal<ChatController, NoError>
|
||||
if let threadId {
|
||||
chatController = chatControllerForForumThreadImpl(context: context, peerId: peerId, threadId: threadId)
|
||||
} else {
|
||||
chatController = .single(ChatControllerImpl(context: context, chatLocation: .peer(id: peerId)))
|
||||
}
|
||||
|
||||
let _ = (chatController
|
||||
|> deliverOnMainQueue).start(next: { [weak navigationController] chatController in
|
||||
guard let navigationController else {
|
||||
return
|
||||
}
|
||||
var controllers = navigationController.viewControllers.filter { controller in
|
||||
if controller is PeerSelectionController {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
controllers.append(chatController)
|
||||
navigationController.setViewControllers(controllers, animated: true)
|
||||
})
|
||||
}
|
||||
|
||||
if let textInputState = textInputState {
|
||||
let _ = (ChatInterfaceState.update(engine: context.engine, peerId: peerId, threadId: nil, { currentState in
|
||||
let _ = (ChatInterfaceState.update(engine: context.engine, peerId: peerId, threadId: threadId, { currentState in
|
||||
return currentState.withUpdatedComposeInputState(textInputState)
|
||||
})
|
||||
|> deliverOnMainQueue).startStandalone(completed: {
|
||||
navigationController?.pushViewController(ChatControllerImpl(context: context, chatLocation: .peer(id: peerId)))
|
||||
updateControllers()
|
||||
})
|
||||
} else {
|
||||
navigationController?.pushViewController(ChatControllerImpl(context: context, chatLocation: .peer(id: peerId)))
|
||||
updateControllers()
|
||||
}
|
||||
}
|
||||
|
||||
@ -344,7 +371,7 @@ func openResolvedUrlImpl(
|
||||
|> deliverOnMainQueue).startStandalone(next: { peer in
|
||||
if let peer = peer {
|
||||
context.sharedContext.applicationBindings.dismissNativeController()
|
||||
continueWithPeer(peer.id)
|
||||
continueWithPeer(peer.id, nil)
|
||||
}
|
||||
})
|
||||
} else {
|
||||
@ -352,7 +379,7 @@ func openResolvedUrlImpl(
|
||||
|> deliverOnMainQueue).startStandalone(next: { peer in
|
||||
if let peer = peer {
|
||||
context.sharedContext.applicationBindings.dismissNativeController()
|
||||
continueWithPeer(peer.id)
|
||||
continueWithPeer(peer.id, nil)
|
||||
}
|
||||
})
|
||||
/*let query = to.trimmingCharacters(in: CharacterSet(charactersIn: "0123456789").inverted)
|
||||
@ -377,13 +404,8 @@ func openResolvedUrlImpl(
|
||||
context.sharedContext.applicationBindings.dismissNativeController()
|
||||
} else {
|
||||
let controller = context.sharedContext.makePeerSelectionController(PeerSelectionControllerParams(context: context, filter: [.onlyWriteable, .excludeDisabled], selectForumThreads: true))
|
||||
controller.peerSelected = { [weak controller] peer, _ in
|
||||
let peerId = peer.id
|
||||
|
||||
if let strongController = controller {
|
||||
strongController.dismiss()
|
||||
continueWithPeer(peerId)
|
||||
}
|
||||
controller.peerSelected = { peer, threadId in
|
||||
continueWithPeer(peer.id, threadId)
|
||||
}
|
||||
context.sharedContext.applicationBindings.dismissNativeController()
|
||||
navigationController?.pushViewController(controller)
|
||||
|
Loading…
x
Reference in New Issue
Block a user