diff --git a/package-lock.json b/package-lock.json index c80e0ef00..a1e7dd570 100644 --- a/package-lock.json +++ b/package-lock.json @@ -54,6 +54,7 @@ "@types/url-parse": "^1.4.11", "autoprefixer": "^10.4.21", "babel-loader": "^10.0.0", + "com.foxdebug.acode.rk.customtabs": "file:src/plugins/custom-tabs", "com.foxdebug.acode.rk.exec.proot": "file:src/plugins/proot", "com.foxdebug.acode.rk.exec.terminal": "file:src/plugins/terminal", "cordova-android": "^14.0.1", @@ -128,7 +129,6 @@ "integrity": "sha512-UlLAnTPrFdNGoFtbSXwcGFQBtQZJCNjaN6hQNP3UPvuNXT1i82N26KL3dZeIpNalWywr9IuQuncaAfUaS1g6sQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@ampproject/remapping": "^2.2.0", "@babel/code-frame": "^7.27.1", @@ -2959,7 +2959,8 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/@types/linkify-it/-/linkify-it-5.0.0.tgz", "integrity": "sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q==", - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/@types/markdown-it": { "version": "14.1.2", @@ -2976,7 +2977,8 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/@types/mdurl/-/mdurl-2.0.0.tgz", "integrity": "sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg==", - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/@types/node": { "version": "24.2.1", @@ -3289,8 +3291,7 @@ "version": "5.5.0", "resolved": "https://registry.npmjs.org/@xterm/xterm/-/xterm-5.5.0.tgz", "integrity": "sha512-hqJHYaQb5OptNunnyAnkHyM8aCjZ1MEIDTQu1iIbbTD/xops91NB5yq1ZK/dC2JDbVWtF23zUtl9JE2NqwT87A==", - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/@xtuc/ieee754": { "version": "1.2.0", @@ -3321,7 +3322,6 @@ "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", "dev": true, "license": "MIT", - "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -3355,7 +3355,6 @@ "version": "8.12.0", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "fast-deep-equal": "^3.1.1", "json-schema-traverse": "^1.0.0", @@ -3736,7 +3735,6 @@ } ], "license": "MIT", - "peer": true, "dependencies": { "caniuse-lite": "^1.0.30001733", "electron-to-chromium": "^1.5.199", @@ -3839,7 +3837,6 @@ "integrity": "sha512-ci2iJH6LeIkvP9eJW6gpueU8cnZhv85ELY8w8WiFtNjMHA5ad6pQLaJo9mEly/9qUyCpvqX8/POVUTf18/HFdw==", "dev": true, "license": "Apache-2.0", - "peer": true, "dependencies": { "@chevrotain/cst-dts-gen": "11.0.3", "@chevrotain/gast": "11.0.3", @@ -3986,6 +3983,10 @@ "dev": true, "license": "MIT" }, + "node_modules/com.foxdebug.acode.rk.customtabs": { + "resolved": "src/plugins/custom-tabs", + "link": true + }, "node_modules/com.foxdebug.acode.rk.exec.proot": { "resolved": "src/plugins/proot", "link": true @@ -6020,7 +6021,6 @@ "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.1.0.tgz", "integrity": "sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==", "license": "MIT", - "peer": true, "dependencies": { "argparse": "^2.0.1", "entities": "^4.4.0", @@ -6906,7 +6906,6 @@ "url": "https://github.com/sponsors/ai" } ], - "peer": true, "dependencies": { "nanoid": "^3.3.7", "picocolors": "^1.0.0", @@ -7061,7 +7060,6 @@ "integrity": "sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==", "dev": true, "license": "MIT", - "peer": true, "bin": { "prettier": "bin/prettier.cjs" }, @@ -7228,7 +7226,6 @@ "version": "6.12.6", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -8061,7 +8058,6 @@ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", "license": "MIT", - "peer": true, "engines": { "node": ">=12" }, @@ -8333,7 +8329,6 @@ "integrity": "sha512-B4t+nJqytPeuZlHuIKTbalhljIFXeNRqrUGAQgTGlfOl2lXXKXw+yZu6bicycP+PUlM44CxBjCFD6aciKFT3LQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@types/eslint-scope": "^3.7.7", "@types/estree": "^1.0.8", @@ -8383,7 +8378,6 @@ "integrity": "sha512-MfwFQ6SfwinsUVi0rNJm7rHZ31GyTcpVE5pgVA3hwFRb7COD4TzjUUwhGWKfO50+xdc2MQPuEBBJoqIMGt3JDw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@discoveryjs/json-ext": "^0.6.1", "@webpack-cli/configtest": "^3.0.1", @@ -8751,6 +8745,12 @@ } } }, + "src/plugins/custom-tabs": { + "name": "com.foxdebug.acode.rk.customtabs", + "version": "1.0.0", + "dev": true, + "license": "MIT" + }, "src/plugins/Executor": { "name": "com.foxdebug.acode.rk.exec.terminal", "version": "1.0.0", diff --git a/package.json b/package.json index f29c7648b..6f81a0789 100644 --- a/package.json +++ b/package.json @@ -38,7 +38,8 @@ "cordova-plugin-sftp": {}, "cordova-plugin-system": {}, "com.foxdebug.acode.rk.exec.proot": {}, - "com.foxdebug.acode.rk.exec.terminal": {} + "com.foxdebug.acode.rk.exec.terminal": {}, + "com.foxdebug.acode.rk.customtabs": {} }, "platforms": [ "android" @@ -63,6 +64,7 @@ "@types/url-parse": "^1.4.11", "autoprefixer": "^10.4.21", "babel-loader": "^10.0.0", + "com.foxdebug.acode.rk.customtabs": "file:src/plugins/custom-tabs", "com.foxdebug.acode.rk.exec.proot": "file:src/plugins/proot", "com.foxdebug.acode.rk.exec.terminal": "file:src/plugins/terminal", "cordova-android": "^14.0.1", diff --git a/src/plugins/custom-tabs/package.json b/src/plugins/custom-tabs/package.json new file mode 100644 index 000000000..eeea20401 --- /dev/null +++ b/src/plugins/custom-tabs/package.json @@ -0,0 +1,17 @@ +{ + "name": "com.foxdebug.acode.rk.customtabs", + "version": "1.0.0", + "description": "Custom tabs api", + "cordova": { + "id": "com.foxdebug.acode.rk.customtabs", + "platforms": [ + "android" + ] + }, + "keywords": [ + "ecosystem:cordova", + "cordova-android" + ], + "author": "@RohitKushvaha01", + "license": "MIT" +} \ No newline at end of file diff --git a/src/plugins/custom-tabs/plugin.xml b/src/plugins/custom-tabs/plugin.xml new file mode 100644 index 000000000..39d5b9b97 --- /dev/null +++ b/src/plugins/custom-tabs/plugin.xml @@ -0,0 +1,36 @@ + + + Custom Tabs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/plugins/custom-tabs/src/CustomTabsPlugin.java b/src/plugins/custom-tabs/src/CustomTabsPlugin.java new file mode 100644 index 000000000..652329dc8 --- /dev/null +++ b/src/plugins/custom-tabs/src/CustomTabsPlugin.java @@ -0,0 +1,80 @@ +package com.foxdebug.acode.rk.customtabs; + +import android.content.ActivityNotFoundException; +import android.content.Intent; +import android.net.Uri; +import android.graphics.Color; + +import androidx.browser.customtabs.CustomTabsIntent; + +import org.apache.cordova.CallbackContext; +import org.apache.cordova.CordovaPlugin; +import org.json.JSONArray; +import org.json.JSONObject; + +public class CustomTabsPlugin extends CordovaPlugin { + + @Override + public boolean execute( + String action, + JSONArray args, + CallbackContext callbackContext + ) { + + if ("open".equals(action)) { + try { + final String url = args.getString(0); + final JSONObject options = args.optJSONObject(1) != null + ? args.optJSONObject(1) + : new JSONObject(); + + cordova.getActivity().runOnUiThread(() -> { + try { + openCustomTab(url, options); + callbackContext.success(); + } catch (Exception e) { + callbackContext.error(e.getMessage()); + } + }); + + return true; + + } catch (Exception e) { + callbackContext.error(e.getMessage()); + return true; + } + } + + return false; + } + + private void openCustomTab(String url, JSONObject options) { + CustomTabsIntent.Builder builder = new CustomTabsIntent.Builder(); + + if (options.optBoolean("showTitle", true)) { + builder.setShowTitle(true); + } + + String toolbarColor = options.optString("toolbarColor", null); + if (toolbarColor != null && !toolbarColor.isEmpty()) { + builder.setToolbarColor(Color.parseColor(toolbarColor)); + } + + CustomTabsIntent customTabsIntent = builder.build(); + customTabsIntent.intent.setPackage("com.android.chrome"); + + try { + customTabsIntent.launchUrl( + cordova.getActivity(), + Uri.parse(url) + ); + } catch (ActivityNotFoundException e) { + // Fallback to default browser + Intent fallback = new Intent( + Intent.ACTION_VIEW, + Uri.parse(url) + ); + cordova.getActivity().startActivity(fallback); + } + } +} diff --git a/src/plugins/custom-tabs/www/customtabs.js b/src/plugins/custom-tabs/www/customtabs.js new file mode 100644 index 000000000..f87bb60f0 --- /dev/null +++ b/src/plugins/custom-tabs/www/customtabs.js @@ -0,0 +1,11 @@ +var exec = require('cordova/exec'); + +exports.open = function (url, options, success, error) { + exec( + success, + error, + 'CustomTabs', + 'open', + [url, options || {}] + ); +}; diff --git a/src/plugins/terminal/www/Executor.js b/src/plugins/terminal/www/Executor.js index 419713e6d..01d4ba414 100644 --- a/src/plugins/terminal/www/Executor.js +++ b/src/plugins/terminal/www/Executor.js @@ -32,7 +32,7 @@ class Executor { * executor.stop(uuid); * }); */ - start(command, onData, alpine = false) { + start(command, onData, alpine = true) { return new Promise((resolve, reject) => { let first = true; exec( @@ -172,7 +172,7 @@ class Executor { * .then(//console.log) * .catch(console.error); */ - execute(command, alpine = false) { + execute(command, alpine = true) { return new Promise((resolve, reject) => { exec(resolve, reject, this.ExecutorType, "exec", [command, String(alpine)]); }); @@ -198,4 +198,4 @@ class Executor { const executorInstance = new Executor(); executorInstance.BackgroundExecutor = new Executor(true); -module.exports = executorInstance; \ No newline at end of file +module.exports = executorInstance;