Group boosts

This commit is contained in:
Ilya Laktyushin 2024-02-10 23:41:41 +04:00
parent 50c186b566
commit 64a49fc6ed
13 changed files with 63 additions and 20 deletions

View File

@ -11289,3 +11289,5 @@ Sorry for the inconvenience.";
"GroupBoost.BoostToUnrestrict.Times_any" = "**%@** times";
"GroupBoost.BoostToUnrestrict" = "Boost the group %1$@ to remove messaging restrictions. Your boosts will help **%2$@** to unlock new features.";
"Story.InputPlaceholderReplyInGroup" = "Comment Story...";

View File

@ -959,7 +959,7 @@ public protocol SharedAccountContext: AnyObject {
func makePremiumIntroController(context: AccountContext, source: PremiumIntroSource, forceDark: Bool, dismissed: (() -> Void)?) -> ViewController
func makePremiumDemoController(context: AccountContext, subject: PremiumDemoSubject, action: @escaping () -> Void) -> ViewController
func makePremiumLimitController(context: AccountContext, subject: PremiumLimitSubject, count: Int32, forceDark: Bool, cancel: @escaping () -> Void, action: @escaping () -> Bool) -> ViewController
func makePremiumGiftController(context: AccountContext, source: PremiumGiftSource) -> ViewController
func makePremiumGiftController(context: AccountContext, source: PremiumGiftSource, completion: (() -> Void)?) -> ViewController
func makePremiumPrivacyControllerController(context: AccountContext, subject: PremiumPrivacySubject, peerId: EnginePeer.Id) -> ViewController
func makePremiumBoostLevelsController(context: AccountContext, peerId: EnginePeer.Id, boostStatus: ChannelBoostStatus, myBoostStatus: MyBoostStatus, forceDark: Bool, openStats: (() -> Void)?) -> ViewController

View File

@ -1683,7 +1683,7 @@ public final class ChatListNode: ListView {
guard let self else {
return
}
let controller = self.context.sharedContext.makePremiumGiftController(context: self.context, source: .chatList)
let controller = self.context.sharedContext.makePremiumGiftController(context: self.context, source: .chatList, completion: nil)
self.push?(controller)
}, openActiveSessions: { [weak self] in
guard let self else {

View File

@ -2209,6 +2209,13 @@ public class PremiumBoostLevelsScreen: ViewController {
let _ = (context.engine.peers.applyChannelBoost(peerId: peerId, slots: [availableBoost.slot])
|> deliverOnMainQueue).startStandalone(completed: { [weak self] in
self?.updatedState.set(context.engine.peers.getChannelBoostStatus(peerId: peerId)
|> beforeNext { [weak self] status in
if let self, let status {
Queue.mainQueue().async {
self.controller?.boostStatusUpdated(status)
}
}
}
|> map { status in
if let status {
return InternalBoostState(level: Int32(status.level), currentLevelBoosts: Int32(status.currentLevelBoosts), nextLevelBoosts: status.nextLevelBoosts.flatMap(Int32.init), boosts: Int32(status.boosts + 1))
@ -2353,7 +2360,7 @@ public class PremiumBoostLevelsScreen: ViewController {
controller?.dismiss(animated: true, completion: nil)
Queue.mainQueue().after(0.4) {
let giftController = context.sharedContext.makePremiumGiftController(context: context, source: .channelBoost)
let giftController = context.sharedContext.makePremiumGiftController(context: context, source: .channelBoost, completion: nil)
navigationController.pushViewController(giftController, animated: true)
}
}
@ -2424,6 +2431,7 @@ public class PremiumBoostLevelsScreen: ViewController {
private var currentLayout: ContainerViewLayout?
public var boostStatusUpdated: (ChannelBoostStatus) -> Void = { _ in }
public var disposed: () -> Void = {}
public init(
@ -2493,7 +2501,7 @@ public class PremiumBoostLevelsScreen: ViewController {
override open func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
self.node.updateIsVisible(isVisible: false)
}

View File

@ -239,7 +239,7 @@ public func PremiumBoostScreen(
dismissImpl?()
Queue.mainQueue().after(0.4) {
let controller = context.sharedContext.makePremiumGiftController(context: context, source: .channelBoost)
let controller = context.sharedContext.makePremiumGiftController(context: context, source: .channelBoost, completion: nil)
pushController(controller)
}
}),

View File

@ -880,7 +880,7 @@ public class ReplaceBoostScreen: ViewController {
}
let navigationController = self.navigationController
self.dismiss(animated: true, completion: {
let giftController = context.sharedContext.makePremiumGiftController(context: context, source: .channelBoost)
let giftController = context.sharedContext.makePremiumGiftController(context: context, source: .channelBoost, completion: nil)
navigationController?.pushViewController(giftController, animated: true)
})
}

View File

@ -1046,7 +1046,7 @@ private func channelStatsControllerEntries(state: ChannelStatsControllerState, p
return entries
}
public func channelStatsController(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)? = nil, peerId: PeerId, section: ChannelStatsSection = .stats, boostStatus: ChannelBoostStatus? = nil) -> ViewController {
public func channelStatsController(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)? = nil, peerId: PeerId, section: ChannelStatsSection = .stats, boostStatus: ChannelBoostStatus? = nil, boostStatusUpdated: ((ChannelBoostStatus) -> Void)? = nil) -> ViewController {
let statePromise = ValuePromise(ChannelStatsControllerState(section: section, boostersExpanded: false, moreBoostersDisplayed: 0, giftsSelected: false), ignoreRepeated: true)
let stateValue = Atomic(value: ChannelStatsControllerState(section: section, boostersExpanded: false, moreBoostersDisplayed: 0, giftsSelected: false))
let updateState: ((ChannelStatsControllerState) -> ChannelStatsControllerState) -> Void = { f in
@ -1087,12 +1087,16 @@ public func channelStatsController(context: AccountContext, updatedPresentationD
})
dataPromise.set(.single(nil) |> then(dataSignal))
let boostData: Signal<ChannelBoostStatus?, NoError>
if let boostStatus {
boostData = .single(boostStatus)
} else {
boostData = .single(nil) |> then(context.engine.peers.getChannelBoostStatus(peerId: peerId))
}
let boostDataPromise = Promise<ChannelBoostStatus?>()
boostDataPromise.set(.single(boostStatus) |> then(context.engine.peers.getChannelBoostStatus(peerId: peerId)))
actionsDisposable.add((boostDataPromise.get()
|> deliverOnMainQueue).start(next: { boostStatus in
if let boostStatus, let boostStatusUpdated {
boostStatusUpdated(boostStatus)
}
}))
let boostsContext = ChannelBoostersContext(account: context.account, peerId: peerId, gift: false)
let giftsContext = ChannelBoostersContext(account: context.account, peerId: peerId, gift: true)
@ -1253,7 +1257,7 @@ public func channelStatsController(context: AccountContext, updatedPresentationD
dataPromise.get(),
messagesPromise.get(),
storiesPromise.get(),
boostData,
boostDataPromise.get(),
boostsContext.state,
giftsContext.state,
longLoadingSignal
@ -1508,6 +1512,8 @@ public func channelStatsController(context: AccountContext, updatedPresentationD
guard let boostStatus, let myBoostStatus else {
return
}
boostDataPromise.set(.single(boostStatus))
let boostController = PremiumBoostLevelsScreen(
context: context,
peerId: peerId,
@ -1515,6 +1521,9 @@ public func channelStatsController(context: AccountContext, updatedPresentationD
status: boostStatus,
myBoostStatus: myBoostStatus
)
boostController.boostStatusUpdated = { boostStatus in
boostDataPromise.set(.single(boostStatus))
}
controller?.push(boostController)
})
}

View File

@ -390,7 +390,7 @@ public final class ChatEntityKeyboardInputNode: ChatInputNode {
}
return true
}
public var useExternalSearchContainer: Bool = false
private var gifContext: GifContext? {
@ -2133,6 +2133,12 @@ public final class ChatEntityKeyboardInputNode: ChatInputNode {
strongSelf.interaction?.presentGlobalOverlayController(contextController, nil)
})
}
public func scrollToGroupEmoji() {
if let pagerView = self.entityKeyboardView.componentView as? EntityKeyboardComponent.View {
pagerView.scrollToItemGroup(contentId: "emoji", groupId: "peerSpecific", subgroupId: nil)
}
}
}
private final class ContextControllerContentSourceImpl: ContextControllerContentSource {

View File

@ -6957,7 +6957,11 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro
}
if channel.flags.contains(.isCreator) || (channel.adminRights?.rights.contains(.canInviteUsers) == true) {
let boostsController = channelStatsController(context: self.context, updatedPresentationData: controller.updatedPresentationData, peerId: self.peerId, section: .boosts, boostStatus: self.boostStatus)
let boostsController = channelStatsController(context: self.context, updatedPresentationData: controller.updatedPresentationData, peerId: self.peerId, section: .boosts, boostStatus: self.boostStatus, boostStatusUpdated: { [weak self] boostStatus in
if let self {
self.boostStatus = boostStatus
}
})
controller.push(boostsController)
} else {
let _ = combineLatest(
@ -8814,7 +8818,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro
let controller = self.context.sharedContext.makePremiumIntroController(context: self.context, source: .settings, forceDark: false, dismissed: nil)
self.controller?.push(controller)
case .premiumGift:
let controller = self.context.sharedContext.makePremiumGiftController(context: self.context, source: .settings)
let controller = self.context.sharedContext.makePremiumGiftController(context: self.context, source: .settings, completion: nil)
self.controller?.push(controller)
case .stickers:
if let settings = self.data?.globalSettings {

View File

@ -450,6 +450,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
var mediaRestrictedTooltipControllerMode = true
weak var checksTooltipController: TooltipController?
weak var copyProtectionTooltipController: TooltipController?
weak var emojiPackTooltipController: TooltipScreen?
var currentMessageTooltipScreens: [(TooltipScreen, ListViewItemNode)] = []
@ -15757,6 +15758,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
}
)
self.present(tooltipScreen, in: .current)
self.emojiPackTooltipController = tooltipScreen
let _ = ApplicationSpecificNotice.incrementGroupEmojiPackSuggestion(accountManager: self.context.sharedContext.accountManager, peerId: peerId).startStandalone()
})

View File

@ -3705,6 +3705,17 @@ class ChatControllerNode: ASDisplayNode, UIScrollViewDelegate {
strongSelf.interfaceInteraction?.updateInputModeAndDismissedButtonKeyboardMessageId({ state in
return (.media(mode: .other, expanded: nil, focused: false), state.interfaceState.messageActionsState.closedButtonKeyboardMessageId)
})
if let emojiPackTooltipController = strongSelf.controller?.emojiPackTooltipController {
strongSelf.controller?.emojiPackTooltipController = nil
emojiPackTooltipController.dismiss()
Queue.mainQueue().after(0.1) {
if let inputNode = strongSelf.inputNode as? ChatEntityKeyboardInputNode {
inputNode.scrollToGroupEmoji()
}
}
}
})
}
}

View File

@ -587,7 +587,7 @@ func openResolvedUrlImpl(
}
case let .premiumMultiGift(reference):
dismissInput()
let controller = context.sharedContext.makePremiumGiftController(context: context, source: .deeplink(reference))
let controller = context.sharedContext.makePremiumGiftController(context: context, source: .deeplink(reference), completion: nil)
if let navigationController = navigationController {
navigationController.pushViewController(controller, animated: true)
}

View File

@ -2049,7 +2049,7 @@ public final class SharedAccountContextImpl: SharedAccountContext {
return PremiumLimitScreen(context: context, subject: mappedSubject, count: count, forceDark: forceDark, cancel: cancel, action: action)
}
public func makePremiumGiftController(context: AccountContext, source: PremiumGiftSource) -> ViewController {
public func makePremiumGiftController(context: AccountContext, source: PremiumGiftSource, completion: (() -> Void)?) -> ViewController {
let options = Promise<[PremiumGiftCodeOption]>()
options.set(context.engine.payments.premiumGiftCodeOptions(peerId: nil))
@ -2101,6 +2101,7 @@ public final class SharedAccountContextImpl: SharedAccountContext {
pushImpl?(c)
}, completion: {
filterImpl?()
completion?()
})
pushImpl = { [weak giftController] c in
giftController?.push(c)
@ -2108,7 +2109,7 @@ public final class SharedAccountContextImpl: SharedAccountContext {
filterImpl = { [weak giftController] in
if let navigationController = giftController?.navigationController as? NavigationController {
var controllers = navigationController.viewControllers
controllers = controllers.filter { !($0 is ContactMultiselectionController) }
controllers = controllers.filter { !($0 is ContactMultiselectionController) && !($0 is PremiumGiftScreen) }
navigationController.setViewControllers(controllers, animated: true)
}
}