codeplay-common 4.6.0 → 4.6.3
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.
- package/README.md +9 -5
- package/files/buildCodeplay/{codeplayBeforeBuild-6.2.js → codeplayBeforeBuild-6.3.js} +105 -117
- package/files/buildCodeplay/{setSplashAnimation-1.2.js → setSplashAnimation-1.4.js} +70 -14
- package/files/buildCodeplay/versions.json +2 -2
- package/files/finalrelease +10 -4
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -28,11 +28,15 @@ For example, publish `agents-1.1.zip` and add this entry to the server's
|
|
|
28
28
|
"agents": "1.1"
|
|
29
29
|
```
|
|
30
30
|
|
|
31
|
-
Donate to get full code including many common functions
|
|
32
|
-
https://ko-fi.com/codeplay
|
|
33
|
-
|
|
34
|
-
4.
|
|
35
|
-
|
|
31
|
+
Donate to get full code including many common functions
|
|
32
|
+
https://ko-fi.com/codeplay
|
|
33
|
+
|
|
34
|
+
Version 4.6.1
|
|
35
|
+
Added automatic IAP startup integration for Framework7 home pages.
|
|
36
|
+
Updated minimum shared versions to IAP 4.2 and AdMob nextgen 2.5.
|
|
37
|
+
|
|
38
|
+
4.2.8
|
|
39
|
+
baseline profile code modifications
|
|
36
40
|
|
|
37
41
|
Version 4.2.3
|
|
38
42
|
Added build warning confirmation when android.ORIENTATION is not "auto" or android.RESIZEABLE_ACTIVITY is not true.
|
|
@@ -502,120 +502,107 @@ checkAppUniqueId();
|
|
|
502
502
|
|
|
503
503
|
|
|
504
504
|
|
|
505
|
-
// ======================================================
|
|
506
|
-
//
|
|
507
|
-
// ======================================================
|
|
508
|
-
|
|
509
|
-
const
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
}
|
|
598
|
-
}
|
|
599
|
-
}
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
//
|
|
606
|
-
if (subscribeImportError) {
|
|
607
|
-
console.error("🚫 Build failed due to forbidden showSubscribePopup static import.");
|
|
608
|
-
process.exit(1);
|
|
609
|
-
} else {
|
|
610
|
-
console.log("✅ showSubscribePopup import usage is valid.");
|
|
611
|
-
}
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
// ======================================================
|
|
617
|
-
// 🚫 BLOCK STATIC IMPORT OF showSubscribePopup (ANY VERSION) END
|
|
618
|
-
// ======================================================
|
|
505
|
+
// ======================================================
|
|
506
|
+
// ENSURE IAP STARTS FROM THE HOME PAGE
|
|
507
|
+
// ======================================================
|
|
508
|
+
|
|
509
|
+
const getHomePagePath = () => {
|
|
510
|
+
const pagesDir = path.join(ROOT_DIR, "pages");
|
|
511
|
+
if (!fs.existsSync(pagesDir)) return null;
|
|
512
|
+
|
|
513
|
+
const exactHomePath = path.join(pagesDir, "home.f7");
|
|
514
|
+
if (fs.existsSync(exactHomePath)) return exactHomePath;
|
|
515
|
+
|
|
516
|
+
const pageFiles = fs.readdirSync(pagesDir)
|
|
517
|
+
.filter(fileName => fileName.endsWith(".f7"));
|
|
518
|
+
|
|
519
|
+
return pageFiles
|
|
520
|
+
.map(fileName => path.join(pagesDir, fileName))
|
|
521
|
+
.find(filePath => /data-name\s*=\s*['"]home['"]/.test(fs.readFileSync(filePath, "utf8"))) || null;
|
|
522
|
+
};
|
|
523
|
+
|
|
524
|
+
const getRelativeModuleImport = (sourceFile, targetFile) => {
|
|
525
|
+
let relativePath = path.relative(path.dirname(sourceFile), targetFile).replace(/\\/g, "/");
|
|
526
|
+
if (!relativePath.startsWith(".")) relativePath = `./${relativePath}`;
|
|
527
|
+
return relativePath;
|
|
528
|
+
};
|
|
529
|
+
|
|
530
|
+
const addInitIapToExistingImport = (content) => {
|
|
531
|
+
const iapImportRegex = /import\s*\{([^}]*)\}\s*from\s*(['"])([^'"]*\/IAP-\d+(?:\.\d+)*\/IAP-check-And-LoadAd\.js)\2\s*;?/;
|
|
532
|
+
const match = content.match(iapImportRegex);
|
|
533
|
+
if (!match || /\binitIAP\b/.test(match[1])) return content;
|
|
534
|
+
|
|
535
|
+
const importNames = match[1].trim();
|
|
536
|
+
const nextImportNames = importNames ? `initIAP, ${importNames}` : "initIAP";
|
|
537
|
+
return content.replace(iapImportRegex, `import { ${nextImportNames} } from ${match[2]}${match[3]}${match[2]};`);
|
|
538
|
+
};
|
|
539
|
+
|
|
540
|
+
const addInitIapCall = (content) => {
|
|
541
|
+
if (/\binitIAP\s*\(/.test(content)) return content;
|
|
542
|
+
|
|
543
|
+
const pageInitRegex = /(\$on\(\s*(['"])pageInit\2\s*,\s*(?:async\s*)?\(\)\s*=>\s*\{\s*\r?\n)/;
|
|
544
|
+
if (pageInitRegex.test(content)) {
|
|
545
|
+
return content.replace(pageInitRegex, "$1 initIAP();\n");
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
const componentStartRegex = /(export\s+default\s*\([^)]*\)\s*=>\s*\{\s*\r?\n)/;
|
|
549
|
+
if (componentStartRegex.test(content)) {
|
|
550
|
+
return content.replace(componentStartRegex, "$1 initIAP();\n");
|
|
551
|
+
}
|
|
552
|
+
|
|
553
|
+
throw new Error("Unable to find a Framework7 component or pageInit lifecycle for IAP startup.");
|
|
554
|
+
};
|
|
555
|
+
|
|
556
|
+
const ensureIapStartupOnHomePage = () => {
|
|
557
|
+
const iapConfig = getAdmobIapConfig()?.IAP;
|
|
558
|
+
if (!isAnyIapStoreEnabled(iapConfig)) {
|
|
559
|
+
console.log("ℹ️ IAP is disabled for every store. AdMob will use direct startup.");
|
|
560
|
+
return;
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
const latestIapDir = getLatestIapDir();
|
|
564
|
+
if (!latestIapDir) {
|
|
565
|
+
throw new Error("IAP is enabled but no IAP-x.x folder was found.");
|
|
566
|
+
}
|
|
567
|
+
|
|
568
|
+
const homePagePath = getHomePagePath();
|
|
569
|
+
if (!homePagePath) {
|
|
570
|
+
throw new Error("IAP is enabled but a Framework7 Home page could not be found in src/pages.");
|
|
571
|
+
}
|
|
572
|
+
|
|
573
|
+
const iapModulePath = path.join(latestIapDir, "IAP-check-And-LoadAd.js");
|
|
574
|
+
if (!fs.existsSync(iapModulePath)) {
|
|
575
|
+
throw new Error(`IAP startup module is missing: ${iapModulePath}`);
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
let content = fs.readFileSync(homePagePath, "utf8");
|
|
579
|
+
const originalContent = content;
|
|
580
|
+
const staticInitImportRegex = /import\s*\{[^}]*\binitIAP\b[^}]*\}\s*from\s*['"][^'"]*\/IAP-\d+(?:\.\d+)*\/IAP-check-And-LoadAd\.js['"]\s*;?/;
|
|
581
|
+
|
|
582
|
+
content = addInitIapToExistingImport(content);
|
|
583
|
+
|
|
584
|
+
if (!staticInitImportRegex.test(content)) {
|
|
585
|
+
const relativeImport = getRelativeModuleImport(homePagePath, iapModulePath);
|
|
586
|
+
const scriptStartRegex = /<script>\s*\r?\n/;
|
|
587
|
+
if (!scriptStartRegex.test(content)) {
|
|
588
|
+
throw new Error(`Unable to find the script block in ${homePagePath}`);
|
|
589
|
+
}
|
|
590
|
+
content = content.replace(scriptStartRegex, `$&import { initIAP } from '${relativeImport}';\n`);
|
|
591
|
+
}
|
|
592
|
+
|
|
593
|
+
content = addInitIapCall(content);
|
|
594
|
+
|
|
595
|
+
if (content !== originalContent) {
|
|
596
|
+
fs.writeFileSync(homePagePath, content, "utf8");
|
|
597
|
+
console.log(`✅ Added direct IAP startup to ${path.relative(process.cwd(), homePagePath)}.`);
|
|
598
|
+
} else {
|
|
599
|
+
console.log(`ℹ️ Direct IAP startup already configured in ${path.relative(process.cwd(), homePagePath)}.`);
|
|
600
|
+
}
|
|
601
|
+
};
|
|
602
|
+
|
|
603
|
+
// ======================================================
|
|
604
|
+
// ENSURE IAP STARTS FROM THE HOME PAGE END
|
|
605
|
+
// ======================================================
|
|
619
606
|
|
|
620
607
|
|
|
621
608
|
|
|
@@ -4184,9 +4171,10 @@ async function main() {
|
|
|
4184
4171
|
await syncAgentInstructions();
|
|
4185
4172
|
|
|
4186
4173
|
await syncAdmobNextgenMigration();
|
|
4187
|
-
syncSystemBarsSafeAreaMigration();
|
|
4188
|
-
await checkPlugins();
|
|
4189
|
-
|
|
4174
|
+
syncSystemBarsSafeAreaMigration();
|
|
4175
|
+
await checkPlugins();
|
|
4176
|
+
ensureIapStartupOnHomePage();
|
|
4177
|
+
syncRevenueCatIapSetup();
|
|
4190
4178
|
syncFirebaseAnalyticsSetup();
|
|
4191
4179
|
checkAndupdateDropInViteConfig();
|
|
4192
4180
|
checkAdmobConfigurationProperty();
|
|
@@ -122,18 +122,74 @@ animations.forEach((animation) => {
|
|
|
122
122
|
const newMainActivityCode =
|
|
123
123
|
`package ${findPackageName()};
|
|
124
124
|
|
|
125
|
-
import android.os.Build;
|
|
126
|
-
import android.os.Bundle;
|
|
127
|
-
import
|
|
128
|
-
|
|
129
|
-
import
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
125
|
+
import android.os.Build;
|
|
126
|
+
import android.os.Bundle;
|
|
127
|
+
import android.view.View;
|
|
128
|
+
import android.webkit.WebView;
|
|
129
|
+
import com.getcapacitor.BridgeActivity;
|
|
130
|
+
import com.getcapacitor.CapConfig;
|
|
131
|
+
import com.getcapacitor.WebViewListener;
|
|
132
|
+
import org.json.JSONException;
|
|
133
|
+
import java.util.Locale;
|
|
134
|
+
|
|
135
|
+
import androidx.activity.EdgeToEdge;
|
|
136
|
+
import androidx.core.graphics.Insets;
|
|
137
|
+
import androidx.core.view.ViewCompat;
|
|
138
|
+
import androidx.core.view.WindowInsetsCompat;
|
|
139
|
+
|
|
140
|
+
public class MainActivity extends BridgeActivity {
|
|
141
|
+
@Override
|
|
142
|
+
protected void load() {
|
|
143
|
+
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.VANILLA_ICE_CREAM) {
|
|
144
|
+
config = CapConfig.loadDefault(this);
|
|
145
|
+
try {
|
|
146
|
+
config.getPluginConfiguration("SystemBars").getConfigJSON().put("insetsHandling", "disable");
|
|
147
|
+
} catch (JSONException e) {
|
|
148
|
+
throw new IllegalStateException("Unable to configure system bars", e);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
super.load();
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
@Override
|
|
155
|
+
protected void onCreate(Bundle savedInstanceState) {
|
|
156
|
+
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.VANILLA_ICE_CREAM) {
|
|
157
|
+
bridgeBuilder.addWebViewListener(new WebViewListener() {
|
|
158
|
+
@Override
|
|
159
|
+
public void onPageCommitVisible(WebView webView, String url) {
|
|
160
|
+
ViewCompat.requestApplyInsets(getWindow().getDecorView());
|
|
161
|
+
}
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
super.onCreate(savedInstanceState);
|
|
165
|
+
|
|
166
|
+
EdgeToEdge.enable(this);
|
|
167
|
+
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.VANILLA_ICE_CREAM) {
|
|
168
|
+
View decorView = getWindow().getDecorView();
|
|
169
|
+
ViewCompat.setOnApplyWindowInsetsListener(decorView, (view, insets) -> {
|
|
170
|
+
Insets bars = insets.getInsets(WindowInsetsCompat.Type.systemBars() | WindowInsetsCompat.Type.displayCutout());
|
|
171
|
+
float density = getResources().getDisplayMetrics().density;
|
|
172
|
+
int top = Math.round(bars.top / density);
|
|
173
|
+
int right = Math.round(bars.right / density);
|
|
174
|
+
int bottom = insets.isVisible(WindowInsetsCompat.Type.ime()) ? 0 : Math.round(bars.bottom / density);
|
|
175
|
+
int left = Math.round(bars.left / density);
|
|
176
|
+
|
|
177
|
+
if (bridge != null && bridge.getWebView() != null) {
|
|
178
|
+
String script = String.format(Locale.US, """
|
|
179
|
+
try {
|
|
180
|
+
const root = document.documentElement;
|
|
181
|
+
root.style.setProperty('--android-system-bar-top', '%dpx');
|
|
182
|
+
root.style.setProperty('--android-system-bar-right', '%dpx');
|
|
183
|
+
root.style.setProperty('--android-system-bar-bottom', '%dpx');
|
|
184
|
+
root.style.setProperty('--android-system-bar-left', '%dpx');
|
|
185
|
+
} catch (e) {}
|
|
186
|
+
""", top, right, bottom, left);
|
|
187
|
+
bridge.getWebView().evaluateJavascript(script, null);
|
|
188
|
+
}
|
|
189
|
+
return insets;
|
|
190
|
+
});
|
|
191
|
+
ViewCompat.requestApplyInsets(decorView);
|
|
192
|
+
}
|
|
137
193
|
|
|
138
194
|
// Handle custom splash screen exit animation
|
|
139
195
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
|
@@ -148,8 +204,8 @@ import androidx.activity.EdgeToEdge;
|
|
|
148
204
|
});
|
|
149
205
|
}
|
|
150
206
|
}
|
|
151
|
-
}
|
|
152
|
-
|
|
207
|
+
}
|
|
208
|
+
`;
|
|
153
209
|
|
|
154
210
|
// Write the new MainActivity.java content
|
|
155
211
|
writeMainActivity(newMainActivityCode);
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
{"name":"backbutton","pattern":"backbutton-(\\d+\\.\\d+)\\.js$","minVersion":"2.1","baseDir":"js","mandatoryUpdate":true},
|
|
4
4
|
{"name":"common-js","pattern":"common-(\\d+\\.\\d+)(?:-beta-(\\d+))?\\.js$","minVersion":"6.7","baseDir":"js","mandatoryUpdate":true},
|
|
5
5
|
|
|
6
|
-
{"name":"admob-emi-nextgen","pattern":"Ads[\\\\/]admob-emi-nextgen-(\\d+\\.\\d+)\\.js$","minVersion":"
|
|
6
|
+
{"name":"admob-emi-nextgen","pattern":"Ads[\\\\/]admob-emi-nextgen-(\\d+\\.\\d+)\\.js$","minVersion":"2.5","baseDir":"js","mandatoryUpdate":true},
|
|
7
7
|
{"name":"video-player","pattern":"video-player-(\\d+\\.\\d+)\\.js$","minVersion":"1.6","baseDir":"js","mandatoryUpdate":true},
|
|
8
8
|
{"name":"image-cropper","pattern":"image-cropper-(\\d+\\.\\d+)\\.js$","minVersion":"1.1","baseDir":"js","mandatoryUpdate":true},
|
|
9
9
|
{"name":"beautify","pattern":"beautify-(\\d+\\.\\d+)\\.js$","minVersion":"1.1","baseDir":"js","mandatoryUpdate":true},
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
{"name":"ffmpeg","pattern":"ffmpeg-(\\d+\\.\\d+)$","minVersion":"1.6","baseDir":"js","mandatoryUpdate":true,"isFolder":true},
|
|
18
18
|
{"name":"theme","pattern":"theme-(\\d+\\.\\d+)$","minVersion":"3.5","baseDir":"theme","destDir":"theme","mandatoryUpdate":true,"isFolder":true},
|
|
19
19
|
{"name":"certificatejs","pattern":"certificatejs-(\\d+\\.\\d+)$","minVersion":"1.9","baseDir":"certificate","destDir":"certificate","mandatoryUpdate":true,"isFolder":true},
|
|
20
|
-
{"name":"IAP","pattern":"IAP-(\\d+\\.\\d+)$","minVersion":"
|
|
20
|
+
{"name":"IAP","pattern":"IAP-(\\d+\\.\\d+)$","minVersion":"4.2","baseDir":"js/Ads","mandatoryUpdate":true,"isFolder":true},
|
|
21
21
|
{"name":"common-less","pattern":"common-(\\d+\\.\\d+)\\.less$","minVersion":"1.8","baseDir":"assets/css","mandatoryUpdate":true},
|
|
22
22
|
{"name":"localNotification_AppSettings","pattern":"localNotification_AppSettings-(\\d+\\.\\d+)\\.js$","minVersion":"1.0","baseDir":"js","mandatoryUpdate":true},
|
|
23
23
|
{"name":"localNotification","pattern":"localNotification-(\\d+\\.\\d+)\\.js$","minVersion":"2.2","baseDir":"js","mandatoryUpdate":true},
|
package/files/finalrelease
CHANGED
|
@@ -703,7 +703,7 @@ function findGradleBlock(content, headerPattern) {
|
|
|
703
703
|
const amazonWindowExtensionsDependency = 'implementation "androidx.window.extensions.core:core:1.0.0"';
|
|
704
704
|
const amazonWindowExtensionsDependencyPattern = /^[ \t]*implementation\s+["']androidx\.window\.extensions\.core:core:[^"']+["'][ \t]*(?:\r?\n)?/gm;
|
|
705
705
|
|
|
706
|
-
function setAmazonWindowExtensionsDependency(enabled) {
|
|
706
|
+
function setAmazonWindowExtensionsDependency(enabled, { cleanup = false } = {}) {
|
|
707
707
|
const currentGradleContent = readFileSync(gradleFilePath, 'utf8');
|
|
708
708
|
let nextGradleContent = currentGradleContent.replace(amazonWindowExtensionsDependencyPattern, '');
|
|
709
709
|
|
|
@@ -728,7 +728,9 @@ function setAmazonWindowExtensionsDependency(enabled) {
|
|
|
728
728
|
|
|
729
729
|
console.log(enabled
|
|
730
730
|
? '✅ Added Amazon Fire WebView compatibility dependency for Store ID 7.'
|
|
731
|
-
:
|
|
731
|
+
: cleanup
|
|
732
|
+
? 'ℹ️ Removed temporary Amazon Fire WebView compatibility dependency after build cleanup.'
|
|
733
|
+
: 'ℹ️ Amazon Fire WebView compatibility dependency is not included for this build.');
|
|
732
734
|
}
|
|
733
735
|
|
|
734
736
|
const versionCodeMatch = gradleContent.match(/versionCode\s+(\d+)/);
|
|
@@ -1002,11 +1004,15 @@ rl.question('Enter new versionCode (press enter to keep current): ', (newVersion
|
|
|
1002
1004
|
} catch (error) {
|
|
1003
1005
|
console.error(`❌ Error during build for Store ID ${id}:`, error);
|
|
1004
1006
|
restoreFlowchartStoreApi();
|
|
1005
|
-
setAmazonWindowExtensionsDependency(false
|
|
1007
|
+
setAmazonWindowExtensionsDependency(false, {
|
|
1008
|
+
cleanup: String(id) === '7' && amazon === true,
|
|
1009
|
+
});
|
|
1006
1010
|
process.exit(1);
|
|
1007
1011
|
} finally {
|
|
1008
1012
|
restoreFlowchartStoreApi();
|
|
1009
|
-
setAmazonWindowExtensionsDependency(false
|
|
1013
|
+
setAmazonWindowExtensionsDependency(false, {
|
|
1014
|
+
cleanup: String(id) === '7' && amazon === true,
|
|
1015
|
+
});
|
|
1010
1016
|
}
|
|
1011
1017
|
});
|
|
1012
1018
|
|