mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
Group boosts
This commit is contained in:
parent
50c186b566
commit
64a49fc6ed
@ -11289,3 +11289,5 @@ Sorry for the inconvenience.";
|
|||||||
"GroupBoost.BoostToUnrestrict.Times_any" = "**%@** times";
|
"GroupBoost.BoostToUnrestrict.Times_any" = "**%@** times";
|
||||||
|
|
||||||
"GroupBoost.BoostToUnrestrict" = "Boost the group %1$@ to remove messaging restrictions. Your boosts will help **%2$@** to unlock new features.";
|
"GroupBoost.BoostToUnrestrict" = "Boost the group %1$@ to remove messaging restrictions. Your boosts will help **%2$@** to unlock new features.";
|
||||||
|
|
||||||
|
"Story.InputPlaceholderReplyInGroup" = "Comment Story...";
|
||||||
|
@ -959,7 +959,7 @@ public protocol SharedAccountContext: AnyObject {
|
|||||||
func makePremiumIntroController(context: AccountContext, source: PremiumIntroSource, forceDark: Bool, dismissed: (() -> Void)?) -> ViewController
|
func makePremiumIntroController(context: AccountContext, source: PremiumIntroSource, forceDark: Bool, dismissed: (() -> Void)?) -> ViewController
|
||||||
func makePremiumDemoController(context: AccountContext, subject: PremiumDemoSubject, action: @escaping () -> 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 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 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
|
func makePremiumBoostLevelsController(context: AccountContext, peerId: EnginePeer.Id, boostStatus: ChannelBoostStatus, myBoostStatus: MyBoostStatus, forceDark: Bool, openStats: (() -> Void)?) -> ViewController
|
||||||
|
|
||||||
|
@ -1683,7 +1683,7 @@ public final class ChatListNode: ListView {
|
|||||||
guard let self else {
|
guard let self else {
|
||||||
return
|
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)
|
self.push?(controller)
|
||||||
}, openActiveSessions: { [weak self] in
|
}, openActiveSessions: { [weak self] in
|
||||||
guard let self else {
|
guard let self else {
|
||||||
|
@ -2209,6 +2209,13 @@ public class PremiumBoostLevelsScreen: ViewController {
|
|||||||
let _ = (context.engine.peers.applyChannelBoost(peerId: peerId, slots: [availableBoost.slot])
|
let _ = (context.engine.peers.applyChannelBoost(peerId: peerId, slots: [availableBoost.slot])
|
||||||
|> deliverOnMainQueue).startStandalone(completed: { [weak self] in
|
|> deliverOnMainQueue).startStandalone(completed: { [weak self] in
|
||||||
self?.updatedState.set(context.engine.peers.getChannelBoostStatus(peerId: peerId)
|
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
|
|> map { status in
|
||||||
if let status {
|
if let status {
|
||||||
return InternalBoostState(level: Int32(status.level), currentLevelBoosts: Int32(status.currentLevelBoosts), nextLevelBoosts: status.nextLevelBoosts.flatMap(Int32.init), boosts: Int32(status.boosts + 1))
|
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)
|
controller?.dismiss(animated: true, completion: nil)
|
||||||
|
|
||||||
Queue.mainQueue().after(0.4) {
|
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)
|
navigationController.pushViewController(giftController, animated: true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2424,6 +2431,7 @@ public class PremiumBoostLevelsScreen: ViewController {
|
|||||||
|
|
||||||
private var currentLayout: ContainerViewLayout?
|
private var currentLayout: ContainerViewLayout?
|
||||||
|
|
||||||
|
public var boostStatusUpdated: (ChannelBoostStatus) -> Void = { _ in }
|
||||||
public var disposed: () -> Void = {}
|
public var disposed: () -> Void = {}
|
||||||
|
|
||||||
public init(
|
public init(
|
||||||
|
@ -239,7 +239,7 @@ public func PremiumBoostScreen(
|
|||||||
dismissImpl?()
|
dismissImpl?()
|
||||||
|
|
||||||
Queue.mainQueue().after(0.4) {
|
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)
|
pushController(controller)
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
|
@ -880,7 +880,7 @@ public class ReplaceBoostScreen: ViewController {
|
|||||||
}
|
}
|
||||||
let navigationController = self.navigationController
|
let navigationController = self.navigationController
|
||||||
self.dismiss(animated: true, completion: {
|
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)
|
navigationController?.pushViewController(giftController, animated: true)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -1046,7 +1046,7 @@ private func channelStatsControllerEntries(state: ChannelStatsControllerState, p
|
|||||||
return entries
|
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 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 stateValue = Atomic(value: ChannelStatsControllerState(section: section, boostersExpanded: false, moreBoostersDisplayed: 0, giftsSelected: false))
|
||||||
let updateState: ((ChannelStatsControllerState) -> ChannelStatsControllerState) -> Void = { f in
|
let updateState: ((ChannelStatsControllerState) -> ChannelStatsControllerState) -> Void = { f in
|
||||||
@ -1087,12 +1087,16 @@ public func channelStatsController(context: AccountContext, updatedPresentationD
|
|||||||
})
|
})
|
||||||
dataPromise.set(.single(nil) |> then(dataSignal))
|
dataPromise.set(.single(nil) |> then(dataSignal))
|
||||||
|
|
||||||
let boostData: Signal<ChannelBoostStatus?, NoError>
|
let boostDataPromise = Promise<ChannelBoostStatus?>()
|
||||||
if let boostStatus {
|
boostDataPromise.set(.single(boostStatus) |> then(context.engine.peers.getChannelBoostStatus(peerId: peerId)))
|
||||||
boostData = .single(boostStatus)
|
|
||||||
} else {
|
actionsDisposable.add((boostDataPromise.get()
|
||||||
boostData = .single(nil) |> then(context.engine.peers.getChannelBoostStatus(peerId: peerId))
|
|> deliverOnMainQueue).start(next: { boostStatus in
|
||||||
|
if let boostStatus, let boostStatusUpdated {
|
||||||
|
boostStatusUpdated(boostStatus)
|
||||||
}
|
}
|
||||||
|
}))
|
||||||
|
|
||||||
let boostsContext = ChannelBoostersContext(account: context.account, peerId: peerId, gift: false)
|
let boostsContext = ChannelBoostersContext(account: context.account, peerId: peerId, gift: false)
|
||||||
let giftsContext = ChannelBoostersContext(account: context.account, peerId: peerId, gift: true)
|
let giftsContext = ChannelBoostersContext(account: context.account, peerId: peerId, gift: true)
|
||||||
|
|
||||||
@ -1253,7 +1257,7 @@ public func channelStatsController(context: AccountContext, updatedPresentationD
|
|||||||
dataPromise.get(),
|
dataPromise.get(),
|
||||||
messagesPromise.get(),
|
messagesPromise.get(),
|
||||||
storiesPromise.get(),
|
storiesPromise.get(),
|
||||||
boostData,
|
boostDataPromise.get(),
|
||||||
boostsContext.state,
|
boostsContext.state,
|
||||||
giftsContext.state,
|
giftsContext.state,
|
||||||
longLoadingSignal
|
longLoadingSignal
|
||||||
@ -1508,6 +1512,8 @@ public func channelStatsController(context: AccountContext, updatedPresentationD
|
|||||||
guard let boostStatus, let myBoostStatus else {
|
guard let boostStatus, let myBoostStatus else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
boostDataPromise.set(.single(boostStatus))
|
||||||
|
|
||||||
let boostController = PremiumBoostLevelsScreen(
|
let boostController = PremiumBoostLevelsScreen(
|
||||||
context: context,
|
context: context,
|
||||||
peerId: peerId,
|
peerId: peerId,
|
||||||
@ -1515,6 +1521,9 @@ public func channelStatsController(context: AccountContext, updatedPresentationD
|
|||||||
status: boostStatus,
|
status: boostStatus,
|
||||||
myBoostStatus: myBoostStatus
|
myBoostStatus: myBoostStatus
|
||||||
)
|
)
|
||||||
|
boostController.boostStatusUpdated = { boostStatus in
|
||||||
|
boostDataPromise.set(.single(boostStatus))
|
||||||
|
}
|
||||||
controller?.push(boostController)
|
controller?.push(boostController)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -2133,6 +2133,12 @@ public final class ChatEntityKeyboardInputNode: ChatInputNode {
|
|||||||
strongSelf.interaction?.presentGlobalOverlayController(contextController, nil)
|
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 {
|
private final class ContextControllerContentSourceImpl: ContextControllerContentSource {
|
||||||
|
@ -6957,7 +6957,11 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro
|
|||||||
}
|
}
|
||||||
|
|
||||||
if channel.flags.contains(.isCreator) || (channel.adminRights?.rights.contains(.canInviteUsers) == true) {
|
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)
|
controller.push(boostsController)
|
||||||
} else {
|
} else {
|
||||||
let _ = combineLatest(
|
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)
|
let controller = self.context.sharedContext.makePremiumIntroController(context: self.context, source: .settings, forceDark: false, dismissed: nil)
|
||||||
self.controller?.push(controller)
|
self.controller?.push(controller)
|
||||||
case .premiumGift:
|
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)
|
self.controller?.push(controller)
|
||||||
case .stickers:
|
case .stickers:
|
||||||
if let settings = self.data?.globalSettings {
|
if let settings = self.data?.globalSettings {
|
||||||
|
@ -450,6 +450,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
|||||||
var mediaRestrictedTooltipControllerMode = true
|
var mediaRestrictedTooltipControllerMode = true
|
||||||
weak var checksTooltipController: TooltipController?
|
weak var checksTooltipController: TooltipController?
|
||||||
weak var copyProtectionTooltipController: TooltipController?
|
weak var copyProtectionTooltipController: TooltipController?
|
||||||
|
weak var emojiPackTooltipController: TooltipScreen?
|
||||||
|
|
||||||
var currentMessageTooltipScreens: [(TooltipScreen, ListViewItemNode)] = []
|
var currentMessageTooltipScreens: [(TooltipScreen, ListViewItemNode)] = []
|
||||||
|
|
||||||
@ -15757,6 +15758,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
self.present(tooltipScreen, in: .current)
|
self.present(tooltipScreen, in: .current)
|
||||||
|
self.emojiPackTooltipController = tooltipScreen
|
||||||
|
|
||||||
let _ = ApplicationSpecificNotice.incrementGroupEmojiPackSuggestion(accountManager: self.context.sharedContext.accountManager, peerId: peerId).startStandalone()
|
let _ = ApplicationSpecificNotice.incrementGroupEmojiPackSuggestion(accountManager: self.context.sharedContext.accountManager, peerId: peerId).startStandalone()
|
||||||
})
|
})
|
||||||
|
@ -3705,6 +3705,17 @@ class ChatControllerNode: ASDisplayNode, UIScrollViewDelegate {
|
|||||||
strongSelf.interfaceInteraction?.updateInputModeAndDismissedButtonKeyboardMessageId({ state in
|
strongSelf.interfaceInteraction?.updateInputModeAndDismissedButtonKeyboardMessageId({ state in
|
||||||
return (.media(mode: .other, expanded: nil, focused: false), state.interfaceState.messageActionsState.closedButtonKeyboardMessageId)
|
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()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -587,7 +587,7 @@ func openResolvedUrlImpl(
|
|||||||
}
|
}
|
||||||
case let .premiumMultiGift(reference):
|
case let .premiumMultiGift(reference):
|
||||||
dismissInput()
|
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 {
|
if let navigationController = navigationController {
|
||||||
navigationController.pushViewController(controller, animated: true)
|
navigationController.pushViewController(controller, animated: true)
|
||||||
}
|
}
|
||||||
|
@ -2049,7 +2049,7 @@ public final class SharedAccountContextImpl: SharedAccountContext {
|
|||||||
return PremiumLimitScreen(context: context, subject: mappedSubject, count: count, forceDark: forceDark, cancel: cancel, action: action)
|
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]>()
|
let options = Promise<[PremiumGiftCodeOption]>()
|
||||||
options.set(context.engine.payments.premiumGiftCodeOptions(peerId: nil))
|
options.set(context.engine.payments.premiumGiftCodeOptions(peerId: nil))
|
||||||
|
|
||||||
@ -2101,6 +2101,7 @@ public final class SharedAccountContextImpl: SharedAccountContext {
|
|||||||
pushImpl?(c)
|
pushImpl?(c)
|
||||||
}, completion: {
|
}, completion: {
|
||||||
filterImpl?()
|
filterImpl?()
|
||||||
|
completion?()
|
||||||
})
|
})
|
||||||
pushImpl = { [weak giftController] c in
|
pushImpl = { [weak giftController] c in
|
||||||
giftController?.push(c)
|
giftController?.push(c)
|
||||||
@ -2108,7 +2109,7 @@ public final class SharedAccountContextImpl: SharedAccountContext {
|
|||||||
filterImpl = { [weak giftController] in
|
filterImpl = { [weak giftController] in
|
||||||
if let navigationController = giftController?.navigationController as? NavigationController {
|
if let navigationController = giftController?.navigationController as? NavigationController {
|
||||||
var controllers = navigationController.viewControllers
|
var controllers = navigationController.viewControllers
|
||||||
controllers = controllers.filter { !($0 is ContactMultiselectionController) }
|
controllers = controllers.filter { !($0 is ContactMultiselectionController) && !($0 is PremiumGiftScreen) }
|
||||||
navigationController.setViewControllers(controllers, animated: true)
|
navigationController.setViewControllers(controllers, animated: true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user