Skip to content

Commit

Permalink
Merge pull request #1 from ammarahm-ed/master
Browse files Browse the repository at this point in the history
Feature: Create Expo plugin (ammarahm-ed#323)
  • Loading branch information
chipokhiem authored Mar 15, 2023
2 parents ea9c838 + 3948fcc commit 7c21a48
Show file tree
Hide file tree
Showing 15 changed files with 24,829 additions and 9,658 deletions.
2 changes: 2 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
// @generated by expo-module-scripts
module.exports = require('expo-module-scripts/eslintrc.base.js');
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,10 @@ iOSInjectionProject/
.expo
__generated__

# expo plugin files

/plugin/src/*js

### ReactNative.Node Stack ###
# Logs

Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ We on the other hand do not load ads in a WebView. We use a more complex, Native

## Can I design the ads myself?

Yes absolutely you can! There are no limiations. You can design ads that look just like your App's design and colors.
Yes absolutely you can! There are no limitations. You can design ads that look just like your App's design and colors.

## I need other ad formats too, which library do you recommend?
There are a bunch of projects trying to figure out showing ads on react-native. Most are not maintained properly. I would recommend that you use [react-native-admob/admob](https://github.com/react-native-admob/admob) by [@wjaykim](https://github.com/wjaykim). Banners, Interstitials, AdOpen and Rewarded, Rewarded Interstital ads are supported.
Expand Down
1 change: 1 addition & 0 deletions app.plugin.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module.exports = require('./plugin/build/withAdmobNativeAds');
19 changes: 19 additions & 0 deletions docs/docs/installation.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,25 @@ Install `react-native-vector-icons` to use `StarRatingView`.

Complete setup of [react-native-vector-icons ](https://github.com/oblador/react-native-vector-icons) for iOS & Android.

## Expo Setup

Add your AdMob App IDs to `app.json` or `app.config.js`.

```
{
"expo": {
"plugins": [
[
"react-native-admob-native-ads",
{
"androidAppId": "ca-app-pub-xxxxxxxxxxxxxxxx~yyyyyyyyyy",
"iosAppId": "ca-app-pub-xxxxxxxxxxxxxxxx~yyyyyyyyyy"
}
]
]
}
}
```

## Android Setup

Expand Down
34,136 changes: 24,480 additions & 9,656 deletions package-lock.json

Large diffs are not rendered by default.

20 changes: 19 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,26 @@
"private": false,
"devDependencies": {
"@react-native-community/eslint-config": "^3.0.0",
"@tsconfig/node16": "^1.0.3",
"@tsconfig/react-native": "^2.0.3",
"@types/jest": "^29.2.5",
"@types/node": "^18.11.18",
"@types/react": "^18.0.26",
"@types/react-native": "^0.70.8",
"@types/react-test-renderer": "^18.0.0",
"eslint": "^7.31.0",
"eslint-config-prettier": "^8.3.0",
"prettier": "^2.3.2"
"expo": "^47.0.12",
"expo-module-scripts": "^3.0.4",
"prettier": "^2.3.2",
"typescript": "^4.9.4"
},
"scripts": {
"build": "expo-module build",
"clean": "expo-module clean",
"test": "expo-module test",
"prepare": "expo-module prepare",
"prepublishOnly": "expo-module prepublishOnly",
"expo-module": "expo-module"
}
}
1 change: 1 addition & 0 deletions plugin/jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module.exports = require('expo-module-scripts/jest-preset-plugin');
17 changes: 17 additions & 0 deletions plugin/src/withAdmobNativeAds.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import {ConfigPlugin, createRunOncePlugin} from '@expo/config-plugins';
import { withAdmobNativeAdsAndroid } from './withAdmobNativeAdsAndroid';
import { withAdmobNativeAdsGradle } from './withAdmobNativeAdsAppBuildGradle';
import { withAdmobNativeAdsPlist } from './withAdmobNativeAdsInfoPlist';
import { withAdmobNativeAdsPodNat } from './withAdmobNativeAdsPod';

const pkg = require('react-native-admob-native-ads/package.json');

const withAdmobNativeAds: ConfigPlugin = (config, props) => {
config = withAdmobNativeAdsAndroid(config, props);
config = withAdmobNativeAdsGradle(config);
config = withAdmobNativeAdsPlist(config, props);
config = withAdmobNativeAdsPodNat(config);
return config;
};

export default createRunOncePlugin(withAdmobNativeAds, pkg.name, pkg.version);
29 changes: 29 additions & 0 deletions plugin/src/withAdmobNativeAdsAndroid.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import {
AndroidConfig,
ConfigPlugin,
withAndroidManifest,
} from '@expo/config-plugins';

const { addMetaDataItemToMainApplication, getMainApplicationOrThrow } = AndroidConfig.Manifest;

const withAdmobNativeAdsManifest: ConfigPlugin = (config, props) => {
return withAndroidManifest(config, (config) => {
config.modResults = setAdmobNativeAdsConfig(config.modResults, props);
return config;
});
};

const setAdmobNativeAdsConfig = (androidManifest: AndroidConfig.Manifest.AndroidManifest, props: any) => {
let mainApplication = getMainApplicationOrThrow(androidManifest);
addMetaDataItemToMainApplication(
mainApplication,
'com.google.android.gms.ads.APPLICATION_ID',
props.androidAppId
);

return androidManifest;
};

export const withAdmobNativeAdsAndroid: ConfigPlugin = (config, props) => {
return withAdmobNativeAdsManifest(config, props);
};
35 changes: 35 additions & 0 deletions plugin/src/withAdmobNativeAdsAppBuildGradle.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { withDangerousMod, withPlugins } from '@expo/config-plugins';
import { resolve } from 'path';
import { writeFileSync, readFileSync } from 'fs';

const withAdmobNativeAdsAppBuildGradle = (config: any) => {
return withDangerousMod(config, [
'android',
(cfg: any) => {
const { platformProjectRoot } = cfg.modRequest;
const build = resolve(platformProjectRoot, 'app/build.gradle');
const contents = readFileSync(build, 'utf-8');
const lines = contents.split('\n');
const index = lines.findIndex((line: any) =>
/dependencies\s{/.test(line)
);

writeFileSync(
build,
[
...lines.slice(0, index + 1),
` implementation "com.google.android.gms:play-services-ads:21.3.0"`,
...lines.slice(index + 1),
].join('\n')
);

return cfg;
}
]);
};

export const withAdmobNativeAdsGradle = (config: any) => {
return withPlugins(config, [
withAdmobNativeAdsAppBuildGradle,
]);
};
165 changes: 165 additions & 0 deletions plugin/src/withAdmobNativeAdsInfoPlist.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
import { withInfoPlist } from '@expo/config-plugins';

const withAdmobNativeAdsInfoPlist = (config: any, props: any) => {
return withInfoPlist(config, (config) => {
config.modResults.GADApplicationIdentifier = props.iosAppId;
const identifiers = [
{
SKAdNetworkIdentifier: 'cstr6suwn9.skadnetwork',
},
{
SKAdNetworkIdentifier: '4fzdc2evr5.skadnetwork',
},
{
SKAdNetworkIdentifier: '4pfyvq9l8r.skadnetwork',
},
{
SKAdNetworkIdentifier: '2fnua5tdw4.skadnetwork',
},
{
SKAdNetworkIdentifier: 'ydx93a7ass.skadnetwork',
},
{
SKAdNetworkIdentifier: '5a6flpkh64.skadnetwork',
},
{
SKAdNetworkIdentifier: 'p78axxw29g.skadnetwork',
},
{
SKAdNetworkIdentifier: 'v72qych5uu.skadnetwork',
},
{
SKAdNetworkIdentifier: 'ludvb6z3bs.skadnetwork',
},
{
SKAdNetworkIdentifier: 'cp8zw746q7.skadnetwork',
},
{
SKAdNetworkIdentifier: 'c6k4g5qg8m.skadnetwork',
},
{
SKAdNetworkIdentifier: 's39g8k73mm.skadnetwork',
},
{
SKAdNetworkIdentifier: '3qy4746246.skadnetwork',
},
{
SKAdNetworkIdentifier: '3sh42y64q3.skadnetwork',
},
{
SKAdNetworkIdentifier: 'f38h382jlk.skadnetwork',
},
{
SKAdNetworkIdentifier: 'hs6bdukanm.skadnetwork',
},
{
SKAdNetworkIdentifier: 'prcb7njmu6.skadnetwork',
},
{
SKAdNetworkIdentifier: 'v4nxqhlyqp.skadnetwork',
},
{
SKAdNetworkIdentifier: 'wzmmz9fp6w.skadnetwork',
},
{
SKAdNetworkIdentifier: 'yclnxrl5pm.skadnetwork',
},
{
SKAdNetworkIdentifier: 't38b2kh725.skadnetwork',
},
{
SKAdNetworkIdentifier: '7ug5zh24hu.skadnetwork',
},
{
SKAdNetworkIdentifier: '9rd848q2bz.skadnetwork',
},
{
SKAdNetworkIdentifier: 'y5ghdn5j9k.skadnetwork',
},
{
SKAdNetworkIdentifier: 'n6fk4nfna4.skadnetwork',
},
{
SKAdNetworkIdentifier: 'v9wttpbfk9.skadnetwork',
},
{
SKAdNetworkIdentifier: 'n38lu8286q.skadnetwork',
},
{
SKAdNetworkIdentifier: '47vhws6wlr.skadnetwork',
},
{
SKAdNetworkIdentifier: 'kbd757ywx3.skadnetwork',
},
{
SKAdNetworkIdentifier: '9t245vhmpl.skadnetwork',
},
{
SKAdNetworkIdentifier: 'a2p9lx4jpn.skadnetwork',
},
{
SKAdNetworkIdentifier: '22mmun2rn5.skadnetwork',
},
{
SKAdNetworkIdentifier: '4468km3ulz.skadnetwork',
},
{
SKAdNetworkIdentifier: '2u9pt9hc89.skadnetwork',
},
{
SKAdNetworkIdentifier: '8s468mfl3y.skadnetwork',
},
{
SKAdNetworkIdentifier: 'av6w8kgt66.skadnetwork',
},
{
SKAdNetworkIdentifier: 'klf5c3l5u5.skadnetwork',
},
{
SKAdNetworkIdentifier: 'ppxm28t8ap.skadnetwork',
},
{
SKAdNetworkIdentifier: '424m5254lk.skadnetwork',
},
{
SKAdNetworkIdentifier: 'ecpz2srf59.skadnetwork',
},
{
SKAdNetworkIdentifier: 'uw77j35x4d.skadnetwork',
},
{
SKAdNetworkIdentifier: 'mlmmfzh3r3.skadnetwork',
},
{
SKAdNetworkIdentifier: '578prtvx9j.skadnetwork',
},
{
SKAdNetworkIdentifier: '4dzt52r2t5.skadnetwork',
},
{
SKAdNetworkIdentifier: 'gta9lk7p23.skadnetwork',
},
{
SKAdNetworkIdentifier: 'e5fvkxwrpn.skadnetwork',
},
{
SKAdNetworkIdentifier: '8c4e2ghe7u.skadnetwork',
},
{
SKAdNetworkIdentifier: 'zq492l623r.skadnetwork',
},
{
SKAdNetworkIdentifier: '3rd42ekr43.skadnetwork',
},
{
SKAdNetworkIdentifier: '3qcr597p9d.skadnetwork',
}
];
config.modResults.SKAdNetworkItems = identifiers;
return config;
});
};

export const withAdmobNativeAdsPlist = (config: any, props: any) => {
return withAdmobNativeAdsInfoPlist(config, props);
};
36 changes: 36 additions & 0 deletions plugin/src/withAdmobNativeAdsPod.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { withDangerousMod, withPlugins } from '@expo/config-plugins';
import { resolve } from 'path';
import { writeFileSync, readFileSync } from 'fs';

const withAdmobNativeAdsPod = (config: any) => {
return withDangerousMod(config, [
'ios',
(cfg) => {
const { platformProjectRoot } = cfg.modRequest;
const podfile = resolve(platformProjectRoot, 'Podfile');
const contents = readFileSync(podfile, 'utf-8');
const lines = contents.split('\n');
const index = lines.findIndex((line: string) =>
/\s+use_expo_modules!/.test(line)
);

writeFileSync(
podfile,
[
...lines.slice(0, index),
` pod 'Google-Mobile-Ads-SDK'`,
` pod 'GoogleMobileAdsMediationFacebook', '6.11.0.0'`,
...lines.slice(index),
].join('\n')
);

return cfg;
}
]);
};

export const withAdmobNativeAdsPodNat = (config: any) => {
return withPlugins(config, [
withAdmobNativeAdsPod,
]);
};
9 changes: 9 additions & 0 deletions plugin/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"extends": "expo-module-scripts/tsconfig.plugin",
"compilerOptions": {
"outDir": "build",
"rootDir": "src"
},
"include": ["./src"],
"exclude": ["**/__mocks__/*", "**/__tests__/*"]
}
11 changes: 11 additions & 0 deletions tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"compilerOptions": {
"target": "ESNext",
"jsx": "react-native",
"module": "commonjs",
"forceConsistentCasingInFileNames": true,
"strict": true,
"alwaysStrict": true,
"skipLibCheck": true
}
}

0 comments on commit 7c21a48

Please sign in to comment.