mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
Various improvements
This commit is contained in:
parent
dd1d340fdd
commit
e27ec389b1
BIN
Telegram/Telegram-iOS/Resources/Gift2.tgs
Normal file
BIN
Telegram/Telegram-iOS/Resources/Gift2.tgs
Normal file
Binary file not shown.
BIN
Telegram/Telegram-iOS/Resources/Gift3.tgs
Normal file
BIN
Telegram/Telegram-iOS/Resources/Gift3.tgs
Normal file
Binary file not shown.
@ -7840,3 +7840,6 @@ Sorry for the inconvenience.";
|
|||||||
|
|
||||||
"Gallery.AirPlay" = "AirPlay";
|
"Gallery.AirPlay" = "AirPlay";
|
||||||
"Gallery.AirPlayPlaceholder" = "This video is playing on the TV using AirPlay";
|
"Gallery.AirPlayPlaceholder" = "This video is playing on the TV using AirPlay";
|
||||||
|
|
||||||
|
"WebApp.CloseConfirmation" = "Changes that you made may not be saved.";
|
||||||
|
"WebApp.CloseAnyway" = "Close Anyway";
|
||||||
|
@ -37,6 +37,8 @@ final class AttachmentContainer: ASDisplayNode, UIGestureRecognizerDelegate {
|
|||||||
var interactivelyDismissed: (() -> Void)?
|
var interactivelyDismissed: (() -> Void)?
|
||||||
var controllerRemoved: ((ViewController) -> Void)?
|
var controllerRemoved: ((ViewController) -> Void)?
|
||||||
|
|
||||||
|
var shouldCancelPanGesture: (() -> Bool)?
|
||||||
|
|
||||||
var updateModalProgress: ((CGFloat, ContainedViewLayoutTransition) -> Void)?
|
var updateModalProgress: ((CGFloat, ContainedViewLayoutTransition) -> Void)?
|
||||||
|
|
||||||
private var isUpdatingState = false
|
private var isUpdatingState = false
|
||||||
@ -232,6 +234,11 @@ final class AttachmentContainer: ASDisplayNode, UIGestureRecognizerDelegate {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if translation > 40.0, let shouldCancelPanGesture = self.shouldCancelPanGesture, shouldCancelPanGesture() {
|
||||||
|
self.cancelPanGesture()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
var bounds = self.bounds
|
var bounds = self.bounds
|
||||||
if self.isExpanded {
|
if self.isExpanded {
|
||||||
bounds.origin.y = -max(0.0, translation - edgeTopInset)
|
bounds.origin.y = -max(0.0, translation - edgeTopInset)
|
||||||
@ -340,6 +347,12 @@ final class AttachmentContainer: ASDisplayNode, UIGestureRecognizerDelegate {
|
|||||||
|
|
||||||
self.isAnimating = true
|
self.isAnimating = true
|
||||||
self.update(layout: layout, controllers: controllers, coveredByModalTransition: coveredByModalTransition, transition: .animated(duration: 0.3, curve: .easeInOut), completion: completion)
|
self.update(layout: layout, controllers: controllers, coveredByModalTransition: coveredByModalTransition, transition: .animated(duration: 0.3, curve: .easeInOut), completion: completion)
|
||||||
|
|
||||||
|
var bounds = self.bounds
|
||||||
|
let previousBounds = bounds
|
||||||
|
bounds.origin.y = 0.0
|
||||||
|
self.bounds = bounds
|
||||||
|
self.layer.animateBounds(from: previousBounds, to: self.bounds, duration: 0.3, timingFunction: CAMediaTimingFunctionName.easeInEaseOut.rawValue)
|
||||||
default:
|
default:
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
@ -83,6 +83,7 @@ public protocol AttachmentContainable: ViewController {
|
|||||||
func prepareForReuse()
|
func prepareForReuse()
|
||||||
|
|
||||||
func requestDismiss(completion: @escaping () -> Void)
|
func requestDismiss(completion: @escaping () -> Void)
|
||||||
|
func shouldDismissImmediately() -> Bool
|
||||||
}
|
}
|
||||||
|
|
||||||
public extension AttachmentContainable {
|
public extension AttachmentContainable {
|
||||||
@ -101,6 +102,10 @@ public extension AttachmentContainable {
|
|||||||
func requestDismiss(completion: @escaping () -> Void) {
|
func requestDismiss(completion: @escaping () -> Void) {
|
||||||
completion()
|
completion()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func shouldDismissImmediately() -> Bool {
|
||||||
|
return true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum AttachmentMediaPickerSendMode {
|
public enum AttachmentMediaPickerSendMode {
|
||||||
@ -312,6 +317,23 @@ public class AttachmentController: ViewController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self.container.shouldCancelPanGesture = { [weak self] in
|
||||||
|
if let strongSelf = self, let currentController = strongSelf.currentControllers.last {
|
||||||
|
if !currentController.shouldDismissImmediately() {
|
||||||
|
currentController.requestDismiss { [weak self] in
|
||||||
|
if let strongSelf = self {
|
||||||
|
strongSelf.controller?.dismiss(animated: true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
self.panel.selectionChanged = { [weak self] type in
|
self.panel.selectionChanged = { [weak self] type in
|
||||||
if let strongSelf = self {
|
if let strongSelf = self {
|
||||||
return strongSelf.switchToController(type)
|
return strongSelf.switchToController(type)
|
||||||
|
@ -1335,6 +1335,14 @@ public final class MediaPickerScreen: ViewController, AttachmentContainable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public func shouldDismissImmediately() -> Bool {
|
||||||
|
if let selectionState = self.interaction?.selectionState, selectionState.count() > 0 {
|
||||||
|
return false
|
||||||
|
} else {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@objc private func cancelPressed() {
|
@objc private func cancelPressed() {
|
||||||
self.dismissAllTooltips()
|
self.dismissAllTooltips()
|
||||||
|
|
||||||
|
@ -846,12 +846,14 @@ private final class PremiumGiftScreenComponent: CombinedComponent {
|
|||||||
}
|
}
|
||||||
}, completed: { [weak self] in
|
}, completed: { [weak self] in
|
||||||
if let strongSelf = self {
|
if let strongSelf = self {
|
||||||
let _ = updatePremiumPromoConfigurationOnce(account: strongSelf.context.account).start()
|
Queue.mainQueue().after(2.0) {
|
||||||
strongSelf.inProgress = false
|
let _ = updatePremiumPromoConfigurationOnce(account: strongSelf.context.account).start()
|
||||||
strongSelf.updateInProgress(false)
|
strongSelf.inProgress = false
|
||||||
|
strongSelf.updateInProgress(false)
|
||||||
strongSelf.updated(transition: .easeInOut(duration: 0.25))
|
|
||||||
strongSelf.completion(duration)
|
strongSelf.updated(transition: .easeInOut(duration: 0.25))
|
||||||
|
strongSelf.completion(duration)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
@ -1265,8 +1267,8 @@ public final class PremiumGiftScreen: ViewControllerComponentContainer {
|
|||||||
controllers = controllers.filter { !($0 is PeerInfoScreen) && !($0 is PremiumGiftScreen) }
|
controllers = controllers.filter { !($0 is PeerInfoScreen) && !($0 is PremiumGiftScreen) }
|
||||||
navigationController.setViewControllers(controllers, animated: true)
|
navigationController.setViewControllers(controllers, animated: true)
|
||||||
|
|
||||||
Queue.mainQueue().after(0.1, {
|
Queue.mainQueue().after(2.8, {
|
||||||
if let topController = navigationController.viewControllers.first {
|
if let topController = navigationController.viewControllers.last {
|
||||||
topController.view.addSubview(ConfettiView(frame: topController.view.bounds))
|
topController.view.addSubview(ConfettiView(frame: topController.view.bounds))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -1522,7 +1522,7 @@ private final class PremiumIntroScreenComponent: CombinedComponent {
|
|||||||
maximumNumberOfLines: 2,
|
maximumNumberOfLines: 2,
|
||||||
lineSpacing: 0.0
|
lineSpacing: 0.0
|
||||||
),
|
),
|
||||||
availableSize: context.availableSize,
|
availableSize: CGSize(width: context.availableSize.width - 32.0, height: context.availableSize.width),
|
||||||
transition: context.transition
|
transition: context.transition
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -65,8 +65,6 @@ class ChatMessageGiftBubbleContentNode: ChatMessageBubbleContentNode {
|
|||||||
self.buttonNode.cornerRadius = 17.0
|
self.buttonNode.cornerRadius = 17.0
|
||||||
|
|
||||||
self.animationNode = DefaultAnimatedStickerNodeImpl()
|
self.animationNode = DefaultAnimatedStickerNodeImpl()
|
||||||
self.animationNode.setup(source: AnimatedStickerNodeLocalFileSource(name: "Gift"), width: 384, height: 384, playbackMode: .once, mode: .direct(cachePathPrefix: nil))
|
|
||||||
self.animationNode.visibility = true
|
|
||||||
|
|
||||||
self.buttonStarsNode = PremiumStarsNode()
|
self.buttonStarsNode = PremiumStarsNode()
|
||||||
|
|
||||||
@ -136,11 +134,22 @@ class ChatMessageGiftBubbleContentNode: ChatMessageBubbleContentNode {
|
|||||||
let primaryTextColor = serviceMessageColorComponents(theme: item.presentationData.theme.theme, wallpaper: item.presentationData.theme.wallpaper).primaryText
|
let primaryTextColor = serviceMessageColorComponents(theme: item.presentationData.theme.theme, wallpaper: item.presentationData.theme.wallpaper).primaryText
|
||||||
|
|
||||||
var duration: String = ""
|
var duration: String = ""
|
||||||
|
var animationName: String = ""
|
||||||
for media in item.message.media {
|
for media in item.message.media {
|
||||||
if let action = media as? TelegramMediaAction {
|
if let action = media as? TelegramMediaAction {
|
||||||
switch action.action {
|
switch action.action {
|
||||||
case let .giftPremium(_, _, durationValue):
|
case let .giftPremium(_, _, months):
|
||||||
duration = item.presentationData.strings.Notification_PremiumGift_Subtitle(item.presentationData.strings.Notification_PremiumGift_Months(durationValue)).string
|
duration = item.presentationData.strings.Notification_PremiumGift_Subtitle(item.presentationData.strings.Notification_PremiumGift_Months(months)).string
|
||||||
|
switch months {
|
||||||
|
case 12:
|
||||||
|
animationName = "Gift2"
|
||||||
|
case 6:
|
||||||
|
animationName = "Gift1"
|
||||||
|
case 3:
|
||||||
|
animationName = "Gift3"
|
||||||
|
default:
|
||||||
|
animationName = "Gift3"
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
@ -190,6 +199,10 @@ class ChatMessageGiftBubbleContentNode: ChatMessageBubbleContentNode {
|
|||||||
return (backgroundSize.width, { boundingWidth in
|
return (backgroundSize.width, { boundingWidth in
|
||||||
return (backgroundSize, { [weak self] animation, synchronousLoads, _ in
|
return (backgroundSize, { [weak self] animation, synchronousLoads, _ in
|
||||||
if let strongSelf = self {
|
if let strongSelf = self {
|
||||||
|
if strongSelf.item == nil {
|
||||||
|
strongSelf.animationNode.setup(source: AnimatedStickerNodeLocalFileSource(name: animationName), width: 384, height: 384, playbackMode: .once, mode: .direct(cachePathPrefix: nil))
|
||||||
|
strongSelf.animationNode.visibility = true
|
||||||
|
}
|
||||||
strongSelf.item = item
|
strongSelf.item = item
|
||||||
|
|
||||||
strongSelf.backgroundColorNode.backgroundColor = selectDateFillStaticColor(theme: item.presentationData.theme.theme, wallpaper: item.presentationData.theme.wallpaper)
|
strongSelf.backgroundColorNode.backgroundColor = selectDateFillStaticColor(theme: item.presentationData.theme.theme, wallpaper: item.presentationData.theme.wallpaper)
|
||||||
|
@ -778,14 +778,16 @@ public final class WebAppController: ViewController, AttachmentContainable {
|
|||||||
self.controller?.present(alertController, in: .window(.root))
|
self.controller?.present(alertController, in: .window(.root))
|
||||||
}
|
}
|
||||||
case "web_app_setup_closing_behavior":
|
case "web_app_setup_closing_behavior":
|
||||||
if let json = json, let _ = json["need_confirmation"] as? String {
|
if let json = json, let needConfirmation = json["need_confirmation"] as? Bool {
|
||||||
|
self.needDismissConfirmation = needConfirmation
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fileprivate var needDismissConfirmation = false
|
||||||
|
|
||||||
private var headerColorKey: String?
|
private var headerColorKey: String?
|
||||||
private func updateHeaderBackgroundColor(transition: ContainedViewLayoutTransition) {
|
private func updateHeaderBackgroundColor(transition: ContainedViewLayoutTransition) {
|
||||||
let color: UIColor?
|
let color: UIColor?
|
||||||
@ -1121,6 +1123,27 @@ public final class WebAppController: ViewController, AttachmentContainable {
|
|||||||
public func prepareForReuse() {
|
public func prepareForReuse() {
|
||||||
self.updateTabBarAlpha(1.0, .immediate)
|
self.updateTabBarAlpha(1.0, .immediate)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public func requestDismiss(completion: @escaping () -> Void) {
|
||||||
|
if self.controllerNode.needDismissConfirmation {
|
||||||
|
let controller = textAlertController(context: self.context, title: nil, text: self.presentationData.strings.WebApp_CloseConfirmation, actions: [TextAlertAction(type: .genericAction, title: self.presentationData.strings.WebApp_CloseAnyway, action: {
|
||||||
|
completion()
|
||||||
|
}), TextAlertAction(type: .defaultAction, title: self.presentationData.strings.Common_Cancel, action: {
|
||||||
|
|
||||||
|
})], actionLayout: .vertical)
|
||||||
|
self.present(controller, in: .window(.root))
|
||||||
|
} else {
|
||||||
|
completion()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public func shouldDismissImmediately() -> Bool {
|
||||||
|
if self.controllerNode.needDismissConfirmation {
|
||||||
|
return false
|
||||||
|
} else {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
final class WebAppPickerContext: AttachmentMediaPickerContext {
|
final class WebAppPickerContext: AttachmentMediaPickerContext {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"app": "8.8.2",
|
"app": "8.8.3",
|
||||||
"bazel": "5.1.0",
|
"bazel": "5.1.0",
|
||||||
"xcode": "13.4.1"
|
"xcode": "13.4.1"
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user