Various improvements

This commit is contained in:
Ilya Laktyushin 2024-07-26 21:41:03 +02:00
parent 17f076ea1b
commit 24cb5668a6
7 changed files with 110 additions and 43 deletions

View File

@ -12668,3 +12668,5 @@ Sorry for the inconvenience.";
"WebApp.PrivacyPolicy" = "Privacy Policy"; "WebApp.PrivacyPolicy" = "Privacy Policy";
"Conversation.OpenProfile" = "OPEN PROFILE"; "Conversation.OpenProfile" = "OPEN PROFILE";
"Stars.Intro.GiftStars" = "Gift Stars to Friends";

View File

@ -139,6 +139,7 @@ public struct PremiumConfiguration {
showPremiumGiftInAttachMenu: false, showPremiumGiftInAttachMenu: false,
showPremiumGiftInTextField: false, showPremiumGiftInTextField: false,
giveawayGiftsPurchaseAvailable: false, giveawayGiftsPurchaseAvailable: false,
starsGiftsPurchaseAvailable: false,
boostsPerGiftCount: 3, boostsPerGiftCount: 3,
audioTransciptionTrialMaxDuration: 300, audioTransciptionTrialMaxDuration: 300,
audioTransciptionTrialCount: 2, audioTransciptionTrialCount: 2,
@ -165,6 +166,7 @@ public struct PremiumConfiguration {
public let showPremiumGiftInAttachMenu: Bool public let showPremiumGiftInAttachMenu: Bool
public let showPremiumGiftInTextField: Bool public let showPremiumGiftInTextField: Bool
public let giveawayGiftsPurchaseAvailable: Bool public let giveawayGiftsPurchaseAvailable: Bool
public let starsGiftsPurchaseAvailable: Bool
public let boostsPerGiftCount: Int32 public let boostsPerGiftCount: Int32
public let audioTransciptionTrialMaxDuration: Int32 public let audioTransciptionTrialMaxDuration: Int32
public let audioTransciptionTrialCount: Int32 public let audioTransciptionTrialCount: Int32
@ -190,6 +192,7 @@ public struct PremiumConfiguration {
showPremiumGiftInAttachMenu: Bool, showPremiumGiftInAttachMenu: Bool,
showPremiumGiftInTextField: Bool, showPremiumGiftInTextField: Bool,
giveawayGiftsPurchaseAvailable: Bool, giveawayGiftsPurchaseAvailable: Bool,
starsGiftsPurchaseAvailable: Bool,
boostsPerGiftCount: Int32, boostsPerGiftCount: Int32,
audioTransciptionTrialMaxDuration: Int32, audioTransciptionTrialMaxDuration: Int32,
audioTransciptionTrialCount: Int32, audioTransciptionTrialCount: Int32,
@ -214,6 +217,7 @@ public struct PremiumConfiguration {
self.showPremiumGiftInAttachMenu = showPremiumGiftInAttachMenu self.showPremiumGiftInAttachMenu = showPremiumGiftInAttachMenu
self.showPremiumGiftInTextField = showPremiumGiftInTextField self.showPremiumGiftInTextField = showPremiumGiftInTextField
self.giveawayGiftsPurchaseAvailable = giveawayGiftsPurchaseAvailable self.giveawayGiftsPurchaseAvailable = giveawayGiftsPurchaseAvailable
self.starsGiftsPurchaseAvailable = starsGiftsPurchaseAvailable
self.boostsPerGiftCount = boostsPerGiftCount self.boostsPerGiftCount = boostsPerGiftCount
self.audioTransciptionTrialMaxDuration = audioTransciptionTrialMaxDuration self.audioTransciptionTrialMaxDuration = audioTransciptionTrialMaxDuration
self.audioTransciptionTrialCount = audioTransciptionTrialCount self.audioTransciptionTrialCount = audioTransciptionTrialCount
@ -246,6 +250,7 @@ public struct PremiumConfiguration {
showPremiumGiftInAttachMenu: data["premium_gift_attach_menu_icon"] as? Bool ?? defaultValue.showPremiumGiftInAttachMenu, showPremiumGiftInAttachMenu: data["premium_gift_attach_menu_icon"] as? Bool ?? defaultValue.showPremiumGiftInAttachMenu,
showPremiumGiftInTextField: data["premium_gift_text_field_icon"] as? Bool ?? defaultValue.showPremiumGiftInTextField, showPremiumGiftInTextField: data["premium_gift_text_field_icon"] as? Bool ?? defaultValue.showPremiumGiftInTextField,
giveawayGiftsPurchaseAvailable: data["giveaway_gifts_purchase_available"] as? Bool ?? defaultValue.giveawayGiftsPurchaseAvailable, giveawayGiftsPurchaseAvailable: data["giveaway_gifts_purchase_available"] as? Bool ?? defaultValue.giveawayGiftsPurchaseAvailable,
starsGiftsPurchaseAvailable: data["stars_gifts_enabled"] as? Bool ?? defaultValue.starsGiftsPurchaseAvailable,
boostsPerGiftCount: get(data["boosts_per_sent_gift"]) ?? defaultValue.boostsPerGiftCount, boostsPerGiftCount: get(data["boosts_per_sent_gift"]) ?? defaultValue.boostsPerGiftCount,
audioTransciptionTrialMaxDuration: get(data["transcribe_audio_trial_duration_max"]) ?? defaultValue.audioTransciptionTrialMaxDuration, audioTransciptionTrialMaxDuration: get(data["transcribe_audio_trial_duration_max"]) ?? defaultValue.audioTransciptionTrialMaxDuration,
audioTransciptionTrialCount: get(data["transcribe_audio_trial_weekly_number"]) ?? defaultValue.audioTransciptionTrialCount, audioTransciptionTrialCount: get(data["transcribe_audio_trial_weekly_number"]) ?? defaultValue.audioTransciptionTrialCount,

View File

@ -2076,32 +2076,60 @@ public extension TelegramEngine.EngineData.Item {
} }
} }
public struct BotMenu: TelegramEngineDataItem, TelegramEngineMapKeyDataItem, PostboxViewDataItem { public struct BotMenu: TelegramEngineDataItem, TelegramEngineMapKeyDataItem, PostboxViewDataItem {
public typealias Result = Optional<BotMenuButton> public typealias Result = Optional<BotMenuButton>
fileprivate var id: EnginePeer.Id fileprivate var id: EnginePeer.Id
public var mapKey: EnginePeer.Id { public var mapKey: EnginePeer.Id {
return self.id return self.id
} }
public init(id: EnginePeer.Id) { public init(id: EnginePeer.Id) {
self.id = id self.id = id
} }
var key: PostboxViewKey { var key: PostboxViewKey {
return .cachedPeerData(peerId: self.id) return .cachedPeerData(peerId: self.id)
} }
func extract(view: PostboxView) -> Result { func extract(view: PostboxView) -> Result {
guard let view = view as? CachedPeerDataView else { guard let view = view as? CachedPeerDataView else {
preconditionFailure() preconditionFailure()
} }
if let cachedData = view.cachedPeerData as? CachedUserData { if let cachedData = view.cachedPeerData as? CachedUserData {
return cachedData.botInfo?.menuButton return cachedData.botInfo?.menuButton
} else { } else {
return nil return nil
} }
} }
} }
public struct BotCommands: TelegramEngineDataItem, TelegramEngineMapKeyDataItem, PostboxViewDataItem {
public typealias Result = Optional<[BotCommand]>
fileprivate var id: EnginePeer.Id
public var mapKey: EnginePeer.Id {
return self.id
}
public init(id: EnginePeer.Id) {
self.id = id
}
var key: PostboxViewKey {
return .cachedPeerData(peerId: self.id)
}
func extract(view: PostboxView) -> Result {
guard let view = view as? CachedPeerDataView else {
preconditionFailure()
}
if let cachedData = view.cachedPeerData as? CachedUserData {
return cachedData.botInfo?.commands
} else {
return nil
}
}
}
} }
} }

