diff --git a/Telegram/Telegram-iOS/en.lproj/Localizable.strings b/Telegram/Telegram-iOS/en.lproj/Localizable.strings index 5adcefef3c..8ce095bd44 100644 --- a/Telegram/Telegram-iOS/en.lproj/Localizable.strings +++ b/Telegram/Telegram-iOS/en.lproj/Localizable.strings @@ -10313,7 +10313,7 @@ Sorry for the inconvenience."; "Story.Guide.PauseDescription" = "Hold and move sideways"; "Story.Guide.BackTitle" = "Go back"; "Story.Guide.BackDescription" = "Tap the left edge"; -"Story.Guide.MoveTitle" = "Move between stories"; +"Story.Guide.MoveTitle" = "Move between authors"; "Story.Guide.MoveDescription" = "Swipe left or right"; "Story.Guide.Proceed" = "Tap to keep watching"; @@ -10401,3 +10401,6 @@ Sorry for the inconvenience."; "GiftLink.TelegramPremium_1" = "Telegram Premium for %@ month"; "GiftLink.TelegramPremium_any" = "Telegram Premium for %@ months"; "GiftLink.LinkHidden" = "Only the recipient can see the link."; + +"ChannelBoost.EnableColors" = "Enable Colors"; +"ChannelBoost.EnableColorsText" = "Your channel needs %1$@ to change channel color.\n\nAsk your **Premium** subscribers to boost your channel with this link:"; diff --git a/submodules/PremiumUI/Sources/PremiumBoostScreen.swift b/submodules/PremiumUI/Sources/PremiumBoostScreen.swift index 092dce39ce..2c7880d424 100644 --- a/submodules/PremiumUI/Sources/PremiumBoostScreen.swift +++ b/submodules/PremiumUI/Sources/PremiumBoostScreen.swift @@ -30,7 +30,7 @@ private struct BoostState { } return ( - .storiesChannelBoost(peer: peer, isCurrent: isCurrent, level: currentLevel, currentLevelBoosts: currentLevelBoosts, nextLevelBoosts: nextLevelBoosts, link: nil, myBoostCount: myBoostCount), + .storiesChannelBoost(peer: peer, boostSubject: .stories, isCurrent: isCurrent, level: currentLevel, currentLevelBoosts: currentLevelBoosts, nextLevelBoosts: nextLevelBoosts, link: nil, myBoostCount: myBoostCount), boosts ) } @@ -113,23 +113,15 @@ public func PremiumBoostScreen( dismissed() } - var updating = false - let presentationData = context.sharedContext.currentPresentationData.with { $0 } updateImpl = { [weak controller] in - guard !updating else { - return - } if let _ = status.nextLevelBoosts { if let availableBoost = availableBoosts.first { currentMyBoostCount += 1 myBoostCount += 1 - updating = true let _ = (context.engine.peers.applyChannelBoost(peerId: peerId, slots: [availableBoost.slot]) |> deliverOnMainQueue).startStandalone(completed: { - updating = false - updatedState.set(context.engine.peers.getChannelBoostStatus(peerId: peerId) |> map { status in if let status { diff --git a/submodules/PremiumUI/Sources/PremiumLimitScreen.swift b/submodules/PremiumUI/Sources/PremiumLimitScreen.swift index 9c2a51d2a5..e5e17d76b2 100644 --- a/submodules/PremiumUI/Sources/PremiumLimitScreen.swift +++ b/submodules/PremiumUI/Sources/PremiumLimitScreen.swift @@ -1105,7 +1105,7 @@ private final class LimitSheetContent: CombinedComponent { string = strings.Premium_MaxStoriesMonthlyNoPremiumText("\(limit)").string } buttonAnimationName = nil - case let .storiesChannelBoost(peer, isCurrent, level, currentLevelBoosts, nextLevelBoosts, link, myBoostCount): + case let .storiesChannelBoost(peer, boostSubject, isCurrent, level, currentLevelBoosts, nextLevelBoosts, link, myBoostCount): if link == nil, !isCurrent, state.initialized { peerShortcutChild = peerShortcut.update( component: Button( @@ -1177,8 +1177,14 @@ private final class LimitSheetContent: CombinedComponent { let storiesString = strings.ChannelBoost_StoriesPerDay(level + 1) let valueString = strings.ChannelBoost_MoreBoosts(remaining) if level == 0 { - titleText = strings.ChannelBoost_EnableStories - string = strings.ChannelBoost_EnableStoriesText(valueString).string + switch boostSubject { + case .stories: + titleText = strings.ChannelBoost_EnableStories + string = strings.ChannelBoost_EnableStoriesText(valueString).string + case .nameColors: + titleText = strings.ChannelBoost_EnableColors + string = strings.ChannelBoost_EnableColorsText(valueString).string + } } else { titleText = strings.ChannelBoost_IncreaseLimit string = strings.ChannelBoost_IncreaseLimitText(valueString, storiesString).string @@ -1422,7 +1428,7 @@ private final class LimitSheetContent: CombinedComponent { var buttonOffset: CGFloat = 0.0 var textOffset: CGFloat = 184.0 + topOffset - if case let .storiesChannelBoost(_, _, _, _, _, link, _) = component.subject { + if case let .storiesChannelBoost(_, _, _, _, _, _, link, _) = component.subject { if let link { let linkButton = linkButton.update( component: SolidRoundedButtonComponent( @@ -1533,7 +1539,7 @@ private final class LimitSheetContent: CombinedComponent { ) var additionalContentHeight: CGFloat = 0.0 - if case let .storiesChannelBoost(_, _, _, _, _, link, _) = component.subject, link != nil, let openGift = component.openGift { + if case let .storiesChannelBoost(_, _, _, _, _, _, link, _) = component.subject, link != nil, let openGift = component.openGift { let orText = orText.update( component: MultilineTextComponent(text: .plain(NSAttributedString(string: "or", font: Font.regular(15.0), textColor: textColor.withAlphaComponent(0.8), paragraphAlignment: .center))), availableSize: CGSize(width: context.availableSize.width - sideInset * 2.0, height: context.availableSize.height), @@ -1602,7 +1608,7 @@ private final class LimitSheetContent: CombinedComponent { height -= 78.0 } - if case let .storiesChannelBoost(_, isCurrent, _, _, _, link, _) = component.subject { + if case let .storiesChannelBoost(_, _, isCurrent, _, _, _, link, _) = component.subject { if link != nil { height += 66.0 @@ -1763,7 +1769,12 @@ public class PremiumLimitScreen: ViewControllerComponentContainer { case storiesWeekly case storiesMonthly - case storiesChannelBoost(peer: EnginePeer, isCurrent: Bool, level: Int32, currentLevelBoosts: Int32, nextLevelBoosts: Int32?, link: String?, myBoostCount: Int32) + + public enum BoostSubject { + case stories + case nameColors + } + case storiesChannelBoost(peer: EnginePeer, boostSubject: BoostSubject, isCurrent: Bool, level: Int32, currentLevelBoosts: Int32, nextLevelBoosts: Int32?, link: String?, myBoostCount: Int32) } private let context: AccountContext diff --git a/submodules/TelegramUI/Components/Settings/PeerNameColorScreen/Sources/PeerNameColorScreen.swift b/submodules/TelegramUI/Components/Settings/PeerNameColorScreen/Sources/PeerNameColorScreen.swift index fcd523753f..be6b4473be 100644 --- a/submodules/TelegramUI/Components/Settings/PeerNameColorScreen/Sources/PeerNameColorScreen.swift +++ b/submodules/TelegramUI/Components/Settings/PeerNameColorScreen/Sources/PeerNameColorScreen.swift @@ -428,7 +428,7 @@ public func PeerNameColorScreen( } let link = status.url - let controller = PremiumLimitScreen(context: context, subject: .storiesChannelBoost(peer: peer, isCurrent: true, level: Int32(status.level), currentLevelBoosts: Int32(status.currentLevelBoosts), nextLevelBoosts: status.nextLevelBoosts.flatMap(Int32.init), link: link, myBoostCount: 0), count: Int32(status.boosts), action: { + let controller = PremiumLimitScreen(context: context, subject: .storiesChannelBoost(peer: peer, boostSubject: .nameColors, isCurrent: true, level: Int32(status.level), currentLevelBoosts: Int32(status.currentLevelBoosts), nextLevelBoosts: status.nextLevelBoosts.flatMap(Int32.init), link: link, myBoostCount: 0), count: Int32(status.boosts), action: { UIPasteboard.general.string = link presentImpl?(UndoOverlayController(presentationData: presentationData, content: .linkCopied(text: presentationData.strings.ChannelBoost_BoostLinkCopied), elevatedLayout: false, position: .bottom, animateInAsReplacement: false, action: { _ in return false })) return true diff --git a/submodules/TelegramUI/Components/Stories/PeerListItemComponent/Sources/PeerListItemComponent.swift b/submodules/TelegramUI/Components/Stories/PeerListItemComponent/Sources/PeerListItemComponent.swift index 66cfd6bfd8..c2d5ebb118 100644 --- a/submodules/TelegramUI/Components/Stories/PeerListItemComponent/Sources/PeerListItemComponent.swift +++ b/submodules/TelegramUI/Components/Stories/PeerListItemComponent/Sources/PeerListItemComponent.swift @@ -595,6 +595,11 @@ public final class PeerListItemComponent: Component { } else { titleAvailableWidth -= 20.0 } + + if statusIcon != nil { + titleAvailableWidth -= 14.0 + } + let titleSize = self.title.update( transition: .immediate, component: AnyComponent(MultilineTextComponent( diff --git a/submodules/TelegramUI/Sources/ChatController.swift b/submodules/TelegramUI/Sources/ChatController.swift index 0412bc1bb6..98e76e0d18 100644 --- a/submodules/TelegramUI/Sources/ChatController.swift +++ b/submodules/TelegramUI/Sources/ChatController.swift @@ -298,6 +298,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G var keepMessageCountersSyncrhonizedDisposable: Disposable? var saveMediaDisposable: MetaDisposable? var giveawayStatusDisposable: MetaDisposable? + var nameColorDisposable: Disposable? let editingMessage = ValuePromise(nil, ignoreRepeated: true) let startingBot = ValuePromise(false, ignoreRepeated: true) @@ -5108,9 +5109,30 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G |> deliverOnMainQueue).startStrict(next: { [weak self] peerView in if let strongSelf = self { let isPremium = peerView.peers[peerView.peerId]?.isPremium ?? false + strongSelf.updateChatPresentationInterfaceState(animated: false, interactive: false, { state in + return state.updatedIsPremium(isPremium) + }) + } + }) + + if let chatPeerId = chatLocation.peerId { + self.nameColorDisposable = (context.engine.data.subscribe( + TelegramEngine.EngineData.Item.Peer.Peer(id: context.account.peerId), + TelegramEngine.EngineData.Item.Peer.Peer(id: chatPeerId) + ) + |> deliverOnMainQueue).start(next: { [weak self] accountPeer, chatPeer in + guard let self, let accountPeer, let chatPeer else { + return + } + var nameColor: PeerNameColor? + if case let .channel(channel) = chatPeer, case .broadcast = channel.info { + nameColor = chatPeer.nameColor + } else { + nameColor = accountPeer.nameColor + } var accountPeerColor: ChatPresentationInterfaceState.AccountPeerColor? - if let nameColor = peerView.peers[peerView.peerId]?.nameColor { - let colors = strongSelf.context.peerNameColors.get(nameColor) + if let nameColor { + let colors = self.context.peerNameColors.get(nameColor) var style: ChatPresentationInterfaceState.AccountPeerColor.Style = .solid if colors.tertiary != nil { style = .tripleDashed @@ -5119,11 +5141,11 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G } accountPeerColor = ChatPresentationInterfaceState.AccountPeerColor(style: style) } - strongSelf.updateChatPresentationInterfaceState(animated: false, interactive: false, { state in - return state.updatedIsPremium(isPremium).updatedAccountPeerColor(accountPeerColor) + self.updateChatPresentationInterfaceState(animated: false, interactive: false, { state in + return state.updatedAccountPeerColor(accountPeerColor) }) - } - }) + }) + } do { let peerId = chatLocationPeerId @@ -6802,6 +6824,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G self.powerSavingMonitoringDisposable?.dispose() self.saveMediaDisposable?.dispose() self.giveawayStatusDisposable?.dispose() + self.nameColorDisposable?.dispose() self.choosingStickerActivityDisposable?.dispose() self.automaticMediaDownloadSettingsDisposable?.dispose() self.stickerSettingsDisposable?.dispose() diff --git a/submodules/TelegramUI/Sources/OpenResolvedUrl.swift b/submodules/TelegramUI/Sources/OpenResolvedUrl.swift index a1afcdf02a..5c9c0df71b 100644 --- a/submodules/TelegramUI/Sources/OpenResolvedUrl.swift +++ b/submodules/TelegramUI/Sources/OpenResolvedUrl.swift @@ -905,11 +905,9 @@ func openResolvedUrlImpl(_ resolvedUrl: ResolvedUrl, context: AccountContext, ur let controller = PremiumIntroScreen(context: context, source: .settings, forceDark: forceDark, forceHasPremium: true) navigationController?.pushViewController(controller) - if let controller = controller as? PremiumIntroScreen { - Queue.mainQueue().after(0.3, { - controller.animateSuccess() - }) - } + Queue.mainQueue().after(0.3, { + controller.animateSuccess() + }) }) }, openPeer: { peer in diff --git a/submodules/TelegramUI/Sources/PeerInfo/PeerInfoScreen.swift b/submodules/TelegramUI/Sources/PeerInfo/PeerInfoScreen.swift index c05bb29bf8..bd89764d6b 100644 --- a/submodules/TelegramUI/Sources/PeerInfo/PeerInfoScreen.swift +++ b/submodules/TelegramUI/Sources/PeerInfo/PeerInfoScreen.swift @@ -8382,7 +8382,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro if let previousController = navigationController.viewControllers.last as? ShareWithPeersScreen { previousController.dismiss() } - let controller = PremiumLimitScreen(context: self.context, subject: .storiesChannelBoost(peer: peer, isCurrent: true, level: Int32(status.level), currentLevelBoosts: Int32(status.currentLevelBoosts), nextLevelBoosts: status.nextLevelBoosts.flatMap(Int32.init), link: link, myBoostCount: 0), count: Int32(status.boosts), action: { [weak self] in + let controller = PremiumLimitScreen(context: self.context, subject: .storiesChannelBoost(peer: peer, boostSubject: .stories, isCurrent: true, level: Int32(status.level), currentLevelBoosts: Int32(status.currentLevelBoosts), nextLevelBoosts: status.nextLevelBoosts.flatMap(Int32.init), link: link, myBoostCount: 0), count: Int32(status.boosts), action: { [weak self] in UIPasteboard.general.string = link if let self { diff --git a/submodules/TelegramUI/Sources/SharedAccountContext.swift b/submodules/TelegramUI/Sources/SharedAccountContext.swift index a087ec380c..02a761a096 100644 --- a/submodules/TelegramUI/Sources/SharedAccountContext.swift +++ b/submodules/TelegramUI/Sources/SharedAccountContext.swift @@ -1813,7 +1813,7 @@ public final class SharedAccountContextImpl: SharedAccountContext { case .storiesMonthly: mappedSubject = .storiesMonthly case let .storiesChannelBoost(peer, isCurrent, level, currentLevelBoosts, nextLevelBoosts, link, myBoostCount): - mappedSubject = .storiesChannelBoost(peer: peer, isCurrent: isCurrent, level: level, currentLevelBoosts: currentLevelBoosts, nextLevelBoosts: nextLevelBoosts, link: link, myBoostCount: myBoostCount) + mappedSubject = .storiesChannelBoost(peer: peer, boostSubject: .stories, isCurrent: isCurrent, level: level, currentLevelBoosts: currentLevelBoosts, nextLevelBoosts: nextLevelBoosts, link: link, myBoostCount: myBoostCount) } return PremiumLimitScreen(context: context, subject: mappedSubject, count: count, forceDark: forceDark, cancel: cancel, action: action) }