diff --git a/Nicegram/AppLovinAdProvider/BUILD b/Nicegram/AppLovinAdProvider/BUILD new file mode 100644 index 00000000000..4ecd84b83aa --- /dev/null +++ b/Nicegram/AppLovinAdProvider/BUILD @@ -0,0 +1,15 @@ +load("@build_bazel_rules_swift//swift:swift.bzl", "swift_library") + +swift_library( + name = "AppLovinAdProvider", + module_name = "AppLovinAdProvider", + srcs = glob([ + "Sources/**/*.swift", + ]), + deps = [ + "@AppLovin//:AppLovin", + "@swiftpkg_nicegram_assistant_ios//:Sources_NGAiChat", + ], + visibility = ["//visibility:public"], + +) diff --git a/Nicegram/AppLovinAdProvider/Sources/AppLovinAdProvider.swift b/Nicegram/AppLovinAdProvider/Sources/AppLovinAdProvider.swift new file mode 100644 index 00000000000..8b8d0f4fdcc --- /dev/null +++ b/Nicegram/AppLovinAdProvider/Sources/AppLovinAdProvider.swift @@ -0,0 +1,157 @@ +import AppLovinSDK +import NGAiChat +import NGCore +import NGRepoUser + +@available(iOS 13.0.0, *) +public class AppLovinAdProvider: NSObject { + + // MARK: - Dependencies + + private let ad: MARewardedAd + private let sdk: ALSdk + private let userRepository: UserRepository + + // MARK: - Logic + + private var adViewId: String? + private var showAdCompletion: ((ShowAdResult) -> Void)? + + // MARK: - Lifecycle + + public init(apiKey: String, adUnitIdentifier: String, userRepository: UserRepository) { + let sdk = ALSdk.shared(withKey: apiKey)! + + self.ad = MARewardedAd.shared( + withAdUnitIdentifier: adUnitIdentifier, + sdk: sdk + ) + self.sdk = sdk + self.userRepository = userRepository + + super.init() + + ad.delegate = self + } +} + +@available(iOS 13.0.0, *) +extension AppLovinAdProvider: AdProvider { + public func initialize() { + sdk.mediationProvider = "max" + sdk.initializeSdk() + } + + public func showAd() async -> ShowAdResult { + return await withCheckedContinuation { continuation in + self.showAd { result in + continuation.resume(returning: result) + } + } + } +} + +// MARK: - Private Functions + +@available(iOS 13.0.0, *) +private extension AppLovinAdProvider { + func showAd(completion: @escaping (ShowAdResult) -> Void) { + self.showAdCompletion = completion + + if ad.isReady { + internalShowAd() + } else { + ad.load() + } + } + + func internalShowAd() { + let id = UUID().uuidString + + let data = CustomDataDTO( + ad_view_id: id, + user_token: userRepository.getCurrentUser()?.telegramToken + ) + let dataJsonUrlEncoded: String? + if let dataJson = try? JSONEncoder().encode(data), + let dataJsonString = String(data: dataJson, encoding: .utf8) { + dataJsonUrlEncoded = dataJsonString.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed) + } else { + dataJsonUrlEncoded = nil + } + + self.adViewId = id + self.ad.show( + forPlacement: nil, + customData: dataJsonUrlEncoded + ) + } + + func completeSuccessfulAd() { + guard let adViewId else { + completeFailedAd(error: nil) + return + } + self.showAdCompletion?(.success(id: adViewId)) + self.clearCachedData() + } + + func completeFailedAd(error maError: MAError?) { + let error: Error? + if let maError { + error = MessageError(message: maError.message) + } else { + error = nil + } + + self.showAdCompletion?(.error(error)) + self.clearCachedData() + } + + func clearCachedData() { + self.adViewId = nil + self.showAdCompletion = nil + } +} + +// MARK: - MAAdDelegate + +@available(iOS 13.0.0, *) +extension AppLovinAdProvider: MARewardedAdDelegate { + public func didRewardUser(for ad: MAAd, with reward: MAReward) { + completeSuccessfulAd() + } + + public func didLoad(_ ad: MAAd) { + internalShowAd() + } + + public func didFailToLoadAd(forAdUnitIdentifier adUnitIdentifier: String, withError error: MAError) { + completeFailedAd(error: error) + } + + public func didDisplay(_ ad: MAAd) { + // Do nothing + } + + public func didHide(_ ad: MAAd) { + // Do nothing + } + + public func didClick(_ ad: MAAd) { + // Do nothing + } + + public func didFail(toDisplay ad: MAAd, withError error: MAError) { + completeFailedAd(error: error) + } +} + +// MARK: - Helpers + +private struct CustomDataDTO: Encodable { + let ad_view_id: String + let user_token: String? +} + + diff --git a/Nicegram/NGEnv/Sources/NGEnv.swift b/Nicegram/NGEnv/Sources/NGEnv.swift index a2c7ffdf288..a814df21938 100644 --- a/Nicegram/NGEnv/Sources/NGEnv.swift +++ b/Nicegram/NGEnv/Sources/NGEnv.swift @@ -24,6 +24,8 @@ public struct NGEnvObj: Decodable { public let remote_config_cache_duration_seconds: Double public let telegram_auth_bot: String public let google_cloud_api_key: String + public let applovin_api_key: String + public let applovin_ad_unit_id: String } func parseNGEnv() -> NGEnvObj { diff --git a/Nicegram/NGOnboarding/Sources/OnboardingViewController.swift b/Nicegram/NGOnboarding/Sources/OnboardingViewController.swift index b565580ce3c..b59735365f5 100644 --- a/Nicegram/NGOnboarding/Sources/OnboardingViewController.swift +++ b/Nicegram/NGOnboarding/Sources/OnboardingViewController.swift @@ -181,7 +181,7 @@ private extension OnboardingViewController { private extension OnboardingViewController { struct Constants { - static let inactivePageIndicatorColor = UIColor.legacyInactiveButton + static let inactivePageIndicatorColor = UIColor.hex("333334") static let activePageIndicatorColor = UIColor.white static let inactivePageIndicatorWidth = CGFloat(8) diff --git a/Nicegram/NGOnboarding/Sources/Views/OnboardingPageView.swift b/Nicegram/NGOnboarding/Sources/Views/OnboardingPageView.swift index 48880d7d3c9..863ff3ec52f 100644 --- a/Nicegram/NGOnboarding/Sources/Views/OnboardingPageView.swift +++ b/Nicegram/NGOnboarding/Sources/Views/OnboardingPageView.swift @@ -33,7 +33,7 @@ class OnboardingPageView: UIView { titleLabel.textAlignment = .center descriptionLabel.font = .systemFont(ofSize: 14, weight: .regular) - descriptionLabel.textColor = .subtitleFourth + descriptionLabel.textColor = .subtitle4 descriptionLabel.numberOfLines = 0 descriptionLabel.textAlignment = .center diff --git a/Package.resolved b/Package.resolved index 87e01678e5c..7c0e3506e62 100644 --- a/Package.resolved +++ b/Package.resolved @@ -42,7 +42,7 @@ "location" : "git@bitbucket.org:mobyrix/nicegram-assistant-ios.git", "state" : { "branch" : "develop", - "revision" : "18b31ec099ddf2862fd58498ef9c2476fc898479" + "revision" : "4387374d1e966763ae5add0d439e59ac0113e717" } }, { @@ -50,8 +50,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/SDWebImage/SDWebImage.git", "state" : { - "revision" : "20df851f2ae27efbaeeff73e9babdf4fd839a144", - "version" : "5.15.6" + "revision" : "3289629ef6cbf1ad8c3d1dccf0cf09ac97547cd6", + "version" : "5.15.7" } }, { diff --git a/WORKSPACE b/WORKSPACE index b68f9d36681..d84a71c03c8 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -74,12 +74,19 @@ http_archive( ) http_archive( - name = "FirebaseSDK", - urls = ["https://github.com/firebase/firebase-ios-sdk/releases/download/v8.11.0/Firebase.zip"], - build_file = "@//third-party/Firebase:BUILD", + name = "FirebaseSDK", + urls = ["https://github.com/firebase/firebase-ios-sdk/releases/download/v8.11.0/Firebase.zip"], + build_file = "@//third-party/Firebase:BUILD", sha256 = "ecf1013b5d616bb5d3acc7d9ddf257c06228c0a7364dd84d03989bae6af5ac5b", ) +http_archive( + name = "AppLovin", + urls = ["https://artifacts.applovin.com/ios/com/applovin/applovin-sdk/applovin-ios-sdk-11.9.0.zip"], + build_file = "@//third-party/AppLovin:BUILD", + sha256 = "0fc13c7b760b96a879aef234cf5894c3e5865ddf0a5152f4b94e5ca9737fd672", +) + # swift_bazel start http_archive( diff --git a/submodules/ChatListUI/Sources/ChatListController.swift b/submodules/ChatListUI/Sources/ChatListController.swift index b6f472c173e..f7d54c2e704 100644 --- a/submodules/ChatListUI/Sources/ChatListController.swift +++ b/submodules/ChatListUI/Sources/ChatListController.swift @@ -2044,10 +2044,14 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController if #available(iOS 13.0, *) { DispatchQueue.main.asyncAfter(deadline: .now() + .seconds(2)) { - AssistantUITgHelper.presentDailyRewardsIfNeeded() + self.ifNoOverlay { + AssistantUITgHelper.presentDailyRewardsIfNeeded() + } } } - SpecialOfferTgHelper.showSpecialOfferFromHomeIfNeeded() + ifNoOverlay { + SpecialOfferTgHelper.showSpecialOfferFromHomeIfNeeded() + } } func dismissAllUndoControllers() { @@ -3058,6 +3062,14 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController } } + private func ifNoOverlay(perform: () -> Void) { + guard let window = self.context.sharedContext.mainWindow, + !window.hasOverlayController() else { + return + } + perform() + } + public override var keyShortcuts: [KeyShortcut] { let strings = self.presentationData.strings diff --git a/submodules/Display/Source/WindowContent.swift b/submodules/Display/Source/WindowContent.swift index 5abf605134c..a297e21f908 100644 --- a/submodules/Display/Source/WindowContent.swift +++ b/submodules/Display/Source/WindowContent.swift @@ -1381,3 +1381,11 @@ public class Window1 { } } } + +// MARK: Nicegram +public extension Window1 { + func hasOverlayController() -> Bool { + return !topPresentationContext.controllers.isEmpty + } +} +// diff --git a/submodules/TelegramUI/BUILD b/submodules/TelegramUI/BUILD index ca042fdda97..a215c3ecf94 100644 --- a/submodules/TelegramUI/BUILD +++ b/submodules/TelegramUI/BUILD @@ -1,6 +1,7 @@ load("@build_bazel_rules_swift//swift:swift.bzl", "swift_library") NGDEPS = [ + "//Nicegram/AppLovinAdProvider:AppLovinAdProvider", "//Nicegram/NGCopyProtectedContent:NGCopyProtectedContent", "//Nicegram/NGLogging:NGLogging", "//Nicegram/NGData:NGData", diff --git a/submodules/TelegramUI/Sources/AppDelegate.swift b/submodules/TelegramUI/Sources/AppDelegate.swift index 4169d2bc6ec..2081e6bf3ad 100644 --- a/submodules/TelegramUI/Sources/AppDelegate.swift +++ b/submodules/TelegramUI/Sources/AppDelegate.swift @@ -1,4 +1,5 @@ // MARK: Nicegram imports +import AppLovinAdProvider import NGAiChat import NGAssistant import NGAnalytics @@ -404,15 +405,22 @@ private class UserInterfaceStyleObserverWindow: UIWindow { RemoteConfigServiceImpl.shared.prefetch() if #available(iOS 13.0, *) { + AiChatTgHelper.set( + appLovinAdProvider: AppLovinAdProvider( + apiKey: NGENV.applovin_api_key, + adUnitIdentifier: NGENV.applovin_ad_unit_id, + userRepository: RepoUserTgHelper.resolveUserRepository() + ) + ) AnalyticsTgHelper.set(firebaseSender: FirebaseAnalyticsSender()) RemoteConfigTgHelper.set(remoteConfig: RemoteConfigServiceImpl.shared) PremiumTgHelper.set(subscriptionService: SubscriptionAnalytics.SubscriptionService.shared) RepoUserTgHelper.initialize() + AiChatTgHelper.initializeAds() Task { await AssistantTgHelper.tryClaimDailyReward() } - } AiChatTgHelper.resolveTransactionsObserver().startObserving() diff --git a/swift_deps.bzl b/swift_deps.bzl index 72c8a61ee43..5d79d6e2b05 100644 --- a/swift_deps.bzl +++ b/swift_deps.bzl @@ -36,7 +36,7 @@ def swift_dependencies(): # branch: develop swift_package( name = "swiftpkg_nicegram_assistant_ios", - commit = "18b31ec099ddf2862fd58498ef9c2476fc898479", + commit = "4387374d1e966763ae5add0d439e59ac0113e717", dependencies_index = "@//:swift_deps_index.json", remote = "git@bitbucket.org:mobyrix/nicegram-assistant-ios.git", ) @@ -44,7 +44,7 @@ def swift_dependencies(): # version: 5.15.5 swift_package( name = "swiftpkg_sdwebimage", - commit = "20df851f2ae27efbaeeff73e9babdf4fd839a144", + commit = "3289629ef6cbf1ad8c3d1dccf0cf09ac97547cd6", dependencies_index = "@//:swift_deps_index.json", remote = "https://github.com/SDWebImage/SDWebImage.git", ) diff --git a/swift_deps_index.json b/swift_deps_index.json index 20b49bcd6a8..a5df8c201b2 100644 --- a/swift_deps_index.json +++ b/swift_deps_index.json @@ -380,7 +380,7 @@ "name": "swiftpkg_nicegram_assistant_ios", "identity": "nicegram-assistant-ios", "remote": { - "commit": "18b31ec099ddf2862fd58498ef9c2476fc898479", + "commit": "4387374d1e966763ae5add0d439e59ac0113e717", "remote": "git@bitbucket.org:mobyrix/nicegram-assistant-ios.git", "branch": "develop" } @@ -389,9 +389,9 @@ "name": "swiftpkg_sdwebimage", "identity": "sdwebimage", "remote": { - "commit": "20df851f2ae27efbaeeff73e9babdf4fd839a144", + "commit": "3289629ef6cbf1ad8c3d1dccf0cf09ac97547cd6", "remote": "https://github.com/SDWebImage/SDWebImage.git", - "version": "5.15.6" + "version": "5.15.7" } }, { diff --git a/third-party/AppLovin/BUILD b/third-party/AppLovin/BUILD new file mode 100644 index 00000000000..0223255ef97 --- /dev/null +++ b/third-party/AppLovin/BUILD @@ -0,0 +1,15 @@ +load( + "@build_bazel_rules_apple//apple:apple.bzl", + "apple_static_xcframework_import" +) + +apple_static_xcframework_import( + name = "AppLovin", + xcframework_imports = glob([ + "applovin-ios-sdk-11.9.0/AppLovinSDK.xcframework/**", + ]), + deps = [ + + ], + visibility = ["//visibility:public"], +) \ No newline at end of file diff --git a/versions.json b/versions.json index 038c8fb0fc7..d85b27941ad 100644 --- a/versions.json +++ b/versions.json @@ -1,5 +1,5 @@ { - "app": "1.2.8", + "app": "1.2.9", "bazel": "5.4.0", "xcode": "14.2" }