catalyst-core 0.0.3-canary.6 โ 0.0.3-canary.8
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/changelog.md +46 -22
- package/dist/native/androidProject/.idea/deploymentTargetSelector.xml +0 -8
- package/dist/native/androidProject/.idea/gradle.xml +0 -1
- package/dist/native/androidProject/.idea/misc.xml +2 -6
- package/dist/native/androidProject/.idea/vcs.xml +0 -2
- package/dist/native/androidProject/app/build.gradle.kts +55 -26
- package/dist/native/androidProject/app/src/main/AndroidManifest.xml +3 -2
- package/dist/native/androidProject/app/src/main/java/io/yourname/androidproject/CustomWebview.kt +54 -0
- package/dist/native/androidProject/app/src/main/java/io/yourname/androidproject/MainActivity.kt +24 -0
- package/dist/native/androidProject/app/src/main/java/io/yourname/androidproject/NativeBridge.kt +261 -204
- package/dist/native/androidProject/app/src/main/java/io/yourname/androidproject/Utils.kt +64 -0
- package/dist/native/androidProject/app/src/main/java/io/yourname/androidproject/utils/BridgeUtils.kt +217 -0
- package/dist/native/androidProject/app/src/main/java/io/yourname/androidproject/utils/CameraUtils.kt +269 -0
- package/dist/native/androidProject/app/src/main/java/io/yourname/androidproject/utils/DownloadUtils.kt +251 -0
- package/dist/native/androidProject/app/src/main/java/io/yourname/androidproject/utils/FileSizeRouterUtils.kt +347 -0
- package/dist/native/androidProject/app/src/main/java/io/yourname/androidproject/utils/FileUtils.kt +334 -0
- package/dist/native/androidProject/app/src/main/java/io/yourname/androidproject/utils/FrameworkServerUtils.kt +362 -0
- package/dist/native/androidProject/app/src/main/java/io/yourname/androidproject/utils/IntentUtils.kt +274 -0
- package/dist/native/androidProject/app/src/main/res/drawable/splashscreen_fallback.png +0 -0
- package/dist/native/androidProject/app/src/main/res/xml/file_paths.xml +6 -0
- package/dist/native/androidProject/gradle/libs.versions.toml +1 -1
- package/dist/native/androidProject/gradle/wrapper/gradle-wrapper.properties +1 -1
- package/dist/native/bridge/WebBridge.js +42 -2
- package/dist/native/bridge/constants/NativeInterfaces.js +22 -0
- package/dist/native/bridge/errors.js +39 -0
- package/dist/native/bridge/hooks.js +77 -3
- package/dist/native/bridge/standardizedHooks.js +80 -0
- package/dist/native/bridge/useBaseHook.js +44 -0
- package/dist/native/bridge/utils/NativeBridge.js +55 -0
- package/dist/native/buildAppAndroid.js +66 -22
- package/dist/scripts/loadEnvironmentVariables.js +2 -1
- package/dist/sentry.js +2 -0
- package/dist/webpack/base.babel.js +1 -1
- package/package.json +1 -1
- package/dist/native/androidProject/.idea/codeStyles/Project.xml +0 -123
- package/dist/native/androidProject/.idea/codeStyles/codeStyleConfig.xml +0 -5
- package/dist/native/androidProject/.idea/kotlinc.xml +0 -6
- package/dist/native/androidProject/.idea/other.xml +0 -329
- package/dist/native/androidProject/app/src/main/assets/webview_config.properties +0 -8
- package/dist/native/androidProject/app/src/main/cpp/CMakeLists.txt +0 -41
- package/dist/native/androidProject/app/src/main/cpp/native-lib.cpp +0 -22
- package/dist/native/iosnativeWebView/iosnativeWebView/ConfigConstants.swift +0 -7
- package/dist/native/iosnativeWebView/iosnativeWebView.xcodeproj/project.xcworkspace/xcuserdata/mayankmahavar.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
- package/dist/native/iosnativeWebView/iosnativeWebView.xcodeproj/xcuserdata/mayankmahavar.xcuserdatad/xcschemes/xcschememanagement.plist +0 -32
package/changelog.md
CHANGED
|
@@ -1,34 +1,58 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.0.3-canary.8] - 2025-01-06
|
|
3
4
|
|
|
4
|
-
|
|
5
|
+
- **App icon configuration**
|
|
6
|
+
- **Splash screen integration**
|
|
7
|
+
- **Url Whitelisting**
|
|
5
8
|
|
|
9
|
+
## [0.0.3-canary.7] - 2025-01-06
|
|
6
10
|
|
|
7
|
-
|
|
11
|
+
### ๐ Features
|
|
8
12
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
+
- **Native API Integration**: Enhanced native module integration for better performance
|
|
14
|
+
- **Automated IP Resolution**: Intelligent network detection eliminates manual IP configuration
|
|
15
|
+
- **Universal Build System**: Streamlined one-command builds for both Android and iOS platforms
|
|
16
|
+
- **Enhanced CLI Interface**: Improved command-line tools for better developer experience
|
|
13
17
|
|
|
14
|
-
|
|
18
|
+
### ๐ Bug Fixes
|
|
15
19
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
โข โ
CLI Operations: Tested enhanced command-line workflows
|
|
20
|
+
- Fixed IP address detection issues on development environments
|
|
21
|
+
- Resolved build configuration conflicts between platforms
|
|
22
|
+
- Improved error handling and recovery mechanisms
|
|
20
23
|
|
|
21
|
-
|
|
22
|
-
โข None: All changes are backward compatible
|
|
23
|
-
โข Enhanced: Existing functionality improved without breaking existing workflows
|
|
24
|
+
### ๐ง Improvements
|
|
24
25
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
26
|
+
- **Performance**: Optimized native module loading and execution
|
|
27
|
+
- **Developer Experience**: Enhanced CLI with better error messages and debugging info
|
|
28
|
+
- **Configuration**: Dynamic config updates without requiring restarts
|
|
29
|
+
- **Build Process**: Faster and more reliable build pipeline
|
|
30
|
+
|
|
31
|
+
### ๐งช Testing & Validation
|
|
32
|
+
|
|
33
|
+
- โ
**Android Build**: Verified APK generation, installation, and runtime behavior
|
|
34
|
+
- โ
**iOS Build**: Tested build process and device compatibility
|
|
35
|
+
- โ
**IP Detection**: Validated automatic network resolution across platforms
|
|
36
|
+
- โ
**Native Modules**: Confirmed API integration and performance benchmarks
|
|
37
|
+
- โ
**CLI Operations**: Tested enhanced command-line workflows and error handling
|
|
38
|
+
|
|
39
|
+
### ๐ Breaking Changes
|
|
40
|
+
|
|
41
|
+
**None** - All changes maintain backward compatibility while enhancing existing functionality
|
|
42
|
+
|
|
43
|
+
### ๐ Technical Details
|
|
44
|
+
|
|
45
|
+
- Improved native API bridge for better cross-platform communication
|
|
46
|
+
- Enhanced error reporting with detailed stack traces and suggestions
|
|
47
|
+
- Optimized build configuration for faster development cycles
|
|
48
|
+
- Added comprehensive logging for debugging and monitoring
|
|
49
|
+
|
|
50
|
+
### ๐ Migration Notes
|
|
51
|
+
|
|
52
|
+
- No migration steps required
|
|
53
|
+
- Existing projects will automatically benefit from improvements
|
|
54
|
+
- Optional: Update CLI usage to leverage new enhanced features
|
|
28
55
|
|
|
29
|
-
๐ Related
|
|
30
|
-
โข Base Branch: universal_main
|
|
31
|
-
โข Target: Production deployment automation
|
|
32
|
-
โข Platform: Universal (Android + iOS)
|
|
33
56
|
## Version
|
|
34
|
-
|
|
57
|
+
|
|
58
|
+
- Target version: 0.0.3-canary.7
|
|
@@ -4,14 +4,6 @@
|
|
|
4
4
|
<selectionStates>
|
|
5
5
|
<SelectionState runConfigName="app">
|
|
6
6
|
<option name="selectionMode" value="DROPDOWN" />
|
|
7
|
-
<DropdownSelection timestamp="2025-02-18T04:28:14.358379Z">
|
|
8
|
-
<Target type="DEFAULT_BOOT">
|
|
9
|
-
<handle>
|
|
10
|
-
<DeviceId pluginId="PhysicalDevice" identifier="serial=9fbee4f0" />
|
|
11
|
-
</handle>
|
|
12
|
-
</Target>
|
|
13
|
-
</DropdownSelection>
|
|
14
|
-
<DialogSelection />
|
|
15
7
|
</SelectionState>
|
|
16
8
|
</selectionStates>
|
|
17
9
|
</component>
|
|
@@ -1,9 +1,5 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
1
2
|
<project version="4">
|
|
2
3
|
<component name="ExternalStorageConfigurationManager" enabled="true" />
|
|
3
|
-
<component name="ProjectRootManager" version="2" languageLevel="JDK_21" default="true" project-jdk-name="jbr-21" project-jdk-type="JavaSDK"
|
|
4
|
-
<output url="file://$PROJECT_DIR$/build/classes" />
|
|
5
|
-
</component>
|
|
6
|
-
<component name="ProjectType">
|
|
7
|
-
<option name="id" value="Android" />
|
|
8
|
-
</component>
|
|
4
|
+
<component name="ProjectRootManager" version="2" languageLevel="JDK_21" default="true" project-jdk-name="jbr-21" project-jdk-type="JavaSDK" />
|
|
9
5
|
</project>
|
|
@@ -2,7 +2,5 @@
|
|
|
2
2
|
<project version="4">
|
|
3
3
|
<component name="VcsDirectoryMappings">
|
|
4
4
|
<mapping directory="$PROJECT_DIR$/../../.." vcs="Git" />
|
|
5
|
-
<mapping directory="$PROJECT_DIR$/.." vcs="Git" />
|
|
6
|
-
<mapping directory="$USER_HOME$/catalyst-webview-apps" vcs="Git" />
|
|
7
5
|
</component>
|
|
8
6
|
</project>
|
|
@@ -1,6 +1,14 @@
|
|
|
1
1
|
import java.net.NetworkInterface
|
|
2
2
|
import java.io.File
|
|
3
3
|
import java.util.Properties
|
|
4
|
+
import org.json.JSONObject
|
|
5
|
+
import org.json.JSONArray
|
|
6
|
+
|
|
7
|
+
buildscript {
|
|
8
|
+
dependencies {
|
|
9
|
+
classpath("org.json:json:20231013")
|
|
10
|
+
}
|
|
11
|
+
}
|
|
4
12
|
|
|
5
13
|
val configPath: String? by project.properties
|
|
6
14
|
val keystorePassword: String? by project.properties // Changed from keyStorePassword to keystorePassword
|
|
@@ -111,6 +119,8 @@ android {
|
|
|
111
119
|
excludes.add("**/route-manifest.json.br")
|
|
112
120
|
excludes.add("META-INF/LICENSE")
|
|
113
121
|
excludes.add("META-INF/NOTICE")
|
|
122
|
+
excludes.add("META-INF/INDEX.LIST")
|
|
123
|
+
excludes.add("META-INF/io.netty.versions.properties")
|
|
114
124
|
}
|
|
115
125
|
}
|
|
116
126
|
|
|
@@ -131,6 +141,16 @@ dependencies {
|
|
|
131
141
|
androidTestImplementation(libs.androidx.espresso.core)
|
|
132
142
|
implementation("androidx.webkit:webkit:1.12.1")
|
|
133
143
|
implementation("org.json:json:20231013")
|
|
144
|
+
implementation("androidx.core:core-splashscreen:1.0.1")
|
|
145
|
+
|
|
146
|
+
// Ktor Server dependencies for FrameworkServer (~200KB total)
|
|
147
|
+
implementation("io.ktor:ktor-server-core:2.3.7")
|
|
148
|
+
implementation("io.ktor:ktor-server-netty:2.3.7")
|
|
149
|
+
implementation("io.ktor:ktor-server-content-negotiation:2.3.7")
|
|
150
|
+
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3")
|
|
151
|
+
|
|
152
|
+
// SLF4J simple logger for Ktor (optional, can be excluded if needed)
|
|
153
|
+
implementation("org.slf4j:slf4j-simple:2.0.9")
|
|
134
154
|
}
|
|
135
155
|
|
|
136
156
|
// Task to verify local IP
|
|
@@ -185,12 +205,15 @@ tasks.register("generateWebViewConfig") {
|
|
|
185
205
|
}
|
|
186
206
|
|
|
187
207
|
val configContent = configJsonFile.readText()
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
208
|
+
|
|
209
|
+
val jsonObject = JSONObject(configContent)
|
|
210
|
+
|
|
211
|
+
if (!jsonObject.has("WEBVIEW_CONFIG")) {
|
|
212
|
+
throw GradleException("WEBVIEW_CONFIG not found in config file")
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
val webviewConfig = jsonObject.getJSONObject("WEBVIEW_CONFIG")
|
|
216
|
+
|
|
194
217
|
val properties = Properties()
|
|
195
218
|
|
|
196
219
|
// Set different IP based on build type
|
|
@@ -204,30 +227,36 @@ tasks.register("generateWebViewConfig") {
|
|
|
204
227
|
properties.setProperty("buildOptimisation", "false")
|
|
205
228
|
}
|
|
206
229
|
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
230
|
+
fun extractProperties(jsonObj: org.json.JSONObject, prefix: String = "") {
|
|
231
|
+
try {
|
|
232
|
+
val keys = jsonObj.keys()
|
|
233
|
+
|
|
234
|
+
while (keys.hasNext()) {
|
|
235
|
+
val key = keys.next()
|
|
236
|
+
val value = jsonObj.opt(key)
|
|
237
|
+
val fullKey = if (prefix.isEmpty()) key else "$prefix.$key"
|
|
238
|
+
|
|
239
|
+
when (value) {
|
|
240
|
+
is org.json.JSONObject -> {
|
|
241
|
+
extractProperties(value, fullKey)
|
|
242
|
+
}
|
|
243
|
+
is org.json.JSONArray -> {
|
|
244
|
+
val arrayValues = (0 until value.length()).map { i ->
|
|
245
|
+
value.opt(i).toString()
|
|
246
|
+
}.joinToString(",")
|
|
247
|
+
properties.setProperty(fullKey, arrayValues)
|
|
248
|
+
}
|
|
249
|
+
else -> {
|
|
250
|
+
properties.setProperty(fullKey, value.toString())
|
|
251
|
+
}
|
|
252
|
+
}
|
|
214
253
|
}
|
|
254
|
+
} catch (e: Exception) {
|
|
255
|
+
throw RuntimeException("Failed to extract properties from JSON at prefix: $prefix", e)
|
|
215
256
|
}
|
|
216
257
|
}
|
|
217
258
|
|
|
218
|
-
|
|
219
|
-
val androidRegex = """"android"\s*:\s*\{([^}]*)\}""".toRegex()
|
|
220
|
-
val androidMatch = androidRegex.find(webviewConfigContent ?: "")
|
|
221
|
-
val androidContent = androidMatch?.groupValues?.get(1)
|
|
222
|
-
|
|
223
|
-
// Parse android object properties
|
|
224
|
-
val androidPropsRegex = """"([^"]+)"\s*:\s*"([^"]+)"""".toRegex()
|
|
225
|
-
androidContent?.let {
|
|
226
|
-
androidPropsRegex.findAll(it).forEach { matchResult ->
|
|
227
|
-
val (key, value) = matchResult.destructured
|
|
228
|
-
properties.setProperty("android.$key", value)
|
|
229
|
-
}
|
|
230
|
-
}
|
|
259
|
+
extractProperties(webviewConfig)
|
|
231
260
|
|
|
232
261
|
// Set production-specific properties for release builds
|
|
233
262
|
if (gradle.startParameter.taskNames.any { it.contains("Release") || it.contains("release") }) {
|
|
@@ -25,7 +25,8 @@
|
|
|
25
25
|
tools:targetApi="31">
|
|
26
26
|
<activity
|
|
27
27
|
android:name="io.yourname.androidproject.MainActivity"
|
|
28
|
-
android:exported="true"
|
|
28
|
+
android:exported="true"
|
|
29
|
+
android:screenOrientation="portrait">
|
|
29
30
|
<intent-filter>
|
|
30
31
|
<action android:name="android.intent.action.MAIN" />
|
|
31
32
|
|
|
@@ -34,7 +35,7 @@
|
|
|
34
35
|
</activity>
|
|
35
36
|
<provider
|
|
36
37
|
android:name="androidx.core.content.FileProvider"
|
|
37
|
-
android:authorities="io.yourname.androidproject.
|
|
38
|
+
android:authorities="io.yourname.androidproject.fileprovider"
|
|
38
39
|
android:exported="false"
|
|
39
40
|
android:grantUriPermissions="true">
|
|
40
41
|
<meta-data
|
package/dist/native/androidProject/app/src/main/java/io/yourname/androidproject/CustomWebview.kt
CHANGED
|
@@ -2,6 +2,7 @@ package io.yourname.androidproject
|
|
|
2
2
|
|
|
3
3
|
import android.annotation.SuppressLint
|
|
4
4
|
import android.content.Context
|
|
5
|
+
import android.content.Intent
|
|
5
6
|
import android.graphics.Bitmap
|
|
6
7
|
import android.net.Uri
|
|
7
8
|
import android.os.Bundle
|
|
@@ -11,6 +12,8 @@ import android.webkit.*
|
|
|
11
12
|
import android.widget.ProgressBar
|
|
12
13
|
import androidx.webkit.WebViewAssetLoader
|
|
13
14
|
import io.yourname.androidproject.WebCacheManager
|
|
15
|
+
import io.yourname.androidproject.isUrlAllowed
|
|
16
|
+
import io.yourname.androidproject.isExternalDomain
|
|
14
17
|
import kotlinx.coroutines.*
|
|
15
18
|
import java.util.Properties
|
|
16
19
|
|
|
@@ -34,6 +37,7 @@ class CustomWebView(
|
|
|
34
37
|
private var isInitialPageLoaded: Boolean = false
|
|
35
38
|
private var buildOptimisation: Boolean = false // Added property for build optimization
|
|
36
39
|
private lateinit var assetLoader: WebViewAssetLoader
|
|
40
|
+
private var allowedUrls: List<String> = emptyList()
|
|
37
41
|
|
|
38
42
|
// Counters for asset loading statistics
|
|
39
43
|
private var assetLoadAttempts = 0
|
|
@@ -56,6 +60,12 @@ class CustomWebView(
|
|
|
56
60
|
// Parse buildOptimisation property
|
|
57
61
|
buildOptimisation = properties.getProperty("buildOptimisation", "false").toBoolean()
|
|
58
62
|
|
|
63
|
+
// Load allowed URLs from properties
|
|
64
|
+
allowedUrls = properties.getProperty("accessControl.allowedUrls", "")
|
|
65
|
+
.split(",")
|
|
66
|
+
.map { it.trim() }
|
|
67
|
+
.filter { it.isNotEmpty() }
|
|
68
|
+
|
|
59
69
|
// Set initial flags based on buildOptimisation
|
|
60
70
|
if (buildOptimisation) {
|
|
61
71
|
isInitialApiCalled = false
|
|
@@ -71,6 +81,7 @@ class CustomWebView(
|
|
|
71
81
|
Log.d(TAG, "Cache Pattern: $cachePatterns")
|
|
72
82
|
Log.d(TAG, "API Base URL: $apiBaseUrl")
|
|
73
83
|
Log.d(TAG, "Build Optimisation: $buildOptimisation")
|
|
84
|
+
Log.d(TAG, "Allowed URLs: $allowedUrls")
|
|
74
85
|
Log.d(TAG, "Initial API Called: $isInitialApiCalled")
|
|
75
86
|
Log.d(TAG, "Initial Page Loaded: $isInitialPageLoaded")
|
|
76
87
|
}
|
|
@@ -198,6 +209,22 @@ class CustomWebView(
|
|
|
198
209
|
}
|
|
199
210
|
}
|
|
200
211
|
|
|
212
|
+
|
|
213
|
+
|
|
214
|
+
private fun openInInAppBrowser(url: String) {
|
|
215
|
+
try {
|
|
216
|
+
val intent = Intent(Intent.ACTION_VIEW, Uri.parse(url))
|
|
217
|
+
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
|
218
|
+
context.startActivity(intent)
|
|
219
|
+
if (BuildConfig.DEBUG) {
|
|
220
|
+
Log.d(TAG, "๐ Opening external URL in in-app browser: $url")
|
|
221
|
+
}
|
|
222
|
+
} catch (e: Exception) {
|
|
223
|
+
Log.e(TAG, "โ Failed to open URL in in-app browser: $url", e)
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
|
|
201
228
|
private fun isApiCall(url: String): Boolean {
|
|
202
229
|
// Check if URL is an API call based on your API base URL
|
|
203
230
|
return apiBaseUrl.isNotEmpty() && url.startsWith(apiBaseUrl)
|
|
@@ -290,6 +317,25 @@ class CustomWebView(
|
|
|
290
317
|
webView.webViewClient = object : WebViewClient() {
|
|
291
318
|
override fun shouldOverrideUrlLoading(view: WebView?, request: WebResourceRequest?): Boolean {
|
|
292
319
|
request?.url?.let { url ->
|
|
320
|
+
val urlString = url.toString()
|
|
321
|
+
|
|
322
|
+
// Check if URL is an external domain
|
|
323
|
+
if (url.scheme in listOf("http", "https") && isExternalDomain(urlString, allowedUrls)) {
|
|
324
|
+
if (BuildConfig.DEBUG) {
|
|
325
|
+
Log.d(TAG, "๐ External domain detected, opening in in-app browser: $urlString")
|
|
326
|
+
}
|
|
327
|
+
openInInAppBrowser(urlString)
|
|
328
|
+
return true
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
// Check if URL is allowed for internal navigation
|
|
332
|
+
if (!isUrlAllowed(urlString, allowedUrls)) {
|
|
333
|
+
if (BuildConfig.DEBUG) {
|
|
334
|
+
Log.w(TAG, "๐ซ URL blocked by access control: $urlString")
|
|
335
|
+
}
|
|
336
|
+
return true
|
|
337
|
+
}
|
|
338
|
+
|
|
293
339
|
// Let WebView handle loading non-API HTTP/HTTPS URLs
|
|
294
340
|
if (url.scheme in listOf("http", "https")) {
|
|
295
341
|
return false
|
|
@@ -307,6 +353,14 @@ class CustomWebView(
|
|
|
307
353
|
Log.d(TAG, "๐ Intercepting request for: $url on thread: ${Thread.currentThread().name}")
|
|
308
354
|
}
|
|
309
355
|
|
|
356
|
+
if (!isUrlAllowed(url, allowedUrls)) {
|
|
357
|
+
if (BuildConfig.DEBUG) {
|
|
358
|
+
Log.w(TAG, "๐ซ Network request blocked by access control: $url")
|
|
359
|
+
}
|
|
360
|
+
// Return an empty response to block the request
|
|
361
|
+
return WebResourceResponse("text/plain", "utf-8", null)
|
|
362
|
+
}
|
|
363
|
+
|
|
310
364
|
// Handle the initial route request - intercept first request regardless of host
|
|
311
365
|
if (!isInitialApiCalled && request.method == "GET") {
|
|
312
366
|
isInitialApiCalled = true
|
package/dist/native/androidProject/app/src/main/java/io/yourname/androidproject/MainActivity.kt
CHANGED
|
@@ -10,6 +10,7 @@ import io.yourname.androidproject.NativeBridge
|
|
|
10
10
|
import kotlinx.coroutines.CoroutineScope
|
|
11
11
|
import kotlinx.coroutines.MainScope
|
|
12
12
|
import kotlinx.coroutines.cancelChildren
|
|
13
|
+
import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
|
|
13
14
|
|
|
14
15
|
class MainActivity : AppCompatActivity(), CoroutineScope by MainScope() {
|
|
15
16
|
|
|
@@ -20,6 +21,7 @@ class MainActivity : AppCompatActivity(), CoroutineScope by MainScope() {
|
|
|
20
21
|
private lateinit var properties: Properties
|
|
21
22
|
private var isHardwareAccelerationEnabled = false
|
|
22
23
|
private var currentUrl: String = ""
|
|
24
|
+
private var splashStartTime: Long = 0
|
|
23
25
|
|
|
24
26
|
private fun enableHardwareAcceleration() {
|
|
25
27
|
if (!isHardwareAccelerationEnabled) {
|
|
@@ -45,6 +47,7 @@ class MainActivity : AppCompatActivity(), CoroutineScope by MainScope() {
|
|
|
45
47
|
}
|
|
46
48
|
|
|
47
49
|
override fun onCreate(savedInstanceState: Bundle?) {
|
|
50
|
+
val splashScreen = installSplashScreen()
|
|
48
51
|
super.onCreate(savedInstanceState)
|
|
49
52
|
if (BuildConfig.DEBUG) {
|
|
50
53
|
Log.d(TAG, "๐ฑ onCreate started on thread: ${Thread.currentThread().name}")
|
|
@@ -63,6 +66,10 @@ class MainActivity : AppCompatActivity(), CoroutineScope by MainScope() {
|
|
|
63
66
|
properties.setProperty("buildOptimisation", (!BuildConfig.DEBUG).toString())
|
|
64
67
|
}
|
|
65
68
|
|
|
69
|
+
// Configure splash screen
|
|
70
|
+
splashStartTime = System.currentTimeMillis()
|
|
71
|
+
configureSplashScreen(splashScreen)
|
|
72
|
+
|
|
66
73
|
// Setup UI
|
|
67
74
|
binding = ActivityMainBinding.inflate(layoutInflater)
|
|
68
75
|
supportActionBar?.hide()
|
|
@@ -159,4 +166,21 @@ class MainActivity : AppCompatActivity(), CoroutineScope by MainScope() {
|
|
|
159
166
|
customWebView.destroy()
|
|
160
167
|
super.onDestroy()
|
|
161
168
|
}
|
|
169
|
+
|
|
170
|
+
private fun configureSplashScreen(splashScreen: androidx.core.splashscreen.SplashScreen) {
|
|
171
|
+
val durationProperty = properties.getProperty("splashScreen.duration")
|
|
172
|
+
|
|
173
|
+
splashScreen.setKeepOnScreenCondition {
|
|
174
|
+
val webViewLoaded = ::customWebView.isInitialized &&
|
|
175
|
+
customWebView.getWebView().progress >= 100
|
|
176
|
+
|
|
177
|
+
if (durationProperty != null) {
|
|
178
|
+
val duration = durationProperty.toLong()
|
|
179
|
+
val timeElapsed = System.currentTimeMillis() - splashStartTime >= duration
|
|
180
|
+
!timeElapsed
|
|
181
|
+
} else {
|
|
182
|
+
!webViewLoaded
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
}
|
|
162
186
|
}
|