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
f4aaf08e8c
commit
e7f6d60b73
@ -13223,3 +13223,6 @@ Sorry for the inconvenience.";
|
|||||||
"Gift.Send.SendShort" = "Send";
|
"Gift.Send.SendShort" = "Send";
|
||||||
|
|
||||||
"Premium.EmojiStatus.Proceed" = "Unlock Emoji Statuses";
|
"Premium.EmojiStatus.Proceed" = "Unlock Emoji Statuses";
|
||||||
|
|
||||||
|
"Stars.Transaction.Subscription.CancelledByBot" = "Your subscription was cancelled by the bot.";
|
||||||
|
"Stars.Transaction.Subscription.CancelledByBusiness" = "Your subscription was cancelled by the business.";
|
||||||
|
@ -568,6 +568,9 @@ private extension StarsContext.State.Subscription {
|
|||||||
if (apiFlags & (1 << 2)) != 0 {
|
if (apiFlags & (1 << 2)) != 0 {
|
||||||
flags.insert(.missingBalance)
|
flags.insert(.missingBalance)
|
||||||
}
|
}
|
||||||
|
if (apiFlags & (1 << 7)) != 0 {
|
||||||
|
flags.insert(.isCancelledByBot)
|
||||||
|
}
|
||||||
self.init(flags: flags, id: id, peer: EnginePeer(peer), untilDate: untilDate, pricing: StarsSubscriptionPricing(apiStarsSubscriptionPricing: pricing), inviteHash: inviteHash, title: title, photo: photo.flatMap(TelegramMediaWebFile.init), invoiceSlug: invoiceSlug)
|
self.init(flags: flags, id: id, peer: EnginePeer(peer), untilDate: untilDate, pricing: StarsSubscriptionPricing(apiStarsSubscriptionPricing: pricing), inviteHash: inviteHash, title: title, photo: photo.flatMap(TelegramMediaWebFile.init), invoiceSlug: invoiceSlug)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -719,6 +722,7 @@ public final class StarsContext {
|
|||||||
public static let isCancelled = Flags(rawValue: 1 << 0)
|
public static let isCancelled = Flags(rawValue: 1 << 0)
|
||||||
public static let canRefulfill = Flags(rawValue: 1 << 1)
|
public static let canRefulfill = Flags(rawValue: 1 << 1)
|
||||||
public static let missingBalance = Flags(rawValue: 1 << 2)
|
public static let missingBalance = Flags(rawValue: 1 << 2)
|
||||||
|
public static let isCancelledByBot = Flags(rawValue: 1 << 3)
|
||||||
}
|
}
|
||||||
|
|
||||||
public let flags: Flags
|
public let flags: Flags
|
||||||
|
@ -149,6 +149,8 @@ private func contentNodeMessagesAndClassesForItem(_ item: ChatMessageItem) -> ([
|
|||||||
messageWithCaptionToAdd = (message, itemAttributes)
|
messageWithCaptionToAdd = (message, itemAttributes)
|
||||||
}
|
}
|
||||||
result.append((message, ChatMessageMediaBubbleContentNode.self, itemAttributes, BubbleItemAttributes(isAttachment: false, neighborType: .media, neighborSpacing: .default)))
|
result.append((message, ChatMessageMediaBubbleContentNode.self, itemAttributes, BubbleItemAttributes(isAttachment: false, neighborType: .media, neighborSpacing: .default)))
|
||||||
|
} else if let _ = media as? TelegramMediaWebFile {
|
||||||
|
result.append((message, ChatMessageMediaBubbleContentNode.self, itemAttributes, BubbleItemAttributes(isAttachment: false, neighborType: .media, neighborSpacing: .default)))
|
||||||
} else if let story = media as? TelegramMediaStory {
|
} else if let story = media as? TelegramMediaStory {
|
||||||
if story.isMention {
|
if story.isMention {
|
||||||
if let storyItem = message.associatedStories[story.storyId], storyItem.data.isEmpty {
|
if let storyItem = message.associatedStories[story.storyId], storyItem.data.isEmpty {
|
||||||
|
@ -1920,6 +1920,8 @@ public final class ChatMessageInteractiveMediaNode: ASDisplayNode, GalleryItemTr
|
|||||||
imageDimensions = dimensions.cgSize
|
imageDimensions = dimensions.cgSize
|
||||||
} else if let image = media as? TelegramMediaWebFile, let dimensions = image.dimensions {
|
} else if let image = media as? TelegramMediaWebFile, let dimensions = image.dimensions {
|
||||||
imageDimensions = dimensions.cgSize
|
imageDimensions = dimensions.cgSize
|
||||||
|
} else if let file = media as? TelegramMediaWebFile, let dimensions = file.dimensions {
|
||||||
|
imageDimensions = dimensions.cgSize
|
||||||
}
|
}
|
||||||
|
|
||||||
if let imageDimensions = imageDimensions {
|
if let imageDimensions = imageDimensions {
|
||||||
|
@ -183,8 +183,7 @@ public class ChatMessageMediaBubbleContentNode: ChatMessageBubbleContentNode {
|
|||||||
} else if let invoice = media as? TelegramMediaInvoice {
|
} else if let invoice = media as? TelegramMediaInvoice {
|
||||||
selectedMedia = invoice
|
selectedMedia = invoice
|
||||||
extendedMedia = invoice.extendedMedia
|
extendedMedia = invoice.extendedMedia
|
||||||
}
|
} else if let paidContent = media as? TelegramMediaPaidContent {
|
||||||
else if let paidContent = media as? TelegramMediaPaidContent {
|
|
||||||
selectedMedia = paidContent
|
selectedMedia = paidContent
|
||||||
if case let .mosaic(_, _, index) = preparePosition, let index {
|
if case let .mosaic(_, _, index) = preparePosition, let index {
|
||||||
extendedMedia = paidContent.extendedMedia[index]
|
extendedMedia = paidContent.extendedMedia[index]
|
||||||
@ -192,6 +191,11 @@ public class ChatMessageMediaBubbleContentNode: ChatMessageBubbleContentNode {
|
|||||||
} else {
|
} else {
|
||||||
extendedMedia = paidContent.extendedMedia.first
|
extendedMedia = paidContent.extendedMedia.first
|
||||||
}
|
}
|
||||||
|
} else if let webFile = media as? TelegramMediaWebFile {
|
||||||
|
selectedMedia = webFile
|
||||||
|
if item.presentationData.isPreview {
|
||||||
|
automaticDownload = .full
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,18 +15,20 @@ import MultilineTextComponent
|
|||||||
public final class StarsAvatarComponent: Component {
|
public final class StarsAvatarComponent: Component {
|
||||||
let context: AccountContext
|
let context: AccountContext
|
||||||
let theme: PresentationTheme
|
let theme: PresentationTheme
|
||||||
let peer: StarsContext.State.Transaction.Peer
|
let peer: StarsContext.State.Transaction.Peer?
|
||||||
let photo: TelegramMediaWebFile?
|
let photo: TelegramMediaWebFile?
|
||||||
let media: [Media]
|
let media: [Media]
|
||||||
let backgroundColor: UIColor
|
let backgroundColor: UIColor
|
||||||
|
let size: CGSize?
|
||||||
|
|
||||||
public init(context: AccountContext, theme: PresentationTheme, peer: StarsContext.State.Transaction.Peer, photo: TelegramMediaWebFile?, media: [Media], backgroundColor: UIColor) {
|
public init(context: AccountContext, theme: PresentationTheme, peer: StarsContext.State.Transaction.Peer?, photo: TelegramMediaWebFile?, media: [Media], backgroundColor: UIColor, size: CGSize? = nil) {
|
||||||
self.context = context
|
self.context = context
|
||||||
self.theme = theme
|
self.theme = theme
|
||||||
self.peer = peer
|
self.peer = peer
|
||||||
self.photo = photo
|
self.photo = photo
|
||||||
self.media = media
|
self.media = media
|
||||||
self.backgroundColor = backgroundColor
|
self.backgroundColor = backgroundColor
|
||||||
|
self.size = size
|
||||||
}
|
}
|
||||||
|
|
||||||
public static func ==(lhs: StarsAvatarComponent, rhs: StarsAvatarComponent) -> Bool {
|
public static func ==(lhs: StarsAvatarComponent, rhs: StarsAvatarComponent) -> Bool {
|
||||||
@ -48,6 +50,9 @@ public final class StarsAvatarComponent: Component {
|
|||||||
if lhs.backgroundColor != rhs.backgroundColor {
|
if lhs.backgroundColor != rhs.backgroundColor {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
if lhs.size != rhs.size {
|
||||||
|
return false
|
||||||
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -88,14 +93,13 @@ public final class StarsAvatarComponent: Component {
|
|||||||
self.component = component
|
self.component = component
|
||||||
self.state = state
|
self.state = state
|
||||||
|
|
||||||
let size = CGSize(width: 40.0, height: 40.0)
|
let size = component.size ?? CGSize(width: 40.0, height: 40.0)
|
||||||
var iconInset: CGFloat = 3.0
|
var iconInset: CGFloat = 3.0
|
||||||
var iconOffset: CGFloat = 0.0
|
var iconOffset: CGFloat = 0.0
|
||||||
|
|
||||||
var dimensions = size
|
var dimensions = size
|
||||||
|
|
||||||
switch component.peer {
|
var didSetup = false
|
||||||
case let .peer(peer):
|
|
||||||
if !component.media.isEmpty {
|
if !component.media.isEmpty {
|
||||||
let imageNode: TransformImageNode
|
let imageNode: TransformImageNode
|
||||||
var isFirstTime = false
|
var isFirstTime = false
|
||||||
@ -180,6 +184,7 @@ public final class StarsAvatarComponent: Component {
|
|||||||
self.backgroundView.isHidden = true
|
self.backgroundView.isHidden = true
|
||||||
self.iconView.isHidden = true
|
self.iconView.isHidden = true
|
||||||
self.avatarNode.isHidden = true
|
self.avatarNode.isHidden = true
|
||||||
|
didSetup = true
|
||||||
} else if let photo = component.photo {
|
} else if let photo = component.photo {
|
||||||
let imageNode: TransformImageNode
|
let imageNode: TransformImageNode
|
||||||
if let current = self.imageNode {
|
if let current = self.imageNode {
|
||||||
@ -195,12 +200,19 @@ public final class StarsAvatarComponent: Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
imageNode.frame = CGRect(origin: .zero, size: size)
|
imageNode.frame = CGRect(origin: .zero, size: size)
|
||||||
imageNode.asyncLayout()(TransformImageArguments(corners: ImageCorners(radius: 8.0), imageSize: size, boundingSize: size, intrinsicInsets: UIEdgeInsets(), emptyColor: component.theme.list.mediaPlaceholderColor))()
|
imageNode.asyncLayout()(TransformImageArguments(corners: ImageCorners(radius: floor(size.width / 5.0)), imageSize: size, boundingSize: size, intrinsicInsets: UIEdgeInsets(), emptyColor: component.theme.list.mediaPlaceholderColor))()
|
||||||
|
|
||||||
self.backgroundView.isHidden = true
|
self.backgroundView.isHidden = true
|
||||||
self.iconView.isHidden = true
|
self.iconView.isHidden = true
|
||||||
self.avatarNode.isHidden = true
|
self.avatarNode.isHidden = true
|
||||||
} else {
|
didSetup = true
|
||||||
|
}
|
||||||
|
|
||||||
|
switch component.peer {
|
||||||
|
case .none:
|
||||||
|
break
|
||||||
|
case let .peer(peer):
|
||||||
|
if !didSetup {
|
||||||
self.avatarNode.setPeer(
|
self.avatarNode.setPeer(
|
||||||
context: component.context,
|
context: component.context,
|
||||||
theme: component.theme,
|
theme: component.theme,
|
||||||
|
@ -226,6 +226,7 @@ private final class StarsTransactionSheetContent: CombinedComponent {
|
|||||||
var isSubscriber = false
|
var isSubscriber = false
|
||||||
var isSubscriptionFee = false
|
var isSubscriptionFee = false
|
||||||
var isBotSubscription = false
|
var isBotSubscription = false
|
||||||
|
var isBusinessSubscription = false
|
||||||
var isCancelled = false
|
var isCancelled = false
|
||||||
var isReaction = false
|
var isReaction = false
|
||||||
var giveawayMessageId: MessageId?
|
var giveawayMessageId: MessageId?
|
||||||
@ -259,8 +260,12 @@ private final class StarsTransactionSheetContent: CombinedComponent {
|
|||||||
transactionPeer = .peer(peer)
|
transactionPeer = .peer(peer)
|
||||||
isSubscriber = true
|
isSubscriber = true
|
||||||
case let .subscription(subscription):
|
case let .subscription(subscription):
|
||||||
if case let .user(user) = subscription.peer, user.botInfo != nil {
|
if case let .user(user) = subscription.peer {
|
||||||
|
if user.botInfo != nil {
|
||||||
isBotSubscription = true
|
isBotSubscription = true
|
||||||
|
} else {
|
||||||
|
isBusinessSubscription = true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if let title = subscription.title {
|
if let title = subscription.title {
|
||||||
titleText = title
|
titleText = title
|
||||||
@ -318,18 +323,30 @@ private final class StarsTransactionSheetContent: CombinedComponent {
|
|||||||
}
|
}
|
||||||
isCancelled = true
|
isCancelled = true
|
||||||
} else {
|
} else {
|
||||||
if subscription.flags.contains(.isCancelled) {
|
if subscription.flags.contains(.isCancelledByBot) {
|
||||||
|
if case let .user(user) = subscription.peer, user.botInfo == nil {
|
||||||
|
statusText = strings.Stars_Transaction_Subscription_CancelledByBusiness
|
||||||
|
} else {
|
||||||
|
statusText = strings.Stars_Transaction_Subscription_CancelledByBot
|
||||||
|
}
|
||||||
|
statusIsDestructive = true
|
||||||
|
buttonText = strings.Common_OK
|
||||||
|
isCancelled = true
|
||||||
|
} else if subscription.flags.contains(.isCancelled) {
|
||||||
statusText = strings.Stars_Transaction_Subscription_Cancelled
|
statusText = strings.Stars_Transaction_Subscription_Cancelled
|
||||||
statusIsDestructive = true
|
statusIsDestructive = true
|
||||||
if date > Int32(CFAbsoluteTimeGetCurrent() + kCFAbsoluteTimeIntervalSince1970) {
|
if date > Int32(CFAbsoluteTimeGetCurrent() + kCFAbsoluteTimeIntervalSince1970) {
|
||||||
buttonText = strings.Stars_Transaction_Subscription_Renew
|
buttonText = strings.Stars_Transaction_Subscription_Renew
|
||||||
} else {
|
} else {
|
||||||
if let _ = subscription.inviteHash, !isKicked {
|
if let _ = subscription.invoiceSlug {
|
||||||
|
buttonText = strings.Stars_Transaction_Subscription_Renew
|
||||||
|
} else if let _ = subscription.inviteHash, !isKicked {
|
||||||
buttonText = strings.Stars_Transaction_Subscription_JoinAgainChannel
|
buttonText = strings.Stars_Transaction_Subscription_JoinAgainChannel
|
||||||
} else {
|
} else {
|
||||||
buttonText = strings.Common_OK
|
buttonText = strings.Common_OK
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
isCancelled = true
|
||||||
} else {
|
} else {
|
||||||
statusText = strings.Stars_Transaction_Subscription_Active(stringForMediumDate(timestamp: subscription.untilDate, strings: strings, dateTimeFormat: dateTimeFormat, withTime: false)).string
|
statusText = strings.Stars_Transaction_Subscription_Active(stringForMediumDate(timestamp: subscription.untilDate, strings: strings, dateTimeFormat: dateTimeFormat, withTime: false)).string
|
||||||
cancelButtonText = strings.Stars_Transaction_Subscription_Cancel
|
cancelButtonText = strings.Stars_Transaction_Subscription_Cancel
|
||||||
@ -710,6 +727,8 @@ private final class StarsTransactionSheetContent: CombinedComponent {
|
|||||||
if isBotSubscription {
|
if isBotSubscription {
|
||||||
//TODO:localize
|
//TODO:localize
|
||||||
title = "Bot"
|
title = "Bot"
|
||||||
|
} else if isBusinessSubscription {
|
||||||
|
title = "Business"
|
||||||
} else {
|
} else {
|
||||||
title = strings.Stars_Transaction_Subscription_Subscription
|
title = strings.Stars_Transaction_Subscription_Subscription
|
||||||
}
|
}
|
||||||
|
@ -708,10 +708,10 @@ final class StarsTransactionsScreenComponent: Component {
|
|||||||
))
|
))
|
||||||
))
|
))
|
||||||
var nameGroupComponent: AnyComponent<Empty>
|
var nameGroupComponent: AnyComponent<Empty>
|
||||||
if let _ = subscription.photo {
|
if let photo = subscription.photo {
|
||||||
nameGroupComponent = AnyComponent(
|
nameGroupComponent = AnyComponent(
|
||||||
HStack([
|
HStack([
|
||||||
AnyComponentWithIdentity(id: AnyHashable(0), component: AnyComponent(RoundedRectangle(color: .lightGray, cornerRadius: 3.0, size: CGSize(width: 19.0, height: 19.0)))),
|
AnyComponentWithIdentity(id: AnyHashable(0), component: AnyComponent(StarsAvatarComponent(context: component.context, theme: environment.theme, peer: nil, photo: photo, media: [], backgroundColor: .clear, size: CGSize(width: 19.0, height: 19.0)))),
|
||||||
AnyComponentWithIdentity(id: AnyHashable(1), component: nameComponent)
|
AnyComponentWithIdentity(id: AnyHashable(1), component: nameComponent)
|
||||||
], spacing: 6.0)
|
], spacing: 6.0)
|
||||||
)
|
)
|
||||||
@ -1055,6 +1055,10 @@ public final class StarsTransactionsScreen: ViewControllerComponentContainer {
|
|||||||
let _ = self.context.engine.payments.fulfillStarsSubscription(peerId: context.account.peerId, subscriptionId: subscription.id).startStandalone()
|
let _ = self.context.engine.payments.fulfillStarsSubscription(peerId: context.account.peerId, subscriptionId: subscription.id).startStandalone()
|
||||||
updated = true
|
updated = true
|
||||||
}
|
}
|
||||||
|
if let _ = subscription.inviteHash, !subscription.flags.contains(.isCancelledByBot) {
|
||||||
|
let _ = self.context.engine.payments.fulfillStarsSubscription(peerId: context.account.peerId, subscriptionId: subscription.id).startStandalone()
|
||||||
|
updated = true
|
||||||
|
}
|
||||||
if !updated {
|
if !updated {
|
||||||
if subscription.flags.contains(.isCancelled) {
|
if subscription.flags.contains(.isCancelled) {
|
||||||
self.subscriptionsContext.updateSubscription(id: subscription.id, cancel: false)
|
self.subscriptionsContext.updateSubscription(id: subscription.id, cancel: false)
|
||||||
@ -1065,6 +1069,8 @@ public final class StarsTransactionsScreen: ViewControllerComponentContainer {
|
|||||||
} else {
|
} else {
|
||||||
if let inviteHash = subscription.inviteHash {
|
if let inviteHash = subscription.inviteHash {
|
||||||
self.context.sharedContext.handleTextLinkAction(context: self.context, peerId: nil, navigateDisposable: self.navigateDisposable, controller: self, action: .tap, itemLink: .url(url: "https://t.me/+\(inviteHash)", concealed: false))
|
self.context.sharedContext.handleTextLinkAction(context: self.context, peerId: nil, navigateDisposable: self.navigateDisposable, controller: self, action: .tap, itemLink: .url(url: "https://t.me/+\(inviteHash)", concealed: false))
|
||||||
|
} else if let invoiceSlug = subscription.invoiceSlug {
|
||||||
|
self.context.sharedContext.handleTextLinkAction(context: self.context, peerId: nil, navigateDisposable: self.navigateDisposable, controller: self, action: .tap, itemLink: .url(url: "https://t.me/$\(invoiceSlug)", concealed: false))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -100,7 +100,7 @@ func handleTextLinkActionImpl(context: AccountContext, peerId: EnginePeer.Id?, n
|
|||||||
let sourceLocation = InstantPageSourceLocation(userLocation: peerId.flatMap(MediaResourceUserLocation.peer) ?? .other, peerType: .group)
|
let sourceLocation = InstantPageSourceLocation(userLocation: peerId.flatMap(MediaResourceUserLocation.peer) ?? .other, peerType: .group)
|
||||||
let browserController = context.sharedContext.makeInstantPageController(context: context, webPage: webPage, anchor: anchor, sourceLocation: sourceLocation)
|
let browserController = context.sharedContext.makeInstantPageController(context: context, webPage: webPage, anchor: anchor, sourceLocation: sourceLocation)
|
||||||
(controller.navigationController as? NavigationController)?.pushViewController(browserController, animated: true)
|
(controller.navigationController as? NavigationController)?.pushViewController(browserController, animated: true)
|
||||||
case .boost, .chatFolder, .join:
|
case .boost, .chatFolder, .join, .invoice:
|
||||||
if let navigationController = controller.navigationController as? NavigationController {
|
if let navigationController = controller.navigationController as? NavigationController {
|
||||||
openResolvedUrlImpl(result, context: context, urlContext: peerId.flatMap { .chat(peerId: $0, message: nil, updatedPresentationData: nil) } ?? .generic, navigationController: navigationController, forceExternal: false, forceUpdate: false, openPeer: { peer, navigateToPeer in
|
openResolvedUrlImpl(result, context: context, urlContext: peerId.flatMap { .chat(peerId: $0, message: nil, updatedPresentationData: nil) } ?? .generic, navigationController: navigationController, forceExternal: false, forceUpdate: false, openPeer: { peer, navigateToPeer in
|
||||||
openResolvedPeerImpl(peer, navigateToPeer)
|
openResolvedPeerImpl(peer, navigateToPeer)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user