Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
114 changes: 57 additions & 57 deletions ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -42,67 +42,67 @@ PODS:
- file_picker (0.0.1):
- DKImagePickerController/PhotoGallery
- Flutter
- Firebase/CoreOnly (12.14.0):
- FirebaseCore (~> 12.14.0)
- Firebase/Crashlytics (12.14.0):
- Firebase/CoreOnly (12.17.0):
- FirebaseCore (~> 12.17.0)
- Firebase/Crashlytics (12.17.0):
- Firebase/CoreOnly
- FirebaseCrashlytics (~> 12.14.0)
- firebase_analytics (12.4.2):
- FirebaseCrashlytics (~> 12.17.0)
- firebase_analytics (12.4.6):
- firebase_core
- FirebaseAnalytics (= 12.14.0)
- FirebaseAnalytics (= 12.17.0)
- Flutter
- firebase_core (4.10.0):
- Firebase/CoreOnly (= 12.14.0)
- firebase_core (4.13.0):
- Firebase/CoreOnly (= 12.17.0)
- Flutter
- firebase_crashlytics (5.2.3):
- Firebase/Crashlytics (= 12.14.0)
- firebase_crashlytics (5.2.7):
- Firebase/Crashlytics (= 12.17.0)
- firebase_core
- Flutter
- FirebaseAnalytics (12.14.0):
- FirebaseAnalytics/Default (= 12.14.0)
- FirebaseCore (~> 12.14.0)
- FirebaseInstallations (~> 12.14.0)
- FirebaseAnalytics (12.17.0):
- FirebaseAnalytics/Default (= 12.17.0)
- FirebaseCore (~> 12.17.0)
- FirebaseInstallations (~> 12.17.0)
- GoogleUtilities/AppDelegateSwizzler (~> 8.1)
- GoogleUtilities/MethodSwizzler (~> 8.1)
- GoogleUtilities/Network (~> 8.1)
- "GoogleUtilities/NSData+zlib (~> 8.1)"
- nanopb (~> 3.30910.0)
- FirebaseAnalytics/Default (12.14.0):
- FirebaseCore (~> 12.14.0)
- FirebaseInstallations (~> 12.14.0)
- GoogleAppMeasurement/Default (= 12.14.0)
- FirebaseAnalytics/Default (12.17.0):
- FirebaseCore (~> 12.17.0)
- FirebaseInstallations (~> 12.17.0)
- GoogleAppMeasurement/Default (= 12.17.0)
- GoogleUtilities/AppDelegateSwizzler (~> 8.1)
- GoogleUtilities/MethodSwizzler (~> 8.1)
- GoogleUtilities/Network (~> 8.1)
- "GoogleUtilities/NSData+zlib (~> 8.1)"
- nanopb (~> 3.30910.0)
- FirebaseCore (12.14.0):
- FirebaseCoreInternal (~> 12.14.0)
- FirebaseCore (12.17.0):
- FirebaseCoreInternal (~> 12.17.0)
- GoogleUtilities/Environment (~> 8.1)
- GoogleUtilities/Logger (~> 8.1)
- FirebaseCoreExtension (12.14.0):
- FirebaseCore (~> 12.14.0)
- FirebaseCoreInternal (12.14.0):
- FirebaseCoreExtension (12.17.0):
- FirebaseCore (~> 12.17.0)
- FirebaseCoreInternal (12.17.0):
- "GoogleUtilities/NSData+zlib (~> 8.1)"
- FirebaseCrashlytics (12.14.0):
- FirebaseCore (~> 12.14.0)
- FirebaseInstallations (~> 12.14.0)
- FirebaseRemoteConfigInterop (~> 12.14.0)
- FirebaseSessions (~> 12.14.0)
- FirebaseCrashlytics (12.17.0):
- FirebaseCore (~> 12.17.0)
- FirebaseInstallations (~> 12.17.0)
- FirebaseRemoteConfigInterop (~> 12.17.0)
- FirebaseSessions (~> 12.17.0)
- GoogleDataTransport (~> 10.1)
- GoogleUtilities/Environment (~> 8.1)
- nanopb (~> 3.30910.0)
- PromisesObjC (~> 2.4)
- FirebaseInstallations (12.14.0):
- FirebaseCore (~> 12.14.0)
- FirebaseInstallations (12.17.0):
- FirebaseCore (~> 12.17.0)
- GoogleUtilities/Environment (~> 8.1)
- GoogleUtilities/UserDefaults (~> 8.1)
- PromisesObjC (~> 2.4)
- FirebaseRemoteConfigInterop (12.14.0)
- FirebaseSessions (12.14.0):
- FirebaseCore (~> 12.14.0)
- FirebaseCoreExtension (~> 12.14.0)
- FirebaseInstallations (~> 12.14.0)
- FirebaseRemoteConfigInterop (12.17.0)
- FirebaseSessions (12.17.0):
- FirebaseCore (~> 12.17.0)
- FirebaseCoreExtension (~> 12.17.0)
- FirebaseInstallations (~> 12.17.0)
- GoogleDataTransport (~> 10.1)
- GoogleUtilities/Environment (~> 8.1)
- GoogleUtilities/UserDefaults (~> 8.1)
Expand All @@ -127,29 +127,29 @@ PODS:
- GoogleUtilities/Logger (~> 8.1)
- GoogleUtilities/Network (~> 8.1)
- nanopb (~> 3.30910.0)
- GoogleAppMeasurement/Core (12.14.0):
- GoogleAppMeasurement/Core (12.17.0):
- GoogleUtilities/AppDelegateSwizzler (~> 8.1)
- GoogleUtilities/MethodSwizzler (~> 8.1)
- GoogleUtilities/Network (~> 8.1)
- "GoogleUtilities/NSData+zlib (~> 8.1)"
- nanopb (~> 3.30910.0)
- GoogleAppMeasurement/Default (12.14.0):
- GoogleAppMeasurement/Default (12.17.0):
- GoogleAdsOnDeviceConversion (~> 3.6.0)
- GoogleAppMeasurement/Core (= 12.14.0)
- GoogleAppMeasurement/IdentitySupport (= 12.14.0)
- GoogleAppMeasurement/Core (= 12.17.0)
- GoogleAppMeasurement/IdentitySupport (= 12.17.0)
- GoogleUtilities/AppDelegateSwizzler (~> 8.1)
- GoogleUtilities/MethodSwizzler (~> 8.1)
- GoogleUtilities/Network (~> 8.1)
- "GoogleUtilities/NSData+zlib (~> 8.1)"
- nanopb (~> 3.30910.0)
- GoogleAppMeasurement/IdentitySupport (12.14.0):
- GoogleAppMeasurement/Core (= 12.14.0)
- GoogleAppMeasurement/IdentitySupport (12.17.0):
- GoogleAppMeasurement/Core (= 12.17.0)
- GoogleUtilities/AppDelegateSwizzler (~> 8.1)
- GoogleUtilities/MethodSwizzler (~> 8.1)
- GoogleUtilities/Network (~> 8.1)
- "GoogleUtilities/NSData+zlib (~> 8.1)"
- nanopb (~> 3.30910.0)
- GoogleDataTransport (10.1.0):
- GoogleDataTransport (10.1.1):
- nanopb (~> 3.30910.0)
- PromisesObjC (~> 2.4)
- GoogleUserMessagingPlatform (3.1.0)
Expand Down Expand Up @@ -297,27 +297,27 @@ SPEC CHECKSUMS:
DKImagePickerController: 946cec48c7873164274ecc4624d19e3da4c1ef3c
DKPhotoGallery: b3834fecb755ee09a593d7c9e389d8b5d6deed60
file_picker: a0560bc09d61de87f12d246fc47d2119e6ef37be
Firebase: 7cc10425300768ec86292688af5cb228f0604bde
firebase_analytics: 9ea6c22e60e1d37ee76772de57b4addddb03e276
firebase_core: 383e19b49a08df5d7a6cf5017616de6a357ed7af
firebase_crashlytics: 88273c8643a258ff74ee26203e319a782aa8b12c
FirebaseAnalytics: 99364329a3ea4d1ab4a3744b5464371b7351c481
FirebaseCore: 4939b340b9c598dc1f965d68f8fe57e630b65407
FirebaseCoreExtension: ee3e3697acea1062288b1900bcdcab4d59ab93b4
FirebaseCoreInternal: 090369a5fffd7423cf88006ab4d2ccc2173a8db9
FirebaseCrashlytics: 1fabfdca902d0706cb51bf839edb58b45db421ff
FirebaseInstallations: 7cdc919e29dc54306edeffdbdc1eed1a40d7d1e7
FirebaseRemoteConfigInterop: 40ecdce5a4feee7643b81342f32f1cded905bb07
FirebaseSessions: c9e7b7829265454f08cb68f7f8a6650c9b221bd4
Firebase: e8400c058702940d53f31fc0653e4e7a06332326
firebase_analytics: 4dc4986181e6f58d24f879716f175a53e837c914
firebase_core: c94f9efeed0ded590b7eecaf6110a374eb865d7a
firebase_crashlytics: 36d85edffd4bfd025c13025b0009f63754983536
FirebaseAnalytics: 652858a1424ca8c549b62261876814ff56dff650
FirebaseCore: 52d4512296984a44a8c8870c6494870fc7aeee2f
FirebaseCoreExtension: be2d62bfcf339c7dd94646d43d910aaf37fe17c1
FirebaseCoreInternal: 3b310521b34a51ce3a6c605e4618b9aef8f6c112
FirebaseCrashlytics: 33f4bb8b7140f1864a4db6b819edf36e6d2b1b0d
FirebaseInstallations: bd8e80f51d4c8bdc6c872011dede0b800c5b49ea
FirebaseRemoteConfigInterop: 785e617ae4cbc778eea97dde952b88fb934e11ff
FirebaseSessions: 83cf567ddcef20303eb85e003dfdbe030343ef8d
Flutter: cabc95a1d2626b1b06e7179b784ebcf0c0cde467
flutter_native_splash: c32d145d68aeda5502d5f543ee38c192065986cf
flutter_secure_storage_darwin: acdb3f316ed05a3e68f856e0353b133eec373a23
flutter_timezone: 7c838e17ffd4645d261e87037e5bebf6d38fe544
Google-Mobile-Ads-SDK: 1dfb0c3cb46c7e2b00b0f4de74a1e06d9ea25d67
google_mobile_ads: 535223588a6791b7a3cc3513a1bc7b89d12f3e62
GoogleAdsOnDeviceConversion: e3b71da24ff4cf01cf520756ac1c2b93c07b86ff
GoogleAppMeasurement: 1987ffa55055dfb22c52e363c31aa50c1e11d349
GoogleDataTransport: aae35b7ea0c09004c3797d53c8c41f66f219d6a7
GoogleAppMeasurement: 2234668e2451f9da37b93dad7830e457600c008f
GoogleDataTransport: a24e58982ab3ba2f64d79613e027fe7f57e88539
GoogleUserMessagingPlatform: befe603da6501006420c206222acd449bba45a9c
GoogleUtilities: 766ace00c6b10d8148408f329d10c4f051931850
nanopb: fad817b59e0457d11a5dfbde799381cd727c1275
Expand All @@ -333,4 +333,4 @@ SPEC CHECKSUMS:

