mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-08-08 08:31:13 +00:00
Suggested posts
This commit is contained in:
parent
f1b98f6dd8
commit
0a30a0ee56
@ -1034,6 +1034,7 @@ public enum StarsWithdrawalScreenSubject {
|
|||||||
case withdraw(completion: (Int64) -> Void)
|
case withdraw(completion: (Int64) -> Void)
|
||||||
case enterAmount(current: StarsAmount, minValue: StarsAmount, fractionAfterCommission: Int, kind: PaidMessageKind, completion: (Int64) -> Void)
|
case enterAmount(current: StarsAmount, minValue: StarsAmount, fractionAfterCommission: Int, kind: PaidMessageKind, completion: (Int64) -> Void)
|
||||||
case postSuggestion(channel: EnginePeer, current: StarsAmount, timestamp: Int32?, completion: (Int64, Int32?) -> Void)
|
case postSuggestion(channel: EnginePeer, current: StarsAmount, timestamp: Int32?, completion: (Int64, Int32?) -> Void)
|
||||||
|
case postSuggestionModification(current: StarsAmount, timestamp: Int32?, completion: (Int64, Int32?) -> Void)
|
||||||
}
|
}
|
||||||
|
|
||||||
public protocol SharedAccountContext: AnyObject {
|
public protocol SharedAccountContext: AnyObject {
|
||||||
|
@ -189,7 +189,7 @@ private final class PromptAlertContentNode: AlertContentNode {
|
|||||||
return self.isUserInteractionEnabled
|
return self.isUserInteractionEnabled
|
||||||
}
|
}
|
||||||
|
|
||||||
init(theme: AlertControllerTheme, ptheme: PresentationTheme, strings: PresentationStrings, actions: [TextAlertAction], text: String, titleFont: PromptControllerTitleFont, value: String?, characterLimit: Int) {
|
init(theme: AlertControllerTheme, ptheme: PresentationTheme, strings: PresentationStrings, actions: [TextAlertAction], text: String, titleFont: PromptControllerTitleFont, value: String?, placeholder: String?, characterLimit: Int) {
|
||||||
self.strings = strings
|
self.strings = strings
|
||||||
self.text = text
|
self.text = text
|
||||||
self.titleFont = titleFont
|
self.titleFont = titleFont
|
||||||
@ -197,7 +197,7 @@ private final class PromptAlertContentNode: AlertContentNode {
|
|||||||
self.textNode = ASTextNode()
|
self.textNode = ASTextNode()
|
||||||
self.textNode.maximumNumberOfLines = 2
|
self.textNode.maximumNumberOfLines = 2
|
||||||
|
|
||||||
self.inputFieldNode = PromptInputFieldNode(theme: ptheme, placeholder: "", characterLimit: characterLimit)
|
self.inputFieldNode = PromptInputFieldNode(theme: ptheme, placeholder: placeholder ?? "", characterLimit: characterLimit)
|
||||||
self.inputFieldNode.text = value ?? ""
|
self.inputFieldNode.text = value ?? ""
|
||||||
|
|
||||||
self.actionNodesSeparator = ASDisplayNode()
|
self.actionNodesSeparator = ASDisplayNode()
|
||||||
@ -407,7 +407,7 @@ public enum PromptControllerTitleFont {
|
|||||||
case bold
|
case bold
|
||||||
}
|
}
|
||||||
|
|
||||||
public func promptController(sharedContext: SharedAccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)? = nil, text: String, titleFont: PromptControllerTitleFont = .regular, value: String?, characterLimit: Int = 1000, apply: @escaping (String?) -> Void) -> AlertController {
|
public func promptController(sharedContext: SharedAccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)? = nil, text: String, titleFont: PromptControllerTitleFont = .regular, value: String?, placeholder: String? = nil, characterLimit: Int = 1000, apply: @escaping (String?) -> Void) -> AlertController {
|
||||||
let presentationData = updatedPresentationData?.initial ?? sharedContext.currentPresentationData.with { $0 }
|
let presentationData = updatedPresentationData?.initial ?? sharedContext.currentPresentationData.with { $0 }
|
||||||
|
|
||||||
var dismissImpl: ((Bool) -> Void)?
|
var dismissImpl: ((Bool) -> Void)?
|
||||||
@ -421,8 +421,9 @@ public func promptController(sharedContext: SharedAccountContext, updatedPresent
|
|||||||
applyImpl?()
|
applyImpl?()
|
||||||
})]
|
})]
|
||||||
|
|
||||||
let contentNode = PromptAlertContentNode(theme: AlertControllerTheme(presentationData: presentationData), ptheme: presentationData.theme, strings: presentationData.strings, actions: actions, text: text, titleFont: titleFont, value: value, characterLimit: characterLimit)
|
let contentNode = PromptAlertContentNode(theme: AlertControllerTheme(presentationData: presentationData), ptheme: presentationData.theme, strings: presentationData.strings, actions: actions, text: text, titleFont: titleFont, value: value, placeholder: placeholder, characterLimit: characterLimit)
|
||||||
contentNode.complete = {
|
contentNode.complete = {
|
||||||
|
dismissImpl?(true)
|
||||||
applyImpl?()
|
applyImpl?()
|
||||||
}
|
}
|
||||||
applyImpl = { [weak contentNode] in
|
applyImpl = { [weak contentNode] in
|
||||||
|
@ -1591,6 +1591,7 @@ public extension TelegramEngine {
|
|||||||
public enum MonoforumSuggestedPostAction {
|
public enum MonoforumSuggestedPostAction {
|
||||||
case approve(timestamp: Int32?)
|
case approve(timestamp: Int32?)
|
||||||
case reject(comment: String?)
|
case reject(comment: String?)
|
||||||
|
case proposeChanges(amount: Int64, timestamp: Int32?)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func monoforumPerformSuggestedPostAction(id: EngineMessage.Id, action: MonoforumSuggestedPostAction) -> Signal<Never, NoError> {
|
public func monoforumPerformSuggestedPostAction(id: EngineMessage.Id, action: MonoforumSuggestedPostAction) -> Signal<Never, NoError> {
|
||||||
@ -1601,6 +1602,34 @@ public extension TelegramEngine {
|
|||||||
|
|
||||||
func _internal_monoforumPerformSuggestedPostAction(account: Account, id: EngineMessage.Id, action: TelegramEngine.Messages.MonoforumSuggestedPostAction) -> Signal<Never, NoError> {
|
func _internal_monoforumPerformSuggestedPostAction(account: Account, id: EngineMessage.Id, action: TelegramEngine.Messages.MonoforumSuggestedPostAction) -> Signal<Never, NoError> {
|
||||||
return account.postbox.transaction { transaction -> Api.InputPeer? in
|
return account.postbox.transaction { transaction -> Api.InputPeer? in
|
||||||
|
if case let .proposeChanges(amount, timestamp) = action, let message = transaction.getMessage(id) {
|
||||||
|
var attributes: [MessageAttribute] = []
|
||||||
|
attributes.append(SuggestedPostMessageAttribute(
|
||||||
|
amount: amount,
|
||||||
|
timestamp: timestamp,
|
||||||
|
state: nil
|
||||||
|
))
|
||||||
|
|
||||||
|
var mediaReference: AnyMediaReference?
|
||||||
|
if let media = message.media.first {
|
||||||
|
mediaReference = .message(message: MessageReference(message), media: media)
|
||||||
|
}
|
||||||
|
|
||||||
|
let enqueueMessage: EnqueueMessage = .message(
|
||||||
|
text: message.text,
|
||||||
|
attributes: attributes,
|
||||||
|
inlineStickers: [:],
|
||||||
|
mediaReference: mediaReference,
|
||||||
|
threadId: message.threadId,
|
||||||
|
replyToMessageId: EngineMessageReplySubject(messageId: message.id, quote: nil),
|
||||||
|
replyToStoryId: nil,
|
||||||
|
localGroupingKey: nil,
|
||||||
|
correlationId: nil,
|
||||||
|
bubbleUpEmojiOrStickersets: []
|
||||||
|
)
|
||||||
|
let _ = enqueueMessages(transaction: transaction, account: account, peerId: id.peerId, messages: [(true, enqueueMessage)])
|
||||||
|
}
|
||||||
|
|
||||||
return transaction.getPeer(id.peerId).flatMap(apiInputPeer)
|
return transaction.getPeer(id.peerId).flatMap(apiInputPeer)
|
||||||
}
|
}
|
||||||
|> mapToSignal { inputPeer -> Signal<Never, NoError> in
|
|> mapToSignal { inputPeer -> Signal<Never, NoError> in
|
||||||
@ -1626,6 +1655,8 @@ func _internal_monoforumPerformSuggestedPostAction(account: Account, id: EngineM
|
|||||||
if rejectComment != nil {
|
if rejectComment != nil {
|
||||||
flags |= 1 << 2
|
flags |= 1 << 2
|
||||||
}
|
}
|
||||||
|
case .proposeChanges:
|
||||||
|
flags |= 1 << 1
|
||||||
}
|
}
|
||||||
return account.network.request(Api.functions.messages.toggleSuggestedPostApproval(flags: flags, peer: inputPeer, msgId: id.id, scheduleDate: timestamp, rejectComment: rejectComment))
|
return account.network.request(Api.functions.messages.toggleSuggestedPostApproval(flags: flags, peer: inputPeer, msgId: id.id, scheduleDate: timestamp, rejectComment: rejectComment))
|
||||||
|> map(Optional.init)
|
|> map(Optional.init)
|
||||||
|
@ -1390,6 +1390,22 @@ public func universalServiceMessageString(presentationData: (PresentationTheme,
|
|||||||
}
|
}
|
||||||
|
|
||||||
let string: String
|
let string: String
|
||||||
|
if !message.flags.contains(.Incoming) {
|
||||||
|
switch status {
|
||||||
|
case .approved:
|
||||||
|
if messageText.isEmpty {
|
||||||
|
string = "The message was approved"
|
||||||
|
} else {
|
||||||
|
string = "The message \"\(messageText)\" was approved"
|
||||||
|
}
|
||||||
|
case .rejected:
|
||||||
|
if messageText.isEmpty {
|
||||||
|
string = "The message was declined"
|
||||||
|
} else {
|
||||||
|
string = "The message \"\(messageText)\" was declined"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
switch status {
|
switch status {
|
||||||
case .approved:
|
case .approved:
|
||||||
if messageText.isEmpty {
|
if messageText.isEmpty {
|
||||||
@ -1399,9 +1415,10 @@ public func universalServiceMessageString(presentationData: (PresentationTheme,
|
|||||||
}
|
}
|
||||||
case .rejected:
|
case .rejected:
|
||||||
if messageText.isEmpty {
|
if messageText.isEmpty {
|
||||||
string = "Your message was rejected"
|
string = "Your message was declined"
|
||||||
} else {
|
} else {
|
||||||
string = "Your message \"\(messageText)\" was rejected"
|
string = "Your message \"\(messageText)\" was declined"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
attributedString = NSAttributedString(string: string, font: titleFont, textColor: primaryTextColor)
|
attributedString = NSAttributedString(string: string, font: titleFont, textColor: primaryTextColor)
|
||||||
|
@ -231,22 +231,27 @@ public class ChatMessageActionBubbleContentNode: ChatMessageBubbleContentNode {
|
|||||||
//TODO:localize
|
//TODO:localize
|
||||||
let timeString = humanReadableStringForTimestamp(strings: item.presentationData.strings, dateTimeFormat: item.presentationData.dateTimeFormat, timestamp: timestamp ?? 0, alwaysShowTime: true, allowYesterday: false, format: HumanReadableStringFormat(
|
let timeString = humanReadableStringForTimestamp(strings: item.presentationData.strings, dateTimeFormat: item.presentationData.dateTimeFormat, timestamp: timestamp ?? 0, alwaysShowTime: true, allowYesterday: false, format: HumanReadableStringFormat(
|
||||||
dateFormatString: { value in
|
dateFormatString: { value in
|
||||||
return PresentationStrings.FormattedString(string: item.presentationData.strings.SuggestPost_SetTimeFormat_Date(value).string, ranges: [])
|
return PresentationStrings.FormattedString(string: item.presentationData.strings.SuggestPost_SetTimeFormat_Date(value).string.lowercased(), ranges: [])
|
||||||
},
|
},
|
||||||
tomorrowFormatString: { value in
|
tomorrowFormatString: { value in
|
||||||
return PresentationStrings.FormattedString(string: item.presentationData.strings.SuggestPost_SetTimeFormat_TomorrowAt(value).string, ranges: [])
|
return PresentationStrings.FormattedString(string: item.presentationData.strings.SuggestPost_SetTimeFormat_TomorrowAt(value).string.lowercased(), ranges: [])
|
||||||
},
|
},
|
||||||
todayFormatString: { value in
|
todayFormatString: { value in
|
||||||
return PresentationStrings.FormattedString(string: item.presentationData.strings.SuggestPost_SetTimeFormat_TodayAt(value).string, ranges: [])
|
return PresentationStrings.FormattedString(string: item.presentationData.strings.SuggestPost_SetTimeFormat_TodayAt(value).string.lowercased(), ranges: [])
|
||||||
},
|
},
|
||||||
yesterdayFormatString: { value in
|
yesterdayFormatString: { value in
|
||||||
return PresentationStrings.FormattedString(string: item.presentationData.strings.SuggestPost_SetTimeFormat_TodayAt(value).string, ranges: [])
|
return PresentationStrings.FormattedString(string: item.presentationData.strings.SuggestPost_SetTimeFormat_TodayAt(value).string.lowercased(), ranges: [])
|
||||||
}
|
}
|
||||||
)).string
|
)).string
|
||||||
|
|
||||||
let amountString = amount == 1 ? "\(amount) Star" : "\(amount) Stars"
|
let amountString = amount == 1 ? "\(amount) Star" : "\(amount) Stars"
|
||||||
|
|
||||||
let rawString = "📅 Your post will be automatically published on **\(channelName)** **\(timeString)**.\n\n💰 You have been charged \(amountString).\n\n⌛ **\(channelName)** will receive your Stars once the post has been live for 24 hours.\n\n🔄 If **\(channelName)** removes the post before it has been live for 24 hours, your Stars will be refunded."
|
let rawString: String
|
||||||
|
if !item.message.effectivelyIncoming(item.context.account.peerId) {
|
||||||
|
rawString = "📅 The post will be automatically published on **\(channelName)** **\(timeString)**.\n\n💰 The user have been charged \(amountString).\n\n⌛ **\(channelName)** will receive the Stars once the post has been live for 24 hours.\n\n🔄 If your remove the post before it has been live for 24 hours, the user's Stars will be refunded."
|
||||||
|
} else {
|
||||||
|
rawString = "📅 Your post will be automatically published on **\(channelName)** **\(timeString)**.\n\n💰 You have been charged \(amountString).\n\n⌛ **\(channelName)** will receive your Stars once the post has been live for 24 hours.\n\n🔄 If **\(channelName)** removes the post before it has been live for 24 hours, your Stars will be refunded."
|
||||||
|
}
|
||||||
updatedAttributedString = parseMarkdownIntoAttributedString(rawString, attributes: MarkdownAttributes(
|
updatedAttributedString = parseMarkdownIntoAttributedString(rawString, attributes: MarkdownAttributes(
|
||||||
body: MarkdownAttributeSet(font: Font.regular(13.0), textColor: primaryTextColor),
|
body: MarkdownAttributeSet(font: Font.regular(13.0), textColor: primaryTextColor),
|
||||||
bold: MarkdownAttributeSet(font: Font.semibold(13.0), textColor: primaryTextColor),
|
bold: MarkdownAttributeSet(font: Font.semibold(13.0), textColor: primaryTextColor),
|
||||||
@ -257,6 +262,18 @@ public class ChatMessageActionBubbleContentNode: ChatMessageBubbleContentNode {
|
|||||||
))
|
))
|
||||||
case let .rejected(reason, comment):
|
case let .rejected(reason, comment):
|
||||||
let rawString: String
|
let rawString: String
|
||||||
|
if !item.message.effectivelyIncoming(item.context.account.peerId) {
|
||||||
|
switch reason {
|
||||||
|
case .generic:
|
||||||
|
if let comment {
|
||||||
|
rawString = "You declined the post with the following comment:\n\n" + comment
|
||||||
|
} else {
|
||||||
|
rawString = "You declined the post."
|
||||||
|
}
|
||||||
|
case .lowBalance:
|
||||||
|
rawString = "**\(channelName)** was unable to post the message, because the user did not have enough Stars."
|
||||||
|
}
|
||||||
|
} else {
|
||||||
switch reason {
|
switch reason {
|
||||||
case .generic:
|
case .generic:
|
||||||
if let comment {
|
if let comment {
|
||||||
@ -267,6 +284,7 @@ public class ChatMessageActionBubbleContentNode: ChatMessageBubbleContentNode {
|
|||||||
case .lowBalance:
|
case .lowBalance:
|
||||||
rawString = "**\(channelName)** was unable to post your message, because you did not have enough Stars."
|
rawString = "**\(channelName)** was unable to post your message, because you did not have enough Stars."
|
||||||
}
|
}
|
||||||
|
}
|
||||||
updatedAttributedString = parseMarkdownIntoAttributedString(rawString, attributes: MarkdownAttributes(
|
updatedAttributedString = parseMarkdownIntoAttributedString(rawString, attributes: MarkdownAttributes(
|
||||||
body: MarkdownAttributeSet(font: Font.regular(13.0), textColor: primaryTextColor),
|
body: MarkdownAttributeSet(font: Font.regular(13.0), textColor: primaryTextColor),
|
||||||
bold: MarkdownAttributeSet(font: Font.semibold(13.0), textColor: primaryTextColor),
|
bold: MarkdownAttributeSet(font: Font.semibold(13.0), textColor: primaryTextColor),
|
||||||
@ -344,7 +362,7 @@ public class ChatMessageActionBubbleContentNode: ChatMessageBubbleContentNode {
|
|||||||
backgroundSize.height += imageSize.height + 10.0
|
backgroundSize.height += imageSize.height + 10.0
|
||||||
}
|
}
|
||||||
|
|
||||||
let titleSpacing: CGFloat = 18.0
|
let titleSpacing: CGFloat = 14.0
|
||||||
|
|
||||||
var contentInsets = UIEdgeInsets()
|
var contentInsets = UIEdgeInsets()
|
||||||
var contentOuterInsets = UIEdgeInsets()
|
var contentOuterInsets = UIEdgeInsets()
|
||||||
@ -353,8 +371,8 @@ public class ChatMessageActionBubbleContentNode: ChatMessageBubbleContentNode {
|
|||||||
backgroundSize.width = max(backgroundSize.width, titleLayoutAndApply.0.size.width)
|
backgroundSize.width = max(backgroundSize.width, titleLayoutAndApply.0.size.width)
|
||||||
backgroundSize.height += titleSpacing + titleLayoutAndApply.0.size.height
|
backgroundSize.height += titleSpacing + titleLayoutAndApply.0.size.height
|
||||||
|
|
||||||
contentInsets = UIEdgeInsets(top: 16.0, left: 16.0, bottom: 16.0, right: 16.0)
|
contentInsets = UIEdgeInsets(top: 12.0, left: 16.0, bottom: 12.0, right: 16.0)
|
||||||
contentOuterInsets = UIEdgeInsets(top: 8.0, left: 0.0, bottom: 8.0, right: 0.0)
|
contentOuterInsets = UIEdgeInsets(top: 4.0, left: 0.0, bottom: 4.0, right: 0.0)
|
||||||
|
|
||||||
backgroundSize.width += contentInsets.left + contentInsets.right
|
backgroundSize.width += contentInsets.left + contentInsets.right
|
||||||
backgroundSize.height += contentInsets.top + contentInsets.bottom
|
backgroundSize.height += contentInsets.top + contentInsets.bottom
|
||||||
|
@ -2797,7 +2797,7 @@ public class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewI
|
|||||||
actionButtonsFinalize = buttonsLayout
|
actionButtonsFinalize = buttonsLayout
|
||||||
|
|
||||||
lastNodeTopPosition = .None(.Both)
|
lastNodeTopPosition = .None(.Both)
|
||||||
} else if incoming, let channel = item.message.peers[item.message.id.peerId] as? TelegramChannel, channel.isMonoForum, item.chatLocation.threadId != nil, let linkedMonoforumId = channel.linkedMonoforumId, let mainChannel = item.message.peers[linkedMonoforumId] as? TelegramChannel, mainChannel.hasPermission(.sendSomething), let attribute = item.message.attributes.first(where: { $0 is SuggestedPostMessageAttribute }) as? SuggestedPostMessageAttribute, attribute.state == nil {
|
} else if incoming, /*let channel = item.message.peers[item.message.id.peerId] as? TelegramChannel, channel.isMonoForum, let linkedMonoforumId = channel.linkedMonoforumId, let mainChannel = item.message.peers[linkedMonoforumId] as? TelegramChannel, mainChannel.hasPermission(.sendSomething),*/ let attribute = item.message.attributes.first(where: { $0 is SuggestedPostMessageAttribute }) as? SuggestedPostMessageAttribute, attribute.state == nil {
|
||||||
//TODO:localize
|
//TODO:localize
|
||||||
var buttonDecline: UInt8 = 0
|
var buttonDecline: UInt8 = 0
|
||||||
var buttonApprove: UInt8 = 1
|
var buttonApprove: UInt8 = 1
|
||||||
|
@ -22,6 +22,7 @@ swift_library(
|
|||||||
"//submodules/WallpaperBackgroundNode",
|
"//submodules/WallpaperBackgroundNode",
|
||||||
"//submodules/TelegramUI/Components/Chat/ChatMessageItem",
|
"//submodules/TelegramUI/Components/Chat/ChatMessageItem",
|
||||||
"//submodules/TelegramStringFormatting",
|
"//submodules/TelegramStringFormatting",
|
||||||
|
"//submodules/Markdown",
|
||||||
],
|
],
|
||||||
visibility = [
|
visibility = [
|
||||||
"//visibility:public",
|
"//visibility:public",
|
||||||
|
@ -12,6 +12,7 @@ import AccountContext
|
|||||||
import WallpaperBackgroundNode
|
import WallpaperBackgroundNode
|
||||||
import ChatMessageItem
|
import ChatMessageItem
|
||||||
import TelegramStringFormatting
|
import TelegramStringFormatting
|
||||||
|
import Markdown
|
||||||
|
|
||||||
public final class ChatMessageSuggestedPostInfoNode: ASDisplayNode {
|
public final class ChatMessageSuggestedPostInfoNode: ASDisplayNode {
|
||||||
private var titleNode: TextNode?
|
private var titleNode: TextNode?
|
||||||
@ -84,10 +85,23 @@ public final class ChatMessageSuggestedPostInfoNode: ASDisplayNode {
|
|||||||
if !item.message.effectivelyIncoming(item.context.account.peerId) {
|
if !item.message.effectivelyIncoming(item.context.account.peerId) {
|
||||||
titleText = "You suggest to post\nthis message."
|
titleText = "You suggest to post\nthis message."
|
||||||
} else {
|
} else {
|
||||||
titleText = "\(item.message.author.flatMap(EnginePeer.init)?.compactDisplayTitle ?? " ") suggests to post\nthis message."
|
if item.message.author is TelegramChannel {
|
||||||
|
titleText = "**\(item.message.author.flatMap(EnginePeer.init)?.compactDisplayTitle ?? " ")** suggests a new price,\ntime, and text for your message."
|
||||||
|
} else {
|
||||||
|
titleText = "**\(item.message.author.flatMap(EnginePeer.init)?.compactDisplayTitle ?? " ")** suggests to post\nthis message."
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let titleLayout = makeTitleLayout(TextNodeLayoutArguments(attributedString: NSAttributedString(string: titleText, font: Font.regular(13.0), textColor: serviceColor.primaryText), backgroundColor: nil, maximumNumberOfLines: 0, truncationType: .end, constrainedSize: CGSize(width: maxWidth - insets.left - insets.right, height: CGFloat.greatestFiniteMagnitude), alignment: .center, cutout: nil, insets: UIEdgeInsets()))
|
let titleAttributedText = parseMarkdownIntoAttributedString(titleText, attributes: MarkdownAttributes(
|
||||||
|
body: MarkdownAttributeSet(font: Font.regular(13.0), textColor: serviceColor.primaryText),
|
||||||
|
bold: MarkdownAttributeSet(font: Font.semibold(13.0), textColor: serviceColor.primaryText),
|
||||||
|
link: MarkdownAttributeSet(font: Font.regular(13.0), textColor: serviceColor.primaryText),
|
||||||
|
linkAttribute: { url in
|
||||||
|
return ("URL", url)
|
||||||
|
}
|
||||||
|
))
|
||||||
|
|
||||||
|
let titleLayout = makeTitleLayout(TextNodeLayoutArguments(attributedString: titleAttributedText, backgroundColor: nil, maximumNumberOfLines: 0, truncationType: .end, constrainedSize: CGSize(width: maxWidth - insets.left - insets.right, height: CGFloat.greatestFiniteMagnitude), alignment: .center, cutout: nil, insets: UIEdgeInsets()))
|
||||||
|
|
||||||
let priceLabelLayout = makePriceLabelLayout(TextNodeLayoutArguments(attributedString: NSAttributedString(string: "Price", font: Font.regular(13.0), textColor: serviceColor.primaryText.withMultipliedAlpha(0.5)), backgroundColor: nil, maximumNumberOfLines: 0, truncationType: .end, constrainedSize: CGSize(width: maxWidth - insets.left - insets.right, height: CGFloat.greatestFiniteMagnitude), alignment: .natural, cutout: nil, insets: UIEdgeInsets()))
|
let priceLabelLayout = makePriceLabelLayout(TextNodeLayoutArguments(attributedString: NSAttributedString(string: "Price", font: Font.regular(13.0), textColor: serviceColor.primaryText.withMultipliedAlpha(0.5)), backgroundColor: nil, maximumNumberOfLines: 0, truncationType: .end, constrainedSize: CGSize(width: maxWidth - insets.left - insets.right, height: CGFloat.greatestFiniteMagnitude), alignment: .natural, cutout: nil, insets: UIEdgeInsets()))
|
||||||
let timeLabelLayout = makeTimeLabelLayout(TextNodeLayoutArguments(attributedString: NSAttributedString(string: "Time", font: Font.regular(13.0), textColor: serviceColor.primaryText.withMultipliedAlpha(0.5)), backgroundColor: nil, maximumNumberOfLines: 0, truncationType: .end, constrainedSize: CGSize(width: maxWidth - insets.left - insets.right, height: CGFloat.greatestFiniteMagnitude), alignment: .natural, cutout: nil, insets: UIEdgeInsets()))
|
let timeLabelLayout = makeTimeLabelLayout(TextNodeLayoutArguments(attributedString: NSAttributedString(string: "Time", font: Font.regular(13.0), textColor: serviceColor.primaryText.withMultipliedAlpha(0.5)), backgroundColor: nil, maximumNumberOfLines: 0, truncationType: .end, constrainedSize: CGSize(width: maxWidth - insets.left - insets.right, height: CGFloat.greatestFiniteMagnitude), alignment: .natural, cutout: nil, insets: UIEdgeInsets()))
|
||||||
|
@ -1400,13 +1400,10 @@ private final class ChatSendStarsScreenComponent: Component {
|
|||||||
guard let environment = self.environment else {
|
guard let environment = self.environment else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
guard case let .suggestPost(suggestPostData) = component.initialData.subjectInitialData else {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
let mode: ChatScheduleTimeControllerMode = .suggestPost
|
let mode: ChatScheduleTimeControllerMode = .suggestPost(needsTime: false)
|
||||||
let theme = environment.theme
|
let theme = environment.theme
|
||||||
let controller = ChatScheduleTimeController(context: component.context, updatedPresentationData: (component.context.sharedContext.currentPresentationData.with({ $0 }).withUpdated(theme: theme), component.context.sharedContext.presentationData |> map { $0.withUpdated(theme: theme) }), peerId: suggestPostData.peer.id, mode: mode, style: .default, currentTime: self.currentSuggestPostTimestamp, minimalTime: nil, dismissByTapOutside: true, completion: { [weak self] time in
|
let controller = ChatScheduleTimeController(context: component.context, updatedPresentationData: (component.context.sharedContext.currentPresentationData.with({ $0 }).withUpdated(theme: theme), component.context.sharedContext.presentationData |> map { $0.withUpdated(theme: theme) }), mode: mode, style: .default, currentTime: self.currentSuggestPostTimestamp, minimalTime: nil, dismissByTapOutside: true, completion: { [weak self] time in
|
||||||
guard let self else {
|
guard let self else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,7 @@ import TelegramPresentationData
|
|||||||
public enum ChatScheduleTimeControllerMode {
|
public enum ChatScheduleTimeControllerMode {
|
||||||
case scheduledMessages(sendWhenOnlineAvailable: Bool)
|
case scheduledMessages(sendWhenOnlineAvailable: Bool)
|
||||||
case reminders
|
case reminders
|
||||||
case suggestPost
|
case suggestPost(needsTime: Bool)
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum ChatScheduleTimeControllerStyle {
|
public enum ChatScheduleTimeControllerStyle {
|
||||||
@ -27,7 +27,6 @@ public final class ChatScheduleTimeController: ViewController {
|
|||||||
private var animatedIn = false
|
private var animatedIn = false
|
||||||
|
|
||||||
private let context: AccountContext
|
private let context: AccountContext
|
||||||
private let peerId: PeerId
|
|
||||||
private let mode: ChatScheduleTimeControllerMode
|
private let mode: ChatScheduleTimeControllerMode
|
||||||
private let style: ChatScheduleTimeControllerStyle
|
private let style: ChatScheduleTimeControllerStyle
|
||||||
private let currentTime: Int32?
|
private let currentTime: Int32?
|
||||||
@ -40,9 +39,8 @@ public final class ChatScheduleTimeController: ViewController {
|
|||||||
|
|
||||||
public var dismissed: () -> Void = {}
|
public var dismissed: () -> Void = {}
|
||||||
|
|
||||||
public init(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)? = nil, peerId: PeerId, mode: ChatScheduleTimeControllerMode, style: ChatScheduleTimeControllerStyle, currentTime: Int32? = nil, minimalTime: Int32? = nil, dismissByTapOutside: Bool = true, completion: @escaping (Int32) -> Void) {
|
public init(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)? = nil, mode: ChatScheduleTimeControllerMode, style: ChatScheduleTimeControllerStyle, currentTime: Int32? = nil, minimalTime: Int32? = nil, dismissByTapOutside: Bool = true, completion: @escaping (Int32) -> Void) {
|
||||||
self.context = context
|
self.context = context
|
||||||
self.peerId = peerId
|
|
||||||
self.mode = mode
|
self.mode = mode
|
||||||
self.style = style
|
self.style = style
|
||||||
self.currentTime = currentTime != scheduleWhenOnlineTimestamp ? currentTime : nil
|
self.currentTime = currentTime != scheduleWhenOnlineTimestamp ? currentTime : nil
|
||||||
|
@ -100,11 +100,17 @@ class ChatScheduleTimeControllerNode: ViewControllerTracingNode, ASScrollViewDel
|
|||||||
title = self.presentationData.strings.Conversation_ScheduleMessage_Title
|
title = self.presentationData.strings.Conversation_ScheduleMessage_Title
|
||||||
case .reminders:
|
case .reminders:
|
||||||
title = self.presentationData.strings.Conversation_SetReminder_Title
|
title = self.presentationData.strings.Conversation_SetReminder_Title
|
||||||
case .suggestPost:
|
case let .suggestPost(needsTime):
|
||||||
|
if needsTime {
|
||||||
|
//TODO:localize
|
||||||
|
title = "Time"
|
||||||
|
text = "Set the date and time you want\nthis message to be published."
|
||||||
|
} else {
|
||||||
//TODO:localize
|
//TODO:localize
|
||||||
title = "Time"
|
title = "Time"
|
||||||
text = "Set the date and time you want\nyour message to be published."
|
text = "Set the date and time you want\nyour message to be published."
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
self.titleNode = ASTextNode()
|
self.titleNode = ASTextNode()
|
||||||
self.titleNode.attributedText = NSAttributedString(string: title, font: Font.bold(17.0), textColor: textColor)
|
self.titleNode.attributedText = NSAttributedString(string: title, font: Font.bold(17.0), textColor: textColor)
|
||||||
@ -169,7 +175,7 @@ class ChatScheduleTimeControllerNode: ViewControllerTracingNode, ASScrollViewDel
|
|||||||
self.contentContainerNode.addSubnode(self.doneButton)
|
self.contentContainerNode.addSubnode(self.doneButton)
|
||||||
if case .scheduledMessages(true) = self.mode {
|
if case .scheduledMessages(true) = self.mode {
|
||||||
self.contentContainerNode.addSubnode(self.onlineButton)
|
self.contentContainerNode.addSubnode(self.onlineButton)
|
||||||
} else if case .suggestPost = self.mode {
|
} else if case let .suggestPost(needsTime) = self.mode, !needsTime {
|
||||||
self.contentContainerNode.addSubnode(self.onlineButton)
|
self.contentContainerNode.addSubnode(self.onlineButton)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -425,7 +431,7 @@ class ChatScheduleTimeControllerNode: ViewControllerTracingNode, ASScrollViewDel
|
|||||||
var buttonOffset: CGFloat = 0.0
|
var buttonOffset: CGFloat = 0.0
|
||||||
if case .scheduledMessages(true) = self.mode {
|
if case .scheduledMessages(true) = self.mode {
|
||||||
buttonOffset += 64.0
|
buttonOffset += 64.0
|
||||||
} else if case .suggestPost = self.mode {
|
} else if case let .suggestPost(needsTime) = self.mode, !needsTime {
|
||||||
buttonOffset += 64.0
|
buttonOffset += 64.0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -50,7 +50,7 @@ private final class SheetContent: CombinedComponent {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
static var body: Body {
|
static var body: (CombinedComponentContext<SheetContent>) -> CGSize {
|
||||||
let closeButton = Child(Button.self)
|
let closeButton = Child(Button.self)
|
||||||
let title = Child(Text.self)
|
let title = Child(Text.self)
|
||||||
let amountSection = Child(ListSectionComponent.self)
|
let amountSection = Child(ListSectionComponent.self)
|
||||||
@ -61,7 +61,7 @@ private final class SheetContent: CombinedComponent {
|
|||||||
let balanceValue = Child(MultilineTextComponent.self)
|
let balanceValue = Child(MultilineTextComponent.self)
|
||||||
let balanceIcon = Child(BundleIconComponent.self)
|
let balanceIcon = Child(BundleIconComponent.self)
|
||||||
|
|
||||||
return { context in
|
return { (context: CombinedComponentContext<SheetContent>) -> CGSize in
|
||||||
let environment = context.environment[EnvironmentType.self]
|
let environment = context.environment[EnvironmentType.self]
|
||||||
let component = context.component
|
let component = context.component
|
||||||
let state = context.state
|
let state = context.state
|
||||||
@ -160,9 +160,14 @@ private final class SheetContent: CombinedComponent {
|
|||||||
|
|
||||||
minAmount = StarsAmount(value: minAmountValue, nanos: 0)
|
minAmount = StarsAmount(value: minAmountValue, nanos: 0)
|
||||||
maxAmount = StarsAmount(value: resaleConfiguration.paidMessageMaxAmount, nanos: 0)
|
maxAmount = StarsAmount(value: resaleConfiguration.paidMessageMaxAmount, nanos: 0)
|
||||||
case .suggestedPost:
|
case let .suggestedPost(mode, _, _, _):
|
||||||
//TODO:localize
|
//TODO:localize
|
||||||
|
switch mode {
|
||||||
|
case .sender:
|
||||||
titleString = "Suggest Terms"
|
titleString = "Suggest Terms"
|
||||||
|
case .admin:
|
||||||
|
titleString = "Suggest Changes"
|
||||||
|
}
|
||||||
amountTitle = "ENTER A PRICE IN STARS"
|
amountTitle = "ENTER A PRICE IN STARS"
|
||||||
amountPlaceholder = "Price"
|
amountPlaceholder = "Price"
|
||||||
|
|
||||||
@ -321,6 +326,13 @@ private final class SheetContent: CombinedComponent {
|
|||||||
text: .plain(amountInfoString),
|
text: .plain(amountInfoString),
|
||||||
maximumNumberOfLines: 0
|
maximumNumberOfLines: 0
|
||||||
))
|
))
|
||||||
|
case .admin:
|
||||||
|
//TODO:localize
|
||||||
|
let amountInfoString = NSAttributedString(attributedString: parseMarkdownIntoAttributedString("Choose how many Stars you charge for the message.", attributes: amountMarkdownAttributes, textAlignment: .natural))
|
||||||
|
amountFooter = AnyComponent(MultilineTextComponent(
|
||||||
|
text: .plain(amountInfoString),
|
||||||
|
maximumNumberOfLines: 0
|
||||||
|
))
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
amountFooter = nil
|
amountFooter = nil
|
||||||
@ -380,11 +392,19 @@ private final class SheetContent: CombinedComponent {
|
|||||||
.position(CGPoint(x: context.availableSize.width - amountAdditionalLabel.size.width / 2.0 - sideInset - 16.0, y: contentSize.height - amountAdditionalLabel.size.height / 2.0)))
|
.position(CGPoint(x: context.availableSize.width - amountAdditionalLabel.size.width / 2.0 - sideInset - 16.0, y: contentSize.height - amountAdditionalLabel.size.height / 2.0)))
|
||||||
}
|
}
|
||||||
|
|
||||||
if case .suggestedPost = component.mode {
|
if case let .suggestedPost(mode, _, _, _) = component.mode {
|
||||||
contentSize.height += 24.0
|
contentSize.height += 24.0
|
||||||
|
|
||||||
//TODO:localize
|
//TODO:localize
|
||||||
let timestampFooterString = NSAttributedString(attributedString: parseMarkdownIntoAttributedString("Select the date and time you want your message to be published.", attributes: amountMarkdownAttributes, textAlignment: .natural))
|
let footerString: String
|
||||||
|
switch mode {
|
||||||
|
case .sender:
|
||||||
|
footerString = "Select the date and time you want your message to be published."
|
||||||
|
case .admin:
|
||||||
|
footerString = "Select the date and time you want to publish the message."
|
||||||
|
}
|
||||||
|
|
||||||
|
let timestampFooterString = NSAttributedString(attributedString: parseMarkdownIntoAttributedString(footerString, attributes: amountMarkdownAttributes, textAlignment: .natural))
|
||||||
let timestampFooter = AnyComponent(MultilineTextComponent(
|
let timestampFooter = AnyComponent(MultilineTextComponent(
|
||||||
text: .plain(timestampFooterString),
|
text: .plain(timestampFooterString),
|
||||||
maximumNumberOfLines: 0
|
maximumNumberOfLines: 0
|
||||||
@ -443,15 +463,9 @@ private final class SheetContent: CombinedComponent {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
let component = state.component
|
let component = state.component
|
||||||
guard case let .suggestedPost(mode, _, _, _) = component.mode else {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
guard case let .sender(channel) = mode else {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
let theme = environment.theme
|
let theme = environment.theme
|
||||||
let controller = ChatScheduleTimeController(context: state.context, updatedPresentationData: (state.context.sharedContext.currentPresentationData.with({ $0 }).withUpdated(theme: theme), state.context.sharedContext.presentationData |> map { $0.withUpdated(theme: theme) }), peerId: channel.id, mode: .suggestPost, style: .default, currentTime: state.timestamp, minimalTime: nil, dismissByTapOutside: true, completion: { [weak state] time in
|
let controller = ChatScheduleTimeController(context: state.context, updatedPresentationData: (state.context.sharedContext.currentPresentationData.with({ $0 }).withUpdated(theme: theme), state.context.sharedContext.presentationData |> map { $0.withUpdated(theme: theme) }), mode: .suggestPost(needsTime: false), style: .default, currentTime: state.timestamp, minimalTime: nil, dismissByTapOutside: true, completion: { [weak state] time in
|
||||||
guard let state else {
|
guard let state else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -498,6 +512,8 @@ private final class SheetContent: CombinedComponent {
|
|||||||
} else {
|
} else {
|
||||||
buttonString = "Offer"
|
buttonString = "Offer"
|
||||||
}
|
}
|
||||||
|
case .admin:
|
||||||
|
buttonString = "Update Terms"
|
||||||
}
|
}
|
||||||
} else if let amount = state.amount {
|
} else if let amount = state.amount {
|
||||||
buttonString = "\(environment.strings.Stars_Withdraw_Withdraw) # \(presentationStringsFormattedNumber(amount, environment.dateTimeFormat.groupingSeparator))"
|
buttonString = "\(environment.strings.Stars_Withdraw_Withdraw) # \(presentationStringsFormattedNumber(amount, environment.dateTimeFormat.groupingSeparator))"
|
||||||
@ -770,6 +786,7 @@ public final class StarsWithdrawScreen: ViewControllerComponentContainer {
|
|||||||
public enum Mode {
|
public enum Mode {
|
||||||
public enum SuggestedPostMode {
|
public enum SuggestedPostMode {
|
||||||
case sender(channel: EnginePeer)
|
case sender(channel: EnginePeer)
|
||||||
|
case admin
|
||||||
}
|
}
|
||||||
|
|
||||||
case withdraw(StarsRevenueStats, completion: (Int64) -> Void)
|
case withdraw(StarsRevenueStats, completion: (Int64) -> Void)
|
||||||
|
@ -466,6 +466,7 @@ final class StoryItemSetContainerSendMessage {
|
|||||||
guard let peerId = focusedItem.peerId else {
|
guard let peerId = focusedItem.peerId else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
let _ = peerId
|
||||||
let controller = component.controller() as? StoryContainerScreen
|
let controller = component.controller() as? StoryContainerScreen
|
||||||
|
|
||||||
var sendWhenOnlineAvailable = false
|
var sendWhenOnlineAvailable = false
|
||||||
@ -473,7 +474,7 @@ final class StoryItemSetContainerSendMessage {
|
|||||||
sendWhenOnlineAvailable = true
|
sendWhenOnlineAvailable = true
|
||||||
}
|
}
|
||||||
|
|
||||||
let timeController = ChatScheduleTimeController(context: component.context, updatedPresentationData: nil, peerId: peerId, mode: .scheduledMessages(sendWhenOnlineAvailable: sendWhenOnlineAvailable), style: .media, currentTime: nil, minimalTime: nil, dismissByTapOutside: true, completion: { [weak self, weak view] time in
|
let timeController = ChatScheduleTimeController(context: component.context, updatedPresentationData: nil, mode: .scheduledMessages(sendWhenOnlineAvailable: sendWhenOnlineAvailable), style: .media, currentTime: nil, minimalTime: nil, dismissByTapOutside: true, completion: { [weak self, weak view] time in
|
||||||
guard let self, let view else {
|
guard let self, let view else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -2607,7 +2608,7 @@ final class StoryItemSetContainerSendMessage {
|
|||||||
mode = .scheduledMessages(sendWhenOnlineAvailable: sendWhenOnlineAvailable)
|
mode = .scheduledMessages(sendWhenOnlineAvailable: sendWhenOnlineAvailable)
|
||||||
}
|
}
|
||||||
let theme = component.theme
|
let theme = component.theme
|
||||||
let controller = ChatScheduleTimeController(context: component.context, updatedPresentationData: (component.context.sharedContext.currentPresentationData.with({ $0 }).withUpdated(theme: theme), component.context.sharedContext.presentationData |> map { $0.withUpdated(theme: theme) }), peerId: peer.id, mode: mode, style: style, currentTime: selectedTime, minimalTime: nil, dismissByTapOutside: dismissByTapOutside, completion: { time in
|
let controller = ChatScheduleTimeController(context: component.context, updatedPresentationData: (component.context.sharedContext.currentPresentationData.with({ $0 }).withUpdated(theme: theme), component.context.sharedContext.presentationData |> map { $0.withUpdated(theme: theme) }), mode: mode, style: style, currentTime: selectedTime, minimalTime: nil, dismissByTapOutside: dismissByTapOutside, completion: { time in
|
||||||
completion(time)
|
completion(time)
|
||||||
})
|
})
|
||||||
view.endEditing(true)
|
view.endEditing(true)
|
||||||
|
@ -137,6 +137,7 @@ import ChatMessagePaymentAlertController
|
|||||||
import TelegramCallsUI
|
import TelegramCallsUI
|
||||||
import QuickShareScreen
|
import QuickShareScreen
|
||||||
import PostSuggestionsSettingsScreen
|
import PostSuggestionsSettingsScreen
|
||||||
|
import PromptUI
|
||||||
|
|
||||||
public final class ChatControllerOverlayPresentationData {
|
public final class ChatControllerOverlayPresentationData {
|
||||||
public let expandData: (ASDisplayNode?, () -> Void)
|
public let expandData: (ASDisplayNode?, () -> Void)
|
||||||
@ -2331,16 +2332,49 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
|||||||
if message.effectivelyIncoming(strongSelf.context.account.peerId) {
|
if message.effectivelyIncoming(strongSelf.context.account.peerId) {
|
||||||
switch buttonType {
|
switch buttonType {
|
||||||
case 0:
|
case 0:
|
||||||
let _ = strongSelf.context.engine.messages.monoforumPerformSuggestedPostAction(id: message.id, action: .reject(comment: nil)).startStandalone()
|
//TODO:localize
|
||||||
|
let promptController = promptController(sharedContext: strongSelf.context.sharedContext, updatedPresentationData: strongSelf.updatedPresentationData, text: "Comment", titleFont: .bold, value: "", placeholder: "Optional", characterLimit: 4096, apply: { value in
|
||||||
|
guard let self else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if let value {
|
||||||
|
let _ = self.context.engine.messages.monoforumPerformSuggestedPostAction(id: message.id, action: .reject(comment: value.isEmpty ? nil : value)).startStandalone()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
strongSelf.present(promptController, in: .window(.root))
|
||||||
case 1:
|
case 1:
|
||||||
var timestamp: Int32?
|
var timestamp: Int32?
|
||||||
if attribute.timestamp == nil {
|
if attribute.timestamp == nil {
|
||||||
timestamp = Int32(Date().timeIntervalSince1970) + 1 * 60 * 60
|
let controller = ChatScheduleTimeController(context: strongSelf.context, updatedPresentationData: strongSelf.updatedPresentationData, mode: .suggestPost(needsTime: true), style: .default, currentTime: nil, minimalTime: nil, dismissByTapOutside: true, completion: { [weak strongSelf] time in
|
||||||
|
guard let strongSelf else {
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
if time != 0 {
|
||||||
|
let _ = strongSelf.context.engine.messages.monoforumPerformSuggestedPostAction(id: message.id, action: .approve(timestamp: time)).startStandalone()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
strongSelf.view.endEditing(true)
|
||||||
|
strongSelf.present(controller, in: .window(.root))
|
||||||
|
|
||||||
|
timestamp = Int32(Date().timeIntervalSince1970) + 1 * 60 * 60
|
||||||
|
} else {
|
||||||
let _ = strongSelf.context.engine.messages.monoforumPerformSuggestedPostAction(id: message.id, action: .approve(timestamp: timestamp)).startStandalone()
|
let _ = strongSelf.context.engine.messages.monoforumPerformSuggestedPostAction(id: message.id, action: .approve(timestamp: timestamp)).startStandalone()
|
||||||
|
}
|
||||||
case 2:
|
case 2:
|
||||||
//suggest changes
|
strongSelf.push(strongSelf.context.sharedContext.makeStarsWithdrawalScreen(
|
||||||
break
|
context: strongSelf.context,
|
||||||
|
subject: .postSuggestionModification(
|
||||||
|
current: StarsAmount(value: attribute.amount, nanos: 0),
|
||||||
|
timestamp: attribute.timestamp,
|
||||||
|
completion: { [weak strongSelf] price, timestamp in
|
||||||
|
guard let strongSelf else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
let _ = strongSelf.context.engine.messages.monoforumPerformSuggestedPostAction(id: message.id, action: .proposeChanges(amount: price, timestamp: timestamp)).startStandalone()
|
||||||
|
}
|
||||||
|
)
|
||||||
|
))
|
||||||
default:
|
default:
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
@ -9525,7 +9559,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
|||||||
} else {
|
} else {
|
||||||
mode = .scheduledMessages(sendWhenOnlineAvailable: sendWhenOnlineAvailable)
|
mode = .scheduledMessages(sendWhenOnlineAvailable: sendWhenOnlineAvailable)
|
||||||
}
|
}
|
||||||
let controller = ChatScheduleTimeController(context: strongSelf.context, updatedPresentationData: strongSelf.updatedPresentationData, peerId: peerId, mode: mode, style: style, currentTime: selectedTime, minimalTime: strongSelf.presentationInterfaceState.slowmodeState?.timeout, dismissByTapOutside: dismissByTapOutside, completion: { time in
|
let controller = ChatScheduleTimeController(context: strongSelf.context, updatedPresentationData: strongSelf.updatedPresentationData, mode: mode, style: style, currentTime: selectedTime, minimalTime: strongSelf.presentationInterfaceState.slowmodeState?.timeout, dismissByTapOutside: dismissByTapOutside, completion: { time in
|
||||||
completion(time)
|
completion(time)
|
||||||
})
|
})
|
||||||
strongSelf.chatDisplayNode.dismissInput()
|
strongSelf.chatDisplayNode.dismissInput()
|
||||||
|
@ -233,7 +233,7 @@ func inputTextPanelStateForChatPresentationInterfaceState(_ chatPresentationInte
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if isTextEmpty, let channel = chatPresentationInterfaceState.renderedPeer?.peer as? TelegramChannel, channel.isMonoForum, let mainChannel = chatPresentationInterfaceState.renderedPeer?.chatOrMonoforumMainPeer as? TelegramChannel, !mainChannel.hasPermission(.sendSomething) {
|
if let channel = chatPresentationInterfaceState.renderedPeer?.peer as? TelegramChannel, channel.isMonoForum, let mainChannel = chatPresentationInterfaceState.renderedPeer?.chatOrMonoforumMainPeer as? TelegramChannel, !mainChannel.hasPermission(.sendSomething) {
|
||||||
if chatPresentationInterfaceState.interfaceState.postSuggestionState == nil {
|
if chatPresentationInterfaceState.interfaceState.postSuggestionState == nil {
|
||||||
accessoryItems.append(.suggestPost)
|
accessoryItems.append(.suggestPost)
|
||||||
}
|
}
|
||||||
|
@ -3731,6 +3731,8 @@ public final class SharedAccountContextImpl: SharedAccountContext {
|
|||||||
mode = .paidMessages(current: current.value, minValue: minValue.value, fractionAfterCommission: fractionAfterCommission, kind: kind, completion: completion)
|
mode = .paidMessages(current: current.value, minValue: minValue.value, fractionAfterCommission: fractionAfterCommission, kind: kind, completion: completion)
|
||||||
case let .postSuggestion(channel, current, timestamp, completion):
|
case let .postSuggestion(channel, current, timestamp, completion):
|
||||||
mode = .suggestedPost(mode: .sender(channel: channel), price: current.value, timestamp: timestamp, completion: completion)
|
mode = .suggestedPost(mode: .sender(channel: channel), price: current.value, timestamp: timestamp, completion: completion)
|
||||||
|
case let .postSuggestionModification(current, timestamp, completion):
|
||||||
|
mode = .suggestedPost(mode: .admin, price: current.value, timestamp: timestamp, completion: completion)
|
||||||
}
|
}
|
||||||
return StarsWithdrawScreen(context: context, mode: mode)
|
return StarsWithdrawScreen(context: context, mode: mode)
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user