Compare commits

14 Commits
v2.3 ... v2.5

Author SHA1 Message Date
KOWX712
e192fcc916 v2.5 2024-11-22 00:23:08 +08:00
KOWX712
7a2c87b365 minor ui change x2 2024-11-22 00:15:51 +08:00
KOWX712
a1f4d8fc72 minor layout change 2024-11-21 23:51:26 +08:00
KOWX712
7f7c124b25 Add more detail x2 2024-11-21 23:24:38 +08:00
KOWX712
90696c5c5d Update update.json 2024-11-21 23:09:01 +08:00
KOWX712
9cbb73bab0 Add more detail
Add more detail in help menu and clarity keybox operation prompt.
2024-11-21 23:04:38 +08:00
KOWX712
d9eb97cb3c fix webui installation skip
Magisk action.sh: On next installation, prompt webui again if rejected.
2024-11-21 23:04:13 +08:00
KOWX712
e848da327b change kb logic 2024-11-20 15:05:37 +08:00
KOWX712
67581ae941 Update .extra 2024-11-20 13:56:15 +08:00
KOWX712
91dea027ce Create .extra 2024-11-20 13:40:27 +08:00
KOWX712
5806ab16d7 v2.4 2024-11-20 00:52:21 +08:00
KOWX712
0736f4ea38 Add app name display
try to display app name in webui
2024-11-20 00:44:28 +08:00
KOWX712
ff8a768a00 Add aapt bianry
prepare for app name feature
2024-11-19 23:26:27 +08:00
KOWX712
af3f8b88c0 Update changelog.md 2024-11-18 22:02:31 +08:00
18 changed files with 228 additions and 196 deletions

1
.extra Normal file

File diff suppressed because one or more lines are too long

View File

