Skip to content

Commit

Permalink
Integrate Ad provider
Browse files Browse the repository at this point in the history
  • Loading branch information
joecks committed Jul 12, 2022
1 parent f24072e commit ee7c5d8
Show file tree
Hide file tree
Showing 5 changed files with 209 additions and 50 deletions.
23 changes: 23 additions & 0 deletions application/android/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,26 @@
android:label="@string/app_name"
tools:replace="android:fullBackupContent">

<!-- TODO replace YOUR_APP_ID with actual value -->
<meta-data
android:name="com.startapp.sdk.APPLICATION_ID"
android:value="206770102" />

<!-- &lt;!&ndash; TODO Return Ad controlled by the value below &ndash;&gt;-->
<!-- <meta-data-->
<!-- android:name="com.startapp.sdk.RETURN_ADS_ENABLED"-->
<!-- android:value="false" />-->

<!-- &lt;!&ndash; TODO Splash Ad controlled by the value below &ndash;&gt;-->
<!-- <provider-->
<!-- android:authorities="com.startapp.flutter.sdk.${applicationId}"-->
<!-- android:name="com.startapp.flutter.sdk.StartAppFlutterHelper"-->
<!-- android:exported="false"/>-->
<!-- -->
<!-- <meta-data-->
<!-- android:name="com.startapp.sdk.SPLASH_ADS_ENABLED"-->
<!-- android:value="false" />-->

<activity
android:name=".MainActivity"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
Expand Down Expand Up @@ -56,6 +76,7 @@
<meta-data
android:name="io.flutter.embedding.android.NormalTheme"
android:resource="@style/NormalTheme" />

</activity>
<!-- Don't delete the meta-data below.
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
Expand All @@ -71,4 +92,6 @@

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.VIBRATE" />


</manifest>
6 changes: 6 additions & 0 deletions application/ios/Runner/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,12 @@
<string>$(FLUTTER_BUILD_NAME)</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>com.startapp.sdk.APPLICATION_ID</key>
<string>206340173</string>
<key>com.startapp.sdk.RETURN_ADS_ENABLED</key>
<false/>
<key>com.startapp.sdk.SPLASH_ADS_ENABLED</key>
<false/>
<key>CFBundleURLTypes</key>
<array>
<dict>
Expand Down
5 changes: 4 additions & 1 deletion application/lib/domain/model/feature.dart
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,10 @@ enum Feature {
EnvironmentHelper.kIsDebug || EnvironmentHelper.kIsInternalFlavor,
'Open menu when clicking card header icon',
),
ads(Owner.Frank, false, 'Show ads in the feed based on logic'),
ads(
Owner.Frank,
EnvironmentHelper.kIsDebug || EnvironmentHelper.kIsInternalFlavor,
'Show ads in the feed based on logic'),
pushNotificationDeepLinks(Owner.Peter, EnvironmentHelper.kIsDebug,
'Allows to deep link to an article when tapping on push notification');

Expand Down
Original file line number Diff line number Diff line change
@@ -1,74 +1,198 @@
import 'package:flutter/widgets.dart';
import 'package:injectable/injectable.dart';
import 'package:startapp_sdk/startapp.dart';
import 'package:xayn_design/xayn_design.dart';
import 'package:xayn_discovery_app/infrastructure/di/di_config.dart';
import 'package:xayn_discovery_app/presentation/constants/r.dart';
import 'package:xayn_discovery_app/presentation/images/widget/cached_image.dart';
import 'package:xayn_discovery_app/presentation/images/widget/shader/shader.dart';
import 'package:xayn_discovery_app/presentation/images/widget/shader/static/static_painter.dart';
import 'package:xayn_discovery_app/presentation/widget/animation_player.dart';

