diff --git a/.gitignore b/.gitignore index c5439f6..f649533 100755 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ __MACOSX .DS_Store +applist.json \ No newline at end of file diff --git a/module/service.sh b/module/service.sh index d264ee6..b073f51 100644 --- a/module/service.sh +++ b/module/service.sh @@ -78,7 +78,7 @@ if [ ! -d "$TS/webroot" ] && [ ! -L "$TS/webroot" ]; then fi # Optimization -OUTPUT_APP="$MODPATH/common/tmp/applist" +OUTPUT_APP="$MODPATH/webui/applist.json" OUTPUT_SKIP="$MODPATH/common/tmp/skiplist" OUTPUT_XPOSED="$MODPATH/common/tmp/xposed" @@ -97,7 +97,7 @@ else fi # Initialize cache files to save app list and skip list -echo "# This file is generated from service.sh to speed up load time" > "$OUTPUT_APP" +echo "[" > "$OUTPUT_APP" echo "# This file is generated from service.sh to speed up load time" > "$OUTPUT_SKIP" # Get list of third party apps and specific system apps, then cache app name @@ -107,16 +107,12 @@ echo "# This file is generated from service.sh to speed up load time" > "$OUTPUT pm list packages -s | grep -E "$SYSTEM_APP" 2>/dev/null || true } | awk -F: '{print $2}' | while read -r PACKAGE; do # Get APK path for the package - APK_PATH=$(pm path "$PACKAGE" 2>/dev/null | grep "base.apk" | awk -F: '{print $2}' | tr -d '\r') - [ -z "$APK_PATH" ] && APK_PATH=$(pm path "$PACKAGE" 2>/dev/null | grep ".apk" | awk -F: '{print $2}' | tr -d '\r') + APK_PATH=$(pm path "$PACKAGE" 2>/dev/null | grep "base.apk" | awk -F: '{print $2}') + [ -z "$APK_PATH" ] && APK_PATH=$(pm path "$PACKAGE" 2>/dev/null | grep ".apk" | awk -F: '{print $2}') - if [ -n "$APK_PATH" ]; then - # Extract app name and save package info - APP_NAME=$(aapt dump badging "$APK_PATH" 2>/dev/null | grep "application-label:" | sed "s/application-label://g; s/'//g") - echo "app-name: $APP_NAME, package-name: $PACKAGE" >> "$OUTPUT_APP" - else - echo "app-name: Unknown App package-name: $PACKAGE" >> "$OUTPUT_APP" - fi + APP_NAME=$(aapt dump badging "$APK_PATH" 2>/dev/null | grep "application-label:" | sed "s/application-label://g; s/'//g") + [ -z "$APP_NAME" ] && APP_NAME="$PACKAGE" + echo " {\"app_name\": \"$APP_NAME\", \"package_name\": \"$PACKAGE\"}," >> "$OUTPUT_APP" # Check if app is Xposed module and add to skip list if not touch "$OUTPUT_XPOSED" @@ -126,3 +122,6 @@ echo "# This file is generated from service.sh to speed up load time" > "$OUTPUT echo "$PACKAGE" >> "$OUTPUT_SKIP" fi done + +sed -i '$ s/,$//' "$OUTPUT_APP" +echo "]" >> "$OUTPUT_APP" diff --git a/module/webui/index.html b/module/webui/index.html index 6a6d58d..704a2ee 100644 --- a/module/webui/index.html +++ b/module/webui/index.html @@ -105,29 +105,29 @@
- - + + +
+ +
+
+ + +

