codeplay-common 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ VITE_STORE_ID=1
@@ -0,0 +1 @@
1
+ VITE_STORE_ID=2
@@ -0,0 +1 @@
1
+ VITE_STORE_ID=7
@@ -0,0 +1,77 @@
1
+ const fs = require("fs");
2
+ const path = require("path");
3
+
4
+ // Define file paths
5
+ const projectFolder = path.resolve(".");
6
+ const sourceSplashIcon = path.join(projectFolder, "resources", "splash_icon.png");
7
+ const destinationSplashIcon = path.join(
8
+ projectFolder,
9
+ "android",
10
+ "app",
11
+ "src",
12
+ "main",
13
+ "res",
14
+ "drawable-nodpi",
15
+ "splash_icon.png"
16
+ );
17
+ const sourceSplashXML = path.join(projectFolder, "splashxml", "codeplay_splashScreen.xml");
18
+ const destinationSplashXML = path.join(
19
+ projectFolder,
20
+ "android",
21
+ "app",
22
+ "src",
23
+ "main",
24
+ "res",
25
+ "values",
26
+ "codeplay_splashScreen.xml"
27
+ );
28
+ const androidManifestPath = path.join(
29
+ projectFolder,
30
+ "android",
31
+ "app",
32
+ "src",
33
+ "main",
34
+ "AndroidManifest.xml"
35
+ );
36
+
37
+ // Helper function to copy files
38
+ function copyFile(source, destination) {
39
+ if (!fs.existsSync(source)) {
40
+ throw new Error(`Source file not found: ${source}`);
41
+ }
42
+ fs.mkdirSync(path.dirname(destination), { recursive: true });
43
+ fs.copyFileSync(source, destination);
44
+ console.log(`Copied: ${source} -> ${destination}`);
45
+ }
46
+
47
+ // Helper function to update AndroidManifest.xml
48
+ function updateAndroidManifest() {
49
+ if (!fs.existsSync(androidManifestPath)) {
50
+ throw new Error(`AndroidManifest.xml not found: ${androidManifestPath}`);
51
+ }
52
+
53
+ let manifestContent = fs.readFileSync(androidManifestPath, "utf-8");
54
+
55
+ // Replace the android:theme attribute in the <activity> tag
56
+ manifestContent = manifestContent.replace(
57
+ /<activity[^>]*android:theme="[^"]*"/,
58
+ (match) => {
59
+ return match.replace(/android:theme="[^"]*"/, 'android:theme="@style/Theme.Codeplay.SplashScreen"');
60
+ }
61
+ );
62
+
63
+ fs.writeFileSync(androidManifestPath, manifestContent, "utf-8");
64
+ console.log(`Updated AndroidManifest.xml with new theme.`);
65
+ }
66
+
67
+ // Perform the tasks
68
+ try {
69
+ console.log("Starting splash screen setup...");
70
+ copyFile(sourceSplashIcon, destinationSplashIcon);
71
+ copyFile(sourceSplashXML, destinationSplashXML);
72
+ updateAndroidManifest();
73
+ console.log("Splash screen setup completed.");
74
+ } catch (error) {
75
+ console.error(`Error: ${error.message}`);
76
+ process.exit(1);
77
+ }
@@ -0,0 +1,139 @@
1
+ const fs = require('fs');
2
+ const path = require('path');
3
+ const plist = require('plist');
4
+
5
+ const configPath = path.join(process.cwd(), 'capacitor.config.json');
6
+ const androidPlatformPath = path.join(process.cwd(), 'android');
7
+ const iosPlatformPath = path.join(process.cwd(), 'ios');
8
+ const pluginPath = path.join(process.cwd(), 'node_modules', 'emi-indo-cordova-plugin-admob', 'plugin.xml');
9
+ const infoPlistPath = path.join(process.cwd(), 'ios', 'App', 'App', 'Info.plist');
10
+
11
+ function fileExists(filePath) {
12
+ return fs.existsSync(filePath);
13
+ }
14
+
15
+ function getAdMobConfig() {
16
+ if (!fileExists(configPath)) {
17
+ throw new Error('capacitor.config.json not found. Ensure this is a Capacitor project.');
18
+ }
19
+
20
+ const config = JSON.parse(fs.readFileSync(configPath, 'utf8'));
21
+ const admobConfig = config.plugins?.AdMob;
22
+
23
+ if (!admobConfig || !admobConfig.APP_ID_ANDROID || !admobConfig.APP_ID_IOS) {
24
+ throw new Error('AdMob configuration is missing in capacitor.config.json. Ensure APP_ID_ANDROID and APP_ID_IOS are defined.');
25
+ }
26
+
27
+ return {
28
+ APP_ID_ANDROID: admobConfig.APP_ID_ANDROID,
29
+ APP_ID_IOS: admobConfig.APP_ID_IOS,
30
+ USE_LITE_ADS: admobConfig.USE_LITE_ADS === "lite",
31
+ };
32
+ }
33
+
34
+ function updatePluginXml(admobConfig) {
35
+ if (!fileExists(pluginPath)) {
36
+ console.error('plugin.xml not found. Ensure the plugin is installed.');
37
+ return;
38
+ }
39
+
40
+ let pluginContent = fs.readFileSync(pluginPath, 'utf8');
41
+
42
+ pluginContent = pluginContent
43
+ .replace(/<preference name="APP_ID_ANDROID" default=".*?" \/>/, `<preference name="APP_ID_ANDROID" default="${admobConfig.APP_ID_ANDROID}" />`)
44
+ .replace(/<preference name="APP_ID_IOS" default=".*?" \/>/, `<preference name="APP_ID_IOS" default="${admobConfig.APP_ID_IOS}" />`);
45
+
46
+
47
+ fs.writeFileSync(pluginPath, pluginContent, 'utf8');
48
+ console.log('AdMob IDs successfully updated in plugin.xml');
49
+ }
50
+
51
+ function updateInfoPlist(admobConfig) {
52
+ if (!fileExists(infoPlistPath)) {
53
+ console.error('Info.plist not found. Ensure you have built the iOS project.');
54
+ return;
55
+ }
56
+
57
+ const plistContent = fs.readFileSync(infoPlistPath, 'utf8');
58
+ const plistData = plist.parse(plistContent);
59
+
60
+ plistData.GADApplicationIdentifier = admobConfig.APP_ID_IOS;
61
+ plistData.NSUserTrackingUsageDescription = 'This identifier will be used to deliver personalized ads to you.';
62
+ plistData.GADDelayAppMeasurementInit = true;
63
+
64
+ // https://developers.google.com/admob/ios/quick-start
65
+ plistData.SKAdNetworkItems = [
66
+ { SKAdNetworkIdentifier: 'cstr6suwn9.skadnetwork' }, // Google
67
+ { SKAdNetworkIdentifier: '4fzdc2evr5.skadnetwork' }, // Aarki
68
+ { SKAdNetworkIdentifier: '2fnua5tdw4.skadnetwork' }, // Adform
69
+ { SKAdNetworkIdentifier: 'ydx93a7ass.skadnetwork' }, // Adikteev
70
+ { SKAdNetworkIdentifier: 'p78axxw29g.skadnetwork' }, // Amazon
71
+ { SKAdNetworkIdentifier: 'v72qych5uu.skadnetwork' }, // Appier
72
+ { SKAdNetworkIdentifier: 'ludvb6z3bs.skadnetwork' }, // Applovin
73
+ { SKAdNetworkIdentifier: 'cp8zw746q7.skadnetwork' }, // Arpeely
74
+ { SKAdNetworkIdentifier: '3sh42y64q3.skadnetwork' }, // Basis
75
+ { SKAdNetworkIdentifier: 'c6k4g5qg8m.skadnetwork' }, // Beeswax.io
76
+ { SKAdNetworkIdentifier: 's39g8k73mm.skadnetwork' }, // Bidease
77
+ { SKAdNetworkIdentifier: '3qy4746246.skadnetwork' }, // Bigabid
78
+ { SKAdNetworkIdentifier: 'hs6bdukanm.skadnetwork' }, // Criteo
79
+ { SKAdNetworkIdentifier: 'mlmmfzh3r3.skadnetwork' }, // Digital Turbine DSP
80
+ { SKAdNetworkIdentifier: 'v4nxqhlyqp.skadnetwork' }, // i-mobile
81
+ { SKAdNetworkIdentifier: 'wzmmz9fp6w.skadnetwork' }, // InMobi
82
+ { SKAdNetworkIdentifier: 'su67r6k2v3.skadnetwork' }, // ironSource Ads
83
+ { SKAdNetworkIdentifier: 'yclnxrl5pm.skadnetwork' }, // Jampp
84
+ { SKAdNetworkIdentifier: '7ug5zh24hu.skadnetwork' }, // Liftoff
85
+ { SKAdNetworkIdentifier: 'gta9lk7p23.skadnetwork' }, // Liftoff Monetize
86
+ { SKAdNetworkIdentifier: 'vutu7akeur.skadnetwork' }, // LINE
87
+ { SKAdNetworkIdentifier: 'y5ghdn5j9k.skadnetwork' }, // Mediaforce
88
+ { SKAdNetworkIdentifier: 'v9wttpbfk9.skadnetwork' }, // Meta (1 of 2)
89
+ { SKAdNetworkIdentifier: 'n38lu8286q.skadnetwork' }, // Meta (2 of 2)
90
+ { SKAdNetworkIdentifier: '47vhws6wlr.skadnetwork' }, // MicroAd
91
+ { SKAdNetworkIdentifier: 'kbd757ywx3.skadnetwork' }, // Mintegral / Mobvista
92
+ { SKAdNetworkIdentifier: '9t245vhmpl.skadnetwork' }, // Moloco
93
+ { SKAdNetworkIdentifier: 'a2p9lx4jpn.skadnetwork' }, // Opera
94
+ { SKAdNetworkIdentifier: '22mmun2rn5.skadnetwork' }, // Pangle
95
+ { SKAdNetworkIdentifier: '4468km3ulz.skadnetwork' }, // Realtime Technologies GmbH
96
+ { SKAdNetworkIdentifier: '2u9pt9hc89.skadnetwork' }, // Remerge
97
+ { SKAdNetworkIdentifier: '8s468mfl3y.skadnetwork' }, // RTB House
98
+ { SKAdNetworkIdentifier: 'ppxm28t8ap.skadnetwork' }, // Smadex
99
+ { SKAdNetworkIdentifier: 'uw77j35x4d.skadnetwork' }, // The Trade Desk
100
+ { SKAdNetworkIdentifier: 'pwa73g5rt2.skadnetwork' }, // Tremor
101
+ { SKAdNetworkIdentifier: '578prtvx9j.skadnetwork' }, // Unicorn
102
+ { SKAdNetworkIdentifier: '4dzt52r2t5.skadnetwork' }, // Unity Ads
103
+ { SKAdNetworkIdentifier: 'tl55sbb4fm.skadnetwork' }, // Verve
104
+ { SKAdNetworkIdentifier: 'e5fvkxwrpn.skadnetwork' }, // Yahoo!
105
+ { SKAdNetworkIdentifier: '8c4e2ghe7u.skadnetwork' }, // Yahoo! Japan Ads
106
+ { SKAdNetworkIdentifier: '3rd42ekr43.skadnetwork' }, // YouAppi
107
+ { SKAdNetworkIdentifier: '3qcr597p9d.skadnetwork' }, // Zucks
108
+ ];
109
+
110
+ const updatedPlistContent = plist.build(plistData);
111
+ fs.writeFileSync(infoPlistPath, updatedPlistContent, 'utf8');
112
+ console.log('AdMob IDs and additional configurations successfully updated in Info.plist');
113
+ }
114
+
115
+ try {
116
+ if (!fileExists(configPath)) {
117
+ throw new Error('capacitor.config.json not found. Skipping setup.');
118
+ }
119
+
120
+ if (!fileExists(androidPlatformPath) && !fileExists(iosPlatformPath)) {
121
+ throw new Error('Neither Android nor iOS platforms are found. Ensure platforms are added to your Capacitor project.');
122
+ }
123
+
124
+ const admobConfig = getAdMobConfig();
125
+
126
+ if (fileExists(androidPlatformPath)) {
127
+ updatePluginXml(admobConfig);
128
+ }
129
+
130
+ if (fileExists(iosPlatformPath)) {
131
+ updateInfoPlist(admobConfig);
132
+ }
133
+ } catch (error) {
134
+ console.error(error.message);
135
+ }
136
+
137
+
138
+
139
+
@@ -0,0 +1,493 @@
1
+ const fs = require('fs');
2
+ const path = require('path');
3
+ const child_process = require('child_process');
4
+ const readline = require('readline');
5
+
6
+ // Define a mapping between store IDs and store names
7
+ const storeNames = {
8
+ "1": "PlayStore",
9
+ "2": "SamsungStore",
10
+ "7": "AmazonStore"
11
+ };
12
+
13
+ const androidManifestPath = path.join("android", "app", "src", "main", "AndroidManifest.xml");
14
+
15
+
16
+
17
+ const admobConfigPath = path.join('src', 'js','Ads', 'admob-ad-configuration.json');
18
+ let admobConfig;
19
+ try {
20
+ admobConfig = JSON.parse(fs.readFileSync(admobConfigPath, 'utf8'));
21
+ } catch (err) {
22
+ console.error("Failed to read admob-ad-configuration.json", err);
23
+ process.exit(1);
24
+ }
25
+
26
+
27
+
28
+
29
+ const checkCommonFileStoreId=()=>{
30
+ const possibleConfigFiles = ['vite.config.mjs', 'vite.config.js'];
31
+ let viteConfigPath;
32
+ for (const configFile of possibleConfigFiles) {
33
+ const fullPath = path.resolve( configFile);
34
+ if (fs.existsSync(fullPath)) {
35
+ viteConfigPath = fullPath;
36
+ break;
37
+ }
38
+ }
39
+
40
+ if (!viteConfigPath) {
41
+ console.error('Error: No vite.config.mjs or vite.config.js file found.');
42
+ process.exit(1);
43
+ }
44
+
45
+ try {
46
+ // Read vite config file
47
+ const viteConfigContent = fs.readFileSync(viteConfigPath, 'utf-8');
48
+
49
+ // Extract @common alias path
50
+ const aliasPattern = /'@common':\s*path\.resolve\(__dirname,\s*'(.+?)'\)/;
51
+ const match = viteConfigContent.match(aliasPattern);
52
+
53
+ if (!match) {
54
+ console.error(`Error: @common alias not found in ${viteConfigPath}`);
55
+ process.exit(1);
56
+ }
57
+
58
+ const commonFilePath = match[1];
59
+ const resolvedCommonPath = path.resolve(__dirname, commonFilePath);
60
+
61
+ // Read the common file content
62
+ if (!fs.existsSync(resolvedCommonPath)) {
63
+ console.error(`Error: Resolved common file does not exist: ${resolvedCommonPath}`);
64
+ process.exit(1);
65
+ }
66
+
67
+ const commonFileContent = fs.readFileSync(resolvedCommonPath, 'utf-8');
68
+
69
+ // Check for the _storeid export line
70
+ const storeIdPattern = /export\s+let\s+_storeid\s*=\s*import\.meta\.env\.VITE_STORE_ID\s*\|\|\s*1\s*;/;
71
+ if (!storeIdPattern.test(commonFileContent)) {
72
+ console.error(`Error: _storeid value is wrong in ${commonFilePath}`);
73
+ process.exit(1);
74
+ }
75
+
76
+ console.log(commonFilePath,'Success - No problem found');
77
+ } catch (error) {
78
+ console.error('Error:', error);
79
+ process.exit(1);
80
+ }
81
+
82
+ }
83
+
84
+ const checkIsTestingInAdmob=()=>{
85
+
86
+ if (admobConfig.config && admobConfig.config.isTesting === true) {
87
+ console.error(`Problem found while generating the AAB file. Please change "isTesting: true" to "isTesting: false" in the "admob-ad-configuration.json" file.`);
88
+ process.exit(1); // Exit with an error code to halt the process
89
+ } else {
90
+ console.log('No problem found. "isTesting" is either already false or not defined.');
91
+ }
92
+ }
93
+
94
+ const addPermission_AD_ID=()=>{
95
+
96
+ const admobPluginXmlPath = path.join('node_modules', 'emi-indo-cordova-plugin-admob', 'plugin.xml');
97
+
98
+
99
+ fs.access(admobPluginXmlPath, fs.constants.F_OK, (err) => {
100
+ if (err) {
101
+ isAdmobFound = false;
102
+ } else {
103
+ isAdmobFound = true;
104
+ }
105
+ });
106
+
107
+
108
+ if (isAdmobFound) {
109
+ // Check if AndroidManifest.xml exists
110
+ if (fs.existsSync(androidManifestPath)) {
111
+ // Read the content of AndroidManifest.xml
112
+ let manifestContent = fs.readFileSync(androidManifestPath, 'utf8');
113
+
114
+ // Check if the ad_id permission already exists
115
+ const adIdPermission = '<uses-permission android:name="com.google.android.gms.permission.AD_ID" />';
116
+ if (!manifestContent.includes(adIdPermission)) {
117
+ console.log("ad_id permission not found. Adding to AndroidManifest.xml.");
118
+
119
+ // Add the ad_id permission before the closing </manifest> tag
120
+ manifestContent = manifestContent.replace('</manifest>', ` ${adIdPermission}\n</manifest>`);
121
+
122
+ // Write the updated manifest content back to AndroidManifest.xml
123
+ fs.writeFileSync(androidManifestPath, manifestContent, 'utf8');
124
+ console.log("ad_id permission added successfully.");
125
+ } else {
126
+ console.log("ad_id permission already exists in AndroidManifest.xml.");
127
+ }
128
+ } else {
129
+ console.error("AndroidManifest.xml not found at the specified path.");
130
+ }
131
+ } else {
132
+ console.log("\x1b[33m%s\x1b[0m", "No admob found, so permission.AD_ID is not added");
133
+ }
134
+ }
135
+
136
+
137
+ checkCommonFileStoreId();
138
+ checkIsTestingInAdmob();
139
+
140
+
141
+ let isAdmobFound = true;
142
+ addPermission_AD_ID()
143
+
144
+
145
+
146
+ const { playstore, samsung, amazon } = admobConfig.IAP;
147
+ console.log(`IAP Configurations - PlayStore: ${playstore}, Samsung: ${samsung}, Amazon: ${amazon}`);
148
+
149
+
150
+
151
+
152
+
153
+
154
+ // Get the store ID from the command line arguments
155
+ const storeIdArg = process.argv[2]; // Get the store ID from the command line
156
+ const storeIds = storeIdArg ? [storeIdArg] : ["1", "2", "7"]; // If a specific ID is provided, use it; otherwise, use all store IDs
157
+
158
+ // Store the original minSdkVersion globally
159
+ let originalMinSdkVersion;
160
+
161
+ // Remove any existing AAB files before starting the build process
162
+ const aabDirectory = path.join("android", "app", "build", "outputs", "bundle", "release");
163
+ if (fs.existsSync(aabDirectory)) {
164
+ const files = fs.readdirSync(aabDirectory).filter(file => file.endsWith('.aab'));
165
+ files.forEach(file => {
166
+ const filePath = path.join(aabDirectory, file);
167
+ fs.unlinkSync(filePath);
168
+ console.log(`Deleted existing AAB file: ${file}`);
169
+ });
170
+ }
171
+
172
+ const aabOutputDir = path.join("AAB");
173
+ if (!fs.existsSync(aabOutputDir)) {
174
+ fs.mkdirSync(aabOutputDir);
175
+ console.log(`Created directory: ${aabOutputDir}`);
176
+ }
177
+
178
+ if (fs.existsSync(aabOutputDir)) {
179
+ const files = fs.readdirSync(aabOutputDir).filter(file => file.endsWith('.aab'));
180
+ files.forEach(file => {
181
+ const filePath = path.join(aabOutputDir, file);
182
+ fs.unlinkSync(filePath);
183
+ console.log(`Deleted existing AAB file: ${file}`);
184
+ });
185
+ }
186
+
187
+
188
+ // Extract version code and version name from build.gradle
189
+ const gradleFilePath = path.join("android", "app", "build.gradle");
190
+ const gradleContent = fs.readFileSync(gradleFilePath, 'utf8');
191
+
192
+ const versionCodeMatch = gradleContent.match(/versionCode\s+(\d+)/);
193
+ const versionNameMatch = gradleContent.match(/versionName\s+"([^"]+)"/);
194
+
195
+ const versionCode = versionCodeMatch ? versionCodeMatch[1] : '';
196
+ const versionName = versionNameMatch ? versionNameMatch[1] : '';
197
+
198
+ // Display the current versionCode and versionName
199
+ console.log(`Current versionCode: ${versionCode}`);
200
+ console.log(`Current versionName: ${versionName}`);
201
+
202
+ // Create an interface for user input
203
+ const rl = readline.createInterface({
204
+ input: process.stdin,
205
+ output: process.stdout
206
+ });
207
+
208
+ // Ask for new versionCode
209
+ rl.question('Enter new versionCode (press enter to keep current): ', (newVersionCode) => {
210
+ const finalVersionCode = newVersionCode || versionCode; // Use existing if no input
211
+
212
+ // Ask for new versionName
213
+ rl.question('Enter new versionName (press enter to keep current): ', (newVersionName) => {
214
+ const finalVersionName = newVersionName || versionName; // Use existing if no input
215
+
216
+ // Log the final version details
217
+ console.log(`Final versionCode: ${finalVersionCode}`);
218
+ console.log(`Final versionName: ${finalVersionName}`);
219
+
220
+ // Update build.gradle with the new version details
221
+ let updatedGradleContent = gradleContent
222
+ .replace(/versionCode\s+\d+/, `versionCode ${finalVersionCode}`)
223
+ .replace(/versionName\s+"[^"]+"/, `versionName "${finalVersionName}"`);
224
+
225
+ // Check if resConfigs "en" already exists
226
+ const resConfigsLine = ' resConfigs "en"';
227
+ if (!updatedGradleContent.includes(resConfigsLine)) {
228
+ // Add resConfigs "en" below versionName
229
+ updatedGradleContent = updatedGradleContent.replace(/versionName\s+"[^"]+"/, `versionName "${finalVersionName}"\n${resConfigsLine}`);
230
+ } else {
231
+ console.log('resConfigs "en" already exists in build.gradle.');
232
+ }
233
+
234
+ // Write the updated gradle content back to build.gradle
235
+ fs.writeFileSync(gradleFilePath, updatedGradleContent, 'utf8');
236
+ console.log(`Updated build.gradle with versionCode: ${finalVersionCode}, versionName: ${finalVersionName}, and resConfigs "en"`);
237
+
238
+ storeIds.forEach((id) => {
239
+ console.log(`Building for Store ID ${id}`);
240
+
241
+ // Set the environment variable for store ID
242
+ process.env.VITE_STORE_ID = id;
243
+
244
+ // Conditionally set the new file name
245
+ let newFileName;
246
+ const storeName = storeNames[id];
247
+
248
+ managePackages(storeName);
249
+
250
+ if (storeName === "SamsungStore") {
251
+ // For SamsungStore, rename to versionCode value only
252
+ newFileName = `${finalVersionCode}.aab`;
253
+ } else {
254
+ // For other stores, use the standard naming format
255
+ newFileName = `app-release-signed-${storeName}-b${finalVersionCode}-v${finalVersionName}.aab`;
256
+ }
257
+
258
+ const checkFullPath = path.join("AAB", newFileName); // Update to point to the new AAB directory
259
+
260
+ // Modify minSdkVersion in variables.gradle for SamsungStore
261
+ const variablesGradleFilePath = path.join("android", "variables.gradle");
262
+ let variablesGradleContent = fs.readFileSync(variablesGradleFilePath, 'utf8');
263
+
264
+ // Extract the current minSdkVersion
265
+ const minSdkVersionMatch = variablesGradleContent.match(/minSdkVersion\s*=\s*(\d+)/);
266
+ const currentMinSdkVersion = minSdkVersionMatch ? parseInt(minSdkVersionMatch[1], 10) : null;
267
+
268
+ // Store the original minSdkVersion (only on the first iteration)
269
+ if (!originalMinSdkVersion) {
270
+ originalMinSdkVersion = currentMinSdkVersion;
271
+ }
272
+ try {
273
+ // Modify the minSdkVersion based on the store
274
+ if (storeName === "SamsungStore" || storeName === "PlayStore") {
275
+ if (currentMinSdkVersion !== 24) {
276
+ variablesGradleContent = variablesGradleContent.replace(/minSdkVersion\s*=\s*\d+/, 'minSdkVersion = 24');
277
+ console.log('minSdkVersion updated to 24 for SamsungStore & PlayStore');
278
+ fs.writeFileSync(variablesGradleFilePath, variablesGradleContent);
279
+ }
280
+ } else {
281
+ // For PlayStore and AmazonStore, ensure minSdkVersion is originalMinSdkVersion
282
+ if (currentMinSdkVersion !== originalMinSdkVersion) {
283
+ variablesGradleContent = variablesGradleContent.replace(/minSdkVersion\s*=\s*\d+/, `minSdkVersion = ${originalMinSdkVersion}`);
284
+ console.log(`minSdkVersion reverted to ${originalMinSdkVersion} for ${storeName}`);
285
+ fs.writeFileSync(variablesGradleFilePath, variablesGradleContent);
286
+ }
287
+ }
288
+
289
+ // Run the Node.js script to modify plugin.xml
290
+ if (isAdmobFound) {
291
+ child_process.execSync('node modify-plugin-xml.js', { stdio: 'inherit' });
292
+ } else {
293
+ console.log("\x1b[33m%s\x1b[0m", "Seems to Pro Version [No ads found]");
294
+ }
295
+
296
+ // Run the Vite build
297
+ child_process.execSync(`npm run build:storeid${id}`, { stdio: 'inherit' });
298
+
299
+
300
+
301
+ // Copy the built files to the appropriate folder
302
+ const src = path.join("www", "*");
303
+ const dest = path.join("android", "app", "src", "main", "assets", "public");
304
+
305
+ // Use 'xcopy' command for Windows
306
+ child_process.execSync(`xcopy ${src} ${dest} /E /I /Y`, { stdio: 'inherit' });
307
+
308
+ // Build Android AAB file
309
+ //child_process.execSync('cd android && ./gradlew bundleRelease', { stdio: 'inherit' });
310
+
311
+
312
+ // Build Android AAB file with Capacitor
313
+ child_process.execSync('npx cap sync android', { stdio: 'inherit' });
314
+ child_process.execSync('npx cap build android --androidreleasetype=AAB', { stdio: 'inherit' });
315
+
316
+
317
+ // Rename the output AAB file
318
+ const oldFilePath = path.join(aabDirectory, "app-release-signed.aab");
319
+ if (fs.existsSync(oldFilePath)) {
320
+ fs.renameSync(oldFilePath, checkFullPath);
321
+ console.log(`Renamed output AAB file to: ${newFileName}`);
322
+ } else {
323
+ console.error("AAB file not found after build.");
324
+ }
325
+
326
+ } catch (error) {
327
+ console.error(`Error during build for Store ID ${id}:`, error);
328
+ }
329
+ });
330
+
331
+ rl.close(); // Close the readline interface after all operations
332
+ });
333
+ });
334
+
335
+
336
+
337
+
338
+
339
+ function managePackages(store) {
340
+ console.log(`IAP Configurations - PlayStore: ${playstore}, Samsung: ${samsung}, Amazon: ${amazon}`);
341
+
342
+ let install = "";
343
+ let uninstall = "";
344
+
345
+
346
+
347
+ let manifestContent = fs.readFileSync(androidManifestPath, 'utf-8');
348
+
349
+ const permissionsToRemove = [
350
+ 'com.android.vending.BILLING',
351
+ 'com.samsung.android.iap.permission.BILLING'
352
+ ];
353
+
354
+
355
+ permissionsToRemove.forEach(permission => {
356
+ const permissionRegex = new RegExp(`^\\s*<uses-permission\\s+android:name="${permission}"\\s*/?>\\s*[\r\n]?`, 'm');
357
+ if (permissionRegex.test(manifestContent)) {
358
+ manifestContent = manifestContent.replace(permissionRegex, '');
359
+ console.log(`Removed <uses-permission android:name="${permission}" /> from AndroidManifest.xml`);
360
+ }
361
+ });
362
+
363
+ // Write the updated content back to the file
364
+ fs.writeFileSync(androidManifestPath, manifestContent, 'utf-8');
365
+
366
+
367
+
368
+ if ((playstore && store === "PlayStore") || (amazon && store === "AmazonStore")) {
369
+ install = '@revenuecat/purchases-capacitor';
370
+ uninstall = 'cordova-plugin-samsungiap';
371
+
372
+ // Update AndroidManifest.xml for PlayStore
373
+ if(playstore)
374
+ updateAndroidManifest(store,
375
+ '<uses-permission android:name="com.android.vending.BILLING" />');
376
+
377
+ } else if (samsung && store === "SamsungStore") {
378
+ install = 'cordova-plugin-samsungiap';
379
+ uninstall = '@revenuecat/purchases-capacitor';
380
+
381
+ // Update AndroidManifest.xml for SamsungStore
382
+ updateAndroidManifest(store,
383
+ '<uses-permission android:name="com.samsung.android.iap.permission.BILLING" />');
384
+
385
+ } else {
386
+ console.log("No valid store specified or no configurations found. Both plugins will be uninstalled.");
387
+ try {
388
+ child_process.execSync(`npm uninstall cordova-plugin-samsungiap`, { stdio: 'inherit' });
389
+ child_process.execSync(`npm uninstall @revenuecat/purchases-capacitor`, { stdio: 'inherit' });
390
+ console.log(`Both plugins uninstalled successfully.`);
391
+ } catch (err) {
392
+ console.error("Error uninstalling plugins:", err);
393
+ }
394
+ return;
395
+ }
396
+
397
+ console.log(`Installing ${install} and uninstalling ${uninstall} for ${store}...`);
398
+ try {
399
+ if (install) {
400
+ child_process.execSync(`npm install ${install}`, { stdio: 'inherit' });
401
+ }
402
+ if (uninstall) {
403
+ child_process.execSync(`npm uninstall ${uninstall}`, { stdio: 'inherit' });
404
+ }
405
+ console.log(`${install} installed and ${uninstall} uninstalled successfully.`);
406
+ } catch (err) {
407
+ console.error(`Error managing packages for ${store}:`, err);
408
+ }
409
+ }
410
+
411
+
412
+
413
+ function updateAndroidManifest(store, addPermission) {
414
+ try {
415
+ if (!fs.existsSync(androidManifestPath)) {
416
+ console.error("AndroidManifest.xml file not found!");
417
+ return;
418
+ }
419
+
420
+ // Read the content of the AndroidManifest.xml
421
+ let manifestContent = fs.readFileSync(androidManifestPath, 'utf-8');
422
+
423
+ // Normalize line endings to `\n` for consistent processing
424
+ manifestContent = manifestContent.replace(/\r\n/g, '\n');
425
+
426
+ // Check if the permission is already present
427
+ if (manifestContent.includes(addPermission.trim())) {
428
+ console.log(`${addPermission} is already in the AndroidManifest.xml. Skipping addition.`);
429
+ return; // Skip if the permission is already present
430
+ }
431
+
432
+ // Insert the permission before the closing </manifest> tag
433
+ const closingTag = '</manifest>';
434
+ const formattedPermission = ` ${addPermission.trim()}\n`;
435
+ if (manifestContent.includes(closingTag)) {
436
+ manifestContent = manifestContent.replace(
437
+ closingTag,
438
+ `${formattedPermission}${closingTag}`
439
+ );
440
+ console.log(`Added ${addPermission} before </manifest> tag.`);
441
+ } else {
442
+ console.warn(`</manifest> tag not found. Adding ${addPermission} at the end of the file.`);
443
+ manifestContent += `\n${formattedPermission}`;
444
+ }
445
+
446
+ // Normalize line endings back to `\r\n` and write the updated content
447
+ manifestContent = manifestContent.replace(/\n/g, '\r\n');
448
+ fs.writeFileSync(androidManifestPath, manifestContent, 'utf-8');
449
+ console.log(`AndroidManifest.xml updated successfully for ${store}`);
450
+ } catch (err) {
451
+ console.error(`Error updating AndroidManifest.xml for ${store}:`, err);
452
+ }
453
+ }
454
+
455
+
456
+
457
+ /* function updateAndroidManifest1(store, addPermission) {
458
+ try {
459
+ if (!fs.existsSync(androidManifestPath)) {
460
+ console.error("AndroidManifest.xml file not found!");
461
+ return;
462
+ }
463
+
464
+ let manifestContent = fs.readFileSync(androidManifestPath, 'utf-8');
465
+
466
+
467
+
468
+ // Add the required permission if not already present
469
+ if (!manifestContent.includes(addPermission)) {
470
+ const manifestLines = manifestContent.split('\n');
471
+ const insertIndex = manifestLines.findIndex(line => line.trim().startsWith('<application'));
472
+ if (insertIndex > -1) {
473
+ manifestLines.splice(insertIndex, 0, ` ${addPermission}`);
474
+ manifestContent = manifestLines.join('\n');
475
+ console.log(`Added ${addPermission} to AndroidManifest.xml`);
476
+ }
477
+ }
478
+
479
+ // Write the updated content back to the file
480
+ fs.writeFileSync(androidManifestPath, manifestContent, 'utf-8');
481
+ console.log(`AndroidManifest.xml updated successfully for ${store}`);
482
+ } catch (err) {
483
+ console.error(`Error updating AndroidManifest.xml for ${store}:`, err);
484
+ }
485
+ } */
486
+
487
+
488
+
489
+
490
+
491
+
492
+
493
+
@@ -0,0 +1,146 @@
1
+ const fs = require('fs');
2
+ const path = require('path');
3
+
4
+
5
+
6
+ const androidManifestPath = path.join("android", "app", "src", "main", "AndroidManifest.xml");
7
+
8
+ // Find the vite config file
9
+ const possibleConfigFiles = ['vite.config.mjs', 'vite.config.js'];
10
+ let viteConfigPath;
11
+
12
+ for (const configFile of possibleConfigFiles) {
13
+ const fullPath = path.resolve(configFile);
14
+ if (fs.existsSync(fullPath)) {
15
+ viteConfigPath = fullPath;
16
+ break;
17
+ }
18
+ }
19
+
20
+ if (!viteConfigPath) {
21
+ console.error('Error: No vite.config.mjs or vite.config.js file found.');
22
+ process.exit(1);
23
+ }
24
+
25
+ try {
26
+ // Read vite config file
27
+ const viteConfigContent = fs.readFileSync(viteConfigPath, 'utf-8');
28
+
29
+ // Extract @common alias path
30
+ const aliasPattern = /'@common':\s*path\.resolve\(__dirname,\s*'(.+?)'\)/;
31
+ const match = viteConfigContent.match(aliasPattern);
32
+
33
+ if (!match) {
34
+ console.error(`Error: @common alias not found in ${viteConfigPath}`);
35
+ process.exit(1);
36
+ }
37
+
38
+ const commonFilePath = match[1];
39
+ const resolvedCommonPath = path.resolve(__dirname, commonFilePath);
40
+
41
+ // Read the common file content
42
+ if (!fs.existsSync(resolvedCommonPath)) {
43
+ console.error(`Error: Resolved common file does not exist: ${resolvedCommonPath}`);
44
+ process.exit(1);
45
+ }
46
+
47
+ const commonFileContent = fs.readFileSync(resolvedCommonPath, 'utf-8');
48
+
49
+ // Extract _storeid value
50
+ const storeIdPattern = /export\s+let\s+_storeid\s*=\s*(?:import\.meta\.env\.VITE_STORE_ID\|\|)?(\d+)/;
51
+ const storeMatch = commonFileContent.match(storeIdPattern);
52
+
53
+ if (!storeMatch) {
54
+ console.error(`Error: _storeid not found in ${resolvedCommonPath}`);
55
+ process.exit(1);
56
+ }
57
+
58
+ const _storeid = parseInt(storeMatch[1], 10);
59
+
60
+ // Determine the store name based on _storeid
61
+
62
+
63
+
64
+ let storeName = "";
65
+ if (_storeid === 1) {
66
+ storeName = "PlayStore";
67
+ } else if (_storeid === 2) {
68
+ storeName = "SamsungStore";
69
+ } else if (_storeid === 7) {
70
+ storeName = "AmazonStore";
71
+ }
72
+ else {
73
+ console.error(`Error: Unsupported _storeid value: ${_storeid}`);
74
+ process.exit(1);
75
+ }
76
+
77
+ // Call managePackages with the determined store name
78
+ managePackages(storeName);
79
+
80
+ console.log(commonFilePath, `Success - _storeid found: ${_storeid}, Store: ${storeName}`);
81
+ } catch (error) {
82
+ console.error('Error:', error);
83
+ process.exit(1);
84
+ }
85
+
86
+ function managePackages(store) {
87
+ console.log(`Managing packages for store: ${store}`);
88
+
89
+ let install = "";
90
+ let uninstall = "";
91
+
92
+ //let androidManifestPath = "path/to/AndroidManifest.xml"; // Update this path
93
+
94
+
95
+ let manifestContent = fs.readFileSync(androidManifestPath, 'utf-8');
96
+
97
+ const permissionsToRemove = [
98
+ 'com.android.vending.BILLING',
99
+ 'com.samsung.android.iap.permission.BILLING'
100
+ ];
101
+
102
+ permissionsToRemove.forEach(permission => {
103
+ const permissionRegex = new RegExp(`^\\s*<uses-permission\\s+android:name="${permission}"\\s*/?>\\s*[\r\n]?`, 'm');
104
+ if (permissionRegex.test(manifestContent)) {
105
+ manifestContent = manifestContent.replace(permissionRegex, '');
106
+ console.log(`Removed <uses-permission android:name="${permission}" /> from AndroidManifest.xml`);
107
+ }
108
+ });
109
+
110
+ // Write the updated content back to the file
111
+ fs.writeFileSync(androidManifestPath, manifestContent, 'utf-8');
112
+
113
+ if (store === "PlayStore") {
114
+ install = '@revenuecat/purchases-capacitor';
115
+ uninstall = 'cordova-plugin-samsungiap';
116
+ } else if (store === "AmazonStore") {
117
+ install = '@revenuecat/purchases-capacitor';
118
+ uninstall = 'cordova-plugin-samsungiap';
119
+ } else if (store === "SamsungStore") {
120
+ install = 'cordova-plugin-samsungiap';
121
+ uninstall = '@revenuecat/purchases-capacitor';
122
+ } else {
123
+ console.log("No valid store specified. Uninstalling both plugins.");
124
+ try {
125
+ require('child_process').execSync(`npm uninstall cordova-plugin-samsungiap`, { stdio: 'inherit' });
126
+ require('child_process').execSync(`npm uninstall @revenuecat/purchases-capacitor`, { stdio: 'inherit' });
127
+ console.log("Both plugins uninstalled successfully.");
128
+ } catch (err) {
129
+ console.error("Error uninstalling plugins:", err);
130
+ }
131
+ return;
132
+ }
133
+
134
+ console.log(`Installing ${install} and uninstalling ${uninstall} for ${store}...`);
135
+ try {
136
+ if (install) {
137
+ require('child_process').execSync(`npm install ${install}`, { stdio: 'inherit' });
138
+ }
139
+ if (uninstall) {
140
+ require('child_process').execSync(`npm uninstall ${uninstall}`, { stdio: 'inherit' });
141
+ }
142
+ console.log(`${install} installed and ${uninstall} uninstalled successfully.`);
143
+ } catch (err) {
144
+ console.error(`Error managing packages for ${store}:`, err);
145
+ }
146
+ }
@@ -0,0 +1,7 @@
1
+ {
2
+ "name": "merbin-test-app",
3
+ "integrations": {
4
+ "capacitor": {}
5
+ },
6
+ "type": "custom"
7
+ }
@@ -0,0 +1,36 @@
1
+ const fs = require('fs');
2
+ const path = require('path');
3
+
4
+ // Path to the plugin.xml file
5
+ const pluginXmlPath = path.join('node_modules', 'emi-indo-cordova-plugin-admob', 'plugin.xml');
6
+
7
+ // Get the store ID from the environment variable
8
+ const storeId = process.env.VITE_STORE_ID || '1';
9
+
10
+ // Determine the framework to use based on storeId
11
+ const framework = storeId === '7'
12
+ ? '<framework src="com.google.android.gms:play-services-ads:$PLAY_SERVICES_VERSION" />'
13
+ : '<framework src="com.google.android.gms:play-services-ads-lite:$PLAY_SERVICES_VERSION" />';
14
+
15
+ // Read and modify the plugin.xml file
16
+ fs.readFile(pluginXmlPath, 'utf8', (err, data) => {
17
+ if (err) {
18
+ console.error('Error reading plugin.xml:', err);
19
+ process.exit(1);
20
+ }
21
+
22
+ // Replace the existing framework line with the selected one
23
+ const modifiedData = data.replace(
24
+ /<framework src="com.google.android.gms:play-services-ads.*" \/>\n/,
25
+ `${framework}\n`
26
+ );
27
+
28
+ // Write the modified content back to plugin.xml
29
+ fs.writeFile(pluginXmlPath, modifiedData, 'utf8', (err) => {
30
+ if (err) {
31
+ console.error('Error writing plugin.xml:', err);
32
+ process.exit(1);
33
+ }
34
+ console.log('plugin.xml updated successfully.');
35
+ });
36
+ });
@@ -0,0 +1,167 @@
1
+ const fs = require('fs');
2
+ const readline = require('readline');
3
+ const path = require('path');
4
+
5
+ // Define the root directory of the project (adjust if needed)
6
+ const projectRoot = path.join('android/app/src/main');
7
+
8
+ // Animation options
9
+ const animations = [
10
+ { id: 1, name: 'Ripple Effect', code: `.scaleX(1.2f).scaleY(1.2f).alpha(0.3f)` }, //Okay super
11
+ { id: 2, name: 'Pop Out', code: `.scaleX(1.2f).scaleY(1.2f).alpha(0f)` }, //Okay super
12
+ { id: 3, name: 'Super Zoom', code: `.scaleX(1.5f).scaleY(1.5f).alpha(1f)` }, //Okay super
13
+
14
+
15
+ { id: 4, name: 'Flip and Fade', code: `.scaleX(0f).scaleY(0f).rotation(180f).alpha(0f)` }, //Okay
16
+ { id: 5, name: 'Wipe Away', code: `.translationX(splashScreenView.getWidth()).alpha(0f)` }, //Okay
17
+ { id: 6, name: 'Bounce in Spiral', code: `.scaleX(0.5f).scaleY(0.5f).alpha(0.5f).rotation(360f)` }, //Okay
18
+ { id: 7, name: 'Fade and Slide', code: `.alpha(0f).translationY(splashScreenView.getHeight())` }, //Okay
19
+ { id: 8, name: 'Zoom Out with Bounce', code: `.scaleX(0f).scaleY(0f).alpha(0f).translationY(splashScreenView.getHeight())` }, //Okay
20
+ { id: 9, name: 'Twist', code: `.rotation(720f).alpha(0f)` }, //Okay
21
+ { id: 10, name: 'Rotate Back', code: `.rotation(-360f).alpha(1f)` }, //Okay
22
+ { id: 11, name: 'Stretch In', code: `.scaleX(1.5f).scaleY(1.5f).alpha(1f)` }, //Okay
23
+ { id: 12, name: 'Fade and Scale', code: `.alpha(0f).scaleX(0f).scaleY(0f)` }, //Okay
24
+ { id: 13, name: 'Slide Left and Fade', code: `.translationX(-splashScreenView.getWidth()).alpha(0f)` }, //Okay
25
+
26
+
27
+ { id: 14, name: 'Fade Out', code: `.alpha(0f)` },
28
+ { id: 15, name: 'Slide Down', code: `.translationY(splashScreenView.getHeight())` },
29
+ { id: 16, name: 'Zoom Out', code: `.scaleX(0f).scaleY(0f).alpha(0f)` },
30
+ { id: 17, name: 'Rotate Out', code: `.rotation(360f).alpha(0f)` },
31
+ { id: 18, name: 'Slide Up', code: `.translationY(-splashScreenView.getHeight()).alpha(0f)` },
32
+ { id: 19, name: 'Bounce Effect', code: `.translationY(splashScreenView.getHeight())` },
33
+ { id: 20, name: 'Flip Out', code: `.scaleX(0f).alpha(0f)` },
34
+ { id: 21, name: 'Diagonal Slide and Fade Out', code: `.translationX(splashScreenView.getWidth()).translationY(splashScreenView.getHeight()).alpha(0f)` },
35
+ { id: 22, name: 'Scale Down with Bounce', code: `.scaleX(0f).scaleY(0f)` },
36
+ { id: 23, name: 'Slide Left', code: `.translationX(-splashScreenView.getWidth()).alpha(0f)` },
37
+ { id: 24, name: 'Slide Right', code: `.translationX(splashScreenView.getWidth()).alpha(0f)` },
38
+ { id: 25, name: 'Scale Up', code: `.scaleX(1f).scaleY(1f).alpha(1f)` },
39
+ { id: 26, name: 'Rotate In', code: `.rotation(180f).alpha(1f)` },
40
+ { id: 27, name: 'Bounce Up', code: `.translationY(-100f).setInterpolator(new BounceInterpolator())` },
41
+ { id: 28, name: 'Flip Horizontal', code: `.scaleX(-1f).alpha(1f)` },
42
+ { id: 29, name: 'Zoom In', code: `.scaleX(1f).scaleY(1f).alpha(1f)` },
43
+ { id: 30, name: 'Wobble', code: `.translationX(10f).translationX(-10f).translationX(10f)` },
44
+ { id: 31, name: 'Vertical Shake', code: `.translationY(10f).translationY(-10f).translationY(10f)` },
45
+ { id: 32, name: 'Bounce Down', code: `.translationY(100f).setInterpolator(new BounceInterpolator())` },
46
+ { id: 33, name: 'Swing', code: `.rotation(15f).translationX(-10f).rotation(-15f).translationX(10f)` },
47
+ { id: 34, name: 'Elastic Bounce', code: `.translationX(30f).translationX(-30f).translationX(15f).translationX(-15f)` },
48
+ { id: 35, name: 'Pulse', code: `.scaleX(1.1f).scaleY(1.1f).alpha(1f).setRepeatMode(ValueAnimator.REVERSE).setRepeatCount(ValueAnimator.INFINITE)` },
49
+ { id: 36, name: 'Skew', code: `.setRotationX(30f).setRotationY(30f).alpha(0.5f)` },
50
+ { id: 37, name: 'Vibrate', code: `.translationX(5f).translationX(-5f).translationX(5f).translationX(-5f)` },
51
+ { id: 38, name: 'Speed Out', code: `.alpha(0f).setDuration(300)` },
52
+ { id: 39, name: 'Wave', code: `.translationX(20f).translationX(-20f).translationX(20f).translationX(-20f)` },
53
+ { id: 40, name: 'Swing Bounce', code: `.rotation(15f).translationX(10f).translationX(-10f)` },
54
+ ];
55
+
56
+
57
+ // Function to find the package name from capacitor.config.json
58
+ function findPackageName() {
59
+ const configPath = path.join('capacitor.config.json');
60
+ if (!fs.existsSync(configPath)) {
61
+ console.error('capacitor.config.json not found. Ensure this is a valid Capacitor project.');
62
+ process.exit(1);
63
+ }
64
+
65
+ const configContent = JSON.parse(fs.readFileSync(configPath, 'utf8'));
66
+ return configContent.appId;
67
+ }
68
+
69
+ // Function to construct the MainActivity.java path
70
+ function constructMainActivityPath(packageName) {
71
+ const packagePath = packageName.replace(/\./g, '/'); // Convert package name to path
72
+ const mainActivityPath = path.join('android', 'app', 'src', 'main', 'java', packagePath, 'MainActivity.java');
73
+
74
+ console.log('MainActivity path:', mainActivityPath); // Output for debugging
75
+ return mainActivityPath;
76
+ }
77
+
78
+ // Find package name and MainActivity.java path
79
+ const packageName = findPackageName();
80
+ if (!packageName) {
81
+ console.error('Failed to extract the package name from capacitor.config.json.');
82
+ process.exit(1);
83
+ }
84
+
85
+ const mainActivityPath = constructMainActivityPath(packageName);
86
+
87
+ // Display animation options
88
+ /* const rl = readline.createInterface({
89
+ input: process.stdin,
90
+ output: process.stdout,
91
+ }); */
92
+
93
+ console.log('Select an animation type for the splash screen:');
94
+ animations.forEach((animation) => {
95
+ console.log(`${animation.id}. ${animation.name}`);
96
+ });
97
+
98
+ // Prompt user for animation selection
99
+ //rl.question('Enter the number of the animation type: ', (answer) => {
100
+
101
+ const answer=1;
102
+
103
+ const selectedAnimation = animations.find((anim) => anim.id === parseInt(answer, 10));
104
+
105
+ if (!selectedAnimation) {
106
+ console.log('Invalid selection. Please run the script again.');
107
+ //rl.close();
108
+ return;
109
+ }
110
+
111
+ console.log(`Selected: ${selectedAnimation.name}`);
112
+
113
+ // Read the MainActivity.java file
114
+ fs.readFile(mainActivityPath, 'utf8', (err, data) => {
115
+ if (err) {
116
+ console.error(`Error reading MainActivity.java: ${err.message}`);
117
+ //rl.close();
118
+ return;
119
+ }
120
+
121
+ // New logic for removing existing code and adding new splash screen animation code
122
+ const newMainActivityCode =
123
+ `package ${findPackageName()};
124
+
125
+ import android.os.Build;
126
+ import android.os.Bundle;
127
+ import com.getcapacitor.BridgeActivity;
128
+
129
+
130
+ public class MainActivity extends BridgeActivity {
131
+ @Override
132
+ protected void onCreate(Bundle savedInstanceState) {
133
+ super.onCreate(savedInstanceState);
134
+
135
+ // Handle custom splash screen exit animation
136
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
137
+ getSplashScreen().setOnExitAnimationListener(splashScreenView -> {
138
+ // Add your custom animation here (e.g., fade out)
139
+ splashScreenView.setAlpha(1f);
140
+ splashScreenView.animate()
141
+ ${selectedAnimation.code} // Apply selected animation
142
+ .setDuration(1000) // Animation duration (1000ms)
143
+ .withEndAction(splashScreenView::remove) // Remove splash screen
144
+ .start();
145
+ });
146
+ }
147
+ }
148
+ }
149
+ `;
150
+
151
+ // Write the new MainActivity.java content
152
+ writeMainActivity(newMainActivityCode);
153
+ });
154
+
155
+ //rl.close();
156
+ //});
157
+
158
+ // Write updated data to MainActivity.java
159
+ function writeMainActivity(updatedData) {
160
+ fs.writeFile(mainActivityPath, updatedData, 'utf8', (err) => {
161
+ if (err) {
162
+ console.error(`Error writing to MainActivity.java: ${err.message}`);
163
+ return;
164
+ }
165
+ console.log('MainActivity.java updated successfully!');
166
+ });
167
+ }
@@ -0,0 +1,11 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <resources>
3
+ <color name="splashscreen_background">#FFFFFF</color>
4
+
5
+ <style name="Theme.Codeplay.SplashScreen" parent="Theme.SplashScreen.IconBackground">
6
+ <item name="windowSplashScreenBackground">@color/splashscreen_background</item>
7
+ <item name="windowSplashScreenAnimatedIcon">@drawable/splash_icon</item>
8
+ <item name="windowSplashScreenAnimationDuration">10000</item>
9
+ <item name="postSplashScreenTheme">@style/Theme.AppCompat.NoActionBar</item>
10
+ </style>
11
+ </resources>
package/package.json ADDED
@@ -0,0 +1,15 @@
1
+ {
2
+ "name": "codeplay-common",
3
+ "version": "1.0.0",
4
+ "description": "Common build scripts and files",
5
+ "main": "index.js",
6
+ "scripts": {
7
+ "postinstall": "node scripts/sync-files.js"
8
+ },
9
+ "repository": {
10
+ "type": "git",
11
+ "url": "https://github.com/merbin2012/codeplay-common.git"
12
+ },
13
+ "author": "Codeplay Technologies",
14
+ "license": "MIT"
15
+ }
@@ -0,0 +1,67 @@
1
+ const fs = require("fs");
2
+ const path = require("path");
3
+
4
+ const projectRoot = process.cwd(); // Project root where this package is installed
5
+ const commonBuildPath = path.join(__dirname, "../files"); // Path to "Common Build File" folder
6
+ const packageJsonPath = path.join(projectRoot, "package.json");
7
+
8
+ // Ensure package.json exists
9
+ if (!fs.existsSync(packageJsonPath)) {
10
+ console.error("❌ Error: package.json not found in project.");
11
+ process.exit(1);
12
+ }
13
+
14
+ // Function to get the latest versioned file dynamically
15
+ function getLatestFile(prefix) {
16
+ const files = fs.readdirSync(commonBuildPath);
17
+ const matchingFiles = files.filter(file => file.startsWith(prefix));
18
+
19
+ if (matchingFiles.length === 0) {
20
+ console.warn(`⚠️ Warning: No file found for ${prefix}`);
21
+ return null;
22
+ }
23
+
24
+ // Sort files by version and pick the latest one
25
+ matchingFiles.sort((a, b) => b.localeCompare(a, undefined, { numeric: true }));
26
+ return matchingFiles[0];
27
+ }
28
+
29
+ // Copy all files from "files" folder to the project root
30
+ fs.readdirSync(commonBuildPath).forEach(file => {
31
+ fs.copyFileSync(path.join(commonBuildPath, file), path.join(projectRoot, file));
32
+ console.log(`✅ Copied: ${file}`);
33
+ });
34
+
35
+ // Get the latest versions
36
+ const latestSplashScreen = getLatestFile("add-splash-screen-");
37
+ const latestSplashAnimation = getLatestFile("setSplashAnimation-");
38
+ const latestCodeplayBuild = getLatestFile("codeplayBeforeBuild-");
39
+
40
+ // Read and update package.json
41
+ const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, "utf8"));
42
+
43
+ // Update only the versioned script names in package.json
44
+ if (latestSplashScreen) {
45
+ packageJson.scripts["capacitor:sync:after"] = packageJson.scripts["capacitor:sync:after"].replace(
46
+ /add-splash-screen-\d+\.\d+\.js/,
47
+ latestSplashScreen
48
+ );
49
+ }
50
+
51
+ if (latestSplashAnimation) {
52
+ packageJson.scripts["capacitor:sync:after"] = packageJson.scripts["capacitor:sync:after"].replace(
53
+ /setSplashAnimation-\d+\.\d+\.js/,
54
+ latestSplashAnimation
55
+ );
56
+ }
57
+
58
+ if (latestCodeplayBuild) {
59
+ packageJson.scripts["build"] = packageJson.scripts["build"].replace(
60
+ /codeplayBeforeBuild-\d+\.\d+\.js/,
61
+ latestCodeplayBuild
62
+ );
63
+ }
64
+
65
+ // Write updated package.json
66
+ fs.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2), "utf8");
67
+ console.log("✅ package.json updated successfully!");