PODFILE CHECKSUM: 4d58577ccbfce16136516f00e34396d0d7432493

COCOAPODS: 1.16.2
COCOAPODS: 1.17.0
31 changes: 8 additions & 23 deletions lib/app/ad_director_provider.dart
Original file line number Diff line number Diff line change
Expand Up @@ -14,19 +14,19 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
/// Cached environment details to avoid repeated timezone/platform detection.
/// This is computed once at app startup and used throughout the app lifecycle.
class AdEnvironment {
final bool isIranian;
final bool adMobIsDisabled;
final bool isMobilePlatform;
final bool shouldInitializeAdMob;

const AdEnvironment({
required this.isIranian,
required this.adMobIsDisabled,
required this.isMobilePlatform,
required this.shouldInitializeAdMob,
});

@override
String toString() =>
'AdEnvironment(isIranian: $isIranian, isMobile: $isMobilePlatform, initAdMob: $shouldInitializeAdMob)';
'AdEnvironment(isIranian: $adMobIsDisabled, isMobile: $isMobilePlatform, initAdMob: $shouldInitializeAdMob)';
}
Comment on lines 28 to 30

/// Provider for ad environment configuration
Expand All @@ -39,13 +39,12 @@ class AdEnvironment {
/// - Desktop platforms: Don't initialize AdMob, only use internal ads
/// - Mobile non-Iranian: Initialize AdMob, use both strategies
final adEnvironmentProvider = FutureProvider<AdEnvironment>((ref) async {

final isIranian = await AdvertiseDirector.isIranianUser();
final adMobIsDisabled = await AdvertiseDirector.shouldUseInternalAds(ref);
final isMobile = Platform.isAndroid || Platform.isIOS;
final shouldInitAdMob = isMobile && !isIranian;
final shouldInitAdMob = isMobile && !adMobIsDisabled;

final environment = AdEnvironment(
isIranian: isIranian,
adMobIsDisabled: adMobIsDisabled,
isMobilePlatform: isMobile,
shouldInitializeAdMob: shouldInitAdMob,
);
Expand All @@ -63,7 +62,6 @@ final adEnvironmentProvider = FutureProvider<AdEnvironment>((ref) async {
/// - Manages connection state listener lifecycle
class AdStrategyManager {
final Ref _ref;
final AdEnvironment _environment;
final InternalAdStrategy _internalStrategy;
final GoogleAdStrategy? _googleStrategy; // null for Iranian/desktop users
final bool _hasGoogleStrategy;
Expand All @@ -77,7 +75,6 @@ class AdStrategyManager {
required InternalAdStrategy internalStrategy,
required GoogleAdStrategy? googleStrategy,
}) : _ref = ref,
_environment = environment,
_internalStrategy = internalStrategy,
_googleStrategy = googleStrategy,
_hasGoogleStrategy = googleStrategy != null;
Expand All @@ -89,7 +86,6 @@ class AdStrategyManager {
Color backgroundColor = const Color(0xFF19312F),
double cornerRadius = 10.0,
}) {

// Create InternalAdStrategy (always needed)
final internalStrategy = InternalAdStrategy(
backgroundColor: backgroundColor,
Expand Down Expand Up @@ -119,7 +115,6 @@ class AdStrategyManager {

/// Initialize connection state listener
void _initializeConnectionListener() {

// Listen to connection changes and delegate to strategies
_connectionSubscription = _ref.listen(conn.connectionStateProvider, (
previous,
Expand Down Expand Up @@ -170,8 +165,6 @@ class AdStrategyManager {
required conn.ConnectionStatus previous,
required conn.ConnectionStatus current,
}) {


// When connecting: notify internal strategy
if (current == conn.ConnectionStatus.connected &&
previous != conn.ConnectionStatus.connected) {
Expand All @@ -187,7 +180,6 @@ class AdStrategyManager {
// This handles: connected → disconnecting, connected → disconnected
else if (previous == conn.ConnectionStatus.connected &&
current != conn.ConnectionStatus.connected) {

_internalStrategy.onConnectionStateChanged(
ref: _ref,
previous: previous,
Expand All @@ -202,15 +194,14 @@ class AdStrategyManager {
if (current == conn.ConnectionStatus.disconnected &&
previous != conn.ConnectionStatus.disconnected) {
if (_hasGoogleStrategy) {

_googleStrategy!.onConnectionStateChanged(
ref: _ref,
previous: previous,
current: current,
hasInitialized: true,
onRefreshNeeded: () => _googleStrategy.loadAd(ref: _ref),
);
}
}
}
}

Expand All @@ -225,10 +216,8 @@ class AdStrategyManager {
// This handles the case where app starts in disconnected state (no state change)
final initialConnectionState = _ref.read(conn.connectionStateProvider);


if (initialConnectionState.status == conn.ConnectionStatus.disconnected &&
_hasGoogleStrategy) {

// Simulate a state change to trigger ad load
final googleStrategy = _googleStrategy!;
googleStrategy.onConnectionStateChanged(
Expand All @@ -240,7 +229,6 @@ class AdStrategyManager {
);
} else if (initialConnectionState.status ==
conn.ConnectionStatus.connected) {

// Simulate a state change to trigger internal ad load
_internalStrategy.onConnectionStateChanged(
ref: _ref,
Expand Down Expand Up @@ -305,15 +293,12 @@ class AdStrategyManager {
/// - Session-scoped provider (NOT autoDispose) to prevent recreation churn
/// - Manager holds static NativeAd which should persist across widget rebuilds
/// - ref.onDispose: Ensures manager.dispose() is called on app exit
final adStrategyManagerProvider = Provider<AdStrategyManager?>((
ref,
) {
final adStrategyManagerProvider = Provider<AdStrategyManager?>((ref) {
// Wait for environment to be ready
final environmentAsync = ref.watch(adEnvironmentProvider);

return environmentAsync.when(
data: (environment) {

// Create manager with environment
final manager = AdStrategyManager.create(
ref: ref,
Expand Down
Loading