diff --git a/Telegram/Telegram-iOS/en.lproj/Localizable.strings b/Telegram/Telegram-iOS/en.lproj/Localizable.strings index 11c3bd6079..9afe3de581 100644 --- a/Telegram/Telegram-iOS/en.lproj/Localizable.strings +++ b/Telegram/Telegram-iOS/en.lproj/Localizable.strings @@ -10215,9 +10215,9 @@ Sorry for the inconvenience."; "ReassignBoost.ExpiresOn" = "Boost expires on %@"; "ReassignBoost.WaitForCooldown" = "Wait until the boost is available or get **%1$@** more boosts by gifting a **Telegram Premium** subscription."; -"ReassignBoost.Success" = "%1$@ are reassigned from %2$@."; -"ReassignBoost.Boosts_1" = "%@ boost"; -"ReassignBoost.Boosts_any" = "%@ boosts"; +"ReassignBoost.Success" = "%1$@ from %2$@."; +"ReassignBoost.Boosts_1" = "%@ boost is reassigned"; +"ReassignBoost.Boosts_any" = "%@ boosts are reassigned"; "ReassignBoost.OtherChannels_1" = "%@ other channel"; "ReassignBoost.OtherChannels_any" = "%@ other channels"; @@ -10433,6 +10433,10 @@ Sorry for the inconvenience."; "CountriesList.SaveCountries" = "Save Countries"; "CountriesList.SelectUpTo_1" = "select up to %@ country"; "CountriesList.SelectUpTo_any" = "select up to %@ countries"; +"CountriesList.Search" = "Search"; +"CountriesList.MaximumReached" = "You can select up to %@."; +"CountriesList.MaximumReached.Countries_1" = "%@ country"; +"CountriesList.MaximumReached.Countries_any" = "%@ countries"; "Message.GiveawayOngoing" = "Giveaway: %1$@ on %2$@"; "Message.GiveawayOngoing.Winners_1" = "%@ winner to be selected"; @@ -10442,6 +10446,9 @@ Sorry for the inconvenience."; "Message.GiveawayFinished.Winners_1" = "%@ winner was selected"; "Message.GiveawayFinished.Winners_any" = "%@ winners were selected"; +"Message.GiveawayStarted" = "Channel started a giveaway"; +"Message.GiveawayStartedOther" = "%@ started a giveaway"; + "Conversation.PinnedGiveaway" = "Giveaway"; "Conversation.PinnedGiveaway.Ongoing" = "%1$@ on %2$@"; @@ -10451,3 +10458,9 @@ Sorry for the inconvenience."; "Conversation.PinnedGiveaway.Finished" = "%1$@ on %2$@"; "Conversation.PinnedGiveaway.Finished.Winners_1" = "%@ winner was selected"; "Conversation.PinnedGiveaway.Finished.Winners_any" = "%@ winners were selected"; + +"BoostGift.StartConfirmation.Title" = "Start Giveaway"; +"BoostGift.StartConfirmation.Text" = "Are you sure you want to start giveaway now?"; +"BoostGift.StartConfirmation.Start" = "Start"; + +"Channel.Info.Stats" = "Statistics and Boosts"; diff --git a/submodules/ChatListUI/Sources/Node/ChatListItemStrings.swift b/submodules/ChatListUI/Sources/Node/ChatListItemStrings.swift index df85d40dd5..4778982f7b 100644 --- a/submodules/ChatListUI/Sources/Node/ChatListItemStrings.swift +++ b/submodules/ChatListUI/Sources/Node/ChatListItemStrings.swift @@ -305,16 +305,11 @@ public func chatListItemStrings(strings: PresentationStrings, nameDisplayOrder: } else { messageText = strings.Notification_Story } - case let giveaway as TelegramMediaGiveaway: - let dateString = stringForDateWithoutYear(date: Date(timeIntervalSince1970: TimeInterval(giveaway.untilDate)), timeZone: .current, strings: strings) - let currentTime = Int32(CFAbsoluteTimeGetCurrent() + kCFAbsoluteTimeIntervalSince1970) - let isFinished = currentTime >= giveaway.untilDate - if isFinished { - let winnersString = strings.Message_GiveawayFinished_Winners(giveaway.quantity) - messageText = strings.Message_GiveawayFinished(winnersString, dateString).string + case _ as TelegramMediaGiveaway: + if let forwardInfo = message.forwardInfo, let author = forwardInfo.author { + messageText = strings.Message_GiveawayStartedOther(EnginePeer(author).compactDisplayTitle).string } else { - let winnersString = strings.Message_GiveawayOngoing_Winners(giveaway.quantity) - messageText = strings.Message_GiveawayOngoing(winnersString, dateString).string + messageText = strings.Message_GiveawayStarted } case let webpage as TelegramMediaWebpage: if messageText.isEmpty, case let .Loaded(content) = webpage.content { diff --git a/submodules/PremiumUI/Sources/CreateGiveawayController.swift b/submodules/PremiumUI/Sources/CreateGiveawayController.swift index 8eb6fa8688..4897e22b52 100644 --- a/submodules/PremiumUI/Sources/CreateGiveawayController.swift +++ b/submodules/PremiumUI/Sources/CreateGiveawayController.swift @@ -837,7 +837,14 @@ public func createGiveawayController(context: AccountContext, updatedPresentatio badgeCount = Int32(state.peers.count) * 4 } let footerItem = CreateGiveawayFooterItem(theme: presentationData.theme, title: state.mode == .gift ? presentationData.strings.BoostGift_GiftPremium : presentationData.strings.BoostGift_StartGiveaway, badgeCount: badgeCount, isLoading: state.updating, action: { - buyActionImpl?() + if case .prepaid = subject { + let alertController = textAlertController(context: context, title: presentationData.strings.BoostGift_StartConfirmation_Title, text: presentationData.strings.BoostGift_StartConfirmation_Text, actions: [TextAlertAction(type: .genericAction, title: presentationData.strings.Common_Cancel, action: {}), TextAlertAction(type: .defaultAction, title: presentationData.strings.BoostGift_StartConfirmation_Start, action: { + buyActionImpl?() + })], parseMarkdown: true) + presentControllerImpl?(alertController) + } else { + buyActionImpl?() + } }) let leftNavigationButton = ItemListNavigationButton(content: .none, style: .regular, enabled: false, action: {}) diff --git a/submodules/PremiumUI/Sources/GiftOptionItem.swift b/submodules/PremiumUI/Sources/GiftOptionItem.swift index 239293955a..b7fe236e66 100644 --- a/submodules/PremiumUI/Sources/GiftOptionItem.swift +++ b/submodules/PremiumUI/Sources/GiftOptionItem.swift @@ -304,12 +304,14 @@ class GiftOptionItemNode: ItemListRevealOptionsItemNode { let (labelLayout, labelApply) = makeLabelLayout(TextNodeLayoutArguments(attributedString: labelAttributedString, maximumNumberOfLines: 1, truncationType: .end, constrainedSize: CGSize(width: params.width, height: .greatestFiniteMagnitude))) var textConstrainedWidth = params.width - leftInset - 8.0 - editingOffset - rightInset - labelLayout.size.width - avatarInset + var subtitleConstrainedWidth = textConstrainedWidth if let label = item.label, case .semitransparent = label { textConstrainedWidth -= 54.0 + subtitleConstrainedWidth -= 30.0 } let (titleLayout, titleApply) = makeTitleLayout(TextNodeLayoutArguments(attributedString: titleAttributedString, maximumNumberOfLines: 1, truncationType: .end, constrainedSize: CGSize(width: textConstrainedWidth, height: .greatestFiniteMagnitude))) - let (statusLayout, statusApply) = makeStatusLayout(TextNodeLayoutArguments(attributedString: statusAttributedString, backgroundColor: nil, maximumNumberOfLines: 1, truncationType: .end, constrainedSize: CGSize(width: textConstrainedWidth, height: CGFloat.greatestFiniteMagnitude), alignment: .natural, cutout: nil, insets: UIEdgeInsets())) + let (statusLayout, statusApply) = makeStatusLayout(TextNodeLayoutArguments(attributedString: statusAttributedString, backgroundColor: nil, maximumNumberOfLines: 1, truncationType: .end, constrainedSize: CGSize(width: subtitleConstrainedWidth, height: CGFloat.greatestFiniteMagnitude), alignment: .natural, cutout: nil, insets: UIEdgeInsets())) let (badgeLayout, badgeApply) = makeBadgeLayout(TextNodeLayoutArguments(attributedString: badgeAttributedString, backgroundColor: nil, maximumNumberOfLines: 1, truncationType: .end, constrainedSize: CGSize(width: textConstrainedWidth, height: CGFloat.greatestFiniteMagnitude), alignment: .natural, cutout: nil, insets: UIEdgeInsets())) diff --git a/submodules/TelegramUI/Components/Chat/ChatMessageBubbleItemNode/Sources/ChatMessageBubbleItemNode.swift b/submodules/TelegramUI/Components/Chat/ChatMessageBubbleItemNode/Sources/ChatMessageBubbleItemNode.swift index d41bd85eb4..f8d08f6b63 100644 --- a/submodules/TelegramUI/Components/Chat/ChatMessageBubbleItemNode/Sources/ChatMessageBubbleItemNode.swift +++ b/submodules/TelegramUI/Components/Chat/ChatMessageBubbleItemNode/Sources/ChatMessageBubbleItemNode.swift @@ -1556,7 +1556,7 @@ public class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewI for contentNodeItemValue in contentNodeMessagesAndClasses { let contentNodeItem = contentNodeItemValue as (message: Message, type: AnyClass, attributes: ChatMessageEntryAttributes, bubbleAttributes: BubbleItemAttributes) if contentNodeItem.type == ChatMessageGiveawayBubbleContentNode.self { - maximumContentWidth = 260.0 + maximumContentWidth = min(305.0, maximumContentWidth) break } if contentNodeItem.type == ChatMessageInstantVideoBubbleContentNode.self, !contentNodeItem.bubbleAttributes.isAttachment { diff --git a/submodules/TelegramUI/Components/Chat/ChatMessageGiveawayBubbleContentNode/Sources/ChatMessageGiveawayBubbleContentNode.swift b/submodules/TelegramUI/Components/Chat/ChatMessageGiveawayBubbleContentNode/Sources/ChatMessageGiveawayBubbleContentNode.swift index 35fe59fd49..d65462b819 100644 --- a/submodules/TelegramUI/Components/Chat/ChatMessageGiveawayBubbleContentNode/Sources/ChatMessageGiveawayBubbleContentNode.swift +++ b/submodules/TelegramUI/Components/Chat/ChatMessageGiveawayBubbleContentNode/Sources/ChatMessageGiveawayBubbleContentNode.swift @@ -319,7 +319,7 @@ public class ChatMessageGiveawayBubbleContentNode: ChatMessageBubbleContentNode let (participantsTitleLayout, participantsTitleApply) = makeParticipantsTitleLayout(TextNodeLayoutArguments(attributedString: participantsTitleString, backgroundColor: nil, maximumNumberOfLines: 1, truncationType: .end, constrainedSize: CGSize(width: maxTextWidth, height: CGFloat.greatestFiniteMagnitude), alignment: .center, cutout: nil, insets: UIEdgeInsets())) let (participantsTextLayout, participantsTextApply) = makeParticipantsTextLayout(TextNodeLayoutArguments(attributedString: participantsTextString, backgroundColor: nil, maximumNumberOfLines: 5, truncationType: .end, constrainedSize: CGSize(width: maxTextWidth, height: CGFloat.greatestFiniteMagnitude), alignment: .center, cutout: nil, insets: UIEdgeInsets())) - let (countriesTextLayout, countriesTextApply) = makeCountriesTextLayout(TextNodeLayoutArguments(attributedString: countriesTextString, backgroundColor: nil, maximumNumberOfLines: 5, truncationType: .end, constrainedSize: CGSize(width: maxTextWidth, height: CGFloat.greatestFiniteMagnitude), alignment: .center, cutout: nil, insets: UIEdgeInsets())) + let (countriesTextLayout, countriesTextApply) = makeCountriesTextLayout(TextNodeLayoutArguments(attributedString: countriesTextString, backgroundColor: nil, maximumNumberOfLines: 0, truncationType: .end, constrainedSize: CGSize(width: maxTextWidth, height: CGFloat.greatestFiniteMagnitude), alignment: .center, cutout: nil, insets: UIEdgeInsets())) let (dateTitleLayout, dateTitleApply) = makeDateTitleLayout(TextNodeLayoutArguments(attributedString: dateTitleString, backgroundColor: nil, maximumNumberOfLines: 1, truncationType: .end, constrainedSize: CGSize(width: maxTextWidth, height: CGFloat.greatestFiniteMagnitude), alignment: .center, cutout: nil, insets: UIEdgeInsets())) let (dateTextLayout, dateTextApply) = makeDateTextLayout(TextNodeLayoutArguments(attributedString: dateTextString, backgroundColor: nil, maximumNumberOfLines: 5, truncationType: .end, constrainedSize: CGSize(width: maxTextWidth, height: CGFloat.greatestFiniteMagnitude), alignment: .center, cutout: nil, insets: UIEdgeInsets())) @@ -437,7 +437,7 @@ public class ChatMessageGiveawayBubbleContentNode: ChatMessageBubbleContentNode } } } - let (channelsWidth, continueChannelLayout) = makeChannelsLayout(item.context, 220.0, channelPeers, accentColor, accentColor.withAlphaComponent(0.1)) + let (channelsWidth, continueChannelLayout) = makeChannelsLayout(item.context, 220.0, channelPeers, accentColor, accentColor.withAlphaComponent(0.1), incoming, item.presentationData.theme.theme.overallDarkAppearance) maxContentWidth = max(maxContentWidth, channelsWidth) maxContentWidth += 30.0 @@ -649,11 +649,11 @@ private final class PeerButtonsStackNode: ASDisplayNode { var buttonNodes: [PeerButtonNode] = [] var openPeer: (EnginePeer) -> Void = { _ in } - static func asyncLayout(_ current: PeerButtonsStackNode) -> (_ context: AccountContext, _ width: CGFloat, _ peers: [EnginePeer], _ titleColor: UIColor, _ backgroundColor: UIColor) -> (CGFloat, (CGFloat) -> (CGSize, () -> PeerButtonsStackNode)) { + static func asyncLayout(_ current: PeerButtonsStackNode) -> (_ context: AccountContext, _ width: CGFloat, _ peers: [EnginePeer], _ titleColor: UIColor, _ backgroundColor: UIColor, _ incoming: Bool, _ dark: Bool) -> (CGFloat, (CGFloat) -> (CGSize, () -> PeerButtonsStackNode)) { let currentChannelButtons = current.buttonNodes.isEmpty ? nil : current.buttonNodes let maybeMakeChannelButtons = current.buttonNodes.map(PeerButtonNode.asyncLayout) - return { context, width, peers, titleColor, backgroundColor in + return { context, width, peers, titleColor, backgroundColor, incoming, dark in let targetNode = current var buttonNodes: [PeerButtonNode] = [] @@ -682,6 +682,13 @@ private final class PeerButtonsStackNode: ASDisplayNode { let peer = peers[i] let makeChannelButtonLayout = makeChannelButtonLayouts[i] + var titleColor = titleColor + var backgroundColor = backgroundColor + if incoming, let nameColor = peer.nameColor { + titleColor = context.peerNameColors.get(nameColor, dark: dark).main + backgroundColor = titleColor.withAlphaComponent(0.1) + } + let (buttonWidth, buttonContinue) = makeChannelButtonLayout(context, width, peer, titleColor, backgroundColor) sizes.append(CGSize(width: buttonWidth, height: buttonHeight)) buttonContinues.append(buttonContinue) diff --git a/submodules/TelegramUI/Components/ShareWithPeersScreen/Sources/CountriesMultiselectionScreen.swift b/submodules/TelegramUI/Components/ShareWithPeersScreen/Sources/CountriesMultiselectionScreen.swift index db68431ac0..1559896c2f 100644 --- a/submodules/TelegramUI/Components/ShareWithPeersScreen/Sources/CountriesMultiselectionScreen.swift +++ b/submodules/TelegramUI/Components/ShareWithPeersScreen/Sources/CountriesMultiselectionScreen.swift @@ -468,7 +468,8 @@ final class CountriesMultiselectionScreenComponent: Component { self.hapticFeedback.error() let presentationData = component.context.sharedContext.currentPresentationData.with { $0 } - controller.present(UndoOverlayController(presentationData: presentationData, content: .info(title: nil, text: "You can select maximum \(limit) countries.", timeout: nil, customUndoText: nil), elevatedLayout: false, position: .bottom, animateInAsReplacement: false, action: { _ in return false }), in: .current) + let countriesValue = environment.strings.CountriesList_MaximumReached_Countries(limit) + controller.present(UndoOverlayController(presentationData: presentationData, content: .info(title: nil, text: environment.strings.CountriesList_MaximumReached(countriesValue).string, timeout: nil, customUndoText: nil), elevatedLayout: false, position: .bottom, animateInAsReplacement: false, action: { _ in return false }), in: .current) return } toggleCountry() @@ -721,7 +722,7 @@ final class CountriesMultiselectionScreenComponent: Component { )) } - let placeholder: String = "Search" + let placeholder: String = environment.strings.CountriesList_Search self.navigationTextField.parentState = state let navigationTextFieldSize = self.navigationTextField.update( transition: transition, diff --git a/submodules/TelegramUI/Images.xcassets/Chat/Info/StatsIcon.imageset/Contents.json b/submodules/TelegramUI/Images.xcassets/Chat/Info/StatsIcon.imageset/Contents.json new file mode 100644 index 0000000000..b7a0fdc912 --- /dev/null +++ b/submodules/TelegramUI/Images.xcassets/Chat/Info/StatsIcon.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "stats_30.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/submodules/TelegramUI/Images.xcassets/Chat/Info/StatsIcon.imageset/stats_30.pdf b/submodules/TelegramUI/Images.xcassets/Chat/Info/StatsIcon.imageset/stats_30.pdf new file mode 100644 index 0000000000..019b307677 --- /dev/null +++ b/submodules/TelegramUI/Images.xcassets/Chat/Info/StatsIcon.imageset/stats_30.pdf @@ -0,0 +1,218 @@ +%PDF-1.7 + +1 0 obj + << /Type /XObject + /Length 2 0 R + /Group << /Type /Group + /S /Transparency + >> + /Subtype /Form + /Resources << >> + /BBox [ 0.000000 0.000000 30.000000 30.000000 ] + >> +stream +/DeviceRGB CS +/DeviceRGB cs +q +1.000000 0.000000 -0.000000 1.000000 0.000000 0.000000 cm +0.345098 0.337255 0.839216 scn +0.000000 18.799999 m +0.000000 22.720367 0.000000 24.680552 0.762954 26.177933 c +1.434068 27.495068 2.504932 28.565931 3.822066 29.237045 c +5.319448 30.000000 7.279633 30.000000 11.200000 30.000000 c +18.799999 30.000000 l +22.720367 30.000000 24.680552 30.000000 26.177933 29.237045 c +27.495068 28.565931 28.565931 27.495068 29.237045 26.177933 c +30.000000 24.680552 30.000000 22.720367 30.000000 18.799999 c +30.000000 11.200001 l +30.000000 7.279633 30.000000 5.319448 29.237045 3.822067 c +28.565931 2.504932 27.495068 1.434069 26.177933 0.762955 c +24.680552 0.000000 22.720367 0.000000 18.799999 0.000000 c +11.200000 0.000000 l +7.279633 0.000000 5.319448 0.000000 3.822066 0.762955 c +2.504932 1.434069 1.434068 2.504932 0.762954 3.822067 c +0.000000 5.319448 0.000000 7.279633 0.000000 11.200001 c +0.000000 18.799999 l +h +f +n +Q +q +1.000000 0.000000 -0.000000 1.000000 6.000000 7.000000 cm +1.000000 1.000000 1.000000 scn +7.000000 14.000000 m +7.000000 14.464986 7.000000 14.697479 7.051111 14.888228 c +7.189812 15.405867 7.594133 15.810188 8.111772 15.948889 c +8.302522 16.000000 8.535014 16.000000 9.000000 16.000000 c +9.464986 16.000000 9.697478 16.000000 9.888228 15.948889 c +10.405867 15.810188 10.810188 15.405867 10.948889 14.888228 c +11.000000 14.697479 11.000000 14.464986 11.000000 14.000000 c +11.000000 2.000000 l +11.000000 1.535014 11.000000 1.302522 10.948889 1.111772 c +10.810188 0.594133 10.405867 0.189812 9.888228 0.051111 c +9.697478 0.000000 9.464986 0.000000 9.000000 0.000000 c +8.535014 0.000000 8.302522 0.000000 8.111772 0.051111 c +7.594133 0.189812 7.189812 0.594133 7.051111 1.111772 c +7.000000 1.302522 7.000000 1.535014 7.000000 2.000000 c +7.000000 14.000000 l +h +0.000000 8.000000 m +0.000000 8.464986 0.000000 8.697479 0.051111 8.888228 c +0.189812 9.405867 0.594133 9.810188 1.111771 9.948889 c +1.302521 10.000000 1.535014 10.000000 2.000000 10.000000 c +2.464986 10.000000 2.697479 10.000000 2.888229 9.948889 c +3.405867 9.810188 3.810188 9.405867 3.948889 8.888228 c +4.000000 8.697479 4.000000 8.464986 4.000000 8.000000 c +4.000000 2.000000 l +4.000000 1.535014 4.000000 1.302522 3.948889 1.111772 c +3.810188 0.594133 3.405867 0.189812 2.888229 0.051111 c +2.697479 0.000000 2.464986 0.000000 2.000000 0.000000 c +1.535014 0.000000 1.302521 0.000000 1.111771 0.051111 c +0.594133 0.189812 0.189812 0.594133 0.051111 1.111772 c +0.000000 1.302522 0.000000 1.535014 0.000000 2.000000 c +0.000000 8.000000 l +h +14.051111 4.888228 m +14.000000 4.697478 14.000000 4.464986 14.000000 4.000000 c +14.000000 2.000000 l +14.000000 1.535014 14.000000 1.302522 14.051111 1.111772 c +14.189812 0.594133 14.594133 0.189812 15.111772 0.051111 c +15.302522 0.000000 15.535014 0.000000 16.000000 0.000000 c +16.464985 0.000000 16.697479 0.000000 16.888229 0.051111 c +17.405867 0.189812 17.810188 0.594133 17.948889 1.111772 c +18.000000 1.302522 18.000000 1.535014 18.000000 2.000000 c +18.000000 4.000000 l +18.000000 4.464986 18.000000 4.697478 17.948889 4.888228 c +17.810188 5.405867 17.405867 5.810188 16.888229 5.948889 c +16.697479 6.000000 16.464985 6.000000 16.000000 6.000000 c +15.535014 6.000000 15.302522 6.000000 15.111772 5.948889 c +14.594133 5.810188 14.189812 5.405867 14.051111 4.888228 c +h +f* +n +Q + +endstream +endobj + +2 0 obj + 3320 +endobj + +3 0 obj + << /Type /XObject + /Length 4 0 R + /Group << /Type /Group + /S /Transparency + >> + /Subtype /Form + /Resources << >> + /BBox [ 0.000000 0.000000 30.000000 30.000000 ] + >> +stream +/DeviceRGB CS +/DeviceRGB cs +q +1.000000 0.000000 -0.000000 1.000000 0.000000 0.000000 cm +0.000000 0.000000 0.000000 scn +0.000000 18.799999 m +0.000000 22.720367 0.000000 24.680552 0.762954 26.177933 c +1.434068 27.495068 2.504932 28.565931 3.822066 29.237045 c +5.319448 30.000000 7.279633 30.000000 11.200000 30.000000 c +18.799999 30.000000 l +22.720367 30.000000 24.680552 30.000000 26.177933 29.237045 c +27.495068 28.565931 28.565931 27.495068 29.237045 26.177933 c +30.000000 24.680552 30.000000 22.720367 30.000000 18.799999 c +30.000000 11.200001 l +30.000000 7.279633 30.000000 5.319448 29.237045 3.822067 c +28.565931 2.504932 27.495068 1.434069 26.177933 0.762955 c +24.680552 0.000000 22.720367 0.000000 18.799999 0.000000 c +11.200000 0.000000 l +7.279633 0.000000 5.319448 0.000000 3.822066 0.762955 c +2.504932 1.434069 1.434068 2.504932 0.762954 3.822067 c +0.000000 5.319448 0.000000 7.279633 0.000000 11.200001 c +0.000000 18.799999 l +h +f +n +Q + +endstream +endobj + +4 0 obj + 944 +endobj + +5 0 obj + << /XObject << /X1 1 0 R >> + /ExtGState << /E1 << /SMask << /Type /Mask + /G 3 0 R + /S /Alpha + >> + /Type /ExtGState + >> >> + >> +endobj + +6 0 obj + << /Length 7 0 R >> +stream +/DeviceRGB CS +/DeviceRGB cs +q +/E1 gs +/X1 Do +Q + +endstream +endobj + +7 0 obj + 46 +endobj + +8 0 obj + << /Annots [] + /Type /Page + /MediaBox [ 0.000000 0.000000 30.000000 30.000000 ] + /Resources 5 0 R + /Contents 6 0 R + /Parent 9 0 R + >> +endobj + +9 0 obj + << /Kids [ 8 0 R ] + /Count 1 + /Type /Pages + >> +endobj + +10 0 obj + << /Pages 9 0 R + /Type /Catalog + >> +endobj + +xref +0 11 +0000000000 65535 f +0000000010 00000 n +0000003578 00000 n +0000003601 00000 n +0000004793 00000 n +0000004815 00000 n +0000005113 00000 n +0000005215 00000 n +0000005236 00000 n +0000005409 00000 n +0000005483 00000 n +trailer +<< /ID [ (some) (id) ] + /Root 10 0 R + /Size 11 +>> +startxref +5543 +%%EOF \ No newline at end of file diff --git a/submodules/TelegramUI/Sources/PeerInfo/PeerInfoScreen.swift b/submodules/TelegramUI/Sources/PeerInfo/PeerInfoScreen.swift index 05f743cb9d..5978f96c9c 100644 --- a/submodules/TelegramUI/Sources/PeerInfo/PeerInfoScreen.swift +++ b/submodules/TelegramUI/Sources/PeerInfo/PeerInfoScreen.swift @@ -529,6 +529,7 @@ private final class PeerInfoInteraction { let editingToggleMessageSignatures: (Bool) -> Void let openParticipantsSection: (PeerInfoParticipantsSection) -> Void let openRecentActions: () -> Void + let openStats: () -> Void let editingOpenPreHistorySetup: () -> Void let editingOpenAutoremoveMesages: () -> Void let openPermissions: () -> Void @@ -582,6 +583,7 @@ private final class PeerInfoInteraction { editingToggleMessageSignatures: @escaping (Bool) -> Void, openParticipantsSection: @escaping (PeerInfoParticipantsSection) -> Void, openRecentActions: @escaping () -> Void, + openStats: @escaping () -> Void, editingOpenPreHistorySetup: @escaping () -> Void, editingOpenAutoremoveMesages: @escaping () -> Void, openPermissions: @escaping () -> Void, @@ -634,6 +636,7 @@ private final class PeerInfoInteraction { self.editingToggleMessageSignatures = editingToggleMessageSignatures self.openParticipantsSection = openParticipantsSection self.openRecentActions = openRecentActions + self.openStats = openStats self.editingOpenPreHistorySetup = editingOpenPreHistorySetup self.editingOpenAutoremoveMesages = editingOpenAutoremoveMesages self.openPermissions = openPermissions @@ -1550,8 +1553,9 @@ private func editingItems(data: PeerInfoScreenData?, state: PeerInfoState, chatL let ItemAdmins = 9 let ItemMembers = 10 let ItemMemberRequests = 11 - let ItemBanned = 12 - let ItemRecentActions = 13 + let ItemStats = 12 + let ItemBanned = 13 + let ItemRecentActions = 14 let isCreator = channel.flags.contains(.isCreator) @@ -1641,47 +1645,56 @@ private func editingItems(data: PeerInfoScreenData?, state: PeerInfoState, chatL } var canEditMembers = false - if channel.hasPermission(.banMembers) { + if channel.hasPermission(.banMembers) && (channel.adminRights != nil || channel.flags.contains(.isCreator)) { canEditMembers = true } if canEditMembers { - if channel.adminRights != nil || channel.flags.contains(.isCreator) { - let adminCount: Int32 - let memberCount: Int32 - let bannedCount: Int32 - if let cachedData = data.cachedData as? CachedChannelData { - adminCount = cachedData.participantsSummary.adminCount ?? 0 - memberCount = cachedData.participantsSummary.memberCount ?? 0 - bannedCount = cachedData.participantsSummary.kickedCount ?? 0 - } else { - adminCount = 0 - memberCount = 0 - bannedCount = 0 - } - - items[.peerAdditionalSettings]!.append(PeerInfoScreenDisclosureItem(id: ItemAdmins, label: .text("\(adminCount == 0 ? "" : "\(presentationStringsFormattedNumber(adminCount, presentationData.dateTimeFormat.groupingSeparator))")"), text: presentationData.strings.GroupInfo_Administrators, icon: UIImage(bundleImageName: "Chat/Info/GroupAdminsIcon"), action: { - interaction.openParticipantsSection(.admins) - })) - items[.peerAdditionalSettings]!.append(PeerInfoScreenDisclosureItem(id: ItemMembers, label: .text("\(memberCount == 0 ? "" : "\(presentationStringsFormattedNumber(memberCount, presentationData.dateTimeFormat.groupingSeparator))")"), text: presentationData.strings.Channel_Info_Subscribers, icon: UIImage(bundleImageName: "Chat/Info/GroupMembersIcon"), action: { - interaction.openParticipantsSection(.members) - })) - - if let count = data.requests?.count, count > 0 { - items[.peerAdditionalSettings]!.append(PeerInfoScreenDisclosureItem(id: ItemMemberRequests, label: .badge(presentationStringsFormattedNumber(count, presentationData.dateTimeFormat.groupingSeparator), presentationData.theme.list.itemAccentColor), text: presentationData.strings.GroupInfo_MemberRequests, icon: UIImage(bundleImageName: "Chat/Info/GroupRequestsIcon"), action: { - interaction.openParticipantsSection(.memberRequests) - })) - } - - items[.peerAdditionalSettings]!.append(PeerInfoScreenDisclosureItem(id: ItemBanned, label: .text("\(bannedCount == 0 ? "" : "\(presentationStringsFormattedNumber(bannedCount, presentationData.dateTimeFormat.groupingSeparator))")"), text: presentationData.strings.GroupInfo_Permissions_Removed, icon: UIImage(bundleImageName: "Chat/Info/GroupRemovedIcon"), action: { - interaction.openParticipantsSection(.banned) - })) - - items[.peerAdditionalSettings]!.append(PeerInfoScreenDisclosureItem(id: ItemRecentActions, label: .none, text: presentationData.strings.Group_Info_AdminLog, icon: UIImage(bundleImageName: "Chat/Info/RecentActionsIcon"), action: { - interaction.openRecentActions() + let adminCount: Int32 + let memberCount: Int32 + if let cachedData = data.cachedData as? CachedChannelData { + adminCount = cachedData.participantsSummary.adminCount ?? 0 + memberCount = cachedData.participantsSummary.memberCount ?? 0 + } else { + adminCount = 0 + memberCount = 0 + } + + items[.peerAdditionalSettings]!.append(PeerInfoScreenDisclosureItem(id: ItemAdmins, label: .text("\(adminCount == 0 ? "" : "\(presentationStringsFormattedNumber(adminCount, presentationData.dateTimeFormat.groupingSeparator))")"), text: presentationData.strings.GroupInfo_Administrators, icon: UIImage(bundleImageName: "Chat/Info/GroupAdminsIcon"), action: { + interaction.openParticipantsSection(.admins) + })) + items[.peerAdditionalSettings]!.append(PeerInfoScreenDisclosureItem(id: ItemMembers, label: .text("\(memberCount == 0 ? "" : "\(presentationStringsFormattedNumber(memberCount, presentationData.dateTimeFormat.groupingSeparator))")"), text: presentationData.strings.Channel_Info_Subscribers, icon: UIImage(bundleImageName: "Chat/Info/GroupMembersIcon"), action: { + interaction.openParticipantsSection(.members) + })) + + if let count = data.requests?.count, count > 0 { + items[.peerAdditionalSettings]!.append(PeerInfoScreenDisclosureItem(id: ItemMemberRequests, label: .badge(presentationStringsFormattedNumber(count, presentationData.dateTimeFormat.groupingSeparator), presentationData.theme.list.itemAccentColor), text: presentationData.strings.GroupInfo_MemberRequests, icon: UIImage(bundleImageName: "Chat/Info/GroupRequestsIcon"), action: { + interaction.openParticipantsSection(.memberRequests) })) } } + if let cachedData = data.cachedData as? CachedChannelData, cachedData.flags.contains(.canViewStats) { + items[.peerAdditionalSettings]!.append(PeerInfoScreenDisclosureItem(id: ItemStats, label: .none, text: presentationData.strings.Channel_Info_Stats, icon: UIImage(bundleImageName: "Chat/Info/StatsIcon"), action: { + interaction.openStats() + })) + } + + if canEditMembers { + let bannedCount: Int32 + if let cachedData = data.cachedData as? CachedChannelData { + bannedCount = cachedData.participantsSummary.kickedCount ?? 0 + } else { + bannedCount = 0 + } + items[.peerAdditionalSettings]!.append(PeerInfoScreenDisclosureItem(id: ItemBanned, label: .text("\(bannedCount == 0 ? "" : "\(presentationStringsFormattedNumber(bannedCount, presentationData.dateTimeFormat.groupingSeparator))")"), text: presentationData.strings.GroupInfo_Permissions_Removed, icon: UIImage(bundleImageName: "Chat/Info/GroupRemovedIcon"), action: { + interaction.openParticipantsSection(.banned) + })) + + items[.peerAdditionalSettings]!.append(PeerInfoScreenDisclosureItem(id: ItemRecentActions, label: .none, text: presentationData.strings.Group_Info_AdminLog, icon: UIImage(bundleImageName: "Chat/Info/RecentActionsIcon"), action: { + interaction.openRecentActions() + })) + } + if isCreator { //if let cachedData = data.cachedData as? CachedChannelData, cachedData.flags.contains(.canDeleteHistory) { items[.peerActions]!.append(PeerInfoScreenActionItem(id: ItemDeleteChannel, text: presentationData.strings.ChannelInfo_DeleteChannel, color: .destructive, icon: nil, alignment: .natural, action: { interaction.openDeletePeer() @@ -2304,6 +2317,9 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro openRecentActions: { [weak self] in self?.openRecentActions() }, + openStats: { [weak self] in + self?.openStats() + }, editingOpenPreHistorySetup: { [weak self] in self?.editingOpenPreHistorySetup() },