Various improvements
@ -332,6 +332,7 @@ swift_library(
|
|||||||
"Telegram-iOS/Application.swift",
|
"Telegram-iOS/Application.swift",
|
||||||
]),
|
]),
|
||||||
data = [
|
data = [
|
||||||
|
":Icons",
|
||||||
":AppResources",
|
":AppResources",
|
||||||
":AppIntentVocabularyResources",
|
":AppIntentVocabularyResources",
|
||||||
":InfoPlistStringResources",
|
":InfoPlistStringResources",
|
||||||
|
@ -1,104 +0,0 @@
|
|||||||
{
|
|
||||||
"images" : [
|
|
||||||
{
|
|
||||||
"idiom" : "iphone",
|
|
||||||
"size" : "20x20",
|
|
||||||
"scale" : "2x"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"idiom" : "iphone",
|
|
||||||
"size" : "20x20",
|
|
||||||
"scale" : "3x"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"idiom" : "iphone",
|
|
||||||
"size" : "29x29",
|
|
||||||
"scale" : "2x"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"idiom" : "iphone",
|
|
||||||
"size" : "29x29",
|
|
||||||
"scale" : "3x"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"idiom" : "iphone",
|
|
||||||
"size" : "40x40",
|
|
||||||
"scale" : "2x"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"idiom" : "iphone",
|
|
||||||
"size" : "40x40",
|
|
||||||
"scale" : "3x"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"size" : "60x60",
|
|
||||||
"idiom" : "iphone",
|
|
||||||
"filename" : "icon@120px.png",
|
|
||||||
"scale" : "2x"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"size" : "60x60",
|
|
||||||
"idiom" : "iphone",
|
|
||||||
"filename" : "icon@180px.png",
|
|
||||||
"scale" : "3x"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"idiom" : "ipad",
|
|
||||||
"size" : "20x20",
|
|
||||||
"scale" : "1x"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"idiom" : "ipad",
|
|
||||||
"size" : "20x20",
|
|
||||||
"scale" : "2x"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"idiom" : "ipad",
|
|
||||||
"size" : "29x29",
|
|
||||||
"scale" : "1x"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"idiom" : "ipad",
|
|
||||||
"size" : "29x29",
|
|
||||||
"scale" : "2x"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"idiom" : "ipad",
|
|
||||||
"size" : "40x40",
|
|
||||||
"scale" : "1x"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"idiom" : "ipad",
|
|
||||||
"size" : "40x40",
|
|
||||||
"scale" : "2x"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"size" : "76x76",
|
|
||||||
"idiom" : "ipad",
|
|
||||||
"filename" : "icon@76px.png",
|
|
||||||
"scale" : "1x"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"size" : "76x76",
|
|
||||||
"idiom" : "ipad",
|
|
||||||
"filename" : "icon@152px.png",
|
|
||||||
"scale" : "2x"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"size" : "83.5x83.5",
|
|
||||||
"idiom" : "ipad",
|
|
||||||
"filename" : "icon@167px.png",
|
|
||||||
"scale" : "2x"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"size" : "1024x1024",
|
|
||||||
"idiom" : "ios-marketing",
|
|
||||||
"filename" : "icon@1024px.png",
|
|
||||||
"scale" : "1x"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"info" : {
|
|
||||||
"version" : 1,
|
|
||||||
"author" : "xcode"
|
|
||||||
}
|
|
||||||
}
|
|
Before Width: | Height: | Size: 370 KiB |
Before Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 17 KiB |
Before Width: | Height: | Size: 19 KiB |
Before Width: | Height: | Size: 22 KiB |
Before Width: | Height: | Size: 6.4 KiB |
Before Width: | Height: | Size: 7.6 KiB |
Before Width: | Height: | Size: 3.8 KiB |
Before Width: | Height: | Size: 5.9 KiB |
Before Width: | Height: | Size: 4.2 KiB |
Before Width: | Height: | Size: 10 KiB |
Before Width: | Height: | Size: 5.5 KiB |
Before Width: | Height: | Size: 665 B |
Before Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 3.3 KiB |
@ -1,119 +0,0 @@
|
|||||||
{
|
|
||||||
"images" : [
|
|
||||||
{
|
|
||||||
"size" : "20x20",
|
|
||||||
"idiom" : "iphone",
|
|
||||||
"filename" : "BlueNotificationIcon@2x.png",
|
|
||||||
"scale" : "2x"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"size" : "20x20",
|
|
||||||
"idiom" : "iphone",
|
|
||||||
"filename" : "BlueNotificationIcon@3x.png",
|
|
||||||
"scale" : "3x"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"size" : "29x29",
|
|
||||||
"idiom" : "iphone",
|
|
||||||
"filename" : "Simple@58x58.png",
|
|
||||||
"scale" : "2x"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"size" : "29x29",
|
|
||||||
"idiom" : "iphone",
|
|
||||||
"filename" : "Simple@87x87.png",
|
|
||||||
"scale" : "3x"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"size" : "40x40",
|
|
||||||
"idiom" : "iphone",
|
|
||||||
"filename" : "Simple@80x80.png",
|
|
||||||
"scale" : "2x"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"size" : "40x40",
|
|
||||||
"idiom" : "iphone",
|
|
||||||
"filename" : "BlueIcon@2x-1.png",
|
|
||||||
"scale" : "3x"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"size" : "60x60",
|
|
||||||
"idiom" : "iphone",
|
|
||||||
"filename" : "BlueIcon@2x.png",
|
|
||||||
"scale" : "2x"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"size" : "60x60",
|
|
||||||
"idiom" : "iphone",
|
|
||||||
"filename" : "BlueIcon@3x.png",
|
|
||||||
"scale" : "3x"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"size" : "20x20",
|
|
||||||
"idiom" : "ipad",
|
|
||||||
"filename" : "BlueNotificationIcon.png",
|
|
||||||
"scale" : "1x"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"size" : "20x20",
|
|
||||||
"idiom" : "ipad",
|
|
||||||
"filename" : "BlueNotificationIcon@2x-1.png",
|
|
||||||
"scale" : "2x"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"size" : "29x29",
|
|
||||||
"idiom" : "ipad",
|
|
||||||
"filename" : "Simple@29x29.png",
|
|
||||||
"scale" : "1x"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"size" : "29x29",
|
|
||||||
"idiom" : "ipad",
|
|
||||||
"filename" : "Simple@58x58-1.png",
|
|
||||||
"scale" : "2x"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"size" : "40x40",
|
|
||||||
"idiom" : "ipad",
|
|
||||||
"filename" : "Simple@40x40-1.png",
|
|
||||||
"scale" : "1x"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"size" : "40x40",
|
|
||||||
"idiom" : "ipad",
|
|
||||||
"filename" : "Simple@80x80-1.png",
|
|
||||||
"scale" : "2x"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"size" : "76x76",
|
|
||||||
"idiom" : "ipad",
|
|
||||||
"filename" : "BlueIconIpad.png",
|
|
||||||
"scale" : "1x"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"size" : "76x76",
|
|
||||||
"idiom" : "ipad",
|
|
||||||
"filename" : "BlueIconIpad@2x.png",
|
|
||||||
"scale" : "2x"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"size" : "83.5x83.5",
|
|
||||||
"idiom" : "ipad",
|
|
||||||
"filename" : "BlueIconLargeIpad@2x.png",
|
|
||||||
"scale" : "2x"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"size" : "1024x1024",
|
|
||||||
"idiom" : "ios-marketing",
|
|
||||||
"filename" : "Simple-iTunesArtwork.png",
|
|
||||||
"scale" : "1x"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"info" : {
|
|
||||||
"version" : 1,
|
|
||||||
"author" : "xcode"
|
|
||||||
},
|
|
||||||
"properties" : {
|
|
||||||
"pre-rendered" : true
|
|
||||||
}
|
|
||||||
}
|
|
Before Width: | Height: | Size: 159 KiB |
Before Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 1.8 KiB |
Before Width: | Height: | Size: 2.9 KiB |
Before Width: | Height: | Size: 2.9 KiB |
Before Width: | Height: | Size: 4.5 KiB |
Before Width: | Height: | Size: 4.5 KiB |
Before Width: | Height: | Size: 5.0 KiB |
@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"images" : [
|
"images" : [
|
||||||
{
|
{
|
||||||
"idiom" : "universal",
|
"filename" : "ic_lt_user.pdf",
|
||||||
"filename" : "ic_lt_user.pdf"
|
"idiom" : "universal"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"info" : {
|
"info" : {
|
||||||
"version" : 1,
|
"author" : "xcode",
|
||||||
"author" : "xcode"
|
"version" : 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -264,7 +264,9 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
|||||||
}
|
}
|
||||||
strongSelf.chatListDisplayNode.containerNode.currentItemNode.scrollToPosition(.top)
|
strongSelf.chatListDisplayNode.containerNode.currentItemNode.scrollToPosition(.top)
|
||||||
case let .known(offset):
|
case let .known(offset):
|
||||||
if offset <= navigationBarSearchContentHeight + 1.0 && strongSelf.chatListDisplayNode.containerNode.currentItemNode.chatListFilter != nil {
|
let isFirstFilter = strongSelf.chatListDisplayNode.containerNode.currentItemNode.chatListFilter == strongSelf.chatListDisplayNode.containerNode.availableFilters.first?.filter
|
||||||
|
|
||||||
|
if offset <= navigationBarSearchContentHeight + 1.0 && !isFirstFilter {
|
||||||
let _ = (strongSelf.context.engine.peers.currentChatListFilters()
|
let _ = (strongSelf.context.engine.peers.currentChatListFilters()
|
||||||
|> deliverOnMainQueue).start(next: { [weak self] filters in
|
|> deliverOnMainQueue).start(next: { [weak self] filters in
|
||||||
guard let strongSelf = self else {
|
guard let strongSelf = self else {
|
||||||
|
@ -431,7 +431,7 @@ final class ChatListContainerNode: ASDisplayNode, UIGestureRecognizerDelegate {
|
|||||||
|
|
||||||
private var itemNodes: [ChatListFilterTabEntryId: ChatListContainerItemNode] = [:]
|
private var itemNodes: [ChatListFilterTabEntryId: ChatListContainerItemNode] = [:]
|
||||||
private var pendingItemNode: (ChatListFilterTabEntryId, ChatListContainerItemNode, Disposable)?
|
private var pendingItemNode: (ChatListFilterTabEntryId, ChatListContainerItemNode, Disposable)?
|
||||||
private var availableFilters: [ChatListContainerNodeFilter] = [.all]
|
private(set) var availableFilters: [ChatListContainerNodeFilter] = [.all]
|
||||||
private var filtersLimit: Int32? = nil
|
private var filtersLimit: Int32? = nil
|
||||||
private var selectedId: ChatListFilterTabEntryId
|
private var selectedId: ChatListFilterTabEntryId
|
||||||
|
|
||||||
|
@ -626,24 +626,15 @@ private func internalChatListFilterAddChatsController(context: AccountContext, f
|
|||||||
controller?.push(c)
|
controller?.push(c)
|
||||||
}
|
}
|
||||||
|
|
||||||
let _ = combineLatest(
|
let _ = (controller.result
|
||||||
queue: Queue.mainQueue(),
|
|> take(1)
|
||||||
controller.result |> take(1),
|
|> deliverOnMainQueue)
|
||||||
context.engine.data.get(
|
.start(next: { [weak controller] result in
|
||||||
TelegramEngine.EngineData.Item.Peer.Peer(id: context.account.peerId),
|
|
||||||
TelegramEngine.EngineData.Item.Configuration.UserLimits(isPremium: false),
|
|
||||||
TelegramEngine.EngineData.Item.Configuration.UserLimits(isPremium: true)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
.start(next: { [weak controller] result, data in
|
|
||||||
guard case let .result(peerIds, additionalCategoryIds) = result else {
|
guard case let .result(peerIds, additionalCategoryIds) = result else {
|
||||||
controller?.dismiss()
|
controller?.dismiss()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// let (accountPeer, limits, premiumLimits) = data
|
|
||||||
// let isPremium = accountPeer?.isPremium ?? false
|
|
||||||
|
|
||||||
var includePeers: [PeerId] = []
|
var includePeers: [PeerId] = []
|
||||||
for peerId in peerIds {
|
for peerId in peerIds {
|
||||||
switch peerId {
|
switch peerId {
|
||||||
@ -655,24 +646,6 @@ private func internalChatListFilterAddChatsController(context: AccountContext, f
|
|||||||
}
|
}
|
||||||
includePeers.sort()
|
includePeers.sort()
|
||||||
|
|
||||||
// if includePeers.count > premiumLimits.maxFolderChatsCount {
|
|
||||||
// let limitController = PremiumLimitScreen(context: context, subject: .chatsPerFolder, count: Int32(includePeers.count), action: {})
|
|
||||||
// controller?.push(limitController)
|
|
||||||
// return
|
|
||||||
// } else if includePeers.count > limits.maxFolderChatsCount && !isPremium {
|
|
||||||
// var replaceImpl: ((ViewController) -> Void)?
|
|
||||||
// let limitController = PremiumLimitScreen(context: context, subject: .chatsPerFolder, count: Int32(includePeers.count), action: {
|
|
||||||
// let introController = PremiumIntroScreen(context: context, source: .chatsPerFolder)
|
|
||||||
// replaceImpl?(introController)
|
|
||||||
// })
|
|
||||||
// replaceImpl = { [weak controller] c in
|
|
||||||
// controller?.replace(with: c)
|
|
||||||
// }
|
|
||||||
// controller?.push(limitController)
|
|
||||||
//
|
|
||||||
// return
|
|
||||||
// }
|
|
||||||
|
|
||||||
var categories: ChatListFilterPeerCategories = []
|
var categories: ChatListFilterPeerCategories = []
|
||||||
for id in additionalCategoryIds {
|
for id in additionalCategoryIds {
|
||||||
if let index = categoryMapping.firstIndex(where: { $0.1.rawValue == id }) {
|
if let index = categoryMapping.firstIndex(where: { $0.1.rawValue == id }) {
|
||||||
|
Before Width: | Height: | Size: 1.1 KiB |
@ -685,7 +685,7 @@ private final class LimitSheetContent: CombinedComponent {
|
|||||||
var buttonAnimationName = "premium_x2"
|
var buttonAnimationName = "premium_x2"
|
||||||
let iconName: String
|
let iconName: String
|
||||||
let badgeText: String
|
let badgeText: String
|
||||||
let string: String
|
var string: String
|
||||||
let defaultValue: String
|
let defaultValue: String
|
||||||
let premiumValue: String
|
let premiumValue: String
|
||||||
let badgePosition: CGFloat
|
let badgePosition: CGFloat
|
||||||
@ -699,6 +699,10 @@ private final class LimitSheetContent: CombinedComponent {
|
|||||||
defaultValue = component.count > limit ? "\(limit)" : ""
|
defaultValue = component.count > limit ? "\(limit)" : ""
|
||||||
premiumValue = component.count >= premiumLimit ? "" : "\(premiumLimit)"
|
premiumValue = component.count >= premiumLimit ? "" : "\(premiumLimit)"
|
||||||
badgePosition = CGFloat(component.count) / CGFloat(premiumLimit)
|
badgePosition = CGFloat(component.count) / CGFloat(premiumLimit)
|
||||||
|
|
||||||
|
if !state.isPremium && badgePosition > 0.5 {
|
||||||
|
string = strings.Premium_MaxFoldersCountText("\(limit)", "\(premiumLimit)").string
|
||||||
|
}
|
||||||
case .chatsPerFolder:
|
case .chatsPerFolder:
|
||||||
let limit = state.limits.maxFolderChatsCount
|
let limit = state.limits.maxFolderChatsCount
|
||||||
let premiumLimit = state.premiumLimits.maxFolderChatsCount
|
let premiumLimit = state.premiumLimits.maxFolderChatsCount
|
||||||
|
@ -126,16 +126,20 @@ private class ReactionCarouselNode: ASDisplayNode, UIScrollViewDelegate {
|
|||||||
reactionMap[reaction.value] = reaction
|
reactionMap[reaction.value] = reaction
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var addedReactions = Set<String>()
|
||||||
var sortedReactions: [AvailableReactions.Reaction] = []
|
var sortedReactions: [AvailableReactions.Reaction] = []
|
||||||
for emoji in order {
|
for emoji in order {
|
||||||
if let reaction = reactionMap[emoji] {
|
if let reaction = reactionMap[emoji] {
|
||||||
sortedReactions.append(reaction)
|
sortedReactions.append(reaction)
|
||||||
|
addedReactions.insert(emoji)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// for reaction in reactions {
|
for reaction in reactions {
|
||||||
// sortedReactions.append(reaction)
|
if !addedReactions.contains(reaction.value) {
|
||||||
// }
|
sortedReactions.append(reaction)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
self.reactions = sortedReactions
|
self.reactions = sortedReactions
|
||||||
|
|
||||||
@ -537,13 +541,15 @@ private class ReactionCarouselNode: ASDisplayNode, UIScrollViewDelegate {
|
|||||||
}
|
}
|
||||||
return relativeAngle
|
return relativeAngle
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let rotatedAngle = angle - CGFloat.pi / 2.0
|
||||||
|
|
||||||
let relativeAngle = calculateRelativeAngle(angle)
|
var updatedAngle = rotatedAngle + 0.5 * sin(rotatedAngle)
|
||||||
|
updatedAngle = updatedAngle + CGFloat.pi / 2.0
|
||||||
|
|
||||||
|
let relativeAngle = calculateRelativeAngle(updatedAngle)
|
||||||
let distance = abs(relativeAngle) / CGFloat.pi
|
let distance = abs(relativeAngle) / CGFloat.pi
|
||||||
|
|
||||||
let updatedAngle = angle
|
|
||||||
// updatedAngle += 10 * cos(updatedAngle)
|
|
||||||
|
|
||||||
let point = CGPoint(
|
let point = CGPoint(
|
||||||
x: cos(updatedAngle),
|
x: cos(updatedAngle),
|
||||||
y: sin(updatedAngle)
|
y: sin(updatedAngle)
|
||||||
|
@ -555,7 +555,6 @@ private class StickersCarouselNode: ASDisplayNode, UIScrollViewDelegate {
|
|||||||
let bounds = CGRect(origin: .zero, size: size)
|
let bounds = CGRect(origin: .zero, size: size)
|
||||||
let areaSize = CGSize(width: floor(size.width * 4.0), height: size.height * 2.2)
|
let areaSize = CGSize(width: floor(size.width * 4.0), height: size.height * 2.2)
|
||||||
|
|
||||||
var visibleCount = 0
|
|
||||||
for i in 0 ..< self.itemNodes.count {
|
for i in 0 ..< self.itemNodes.count {
|
||||||
let itemNode = self.itemNodes[i]
|
let itemNode = self.itemNodes[i]
|
||||||
let containerNode = self.itemContainerNodes[i]
|
let containerNode = self.itemContainerNodes[i]
|
||||||
@ -593,9 +592,6 @@ private class StickersCarouselNode: ASDisplayNode, UIScrollViewDelegate {
|
|||||||
|
|
||||||
let isVisible = self.visibility && itemFrame.intersects(bounds)
|
let isVisible = self.visibility && itemFrame.intersects(bounds)
|
||||||
itemNode.setVisible(isVisible)
|
itemNode.setVisible(isVisible)
|
||||||
if isVisible {
|
|
||||||
visibleCount += 1
|
|
||||||
}
|
|
||||||
|
|
||||||
itemNode.frame = CGRect(origin: CGPoint(), size: itemFrame.size)
|
itemNode.frame = CGRect(origin: CGPoint(), size: itemFrame.size)
|
||||||
itemNode.updateLayout(size: itemFrame.size, transition: transition)
|
itemNode.updateLayout(size: itemFrame.size, transition: transition)
|
||||||
|
@ -356,10 +356,26 @@ private func generatePremiumReactionIcon() -> UIImage? {
|
|||||||
final class PremiumReactionsNode: ASDisplayNode, ReactionItemNode {
|
final class PremiumReactionsNode: ASDisplayNode, ReactionItemNode {
|
||||||
var isExtracted: Bool = false
|
var isExtracted: Bool = false
|
||||||
|
|
||||||
|
var backgroundView: UIVisualEffectView?
|
||||||
|
let backgroundMaskNode: ASImageNode
|
||||||
|
let backgroundOverlayNode: ASImageNode
|
||||||
let imageNode: ASImageNode
|
let imageNode: ASImageNode
|
||||||
let maskImageNode: ASImageNode
|
let maskImageNode: ASImageNode
|
||||||
|
|
||||||
init(theme: PresentationTheme) {
|
init(theme: PresentationTheme) {
|
||||||
|
self.backgroundMaskNode = ASImageNode()
|
||||||
|
self.backgroundMaskNode.contentMode = .center
|
||||||
|
self.backgroundMaskNode.displaysAsynchronously = false
|
||||||
|
self.backgroundMaskNode.isUserInteractionEnabled = false
|
||||||
|
self.backgroundMaskNode.image = UIImage(bundleImageName: "Premium/ReactionsBackground")
|
||||||
|
|
||||||
|
self.backgroundOverlayNode = ASImageNode()
|
||||||
|
self.backgroundOverlayNode.alpha = 0.05
|
||||||
|
self.backgroundOverlayNode.contentMode = .center
|
||||||
|
self.backgroundOverlayNode.displaysAsynchronously = false
|
||||||
|
self.backgroundOverlayNode.isUserInteractionEnabled = false
|
||||||
|
self.backgroundOverlayNode.image = generateTintedImage(image: UIImage(bundleImageName: "Premium/ReactionsBackground"), color: theme.overallDarkAppearance ? .white : .black)
|
||||||
|
|
||||||
self.imageNode = ASImageNode()
|
self.imageNode = ASImageNode()
|
||||||
self.imageNode.contentMode = .center
|
self.imageNode.contentMode = .center
|
||||||
self.imageNode.displaysAsynchronously = false
|
self.imageNode.displaysAsynchronously = false
|
||||||
@ -383,15 +399,35 @@ final class PremiumReactionsNode: ASDisplayNode, ReactionItemNode {
|
|||||||
|
|
||||||
super.init()
|
super.init()
|
||||||
|
|
||||||
|
self.addSubnode(self.backgroundOverlayNode)
|
||||||
self.addSubnode(self.imageNode)
|
self.addSubnode(self.imageNode)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override func didLoad() {
|
||||||
|
super.didLoad()
|
||||||
|
|
||||||
|
let blurEffect: UIBlurEffect
|
||||||
|
if #available(iOS 13.0, *) {
|
||||||
|
blurEffect = UIBlurEffect(style: .systemUltraThinMaterial)
|
||||||
|
} else {
|
||||||
|
blurEffect = UIBlurEffect(style: .light)
|
||||||
|
}
|
||||||
|
let backgroundView = UIVisualEffectView(effect: blurEffect)
|
||||||
|
backgroundView.mask = self.backgroundMaskNode.view
|
||||||
|
self.view.insertSubview(backgroundView, at: 0)
|
||||||
|
self.backgroundView = backgroundView
|
||||||
|
}
|
||||||
|
|
||||||
func appear(animated: Bool) {
|
func appear(animated: Bool) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func updateLayout(size: CGSize, isExpanded: Bool, largeExpanded: Bool, isPreviewing: Bool, transition: ContainedViewLayoutTransition) {
|
func updateLayout(size: CGSize, isExpanded: Bool, largeExpanded: Bool, isPreviewing: Bool, transition: ContainedViewLayoutTransition) {
|
||||||
self.imageNode.frame = CGRect(origin: CGPoint(), size: size)
|
let bounds = CGRect(origin: CGPoint(), size: size)
|
||||||
|
self.backgroundView?.frame = bounds
|
||||||
|
self.backgroundMaskNode.frame = bounds
|
||||||
|
self.backgroundOverlayNode.frame = bounds
|
||||||
|
self.imageNode.frame = bounds
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -100,6 +100,7 @@ swift_library(
|
|||||||
"//submodules/FetchManagerImpl:FetchManagerImpl",
|
"//submodules/FetchManagerImpl:FetchManagerImpl",
|
||||||
"//submodules/ListMessageItem:ListMessageItem",
|
"//submodules/ListMessageItem:ListMessageItem",
|
||||||
"//submodules/PaymentMethodUI:PaymentMethodUI",
|
"//submodules/PaymentMethodUI:PaymentMethodUI",
|
||||||
|
"//submodules/PremiumUI:PremiumUI",
|
||||||
],
|
],
|
||||||
visibility = [
|
visibility = [
|
||||||
"//visibility:public",
|
"//visibility:public",
|
||||||
|
@ -13,6 +13,8 @@ import AccountContext
|
|||||||
import AlertUI
|
import AlertUI
|
||||||
import PresentationDataUtils
|
import PresentationDataUtils
|
||||||
import UrlHandling
|
import UrlHandling
|
||||||
|
import AccountUtils
|
||||||
|
import PremiumUI
|
||||||
|
|
||||||
private struct LogoutOptionsItemArguments {
|
private struct LogoutOptionsItemArguments {
|
||||||
let addAccount: () -> Void
|
let addAccount: () -> Void
|
||||||
@ -133,10 +135,38 @@ public func logoutOptionsController(context: AccountContext, navigationControlle
|
|||||||
let supportPeerDisposable = MetaDisposable()
|
let supportPeerDisposable = MetaDisposable()
|
||||||
|
|
||||||
let arguments = LogoutOptionsItemArguments(addAccount: {
|
let arguments = LogoutOptionsItemArguments(addAccount: {
|
||||||
let isTestingEnvironment = context.account.testingEnvironment
|
let _ = (activeAccountsAndPeers(context: context)
|
||||||
context.sharedContext.beginNewAuth(testingEnvironment: isTestingEnvironment)
|
|> take(1)
|
||||||
|
|> deliverOnMainQueue
|
||||||
dismissImpl?()
|
).start(next: { accountAndPeer, accountsAndPeers in
|
||||||
|
var maximumAvailableAccounts: Int = 3
|
||||||
|
if accountAndPeer?.1.isPremium == true {
|
||||||
|
maximumAvailableAccounts = 4
|
||||||
|
}
|
||||||
|
var count: Int = 1
|
||||||
|
for (_, peer, _) in accountsAndPeers {
|
||||||
|
if peer.isPremium {
|
||||||
|
maximumAvailableAccounts = 4
|
||||||
|
}
|
||||||
|
}
|
||||||
|
count += accountsAndPeers.count
|
||||||
|
|
||||||
|
if count >= maximumAvailableAccounts {
|
||||||
|
var replaceImpl: ((ViewController) -> Void)?
|
||||||
|
let controller = PremiumLimitScreen(context: context, subject: .accounts, count: Int32(count), action: {
|
||||||
|
let controller = PremiumIntroScreen(context: context, source: .accounts)
|
||||||
|
replaceImpl?(controller)
|
||||||
|
})
|
||||||
|
replaceImpl = { [weak controller] c in
|
||||||
|
controller?.replace(with: c)
|
||||||
|
}
|
||||||
|
pushControllerImpl?(controller)
|
||||||
|
} else {
|
||||||
|
context.sharedContext.beginNewAuth(testingEnvironment: context.account.testingEnvironment)
|
||||||
|
|
||||||
|
dismissImpl?()
|
||||||
|
}
|
||||||
|
})
|
||||||
}, setPasscode: {
|
}, setPasscode: {
|
||||||
let _ = passcodeOptionsAccessController(context: context, pushController: { controller in
|
let _ = passcodeOptionsAccessController(context: context, pushController: { controller in
|
||||||
replaceTopControllerImpl?(controller)
|
replaceTopControllerImpl?(controller)
|
||||||
|
@ -187,6 +187,9 @@ public final class StickerPreviewPeekContentNode: ASDisplayNode, PeekControllerC
|
|||||||
if size.width == 292.0 {
|
if size.width == 292.0 {
|
||||||
topOffset = 60.0
|
topOffset = 60.0
|
||||||
textSpacing -= 10.0
|
textSpacing -= 10.0
|
||||||
|
} else if size.width == 347.0 && size.height == 577.0 {
|
||||||
|
topOffset = 60.0
|
||||||
|
textSpacing -= 10.0
|
||||||
}
|
}
|
||||||
|
|
||||||
let textSize = self.textNode.measure(CGSize(width: 100.0, height: 100.0))
|
let textSize = self.textNode.measure(CGSize(width: 100.0, height: 100.0))
|
||||||
@ -276,6 +279,8 @@ final class PremiumStickerPackAccessoryNode: SparseNode, PeekControllerAccessory
|
|||||||
var bottomOffset: CGFloat = 0.0
|
var bottomOffset: CGFloat = 0.0
|
||||||
if size.width == 320.0 {
|
if size.width == 320.0 {
|
||||||
bottomOffset = 30.0
|
bottomOffset = 30.0
|
||||||
|
} else if size.width == 375.0 && size.height == 667.0 {
|
||||||
|
bottomOffset = 30.0
|
||||||
}
|
}
|
||||||
|
|
||||||
let cancelSize = self.cancelButton.measure(size)
|
let cancelSize = self.cancelButton.measure(size)
|
||||||
|
@ -21,6 +21,13 @@ filegroup(
|
|||||||
visibility = ["//visibility:public"],
|
visibility = ["//visibility:public"],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
#filegroup(
|
||||||
|
# name = "Icons",
|
||||||
|
# srcs = glob([
|
||||||
|
# "Telegram-iOS/Icons.xcassets/**/*",
|
||||||
|
# ], exclude = ["Telegram-iOS/Icons.xcassets/**/.*"]),
|
||||||
|
#)
|
||||||
|
|
||||||
internal_bundle_ids = [
|
internal_bundle_ids = [
|
||||||
"org.telegram.Telegram-iOS",
|
"org.telegram.Telegram-iOS",
|
||||||
]
|
]
|
||||||
|