@@ -1,15 +1,27 @@
### Tricky Addon: Update Target List ### Tricky Addon: Update Target List
Automated script to update tricky store target.txt A **KSU WebUI** to configure tricky store target.txt
Requirement: Tricky Store module installed Requirement: Tricky Store module installed
Manually add VerifiedBootHash to /data/adb/modules/TA_utl/boot_hash (optional) Manually add VerifiedBootHash to /data/adb/boot_hash (optional)
GitHub release: [Tricky Addon: Update Target List](https://github.com/KOWX712/Tricky-Addon-Update-Target-List/releases/latest) GitHub release: [Tricky Addon: Update Target List](https://github.com/KOWX712/Tricky-Addon-Update-Target-List/releases/latest)
Telegram channel: [KOW's Little World](https://t.me/kowchannel) Telegram channel: [KOW's Little World](https://t.me/kowchannel)
Starting from v2.4, WebUI will take longer time to load due to reading app name from every base.apk. The more apps installed, the longer time it takes to load the WebUI.
## Changelog ## Changelog
### v2.5
- Remove kb prompt on installation, moved into WebUI
- Restore to AOSP keybox during uninstallation
### v2.4
- Added aapt binary for app name display
**KSU WebUI**
- Added app name display
### v2.3 ### v2.3
- Removed curl binary - Removed curl binary
- Moved boot_hash to /data/adb to prevent overwrite - Moved boot_hash to /data/adb to prevent overwrite

View File

@@ -4,7 +4,7 @@
- Recommend to run with MT manager - Recommend to run with MT manager
## Changelog ## Changelog
### v2.1, v2.2, v2.3 ### v2.1, v2.2, v2.3, v2.4, v2.5
- Remain same with v2.0 - Remain same with v2.0
### v2.0 ### v2.0

View File

@@ -1,6 +1,6 @@
#!/bin/sh #!/bin/sh
# Tricky Addon Lite: Update Target List Script v2.3 # Tricky Addon Lite: Update Target List Script v2.5
# GitHub Repository: https://github.com/KOWX712/Tricky-Addon-Update-Target-List/blob/master/lite-script_only/README.md # GitHub Repository: https://github.com/KOWX712/Tricky-Addon-Update-Target-List/blob/master/lite-script_only/README.md
# Telegram channel: https://t.me/kowchannel # Telegram channel: https://t.me/kowchannel

BIN
module/bin/arm64-v8a/aapt Normal file

Binary file not shown.

BIN
module/bin/armeabi-v7a/aapt Normal file

Binary file not shown.

File diff suppressed because one or more lines are too long

View File

@@ -1,19 +0,0 @@
#!/system/bin/sh
if [ -f "/data/adb/apd" ] || [ -f "/data/adb/ksud" ]; then
exit 1
fi
MODPATH=${0%/*}
OUTPUT="$MODPATH/denylist"
# Get Magisk denylist
magisk --denylist ls 2>/dev/null | \
awk -F'|' '{print $1}' | \
grep -v "isolated" | \
sort | uniq > "$OUTPUT"
if [ ! -s "$OUTPUT" ]; then
echo "Failed to retrieve Magisk denylist or no packages found." > "$OUTPUT"
exit 1
fi

View File

@@ -2,6 +2,7 @@
MODPATH=${0%/*} MODPATH=${0%/*}
OUTPUT="$MODPATH/exclude-list" OUTPUT="$MODPATH/exclude-list"
KBOUTPUT="$MODPATH/.extra"
. $MODPATH/util_func.sh . $MODPATH/util_func.sh
@@ -20,5 +21,12 @@ awk -F'"' '{print $4}' >> "$OUTPUT"
if [ ! -s "$OUTPUT" ]; then if [ ! -s "$OUTPUT" ]; then
echo "Error: Failed to fetch data." > "$OUTPUT" echo "Error: Failed to fetch data." > "$OUTPUT"
rm -f "$KBOUTPUT"
exit 1 exit 1
fi
wget --no-check-certificate -qO "$KBOUTPUT" "https://raw.githubusercontent.com/KOWX712/Tricky-Addon-Update-Target-List/master/.extra"
if [ ! -s "$KBOUTPUT" ]; then
rm -f "$KBOUTPUT"
fi fi

View File

@@ -1,9 +1,9 @@
PACKAGE_NAME="io.github.a13e300.ksuwebui" PACKAGE_NAME="io.github.a13e300.ksuwebui"
MODID="set-id" MODID="set-id"
BBPATH="/data/adb/modules/busybox-ndk/system/*/busybox \ BBPATH="/data/adb/modules/busybox-ndk/system/*/busybox \
/data/adb/magisk/busybox \ /data/adb/magisk/busybox \
/data/adb/ksu/bin/busybox \ /data/adb/ksu/bin/busybox \
/data/adb/ap/bin/busybox" /data/adb/ap/bin/busybox"
find_busybox() { find_busybox() {
for path in $BBPATH; do for path in $BBPATH; do

View File

@@ -37,14 +37,6 @@ ui_print "- Creating config directory..."
find_config find_config
migrate_old_boot_hash migrate_old_boot_hash
ui_print "*********************************************"
ui_print "- Do you want to replace tricky store keybox? (AOSP, no strong)"
ui_print " VOL [+]: YES"
ui_print " VOL [-]: NO"
ui_print "*********************************************"
key_check
kb_operation
rm -f "$MODPATH/install_func.sh" rm -f "$MODPATH/install_func.sh"
ui_print "- Installation completed successfully! " ui_print "- Installation completed successfully! "

View File

@@ -2,6 +2,9 @@ initialize() {
if [ -f "$SCRIPT_DIR/UpdateTargetList.sh" ]; then if [ -f "$SCRIPT_DIR/UpdateTargetList.sh" ]; then
rm -f "$SCRIPT_DIR/UpdateTargetList.sh" rm -f "$SCRIPT_DIR/UpdateTargetList.sh"
fi fi
if [ -f "$CONFIG_DIR/skipwebui" ]; then
rm -f "$CONFIG_DIR/skipwebui"
fi
cp "$MODPATH/module.prop" "$COMPATH/module.prop.orig" cp "$MODPATH/module.prop" "$COMPATH/module.prop.orig"
mv "$COMPATH/UpdateTargetList.sh" "$SCRIPT_DIR/UpdateTargetList.sh" mv "$COMPATH/UpdateTargetList.sh" "$SCRIPT_DIR/UpdateTargetList.sh"
@@ -13,10 +16,14 @@ initialize() {
ui_print "! Failed to set id" ui_print "! Failed to set id"
abort abort
} }
mkdir -p "$MODPATH/system/bin"
mv "$MODPATH/bin/$(getprop ro.product.cpu.abi)/aapt" "$COMPATH/aapt"
rm -rf "$MODPATH/bin"
set_perm $COMPATH/aapt 0 2000 0755
set_perm $SCRIPT_DIR/UpdateTargetList.sh 0 2000 0755 set_perm $SCRIPT_DIR/UpdateTargetList.sh 0 2000 0755
set_perm $COMPATH/get_denylist.sh 0 2000 0755 set_perm $COMPATH/get_extra.sh 0 2000 0755
set_perm $COMPATH/get_exclude-list.sh 0 2000 0755
set_perm $COMPATH/get_WebUI.sh 0 2000 0755 set_perm $COMPATH/get_WebUI.sh 0 2000 0755
if [ "$ACTION" = "false" ]; then if [ "$ACTION" = "false" ]; then
@@ -86,46 +93,4 @@ migrate_old_boot_hash() {
echo -e "\n$hash_value" >> "/data/adb/boot_hash" echo -e "\n$hash_value" >> "/data/adb/boot_hash"
fi fi
fi fi
}
key_check() {
while true; do
key_check=$(/system/bin/getevent -qlc 1)
key_event=$(echo "$key_check" | awk '{ print $3 }' | grep 'KEY_')
key_status=$(echo "$key_check" | awk '{ print $4 }')
if [[ "$key_event" == *"KEY_"* && "$key_status" == "DOWN" ]]; then
keycheck="$key_event"
break
fi
done
while true; do
key_check=$(/system/bin/getevent -qlc 1)
key_event=$(echo "$key_check" | awk '{ print $3 }' | grep 'KEY_')
key_status=$(echo "$key_check" | awk '{ print $4 }')
if [[ "$key_event" == *"KEY_"* && "$key_status" == "UP" ]]; then
break
fi
done
}
kb_operation() {
if [[ "$keycheck" == "KEY_VOLUMEUP" ]]; then
ui_print "- Backing up original keybox..."
ui_print "- Replacing keybox..."
ui_print "*********************************************"
if [ -f "$ORG_DIR/common/origkeybox" ]; then
mv "$ORG_DIR/common/origkeybox" "$COMPATH/origkeybox"
else
mv "$SCRIPT_DIR/keybox.xml" "$COMPATH/origkeybox"
fi
mv "$kb" "$SCRIPT_DIR/keybox.xml"
else
if [ -f "$ORG_DIR/common/origkeybox" ]; then
mv "$ORG_DIR/common/origkeybox" "$COMPATH/origkeybox"
fi
rm -f "$kb"
fi
} }

View File

@@ -1,7 +1,7 @@
id=TA_utl id=TA_utl
name=Tricky Addon - Update Target List name=Tricky Addon - Update Target List
version=v2.3 version=v2.5
versionCode=230 versionCode=250
author=KOWX712 author=KOWX712
description=A WebUI to conifgure tricky store target.txt description=A WebUI to conifgure tricky store target.txt
updateJson=https://raw.githubusercontent.com/KOWX712/Tricky-Addon-Update-Target-List/master/update.json updateJson=https://raw.githubusercontent.com/KOWX712/Tricky-Addon-Update-Target-List/master/update.json

View File

@@ -6,11 +6,8 @@ if [ -f "/storage/emulated/0/stop-tspa-auto-target" ]; then
rm -f "/storage/emulated/0/stop-tspa-auto-target" rm -f "/storage/emulated/0/stop-tspa-auto-target"
fi fi
# Remove residue and restore original keybox. # Remove residue and restore aosp keybox.
rm -rf "$SCRIPT_DIR/target_list_config" rm -rf "$SCRIPT_DIR/target_list_config"
rm -f "$SCRIPT_DIR/UpdateTargetList.sh" rm -f "$SCRIPT_DIR/UpdateTargetList.sh"
rm -f "/data/adb/boot_hash" rm -f "/data/adb/boot_hash"
if [ -f "$MODPATH/common/origkeybox" ]; then xxd -r -p "$MODPATH/common/.default" | base64 -d > "$SCRIPT_DIR/keybox.xml"
rm -f "$SCRIPT_DIR/keybox.xml"
mv "$MODPATH/common/origkeybox" "$SCRIPT_DIR/keybox.xml"
fi

View File

@@ -51,7 +51,7 @@
<li>Deselect Unnecessary <li>Deselect Unnecessary
<ul> <ul>
<li>Unnecessary category: Xposed module, root manager, root-related apps, and general apps <li>Unnecessary category: Xposed module, root manager, root-related apps, and general apps
that never check bootloader status.</li> that never check bootloader status. This option requrie Internet connection.</li>
<ul> <ul>
<li>Contribute to <a <li>Contribute to <a
href="https://raw.githubusercontent.com/KOWX712/Tricky-Addon-Update-Target-List/master/more-excldue.json" href="https://raw.githubusercontent.com/KOWX712/Tricky-Addon-Update-Target-List/master/more-excldue.json"
@@ -64,6 +64,15 @@
<li><br></li> <li><br></li>
</ul> </ul>
</li> </li>
<li>Set AOSP & Valid Keybox
<ul>
<li>Replace tricky store keybox.xml<br><strong>AOSP keybox:</strong> Device
Integrity.<br><strong>Valid keybox:</strong> Strong Integrity, fallback to Basic
Integrity if revoked.<br>AOSP keybox will be replaced if there's no more valid keybox.
Valid keybox option require Internet connection.</li>
<li><br></li>
</ul>
</li>
</ul> </ul>
</div> </div>
</div> </div>
@@ -85,7 +94,9 @@
<li id="select-all">Select All</li> <li id="select-all">Select All</li>
<li id="deselect-all">Deselect All</li> <li id="deselect-all">Deselect All</li>
<li id="select-denylist">Select From DenyList</li> <li id="select-denylist">Select From DenyList</li>
<li id="deselect-xposed">Deselect Unnecessary</li> <li id="deselect-unnecessary">Deselect Unnecessary</li>
<li id="aospkb">Set AOSP Keybox</li>
<li id="extrakb">Set Valid Keybox</li>
</ul> </ul>
</div> </div>
</div> </div>
@@ -96,7 +107,7 @@
</div> </div>
<template id="app-template"> <template id="app-template">
<div class="card" onclick="toggleCheckbox(event)"> <div class="card" onclick="toggleCheckbox(event)">
<div class="content"> <div class="content" data-package="">
<p class="name"></p> <p class="name"></p>
<input type="checkbox" class="checkbox" checked> <input type="checkbox" class="checkbox" checked>
</div> </div>

View File

@@ -56,32 +56,49 @@ function isExcluded(appName) {
return excludeList.some(excludeItem => appName.includes(excludeItem)); return excludeList.some(excludeItem => appName.includes(excludeItem));
} }
// Function to fetch, sort, and render the app list // Function to fetch, sort, and render the app list with app names
async function fetchAppList() { async function fetchAppList() {
try { try {
await readExcludeFile(); await readExcludeFile();
const result = await execCommand("pm list packages -3 </dev/null 2>&1 | cat"); const result = await execCommand(`
const packageList = result.split("\n").map(line => line.replace("package:", "").trim()).filter(Boolean); pm list packages -3 | while read -r line; do
const sortedApps = packageList.sort((a, b) => { PACKAGE=$(echo "$line" | awk -F: '{print $2}')
const aInExclude = isExcluded(a); APK_PATH=$(pm path "$PACKAGE" | grep "base.apk" | awk -F: '{print $2}' | tr -d '\\r')
const bInExclude = isExcluded(b); if [ -n "$APK_PATH" ]; then
return aInExclude === bInExclude ? a.localeCompare(b) : aInExclude ? 1 : -1; APP_NAME=$( ${basePath}aapt dump badging "$APK_PATH" 2>/dev/null | grep "application-label:" | sed "s/application-label://; s/'//g" )
echo "$APP_NAME|$PACKAGE"
else
echo "Unknown App|$PACKAGE"
fi
done
`);
const appEntries = result.split("\n").map(line => {
const [appName, packageName] = line.split("|").map(item => item.trim());
return { appName, packageName };
}).filter(entry => entry.packageName); // Remove invalid entries
const sortedApps = appEntries.sort((a, b) => {
const aInExclude = isExcluded(a.packageName);
const bInExclude = isExcluded(b.packageName);
return aInExclude === bInExclude ? a.appName.localeCompare(b.appName) : aInExclude ? 1 : -1;
}); });
appListContainer.innerHTML = ""; appListContainer.innerHTML = ""; // Clear the container before rendering
sortedApps.forEach(appName => { sortedApps.forEach(({ appName, packageName }) => {
const appElement = document.importNode(appTemplate, true); const appElement = document.importNode(appTemplate, true);
appElement.querySelector(".name").textContent = appName; const contentElement = appElement.querySelector(".content");
contentElement.setAttribute("data-package", packageName);
const nameElement = appElement.querySelector(".name");
nameElement.innerHTML = `<strong>${appName || "Unknown App"}</strong><br>${packageName}`;
const checkbox = appElement.querySelector(".checkbox"); const checkbox = appElement.querySelector(".checkbox");
checkbox.checked = !isExcluded(appName); checkbox.checked = !isExcluded(packageName);
appListContainer.appendChild(appElement); appListContainer.appendChild(appElement);
}); });
console.log("App list fetched, sorted, and rendered successfully."); console.log("App list with names and packages rendered successfully.");
} catch (error) { } catch (error) {
console.error("Failed to fetch or render app list:", error); console.error("Failed to fetch or render app list with names:", error);
} }
floatingBtn.style.transform = 'translateY(-100px)';
}
floatingBtn.style.transform = "translateY(-100px)";
}
// Function to refresh app list // Function to refresh app list
async function refreshAppList() { async function refreshAppList() {
@@ -96,80 +113,13 @@ async function refreshAppList() {
await new Promise(resolve => setTimeout(resolve, 500)); await new Promise(resolve => setTimeout(resolve, 500));
window.scrollTo(0, 0); window.scrollTo(0, 0);
if (noConnection.style.display === "flex") { if (noConnection.style.display === "flex") {
await runXposedScript(); await runExtraScript();
} }
await fetchAppList();[] await fetchAppList();[]
loadingIndicator.style.display = 'none'; loadingIndicator.style.display = 'none';
isRefreshing = false; isRefreshing = false;
} }
// Function to run the Xposed script
async function runXposedScript() {
try {
const scriptPath = `${basePath}get_exclude-list.sh`;
await execCommand(scriptPath);
console.log("Xposed script executed successfully.");
noConnection.style.display = "none";
} catch (error) {
console.error("Failed to execute Xposed script:", error);
showPrompt("Please check your Internet connection", false);
noConnection.style.display = "flex";
}
}
// Function to read the xposed list and uncheck corresponding apps
async function deselectXposedApps() {
try {
const result = await execCommand(`cat ${basePath}exclude-list`);
const xposedApps = result.split("\n").map(app => app.trim()).filter(Boolean);
const apps = document.querySelectorAll(".card");
apps.forEach(app => {
const appName = app.querySelector(".name").textContent.trim();
const checkbox = app.querySelector(".checkbox");
if (xposedApps.includes(appName)) {
checkbox.checked = false; // Uncheck if found in exclude-list
}
});
console.log("Xposed apps deselected successfully.");
} catch (error) {
console.error("Failed to deselect Xposed apps:", error);
}
}
// Function to run the Denylist script
async function runDenylistScript() {
try {
const denylistScriptPath = `${basePath}get_denylist.sh`;
await execCommand(denylistScriptPath);
console.log('Denylist element displayed successfully.');
selectDenylistElement.style.display = "flex";
} catch (error) {
console.error("Failed to execute Denylist script:", error);
}
}
// Function to read the denylist and check corresponding apps
async function selectDenylistApps() {
try {
const result = await execCommand(`cat ${basePath}denylist`);
const denylistApps = result.split("\n")
.map(app => app.trim())
.filter(Boolean);
const apps = document.querySelectorAll(".card");
apps.forEach(app => {
const appName = app.querySelector(".name").textContent.trim();
const checkbox = app.querySelector(".checkbox");
if (denylistApps.includes(appName)) {
checkbox.checked = true; // Select the app if found in denylist
}
});
console.log("Denylist apps selected successfully.");
} catch (error) {
console.error("Failed to select Denylist apps:", error);
}
}
// Function to select all visible apps // Function to select all visible apps
function selectAllApps() { function selectAllApps() {
document.querySelectorAll(".card").forEach(card => { document.querySelectorAll(".card").forEach(card => {
@@ -188,6 +138,120 @@ function deselectAllApps() {
}); });
} }
// Function to run the extra script
async function runExtraScript() {
try {
const scriptPath = `${basePath}get_extra.sh`;
await execCommand(scriptPath);
console.log("Extra script executed successfully.");
noConnection.style.display = "none";
} catch (error) {
console.error("Failed to execute Extra script:", error);
showPrompt("Please check your Internet connection", false);
noConnection.style.display = "flex";
}
}
// Function to read the exclude list and uncheck corresponding apps
async function deselectUnnecessaryApps() {
try {
const result = await execCommand(`cat ${basePath}exclude-list`);
const UnnecessaryApps = result.split("\n").map(app => app.trim()).filter(Boolean);
const apps = document.querySelectorAll(".card");
apps.forEach(app => {
const contentElement = app.querySelector(".content");
const packageName = contentElement.getAttribute("data-package");
const checkbox = app.querySelector(".checkbox");
if (UnnecessaryApps.includes(packageName)) {
checkbox.checked = false; // Uncheck if found in more-exclude list
}
});
console.log("unnecessary apps deselected successfully.");
} catch (error) {
console.error("Failed to deselect unnecessary apps:", error);
}
}
// Function to check if Magisk
async function checkMagisk() {
try {
const hasDenylistCondition = await execCommand(`
if [ ! -f "/data/adb/apd" ] && [ ! -f "/data/adb/ksud" ]; then
echo "OK"
else
echo ""
fi
`);
if (hasDenylistCondition.trim() === "OK") {
console.log("Denylist conditions met, displaying element.");
selectDenylistElement.style.display = "flex";
} else {
console.log("ksud or apd detected, leaving denylist element hidden.");
}
} catch (error) {
console.error("Error while checking denylist conditions:", error);
}
}
// Function to read the denylist and check corresponding apps
async function selectDenylistApps() {
try {
const result = await execCommand(`
magisk --denylist ls 2>/dev/null | \
awk -F'|' '{print $1}' | \
grep -v "isolated" | \
sort | uniq
`);
const denylistApps = result.split("\n").map(app => app.trim()).filter(Boolean);
const apps = document.querySelectorAll(".card");
await deselectAllApps();
apps.forEach(app => {
const contentElement = app.querySelector(".content");
const packageName = contentElement.getAttribute("data-package");
const checkbox = app.querySelector(".checkbox");
if (denylistApps.includes(packageName)) {
checkbox.checked = true; // Select the app if found in denylist
}
});
console.log("Denylist apps selected successfully.");
} catch (error) {
console.error("Failed to select Denylist apps:", error);
}
}
// Function to replace aosp kb
async function aospkb() {
try {
const sourcePath = `${basePath}.default`;
const destinationPath = "/data/adb/tricky_store/keybox.xml";
await execCommand(`xxd -r -p ${sourcePath} | base64 -d > ${destinationPath}`);
console.log("AOSP keybox copied successfully.");
showPrompt("AOSP keybox set successfully.");
} catch (error) {
console.error("Failed to copy AOSP keybox:", error);
showPrompt("Failed to update keybox.", false);
}
}
// Function to replace valid kb
async function extrakb() {
const sourcePath = `${basePath}.extra`;
const destinationPath = "/data/adb/tricky_store/keybox.xml";
try {
const fileExists = await execCommand(`[ -f ${sourcePath} ] && echo "exists"`);
if (fileExists.trim() !== "exists") {
throw new Error(".extra file not found");
}
await execCommand(`xxd -r -p ${sourcePath} | base64 -d > ${destinationPath}`);
console.log("Valid keybox copied successfully.");
showPrompt("Valid keybox set successfully.");
} catch (error) {
console.error("Failed to copy valid keybox:", error);
await aospkb();
showPrompt("No valid keybox found, replaced with AOSP keybox.", false);
}
}
// Function to show the prompt with a success or error message // Function to show the prompt with a success or error message
function showPrompt(message, isSuccess = true) { function showPrompt(message, isSuccess = true) {
const prompt = document.getElementById('prompt'); const prompt = document.getElementById('prompt');
@@ -236,7 +300,7 @@ function setupMenuToggle() {
} }
}); });
const closeMenuItems = ['refresh', 'select-all', 'deselect-all', 'select-denylist', 'deselect-xposed']; const closeMenuItems = ['refresh', 'select-all', 'deselect-all', 'select-denylist', 'deselect-unnecessary', 'aospkb', 'extrakb'];
closeMenuItems.forEach(id => { closeMenuItems.forEach(id => {
const item = document.getElementById(id); const item = document.getElementById(id);
if (item) { if (item) {
@@ -312,26 +376,25 @@ clearBtn.addEventListener("click", () => {
document.getElementById("save").addEventListener("click", async () => { document.getElementById("save").addEventListener("click", async () => {
await readExcludeFile(); await readExcludeFile();
const deselectedApps = Array.from(appListContainer.querySelectorAll(".checkbox:not(:checked)")) const deselectedApps = Array.from(appListContainer.querySelectorAll(".checkbox:not(:checked)"))
.map(checkbox => checkbox.closest(".card").querySelector(".name").textContent); .map(checkbox => checkbox.closest(".card").querySelector(".content").getAttribute("data-package"));
const selectedApps = Array.from(appListContainer.querySelectorAll(".checkbox:checked")) const selectedApps = Array.from(appListContainer.querySelectorAll(".checkbox:checked"))
.map(checkbox => checkbox.closest(".card").querySelector(".name").textContent); .map(checkbox => checkbox.closest(".card").querySelector(".content").getAttribute("data-package"));
// Add deselected apps to EXCLUDE list
for (const app of deselectedApps) { for (const packageName of deselectedApps) {
if (!excludeList.includes(app)) { if (!excludeList.includes(packageName)) {
excludeList.push(app); excludeList.push(packageName);
console.log("Added to EXCLUDE list:", app); console.log("Added to EXCLUDE list:", packageName);
} else { } else {
console.log("App already in EXCLUDE file, skipping:", app); console.log("Package already in EXCLUDE file, skipping:", packageName);
} }
} }
// Remove selected apps from EXCLUDE list
if (selectedApps.length > 0) { if (selectedApps.length > 0) {
selectedApps.forEach(app => { selectedApps.forEach(packageName => {
excludeList = excludeList.filter(excludedApp => excludedApp !== app); excludeList = excludeList.filter(excludedPackage => excludedPackage !== packageName);
console.log("Removed from EXCLUDE list:", app); console.log("Removed from EXCLUDE list:", packageName);
}); });
} }
try { try {
// Save the EXCLUDE file // Save the EXCLUDE file
const updatedExcludeContent = excludeList.join("\n"); const updatedExcludeContent = excludeList.join("\n");
@@ -361,10 +424,12 @@ document.addEventListener('DOMContentLoaded', async () => {
document.getElementById("select-all").addEventListener("click", selectAllApps); document.getElementById("select-all").addEventListener("click", selectAllApps);
document.getElementById("deselect-all").addEventListener("click", deselectAllApps); document.getElementById("deselect-all").addEventListener("click", deselectAllApps);
document.getElementById("select-denylist").addEventListener("click", selectDenylistApps); document.getElementById("select-denylist").addEventListener("click", selectDenylistApps);
document.getElementById("deselect-xposed").addEventListener("click", deselectXposedApps); document.getElementById("deselect-unnecessary").addEventListener("click", deselectUnnecessaryApps);
document.getElementById("aospkb").addEventListener("click", aospkb);
document.getElementById("extrakb").addEventListener("click", extrakb);
await fetchAppList(); await fetchAppList();
runDenylistScript(); checkMagisk();
runXposedScript(); runExtraScript();
loadingIndicator.style.display = "none"; loadingIndicator.style.display = "none";
}); });

View File

@@ -75,7 +75,7 @@ body {
.help-menu { .help-menu {
position: relative; position: relative;
width: 75vw; width: 75vw;
max-width: 600px; max-width: 800px;
background-color: white; background-color: white;
padding: 0 10px; padding: 0 10px;
border-radius: 15px; border-radius: 15px;
@@ -110,7 +110,7 @@ body {
.help-content ul li { .help-content ul li {
font-weight: bold; font-weight: bold;
font-size: 17px; font-size: 18px;
} }
.help-content ul ul li { .help-content ul ul li {

View File

@@ -1,6 +1,6 @@
{ {
"versionCode": 230, "versionCode": 250,
"version": "v2.3", "version": "v2.5",
"zipUrl": "https://github.com/KOWX712/Tricky-Addon-Update-Target-List/releases/download/v2.3/TrickyAddonModule-v2.3.zip", "zipUrl": "https://github.com/KOWX712/Tricky-Addon-Update-Target-List/releases/download/v2.5/TrickyAddonModule-v2.5.zip",
"changelog": "https://raw.githubusercontent.com/KOWX712/Tricky-Addon-Update-Target-List/refs/heads/master/changelog.md" "changelog": "https://raw.githubusercontent.com/KOWX712/Tricky-Addon-Update-Target-List/master/changelog.md"
} }