class AdCard extends StatelessWidget {
late final ShaderBuilder primaryCardShader =
ShaderFactory.fromType(ShaderType.static);
@lazySingleton
class Start {
final startAppSdk = StartAppSdk();
//..setTestAdsEnabled(true);
}

class AdCard extends StatefulWidget {
final VoidCallback onPressed;

AdCard({
const AdCard({
Key? key,
required this.onPressed,
}) : super(key: key);

@override
State<AdCard> createState() => _AdCardState();
}

const double _kNoImageSize = 400.0;

class _AdCardState extends State<AdCard> {
late final ShaderBuilder primaryCardShader =
ShaderFactory.fromType(ShaderType.static);

late final startAppSdk = di.get<Start>().startAppSdk;
StartAppNativeAd? _nativeAd;

void loadAd() => startAppSdk
.loadNativeAd(
prefs: StartAppAdPreferences(
// somehow this is ignored
// desiredWidth: R.dimen.screenSize.width.floor(),
// desiredHeight: R.dimen.screenSize.height.floor(),
))
.then((ad) {
setState(() {
_nativeAd = ad;
});
}).onError<StartAppException>((ex, stackTrace) {
debugPrint("Error loading Native ad: ${ex.message}");
}).onError((error, stackTrace) {
debugPrint("Error loading Native ad: $error");
});

@override
void initState() {
super.initState();

loadAd();
}

String? get imageUrl => (_nativeAd?.imageUrl?.isNotEmpty == true
? _nativeAd?.imageUrl
: _nativeAd?.secondaryImageUrl)
?.replaceAll('_150', '_${R.dimen.screenSize.width.floor()}');

@override
Widget build(BuildContext context) {
final children = <Widget>[
SizedBox(height: R.dimen.unit),
Expanded(child: _buildAnimation()),
SizedBox(height: R.dimen.unit2),
Text(
'Buy buy buy!',
textAlign: TextAlign.center,
style: R.styles.lBoldStyle.copyWith(color: R.colors.brightText),
),
SizedBox(height: R.dimen.unit2),
Text(
'click this ad for great success!!',
textAlign: TextAlign.center,
style: R.styles.mStyle.copyWith(color: R.colors.brightText),
),
SizedBox(height: R.dimen.unit2_5),
_buildTakeSurveyBtn(),
];

return Stack(
children: [
Positioned.fill(
child: CustomPaint(
painter: StaticPainter(
shadowColor: R.colors.shadow,
if (_nativeAd == null) {
return const Center(
child: Text('No Ad'),
);
}

final nativeAd = _nativeAd!;
return StartAppNative(
nativeAd, (context, setState, nativeAd) => _buildContent(nativeAd));
}

Stack _buildContent(StartAppNativeAd nativeAd) {
final content = Padding(
padding: EdgeInsets.symmetric(
horizontal: R.dimen.unit4,
vertical: R.dimen.unit6,
),
child: Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.end,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(height: R.dimen.unit2),
Text(
nativeAd.title!,
textAlign: TextAlign.center,
style: R.styles.xlBoldStyle.copyWith(color: R.colors.brightText),
),
),
SizedBox(height: R.dimen.unit2),
Text(
nativeAd.description ?? '',
textAlign: TextAlign.center,
style: R.styles.mStyle.copyWith(color: R.colors.brightText),
),
SizedBox(height: R.dimen.unit2_5),
_buildCTAButton(text: nativeAd.callToAction!),
Text(
'Sponsored',
textAlign: TextAlign.center,
style: R.styles.sStyle.copyWith(color: R.colors.brightText),
),
],
));

return Stack(children: [
buildImage(R.colors.swipeCardBackgroundDefault),
content,
]);
}

Widget _buildCTAButton({required String text}) => SizedBox(
width: double.maxFinite,
child: AppRaisedButton.text(
text: text,
onPressed: loadAd,
),
Padding(
padding: EdgeInsets.symmetric(
horizontal: R.dimen.unit4,
vertical: R.dimen.unit6,
);

Widget buildImage(Color shadowColor) {
// allow opaque-when-loading, because the card will fade in on load completion.
buildBackgroundPane({required bool opaque}) =>
Container(color: opaque ? null : R.colors.swipeCardBackgroundHome);

getDeterministicNoImage() {
final deterministicRandom = imageUrl.hashCode % 4;
// position the animation at 1/3 from the top of the card
// this is translated by taking the height divided by 3, and then
// subtracting half of the animation's height
final topOffset = R.dimen.screenSize.height / 3 - _kNoImageSize / 2;
late String assetName;
late Color background;

switch (deterministicRandom) {
case 0:
background = R.colors.noImageBackgroundGreen;
assetName = R.assets.lottie.contextual.noImageA;
break;
case 1:
background = R.colors.noImageBackgroundPink;
assetName = R.assets.lottie.contextual.noImageB;
break;
case 2:
background = R.colors.noImageBackgroundPurple;
assetName = R.assets.lottie.contextual.noImageC;
break;
default:
background = R.colors.noImageBackgroundOrange;
assetName = R.assets.lottie.contextual.noImageD;
break;
}

return Container(
alignment: Alignment.topCenter,
color: background,
child: Padding(
padding: EdgeInsets.only(
// needs to be a double between [.0 and maxFinite]
// if < 0 then we just use zero
top: topOffset.clamp(.0, double.maxFinite),
),
child: Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
children: children,
child: AnimationPlayer.assetUnrestrictedSize(
assetName,
playsFromStart: false,
),
),
],
);
}

if (imageUrl == null) return getDeterministicNoImage();

return CachedImage(
singleFrameOnly: false,
uri: Uri.parse(imageUrl!),
width: R.dimen.screenSize.width.floor(),
height: R.dimen.screenSize.height.floor(),
shadowColor: shadowColor,
loadingBuilder: (_, __) => buildBackgroundPane(opaque: true),
errorBuilder: (_) => buildBackgroundPane(opaque: false),
noImageBuilder: (_) => getDeterministicNoImage(),
);
}
}

Widget _buildAnimation() =>
AnimationPlayer.assetUnrestrictedSize(R.assets.lottie.bookmarkClick);
String? cutString(String? input, int length) {
if (input != null && input.length > length) {
return '${input.substring(0, length)}...';
}

Widget _buildTakeSurveyBtn() => SizedBox(
width: double.maxFinite,
child: AppRaisedButton.text(
text: 'OMG I WANT THIS NOW!!!',
onPressed: onPressed,
),
);
return input;
}
3 changes: 3 additions & 0 deletions application/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,9 @@ dependencies:
url: [email protected]:Bestfastfire/super_rich_text.git
ref: f9d3963421682e2e0dd99c1ab553b99e38766ea1
system_info2: 2.0.3
startapp_sdk:
git:
url: https://github.com/StartApp-SDK/flutter-plugin
quiver: 3.0.1+1
url_launcher: 6.0.20
uuid: 3.0.6
Expand Down

0 comments on commit ee7c5d8

Please sign in to comment.