diff --git a/module/webui/scripts/applist.js b/module/webui/scripts/applist.js index 4f693f3..a61b2df 100644 --- a/module/webui/scripts/applist.js +++ b/module/webui/scripts/applist.js @@ -9,6 +9,7 @@ export let modeActive = false; // Fetch and render applist export async function fetchAppList() { try { + // fetch target list let targetList = []; try { const targetFileContent = await execCommand('cat /data/adb/tricky_store/target.txt'); @@ -19,56 +20,46 @@ export async function fetchAppList() { console.error("Failed to read target.txt file:", error); } + // fetch applist let applistMap = {}; - try { - const applistResult = await execCommand(`cat ${basePath}common/tmp/applist`); - applistMap = applistResult - .split("\n") - .reduce((map, line) => { - const match = line.match(/app-name:\s*(.+),\s*package-name:\s*(.+)/); - if (match) { - const appName = match[1].trim(); - const packageName = match[2].trim(); - map[packageName] = appName; - } - return map; - }, {}); - console.log("Applist loaded successfully."); - } catch (error) { - console.warn("Applist file not found or could not be loaded. Skipping applist lookup."); - } + const response = await fetch('applist.json'); + const appList = await response.json(); + const appNameMap = appList.reduce((map, app) => { + map[app.package_name] = app.app_name; + return map; + }, {}); - const result = await execCommand(` - pm list packages -3 | awk -F: '{print $2}' - [ -f "/data/adb/tricky_store/system_app" ] && SYSTEM_APP=$(cat "/data/adb/tricky_store/system_app" | tr '\n' '|' | sed 's/|*$//') || SYSTEM_APP="" - pm list packages -s | awk -F: '{print $2}' | grep -Ex "$SYSTEM_APP" 2>/dev/null || true - `); - const appEntries = result - .split("\n") - .map(line => { - const packageName = line.trim(); - const appName = applistMap[packageName] || null; - return { appName, packageName }; - }) - .filter(entry => entry.packageName); - for (const entry of appEntries) { - if (!entry.appName) { - try { - const apkPath = await execCommand(` - base_apk=$(pm path ${entry.packageName} | grep "base.apk" | awk -F: '{print $2}' | tr -d '\\r') - [ -n "$base_apk" ] || base_apk=$(pm path ${entry.packageName} | grep ".apk" | awk -F: '{print $2}' | tr -d '\\r') - echo "$base_apk" - `); - if (apkPath) { - const appName = await execCommand(`${basePath}common/aapt dump badging ${apkPath.trim()} 2>/dev/null | grep "application-label:" | sed "s/application-label://; s/'//g"`); - entry.appName = appName.trim() || "Unknown App"; - } else { - entry.appName = "Unknown App"; - } - } catch (error) { - entry.appName = "Unknown App"; + // Get installed packages first + let appEntries = [], installedPackages = []; + try { + installedPackages = await execCommand(` + pm list packages -3 | awk -F: '{print $2}' + [ -s "/data/adb/tricky_store/system_app" ] && SYSTEM_APP=$(cat "/data/adb/tricky_store/system_app" | tr '\n' '|' | sed 's/|*$//') || SYSTEM_APP="" + [ -z "$SYSTEM_APP" ] || pm list packages -s | awk -F: '{print $2}' | grep -Ex "$SYSTEM_APP" 2>/dev/null || true + `) + installedPackages = installedPackages.split("\n").map(line => line.trim()).filter(Boolean); + appEntries = await Promise.all(installedPackages.map(async packageName => { + if (appNameMap[packageName]) { + return { + appName: appNameMap[packageName], + packageName + }; } - } + const appName = await execCommand(` + base_apk=$(pm path ${packageName} | grep "base.apk" | awk -F: '{print $2}') + [ -n "$base_apk" ] || base_apk=$(pm path ${packageName} | grep ".apk" | awk -F: '{print $2}') + ${basePath}common/aapt dump badging $base_apk 2>/dev/null | grep "application-label:" | sed "s/application-label://; s/'//g" + `); + return { + appName: appName.trim() || packageName, + packageName + }; + })); + } catch (error) { + appEntries = appList.map(app => ({ + appName: app.app_name, + packageName: app.package_name + })); } // Sort @@ -108,7 +99,12 @@ export async function fetchAppList() { } const nameElement = appElement.querySelector(".name"); - nameElement.innerHTML = `${appName || "Unknown App"}
${packageName}`; + nameElement.innerHTML = ` +
+
${appName}
+
${packageName}
+
+ `; const checkbox = appElement.querySelector(".checkbox"); checkbox.checked = targetList.includes(packageName); appListContainer.appendChild(appElement);