View File

@ -538,7 +538,7 @@ final class StarsTransactionsScreenComponent: Component {
component.buy() component.buy()
}, },
buyAds: nil, buyAds: nil,
additionalAction: AnyComponent( additionalAction: premiumConfiguration.starsGiftsPurchaseAvailable ? AnyComponent(
Button( Button(
content: AnyComponent( content: AnyComponent(
HStack([ HStack([
@ -548,7 +548,7 @@ final class StarsTransactionsScreenComponent: Component {
), ),
AnyComponentWithIdentity( AnyComponentWithIdentity(
id: "label", id: "label",
component: AnyComponent(MultilineTextComponent(text: .plain(NSAttributedString(string: "Gift Stars to Friends", font: Font.regular(17.0), textColor: environment.theme.list.itemAccentColor)))) component: AnyComponent(MultilineTextComponent(text: .plain(NSAttributedString(string: environment.strings.Stars_Intro_GiftStars, font: Font.regular(17.0), textColor: environment.theme.list.itemAccentColor))))
) )
], ],
spacing: 6.0) spacing: 6.0)
@ -557,7 +557,7 @@ final class StarsTransactionsScreenComponent: Component {
component.gift() component.gift()
} }
) )
) ) : nil
) )
))] ))]
)), )),

View File

@ -0,0 +1,12 @@
{
"images" : [
{
"filename" : "privacy.pdf",
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@ -1987,7 +1987,12 @@ public final class WebAppController: ViewController, AttachmentContainable {
@objc private func morePressed(node: ContextReferenceContentNode, gesture: ContextGesture?) { @objc private func morePressed(node: ContextReferenceContentNode, gesture: ContextGesture?) {
let context = self.context let context = self.context
let presentationData = self.presentationData var presentationData = self.presentationData
if !presentationData.theme.overallDarkAppearance, let headerColor = self.controllerNode.headerColor {
if headerColor.lightness < 0.5 {
presentationData = presentationData.withUpdated(theme: defaultDarkPresentationTheme)
}
}
let peerId = self.peerId let peerId = self.peerId
let botId = self.botId let botId = self.botId
@ -1998,10 +2003,11 @@ public final class WebAppController: ViewController, AttachmentContainable {
let items = combineLatest(queue: Queue.mainQueue(), let items = combineLatest(queue: Queue.mainQueue(),
context.engine.messages.attachMenuBots(), context.engine.messages.attachMenuBots(),
context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: self.botId)) context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: self.botId)),
context.engine.data.get(TelegramEngine.EngineData.Item.Peer.BotCommands(id: self.botId))
) )
|> take(1) |> take(1)
|> map { [weak self] attachMenuBots, botPeer -> ContextController.Items in |> map { [weak self] attachMenuBots, botPeer, botCommands -> ContextController.Items in
var items: [ContextMenuItem] = [] var items: [ContextMenuItem] = []
let attachMenuBot = attachMenuBots.first(where: { $0.peer.id == botId && !$0.flags.contains(.notActivated) }) let attachMenuBot = attachMenuBots.first(where: { $0.peer.id == botId && !$0.flags.contains(.notActivated) })
@ -2068,15 +2074,7 @@ public final class WebAppController: ViewController, AttachmentContainable {
self?.controllerNode.webView?.reload() self?.controllerNode.webView?.reload()
}))) })))
// items.append(.action(ContextMenuActionItem(text: presentationData.strings.WebApp_PrivacyPolicy, icon: { theme in
// return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Reload"), color: theme.contextMenu.primaryColor)
// }, action: { [weak self] c, _ in
// c?.dismiss(completion: nil)
//
// self?.controllerNode.webView?.reload()
// })))
items.append(.action(ContextMenuActionItem(text: presentationData.strings.WebApp_TermsOfUse, icon: { theme in items.append(.action(ContextMenuActionItem(text: presentationData.strings.WebApp_TermsOfUse, icon: { theme in
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Info"), color: theme.contextMenu.primaryColor) return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Info"), color: theme.contextMenu.primaryColor)
}, action: { [weak self] c, _ in }, action: { [weak self] c, _ in
@ -2096,6 +2094,28 @@ public final class WebAppController: ViewController, AttachmentContainable {
}) })
}))) })))
if let botCommands {
for command in botCommands {
if command.text == "privacy" {
items.append(.action(ContextMenuActionItem(text: presentationData.strings.WebApp_PrivacyPolicy, icon: { theme in
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Privacy"), color: theme.contextMenu.primaryColor)
}, action: { [weak self] c, _ in
c?.dismiss(completion: nil)
guard let self else {
return
}
let _ = enqueueMessages(account: self.context.account, peerId: self.botId, messages: [.message(text: "/privacy", attributes: [], inlineStickers: [:], mediaReference: nil, threadId: nil, replyToMessageId: nil, replyToStoryId: nil, localGroupingKey: nil, correlationId: nil, bubbleUpEmojiOrStickersets: [])]).startStandalone()
if let botPeer, let navigationController = self.getNavigationController() {
(self.parentController() as? AttachmentController)?.minimizeIfNeeded()
self.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: self.context, chatLocation: .peer(botPeer)))
}
})))
}
}
}
if let _ = attachMenuBot, [.attachMenu, .settings, .generic].contains(source) { if let _ = attachMenuBot, [.attachMenu, .settings, .generic].contains(source) {
items.append(.action(ContextMenuActionItem(text: presentationData.strings.WebApp_RemoveBot, textColor: .destructive, icon: { theme in items.append(.action(ContextMenuActionItem(text: presentationData.strings.WebApp_RemoveBot, textColor: .destructive, icon: { theme in
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Delete"), color: theme.contextMenu.destructiveColor) return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Delete"), color: theme.contextMenu.destructiveColor)
@ -2117,7 +2137,7 @@ public final class WebAppController: ViewController, AttachmentContainable {
return ContextController.Items(content: .list(items)) return ContextController.Items(content: .list(items))
} }
let contextController = ContextController(presentationData: self.presentationData, source: .reference(WebAppContextReferenceContentSource(controller: self, sourceNode: node)), items: items, gesture: gesture) let contextController = ContextController(presentationData: presentationData, source: .reference(WebAppContextReferenceContentSource(controller: self, sourceNode: node)), items: items, gesture: gesture)
self.presentInGlobalOverlay(contextController) self.presentInGlobalOverlay(contextController)
} }