You've already forked Tricky-Addon-Update-Target-List
mirror of
https://github.com/KOWX712/Tricky-Addon-Update-Target-List.git
synced 2025-09-06 06:37:09 +00:00
Support ! and ? mode in WebUI
- Long press to open mode menu - Show toast on error log #7
This commit is contained in:
@@ -90,10 +90,37 @@
|
|||||||
<p id="update-available" data-i18n="update_banner.update_available"></p>
|
<p id="update-available" data-i18n="update_banner.update_available"></p>
|
||||||
<p id="redirect-to-release" data-i18n="update_banner.redirect_to_release"></p>
|
<p id="redirect-to-release" data-i18n="update_banner.redirect_to_release"></p>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="mode-overlay"></div>
|
||||||
<template id="app-template">
|
<template id="app-template">
|
||||||
<div class="card-box">
|
<div class="card-box">
|
||||||
<div class="card" id="card">
|
<div class="card" id="card">
|
||||||
<div class="content" data-package="">
|
<div class="content" data-package="">
|
||||||
|
<div class="mode">
|
||||||
|
<label class="mode-switch" id="normal">
|
||||||
|
<input type="radio" class="mode-input" id="normal-mode">
|
||||||
|
<i class="mode-icon">
|
||||||
|
<div class="status-indicator" id="normal-indicator">
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" height="30px" viewBox="0 -960 960 960" width="30px" fill="#ffffff"><path d="M480-480Zm0 280q-116 0-198-82t-82-198q0-116 82-198t198-82q116 0 198 82t82 198q0 116-82 198t-198 82Zm0-80q83 0 141.5-58.5T680-480q0-83-58.5-141.5T480-680q-83 0-141.5 58.5T280-480q0 83 58.5 141.5T480-280Z"/></svg>
|
||||||
|
</div>
|
||||||
|
</i>
|
||||||
|
</label>
|
||||||
|
<label class="mode-switch" id="hack">
|
||||||
|
<input type="radio" class="mode-input" id="hack-mode">
|
||||||
|
<i class="mode-icon">
|
||||||
|
<div class="status-indicator" id="hack-indicator">
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" height="19px" viewBox="0 -960 960 960" width="19px" fill="#ffffff"><path d="M424-320q0-81 14.5-116.5T500-514q41-36 62.5-62.5T584-637q0-41-27.5-68T480-732q-51 0-77.5 31T365-638l-103-44q21-64 77-111t141-47q105 0 161.5 58.5T698-641q0 50-21.5 85.5T609-475q-49 47-59.5 71.5T539-320H424Zm56 240q-33 0-56.5-23.5T400-160q0-33 23.5-56.5T480-240q33 0 56.5 23.5T560-160q0 33-23.5 56.5T480-80Z"/></svg>
|
||||||
|
</div>
|
||||||
|
</i>
|
||||||
|
</label>
|
||||||
|
<label class="mode-switch" id="generate">
|
||||||
|
<input type="radio" class="mode-input" id="generate-mode">
|
||||||
|
<i class="mode-icon">
|
||||||
|
<div class="status-indicator" id="generate-indicator">
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" height="18px" viewBox="0 -960 960 960" width="18px" fill="#ffffff"><path d="M480-120q-33 0-56.5-23.5T400-200q0-33 23.5-56.5T480-280q33 0 56.5 23.5T560-200q0 33-23.5 56.5T480-120Zm-80-240v-480h160v480H400Z"/></svg>
|
||||||
|
</div>
|
||||||
|
</i>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
<p class="name"></p>
|
<p class="name"></p>
|
||||||
<div class="checkbox-wrapper">
|
<div class="checkbox-wrapper">
|
||||||
<input type="checkbox" class="checkbox" id="checkbox1" disabled />
|
<input type="checkbox" class="checkbox" id="checkbox1" disabled />
|
||||||
|
|||||||
@@ -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 appTemplate = document.getElementById('app-template').content;
|
||||||
|
const modeOverlay = document.querySelector('.mode-overlay');
|
||||||
export const appListContainer = document.getElementById('apps-list');
|
export const appListContainer = document.getElementById('apps-list');
|
||||||
export const updateCard = document.getElementById('update-card');
|
export const updateCard = document.getElementById('update-card');
|
||||||
|
|
||||||
@@ -13,6 +14,7 @@ export async function fetchAppList() {
|
|||||||
targetList = processTargetList(targetFileContent);
|
targetList = processTargetList(targetFileContent);
|
||||||
console.log("Current target list:", targetList);
|
console.log("Current target list:", targetList);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
toast("Failed to read target.txt!");
|
||||||
console.error("Failed to read target.txt file:", error);
|
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.");
|
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
|
const appEntries = result
|
||||||
.split("\n")
|
.split("\n")
|
||||||
.map(line => {
|
.map(line => {
|
||||||
@@ -76,6 +78,26 @@ export async function fetchAppList() {
|
|||||||
const appElement = document.importNode(appTemplate, true);
|
const appElement = document.importNode(appTemplate, true);
|
||||||
const contentElement = appElement.querySelector(".content");
|
const contentElement = appElement.querySelector(".content");
|
||||||
contentElement.setAttribute("data-package", packageName);
|
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");
|
const nameElement = appElement.querySelector(".name");
|
||||||
nameElement.innerHTML = `<strong>${appName || "Unknown App"}</strong><br>${packageName}`;
|
nameElement.innerHTML = `<strong>${appName || "Unknown App"}</strong><br>${packageName}`;
|
||||||
const checkbox = appElement.querySelector(".checkbox");
|
const checkbox = appElement.querySelector(".checkbox");
|
||||||
@@ -84,6 +106,7 @@ export async function fetchAppList() {
|
|||||||
});
|
});
|
||||||
console.log("App list with names and packages rendered successfully.");
|
console.log("App list with names and packages rendered successfully.");
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
toast("Failed to fetch app list!");
|
||||||
console.error("Failed to fetch or render app list with names:", error);
|
console.error("Failed to fetch or render app list with names:", error);
|
||||||
}
|
}
|
||||||
floatingBtn.style.transform = 'translateY(0)';
|
floatingBtn.style.transform = 'translateY(0)';
|
||||||
@@ -91,6 +114,10 @@ export async function fetchAppList() {
|
|||||||
if (appListContainer.firstChild !== updateCard) {
|
if (appListContainer.firstChild !== updateCard) {
|
||||||
appListContainer.insertBefore(updateCard, appListContainer.firstChild);
|
appListContainer.insertBefore(updateCard, appListContainer.firstChild);
|
||||||
}
|
}
|
||||||
|
const checkboxes = appListContainer.querySelectorAll(".checkbox");
|
||||||
|
setupRadioButtonListeners();
|
||||||
|
setupCardHoldListener();
|
||||||
|
updateCheckboxColor();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Function to save app with ! and ? then process target list
|
// Function to save app with ! and ? then process target list
|
||||||
@@ -122,4 +149,112 @@ function toggleableCheckbox() {
|
|||||||
checkbox.checked = !checkbox.checked;
|
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");
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
import { basePath, execCommand } from './main.js';
|
import { basePath, execCommand, toast } from './main.js';
|
||||||
|
|
||||||
const languageButton = document.querySelector('.language-button');
|
const languageButton = document.querySelector('.language-button');
|
||||||
const languageMenu = document.querySelector('.language-menu');
|
const languageMenu = document.querySelector('.language-menu');
|
||||||
@@ -16,6 +16,7 @@ export async function initializeAvailableLanguages() {
|
|||||||
availableLanguages = multiLang.trim().split('\n');
|
availableLanguages = multiLang.trim().split('\n');
|
||||||
generateLanguageMenu();
|
generateLanguageMenu();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
toast("Failed to get available langauge!");
|
||||||
console.error('Failed to fetch available languages:', error);
|
console.error('Failed to fetch available languages:', error);
|
||||||
availableLanguages = ['en-US'];
|
availableLanguages = ['en-US'];
|
||||||
}
|
}
|
||||||
@@ -41,6 +42,7 @@ export async function loadTranslations(lang) {
|
|||||||
translations = await response.json();
|
translations = await response.json();
|
||||||
applyTranslations();
|
applyTranslations();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
toast(`Failed to load translation for ${lang}!`);
|
||||||
console.error(`Error loading translations for ${lang}:`, error);
|
console.error(`Error loading translations for ${lang}:`, error);
|
||||||
if (lang !== 'en-US') {
|
if (lang !== 'en-US') {
|
||||||
console.log("Falling back to English.");
|
console.log("Falling back to English.");
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ async function getModuleVersion() {
|
|||||||
moduleVersion.textContent = version;
|
moduleVersion.textContent = version;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Failed to read version from module.prop:", error);
|
console.error("Failed to read version from module.prop:", error);
|
||||||
updateVersion("Error reading version from module.prop");
|
updateVersion("Error");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -55,6 +55,7 @@ async function refreshAppList() {
|
|||||||
updateCheck();
|
updateCheck();
|
||||||
await execCommand(`[ -f ${basePath}common/tmp/exclude-list ] && rm -f "${basePath}common/tmp/exclude-list"`);
|
await execCommand(`[ -f ${basePath}common/tmp/exclude-list ] && rm -f "${basePath}common/tmp/exclude-list"`);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
toast("Failed!");
|
||||||
console.error("Error occurred:", error);
|
console.error("Error occurred:", error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -77,6 +78,7 @@ async function checkMagisk() {
|
|||||||
console.log("not running on Magisk, leaving denylist element hidden.");
|
console.log("not running on Magisk, leaving denylist element hidden.");
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
toast("Failed to check Magisk!");
|
||||||
console.error("Error while checking denylist conditions:", error);
|
console.error("Error while checking denylist conditions:", error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -106,7 +108,7 @@ export async function linkRedirect(link) {
|
|||||||
try {
|
try {
|
||||||
await execCommand(`am start -a android.intent.action.VIEW -d ${link}`);
|
await execCommand(`am start -a android.intent.action.VIEW -d ${link}`);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
toast('error!');
|
toast("Failed!");
|
||||||
console.error('Error redirect link:', error);
|
console.error('Error redirect link:', error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -199,7 +201,7 @@ function applyRippleEffect() {
|
|||||||
const y = event.clientY - rect.top - size / 2;
|
const y = event.clientY - rect.top - size / 2;
|
||||||
|
|
||||||
// Determine animation duration
|
// Determine animation duration
|
||||||
let duration = 0.2 + (width / 800) * 0.5;
|
let duration = 0.2 + (width / 800) * 0.4;
|
||||||
duration = Math.min(0.8, Math.max(0.2, duration));
|
duration = Math.min(0.8, Math.max(0.2, duration));
|
||||||
|
|
||||||
// Set ripple styles
|
// Set ripple styles
|
||||||
@@ -289,6 +291,7 @@ updateCard.addEventListener('click', async () => {
|
|||||||
try {
|
try {
|
||||||
await execCommand('am start -a android.intent.action.VIEW -d https://github.com/KOWX712/Tricky-Addon-Update-Target-List/releases/latest');
|
await execCommand('am start -a android.intent.action.VIEW -d https://github.com/KOWX712/Tricky-Addon-Update-Target-List/releases/latest');
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
toast("Failed!");
|
||||||
console.error('Error opening GitHub Release link:', error);
|
console.error('Error opening GitHub Release link:', error);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { basePath, execCommand, showPrompt } from './main.js';
|
import { basePath, execCommand, showPrompt, toast } from './main.js';
|
||||||
|
|
||||||
// Function to check or uncheck all app
|
// Function to check or uncheck all app
|
||||||
function toggleCheckboxes(shouldCheck) {
|
function toggleCheckboxes(shouldCheck) {
|
||||||
@@ -32,6 +32,7 @@ document.getElementById("select-denylist").addEventListener("click", async () =>
|
|||||||
});
|
});
|
||||||
console.log("Denylist apps selected successfully.");
|
console.log("Denylist apps selected successfully.");
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
toast("Failed to read DenyList!");
|
||||||
console.error("Failed to select Denylist apps:", error);
|
console.error("Failed to select Denylist apps:", error);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -65,6 +66,7 @@ document.getElementById("deselect-unnecessary").addEventListener("click", async
|
|||||||
});
|
});
|
||||||
console.log("Unnecessary apps deselected successfully.");
|
console.log("Unnecessary apps deselected successfully.");
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
toast("Failed!");
|
||||||
console.error("Failed to deselect unnecessary apps:", error);
|
console.error("Failed to deselect unnecessary apps:", error);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -46,7 +46,7 @@
|
|||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
margin-bottom: 10px;
|
margin-bottom: 10px;
|
||||||
outline: none;
|
outline: none;
|
||||||
padding: 12px;
|
padding: 10px;
|
||||||
width: calc(100% - 30px);
|
width: calc(100% - 30px);
|
||||||
max-width: 900px;
|
max-width: 900px;
|
||||||
transition: background-color 0.2s ease;
|
transition: background-color 0.2s ease;
|
||||||
@@ -58,6 +58,83 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mode {
|
||||||
|
display: none;
|
||||||
|
flex-direction: row;
|
||||||
|
gap: 10px;
|
||||||
|
padding: 10px;
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
margin: auto;
|
||||||
|
width: fit-content;
|
||||||
|
background-color: #B1B1B1;
|
||||||
|
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
border-radius: 12px;
|
||||||
|
opacity: 0;
|
||||||
|
transform: scale(0);
|
||||||
|
transition: all 0.4s cubic-bezier(0.22, 1, 0.36, 1);
|
||||||
|
z-index: 1200;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mode.show {
|
||||||
|
opacity: 1;
|
||||||
|
transform: scale(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.mode-overlay {
|
||||||
|
display: none;
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100vw;
|
||||||
|
height: 100vh;
|
||||||
|
background-color: none;
|
||||||
|
z-index: 1100;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mode-switch {
|
||||||
|
position: relative;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mode-input {
|
||||||
|
opacity: 0;
|
||||||
|
position: absolute;
|
||||||
|
width: 0;
|
||||||
|
height: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-indicator {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
width: 30px;
|
||||||
|
height: 30px;
|
||||||
|
border-radius: 7px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
transition: border-color 0.2s ease;
|
||||||
|
border: 3px solid transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
#normal-indicator {
|
||||||
|
background-color: #007bff;
|
||||||
|
}
|
||||||
|
|
||||||
|
#hack-indicator {
|
||||||
|
background-color: #FF8400;
|
||||||
|
}
|
||||||
|
|
||||||
|
#generate-indicator {
|
||||||
|
background-color: #6C00FF;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mode-input[type="radio"]:checked ~ .mode-icon .status-indicator {
|
||||||
|
border-color: #fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
.name {
|
.name {
|
||||||
@@ -92,8 +169,8 @@
|
|||||||
height: 100%;
|
height: 100%;
|
||||||
border: 2px solid #ccc;
|
border: 2px solid #ccc;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
transition: border-color 1s ease, transform 0.3s ease, background-color 0.4s cubic-bezier(0.22, 1, 0.36, 1);
|
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
|
transition: border-color 1s ease, transform 0.3s ease, background-color 0.4s cubic-bezier(0.22, 1, 0.36, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
.tick-symbol {
|
.tick-symbol {
|
||||||
@@ -109,7 +186,21 @@
|
|||||||
border-color: #007bff;
|
border-color: #007bff;
|
||||||
background-color: #007bff;
|
background-color: #007bff;
|
||||||
transition: border-color 0.1s ease;
|
transition: border-color 0.1s ease;
|
||||||
animation: border-bounce 0.3s ease-out;
|
animation: checked-bounce 0.3s ease-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.checkbox-checked-generate:checked + .custom-checkbox {
|
||||||
|
border-color: #6C00FF;
|
||||||
|
background-color: #6C00FF;
|
||||||
|
}
|
||||||
|
|
||||||
|
.checkbox-checked-hack:checked + .custom-checkbox {
|
||||||
|
border-color: #FF8400;
|
||||||
|
background-color: #FF8400;
|
||||||
|
}
|
||||||
|
|
||||||
|
.checkbox:not(:checked) + .custom-checkbox {
|
||||||
|
animation: unchecked-bounce 0.3s ease-out;
|
||||||
}
|
}
|
||||||
|
|
||||||
.checkbox:checked + .custom-checkbox .tick-symbol {
|
.checkbox:checked + .custom-checkbox .tick-symbol {
|
||||||
@@ -117,7 +208,19 @@
|
|||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@keyframes border-bounce {
|
@keyframes checked-bounce {
|
||||||
|
0% {
|
||||||
|
transform: scale(1);
|
||||||
|
}
|
||||||
|
50% {
|
||||||
|
transform: scale(0.8);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
transform: scale(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes unchecked-bounce {
|
||||||
0% {
|
0% {
|
||||||
transform: scale(1);
|
transform: scale(1);
|
||||||
}
|
}
|
||||||
@@ -137,4 +240,9 @@
|
|||||||
.update-card {
|
.update-card {
|
||||||
background-color: #4D4D4D;
|
background-color: #4D4D4D;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.mode {
|
||||||
|
background-color: #343434;
|
||||||
|
border: 1px solid #6E6E6E;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -15,7 +15,7 @@ body {
|
|||||||
bottom: 50px;
|
bottom: 50px;
|
||||||
left: 50%;
|
left: 50%;
|
||||||
transform: translateX(-50%);
|
transform: translateX(-50%);
|
||||||
z-index: 3;
|
z-index: 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
.floating-btn {
|
.floating-btn {
|
||||||
|
|||||||
Reference in New Issue
Block a user