diff --git a/biome.json b/biome.json
index 40b499694..2ee8fb48b 100644
--- a/biome.json
+++ b/biome.json
@@ -1,5 +1,5 @@
{
- "$schema": "https://biomejs.dev/schemas/2.1.4/schema.json",
+ "$schema": "https://biomejs.dev/schemas/2.4.6/schema.json",
"formatter": {
"enabled": true,
"indentStyle": "tab"
diff --git a/package.json b/package.json
index f571532bd..31821aee5 100644
--- a/package.json
+++ b/package.json
@@ -63,7 +63,7 @@
"@babel/preset-typescript": "^7.28.5",
"@babel/runtime": "^7.28.4",
"@babel/runtime-corejs3": "^7.28.4",
- "@biomejs/biome": "2.1.4",
+ "@biomejs/biome": "2.4.6",
"@rspack/cli": "^1.7.0",
"@rspack/core": "^1.7.0",
"@types/ace": "^0.0.52",
diff --git a/src/components/lspInfoDialog/index.js b/src/components/lspInfoDialog/index.js
index c2fa2e4e1..eb6a1d369 100644
--- a/src/components/lspInfoDialog/index.js
+++ b/src/components/lspInfoDialog/index.js
@@ -634,22 +634,24 @@ function showLspInfoDialog() {
- {logs.length === 0
- ?
No logs yet
- : logs.slice(-50).map((log) => {
- const time = log.timestamp.toLocaleTimeString("en-US", {
- hour12: false,
- hour: "2-digit",
- minute: "2-digit",
- second: "2-digit",
- });
- return (
-
- {time}
- {log.message}
-
- );
- })}
+ {logs.length === 0 ? (
+
No logs yet
+ ) : (
+ logs.slice(-50).map((log) => {
+ const time = log.timestamp.toLocaleTimeString("en-US", {
+ hour12: false,
+ hour: "2-digit",
+ minute: "2-digit",
+ second: "2-digit",
+ });
+ return (
+
+ {time}
+ {log.message}
+
+ );
+ })
+ )}
);
diff --git a/src/components/settingsPage.js b/src/components/settingsPage.js
index 53b02db68..2e04e76a7 100644
--- a/src/components/settingsPage.js
+++ b/src/components/settingsPage.js
@@ -435,9 +435,9 @@ function createTrailingValueDisplay(item) {
return (
@@ -121,14 +121,16 @@ export default (props) => {
{author}
- {authorVerified
- ? {
- toast(strings["verified publisher"]);
- }}
- className="licons verified verified-tick"
- >
- : ""}
+ {authorVerified ? (
+ {
+ toast(strings["verified publisher"]);
+ }}
+ className="licons verified verified-tick"
+ >
+ ) : (
+ ""
+ )}
{
{license || "Unknown"}
- {votesUp !== undefined
- ?
-
-
-
- {helpers.formatDownloadCount(
- typeof downloads === "string"
- ? Number.parseInt(downloads)
- : downloads,
- )}
-
- {strings.downloads}
-
-
-
- = 80 ? "rating-high" : rating.replace("%", "") >= 50 ? "rating-medium" : "rating-low"}`}
- >
- {rating}
-
-
-
+
+
+
+ {helpers.formatDownloadCount(
+ typeof downloads === "string"
+ ? Number.parseInt(downloads)
+ : downloads,
+ )}
+
+ {strings.downloads}
+
+
+
+ = 80 ? "rating-high" : rating.replace("%", "") >= 50 ? "rating-medium" : "rating-low"}`}
>
-
- {commentCount}
- {strings.reviews}
-
+ {rating}
+
- : null}
- {Array.isArray(keywords) && keywords.length
- ?
- {keywords.map((keyword) => (
-
{keyword}
- ))}
+
+
+ {commentCount}
+ {strings.reviews}
- : null}
+
+ ) : null}
+ {Array.isArray(keywords) && keywords.length ? (
+
+ {keywords.map((keyword) => (
+ {keyword}
+ ))}
+
+ ) : null}
diff --git a/src/plugins/system/android/com/foxdebug/system/System.java b/src/plugins/system/android/com/foxdebug/system/System.java
index 0c32cdfe2..55fb27062 100644
--- a/src/plugins/system/android/com/foxdebug/system/System.java
+++ b/src/plugins/system/android/com/foxdebug/system/System.java
@@ -546,7 +546,7 @@ public void run() {
openInBrowser(arg1, callbackContext);
break;
case "launch-app":
- launchApp(arg1, arg2, arg3, callbackContext);
+ launchApp(arg1, arg2, args.optJSONObject(2), callbackContext);
break;
case "get-global-setting":
getGlobalSetting(arg1, callbackContext);
@@ -1564,7 +1564,7 @@ private void openInBrowser(String src, CallbackContext callback) {
private void launchApp(
String appId,
String className,
- String data,
+ JSONObject extras,
CallbackContext callback
) {
if (appId == null || appId.equals("")) {
@@ -1582,21 +1582,38 @@ private void launchApp(
intent.addCategory(Intent.CATEGORY_LAUNCHER);
intent.setPackage(appId);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ intent.setClassName(appId, className);
+
+ if (extras != null) {
+ Iterator keys = extras.keys();
+
+ while (keys.hasNext()) {
+ String key = keys.next();
+ Object value = extras.get(key);
- if (data != null && !data.equals("")) {
- intent.putExtra("acode_data", data);
+ if (value instanceof Integer) {
+ intent.putExtra(key, (Integer) value);
+ } else if (value instanceof Boolean) {
+ intent.putExtra(key, (Boolean) value);
+ } else if (value instanceof Double) {
+ intent.putExtra(key, (Double) value);
+ } else if (value instanceof Long) {
+ intent.putExtra(key, (Long) value);
+ } else if (value instanceof String) {
+ intent.putExtra(key, (String) value);
+ } else {
+ intent.putExtra(key, value.toString());
+ }
+ }
}
- intent.setClassName(appId, className);
activity.startActivity(intent);
callback.success("Launched " + appId);
+
} catch (Exception e) {
callback.error(e.toString());
- return;
}
-
-
}
diff --git a/src/plugins/system/system.d.ts b/src/plugins/system/system.d.ts
index 81b4cb20a..aa2ef8bf7 100644
--- a/src/plugins/system/system.d.ts
+++ b/src/plugins/system/system.d.ts
@@ -27,33 +27,33 @@ interface FileShortcut {
uri: string;
}
-interface Intent {
- action: string;
- data: string;
- type: string;
+interface Intent {
+ action: string;
+ data: string;
+ type: string;
package: string;
extras: {
[key: string]: any;
};
-}
-
-interface RewardStatus {
- adFreeUntil: number;
- lastExpiredRewardUntil: number;
- isActive: boolean;
- remainingMs: number;
- redemptionsToday: number;
- remainingRedemptions: number;
- maxRedemptionsPerDay: number;
- maxActivePassMs: number;
- hasPendingExpiryNotice: boolean;
- expiryNoticePendingUntil: number;
- canRedeem: boolean;
- redeemDisabledReason: string;
- grantedDurationMs?: number;
- appliedDurationMs?: number;
- offerId?: string;
-}
+}
+
+interface RewardStatus {
+ adFreeUntil: number;
+ lastExpiredRewardUntil: number;
+ isActive: boolean;
+ remainingMs: number;
+ redemptionsToday: number;
+ remainingRedemptions: number;
+ maxRedemptionsPerDay: number;
+ maxActivePassMs: number;
+ hasPendingExpiryNotice: boolean;
+ expiryNoticePendingUntil: number;
+ canRedeem: boolean;
+ redeemDisabledReason: string;
+ grantedDurationMs?: number;
+ appliedDurationMs?: number;
+ offerId?: string;
+}
type FileAction = 'VIEW' | 'EDIT' | 'SEND' | 'RUN';
type OnFail = (err: string) => void;
@@ -226,19 +226,20 @@ interface System {
*/
openInBrowser(src: string): void;
/**
- * Launches and app
- * @param app the package name of the app
- * @param className the full class name of the activity
- * @param data Data to pass to the app
- * @param onSuccess
- * @param onFail
+ * Launch an Android application activity.
+ *
+ * @param app Package name of the application (e.g. `com.example.app`)
+ * @param className Fully qualified activity class name (e.g. `com.example.app.MainActivity`)
+ * @param extras Optional key-value pairs passed as Android Intent extras
+ * @param onSuccess Called when the activity launches successfully
+ * @param onFail Called if launching the activity fails
*/
launchApp(
app: string,
className: string,
- data: string,
- onSuccess: OnSuccessBool,
- onFail: OnFail,
+ extras?: Record,
+ onSuccess?: OnSuccessBool,
+ onFail?: OnFail,
): void;
/**
@@ -272,19 +273,19 @@ interface System {
* @param onSuccess
* @param onFail
*/
- getCordovaIntent(onSuccess: (intent: Intent) => void, onFail: OnFail): void;
- getRewardStatus(
- onSuccess: (status: RewardStatus | string) => void,
- onFail: OnFail,
- ): void;
- redeemReward(
- offerId: string,
- onSuccess: (status: RewardStatus | string) => void,
- onFail: OnFail,
- ): void;
- /**
- * Enable/disable native WebView long-press context behavior.
- * Use this when rendering a custom editor context menu.
+ getCordovaIntent(onSuccess: (intent: Intent) => void, onFail: OnFail): void;
+ getRewardStatus(
+ onSuccess: (status: RewardStatus | string) => void,
+ onFail: OnFail,
+ ): void;
+ redeemReward(
+ offerId: string,
+ onSuccess: (status: RewardStatus | string) => void,
+ onFail: OnFail,
+ ): void;
+ /**
+ * Enable/disable native WebView long-press context behavior.
+ * Use this when rendering a custom editor context menu.
* @param disabled
* @param onSuccess
* @param onFail
diff --git a/src/plugins/system/www/plugin.js b/src/plugins/system/www/plugin.js
index 939c130c7..49727ad4b 100644
--- a/src/plugins/system/www/plugin.js
+++ b/src/plugins/system/www/plugin.js
@@ -126,8 +126,30 @@ module.exports = {
openInBrowser: function (src) {
cordova.exec(null, null, 'System', 'open-in-browser', [src]);
},
- launchApp: function (app, className, data, onSuccess, onFail) {
- cordova.exec(onSuccess, onFail, 'System', 'launch-app', [app, className, data]);
+ /**
+ * Launch an Android application activity.
+ *
+ * @param {string} app - Package name of the application (e.g. `com.example.app`).
+ * @param {string} className - Fully qualified activity class name (e.g. `com.example.app.MainActivity`).
+ * @param {Object} [extras] - Optional key-value pairs passed as Intent extras.
+ * @param {(message: string) => void} [onSuccess] - Callback invoked when the activity launches successfully.
+ * @param {(error: any) => void} [onFail] - Callback invoked if launching the activity fails.
+ *
+ * @example
+ * System.launchApp(
+ * "com.example.app",
+ * "com.example.app.MainActivity",
+ * {
+ * user: "example",
+ * age: 20,
+ * premium: true
+ * },
+ * (msg) => console.log(msg),
+ * (err) => console.error(err)
+ * );
+ */
+ launchApp: function (app, className, extras, onSuccess, onFail) {
+ cordova.exec(onSuccess, onFail, 'System', 'launch-app', [app, className, extras]);
},
inAppBrowser: function (url, title, showButtons, disableCache) {
var myInAppBrowser = {
diff --git a/src/sidebarApps/extensions/index.js b/src/sidebarApps/extensions/index.js
index c2c36426d..2502e9b29 100644
--- a/src/sidebarApps/extensions/index.js
+++ b/src/sidebarApps/extensions/index.js
@@ -726,20 +726,22 @@ function ListItem({ icon, name, id, version, downloads, installed, source }) {
>
{name}
- {installed
- ? <>
- {source
- ?
- : null}
-
- >
- : }
+ {installed ? (
+ <>
+ {source ? (
+
+ ) : null}
+
+ >
+ ) : (
+
+ )}
);