mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
Various fixes
This commit is contained in:
parent
a30ab38ce4
commit
072c6bc3c4
@ -979,6 +979,7 @@ public protocol SharedAccountContext: AnyObject {
|
||||
|
||||
func makeStarsGiftController(context: AccountContext, birthdays: [EnginePeer.Id: TelegramBirthday]?, completion: @escaping (([EnginePeer.Id]) -> Void)) -> ViewController
|
||||
func makePremiumGiftController(context: AccountContext, source: PremiumGiftSource, completion: (([EnginePeer.Id]) -> Void)?) -> ViewController
|
||||
func makeGiftOptionsController(context: AccountContext, peerId: EnginePeer.Id, premiumOptions: [CachedPremiumGiftOption]) -> ViewController
|
||||
func makePremiumPrivacyControllerController(context: AccountContext, subject: PremiumPrivacySubject, peerId: EnginePeer.Id) -> ViewController
|
||||
func makePremiumBoostLevelsController(context: AccountContext, peerId: EnginePeer.Id, subject: BoostSubject, boostStatus: ChannelBoostStatus, myBoostStatus: MyBoostStatus, forceDark: Bool, openStats: (() -> Void)?) -> ViewController
|
||||
|
||||
|
@ -136,6 +136,7 @@ public struct Namespaces {
|
||||
public static let cachedRevenueStats: Int8 = 39
|
||||
public static let recommendedApps: Int8 = 40
|
||||
public static let starsReactionDefaultToPrivate: Int8 = 41
|
||||
public static let cachedPremiumGiftCodeOptions: Int8 = 42
|
||||
}
|
||||
|
||||
public struct UnorderedItemList {
|
||||
|
@ -148,6 +148,79 @@ func _internal_getPremiumGiveawayInfo(account: Account, peerId: EnginePeer.Id, m
|
||||
}
|
||||
}
|
||||
|
||||
public final class CachedPremiumGiftCodeOptions: Codable {
|
||||
public let options: [PremiumGiftCodeOption]
|
||||
|
||||
public init(options: [PremiumGiftCodeOption]) {
|
||||
self.options = options
|
||||
}
|
||||
|
||||
public init(from decoder: Decoder) throws {
|
||||
let container = try decoder.container(keyedBy: StringCodingKey.self)
|
||||
|
||||
self.options = try container.decode([PremiumGiftCodeOption].self, forKey: "t")
|
||||
}
|
||||
|
||||
public func encode(to encoder: Encoder) throws {
|
||||
var container = encoder.container(keyedBy: StringCodingKey.self)
|
||||
|
||||
try container.encode(self.options, forKey: "t")
|
||||
}
|
||||
}
|
||||
|
||||
func _internal_premiumGiftCodeOptions(account: Account, peerId: EnginePeer.Id?, onlyCached: Bool = false) -> Signal<[PremiumGiftCodeOption], NoError> {
|
||||
let cached = account.postbox.transaction { transaction -> Signal<[PremiumGiftCodeOption], NoError> in
|
||||
if let entry = transaction.retrieveItemCacheEntry(id: ItemCacheEntryId(collectionId: Namespaces.CachedItemCollection.cachedPremiumGiftCodeOptions, key: ValueBoxKey(length: 0)))?.get(CachedPremiumGiftCodeOptions.self) {
|
||||
return .single(entry.options)
|
||||
}
|
||||
return .single([])
|
||||
} |> switchToLatest
|
||||
|
||||
var flags: Int32 = 0
|
||||
if let _ = peerId {
|
||||
flags |= 1 << 0
|
||||
}
|
||||
let remote = account.postbox.transaction { transaction -> Peer? in
|
||||
if let peerId = peerId {
|
||||
return transaction.getPeer(peerId)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|> mapToSignal { peer in
|
||||
let inputPeer = peer.flatMap(apiInputPeer)
|
||||
return account.network.request(Api.functions.payments.getPremiumGiftCodeOptions(flags: flags, boostPeer: inputPeer))
|
||||
|> map(Optional.init)
|
||||
|> `catch` { _ -> Signal<[Api.PremiumGiftCodeOption]?, NoError> in
|
||||
return .single(nil)
|
||||
}
|
||||
|> mapToSignal { results -> Signal<[PremiumGiftCodeOption], NoError> in
|
||||
let options = results?.map { PremiumGiftCodeOption(apiGiftCodeOption: $0) } ?? []
|
||||
return account.postbox.transaction { transaction -> [PremiumGiftCodeOption] in
|
||||
if peerId == nil {
|
||||
if let entry = CodableEntry(CachedPremiumGiftCodeOptions(options: options)) {
|
||||
transaction.putItemCacheEntry(id: ItemCacheEntryId(collectionId: Namespaces.CachedItemCollection.cachedPremiumGiftCodeOptions, key: ValueBoxKey(length: 0)), entry: entry)
|
||||
}
|
||||
}
|
||||
return options
|
||||
}
|
||||
}
|
||||
}
|
||||
if peerId == nil {
|
||||
return cached
|
||||
|> mapToSignal { cached in
|
||||
if onlyCached && !cached.isEmpty {
|
||||
return .single(cached)
|
||||
} else {
|
||||
return .single(cached)
|
||||
|> then(remote)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return remote
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func _internal_premiumGiftCodeOptions(account: Account, peerId: EnginePeer.Id?) -> Signal<[PremiumGiftCodeOption], NoError> {
|
||||
var flags: Int32 = 0
|
||||
if let _ = peerId {
|
||||
|
@ -54,8 +54,8 @@ public extension TelegramEngine {
|
||||
return _internal_applyPremiumGiftCode(account: self.account, slug: slug)
|
||||
}
|
||||
|
||||
public func premiumGiftCodeOptions(peerId: EnginePeer.Id?) -> Signal<[PremiumGiftCodeOption], NoError> {
|
||||
return _internal_premiumGiftCodeOptions(account: self.account, peerId: peerId)
|
||||
public func premiumGiftCodeOptions(peerId: EnginePeer.Id?, onlyCached: Bool = false) -> Signal<[PremiumGiftCodeOption], NoError> {
|
||||
return _internal_premiumGiftCodeOptions(account: self.account, peerId: peerId, onlyCached: onlyCached)
|
||||
}
|
||||
|
||||
public func premiumGiveawayInfo(peerId: EnginePeer.Id, messageId: EngineMessage.Id) -> Signal<PremiumGiveawayInfo?, NoError> {
|
||||
|
@ -5683,7 +5683,13 @@ public class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewI
|
||||
@objc private func nameButtonPressed() {
|
||||
if let item = self.item, let peer = item.message.author {
|
||||
let messageReference = MessageReference(item.message)
|
||||
if let channel = peer as? TelegramChannel, case .broadcast = channel.info {
|
||||
if peer.id.isVerificationCodes, let forwardAuthor = item.content.firstMessage.forwardInfo?.author {
|
||||
if let channel = forwardAuthor as? TelegramChannel, case .broadcast = channel.info {
|
||||
item.controllerInteraction.openPeer(EnginePeer(channel), .chat(textInputState: nil, subject: nil, peekData: nil), messageReference, .default)
|
||||
} else {
|
||||
item.controllerInteraction.openPeer(EnginePeer(forwardAuthor), .info(nil), messageReference, .default)
|
||||
}
|
||||
} else if let channel = peer as? TelegramChannel, case .broadcast = channel.info {
|
||||
item.controllerInteraction.openPeer(EnginePeer(peer), .chat(textInputState: nil, subject: nil, peekData: nil), messageReference, .default)
|
||||
} else {
|
||||
item.controllerInteraction.openPeer(EnginePeer(peer), .info(nil), messageReference, .groupParticipant(storyStats: nil, avatarHeaderNode: nil))
|
||||
|
@ -438,6 +438,8 @@ final class GiftSetupScreenComponent: Component {
|
||||
|
||||
contentHeight += environment.navigationHeight
|
||||
contentHeight += 26.0
|
||||
|
||||
let giftConfiguration = GiftConfiguration.with(appConfiguration: component.context.currentAppConfiguration.with { $0 })
|
||||
|
||||
var introSectionItems: [AnyComponentWithIdentity<Empty>] = []
|
||||
introSectionItems.append(AnyComponentWithIdentity(id: introSectionItems.count, component: AnyComponent(Rectangle(color: .clear, height: 346.0, tag: self.introPlaceholderTag))))
|
||||
@ -451,10 +453,10 @@ final class GiftSetupScreenComponent: Component {
|
||||
return ListMultilineTextFieldItemComponent.ResetText(value: $0)
|
||||
},
|
||||
placeholder: "Enter Message",
|
||||
autocapitalizationType: .none,
|
||||
autocorrectionType: .no,
|
||||
autocapitalizationType: .sentences,
|
||||
autocorrectionType: .yes,
|
||||
returnKeyType: .done,
|
||||
characterLimit: 255,
|
||||
characterLimit: Int(giftConfiguration.maxCaptionLength),
|
||||
displayCharacterLimit: true,
|
||||
emptyLineHandling: .notAllowed,
|
||||
formatMenuAvailability: .available([.bold, .italic, .underline, .strikethrough, .spoiler]),
|
||||
@ -1062,3 +1064,27 @@ public final class GiftSetupScreen: ViewControllerComponentContainer {
|
||||
super.containerLayoutUpdated(layout, transition: transition)
|
||||
}
|
||||
}
|
||||
|
||||
private struct GiftConfiguration {
|
||||
static var defaultValue: GiftConfiguration {
|
||||
return GiftConfiguration(maxCaptionLength: 255)
|
||||
}
|
||||
|
||||
let maxCaptionLength: Int32
|
||||
|
||||
fileprivate init(maxCaptionLength: Int32) {
|
||||
self.maxCaptionLength = maxCaptionLength
|
||||
}
|
||||
|
||||
static func with(appConfiguration: AppConfiguration) -> GiftConfiguration {
|
||||
if let data = appConfiguration.data {
|
||||
var maxCaptionLength: Int32?
|
||||
if let value = data["stargifts_message_length_max"] as? Double {
|
||||
maxCaptionLength = Int32(value)
|
||||
}
|
||||
return GiftConfiguration(maxCaptionLength: maxCaptionLength ?? GiftConfiguration.defaultValue.maxCaptionLength)
|
||||
} else {
|
||||
return .defaultValue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -135,7 +135,6 @@ private final class GiftViewSheetContent: CombinedComponent {
|
||||
|
||||
return { context in
|
||||
let environment = context.environment[ViewControllerComponentContainer.Environment.self].value
|
||||
let controller = environment.controller
|
||||
|
||||
let component = context.component
|
||||
let theme = environment.theme
|
||||
@ -294,17 +293,12 @@ private final class GiftViewSheetContent: CombinedComponent {
|
||||
)
|
||||
),
|
||||
action: {
|
||||
// if "".isEmpty {
|
||||
// component.openPeer(peer)
|
||||
// Queue.mainQueue().after(1.0, {
|
||||
// component.cancel(false)
|
||||
// })
|
||||
// } else {
|
||||
if let controller = controller() as? GiftViewScreen, let navigationController = controller.navigationController, let chatController = navigationController.viewControllers.first(where: { $0 is ChatController }) as? ChatController {
|
||||
chatController.playShakeAnimation()
|
||||
}
|
||||
component.cancel(true)
|
||||
// }
|
||||
if "".isEmpty {
|
||||
component.openPeer(peer)
|
||||
Queue.mainQueue().after(1.0, {
|
||||
component.cancel(false)
|
||||
})
|
||||
}
|
||||
}
|
||||
)
|
||||
)
|
||||
@ -798,12 +792,17 @@ public class GiftViewScreen: ViewControllerComponentContainer {
|
||||
|
||||
self.dismissAnimated()
|
||||
|
||||
let title: String = added ? "Gift Saved to Profile" : "Gift Removed from Profile"
|
||||
var text = added ? "The gift is now displayed in [your profile]()." : "The gift is no longer displayed in [your profile]()."
|
||||
if let _ = updateSavedToProfile {
|
||||
text = text.replacingOccurrences(of: "]()", with: "").replacingOccurrences(of: "[", with: "")
|
||||
}
|
||||
if let navigationController {
|
||||
Queue.mainQueue().after(0.5) {
|
||||
if let lastController = navigationController.viewControllers.last as? ViewController {
|
||||
let resultController = UndoOverlayController(
|
||||
presentationData: presentationData,
|
||||
content: .sticker(context: context, file: arguments.gift.file, loop: false, title: added ? "Gift Saved to Profile" : "Gift Removed from Profile", text: added ? "The gift is now displayed in [your profile]()." : "The gift is no longer displayed in [your profile]().", undoText: nil, customAction: nil),
|
||||
content: .sticker(context: context, file: arguments.gift.file, loop: false, title: title, text: text, undoText: nil, customAction: nil),
|
||||
elevatedLayout: lastController is ChatController,
|
||||
action: { [weak navigationController] action in
|
||||
if case .info = action, let navigationController {
|
||||
@ -854,11 +853,11 @@ public class GiftViewScreen: ViewControllerComponentContainer {
|
||||
self?.dismissAnimated()
|
||||
|
||||
if let navigationController {
|
||||
if let starsContext = context.starsContext {
|
||||
navigationController.pushViewController(context.sharedContext.makeStarsTransactionsScreen(context: context, starsContext: starsContext), animated: true)
|
||||
}
|
||||
|
||||
Queue.mainQueue().after(0.5) {
|
||||
if let starsContext = context.starsContext {
|
||||
navigationController.pushViewController(context.sharedContext.makeStarsTransactionsScreen(context: context, starsContext: starsContext), animated: true)
|
||||
}
|
||||
|
||||
if let lastController = navigationController.viewControllers.last as? ViewController {
|
||||
let resultController = UndoOverlayController(
|
||||
presentationData: presentationData,
|
||||
|
@ -413,7 +413,7 @@ public final class ListMultilineTextFieldItemComponent: Component {
|
||||
environment: {},
|
||||
containerSize: CGSize(width: 100.0, height: 100.0)
|
||||
)
|
||||
let textLimitLabelFrame = CGRect(origin: CGPoint(x: availableSize.width - textLimitLabelSize.width - rightInset, y: verticalInset + 2.0), size: textLimitLabelSize)
|
||||
let textLimitLabelFrame = CGRect(origin: CGPoint(x: availableSize.width - textLimitLabelSize.width - leftInset + 5.0, y: verticalInset + 2.0), size: textLimitLabelSize)
|
||||
if let textLimitLabelView = textLimitLabel.view {
|
||||
if textLimitLabelView.superview == nil {
|
||||
textLimitLabelView.isUserInteractionEnabled = false
|
||||
|
@ -384,6 +384,7 @@ final class PeerInfoScreenData {
|
||||
let starsRevenueStatsContext: StarsRevenueStatsContext?
|
||||
let revenueStatsState: RevenueStats?
|
||||
let profileGiftsContext: ProfileGiftsContext?
|
||||
let premiumGiftOptions: [PremiumGiftCodeOption]
|
||||
|
||||
let _isContact: Bool
|
||||
var forceIsContact: Bool = false
|
||||
@ -430,7 +431,8 @@ final class PeerInfoScreenData {
|
||||
starsRevenueStatsState: StarsRevenueStats?,
|
||||
starsRevenueStatsContext: StarsRevenueStatsContext?,
|
||||
revenueStatsState: RevenueStats?,
|
||||
profileGiftsContext: ProfileGiftsContext?
|
||||
profileGiftsContext: ProfileGiftsContext?,
|
||||
premiumGiftOptions: [PremiumGiftCodeOption]
|
||||
) {
|
||||
self.peer = peer
|
||||
self.chatPeer = chatPeer
|
||||
@ -466,6 +468,7 @@ final class PeerInfoScreenData {
|
||||
self.starsRevenueStatsContext = starsRevenueStatsContext
|
||||
self.revenueStatsState = revenueStatsState
|
||||
self.profileGiftsContext = profileGiftsContext
|
||||
self.premiumGiftOptions = premiumGiftOptions
|
||||
}
|
||||
}
|
||||
|
||||
@ -959,7 +962,8 @@ func peerInfoScreenSettingsData(context: AccountContext, peerId: EnginePeer.Id,
|
||||
starsRevenueStatsState: nil,
|
||||
starsRevenueStatsContext: nil,
|
||||
revenueStatsState: nil,
|
||||
profileGiftsContext: nil
|
||||
profileGiftsContext: nil,
|
||||
premiumGiftOptions: []
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -1005,7 +1009,8 @@ func peerInfoScreenData(context: AccountContext, peerId: PeerId, strings: Presen
|
||||
starsRevenueStatsState: nil,
|
||||
starsRevenueStatsContext: nil,
|
||||
revenueStatsState: nil,
|
||||
profileGiftsContext: nil
|
||||
profileGiftsContext: nil,
|
||||
premiumGiftOptions: []
|
||||
))
|
||||
case let .user(userPeerId, secretChatId, kind):
|
||||
let groupsInCommon: GroupsInCommonContext?
|
||||
@ -1017,11 +1022,17 @@ func peerInfoScreenData(context: AccountContext, peerId: PeerId, strings: Presen
|
||||
groupsInCommon = nil
|
||||
}
|
||||
|
||||
let premiumGiftOptions: Signal<[PremiumGiftCodeOption], NoError>
|
||||
let profileGiftsContext: ProfileGiftsContext?
|
||||
if case .user = kind {
|
||||
profileGiftsContext = ProfileGiftsContext(account: context.account, peerId: userPeerId)
|
||||
premiumGiftOptions = .single([])
|
||||
|> then(
|
||||
context.engine.payments.premiumGiftCodeOptions(peerId: nil, onlyCached: true)
|
||||
)
|
||||
} else {
|
||||
profileGiftsContext = nil
|
||||
premiumGiftOptions = .single([])
|
||||
}
|
||||
|
||||
enum StatusInputData: Equatable {
|
||||
@ -1275,9 +1286,10 @@ func peerInfoScreenData(context: AccountContext, peerId: PeerId, strings: Presen
|
||||
hasBotPreviewItems,
|
||||
peerInfoPersonalChannel(context: context, peerId: peerId, isSettings: false),
|
||||
privacySettings,
|
||||
starsRevenueContextAndState
|
||||
starsRevenueContextAndState,
|
||||
premiumGiftOptions
|
||||
)
|
||||
|> map { peerView, availablePanes, globalNotificationSettings, encryptionKeyFingerprint, status, hasStories, hasStoryArchive, accountIsPremium, savedMessagesPeer, hasSavedMessagesChats, hasSavedMessages, hasSavedMessageTags, hasBotPreviewItems, personalChannel, privacySettings, starsRevenueContextAndState -> PeerInfoScreenData in
|
||||
|> map { peerView, availablePanes, globalNotificationSettings, encryptionKeyFingerprint, status, hasStories, hasStoryArchive, accountIsPremium, savedMessagesPeer, hasSavedMessagesChats, hasSavedMessages, hasSavedMessageTags, hasBotPreviewItems, personalChannel, privacySettings, starsRevenueContextAndState, premiumGiftOptions -> PeerInfoScreenData in
|
||||
var availablePanes = availablePanes
|
||||
if isMyProfile {
|
||||
availablePanes?.insert(.stories, at: 0)
|
||||
@ -1394,7 +1406,8 @@ func peerInfoScreenData(context: AccountContext, peerId: PeerId, strings: Presen
|
||||
starsRevenueStatsState: starsRevenueContextAndState.1,
|
||||
starsRevenueStatsContext: starsRevenueContextAndState.0,
|
||||
revenueStatsState: nil,
|
||||
profileGiftsContext: profileGiftsContext
|
||||
profileGiftsContext: profileGiftsContext,
|
||||
premiumGiftOptions: premiumGiftOptions
|
||||
)
|
||||
}
|
||||
case .channel:
|
||||
@ -1604,7 +1617,8 @@ func peerInfoScreenData(context: AccountContext, peerId: PeerId, strings: Presen
|
||||
starsRevenueStatsState: starsRevenueContextAndState.1,
|
||||
starsRevenueStatsContext: starsRevenueContextAndState.0,
|
||||
revenueStatsState: revenueContextAndState.1,
|
||||
profileGiftsContext: nil
|
||||
profileGiftsContext: nil,
|
||||
premiumGiftOptions: []
|
||||
)
|
||||
}
|
||||
case let .group(groupId):
|
||||
@ -1905,7 +1919,8 @@ func peerInfoScreenData(context: AccountContext, peerId: PeerId, strings: Presen
|
||||
starsRevenueStatsState: nil,
|
||||
starsRevenueStatsContext: nil,
|
||||
revenueStatsState: nil,
|
||||
profileGiftsContext: nil
|
||||
profileGiftsContext: nil,
|
||||
premiumGiftOptions: []
|
||||
))
|
||||
}
|
||||
}
|
||||
|
@ -9816,35 +9816,16 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro
|
||||
}
|
||||
|
||||
private func openPremiumGift() {
|
||||
guard let cachedData = self.data?.cachedData as? CachedUserData else {
|
||||
guard let premiumGiftOptions = self.data?.premiumGiftOptions else {
|
||||
return
|
||||
}
|
||||
var pushControllerImpl: ((ViewController) -> Void)?
|
||||
let controller = PremiumGiftScreen(context: self.context, peerIds: [self.peerId], options: cachedData.premiumGiftOptions, source: .profile, pushController: { c in
|
||||
pushControllerImpl?(c)
|
||||
}, completion: { [weak self] in
|
||||
if let strongSelf = self, let navigationController = strongSelf.controller?.navigationController as? NavigationController {
|
||||
var controllers = navigationController.viewControllers
|
||||
controllers = controllers.filter { !($0 is PeerInfoScreen) && !($0 is PremiumGiftScreen) }
|
||||
var foundController = false
|
||||
for controller in controllers.reversed() {
|
||||
if let chatController = controller as? ChatController, case .peer(id: strongSelf.peerId) = chatController.chatLocation {
|
||||
chatController.hintPlayNextOutgoingGift()
|
||||
foundController = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !foundController {
|
||||
let chatController = strongSelf.context.sharedContext.makeChatController(context: strongSelf.context, chatLocation: .peer(id: strongSelf.peerId), subject: nil, botStart: nil, mode: .standard(.default), params: nil)
|
||||
chatController.hintPlayNextOutgoingGift()
|
||||
controllers.append(chatController)
|
||||
}
|
||||
navigationController.setViewControllers(controllers, animated: true)
|
||||
}
|
||||
})
|
||||
pushControllerImpl = { [weak controller] c in
|
||||
controller?.push(c)
|
||||
}
|
||||
let premiumOptions = premiumGiftOptions.filter { $0.users == 1 }.map { CachedPremiumGiftOption(months: $0.months, currency: $0.currency, amount: $0.amount, botUrl: "", storeProductId: $0.storeProductId) }
|
||||
|
||||
let controller = self.context.sharedContext.makeGiftOptionsController(
|
||||
context: self.context,
|
||||
peerId: self.peerId,
|
||||
premiumOptions: premiumOptions
|
||||
)
|
||||
self.controller?.push(controller)
|
||||
}
|
||||
|
||||
|
@ -2405,6 +2405,15 @@ public final class SharedAccountContextImpl: SharedAccountContext {
|
||||
return controller
|
||||
}
|
||||
|
||||
public func makeGiftOptionsController(context: AccountContext, peerId: EnginePeer.Id, premiumOptions: [CachedPremiumGiftOption]) -> ViewController {
|
||||
guard let starsContext = context.starsContext else {
|
||||
fatalError()
|
||||
}
|
||||
let controller = GiftOptionsScreen(context: context, starsContext: starsContext, peerId: peerId, premiumOptions: premiumOptions)
|
||||
controller.navigationPresentation = .modal
|
||||
return controller
|
||||
}
|
||||
|
||||
public func makePremiumPrivacyControllerController(context: AccountContext, subject: PremiumPrivacySubject, peerId: EnginePeer.Id) -> ViewController {
|
||||
let mappedSubject: PremiumPrivacyScreen.Subject
|
||||
let introSource: PremiumIntroSource
|
||||
|
Loading…
x
Reference in New Issue
Block a user