mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
Web app improvements
This commit is contained in:
parent
bc09798555
commit
e3866ea65b
@ -10411,3 +10411,5 @@ Sorry for the inconvenience.";
|
|||||||
"ChannelBoost.EnableColors" = "Enable Colors";
|
"ChannelBoost.EnableColors" = "Enable Colors";
|
||||||
"ChannelBoost.EnableColorsText" = "Your channel needs %1$@ to change channel color.\n\nAsk your **Premium** subscribers to boost your channel with this link:";
|
"ChannelBoost.EnableColorsText" = "Your channel needs %1$@ to change channel color.\n\nAsk your **Premium** subscribers to boost your channel with this link:";
|
||||||
"ChannelBoost.BoostAgain" = "Boost Again";
|
"ChannelBoost.BoostAgain" = "Boost Again";
|
||||||
|
|
||||||
|
"Settings.New" = "NEW";
|
||||||
|
@ -2421,6 +2421,25 @@ public func chatMessageImageFile(account: Account, userLocation: MediaResourceUs
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public func preloadedBotIcon(account: Account, fileReference: FileMediaReference) -> Signal<Bool, NoError> {
|
||||||
|
let signal = Signal<Bool, NoError> { subscriber in
|
||||||
|
let fetched = fetchedMediaResource(mediaBox: account.postbox.mediaBox, userLocation: .other, userContentType: MediaResourceUserContentType(file: fileReference.media), reference: fileReference.resourceReference(fileReference.media.resource)).start()
|
||||||
|
let dataDisposable = account.postbox.mediaBox.resourceData(fileReference.media.resource, option: .incremental(waitUntilFetchStatus: false)).start(next: { data in
|
||||||
|
if data.complete {
|
||||||
|
subscriber.putNext(true)
|
||||||
|
subscriber.putCompletion()
|
||||||
|
} else {
|
||||||
|
subscriber.putNext(false)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return ActionDisposable {
|
||||||
|
fetched.dispose()
|
||||||
|
dataDisposable.dispose()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return signal
|
||||||
|
}
|
||||||
|
|
||||||
public func instantPageImageFile(account: Account, userLocation: MediaResourceUserLocation, fileReference: FileMediaReference, fetched: Bool = false) -> Signal<(TransformImageArguments) -> DrawingContext?, NoError> {
|
public func instantPageImageFile(account: Account, userLocation: MediaResourceUserLocation, fileReference: FileMediaReference, fetched: Bool = false) -> Signal<(TransformImageArguments) -> DrawingContext?, NoError> {
|
||||||
return chatMessageFileDatas(account: account, userLocation: userLocation, fileReference: fileReference, progressive: false, fetched: fetched)
|
return chatMessageFileDatas(account: account, userLocation: userLocation, fileReference: fileReference, progressive: false, fetched: fetched)
|
||||||
|> map { value in
|
|> map { value in
|
||||||
|
@ -471,7 +471,7 @@ func _internal_acceptAttachMenuBotDisclaimer(postbox: Postbox, botId: PeerId) ->
|
|||||||
} |> ignoreValues
|
} |> ignoreValues
|
||||||
}
|
}
|
||||||
|
|
||||||
public struct AttachMenuBot {
|
public struct AttachMenuBot: Equatable {
|
||||||
public let peer: EnginePeer
|
public let peer: EnginePeer
|
||||||
public let shortName: String
|
public let shortName: String
|
||||||
public let icons: [AttachMenuBots.Bot.IconName: TelegramMediaFile]
|
public let icons: [AttachMenuBots.Bot.IconName: TelegramMediaFile]
|
||||||
|
@ -13551,6 +13551,26 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
|||||||
}
|
}
|
||||||
completion(controller, controller.mediaPickerContext)
|
completion(controller, controller.mediaPickerContext)
|
||||||
strongSelf.controllerNavigationDisposable.set(nil)
|
strongSelf.controllerNavigationDisposable.set(nil)
|
||||||
|
|
||||||
|
if bot.flags.contains(.notActivated) {
|
||||||
|
let alertController = webAppTermsAlertController(context: strongSelf.context, updatedPresentationData: strongSelf.updatedPresentationData, bot: bot, completion: { [weak self] allowWrite in
|
||||||
|
guard let self else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if bot.flags.contains(.showInSettingsDisclaimer) {
|
||||||
|
let _ = self.context.engine.messages.acceptAttachMenuBotDisclaimer(botId: bot.peer.id).startStandalone()
|
||||||
|
}
|
||||||
|
let _ = (self.context.engine.messages.addBotToAttachMenu(botId: bot.peer.id, allowWrite: allowWrite)
|
||||||
|
|> deliverOnMainQueue).startStandalone(error: { _ in
|
||||||
|
}, completed: { [weak controller] in
|
||||||
|
controller?.refresh()
|
||||||
|
})
|
||||||
|
},
|
||||||
|
dismissed: {
|
||||||
|
strongSelf.attachmentController?.dismiss(animated: true)
|
||||||
|
})
|
||||||
|
strongSelf.present(alertController, in: .window(.root))
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
@ -459,23 +459,12 @@ class ContactMultiselectionControllerImpl: ViewController, ContactMultiselection
|
|||||||
}
|
}
|
||||||
chatsNode.updateState { state in
|
chatsNode.updateState { state in
|
||||||
var state = state
|
var state = state
|
||||||
if "".isEmpty {
|
if state.selectedAdditionalCategoryIds.contains(id) {
|
||||||
if !state.selectedAdditionalCategoryIds.contains(id) {
|
state.selectedAdditionalCategoryIds.remove(id)
|
||||||
for id in state.selectedAdditionalCategoryIds {
|
removedTokenIds.append(id)
|
||||||
removedTokenIds.append(id)
|
|
||||||
state.selectedAdditionalCategoryIds.remove(id)
|
|
||||||
}
|
|
||||||
state.selectedAdditionalCategoryIds.insert(id)
|
|
||||||
addedToken = categoryToken
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
if state.selectedAdditionalCategoryIds.contains(id) {
|
state.selectedAdditionalCategoryIds.insert(id)
|
||||||
state.selectedAdditionalCategoryIds.remove(id)
|
addedToken = categoryToken
|
||||||
removedTokenIds.append(id)
|
|
||||||
} else {
|
|
||||||
state.selectedAdditionalCategoryIds.insert(id)
|
|
||||||
addedToken = categoryToken
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return state
|
return state
|
||||||
|
@ -9,12 +9,13 @@ final class PeerInfoScreenDisclosureItem: PeerInfoScreenItem {
|
|||||||
case text(String)
|
case text(String)
|
||||||
case badge(String, UIColor)
|
case badge(String, UIColor)
|
||||||
case semitransparentBadge(String, UIColor)
|
case semitransparentBadge(String, UIColor)
|
||||||
|
case titleBadge(String, UIColor)
|
||||||
|
|
||||||
var text: String {
|
var text: String {
|
||||||
switch self {
|
switch self {
|
||||||
case .none:
|
case .none:
|
||||||
return ""
|
return ""
|
||||||
case let .text(text), let .badge(text, _), let .semitransparentBadge(text, _):
|
case let .text(text), let .badge(text, _), let .semitransparentBadge(text, _), let .titleBadge(text, _):
|
||||||
return text
|
return text
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -23,7 +24,7 @@ final class PeerInfoScreenDisclosureItem: PeerInfoScreenItem {
|
|||||||
switch self {
|
switch self {
|
||||||
case .none, .text:
|
case .none, .text:
|
||||||
return nil
|
return nil
|
||||||
case let .badge(_, color), let .semitransparentBadge(_, color):
|
case let .badge(_, color), let .semitransparentBadge(_, color), let .titleBadge(_, color):
|
||||||
return color
|
return color
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -146,6 +147,9 @@ private final class PeerInfoScreenDisclosureItemNode: PeerInfoScreenItemNode {
|
|||||||
} else if case .badge = item.label {
|
} else if case .badge = item.label {
|
||||||
labelColorValue = presentationData.theme.list.itemCheckColors.foregroundColor
|
labelColorValue = presentationData.theme.list.itemCheckColors.foregroundColor
|
||||||
labelFont = Font.regular(15.0)
|
labelFont = Font.regular(15.0)
|
||||||
|
} else if case .titleBadge = item.label {
|
||||||
|
labelColorValue = presentationData.theme.list.itemCheckColors.foregroundColor
|
||||||
|
labelFont = Font.medium(11.0)
|
||||||
} else {
|
} else {
|
||||||
labelColorValue = presentationData.theme.list.itemSecondaryTextColor
|
labelColorValue = presentationData.theme.list.itemSecondaryTextColor
|
||||||
labelFont = titleFont
|
labelFont = titleFont
|
||||||
@ -178,7 +182,7 @@ private final class PeerInfoScreenDisclosureItemNode: PeerInfoScreenItemNode {
|
|||||||
if previousItem?.text != item.text {
|
if previousItem?.text != item.text {
|
||||||
self.iconNode.image = nil
|
self.iconNode.image = nil
|
||||||
self.iconDisposable.set((iconSignal
|
self.iconDisposable.set((iconSignal
|
||||||
|> deliverOnMainQueue).startStrict(next: { [weak self] icon in
|
|> deliverOnMainQueue).startStrict(next: { [weak self] icon in
|
||||||
if let self {
|
if let self {
|
||||||
self.iconNode.image = icon
|
self.iconNode.image = icon
|
||||||
}
|
}
|
||||||
@ -217,6 +221,13 @@ private final class PeerInfoScreenDisclosureItemNode: PeerInfoScreenItemNode {
|
|||||||
if self.labelBadgeNode.supernode == nil {
|
if self.labelBadgeNode.supernode == nil {
|
||||||
self.insertSubnode(self.labelBadgeNode, belowSubnode: self.labelNode)
|
self.insertSubnode(self.labelBadgeNode, belowSubnode: self.labelNode)
|
||||||
}
|
}
|
||||||
|
} else if case let .titleBadge(text, badgeColor) = item.label, !text.isEmpty {
|
||||||
|
if previousItem?.label.badgeColor != badgeColor {
|
||||||
|
self.labelBadgeNode.image = generateFilledRoundedRectImage(size: CGSize(width: 16.0, height: 16.0), cornerRadius: 5.0, color: badgeColor)?.stretchableImage(withLeftCapWidth: 6, topCapHeight: 6)
|
||||||
|
}
|
||||||
|
if self.labelBadgeNode.supernode == nil {
|
||||||
|
self.insertSubnode(self.labelBadgeNode, belowSubnode: self.labelNode)
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
self.labelBadgeNode.removeFromSupernode()
|
self.labelBadgeNode.removeFromSupernode()
|
||||||
}
|
}
|
||||||
@ -230,11 +241,18 @@ private final class PeerInfoScreenDisclosureItemNode: PeerInfoScreenItemNode {
|
|||||||
labelFrame = CGRect(origin: CGPoint(x: width - rightInset - badgeWidth + (badgeWidth - labelSize.width) / 2.0, y: floor((height - labelSize.height) / 2.0)), size: labelSize)
|
labelFrame = CGRect(origin: CGPoint(x: width - rightInset - badgeWidth + (badgeWidth - labelSize.width) / 2.0, y: floor((height - labelSize.height) / 2.0)), size: labelSize)
|
||||||
} else if case .badge = item.label {
|
} else if case .badge = item.label {
|
||||||
labelFrame = CGRect(origin: CGPoint(x: width - rightInset - badgeWidth + (badgeWidth - labelSize.width) / 2.0, y: floor((height - labelSize.height) / 2.0)), size: labelSize)
|
labelFrame = CGRect(origin: CGPoint(x: width - rightInset - badgeWidth + (badgeWidth - labelSize.width) / 2.0, y: floor((height - labelSize.height) / 2.0)), size: labelSize)
|
||||||
|
} else if case .titleBadge = item.label {
|
||||||
|
labelFrame = CGRect(origin: CGPoint(x: textFrame.maxX + 10.0, y: floor((height - labelSize.height) / 2.0) + 1.0), size: labelSize)
|
||||||
} else {
|
} else {
|
||||||
labelFrame = CGRect(origin: CGPoint(x: width - rightInset - labelSize.width, y: 12.0), size: labelSize)
|
labelFrame = CGRect(origin: CGPoint(x: width - rightInset - labelSize.width, y: 12.0), size: labelSize)
|
||||||
}
|
}
|
||||||
|
|
||||||
let labelBadgeNodeFrame = CGRect(origin: CGPoint(x: width - rightInset - badgeWidth, y: floorToScreenPixels(labelFrame.midY - badgeDiameter / 2.0)), size: CGSize(width: badgeWidth, height: badgeDiameter))
|
let labelBadgeNodeFrame: CGRect
|
||||||
|
if case .titleBadge = item.label {
|
||||||
|
labelBadgeNodeFrame = labelFrame.insetBy(dx: -4.0, dy: -2.0 + UIScreenPixel)
|
||||||
|
} else {
|
||||||
|
labelBadgeNodeFrame = CGRect(origin: CGPoint(x: width - rightInset - badgeWidth, y: floorToScreenPixels(labelFrame.midY - badgeDiameter / 2.0)), size: CGSize(width: badgeWidth, height: badgeDiameter))
|
||||||
|
}
|
||||||
|
|
||||||
self.activateArea.accessibilityLabel = item.text
|
self.activateArea.accessibilityLabel = item.text
|
||||||
self.activateArea.accessibilityValue = item.label.text
|
self.activateArea.accessibilityValue = item.label.text
|
||||||
|
@ -13,6 +13,7 @@ import TelegramNotices
|
|||||||
import AccountUtils
|
import AccountUtils
|
||||||
import DeviceAccess
|
import DeviceAccess
|
||||||
import PeerInfoVisualMediaPaneNode
|
import PeerInfoVisualMediaPaneNode
|
||||||
|
import PhotoResources
|
||||||
|
|
||||||
enum PeerInfoUpdatingAvatar {
|
enum PeerInfoUpdatingAvatar {
|
||||||
case none
|
case none
|
||||||
@ -494,20 +495,56 @@ func peerInfoScreenSettingsData(context: AccountContext, peerId: EnginePeer.Id,
|
|||||||
|
|
||||||
let botsKey = ValueBoxKey(length: 8)
|
let botsKey = ValueBoxKey(length: 8)
|
||||||
botsKey.setInt64(0, value: 0)
|
botsKey.setInt64(0, value: 0)
|
||||||
|
|
||||||
|
var iconLoaded: [EnginePeer.Id: Bool] = [:]
|
||||||
let bots = context.engine.data.subscribe(TelegramEngine.EngineData.Item.ItemCache.Item(collectionId: Namespaces.CachedItemCollection.attachMenuBots, id: botsKey))
|
let bots = context.engine.data.subscribe(TelegramEngine.EngineData.Item.ItemCache.Item(collectionId: Namespaces.CachedItemCollection.attachMenuBots, id: botsKey))
|
||||||
|> mapToSignal { entry -> Signal<[AttachMenuBot], NoError> in
|
|> mapToSignal { entry -> Signal<[AttachMenuBot], NoError> in
|
||||||
let bots: [AttachMenuBots.Bot] = entry?.get(AttachMenuBots.self)?.bots ?? []
|
let bots: [AttachMenuBots.Bot] = entry?.get(AttachMenuBots.self)?.bots ?? []
|
||||||
return context.engine.data.subscribe(
|
return context.engine.data.subscribe(
|
||||||
EngineDataMap(bots.map(\.peerId).map(TelegramEngine.EngineData.Item.Peer.Peer.init))
|
EngineDataMap(bots.map(\.peerId).map(TelegramEngine.EngineData.Item.Peer.Peer.init))
|
||||||
)
|
)
|
||||||
|> map { peersMap -> [AttachMenuBot] in
|
|> mapToSignal { peersMap -> Signal<[AttachMenuBot], NoError> in
|
||||||
var result: [AttachMenuBot] = []
|
var result: [Signal<AttachMenuBot?, NoError>] = []
|
||||||
for bot in bots {
|
for bot in bots {
|
||||||
if let maybePeer = peersMap[bot.peerId], let peer = maybePeer {
|
if let maybePeer = peersMap[bot.peerId], let peer = maybePeer {
|
||||||
result.append(AttachMenuBot(peer: peer, shortName: bot.name, icons: bot.icons, peerTypes: bot.peerTypes, flags: bot.flags))
|
let resultBot = AttachMenuBot(peer: peer, shortName: bot.name, icons: bot.icons, peerTypes: bot.peerTypes, flags: bot.flags)
|
||||||
|
if bot.flags.contains(.showInSettings) {
|
||||||
|
if let peer = PeerReference(peer._asPeer()), let icon = bot.icons[.iOSSettingsStatic] {
|
||||||
|
let fileReference: FileMediaReference = .attachBot(peer: peer, media: icon)
|
||||||
|
let signal: Signal<AttachMenuBot?, NoError>
|
||||||
|
if let _ = iconLoaded[peer.id] {
|
||||||
|
signal = .single(resultBot)
|
||||||
|
} else {
|
||||||
|
signal = .single(nil)
|
||||||
|
|> then(
|
||||||
|
preloadedBotIcon(account: context.account, fileReference: fileReference)
|
||||||
|
|> filter { $0 }
|
||||||
|
|> map { _ -> AttachMenuBot? in
|
||||||
|
return resultBot
|
||||||
|
}
|
||||||
|
|> afterNext { _ in
|
||||||
|
iconLoaded[peer.id] = true
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
result.append(signal)
|
||||||
|
} else {
|
||||||
|
result.append(.single(resultBot))
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result
|
return combineLatest(result)
|
||||||
|
|> map { bots in
|
||||||
|
var result: [AttachMenuBot] = []
|
||||||
|
for bot in bots {
|
||||||
|
if let bot {
|
||||||
|
result.append(bot)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|> distinctUntilChanged
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -818,25 +818,24 @@ private func settingsItems(data: PeerInfoScreenData?, context: AccountContext, p
|
|||||||
var appIndex = 1000
|
var appIndex = 1000
|
||||||
if let settings = data.globalSettings {
|
if let settings = data.globalSettings {
|
||||||
for bot in settings.bots {
|
for bot in settings.bots {
|
||||||
if bot.flags.contains(.showInSettings) {
|
let iconSignal: Signal<UIImage?, NoError>
|
||||||
let iconSignal: Signal<UIImage?, NoError>
|
if let peer = PeerReference(bot.peer._asPeer()), let icon = bot.icons[.iOSSettingsStatic] {
|
||||||
if let peer = PeerReference(bot.peer._asPeer()), let icon = bot.icons[.iOSSettingsStatic] {
|
let fileReference: FileMediaReference = .attachBot(peer: peer, media: icon)
|
||||||
let fileReference: FileMediaReference = .attachBot(peer: peer, media: icon)
|
iconSignal = instantPageImageFile(account: context.account, userLocation: .other, fileReference: fileReference, fetched: true)
|
||||||
iconSignal = instantPageImageFile(account: context.account, userLocation: .other, fileReference: fileReference, fetched: true)
|
|> map { generator -> UIImage? in
|
||||||
|> map { generator -> UIImage? in
|
let size = CGSize(width: 29.0, height: 29.0)
|
||||||
let size = CGSize(width: 29.0, height: 29.0)
|
let context = generator(TransformImageArguments(corners: ImageCorners(), imageSize: size, boundingSize: size, intrinsicInsets: .zero))
|
||||||
let context = generator(TransformImageArguments(corners: ImageCorners(), imageSize: size, boundingSize: size, intrinsicInsets: .zero))
|
return context?.generateImage()
|
||||||
return context?.generateImage()
|
|
||||||
}
|
|
||||||
let _ = freeMediaFileInteractiveFetched(account: context.account, userLocation: .other, fileReference: fileReference).startStandalone()
|
|
||||||
} else {
|
|
||||||
iconSignal = .single(UIImage(bundleImageName: "Settings/Menu/Websites")!)
|
|
||||||
}
|
}
|
||||||
items[.apps]!.append(PeerInfoScreenDisclosureItem(id: bot.peer.id.id._internalGetInt64Value(), text: bot.shortName, icon: nil, iconSignal: iconSignal, action: {
|
let _ = freeMediaFileInteractiveFetched(account: context.account, userLocation: .other, fileReference: fileReference).startStandalone()
|
||||||
interaction.openBotApp(bot)
|
} else {
|
||||||
}))
|
iconSignal = .single(UIImage(bundleImageName: "Settings/Menu/Websites")!)
|
||||||
appIndex += 1
|
|
||||||
}
|
}
|
||||||
|
let label: PeerInfoScreenDisclosureItem.Label = bot.flags.contains(.notActivated) || bot.flags.contains(.showInSettingsDisclaimer) ? .titleBadge(presentationData.strings.Settings_New, presentationData.theme.list.itemAccentColor) : .none
|
||||||
|
items[.apps]!.append(PeerInfoScreenDisclosureItem(id: bot.peer.id.id._internalGetInt64Value(), label: label, text: bot.shortName, icon: nil, iconSignal: iconSignal, action: {
|
||||||
|
interaction.openBotApp(bot)
|
||||||
|
}))
|
||||||
|
appIndex += 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4756,6 +4755,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro
|
|||||||
guard let self else {
|
guard let self else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
let showInstalledTooltip = !bot.flags.contains(.showInSettingsDisclaimer)
|
||||||
if bot.flags.contains(.showInSettingsDisclaimer) {
|
if bot.flags.contains(.showInSettingsDisclaimer) {
|
||||||
let _ = self.context.engine.messages.acceptAttachMenuBotDisclaimer(botId: bot.peer.id).startStandalone()
|
let _ = self.context.engine.messages.acceptAttachMenuBotDisclaimer(botId: bot.peer.id).startStandalone()
|
||||||
}
|
}
|
||||||
@ -4763,7 +4763,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro
|
|||||||
let _ = (self.context.engine.messages.addBotToAttachMenu(botId: bot.peer.id, allowWrite: allowWrite)
|
let _ = (self.context.engine.messages.addBotToAttachMenu(botId: bot.peer.id, allowWrite: allowWrite)
|
||||||
|> deliverOnMainQueue).startStandalone(error: { _ in
|
|> deliverOnMainQueue).startStandalone(error: { _ in
|
||||||
}, completed: {
|
}, completed: {
|
||||||
proceed(true)
|
proceed(showInstalledTooltip)
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
proceed(false)
|
proceed(false)
|
||||||
|
@ -413,6 +413,32 @@ public final class WebAppController: ViewController, AttachmentContainable {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
self.setupWebView()
|
||||||
|
}
|
||||||
|
|
||||||
|
deinit {
|
||||||
|
self.placeholderDisposable?.dispose()
|
||||||
|
self.iconDisposable?.dispose()
|
||||||
|
self.keepAliveDisposable?.dispose()
|
||||||
|
self.paymentDisposable?.dispose()
|
||||||
|
|
||||||
|
self.webView?.removeObserver(self, forKeyPath: #keyPath(WKWebView.estimatedProgress))
|
||||||
|
}
|
||||||
|
|
||||||
|
override func didLoad() {
|
||||||
|
super.didLoad()
|
||||||
|
|
||||||
|
guard let webView = self.webView else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
self.view.addSubview(webView)
|
||||||
|
webView.scrollView.insertSubview(self.topOverscrollNode.view, at: 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
func setupWebView() {
|
||||||
|
guard let controller = self.controller else {
|
||||||
|
return
|
||||||
|
}
|
||||||
if let url = controller.url, controller.source != .menu {
|
if let url = controller.url, controller.source != .menu {
|
||||||
self.queryId = controller.queryId
|
self.queryId = controller.queryId
|
||||||
if let parsedUrl = URL(string: url) {
|
if let parsedUrl = URL(string: url) {
|
||||||
@ -433,7 +459,7 @@ public final class WebAppController: ViewController, AttachmentContainable {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if controller.source.isSimple {
|
if controller.source.isSimple {
|
||||||
let _ = (context.engine.messages.requestSimpleWebView(botId: controller.botId, url: nil, source: .settings, themeParams: generateWebAppThemeParams(presentationData.theme))
|
let _ = (self.context.engine.messages.requestSimpleWebView(botId: controller.botId, url: nil, source: .settings, themeParams: generateWebAppThemeParams(presentationData.theme))
|
||||||
|> deliverOnMainQueue).start(next: { [weak self] result in
|
|> deliverOnMainQueue).start(next: { [weak self] result in
|
||||||
guard let strongSelf = self else {
|
guard let strongSelf = self else {
|
||||||
return
|
return
|
||||||
@ -443,7 +469,7 @@ public final class WebAppController: ViewController, AttachmentContainable {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
let _ = (context.engine.messages.requestWebView(peerId: controller.peerId, botId: controller.botId, url: controller.url, payload: controller.payload, themeParams: generateWebAppThemeParams(presentationData.theme), fromMenu: controller.source == .menu, replyToMessageId: controller.replyToMessageId, threadId: controller.threadId)
|
let _ = (self.context.engine.messages.requestWebView(peerId: controller.peerId, botId: controller.botId, url: controller.url, payload: controller.payload, themeParams: generateWebAppThemeParams(presentationData.theme), fromMenu: controller.source == .menu, replyToMessageId: controller.replyToMessageId, threadId: controller.threadId)
|
||||||
|> deliverOnMainQueue).start(next: { [weak self] result in
|
|> deliverOnMainQueue).start(next: { [weak self] result in
|
||||||
guard let strongSelf = self else {
|
guard let strongSelf = self else {
|
||||||
return
|
return
|
||||||
@ -469,25 +495,6 @@ public final class WebAppController: ViewController, AttachmentContainable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
deinit {
|
|
||||||
self.placeholderDisposable?.dispose()
|
|
||||||
self.iconDisposable?.dispose()
|
|
||||||
self.keepAliveDisposable?.dispose()
|
|
||||||
self.paymentDisposable?.dispose()
|
|
||||||
|
|
||||||
self.webView?.removeObserver(self, forKeyPath: #keyPath(WKWebView.estimatedProgress))
|
|
||||||
}
|
|
||||||
|
|
||||||
override func didLoad() {
|
|
||||||
super.didLoad()
|
|
||||||
|
|
||||||
guard let webView = self.webView else {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
self.view.addSubview(webView)
|
|
||||||
webView.scrollView.insertSubview(self.topOverscrollNode.view, at: 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc fileprivate func mainButtonPressed() {
|
@objc fileprivate func mainButtonPressed() {
|
||||||
if let mainButtonState = self.mainButtonState, !mainButtonState.isVisible || !mainButtonState.isEnabled {
|
if let mainButtonState = self.mainButtonState, !mainButtonState.isVisible || !mainButtonState.isEnabled {
|
||||||
return
|
return
|
||||||
@ -1624,6 +1631,10 @@ public final class WebAppController: ViewController, AttachmentContainable {
|
|||||||
self.updateTabBarAlpha(1.0, .immediate)
|
self.updateTabBarAlpha(1.0, .immediate)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public func refresh() {
|
||||||
|
self.controllerNode.setupWebView()
|
||||||
|
}
|
||||||
|
|
||||||
public func requestDismiss(completion: @escaping () -> Void) {
|
public func requestDismiss(completion: @escaping () -> Void) {
|
||||||
if self.controllerNode.needDismissConfirmation {
|
if self.controllerNode.needDismissConfirmation {
|
||||||
let actionSheet = ActionSheetController(presentationData: self.presentationData)
|
let actionSheet = ActionSheetController(presentationData: self.presentationData)
|
||||||
|
@ -353,7 +353,8 @@ public func webAppTermsAlertController(
|
|||||||
context: AccountContext,
|
context: AccountContext,
|
||||||
updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)?,
|
updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)?,
|
||||||
bot: AttachMenuBot,
|
bot: AttachMenuBot,
|
||||||
completion: @escaping (Bool) -> Void
|
completion: @escaping (Bool) -> Void,
|
||||||
|
dismissed: @escaping () -> Void = {}
|
||||||
) -> AlertController {
|
) -> AlertController {
|
||||||
let theme = defaultDarkColorPresentationTheme
|
let theme = defaultDarkColorPresentationTheme
|
||||||
let presentationData: PresentationData
|
let presentationData: PresentationData
|
||||||
@ -369,6 +370,7 @@ public func webAppTermsAlertController(
|
|||||||
completion(true)
|
completion(true)
|
||||||
dismissImpl?(true)
|
dismissImpl?(true)
|
||||||
}), TextAlertAction(type: .genericAction, title: presentationData.strings.Common_Cancel, action: {
|
}), TextAlertAction(type: .genericAction, title: presentationData.strings.Common_Cancel, action: {
|
||||||
|
dismissed()
|
||||||
dismissImpl?(true)
|
dismissImpl?(true)
|
||||||
})]
|
})]
|
||||||
|
|
||||||
@ -382,6 +384,11 @@ public func webAppTermsAlertController(
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
let controller = AlertController(theme: AlertControllerTheme(presentationData: presentationData), contentNode: contentNode)
|
let controller = AlertController(theme: AlertControllerTheme(presentationData: presentationData), contentNode: contentNode)
|
||||||
|
controller.dismissed = { outside in
|
||||||
|
if outside {
|
||||||
|
dismissed()
|
||||||
|
}
|
||||||
|
}
|
||||||
dismissImpl = { [weak controller] animated in
|
dismissImpl = { [weak controller] animated in
|
||||||
if animated {
|
if animated {
|
||||||
controller?.dismissAnimated()
|
controller?.dismissAnimated()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user