react-native-acoustic-connect-beta
Version:
BETA: React native plugin for Acoustic Connect
184 lines (159 loc) • 6.95 kB
JavaScript
/********************************************************************************************
* Copyright (C) 2025 Acoustic, L.P. All rights reserved.
*
* NOTICE: This file contains material that is confidential and proprietary to
* Acoustic, L.P. and/or other developers. No license is granted under any intellectual or
* industrial property rights of Acoustic, L.P. except as may be provided in an agreement with
* Acoustic, L.P. Any unauthorized copying or distribution of content from this file is
* prohibited.
********************************************************************************************/
const prettier = require("prettier");
const fs = require("fs");
const path = require("path");
const javaPaserPlugin = require("prettier-plugin-java");
const { XMLParser, XMLBuilder } = require("fast-xml-parser");
const { exit } = require("process");
const { isValid } = require('./util');
const directoryPath = path.join(__dirname, "..", "..", "..");
console.log("Run javaParser.js");
if (!isValid(`${directoryPath}/android`)) {
console.log("Directory not valid:")
console.log(`${directoryPath}/android`)
exit(0);
}
function readFile(path) {
let data = "";
if (fs.existsSync(path)) {
try {
data = fs.readFileSync(path, "utf8");
console.log("Read: " + path);
} catch (err) {
console.log("Error reading: " + path);
console.error(err);
}
} else {
console.log("File not found: " + path);
}
return data;
}
const buildGradlePath = `${directoryPath}/android/app/build.gradle`;
console.log("Read build.gradle to get applicationId");
const buildGradleFile = readFile(buildGradlePath)
const regex = /applicationId.*/g;
const foundIt = buildGradleFile.match(regex);
let packageName = null
if (foundIt != null && foundIt[0] != null) {
const singleQuote = foundIt[0].split("'");
const doubleQuote = foundIt[0].split('"');
if (singleQuote != null && singleQuote.length >= 2) {
packageName = singleQuote[1];
} else if (doubleQuote != null && doubleQuote.length >= 2) {
packageName = doubleQuote[1];
}
}
if (packageName == null) {
const xmlFilePath = `${directoryPath}/android/app/src/main/AndroidManifest.xml`;
console.log("Did not find it in " + buildGradlePath + ". I will look in " + xmlFilePath);
const manifestFile = readFile(xmlFilePath)
const options = {
ignoreAttributes: false,
format: true,
preserveOrder: false,
};
const parser = new XMLParser(options);
const jsonObj = parser.parse(manifestFile);
packageName = jsonObj["manifest"]["@_package"];
}
console.log("Found the following applicationId:" + packageName);
if (packageName == null) {
console.log("applicationId not found:")
exit(0);
}
const upperJavaPath = packageName.replace(/\./g, "/");
const mainActivityPathBase = `${directoryPath}/android/app/src/main/java/${upperJavaPath}/MainActivity.`;
const mainActivityPathJava = `${mainActivityPathBase}java`;
const mainActivityPathKotlin = `${mainActivityPathBase}kt`;
const useJava = fs.existsSync(mainActivityPathJava)
const mainActivityPath = useJava ? mainActivityPathJava : mainActivityPathKotlin;
const mainActivityFile = readFile(mainActivityPath);
const semiColonCode = useJava ? ";" : "";
const upperCode = `package ${packageName}${semiColonCode}`;
const importCode1 = `${upperCode}\nimport android.view.MotionEvent${semiColonCode}`;
const importCode2 = `${upperCode}\nimport com.acoustic.connect.android.connectmod.Connect${semiColonCode}`;
const javaCode1 = `public boolean dispatchTouchEvent(MotionEvent e) {
Connect.INSTANCE.dispatchTouchEvent(this, e);
return super.dispatchTouchEvent(e);
}`;
const javaCode2 = `Connect.INSTANCE.dispatchTouchEvent(this, e);
return super.dispatchTouchEvent(e);`;
const kotlinCode1 = `\noverride fun dispatchTouchEvent(e: MotionEvent?): Boolean {
Connect.dispatchTouchEvent(this, e)
return super.dispatchTouchEvent(e)
}`;
const kotlinCode2 = `Connect.dispatchTouchEvent(this, e)
return super.dispatchTouchEvent(e)`;
const code1 = useJava ? javaCode1 : kotlinCode1;
const code2 = useJava ? javaCode2 : kotlinCode2;
// Determine if we are using Java or Kotlin
const prettierPluginKotlin = require("prettier-plugin-kotlin");
// Determine the parser based on whether the file is Java or Kotlin
const parser = useJava ? "java" : "kotlin";
const plugins = useJava ? [javaPaserPlugin] : [prettierPluginKotlin];
// Format the MainActivity file and setup to update file
var updateMainActivityData = prettier.format(mainActivityFile, {
parser: parser,
plugins: plugins,
tabWidth: 4,
});
let updateMainActivity = false;
console.log("useJava: " + useJava);
console.log("parser: " + parser);
// Look for import
const regExImport1 = new RegExp("import android.view.MotionEvent", "g");
if(!regExImport1.test(updateMainActivityData)){
updateMainActivity = true;
updateMainActivityData = updateMainActivityData.replace(upperCode,importCode1);
}
const regExImport2 = new RegExp("import com.acoustic.connect.android.connectmod.Connect", "g");
if(!regExImport2.test(updateMainActivityData)){
updateMainActivity = true;
updateMainActivityData = updateMainActivityData.replace(upperCode,importCode2);
}
// Look for dispatchTouchEvent method
const regExDispatchTouchEvent = new RegExp(/oolean dispatchTouchEvent/, "g");
if (!regExDispatchTouchEvent.test(updateMainActivityData)) {
updateMainActivity = true;
// Add dispatchTouchEvent method with library call
updateMainActivityData = updateMainActivityData.slice(0, updateMainActivityData.lastIndexOf("}"));
updateMainActivityData = `${updateMainActivityData.substring(0, updateMainActivityData.length)}${code1} }`;
}
// Check if our call has been added in dispatchTouchEvent
const regExConnectDispatchTouchEvent = useJava ? new RegExp(/Connect.INSTANCE.dispatchTouchEvent/, "g") : new RegExp(/Connect.dispatchTouchEvent/, "g");
if (!regExConnectDispatchTouchEvent.test(updateMainActivityData)) {
updateMainActivity = true;
// Add Connect.INSTANCE.dispatchTouchEvent
updateMainActivityData = updateMainActivityData.replace(/return super.dispatchTouchEvent\(e\);/, code2);
}
// Update activity
if (updateMainActivity) {
// // Format the MainActivity file and setup to update file
updateMainActivityData = prettier.format(updateMainActivityData, {
parser: parser,
plugins: plugins,
tabWidth: 4,
useTabs: false,
kotlinPlugin: {
alignMultilineComments: true
}
});
console.log("File to be saved:\n" + updateMainActivityData);
try {
fs.writeFileSync(mainActivityPath, updateMainActivityData);
console.log("Updated:" + mainActivityPath);
} catch (err) {
console.log("Error writing:" + mainActivityPath);
console.error(err);
}
} else {
console.log("Update not needed for:" + mainActivityPath);
}