Support ! and ? mode in WebUI

- Long press to open mode menu
- Show toast on error log

#7
This commit is contained in:
KOWX712
2024-12-29 02:38:47 +08:00
parent 940d809ac5
commit 77a6e06631
7 changed files with 289 additions and 12 deletions

View File

@@ -1,6 +1,7 @@
import { basePath, execCommand, floatingBtn, appsWithExclamation, appsWithQuestion } from './main.js';
import { basePath, execCommand, floatingBtn, appsWithExclamation, appsWithQuestion, toast } from './main.js';
const appTemplate = document.getElementById('app-template').content;
const modeOverlay = document.querySelector('.mode-overlay');
export const appListContainer = document.getElementById('apps-list');
export const updateCard = document.getElementById('update-card');
@@ -13,6 +14,7 @@ export async function fetchAppList() {
targetList = processTargetList(targetFileContent);
console.log("Current target list:", targetList);
} catch (error) {
toast("Failed to read target.txt!");
console.error("Failed to read target.txt file:", error);
}
@@ -35,7 +37,7 @@ export async function fetchAppList() {
console.warn("Applist file not found or could not be loaded. Skipping applist lookup.");
}
const result = await execCommand("pm list packages -3");
const result = await execCommand('pm list packages -3; pm path com.google.android.gms >/dev/null 2>&1 && echo "package:com.google.android.gms"');
const appEntries = result
.split("\n")
.map(line => {
@@ -76,6 +78,26 @@ export async function fetchAppList() {
const appElement = document.importNode(appTemplate, true);
const contentElement = appElement.querySelector(".content");
contentElement.setAttribute("data-package", packageName);
// Set unique names for radio button groups
const radioButtons = appElement.querySelectorAll('input[type="radio"]');
radioButtons.forEach((radio) => {
radio.name = `mode-radio-${packageName}`;
});
// Preselect the radio button based on the package name
const generateRadio = appElement.querySelector('#generate-mode');
const hackRadio = appElement.querySelector('#hack-mode');
const normalRadio = appElement.querySelector('#normal-mode');
if (appsWithExclamation.includes(packageName)) {
generateRadio.checked = true;
} else if (appsWithQuestion.includes(packageName)) {
hackRadio.checked = true;
} else {
normalRadio.checked = true;
}
const nameElement = appElement.querySelector(".name");
nameElement.innerHTML = `<strong>${appName || "Unknown App"}</strong><br>${packageName}`;
const checkbox = appElement.querySelector(".checkbox");
@@ -84,6 +106,7 @@ export async function fetchAppList() {
});
console.log("App list with names and packages rendered successfully.");
} catch (error) {
toast("Failed to fetch app list!");
console.error("Failed to fetch or render app list with names:", error);
}
floatingBtn.style.transform = 'translateY(0)';
@@ -91,6 +114,10 @@ export async function fetchAppList() {
if (appListContainer.firstChild !== updateCard) {
appListContainer.insertBefore(updateCard, appListContainer.firstChild);
}
const checkboxes = appListContainer.querySelectorAll(".checkbox");
setupRadioButtonListeners();
setupCardHoldListener();
updateCheckboxColor();
}
// Function to save app with ! and ? then process target list
@@ -122,4 +149,112 @@ function toggleableCheckbox() {
checkbox.checked = !checkbox.checked;
});
});
}
// Add eventlistener to mode button
function setupRadioButtonListeners() {
const radioButtons = appListContainer.querySelectorAll('input[type="radio"]');
radioButtons.forEach((radioButton) => {
radioButton.addEventListener('change', (event) => {
const card = radioButton.closest(".card");
const packageName = card.querySelector(".content").getAttribute("data-package");
if (radioButton.id === 'generate-mode') {
if (!appsWithExclamation.includes(packageName)) {
appsWithExclamation.push(packageName);
}
const indexInQuestion = appsWithQuestion.indexOf(packageName);
if (indexInQuestion > -1) {
appsWithQuestion.splice(indexInQuestion, 1);
}
} else if (radioButton.id === 'hack-mode') {
if (!appsWithQuestion.includes(packageName)) {
appsWithQuestion.push(packageName);
}
const indexInExclamation = appsWithExclamation.indexOf(packageName);
if (indexInExclamation > -1) {
appsWithExclamation.splice(indexInExclamation, 1);
}
} else if (radioButton.id === 'normal-mode') {
const indexInExclamation = appsWithExclamation.indexOf(packageName);
if (indexInExclamation > -1) {
appsWithExclamation.splice(indexInExclamation, 1);
}
const indexInQuestion = appsWithQuestion.indexOf(packageName);
if (indexInQuestion > -1) {
appsWithQuestion.splice(indexInQuestion, 1);
}
}
updateCheckboxColor();
console.log("Updated appsWithExclamation:", appsWithExclamation);
console.log("Updated appsWithQuestion:", appsWithQuestion);
});
});
}
// Hold to open menu
function setupCardHoldListener() {
let holdTimeout;
function showMode(card) {
const modeElement = card.querySelector(".mode");
if (modeElement) {
modeElement.style.display = "flex";
modeOverlay.style.display = "flex";
setTimeout(() => {
modeElement.classList.add('show');
}, 10);
}
}
function hideAllModes() {
const allModeElements = appListContainer.querySelectorAll(".mode");
allModeElements.forEach((modeElement) => {
modeElement.classList.remove('show');
modeOverlay.style.display = "none";
setTimeout(() => {
modeElement.style.display = "none";
}, 200);
});
}
const cards = appListContainer.querySelectorAll(".card");
cards.forEach((card) => {
card.addEventListener("pointerdown", () => {
const checkbox = card.querySelector(".checkbox");
if (checkbox && checkbox.checked) {
holdTimeout = setTimeout(() => {
showMode(card);
}, 500);
}
});
card.addEventListener("pointerup", () => clearTimeout(holdTimeout));
card.addEventListener("pointercancel", () => clearTimeout(holdTimeout));
});
// Close on click/scroll
document.addEventListener("click", (event) => {
if (!event.target.closest(".mode") || modeOverlay.contains(event.target)) {
hideAllModes();
} else if (event.target.closest(".status-indicator")) {
setTimeout(() => {
hideAllModes();
}, 200);
}
});
window.addEventListener("scroll", hideAllModes);
}
// Function to update card borders color
function updateCheckboxColor() {
const cards = appListContainer.querySelectorAll(".card");
cards.forEach((card) => {
const packageName = card.querySelector(".content").getAttribute("data-package");
const checkbox = card.querySelector(".checkbox");
checkbox.classList.remove("checkbox-checked-generate", "checkbox-checked-hack");
if (appsWithExclamation.includes(packageName)) {
checkbox.classList.add("checkbox-checked-generate");
} else if (appsWithQuestion.includes(packageName)) {
checkbox.classList.add("checkbox-checked-hack");
} else if (checkbox.checked) {
checkbox.classList.remove("checkbox-checked-generate", "checkbox-checked-hack");
}
});
}