mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-07-15 15:59:26 +00:00
Monoforums
This commit is contained in:
parent
98dc32fe4c
commit
eb3f95ea63
@ -14377,7 +14377,7 @@ Sorry for the inconvenience.";
|
||||
"PeerInfo.OptionTopics.Enabled" = "Enabled";
|
||||
"PeerInfo.OptionTopics.Disabled" = "Disabled";
|
||||
|
||||
"ChannelMessages.Title" = "Allow Channel Messages";
|
||||
"ChannelMessages.Title" = "Direct Messages";
|
||||
"ChannelMessages.Info" = "Allow users to send messages to your channel, with the option to charge a fee for each message.";
|
||||
"ChannelMessages.SwitchTitle" = "Allow Channel Messages";
|
||||
"ChannelMessages.PriceSectionTitle" = "PRICE FOR EACH MESSAGE";
|
||||
@ -14391,10 +14391,21 @@ Sorry for the inconvenience.";
|
||||
"Chat.InlineTopicMenu.AllTab" = "All";
|
||||
"Chat.ChannelMessagesHint" = "Send a message to the channel's admin";
|
||||
"Chat.ChannelMessagesHintBadge" = "NEW";
|
||||
"Chat.ContextMenu.AuthorInfo" = "Sent by %@";
|
||||
|
||||
"PeerInfo.AllowChannelMessages" = "Allow Channel Messages";
|
||||
"PeerInfo.AllowChannelMessages.On" = "On";
|
||||
"PeerInfo.AllowChannelMessages" = "Direct Messages";
|
||||
"PeerInfo.AllowChannelMessages.Free" = "Free";
|
||||
"PeerInfo.AllowChannelMessages.Off" = "Off";
|
||||
"PeerInfo.ChannelMessages" = "Channel Messages";
|
||||
"PeerInfo.ChannelMessages" = "Direct Messages";
|
||||
|
||||
"Chat.EmptyStateMonoforum.Text" = "Send a direct message to the administrator of **%@**.";
|
||||
"Chat.EmptyStateMonoforumPaid.Text" = "**%1$@** charges **%2$@**\nper message to its admin.";
|
||||
|
||||
"Monoforum.NameFormat" = "%@ Messages";
|
||||
|
||||
"Stars.SendMessage.AdjustmentTitle" = "Price for each Message";
|
||||
"Stars.SendMessage.AdjustmentPlaceholder" = "Price for each Message";
|
||||
"Stars.SendMessage.AdjustmentSectionHeader" = "PRICE IN STARS";
|
||||
"Stars.SendMessage.AdjustmentSectionFooterValue" = "You will receive **%@ Stars**.";
|
||||
"Stars.SendMessage.AdjustmentSectionFooterEmpty" = "You will receive **80%**.";
|
||||
"Stars.SendMessage.AdjustmentAction" = "OK";
|
||||
|
@ -272,6 +272,10 @@ public final class AvatarEditOverlayNode: ASDisplayNode {
|
||||
}
|
||||
}
|
||||
|
||||
private func generateAvatarBubblePath() -> CGPath {
|
||||
return try! convertSvgPath("M60,30.274903 C60,46.843446 46.568544,60.274904 30,60.274904 C13.431458,60.274904 0,46.843446 0,30.274903 C0,23.634797 2.158635,17.499547 5.810547,12.529785 L6.036133,12.226074 C6.921364,10.896042 7.367402,8.104698 5.548828,5.316895 C3.606939,2.340088 1.186019,0.979668 2.399414,0.470215 C3.148032,0.156204 7.572027,0.000065 10.764648,1.790527 C12.148517,2.56662 13.2296,3.342422 14.09224,4.039734 C14.42622,4.309704 14.892063,4.349773 15.265962,4.138523 C19.618079,1.679604 24.644722,0.274902 30,0.274902 C46.568544,0.274902 60,13.70636 60,30.274903 Z ")
|
||||
}
|
||||
|
||||
public final class AvatarNode: ASDisplayNode {
|
||||
public static func avatarBubbleMask(size: CGSize) -> UIImage! {
|
||||
return generateImage(size, rotatedContext: { size, context in
|
||||
@ -282,19 +286,20 @@ public final class AvatarNode: ASDisplayNode {
|
||||
})
|
||||
}
|
||||
|
||||
public static let avatarBubblePath: CGPath = generateAvatarBubblePath()
|
||||
|
||||
public static func addAvatarBubblePath(context: CGContext, rect: CGRect) {
|
||||
if let path = try? convertSvgPath("M60,30.274903 C60,46.843446 46.568544,60.274904 30,60.274904 C13.431458,60.274904 0,46.843446 0,30.274903 C0,23.634797 2.158635,17.499547 5.810547,12.529785 L6.036133,12.226074 C6.921364,10.896042 7.367402,8.104698 5.548828,5.316895 C3.606939,2.340088 1.186019,0.979668 2.399414,0.470215 C3.148032,0.156204 7.572027,0.000065 10.764648,1.790527 C12.148517,2.56662 13.2296,3.342422 14.09224,4.039734 C14.42622,4.309704 14.892063,4.349773 15.265962,4.138523 C19.618079,1.679604 24.644722,0.274902 30,0.274902 C46.568544,0.274902 60,13.70636 60,30.274903 Z ") {
|
||||
let sx = rect.width / 60.0
|
||||
let sy = rect.height / 60.0
|
||||
var transform = CGAffineTransform(
|
||||
a: sx, b: 0.0,
|
||||
c: 0.0, d: -sy,
|
||||
tx: rect.minX,
|
||||
ty: rect.minY + rect.height
|
||||
)
|
||||
let transformedPath = path.copy(using: &transform)!
|
||||
context.addPath(transformedPath)
|
||||
}
|
||||
let path = AvatarNode.avatarBubblePath
|
||||
let sx = rect.width / 60.0
|
||||
let sy = rect.height / 60.274904
|
||||
var transform = CGAffineTransform(
|
||||
a: sx, b: 0.0,
|
||||
c: 0.0, d: -sy,
|
||||
tx: rect.minX,
|
||||
ty: rect.minY + rect.height
|
||||
)
|
||||
let transformedPath = path.copy(using: &transform)!
|
||||
context.addPath(transformedPath)
|
||||
}
|
||||
|
||||
public static let gradientColors: [[UIColor]] = [
|
||||
|
@ -5316,20 +5316,25 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
||||
|
||||
var deleteTitle = strongSelf.presentationData.strings.Common_Delete
|
||||
if case let .channel(channel) = chatPeer {
|
||||
if case .broadcast = channel.info {
|
||||
if channel.isMonoForum {
|
||||
canClear = false
|
||||
deleteTitle = strongSelf.presentationData.strings.Channel_LeaveChannel
|
||||
if channel.flags.contains(.isCreator) {
|
||||
canRemoveGlobally = true
|
||||
}
|
||||
canRemoveGlobally = false
|
||||
} else {
|
||||
deleteTitle = strongSelf.presentationData.strings.Group_DeleteGroup
|
||||
if channel.flags.contains(.isCreator) {
|
||||
canRemoveGlobally = true
|
||||
if case .broadcast = channel.info {
|
||||
canClear = false
|
||||
deleteTitle = strongSelf.presentationData.strings.Channel_LeaveChannel
|
||||
if channel.flags.contains(.isCreator) {
|
||||
canRemoveGlobally = true
|
||||
}
|
||||
} else {
|
||||
deleteTitle = strongSelf.presentationData.strings.Group_DeleteGroup
|
||||
if channel.flags.contains(.isCreator) {
|
||||
canRemoveGlobally = true
|
||||
}
|
||||
}
|
||||
if let addressName = channel.addressName, !addressName.isEmpty {
|
||||
canClear = false
|
||||
}
|
||||
}
|
||||
if let addressName = channel.addressName, !addressName.isEmpty {
|
||||
canClear = false
|
||||
}
|
||||
} else if case let .legacyGroup(group) = chatPeer {
|
||||
if case .creator = group.role {
|
||||
|
@ -2980,7 +2980,7 @@ public class ChatListItemNode: ItemListRevealOptionsItemNode {
|
||||
if customMessageListData.commandPrefix != nil {
|
||||
titleAttributedString = nil
|
||||
} else {
|
||||
if let displayTitle = itemPeer.chatMainPeer?.displayTitle(strings: item.presentationData.strings, displayOrder: item.presentationData.nameDisplayOrder) {
|
||||
if let displayTitle = itemPeer.chatOrMonoforumMainPeer?.displayTitle(strings: item.presentationData.strings, displayOrder: item.presentationData.nameDisplayOrder) {
|
||||
let textColor: UIColor
|
||||
if case let .chatList(index) = item.index, index.messageIndex.id.peerId.namespace == Namespaces.Peer.SecretChat {
|
||||
textColor = theme.secretTitleColor
|
||||
@ -2988,6 +2988,10 @@ public class ChatListItemNode: ItemListRevealOptionsItemNode {
|
||||
textColor = theme.titleColor
|
||||
}
|
||||
titleAttributedString = NSAttributedString(string: displayTitle, font: titleFont, textColor: textColor)
|
||||
|
||||
if case let .channel(channel) = itemPeer.peer, channel.flags.contains(.isMonoforum) {
|
||||
titleBadgeText = item.presentationData.strings.ChatList_MonoforumLabel
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if let threadInfo = threadInfo {
|
||||
|
@ -130,8 +130,8 @@ private final class DeleteChatPeerActionSheetItemNode: ActionSheetItemNode {
|
||||
text = PresentationStrings.FormattedString(string: strings.ChatList_DeleteSavedMessagesConfirmation, ranges: [])
|
||||
} else if case let .legacyGroup(chatPeer) = chatPeer {
|
||||
text = strings.ChatList_DeleteAndLeaveGroupConfirmation(chatPeer.title)
|
||||
} else if case let .channel(chatPeer) = chatPeer {
|
||||
text = strings.ChatList_DeleteAndLeaveGroupConfirmation(chatPeer.title)
|
||||
} else if case .channel = chatPeer {
|
||||
text = strings.ChatList_DeleteAndLeaveGroupConfirmation(peer.compactDisplayTitle)
|
||||
} else if case .secretChat = chatPeer {
|
||||
text = strings.ChatList_DeleteSecretChatConfirmation(peer.displayTitle(strings: strings, displayOrder: nameOrder))
|
||||
} else {
|
||||
|
@ -298,6 +298,7 @@ public protocol Peer: AnyObject, PostboxCoding {
|
||||
var id: PeerId { get }
|
||||
var indexName: PeerIndexNameRepresentation { get }
|
||||
var associatedPeerId: PeerId? { get }
|
||||
var additionalAssociatedPeerId: PeerId? { get }
|
||||
var associatedPeerOverridesIdentity: Bool { get }
|
||||
var notificationSettingsPeerId: PeerId? { get }
|
||||
var associatedMediaIds: [MediaId]? { get }
|
||||
@ -307,6 +308,7 @@ public protocol Peer: AnyObject, PostboxCoding {
|
||||
}
|
||||
|
||||
public extension Peer {
|
||||
var additionalAssociatedPeerId: PeerId? { return nil }
|
||||
var associatedPeerOverridesIdentity: Bool { return false }
|
||||
}
|
||||
|
||||
|
@ -48,15 +48,23 @@ final class MutablePeerView: MutablePostboxView {
|
||||
var messageIds = Set<MessageId>()
|
||||
peerIds.insert(peerId)
|
||||
|
||||
if let peer = getPeer(peerId), let associatedPeerId = peer.associatedPeerId {
|
||||
peerIds.insert(associatedPeerId)
|
||||
|
||||
if peer.associatedPeerOverridesIdentity {
|
||||
self.contactPeerId = associatedPeerId
|
||||
self.peerIsContact = postbox.contactsTable.isContact(peerId: associatedPeerId)
|
||||
if let peer = getPeer(peerId) {
|
||||
if let associatedPeerId = peer.associatedPeerId {
|
||||
peerIds.insert(associatedPeerId)
|
||||
|
||||
if peer.associatedPeerOverridesIdentity {
|
||||
self.contactPeerId = associatedPeerId
|
||||
self.peerIsContact = postbox.contactsTable.isContact(peerId: associatedPeerId)
|
||||
} else {
|
||||
self.contactPeerId = peerId
|
||||
}
|
||||
} else {
|
||||
self.contactPeerId = peerId
|
||||
}
|
||||
|
||||
if let additionalAssociatedPeerId = peer.additionalAssociatedPeerId {
|
||||
peerIds.insert(additionalAssociatedPeerId)
|
||||
}
|
||||
} else {
|
||||
self.contactPeerId = peerId
|
||||
}
|
||||
@ -96,6 +104,11 @@ final class MutablePeerView: MutablePostboxView {
|
||||
} else {
|
||||
self.notificationSettings = postbox.peerNotificationSettingsTable.getEffective(peerId)
|
||||
}
|
||||
if let peer = self.peers[peerId], let additionalAssociatedPeerId = peer.additionalAssociatedPeerId {
|
||||
if let peer = getPeer(additionalAssociatedPeerId) {
|
||||
self.peers[additionalAssociatedPeerId] = peer
|
||||
}
|
||||
}
|
||||
for id in messageIds {
|
||||
if let message = postbox.getMessage(id) {
|
||||
self.messages[id] = message
|
||||
@ -141,8 +154,13 @@ final class MutablePeerView: MutablePostboxView {
|
||||
|
||||
var peerIds = Set<PeerId>()
|
||||
peerIds.insert(self.peerId)
|
||||
if let peer = getPeer(self.peerId), let associatedPeerId = peer.associatedPeerId {
|
||||
peerIds.insert(associatedPeerId)
|
||||
if let peer = getPeer(self.peerId) {
|
||||
if let associatedPeerId = peer.associatedPeerId {
|
||||
peerIds.insert(associatedPeerId)
|
||||
}
|
||||
if let additionalAssociatedPeerId = peer.additionalAssociatedPeerId {
|
||||
peerIds.insert(additionalAssociatedPeerId)
|
||||
}
|
||||
}
|
||||
peerIds.formUnion(cachedData.peerIds)
|
||||
|
||||
@ -186,8 +204,13 @@ final class MutablePeerView: MutablePostboxView {
|
||||
} else {
|
||||
var peerIds = Set<PeerId>()
|
||||
peerIds.insert(self.peerId)
|
||||
if let peer = getPeer(self.peerId), let associatedPeerId = peer.associatedPeerId {
|
||||
peerIds.insert(associatedPeerId)
|
||||
if let peer = getPeer(self.peerId) {
|
||||
if let associatedPeerId = peer.associatedPeerId {
|
||||
peerIds.insert(associatedPeerId)
|
||||
}
|
||||
if let additionalAssociatedPeerId = peer.additionalAssociatedPeerId {
|
||||
peerIds.insert(additionalAssociatedPeerId)
|
||||
}
|
||||
}
|
||||
if let cachedData = self.cachedData {
|
||||
peerIds.formUnion(cachedData.peerIds)
|
||||
|
@ -1285,12 +1285,16 @@ final class ShareControllerNode: ViewControllerTracingNode, ASScrollViewDelegate
|
||||
}
|
||||
)
|
||||
|> take(1)
|
||||
|> map { views -> ([EnginePeer.Id: EnginePeer?], [EnginePeer.Id: Int64]) in
|
||||
var result: [EnginePeer.Id: EnginePeer?] = [:]
|
||||
|> map { views -> ([EnginePeer.Id: EngineRenderedPeer?], [EnginePeer.Id: Int64]) in
|
||||
var result: [EnginePeer.Id: EngineRenderedPeer?] = [:]
|
||||
var requiresStars: [EnginePeer.Id: Int64] = [:]
|
||||
for peerId in peerIds {
|
||||
if let view = views.views[PostboxViewKey.basicPeer(peerId)] as? PeerView, let peer = peerViewMainPeer(view) {
|
||||
result[peerId] = EnginePeer(peer)
|
||||
var peers: [EnginePeer.Id: EnginePeer] = [peer.id: EnginePeer(peer)]
|
||||
if let channel = peer as? TelegramChannel, channel.isMonoForum, let linkedMonoforumId = channel.linkedMonoforumId, let mainChannel = view.peers[linkedMonoforumId] {
|
||||
peers[mainChannel.id] = EnginePeer(mainChannel)
|
||||
}
|
||||
result[peerId] = EngineRenderedPeer(peerId: peer.id, peers: peers, associatedMedia: [:])
|
||||
if peer is TelegramUser, let cachedPeerDataView = views.views[PostboxViewKey.cachedPeerData(peerId: peerId)] as? CachedPeerDataView {
|
||||
if let cachedData = cachedPeerDataView.cachedPeerData as? CachedUserData {
|
||||
requiresStars[peerId] = cachedData.sendPaidMessageStars?.value
|
||||
@ -1307,14 +1311,14 @@ final class ShareControllerNode: ViewControllerTracingNode, ASScrollViewDelegate
|
||||
return
|
||||
}
|
||||
|
||||
var mappedPeers: [EnginePeer] = []
|
||||
var mappedPeers: [EngineRenderedPeer] = []
|
||||
for peerId in peerIds {
|
||||
if let maybePeer = peers[peerId], let peer = maybePeer {
|
||||
mappedPeers.append(peer)
|
||||
}
|
||||
}
|
||||
|
||||
if !tryShare(self.inputFieldNode.text, mappedPeers) {
|
||||
if !tryShare(self.inputFieldNode.text, mappedPeers.compactMap(\.peer)) {
|
||||
return
|
||||
}
|
||||
|
||||
@ -1328,15 +1332,15 @@ final class ShareControllerNode: ViewControllerTracingNode, ASScrollViewDelegate
|
||||
}
|
||||
}
|
||||
|
||||
private func presentPaidMessageAlertIfNeeded(peers: [EnginePeer], requiresStars: [EnginePeer.Id: Int64], completion: @escaping () -> Void) {
|
||||
private func presentPaidMessageAlertIfNeeded(peers: [EngineRenderedPeer], requiresStars: [EnginePeer.Id: Int64], completion: @escaping () -> Void) {
|
||||
var count: Int32 = Int32(self.messageCount)
|
||||
if !self.inputFieldNode.text.isEmpty {
|
||||
count += 1
|
||||
}
|
||||
var chargingPeers: [EnginePeer] = []
|
||||
var chargingPeers: [EngineRenderedPeer] = []
|
||||
var totalAmount: StarsAmount = .zero
|
||||
for peer in peers {
|
||||
if let stars = requiresStars[peer.id] {
|
||||
if let stars = requiresStars[peer.peerId] {
|
||||
chargingPeers.append(peer)
|
||||
totalAmount = totalAmount + StarsAmount(value: stars, nanos: 0)
|
||||
}
|
||||
|
@ -223,6 +223,10 @@ public final class TelegramChannel: Peer, Equatable {
|
||||
}
|
||||
}
|
||||
|
||||
public var additionalAssociatedPeerId: PeerId? {
|
||||
self.linkedMonoforumId
|
||||
}
|
||||
|
||||
public var indexName: PeerIndexNameRepresentation {
|
||||
var addressNames = self.usernames.map { $0.username }
|
||||
if addressNames.isEmpty, let username = self.username, !username.isEmpty {
|
||||
|
@ -422,7 +422,7 @@ public func chatMessagePaymentAlertController(
|
||||
context: AccountContext?,
|
||||
presentationData: PresentationData,
|
||||
updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)?,
|
||||
peers: [EnginePeer],
|
||||
peers: [EngineRenderedPeer],
|
||||
count: Int32,
|
||||
amount: StarsAmount,
|
||||
totalAmount: StarsAmount?,
|
||||
@ -452,10 +452,10 @@ public func chatMessagePaymentAlertController(
|
||||
if peers.count == 1, let peer = peers.first {
|
||||
let amountString = presentationData.strings.Chat_PaidMessage_Confirm_Text_Stars(Int32(amount.value))
|
||||
let totalString = presentationData.strings.Chat_PaidMessage_Confirm_Text_Stars(Int32(amount.value * Int64(count)))
|
||||
if case let .channel(channel) = peer, case .broadcast = channel.info {
|
||||
text = presentationData.strings.Chat_PaidMessage_Confirm_SingleComment_Text(peer.compactDisplayTitle, amountString, totalString, messagesString).string
|
||||
if case let .channel(channel) = peer.chatOrMonoforumMainPeer, case .broadcast = channel.info {
|
||||
text = presentationData.strings.Chat_PaidMessage_Confirm_SingleComment_Text(EnginePeer(channel).compactDisplayTitle, amountString, totalString, messagesString).string
|
||||
} else {
|
||||
text = presentationData.strings.Chat_PaidMessage_Confirm_Single_Text(peer.compactDisplayTitle, amountString, totalString, messagesString).string
|
||||
text = presentationData.strings.Chat_PaidMessage_Confirm_Single_Text(peer.chatOrMonoforumMainPeer?.compactDisplayTitle ?? " ", amountString, totalString, messagesString).string
|
||||
}
|
||||
} else {
|
||||
let amount = totalAmount ?? amount
|
||||
|
@ -537,7 +537,7 @@ private final class PeerInfoScreenPersonalChannelItemNode: PeerInfoScreenItemNod
|
||||
return
|
||||
}
|
||||
|
||||
StoryContainerScreen.openPeerStories(context: item.context, peerId: item.data.peer.id, parentController: controller, avatarNode: itemNode.avatarNode)
|
||||
StoryContainerScreen.openPeerStories(context: item.context, peerId: item.data.peer.peerId, parentController: controller, avatarNode: itemNode.avatarNode)
|
||||
},
|
||||
openStarsTopup: { _ in
|
||||
},
|
||||
@ -565,7 +565,7 @@ private final class PeerInfoScreenPersonalChannelItemNode: PeerInfoScreenItemNod
|
||||
index = EngineChatList.Item.Index.chatList(ChatListIndex(pinningIndex: nil, messageIndex: item.data.topMessages[0].index))
|
||||
messages = item.data.topMessages
|
||||
} else {
|
||||
index = EngineChatList.Item.Index.chatList(ChatListIndex(pinningIndex: nil, messageIndex: MessageIndex(id: MessageId(peerId: item.data.peer.id, namespace: Namespaces.Message.Cloud, id: 1), timestamp: 0)))
|
||||
index = EngineChatList.Item.Index.chatList(ChatListIndex(pinningIndex: nil, messageIndex: MessageIndex(id: MessageId(peerId: item.data.peer.peerId, namespace: Namespaces.Message.Cloud, id: 1), timestamp: 0)))
|
||||
messages = []
|
||||
}
|
||||
|
||||
@ -577,7 +577,7 @@ private final class PeerInfoScreenPersonalChannelItemNode: PeerInfoScreenItemNod
|
||||
index: index,
|
||||
content: .peer(ChatListItemContent.PeerData(
|
||||
messages: messages,
|
||||
peer: EngineRenderedPeer(peer: item.data.peer),
|
||||
peer: item.data.peer,
|
||||
threadInfo: nil,
|
||||
combinedReadState: nil,
|
||||
isRemovedFromTotalUnreadCount: false,
|
||||
|
@ -314,13 +314,13 @@ final class TelegramGlobalSettings {
|
||||
}
|
||||
|
||||
final class PeerInfoPersonalChannelData: Equatable {
|
||||
let peer: EnginePeer
|
||||
let peer: EngineRenderedPeer
|
||||
let subscriberCount: Int?
|
||||
let topMessages: [EngineMessage]
|
||||
let storyStats: PeerStoryStats?
|
||||
let isLoading: Bool
|
||||
|
||||
init(peer: EnginePeer, subscriberCount: Int?, topMessages: [EngineMessage], storyStats: PeerStoryStats?, isLoading: Bool) {
|
||||
init(peer: EngineRenderedPeer, subscriberCount: Int?, topMessages: [EngineMessage], storyStats: PeerStoryStats?, isLoading: Bool) {
|
||||
self.peer = peer
|
||||
self.subscriberCount = subscriberCount
|
||||
self.topMessages = topMessages
|
||||
@ -363,6 +363,7 @@ final class PeerInfoScreenData {
|
||||
let availablePanes: [PeerInfoPaneKey]
|
||||
let groupsInCommon: GroupsInCommonContext?
|
||||
let linkedDiscussionPeer: Peer?
|
||||
let linkedMonoforumPeer: Peer?
|
||||
let members: PeerInfoMembersData?
|
||||
let storyListContext: StoryListContext?
|
||||
let storyArchiveListContext: StoryListContext?
|
||||
@ -413,6 +414,7 @@ final class PeerInfoScreenData {
|
||||
availablePanes: [PeerInfoPaneKey],
|
||||
groupsInCommon: GroupsInCommonContext?,
|
||||
linkedDiscussionPeer: Peer?,
|
||||
linkedMonoforumPeer: Peer?,
|
||||
members: PeerInfoMembersData?,
|
||||
storyListContext: StoryListContext?,
|
||||
storyArchiveListContext: StoryListContext?,
|
||||
@ -451,6 +453,7 @@ final class PeerInfoScreenData {
|
||||
self.availablePanes = availablePanes
|
||||
self.groupsInCommon = groupsInCommon
|
||||
self.linkedDiscussionPeer = linkedDiscussionPeer
|
||||
self.linkedMonoforumPeer = linkedMonoforumPeer
|
||||
self.members = members
|
||||
self.storyListContext = storyListContext
|
||||
self.storyArchiveListContext = storyArchiveListContext
|
||||
@ -663,10 +666,25 @@ public func keepPeerInfoScreenDataHot(context: AccountContext, peerId: PeerId, c
|
||||
}
|
||||
}
|
||||
|
||||
private func peerInfoPersonalChannel(context: AccountContext, peerId: EnginePeer.Id, isSettings: Bool) -> Signal<PeerInfoPersonalChannelData?, NoError> {
|
||||
return context.engine.data.subscribe(
|
||||
TelegramEngine.EngineData.Item.Peer.PersonalChannel(id: peerId)
|
||||
private func peerInfoPersonalOrLinkedChannel(context: AccountContext, peerId: EnginePeer.Id, isSettings: Bool) -> Signal<PeerInfoPersonalChannelData?, NoError> {
|
||||
let personalChannel: Signal<TelegramEngine.EngineData.Item.Peer.PersonalChannel.Result, NoError> = context.engine.data.subscribe(
|
||||
TelegramEngine.EngineData.Item.Peer.Peer(id: peerId)
|
||||
)
|
||||
|> mapToSignal { peer -> Signal<TelegramEngine.EngineData.Item.Peer.PersonalChannel.Result, NoError> in
|
||||
guard let peer else {
|
||||
return .single(.known(nil))
|
||||
}
|
||||
if case .user = peer {
|
||||
return context.engine.data.subscribe(
|
||||
TelegramEngine.EngineData.Item.Peer.PersonalChannel(id: peerId)
|
||||
)
|
||||
} else if case let .channel(channel) = peer, case let .broadcast(info) = channel.info, info.flags.contains(.hasMonoforum), let linkedMonoforumId = channel.linkedMonoforumId {
|
||||
return .single(CachedTelegramPersonalChannel.known(TelegramPersonalChannel(peerId: linkedMonoforumId, subscriberCount: nil, topMessageId: nil)))
|
||||
}
|
||||
return .single(.known(nil))
|
||||
}
|
||||
|
||||
return personalChannel
|
||||
|> distinctUntilChanged
|
||||
|> mapToSignal { personalChannel -> Signal<PeerInfoPersonalChannelData?, NoError> in
|
||||
guard case let .known(personalChannelValue) = personalChannel, let personalChannelValue else {
|
||||
@ -674,15 +692,14 @@ private func peerInfoPersonalChannel(context: AccountContext, peerId: EnginePeer
|
||||
}
|
||||
|
||||
return context.engine.data.subscribe(
|
||||
TelegramEngine.EngineData.Item.Peer.Peer(id: personalChannelValue.peerId),
|
||||
TelegramEngine.EngineData.Item.Peer.RenderedPeer(id: personalChannelValue.peerId),
|
||||
TelegramEngine.EngineData.Item.Peer.ParticipantCount(id: personalChannelValue.peerId)
|
||||
)
|
||||
|> mapToSignal { channelPeer, participantCount -> Signal<PeerInfoPersonalChannelData?, NoError> in
|
||||
guard let channelPeer else {
|
||||
|> mapToSignal { channelRenderedPeer, participantCount -> Signal<PeerInfoPersonalChannelData?, NoError> in
|
||||
guard let channelRenderedPeer, let channelPeer = channelRenderedPeer.peer else {
|
||||
return .single(nil)
|
||||
}
|
||||
|
||||
|
||||
let polledChannel: Signal<Void, NoError> = Signal<Void, NoError>.single(Void())
|
||||
|> then(
|
||||
context.account.viewTracker.polledChannel(peerId: channelPeer.id)
|
||||
@ -723,7 +740,7 @@ private func peerInfoPersonalChannel(context: AccountContext, peerId: EnginePeer
|
||||
}
|
||||
|
||||
return PeerInfoPersonalChannelData(
|
||||
peer: channelPeer,
|
||||
peer: channelRenderedPeer,
|
||||
subscriberCount: mappedParticipantCount,
|
||||
topMessages: messages,
|
||||
storyStats: storyStats,
|
||||
@ -862,7 +879,7 @@ func peerInfoScreenSettingsData(context: AccountContext, peerId: EnginePeer.Id,
|
||||
|> distinctUntilChanged,
|
||||
hasStories,
|
||||
bots,
|
||||
peerInfoPersonalChannel(context: context, peerId: peerId, isSettings: true),
|
||||
peerInfoPersonalOrLinkedChannel(context: context, peerId: peerId, isSettings: true),
|
||||
starsState
|
||||
)
|
||||
|> map { peerView, accountsAndPeers, accountSessions, privacySettings, sharedPreferences, notifications, stickerPacks, hasPassport, hasWatchApp, accountPreferences, suggestions, limits, hasPassword, isPowerSavingEnabled, hasStories, bots, personalChannel, starsState -> PeerInfoScreenData in
|
||||
@ -925,6 +942,7 @@ func peerInfoScreenSettingsData(context: AccountContext, peerId: EnginePeer.Id,
|
||||
availablePanes: [],
|
||||
groupsInCommon: nil,
|
||||
linkedDiscussionPeer: nil,
|
||||
linkedMonoforumPeer: nil,
|
||||
members: nil,
|
||||
storyListContext: hasStories == true ? storyListContext : nil,
|
||||
storyArchiveListContext: nil,
|
||||
@ -974,6 +992,7 @@ func peerInfoScreenData(context: AccountContext, peerId: PeerId, strings: Presen
|
||||
availablePanes: [],
|
||||
groupsInCommon: nil,
|
||||
linkedDiscussionPeer: nil,
|
||||
linkedMonoforumPeer: nil,
|
||||
members: nil,
|
||||
storyListContext: nil,
|
||||
storyArchiveListContext: nil,
|
||||
@ -1325,7 +1344,7 @@ func peerInfoScreenData(context: AccountContext, peerId: PeerId, strings: Presen
|
||||
hasSavedMessages,
|
||||
hasSavedMessageTags,
|
||||
hasBotPreviewItems,
|
||||
peerInfoPersonalChannel(context: context, peerId: peerId, isSettings: false),
|
||||
peerInfoPersonalOrLinkedChannel(context: context, peerId: peerId, isSettings: false),
|
||||
privacySettings,
|
||||
starsRevenueContextAndState,
|
||||
revenueContextAndState,
|
||||
@ -1432,6 +1451,7 @@ func peerInfoScreenData(context: AccountContext, peerId: PeerId, strings: Presen
|
||||
availablePanes: availablePanes ?? [],
|
||||
groupsInCommon: groupsInCommon,
|
||||
linkedDiscussionPeer: nil,
|
||||
linkedMonoforumPeer: nil,
|
||||
members: nil,
|
||||
storyListContext: storyListContext,
|
||||
storyArchiveListContext: storyArchiveListContext,
|
||||
@ -1564,6 +1584,8 @@ func peerInfoScreenData(context: AccountContext, peerId: PeerId, strings: Presen
|
||||
|
||||
let profileGiftsContext = ProfileGiftsContext(account: context.account, peerId: peerId)
|
||||
|
||||
let personalChannel = peerInfoPersonalOrLinkedChannel(context: context, peerId: peerId, isSettings: false)
|
||||
|
||||
return combineLatest(
|
||||
context.account.viewTracker.peerView(peerId, updateData: true),
|
||||
peerInfoAvailableMediaPanes(context: context, peerId: peerId, chatLocation: chatLocation, isMyProfile: false, chatLocationContextHolder: chatLocationContextHolder),
|
||||
@ -1582,9 +1604,10 @@ func peerInfoScreenData(context: AccountContext, peerId: PeerId, strings: Presen
|
||||
isPremiumRequiredForStoryPosting,
|
||||
starsRevenueContextAndState,
|
||||
revenueContextAndState,
|
||||
profileGiftsContext.state
|
||||
profileGiftsContext.state,
|
||||
personalChannel
|
||||
)
|
||||
|> map { peerView, availablePanes, globalNotificationSettings, status, currentInvitationsContext, invitations, currentRequestsContext, requests, hasStories, accountIsPremium, recommendedChannels, hasSavedMessages, hasSavedMessagesChats, hasSavedMessageTags, isPremiumRequiredForStoryPosting, starsRevenueContextAndState, revenueContextAndState, profileGiftsState -> PeerInfoScreenData in
|
||||
|> map { peerView, availablePanes, globalNotificationSettings, status, currentInvitationsContext, invitations, currentRequestsContext, requests, hasStories, accountIsPremium, recommendedChannels, hasSavedMessages, hasSavedMessagesChats, hasSavedMessageTags, isPremiumRequiredForStoryPosting, starsRevenueContextAndState, revenueContextAndState, profileGiftsState, personalChannel -> PeerInfoScreenData in
|
||||
var availablePanes = availablePanes
|
||||
if let hasStories {
|
||||
if hasStories {
|
||||
@ -1621,6 +1644,11 @@ func peerInfoScreenData(context: AccountContext, peerId: PeerId, strings: Presen
|
||||
discussionPeer = peer
|
||||
}
|
||||
|
||||
var monoforumPeer: Peer?
|
||||
if let channel = peerViewMainPeer(peerView) as? TelegramChannel, case let .broadcast(info) = channel.info, info.flags.contains(.hasMonoforum), let linkedMonoforumId = channel.linkedMonoforumId {
|
||||
monoforumPeer = peerView.peers[linkedMonoforumId]
|
||||
}
|
||||
|
||||
var canManageInvitations = false
|
||||
if let channel = peerViewMainPeer(peerView) as? TelegramChannel, let _ = peerView.cachedData as? CachedChannelData, channel.flags.contains(.isCreator) || (channel.adminRights?.rights.contains(.canInviteUsers) == true) {
|
||||
canManageInvitations = true
|
||||
@ -1654,6 +1682,7 @@ func peerInfoScreenData(context: AccountContext, peerId: PeerId, strings: Presen
|
||||
availablePanes: availablePanes ?? [],
|
||||
groupsInCommon: nil,
|
||||
linkedDiscussionPeer: discussionPeer,
|
||||
linkedMonoforumPeer: monoforumPeer,
|
||||
members: nil,
|
||||
storyListContext: storyListContext,
|
||||
storyArchiveListContext: nil,
|
||||
@ -1670,7 +1699,7 @@ func peerInfoScreenData(context: AccountContext, peerId: PeerId, strings: Presen
|
||||
hasSavedMessageTags: hasSavedMessageTags,
|
||||
hasBotPreviewItems: false,
|
||||
isPremiumRequiredForStoryPosting: isPremiumRequiredForStoryPosting,
|
||||
personalChannel: nil,
|
||||
personalChannel: personalChannel,
|
||||
starsState: nil,
|
||||
starsRevenueStatsState: starsRevenueContextAndState.1,
|
||||
starsRevenueStatsContext: starsRevenueContextAndState.0,
|
||||
@ -1903,6 +1932,11 @@ func peerInfoScreenData(context: AccountContext, peerId: PeerId, strings: Presen
|
||||
if case let .known(maybeLinkedDiscussionPeerId) = (peerView.cachedData as? CachedChannelData)?.linkedDiscussionPeerId, let linkedDiscussionPeerId = maybeLinkedDiscussionPeerId, let peer = peerView.peers[linkedDiscussionPeerId] {
|
||||
discussionPeer = peer
|
||||
}
|
||||
|
||||
var monoforumPeer: Peer?
|
||||
if let channel = peerViewMainPeer(peerView) as? TelegramChannel, case let .broadcast(info) = channel.info, info.flags.contains(.hasMonoforum), let linkedMonoforumId = channel.linkedMonoforumId {
|
||||
monoforumPeer = peerView.peers[linkedMonoforumId]
|
||||
}
|
||||
|
||||
var availablePanes = availablePanes
|
||||
if let membersData = membersData, case .longList = membersData {
|
||||
@ -1980,6 +2014,7 @@ func peerInfoScreenData(context: AccountContext, peerId: PeerId, strings: Presen
|
||||
availablePanes: availablePanes ?? [],
|
||||
groupsInCommon: nil,
|
||||
linkedDiscussionPeer: discussionPeer,
|
||||
linkedMonoforumPeer: monoforumPeer,
|
||||
members: membersData,
|
||||
storyListContext: storyListContext,
|
||||
storyArchiveListContext: nil,
|
||||
|
@ -1197,8 +1197,8 @@ private func settingsEditingItems(data: PeerInfoScreenData?, state: PeerInfoStat
|
||||
}
|
||||
if displayPersonalChannel {
|
||||
var personalChannelTitle: String?
|
||||
if let personalChannel = data.personalChannel {
|
||||
personalChannelTitle = personalChannel.peer.compactDisplayTitle
|
||||
if let personalChannel = data.personalChannel, let peer = personalChannel.peer.chatOrMonoforumMainPeer {
|
||||
personalChannelTitle = peer.compactDisplayTitle
|
||||
}
|
||||
|
||||
items[.info]!.append(PeerInfoScreenDisclosureItem(id: ItemPeerPersonalChannel, label: .text(personalChannelTitle ?? presentationData.strings.Settings_PersonalChannelEmptyValue), text: presentationData.strings.Settings_PersonalChannelItem, icon: nil, action: {
|
||||
@ -1288,7 +1288,7 @@ private func infoItems(data: PeerInfoScreenData?, context: AccountContext, prese
|
||||
}
|
||||
|
||||
if let personalChannel = data.personalChannel {
|
||||
let peerId = personalChannel.peer.id
|
||||
let peerId = personalChannel.peer.peerId
|
||||
var label: String?
|
||||
if let subscriberCount = personalChannel.subscriberCount {
|
||||
label = presentationData.strings.Conversation_StatusSubscribers(Int32(subscriberCount))
|
||||
@ -2024,6 +2024,7 @@ private func editingItems(data: PeerInfoScreenData?, boostStatus: ChannelBoostSt
|
||||
case peerDataSettings
|
||||
case peerVerifySettings
|
||||
case peerSettings
|
||||
case linkedMonoforum
|
||||
case peerAdditionalSettings
|
||||
case peerActions
|
||||
}
|
||||
@ -2218,10 +2219,6 @@ private func editingItems(data: PeerInfoScreenData?, boostStatus: ChannelBoostSt
|
||||
items[.peerSettings]!.append(PeerInfoScreenDisclosureItem(id: ItemDiscussionGroup, label: .text(discussionGroupTitle), text: presentationData.strings.Channel_DiscussionGroup, icon: UIImage(bundleImageName: "Chat/Info/GroupDiscussionIcon"), action: {
|
||||
interaction.editingOpenDiscussionGroupSetup()
|
||||
}))
|
||||
|
||||
items[.peerSettings]!.append(PeerInfoScreenDisclosureItem(id: ItemPostSuggestionsSettings, label: .text(channel.linkedMonoforumId == nil ? presentationData.strings.PeerInfo_AllowChannelMessages_Off : presentationData.strings.PeerInfo_AllowChannelMessages_On), additionalBadgeLabel: presentationData.strings.Settings_New, text: presentationData.strings.PeerInfo_AllowChannelMessages, icon: PresentationResourcesSettings.channelMessages, action: {
|
||||
interaction.editingOpenPostSuggestionsSetup()
|
||||
}))
|
||||
}
|
||||
|
||||
if isCreator || (channel.adminRights?.rights.contains(.canChangeInfo) == true) {
|
||||
@ -2266,7 +2263,7 @@ private func editingItems(data: PeerInfoScreenData?, boostStatus: ChannelBoostSt
|
||||
if let approximateBoostLevel = channel.approximateBoostLevel, approximateBoostLevel < 1 {
|
||||
boostIcon = generateDisclosureActionBoostLevelBadgeImage(text: presentationData.strings.Channel_Info_BoostLevelPlusBadge("1").string)
|
||||
} else {
|
||||
let labelText = NSAttributedString(string: presentationData.strings.Settings_New, font: Font.medium(11.0), textColor: presentationData.theme.list.itemCheckColors.foregroundColor)
|
||||
/*let labelText = NSAttributedString(string: presentationData.strings.Settings_New, font: Font.medium(11.0), textColor: presentationData.theme.list.itemCheckColors.foregroundColor)
|
||||
let labelBounds = labelText.boundingRect(with: CGSize(width: 100.0, height: 100.0), options: [.usesLineFragmentOrigin], context: nil)
|
||||
let labelSize = CGSize(width: ceil(labelBounds.width), height: ceil(labelBounds.height))
|
||||
let badgeSize = CGSize(width: labelSize.width + 8.0, height: labelSize.height + 2.0 + 1.0)
|
||||
@ -2282,7 +2279,7 @@ private func editingItems(data: PeerInfoScreenData?, boostStatus: ChannelBoostSt
|
||||
UIGraphicsPushContext(context)
|
||||
labelText.draw(at: CGPoint(x: 4.0, y: 1.0 + UIScreenPixel))
|
||||
UIGraphicsPopContext()
|
||||
})
|
||||
})*/
|
||||
}
|
||||
items[.peerSettings]!.append(PeerInfoScreenDisclosureItem(id: ItemPeerColor, label: .image(colorImage, colorImage.size), additionalBadgeIcon: boostIcon, text: presentationData.strings.Channel_Info_AppearanceItem, icon: UIImage(bundleImageName: "Chat/Info/NameColorIcon"), action: {
|
||||
interaction.editingOpenNameColorSetup()
|
||||
@ -2302,6 +2299,62 @@ private func editingItems(data: PeerInfoScreenData?, boostStatus: ChannelBoostSt
|
||||
}))
|
||||
}
|
||||
|
||||
if isCreator || (channel.adminRights?.rights.contains(.canChangeInfo) == true) {
|
||||
let labelString: NSAttributedString
|
||||
if channel.linkedMonoforumId != nil {
|
||||
if let monoforumPeer = data.linkedMonoforumPeer as? TelegramChannel {
|
||||
if let sendPaidMessageStars = monoforumPeer.sendPaidMessageStars {
|
||||
let formattedLabel = formatStarsAmountText(sendPaidMessageStars, dateTimeFormat: presentationData.dateTimeFormat)
|
||||
let smallLabelFont = Font.regular(floor(presentationData.listsFontSize.itemListBaseFontSize / 17.0 * 13.0))
|
||||
let labelFont = Font.regular(presentationData.listsFontSize.itemListBaseFontSize)
|
||||
let labelColor = presentationData.theme.list.itemSecondaryTextColor
|
||||
let attributedString = tonAmountAttributedString(formattedLabel, integralFont: labelFont, fractionalFont: smallLabelFont, color: labelColor, decimalSeparator: presentationData.dateTimeFormat.decimalSeparator).mutableCopy() as! NSMutableAttributedString
|
||||
attributedString.insert(NSAttributedString(string: "*", font: labelFont, textColor: labelColor), at: 0)
|
||||
|
||||
if let range = attributedString.string.range(of: "*") {
|
||||
attributedString.addAttribute(ChatTextInputAttributes.customEmoji, value: ChatTextInputTextCustomEmojiAttribute(interactivelySelectedFromPackId: nil, fileId: 0, file: nil, custom: .stars(tinted: false)), range: NSRange(range, in: attributedString.string))
|
||||
attributedString.addAttribute(.baselineOffset, value: 1.5, range: NSRange(range, in: attributedString.string))
|
||||
}
|
||||
labelString = attributedString
|
||||
} else {
|
||||
let labelFont = Font.regular(presentationData.listsFontSize.itemListBaseFontSize)
|
||||
let labelColor = presentationData.theme.list.itemSecondaryTextColor
|
||||
|
||||
labelString = NSAttributedString(string: presentationData.strings.PeerInfo_AllowChannelMessages_Free, font: labelFont, textColor: labelColor)
|
||||
}
|
||||
} else {
|
||||
let labelFont = Font.regular(presentationData.listsFontSize.itemListBaseFontSize)
|
||||
let labelColor = presentationData.theme.list.itemSecondaryTextColor
|
||||
|
||||
labelString = NSAttributedString(string: " ", font: labelFont, textColor: labelColor)
|
||||
}
|
||||
} else {
|
||||
let labelFont = Font.regular(presentationData.listsFontSize.itemListBaseFontSize)
|
||||
let labelColor = presentationData.theme.list.itemSecondaryTextColor
|
||||
|
||||
labelString = NSAttributedString(string: presentationData.strings.PeerInfo_AllowChannelMessages_Off, font: labelFont, textColor: labelColor)
|
||||
}
|
||||
|
||||
items[.peerSettings]!.append(PeerInfoScreenDisclosureItem(id: ItemPostSuggestionsSettings, label: .attributedText(labelString), additionalBadgeLabel: presentationData.strings.Settings_New, text: presentationData.strings.PeerInfo_AllowChannelMessages, icon: PresentationResourcesSettings.channelMessages, action: {
|
||||
interaction.editingOpenPostSuggestionsSetup()
|
||||
}))
|
||||
|
||||
if let personalChannel = data.personalChannel {
|
||||
let peerId = personalChannel.peer.peerId
|
||||
items[.linkedMonoforum]?.append(PeerInfoScreenPersonalChannelItem(id: 1, context: context, data: personalChannel, controller: { [weak interaction] in
|
||||
guard let interaction else {
|
||||
return nil
|
||||
}
|
||||
return interaction.getController()
|
||||
}, action: { [weak interaction] in
|
||||
guard let interaction else {
|
||||
return
|
||||
}
|
||||
interaction.openChat(peerId)
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
var canEditMembers = false
|
||||
if channel.hasPermission(.banMembers) && (channel.adminRights != nil || channel.flags.contains(.isCreator)) {
|
||||
canEditMembers = true
|
||||
|
@ -267,14 +267,14 @@ private final class SendInviteLinkScreenComponent: Component {
|
||||
}
|
||||
}
|
||||
|
||||
private func presentPaidMessageAlertIfNeeded(peers: [EnginePeer], requiresStars: [EnginePeer.Id: StarsAmount], completion: @escaping () -> Void) {
|
||||
private func presentPaidMessageAlertIfNeeded(peers: [EngineRenderedPeer], requiresStars: [EnginePeer.Id: StarsAmount], completion: @escaping () -> Void) {
|
||||
guard let component = self.component else {
|
||||
completion()
|
||||
return
|
||||
}
|
||||
var totalAmount: StarsAmount = .zero
|
||||
for peer in peers {
|
||||
if let amount = requiresStars[peer.id] {
|
||||
if let amount = requiresStars[peer.peerId] {
|
||||
totalAmount = totalAmount + amount
|
||||
}
|
||||
}
|
||||
@ -968,7 +968,7 @@ private final class SendInviteLinkScreenComponent: Component {
|
||||
let selectedPeers = component.peers.filter { self.selectedItems.contains($0.peer.id) }
|
||||
|
||||
self.presentPaidMessageAlertIfNeeded(
|
||||
peers: selectedPeers.map { $0.peer },
|
||||
peers: selectedPeers.map { EngineRenderedPeer(peer: $0.peer) },
|
||||
requiresStars: component.sendPaidMessageStars,
|
||||
completion: { [weak self] in
|
||||
guard let self, let component = self.component, let controller = self.environment?.controller() else {
|
||||
|
@ -151,16 +151,10 @@ private final class SheetContent: CombinedComponent {
|
||||
|
||||
minAmount = StarsAmount(value: resaleConfiguration.starGiftResaleMinAmount, nanos: 0)
|
||||
maxAmount = StarsAmount(value: resaleConfiguration.starGiftResaleMaxAmount, nanos: 0)
|
||||
case let .paidMessages(_, minAmountValue, _, kind):
|
||||
//TODO:localize
|
||||
switch kind {
|
||||
case .privacy:
|
||||
titleString = "Price per Message"
|
||||
case .postSuggestion:
|
||||
titleString = "Price for each Suggestion"
|
||||
}
|
||||
amountTitle = "PRICE IN STARS"
|
||||
amountPlaceholder = "Enter Price"
|
||||
case let .paidMessages(_, minAmountValue, _, _):
|
||||
titleString = environment.strings.Stars_SendMessage_AdjustmentTitle
|
||||
amountTitle = environment.strings.Stars_SendMessage_AdjustmentSectionHeader
|
||||
amountPlaceholder = environment.strings.Stars_SendMessage_AdjustmentPlaceholder
|
||||
|
||||
minAmount = StarsAmount(value: minAmountValue, nanos: 0)
|
||||
maxAmount = StarsAmount(value: resaleConfiguration.paidMessageMaxAmount, nanos: 0)
|
||||
@ -299,9 +293,9 @@ private final class SheetContent: CombinedComponent {
|
||||
if let value = state.amount?.value, value > 0 {
|
||||
let fullValue: Int64 = Int64(value) * 1_000_000_000 * Int64(fractionAfterCommission) / 100
|
||||
let amountValue = StarsAmount(value: fullValue / 1_000_000_000, nanos: Int32(fullValue % 1_000_000_000))
|
||||
amountInfoString = NSAttributedString(attributedString: parseMarkdownIntoAttributedString("You will receive **\(amountValue) Stars**.", attributes: amountMarkdownAttributes, textAlignment: .natural))
|
||||
amountInfoString = NSAttributedString(attributedString: parseMarkdownIntoAttributedString(environment.strings.Stars_SendMessage_AdjustmentSectionFooterValue("\(amountValue)").string, attributes: amountMarkdownAttributes, textAlignment: .natural))
|
||||
} else {
|
||||
amountInfoString = NSAttributedString(attributedString: parseMarkdownIntoAttributedString("You will receive **80%**.", attributes: amountMarkdownAttributes, textAlignment: .natural))
|
||||
amountInfoString = NSAttributedString(attributedString: parseMarkdownIntoAttributedString(environment.strings.Stars_SendMessage_AdjustmentSectionFooterEmpty, attributes: amountMarkdownAttributes, textAlignment: .natural))
|
||||
}
|
||||
amountFooter = AnyComponent(MultilineTextComponent(
|
||||
text: .plain(amountInfoString),
|
||||
@ -376,8 +370,7 @@ private final class SheetContent: CombinedComponent {
|
||||
buttonString = environment.strings.Stars_SellGift_Sell
|
||||
}
|
||||
} else if case .paidMessages = component.mode {
|
||||
//TODO:localize
|
||||
buttonString = "OK"
|
||||
buttonString = environment.strings.Stars_SendMessage_AdjustmentAction
|
||||
} else if let amount = state.amount {
|
||||
buttonString = "\(environment.strings.Stars_Withdraw_Withdraw) # \(presentationStringsFormattedNumber(amount, environment.dateTimeFormat.groupingSeparator))"
|
||||
} else {
|
||||
@ -672,6 +665,7 @@ public final class StarsWithdrawScreen: ViewControllerComponentContainer {
|
||||
let presentationData = self.context.sharedContext.currentPresentationData.with { $0 }
|
||||
var text = presentationData.strings.Stars_Withdraw_Withdraw_ErrorMinimum(presentationData.strings.Stars_Withdraw_Withdraw_ErrorMinimum_Stars(Int32(minAmount))).string
|
||||
if case .starGiftResell = self.mode {
|
||||
//TODO:localize
|
||||
text = "You cannot sell gift for less than \(presentationData.strings.Stars_Withdraw_Withdraw_ErrorMinimum_Stars(Int32(minAmount)))."
|
||||
}
|
||||
|
||||
|
@ -504,7 +504,7 @@ final class StoryItemSetContainerSendMessage {
|
||||
context: component.context,
|
||||
presentationData: presentationData,
|
||||
updatedPresentationData: nil,
|
||||
peers: [component.slice.effectivePeer],
|
||||
peers: [EngineRenderedPeer(peer: component.slice.effectivePeer)],
|
||||
count: 1,
|
||||
amount: sendPaidMessageStars,
|
||||
totalAmount: nil,
|
||||
|
@ -20,6 +20,9 @@ extension ChatControllerImpl {
|
||||
completion(false)
|
||||
return
|
||||
}
|
||||
guard let renderedPeer = self.presentationInterfaceState.renderedPeer.flatMap(EngineRenderedPeer.init) else {
|
||||
return
|
||||
}
|
||||
if let sendPaidMessageStars = self.presentationInterfaceState.sendPaidMessageStars, self.presentationInterfaceState.interfaceState.editMessage == nil {
|
||||
let totalAmount = sendPaidMessageStars.value * Int64(count)
|
||||
|
||||
@ -42,14 +45,16 @@ extension ChatControllerImpl {
|
||||
presentationData = presentationData.withUpdated(theme: defaultDarkColorPresentationTheme)
|
||||
}
|
||||
var peer = peer
|
||||
var renderedPeer = renderedPeer
|
||||
if let peerDiscussionId = self.presentationInterfaceState.peerDiscussionId, let channel = self.contentData?.state.peerView?.peers[peerDiscussionId] {
|
||||
peer = EnginePeer(channel)
|
||||
renderedPeer = EngineRenderedPeer(peer: peer)
|
||||
}
|
||||
let controller = chatMessagePaymentAlertController(
|
||||
context: self.context,
|
||||
presentationData: presentationData,
|
||||
updatedPresentationData: nil,
|
||||
peers: [peer],
|
||||
peers: [renderedPeer],
|
||||
count: count,
|
||||
amount: sendPaidMessageStars,
|
||||
totalAmount: nil,
|
||||
|
@ -100,20 +100,25 @@ extension ChatControllerImpl {
|
||||
let _ = (context.engine.data.get(
|
||||
EngineDataMap(
|
||||
peerIds.map(TelegramEngine.EngineData.Item.Peer.SendPaidMessageStars.init(id:))
|
||||
),
|
||||
EngineDataList(
|
||||
peerIds.map(TelegramEngine.EngineData.Item.Peer.RenderedPeer.init(id:))
|
||||
)
|
||||
)
|
||||
|> deliverOnMainQueue).start(next: { [weak self, weak controller] sendPaidMessageStars in
|
||||
|> deliverOnMainQueue).start(next: { [weak self, weak controller] sendPaidMessageStars, renderedPeers in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
let renderedPeers = renderedPeers.compactMap({ $0 })
|
||||
|
||||
var count: Int32 = Int32(messages.count)
|
||||
if messageText.string.count > 0 {
|
||||
count += 1
|
||||
}
|
||||
var totalAmount: StarsAmount = .zero
|
||||
var chargingPeers: [EnginePeer] = []
|
||||
for peer in peers {
|
||||
if let maybeAmount = sendPaidMessageStars[peer.id], let amount = maybeAmount {
|
||||
var chargingPeers: [EngineRenderedPeer] = []
|
||||
for peer in renderedPeers {
|
||||
if let maybeAmount = sendPaidMessageStars[peer.peerId], let amount = maybeAmount {
|
||||
totalAmount = totalAmount + amount
|
||||
chargingPeers.append(peer)
|
||||
}
|
||||
|
@ -398,6 +398,7 @@ class ChatControllerNode: ASDisplayNode, ASScrollViewDelegate {
|
||||
} else {
|
||||
self.loadingPlaceholderNode = nil
|
||||
loadingPlaceholderNode.removeFromSupernode()
|
||||
self.backgroundNode.updateIsLooping(false)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@ -1433,7 +1434,7 @@ class ChatControllerNode: ASDisplayNode, ASScrollViewDelegate {
|
||||
translationPanelNode.clipsToBounds = true
|
||||
}
|
||||
|
||||
let height = translationPanelNode.updateLayout(width: layout.size.width, leftInset: leftPanelSize?.width ?? layout.safeInsets.left, rightInset: layout.safeInsets.right, transition: immediatelyLayoutTitleAccessoryPanelNodeAndAnimateAppearance ? .immediate : transition, interfaceState: self.chatPresentationInterfaceState)
|
||||
let height = translationPanelNode.updateLayout(width: layout.size.width, leftInset: leftPanelSize?.width ?? layout.safeInsets.left, rightInset: layout.safeInsets.right, leftDisplayInset: leftPanelSize?.width ?? 0.0, transition: immediatelyLayoutTitleAccessoryPanelNodeAndAnimateAppearance ? .immediate : transition, interfaceState: self.chatPresentationInterfaceState)
|
||||
translationPanelHeight = height
|
||||
if immediatelyLayoutTranslationPanelNodeAndAnimateAppearance {
|
||||
translationPanelNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2)
|
||||
|
@ -82,7 +82,7 @@ final class ChatTranslationPanelNode: ASDisplayNode {
|
||||
self.layer.animateBounds(from: self.bounds, to: self.bounds.offsetBy(dx: 0.0, dy: self.bounds.size.height), duration: 0.4, timingFunction: kCAMediaTimingFunctionSpring, removeOnCompletion: false)
|
||||
}
|
||||
|
||||
func updateLayout(width: CGFloat, leftInset: CGFloat, rightInset: CGFloat, transition: ContainedViewLayoutTransition, interfaceState: ChatPresentationInterfaceState) -> CGFloat {
|
||||
func updateLayout(width: CGFloat, leftInset: CGFloat, rightInset: CGFloat, leftDisplayInset: CGFloat, transition: ContainedViewLayoutTransition, interfaceState: ChatPresentationInterfaceState) -> CGFloat {
|
||||
let previousIsEnabled = self.chatInterfaceState?.translationState?.isEnabled
|
||||
self.chatInterfaceState = interfaceState
|
||||
|
||||
@ -176,7 +176,7 @@ final class ChatTranslationPanelNode: ASDisplayNode {
|
||||
self.buttonTextNode.bounds = CGRect(origin: CGPoint(), size: buttonTextFrame.size)
|
||||
}
|
||||
|
||||
transition.updateFrame(node: self.separatorNode, frame: CGRect(origin: CGPoint(x: 0.0, y: 0.0), size: CGSize(width: width, height: UIScreenPixel)))
|
||||
transition.updateFrame(node: self.separatorNode, frame: CGRect(origin: CGPoint(x: leftDisplayInset, y: 0.0), size: CGSize(width: width - leftDisplayInset, height: UIScreenPixel)))
|
||||
|
||||
return panelHeight
|
||||
}
|
||||
|
@ -431,16 +431,20 @@ public final class WebAppMessagePreviewScreen: ViewControllerComponentContainer
|
||||
let _ = (self.context.engine.data.get(
|
||||
EngineDataMap(
|
||||
peers.map { TelegramEngine.EngineData.Item.Peer.SendPaidMessageStars.init(id: $0.id) }
|
||||
),
|
||||
EngineDataList(
|
||||
peers.map { TelegramEngine.EngineData.Item.Peer.RenderedPeer.init(id: $0.id) }
|
||||
)
|
||||
)
|
||||
|> deliverOnMainQueue).start(next: { [weak self] sendPaidMessageStars in
|
||||
|> deliverOnMainQueue).start(next: { [weak self] sendPaidMessageStars, renderedPeers in
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
let renderedPeers = renderedPeers.compactMap({ $0 })
|
||||
var totalAmount: StarsAmount = .zero
|
||||
var chargingPeers: [EnginePeer] = []
|
||||
for peer in peers {
|
||||
if let maybeAmount = sendPaidMessageStars[peer.id], let amount = maybeAmount {
|
||||
var chargingPeers: [EngineRenderedPeer] = []
|
||||
for peer in renderedPeers {
|
||||
if let maybeAmount = sendPaidMessageStars[peer.peerId], let amount = maybeAmount {
|
||||
totalAmount = totalAmount + amount
|
||||
chargingPeers.append(peer)
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user