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
Compare commits
54 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d9a00b9540 | ||
|
|
ed77c72a79 | ||
|
|
b5370ad088 | ||
|
|
bb7573f5dd | ||
|
|
ccffd2eaed | ||
|
|
d9c1cdc11d | ||
|
|
e1f9c8904a | ||
|
|
3b98a88c77 | ||
|
|
0b8dcd4503 | ||
|
|
913118ac60 | ||
|
|
cb4276643a | ||
|
|
0087575117 | ||
|
|
5f01b4fed1 | ||
|
|
1f7a4c174b | ||
|
|
19f6b156f6 | ||
|
|
63874eeb8b | ||
|
|
2c5082acbc | ||
|
|
1cb810405a | ||
|
|
142dfdbe81 | ||
|
|
5ef6293924 | ||
|
|
a6b35e8d85 | ||
|
|
51747f261e | ||
|
|
aa7147d115 | ||
|
|
5e9463d8d2 | ||
|
|
d1313d743c | ||
|
|
2542e1a18a | ||
|
|
aa0837ec49 | ||
|
|
684b38afef | ||
|
|
e348fbdd6f | ||
|
|
bb167b760d | ||
|
|
8909a73b59 | ||
|
|
d8848fe5c3 | ||
|
|
2d2cdd7672 | ||
|
|
c1818b6ba2 | ||
|
|
c69337501a | ||
|
|
12a39ce60a | ||
|
|
ec330a4b0b | ||
|
|
7e2c185c5c | ||
|
|
f641f388ad | ||
|
|
f7aee9dc34 | ||
|
|
c19b93ffa3 | ||
|
|
2dc69abea4 | ||
|
|
75ff61e4d2 | ||
|
|
bb3b0abb30 | ||
|
|
502e6f6ea6 | ||
|
|
1d5428e683 | ||
|
|
fe64f37361 | ||
|
|
24548025fe | ||
|
|
d3885966b2 | ||
|
|
ae32ccf973 | ||
|
|
77a6e06631 | ||
|
|
940d809ac5 | ||
|
|
1861e43a81 | ||
|
|
10c02a6924 |
4
.gitattributes
vendored
4
.gitattributes
vendored
@@ -3,7 +3,9 @@
|
|||||||
*.prop text eol=lf
|
*.prop text eol=lf
|
||||||
*.md text eol=lf
|
*.md text eol=lf
|
||||||
*.xml text eol=lf
|
*.xml text eol=lf
|
||||||
|
*.json text eol=lf
|
||||||
|
.extra text eol=lf
|
||||||
META-INF/** text eol=lf
|
META-INF/** text eol=lf
|
||||||
|
|
||||||
# Denote all files that are truly binary and should not be modified.
|
# Denote all files that are truly binary and should not be modified.
|
||||||
common/addon/**/tools/** binary
|
module/bin/**/** binary
|
||||||
26
.github/workflows/build.yml
vendored
26
.github/workflows/build.yml
vendored
@@ -6,6 +6,9 @@ on:
|
|||||||
- main
|
- main
|
||||||
paths:
|
paths:
|
||||||
- 'module/**'
|
- 'module/**'
|
||||||
|
pull_request:
|
||||||
|
paths:
|
||||||
|
- 'module/**'
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
@@ -40,12 +43,16 @@ jobs:
|
|||||||
- name: Check if valid to release
|
- name: Check if valid to release
|
||||||
id: check_tag
|
id: check_tag
|
||||||
run: |
|
run: |
|
||||||
VERSION=$(grep '^version=' module/module.prop | sed 's/version=//')
|
if [ "${{ github.event_name }}" = "pull_request" ]; then
|
||||||
git fetch --tags
|
|
||||||
if git tag | grep -qx "^$VERSION"; then
|
|
||||||
echo "version_tag_exists=true" >> $GITHUB_OUTPUT
|
echo "version_tag_exists=true" >> $GITHUB_OUTPUT
|
||||||
else
|
else
|
||||||
echo "version_tag_exists=false" >> $GITHUB_OUTPUT
|
VERSION=$(grep '^version=' module/module.prop | sed 's/version=//')
|
||||||
|
git fetch --tags
|
||||||
|
if git tag | grep -qx "^$VERSION"; then
|
||||||
|
echo "version_tag_exists=true" >> $GITHUB_OUTPUT
|
||||||
|
else
|
||||||
|
echo "version_tag_exists=false" >> $GITHUB_OUTPUT
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
release:
|
release:
|
||||||
@@ -87,13 +94,12 @@ jobs:
|
|||||||
FILES="TrickyAddonModule-${VERSION}.zip"
|
FILES="TrickyAddonModule-${VERSION}.zip"
|
||||||
else
|
else
|
||||||
PRERELEASE=false
|
PRERELEASE=false
|
||||||
FORMATTED_RELEASE_NOTES=$(echo -e "### Tricky Addon module\n$RELEASE_NOTES\n---\n### Tricky Addon Lite - script only\n- Check on [changelog](https://github.com/KOWX712/Tricky-Addon-Update-Target-List/tree/main/lite-script_only#tricky-addon-lite-update-target-list-script)")
|
FORMATTED_RELEASE_NOTES=$(echo -e "### Tricky Addon module\n$RELEASE_NOTES\n")
|
||||||
FILES="TrickyAddonModule-${VERSION}.zip,TrickyAddonLite_ScriptOnly_Extract-${VERSION}.zip"
|
FILES="TrickyAddonModule-${VERSION}.zip"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "CURRENT_TAG=$CURRENT_TAG" >> $GITHUB_ENV
|
echo "CURRENT_TAG=$CURRENT_TAG" >> $GITHUB_ENV
|
||||||
echo "ZIP_NAME=TrickyAddonModule-${VERSION}.zip" >> $GITHUB_ENV
|
echo "ZIP_NAME=TrickyAddonModule-${VERSION}.zip" >> $GITHUB_ENV
|
||||||
echo "LITE_SCRIPT_ONLY_ZIP_NAME=TrickyAddonLite_ScriptOnly_Extract-${VERSION}.zip" >> $GITHUB_ENV
|
|
||||||
echo "RELEASE_NOTES<<EOF" >> $GITHUB_ENV
|
echo "RELEASE_NOTES<<EOF" >> $GITHUB_ENV
|
||||||
echo "$FORMATTED_RELEASE_NOTES" >> $GITHUB_ENV
|
echo "$FORMATTED_RELEASE_NOTES" >> $GITHUB_ENV
|
||||||
echo "EOF" >> $GITHUB_ENV
|
echo "EOF" >> $GITHUB_ENV
|
||||||
@@ -105,12 +111,6 @@ jobs:
|
|||||||
cd module && zip -r "../${{ env.ZIP_NAME }}" ./*
|
cd module && zip -r "../${{ env.ZIP_NAME }}" ./*
|
||||||
echo "Created zip file: ${{ env.ZIP_NAME }}"
|
echo "Created zip file: ${{ env.ZIP_NAME }}"
|
||||||
|
|
||||||
- name: Compress lite-script_only folder
|
|
||||||
if: ${{ env.PRERELEASE == 'false' }}
|
|
||||||
run: |
|
|
||||||
cd lite-script_only && zip -r "../${{ env.LITE_SCRIPT_ONLY_ZIP_NAME }}" ./*
|
|
||||||
echo "Created zip file: ${{ env.LITE_SCRIPT_ONLY_ZIP_NAME }}"
|
|
||||||
|
|
||||||
- name: Create release
|
- name: Create release
|
||||||
uses: softprops/action-gh-release@v2
|
uses: softprops/action-gh-release@v2
|
||||||
env:
|
env:
|
||||||
|
|||||||
31
.github/workflows/json-lint.yml
vendored
Normal file
31
.github/workflows/json-lint.yml
vendored
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
name: pr_jsonlint
|
||||||
|
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
paths:
|
||||||
|
- 'module/webui/locales/*.json'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
lint:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout code
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
|
- name: Setup Node.js
|
||||||
|
uses: actions/setup-node@v3
|
||||||
|
with:
|
||||||
|
node-version: 18
|
||||||
|
|
||||||
|
- name: Install JSON linter
|
||||||
|
run: npm install -g jsonlint
|
||||||
|
|
||||||
|
- name: Lint JSON files
|
||||||
|
run: |
|
||||||
|
for file in $(find module/webui/locales -name "*.json"); do
|
||||||
|
echo "Checking $file"
|
||||||
|
if ! jsonlint "$file"; then
|
||||||
|
echo "Error in $file"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
done
|
||||||
29
README.md
29
README.md
@@ -16,28 +16,29 @@ Configure Tricky Store target.txt with KSU WebUI.
|
|||||||
|
|
||||||
### Magisk
|
### Magisk
|
||||||
- Action button to open WebUI
|
- Action button to open WebUI
|
||||||
- Support KSUWebUIStandalone and latest MMRL
|
- Support [KSUWebUIStandalone](https://github.com/5ec1cff/KsuWebUIStandalone) and [MMRL](https://github.com/MMRLApp/MMRL)
|
||||||
- Automatic install [KSUWebUIStandalone](https://github.com/5ec1cff/KsuWebUIStandalone) if none of them are installed.
|
- Automatic KSUWebUIStandalone install if none of them are installed.
|
||||||
|
|
||||||
### What Can This Module Do
|
### What Can This Module Do
|
||||||
| Feature | Status |
|
| Feature | Status |
|
||||||
|:---|:---:|
|
| :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :----: |
|
||||||
| Configure target.txt with app name display | ✅ |
|
| Configure target.txt with app name display | ✅ |
|
||||||
| Select apps from Magisk DenyList (optional) | ✅ |
|
| Long press to choose `!` or `?` mode for the app. [Auto](https://github.com/5ec1cff/TrickyStore/releases/tag/1.1.0)<br>Use this only when the app cannot work without this. | ✅ |
|
||||||
| Deselect [unnecessary apps](https://github.com/KOWX712/Tricky-Addon-Update-Target-List/blob/main/more-excldue.json) (optional) | ✅ |
|
| Select apps from Magisk DenyList `optional` | ✅ |
|
||||||
| Set verifiedBootHash (optional) | ✅ |
|
| Deselect [unnecessary apps](https://github.com/KOWX712/Tricky-Addon-Update-Target-List/blob/main/more-exclude.json) `optional` | ✅ |
|
||||||
| Provide AOSP Keybox (optional) | ✅ |
|
| Set verifiedBootHash `optional` | ✅ |
|
||||||
| Valid Keybox (not guaranteed) | ❌ |
|
| Provide AOSP Keybox `optional` | ✅ |
|
||||||
| Shamiko Whitelist switch ([Why?](https://github.com/rushizgithub/shamiko?tab=readme-ov-file#whitelist)) | ❌ |
|
| Valid Keybox `not guaranteed` | ❌ |
|
||||||
| Add `!` or `?` to the target ([Not needed](https://github.com/5ec1cff/TrickyStore/releases/tag/1.1.0)) | ❌ |
|
| Shamiko Whitelist switch. [Why?](https://github.com/rushizgithub/shamiko?tab=readme-ov-file#whitelist) | ❌ |
|
||||||
| Periodically update target and add new apps | ❌ |
|
| Periodically add all app to target.txt | ❌ |
|
||||||
| Add system apps (GMS added by default) | ❌ |
|
| Add system apps `GMS added by default` | ❌ |
|
||||||
|
|
||||||
## Localization
|
## Localization
|
||||||
- Read [Translation Guide](https://github.com/KOWX712/Tricky-Addon-Update-Target-List/blob/main/module/webui/locales/A-translate.md)
|
- Read [Translation Guide](https://github.com/KOWX712/Tricky-Addon-Update-Target-List/blob/main/module/webui/locales/A-translate.md)
|
||||||
|
|
||||||
## Acknowledgement
|
## Acknowledgement
|
||||||
- [j-hc/zygisk-detach](https://github.com/j-hc/zygisk-detach) - KSU WebUI template
|
- [j-hc/zygisk-detach](https://github.com/j-hc/zygisk-detach) - KSU WebUI template
|
||||||
|
- [markedjs/marked](https://github.com/markedjs/marked) - Markdown Support
|
||||||
|
|
||||||
## Links
|
## Links
|
||||||
[](https://github.com/KOWX712/Tricky-Addon-Update-Target-List/releases)
|
[](https://github.com/KOWX712/Tricky-Addon-Update-Target-List/releases)
|
||||||
|
|||||||
32
changelog.md
32
changelog.md
@@ -8,12 +8,38 @@ GitHub release: [Tricky Addon: Update Target List](https://github.com/KOWX712/Tr
|
|||||||
Telegram channel: [KOW's Little World](https://t.me/kowchannel)
|
Telegram channel: [KOW's Little World](https://t.me/kowchannel)
|
||||||
|
|
||||||
## Changelog
|
## Changelog
|
||||||
|
### v3.3
|
||||||
|
- Support auto config `security_patch.txt` for Tricky Store v1.2.1 or higher.
|
||||||
|
- No longer need to add `!` to Play Store for devices that have security patch older than one year to get strong integrity in new A13+ check.
|
||||||
|
- **Magisk:** automatically add apps from DenyList to `target.txt` on boot. To enable this feature, click "Select from DenyList" once in WebUI after update.
|
||||||
|
|
||||||
|
### v3.2
|
||||||
|
- Add `android` and `com.android.vending` by default.
|
||||||
|
- Handle `ro.vendor.build.security_patch` if the value is different.
|
||||||
|
- Updated Japanese translation (#11, @reindex-ot)
|
||||||
|
- Added Turkish translation (@berkmirsatk)
|
||||||
|
|
||||||
|
### v3.1
|
||||||
|
- Added `com.google.android.gsf` and `com.android.vending` into WebUI app list. (#10, @ChiseWaguri)
|
||||||
|
- Fixed multiple instances of GMS appeared in the app list when GMS isn't a system app.
|
||||||
|
- Added auto backup `keybox.xml` to `keybox.xml.bak` before replacing it.
|
||||||
|
- Minor animation improvements and code optimizations.
|
||||||
|
- [Markdown support](https://github.com/markedjs/marked) for future update changelog in WebUI.
|
||||||
|
|
||||||
|
### v3.0
|
||||||
|
- Animation improvement: new checkbox animation, new touch ripple animation, and more.
|
||||||
|
- Adjust save button and prompt position in MMRL.
|
||||||
|
- Long press on app to select `!` and `?` mode, use this only when the app cannot work without this.
|
||||||
|
- Display gms in app list.
|
||||||
|
- Show module version in header.
|
||||||
|
- Rewrite update method, you can now update module directly in WebUI.
|
||||||
|
|
||||||
### v2.9
|
### v2.9
|
||||||
- Preserve `!` and `?` during update target in WebUi.
|
- Preserve `!` and `?` during update target in WebUI.
|
||||||
- Optimized scripts, thanks to @backslashxx.
|
- Optimized scripts, thanks to @backslashxx.
|
||||||
- Fixed freeze in weak connection.
|
- Fixed freeze in weak connection.
|
||||||
- Added Spanish, thanks to @Keinta15.
|
- Added Spanish, thanks to @Keinta15.
|
||||||
- Removed rescriction on installation but module will still be removed if tricky store is not found after reboot.
|
- Removed restriction on installation but module will still be removed if Tricky Store is not found after reboot.
|
||||||
|
|
||||||
### v2.8
|
### v2.8
|
||||||
- Fixed all KSUWebUIStandalone freeze issue, removed visible option.
|
- Fixed all KSUWebUIStandalone freeze issue, removed visible option.
|
||||||
@@ -31,7 +57,7 @@ Telegram channel: [KOW's Little World](https://t.me/kowchannel)
|
|||||||
- Press any position of app card to select/deselct.
|
- Press any position of app card to select/deselct.
|
||||||
|
|
||||||
### v2.6
|
### v2.6
|
||||||
- Invisible module, intergrate action button & webui on tricky store card. You can stil use visible option if you found any issue with invisble module. Thanks for idea from @backslashxx.
|
- Invisible module, integrate action button & WebUI on Tricky Store card. You can still use visible option if you found any issue with invisible module. Thanks for idea from @backslashxx.
|
||||||
- To uninstall invisble module, scroll down to the bottom of WebUI and press Uninstall WebUI.
|
- To uninstall invisble module, scroll down to the bottom of WebUI and press Uninstall WebUI.
|
||||||
- Add update prompt if found new version in webui, and show module if found an update. (invisible)
|
- Add update prompt if found new version in webui, and show module if found an update. (invisible)
|
||||||
- Reduced WebUI loading time
|
- Reduced WebUI loading time
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
## Tricky Addon Lite: Update Target List Script
|
## Tricky Addon Lite: Update Target List Script (EOL)
|
||||||
- Script only, **NOT Module**
|
- Script only, **NOT Module**
|
||||||
- Run with root priviledge
|
- Run with root priviledge
|
||||||
- Recommend to run with MT manager
|
- Recommend to run with MT manager
|
||||||
|
|||||||
@@ -21,6 +21,8 @@ me.garfieldhan.apatch.next"
|
|||||||
|
|
||||||
ADDITION="
|
ADDITION="
|
||||||
com.google.android.gms
|
com.google.android.gms
|
||||||
|
com.google.android.gsf
|
||||||
|
com.android.vending
|
||||||
io.github.vvb2060.keyattestation
|
io.github.vvb2060.keyattestation
|
||||||
io.github.vvb2060.mahoshojo
|
io.github.vvb2060.mahoshojo
|
||||||
icu.nullptr.nativetest"
|
icu.nullptr.nativetest"
|
||||||
|
|||||||
@@ -3,70 +3,67 @@
|
|||||||
###########################################
|
###########################################
|
||||||
|
|
||||||
MODPATH="/data/adb/modules/.TA_utl"
|
MODPATH="/data/adb/modules/.TA_utl"
|
||||||
COMPATH="$MODPATH/common"
|
ORG_PATH="$PATH"
|
||||||
|
TMP_DIR="$MODPATH/common/tmp"
|
||||||
SCRIPT_DIR="/data/adb/tricky_store"
|
SCRIPT_DIR="/data/adb/tricky_store"
|
||||||
URL="https://github.com/5ec1cff/KsuWebUIStandalone/releases/download/v1.0/KsuWebUI-1.0-34-release.apk"
|
APK_PATH="$TMP_DIR/base.apk"
|
||||||
APK_DIR="$COMPATH/tmp"
|
|
||||||
BBPATH="/data/adb/magisk/busybox \
|
|
||||||
/data/adb/ksu/bin/busybox \
|
|
||||||
/data/adb/ap/bin/busybox \
|
|
||||||
/data/adb/modules/busybox-ndk/system/*/busybox"
|
|
||||||
|
|
||||||
check_wget() {
|
abort() {
|
||||||
for path in $BBPATH; do
|
echo "$1"
|
||||||
[ -f "$path" ] && BUSYBOX="$path" && break
|
exit 1
|
||||||
done
|
}
|
||||||
if ! command -v wget >/dev/null || grep -q "wget-curl" "$(command -v wget)"; then
|
|
||||||
if [ -n "$BUSYBOX" ]; then
|
download() {
|
||||||
wget() { "$BUSYBOX" wget "$@"; }
|
download_type=${1#--}
|
||||||
|
download_url=$2
|
||||||
|
download_output=$3
|
||||||
|
|
||||||
|
PATH=/data/adb/magisk:/data/data/com.termux/files/usr/bin:$PATH
|
||||||
|
if command -v curl >/dev/null 2>&1; then
|
||||||
|
if [ "$download_type" = "output" ]; then
|
||||||
|
timeout 10 curl -Lo "$download_output" "$download_url"
|
||||||
else
|
else
|
||||||
exit 1
|
timeout 2 curl -s "$download_url"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
if [ "$download_type" = "output" ]; then
|
||||||
|
timeout 10 busybox wget --no-check-certificate -qO "$download_output" "$download_url"
|
||||||
|
else
|
||||||
|
timeout 2 busybox wget --no-check-certificate -qO- "$download_url"
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
PATH="$ORG_PATH"
|
||||||
}
|
}
|
||||||
|
|
||||||
get_webui() {
|
get_webui() {
|
||||||
echo "- Downloading the WebUI APK..."
|
echo "- Downloading KSU WebUI Standalone..."
|
||||||
check_wget
|
RESPONSE=$(download --fetch "https://api.github.com/repos/5ec1cff/KsuWebUIStandalone/releases/latest")
|
||||||
if ! wget --no-check-certificate -P "$APK_DIR" "$URL"; then
|
URL=$(echo "$RESPONSE" | grep -o '"browser_download_url": "[^"]*"' | cut -d '"' -f 4)
|
||||||
echo "! Error: APK download failed."
|
download --output "$URL" "$APK_PATH" || abort "! Error: APK download failed, please check your internet connection."
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "- Download complete."
|
|
||||||
APK_PATH=$(find "$APK_DIR" -type f -name "*.apk" | head -n 1)
|
|
||||||
if [ -z "$APK_PATH" ]; then
|
|
||||||
echo "! Error: No APK file found in $APK_DIR."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "- Installing..."
|
echo "- Installing..."
|
||||||
if ! pm install -r "$APK_PATH" >/dev/null 2>&1; then
|
pm install -r "$APK_PATH" || {
|
||||||
echo "! Error: APK installation failed."
|
|
||||||
rm -f "$APK_PATH"
|
rm -f "$APK_PATH"
|
||||||
exit 1
|
abort "! Error: APK installation failed."
|
||||||
fi
|
}
|
||||||
|
|
||||||
echo "- Done."
|
echo "- Done."
|
||||||
rm -f "$APK_PATH"
|
rm -f "$APK_PATH"
|
||||||
|
|
||||||
echo "- Launching..."
|
echo "- Launching WebUI..."
|
||||||
if ! am start -n "io.github.a13e300.ksuwebui/.WebUIActivity" -e id "tricky_store"; then
|
am start -n "io.github.a13e300.ksuwebui/.WebUIActivity" -e id "tricky_store" || abort "! Error: WebUI launch failed."
|
||||||
echo "! Error: WebUI launch failed."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "- Application launched successfully."
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# Lunch KSUWebUI standalone or MMRL, install KSUWebUI standalone if both are not installed
|
# Launch KSUWebUI standalone or MMRL, install KSUWebUI standalone if both are not installed
|
||||||
if pm list packages | grep -q "io.github.a13e300.ksuwebui"; then
|
if pm path io.github.a13e300.ksuwebui >/dev/null 2>&1; then
|
||||||
echo "- Launching WebUI in KSUWebUIStandalone..."
|
echo "- Launching WebUI in KSUWebUIStandalone..."
|
||||||
am start -n "io.github.a13e300.ksuwebui/.WebUIActivity" -e id "tricky_store"
|
am start -n "io.github.a13e300.ksuwebui/.WebUIActivity" -e id "tricky_store"
|
||||||
elif pm list packages | grep -q "com.dergoogler.mmrl"; then
|
elif pm path com.dergoogler.mmrl >/dev/null 2>&1; then
|
||||||
echo "- Launching WebUI in MMRL WebUI..."
|
echo "- Launching WebUI in MMRL WebUI..."
|
||||||
am start -n "com.dergoogler.mmrl/.ui.activity.webui.WebUIActivity" -e MOD_ID "tricky_store"
|
am start -n "com.dergoogler.mmrl/.ui.activity.webui.WebUIActivity" -e MOD_ID "tricky_store"
|
||||||
else
|
else
|
||||||
echo "- Installing KSU WebUI..."
|
echo "! No WebUI app found"
|
||||||
get_webui
|
get_webui
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
echo "- WebUI launched successfully."
|
||||||
@@ -1,25 +1,46 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
PATH=/data/adb/ap/bin:/data/adb/ksu/bin:/data/adb/magisk:/data/data/com.termux/files/usr/bin:$PATH
|
|
||||||
MODPATH=${0%/*}
|
MODPATH=${0%/*}
|
||||||
|
ORG_PATH="$PATH"
|
||||||
SKIPLIST="$MODPATH/tmp/skiplist"
|
SKIPLIST="$MODPATH/tmp/skiplist"
|
||||||
OUTPUT="$MODPATH/tmp/exclude-list"
|
OUTPUT="$MODPATH/tmp/exclude-list"
|
||||||
KBOUTPUT="$MODPATH/tmp/.extra"
|
KBOUTPUT="$MODPATH/tmp/.extra"
|
||||||
|
|
||||||
|
if [ "$MODPATH" = "/data/adb/modules/.TA_utl/common" ]; then
|
||||||
|
MODDIR="/data/adb/modules/.TA_utl"
|
||||||
|
MAGISK="true"
|
||||||
|
else
|
||||||
|
MODDIR="/data/adb/modules/TA_utl"
|
||||||
|
fi
|
||||||
|
|
||||||
aapt() { "$MODPATH/aapt" "$@"; }
|
aapt() { "$MODPATH/aapt" "$@"; }
|
||||||
|
|
||||||
# probe for downloaders
|
# probe for downloaders
|
||||||
# wget = low pref, no ssl.
|
# wget = low pref, no ssl.
|
||||||
# curl, has ssl on android, we use it if found
|
# curl, has ssl on android, we use it if found
|
||||||
download() {
|
download() {
|
||||||
|
download_type=${1#--}
|
||||||
|
download_url=$2
|
||||||
|
download_output=$3
|
||||||
|
|
||||||
|
PATH=/data/adb/ap/bin:/data/adb/ksu/bin:/data/adb/magisk:/data/data/com.termux/files/usr/bin:$PATH
|
||||||
if command -v curl >/dev/null 2>&1; then
|
if command -v curl >/dev/null 2>&1; then
|
||||||
timeout 3 curl -s "$1"
|
if [ "$download_type" = "output" ]; then
|
||||||
|
timeout 10 curl -Lo "$download_output" "$download_url"
|
||||||
|
else
|
||||||
|
timeout 3 curl -s "$download_url"
|
||||||
|
fi
|
||||||
else
|
else
|
||||||
timeout 3 busybox wget --no-check-certificate -qO - "$1"
|
if [ "$download_type" = "output" ]; then
|
||||||
|
timeout 10 busybox wget --no-check-certificate -qO "$download_output" "$download_url"
|
||||||
|
else
|
||||||
|
timeout 3 busybox wget --no-check-certificate -qO- "$download_url"
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
|
PATH="$ORG_PATH"
|
||||||
}
|
}
|
||||||
|
|
||||||
get_kb() {
|
get_kb() {
|
||||||
download "https://raw.githubusercontent.com/KOWX712/Tricky-Addon-Update-Target-List/main/.extra" > "$KBOUTPUT"
|
download --output "https://raw.githubusercontent.com/KOWX712/Tricky-Addon-Update-Target-List/main/.extra" "$KBOUTPUT"
|
||||||
[ -s "$KBOUTPUT" ] || rm -f "$KBOUTPUT"
|
[ -s "$KBOUTPUT" ] || rm -f "$KBOUTPUT"
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -36,31 +57,30 @@ get_xposed() {
|
|||||||
|
|
||||||
get_unnecessary() {
|
get_unnecessary() {
|
||||||
if [ ! -s "$OUTPUT" ] || [ ! -f "$OUTPUT" ]; then
|
if [ ! -s "$OUTPUT" ] || [ ! -f "$OUTPUT" ]; then
|
||||||
download "https://raw.githubusercontent.com/KOWX712/Tricky-Addon-Update-Target-List/main/more-exclude.json" 2>/dev/null | grep -o '"package-name": *"[^"]*"' | awk -F'"' '{print $4}' >"$OUTPUT"
|
JSON=$(download --fetch "https://raw.githubusercontent.com/KOWX712/Tricky-Addon-Update-Target-List/main/more-exclude.json") || exit 1
|
||||||
|
echo "$JSON" | grep -o '"package-name": *"[^"]*"' | awk -F'"' '{print $4}' >"$OUTPUT"
|
||||||
fi
|
fi
|
||||||
get_xposed
|
get_xposed
|
||||||
}
|
}
|
||||||
|
|
||||||
check_update() {
|
check_update() {
|
||||||
if [ -d "$MODPATH/update" ]; then
|
[ -f "$MODDIR/disable" ] && rm -f "$MODDIR/disable"
|
||||||
JSON=$(download "https://raw.githubusercontent.com/KOWX712/Tricky-Addon-Update-Target-List/main/update.json") || exit 1
|
JSON=$(download --fetch "https://raw.githubusercontent.com/KOWX712/Tricky-Addon-Update-Target-List/main/update.json") || exit 1
|
||||||
REMOTE_VERSION=$(echo "$JSON" | grep -o '"versionCode": *[0-9]*' | awk -F: '{print $2}' | tr -d ' ')
|
REMOTE_VERSION=$(echo "$JSON" | grep -o '"versionCode": *[0-9]*' | awk -F: '{print $2}' | tr -d ' ')
|
||||||
LOCAL_VERSION=$(grep -o 'versionCode=[0-9]*' "$MODPATH/update/module.prop" | awk -F= '{print $2}')
|
LOCAL_VERSION=$(grep -o 'versionCode=[0-9]*' "$MODPATH/update/module.prop" | awk -F= '{print $2}')
|
||||||
if [ "$REMOTE_VERSION" -gt "$LOCAL_VERSION" ]; then
|
if [ "$REMOTE_VERSION" -gt "$LOCAL_VERSION" ] && [ ! -f "/data/adb/modules/TA_utl/update" ]; then
|
||||||
if [ "$MODPATH" = "/data/adb/modules/.TA_utl/common" ]; then
|
if [ "$MAGISK" = "true" ]; then
|
||||||
[ -d "/data/adb/modules/TA_utl" ] && rm -rf "/data/adb/modules/TA_utl"
|
[ -d "/data/adb/modules/TA_utl" ] && rm -rf "/data/adb/modules/TA_utl"
|
||||||
cp -rf "$MODPATH/update" "/data/adb/modules/TA_utl"
|
cp -rf "$MODPATH/update" "/data/adb/modules/TA_utl"
|
||||||
else
|
else
|
||||||
cp -f "$MODPATH/update/module.prop" "/data/adb/modules/TA_utl/module.prop"
|
cp -f "$MODPATH/update/module.prop" "/data/adb/modules/TA_utl/module.prop"
|
||||||
fi
|
|
||||||
echo "update"
|
|
||||||
fi
|
fi
|
||||||
|
echo "update"
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
uninstall() {
|
uninstall() {
|
||||||
if [ "$MODPATH" = "/data/adb/modules/.TA_utl/common" ]; then
|
if [ "$MAGISK" = "true" ]; then
|
||||||
[ -d "/data/adb/modules/TA_utl" ] && rm -rf "/data/adb/modules/TA_utl"
|
|
||||||
cp -rf "$MODPATH/update" "/data/adb/modules/TA_utl"
|
cp -rf "$MODPATH/update" "/data/adb/modules/TA_utl"
|
||||||
else
|
else
|
||||||
cp -f "$MODPATH/update/module.prop" "/data/adb/modules/TA_utl/module.prop"
|
cp -f "$MODPATH/update/module.prop" "/data/adb/modules/TA_utl/module.prop"
|
||||||
@@ -68,6 +88,42 @@ uninstall() {
|
|||||||
touch "/data/adb/modules/TA_utl/remove"
|
touch "/data/adb/modules/TA_utl/remove"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get_update() {
|
||||||
|
JSON=$(download --fetch "https://raw.githubusercontent.com/KOWX712/Tricky-Addon-Update-Target-List/main/update.json") || exit 1
|
||||||
|
ZIP_URL=$(echo "$JSON" | grep -o '"zipUrl": "[^"]*"' | cut -d '"' -f 4) || exit 1
|
||||||
|
CHANGELOG_URL=$(echo "$JSON" | grep -o '"changelog": "[^"]*"' | cut -d '"' -f 4) || exit 1
|
||||||
|
download --output "$ZIP_URL" "$MODPATH/tmp/module.zip" || exit 1
|
||||||
|
download --output "$CHANGELOG_URL" "$MODPATH/tmp/changelog.md" || exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
install_update() {
|
||||||
|
command -v magisk >/dev/null 2>&1 && {
|
||||||
|
magisk --install-module "$MODPATH/tmp/module.zip"
|
||||||
|
} || command -v apd >/dev/null 2>&1 && {
|
||||||
|
apd module install "$MODPATH/tmp/module.zip"
|
||||||
|
} || command -v ksud >/dev/null 2>&1 && {
|
||||||
|
ksud module install "$MODPATH/tmp/module.zip"
|
||||||
|
} || exit 1
|
||||||
|
|
||||||
|
rm -f "$MODPATH/tmp/module.zip"
|
||||||
|
rm -f "$MODPATH/tmp/changelog.md"
|
||||||
|
}
|
||||||
|
|
||||||
|
release_note() {
|
||||||
|
awk '
|
||||||
|
/^### v[0-9]+\.[0-9]+$/ {
|
||||||
|
if (!found) {
|
||||||
|
version = $0;
|
||||||
|
found = 1;
|
||||||
|
next
|
||||||
|
} else {
|
||||||
|
exit
|
||||||
|
}
|
||||||
|
}
|
||||||
|
found && !/^###/ { content = content $0 "\n" }
|
||||||
|
END { if (found) { print version; print content } }
|
||||||
|
' "$MODPATH/tmp/changelog.md"
|
||||||
|
}
|
||||||
|
|
||||||
case "$1" in
|
case "$1" in
|
||||||
--kb)
|
--kb)
|
||||||
@@ -90,4 +146,16 @@ case "$1" in
|
|||||||
uninstall
|
uninstall
|
||||||
exit
|
exit
|
||||||
;;
|
;;
|
||||||
|
--get-update)
|
||||||
|
get_update
|
||||||
|
exit
|
||||||
|
;;
|
||||||
|
--install-update)
|
||||||
|
install_update
|
||||||
|
exit
|
||||||
|
;;
|
||||||
|
--release-note)
|
||||||
|
release_note
|
||||||
|
exit
|
||||||
|
;;
|
||||||
esac
|
esac
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
id=TA_utl
|
id=TA_utl
|
||||||
name=Tricky Addon - Update Target List
|
name=Tricky Addon - Update Target List
|
||||||
version=v2.9
|
version=v3.3
|
||||||
versionCode=290
|
versionCode=330
|
||||||
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/main/update.json
|
updateJson=https://raw.githubusercontent.com/KOWX712/Tricky-Addon-Update-Target-List/main/update.json
|
||||||
|
|||||||
@@ -15,5 +15,5 @@ if [ ! -d "$TS" ] || [ -f "$TS/remove" ]; then
|
|||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
rm -f "$TS/action.sh"
|
[ -L "$TS/webroot" ] && rm -f "$TS/webroot"
|
||||||
rm -rf "$TS/webroot"
|
[ -L "$TS/action.sh" ] && rm -f "$TS/action.sh"
|
||||||
|
|||||||
@@ -1,17 +1,46 @@
|
|||||||
MODPATH=${0%/*}
|
MODPATH=${0%/*}
|
||||||
HIDE_DIR="/data/adb/modules/.TA_utl"
|
HIDE_DIR="/data/adb/modules/.TA_utl"
|
||||||
TS="/data/adb/modules/tricky_store"
|
TS="/data/adb/modules/tricky_store"
|
||||||
SCRIPT_DIR="/data/adb/tricky_store"
|
TARGET_DIR="/data/adb/tricky_store"
|
||||||
TSPA="/data/adb/modules/tsupport-advance"
|
TSPA="/data/adb/modules/tsupport-advance"
|
||||||
|
|
||||||
aapt() { "$MODPATH/common/aapt" "$@"; }
|
aapt() { "$MODPATH/common/aapt" "$@"; }
|
||||||
|
|
||||||
|
add_denylist_to_target() {
|
||||||
|
exclamation_target=$(grep '!' "/data/adb/tricky_store/target.txt" | sed 's/!$//')
|
||||||
|
question_target=$(grep '?' "/data/adb/tricky_store/target.txt" | sed 's/?$//')
|
||||||
|
target=$(sed 's/[!?]$//' /data/adb/tricky_store/target.txt)
|
||||||
|
denylist=$(magisk --denylist ls 2>/dev/null | awk -F'|' '{print $1}' | grep -v "isolated")
|
||||||
|
|
||||||
|
printf "%s\n" "$target" "$denylist" | sort -u > "/data/adb/tricky_store/target.txt"
|
||||||
|
|
||||||
|
for target in $exclamation_target; do
|
||||||
|
sed -i "s/^$target$/$target!/" "/data/adb/tricky_store/target.txt"
|
||||||
|
done
|
||||||
|
|
||||||
|
for target in $question_target; do
|
||||||
|
sed -i "s/^$target$/$target?/" "/data/adb/tricky_store/target.txt"
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
# Reset verified Boot Hash
|
# Reset verified Boot Hash
|
||||||
hash_value=$(grep -v '^#' "/data/adb/boot_hash" | tr -d '[:space:]')
|
hash_value=$(grep -v '^#' "/data/adb/boot_hash" | tr -d '[:space:]')
|
||||||
if [ -n "$hash_value" ]; then
|
if [ -n "$hash_value" ]; then
|
||||||
resetprop -n ro.boot.vbmeta.digest "$hash_value"
|
resetprop -n ro.boot.vbmeta.digest "$hash_value"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Reset vendor patch if different with security patch
|
||||||
|
security_patch=$(getprop ro.build.version.security_patch)
|
||||||
|
vendor_patch=$(getprop ro.vendor.build.security_patch)
|
||||||
|
if [ "$vendor_patch" != "$security_patch" ]; then
|
||||||
|
TS_version=$(grep "versionCode=" "$TS/module.prop" | cut -d'=' -f2)
|
||||||
|
if [ "$TS_version" -lt 158 ]; then
|
||||||
|
resetprop -n ro.vendor.build.security_patch "$security_patch"
|
||||||
|
else
|
||||||
|
printf "boot=%s\nvendor=%s\n" "$security_patch" "$security_patch" > "$TARGET_DIR/security_patch.txt"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
# Disable TSupport-A auto update target to prevent overwrite
|
# Disable TSupport-A auto update target to prevent overwrite
|
||||||
if [ -d "$TSPA" ]; then
|
if [ -d "$TSPA" ]; then
|
||||||
touch "/storage/emulated/0/stop-tspa-auto-target"
|
touch "/storage/emulated/0/stop-tspa-auto-target"
|
||||||
@@ -19,21 +48,32 @@ elif [ ! -d "$TSPA" ] && [ -f "/storage/emulated/0/stop-tspa-auto-target" ]; the
|
|||||||
rm -f "/storage/emulated/0/stop-tspa-auto-target"
|
rm -f "/storage/emulated/0/stop-tspa-auto-target"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Hide module
|
# Magisk operation
|
||||||
if [ -f "$MODPATH/action.sh" ]; then
|
if [ -f "$MODPATH/action.sh" ]; then
|
||||||
if [[ "$MODPATH" != "$HIDE_DIR" ]]; then
|
# Hide module from Magisk manager
|
||||||
|
if [ "$MODPATH" != "$HIDE_DIR" ]; then
|
||||||
rm -rf "$HIDE_DIR"
|
rm -rf "$HIDE_DIR"
|
||||||
mv "$MODPATH" "$HIDE_DIR"
|
mv "$MODPATH" "$HIDE_DIR"
|
||||||
fi
|
fi
|
||||||
MODPATH="$HIDE_DIR"
|
MODPATH="$HIDE_DIR"
|
||||||
elif [ -d "$HIDE_DIR" ]; then
|
|
||||||
rm -rf "$HIDE_DIR"
|
# Add target from denylist
|
||||||
|
# To trigger this, choose "Select from DenyList" in WebUI once
|
||||||
|
[ -f "/data/adb/tricky_store/target_from_denylist" ] && add_denylist_to_target
|
||||||
|
else
|
||||||
|
[ -d "$HIDE_DIR" ] && rm -rf "$HIDE_DIR"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Hide module from APatch, KernelSU, KSUWebUIStandalone, MMRL
|
||||||
rm -f "$MODPATH/module.prop"
|
rm -f "$MODPATH/module.prop"
|
||||||
|
|
||||||
# Symlink tricky store
|
# Symlink tricky store
|
||||||
[ -f "$MODPATH/action.sh" ] && ln -s "$MODPATH/action.sh" "$TS/action.sh"
|
if [ -f "$MODPATH/action.sh" ] && [ ! -f "$TS/action.sh" ] && [ ! -L "$TS/action.sh" ]; then
|
||||||
ln -s "$MODPATH/webui" "$TS/webroot"
|
ln -s "$MODPATH/action.sh" "$TS/action.sh"
|
||||||
|
fi
|
||||||
|
if [ ! -d "$TS/webroot" ] && [ ! -L "$TS/webroot" ]; then
|
||||||
|
ln -s "$MODPATH/webui" "$TS/webroot"
|
||||||
|
fi
|
||||||
|
|
||||||
# Optimization
|
# Optimization
|
||||||
OUTPUT_APP="$MODPATH/common/tmp/applist"
|
OUTPUT_APP="$MODPATH/common/tmp/applist"
|
||||||
@@ -43,18 +83,36 @@ until [ "$(getprop sys.boot_completed)" = "1" ]; do
|
|||||||
sleep 1
|
sleep 1
|
||||||
done
|
done
|
||||||
|
|
||||||
|
# Create temporary directory
|
||||||
mkdir -p "$MODPATH/common/tmp"
|
mkdir -p "$MODPATH/common/tmp"
|
||||||
|
|
||||||
|
# Additional system apps
|
||||||
|
SYSTEM_APP="com.google.android.gms|com.google.android.gsf|com.android.vending"
|
||||||
|
|
||||||
|
# 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 "# This file is generated from service.sh to speed up load time" > "$OUTPUT_APP"
|
||||||
echo "# This file is generated from service.sh to speed up load time" > "$OUTPUT_SKIP"
|
echo "# This file is generated from service.sh to speed up load time" > "$OUTPUT_SKIP"
|
||||||
pm list packages -3 </dev/null 2>&1 | cat | awk -F: '{print $2}' | while read -r PACKAGE; do
|
|
||||||
APK_PATH=$(pm path "$PACKAGE" </dev/null 2>&1 | cat | grep "base.apk" | awk -F: '{print $2}' | tr -d '\r')
|
# Get list of third party apps and specific system apps, then cache app name
|
||||||
|
# Check Xposed module
|
||||||
|
{
|
||||||
|
pm list packages -3 2>/dev/null
|
||||||
|
pm list package -s | grep -E "$SYSTEM_APP"
|
||||||
|
} | 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')
|
||||||
|
|
||||||
if [ -n "$APK_PATH" ]; then
|
if [ -n "$APK_PATH" ]; then
|
||||||
APP_NAME=$(aapt dump badging "$APK_PATH" </dev/null 2>&1 | cat | grep "application-label:" | sed "s/application-label://g; s/'//g")
|
# 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"
|
echo "app-name: $APP_NAME, package-name: $PACKAGE" >> "$OUTPUT_APP"
|
||||||
else
|
else
|
||||||
echo "app-name: Unknown App package-name: $PACKAGE" >> "$OUTPUT_APP"
|
echo "app-name: Unknown App package-name: $PACKAGE" >> "$OUTPUT_APP"
|
||||||
fi
|
fi
|
||||||
if ! aapt dump xmltree "$APK_PATH" AndroidManifest.xml </dev/null 2>&1 | cat | grep -qE "xposed.category|xposeddescription"; then
|
|
||||||
|
# Check if app is Xposed module and add to skip list if not
|
||||||
|
if ! aapt dump xmltree "$APK_PATH" AndroidManifest.xml 2>/dev/null | grep -qE "xposed.category|xposeddescription"; then
|
||||||
echo "$PACKAGE" >> "$OUTPUT_SKIP"
|
echo "$PACKAGE" >> "$OUTPUT_SKIP"
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|||||||
@@ -10,8 +10,10 @@ fi
|
|||||||
# Remove residue and restore aosp keybox.
|
# Remove residue and restore aosp keybox.
|
||||||
rm -rf "/data/adb/modules/.TA_utl"
|
rm -rf "/data/adb/modules/.TA_utl"
|
||||||
rm -f "/data/adb/boot_hash"
|
rm -f "/data/adb/boot_hash"
|
||||||
|
rm -f "/data/adb/tricky_store/target_from_denylist"
|
||||||
if [ -d "$TS" ]; then
|
if [ -d "$TS" ]; then
|
||||||
rm -f "$TS/action.sh"
|
[ -L "$TS/webroot" ] && rm -f "$TS/webroot"
|
||||||
rm -rf "$TS/webroot"
|
[ -L "$TS/action.sh" ] && rm -f "$TS/action.sh"
|
||||||
fi
|
fi
|
||||||
|
mv -f "$SCRIPT_DIR/keybox.xml" "$SCRIPT_DIR/keybox.xml.bak"
|
||||||
xxd -r -p "$MODPATH/common/.default" | base64 -d > "$SCRIPT_DIR/keybox.xml"
|
xxd -r -p "$MODPATH/common/.default" | base64 -d > "$SCRIPT_DIR/keybox.xml"
|
||||||
|
|||||||
@@ -5,21 +5,25 @@
|
|||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<title data-i18n="title">TrickyAddon</title>
|
<title data-i18n="title">TrickyAddon</title>
|
||||||
|
<link rel="stylesheet" type="text/css" href="/mmrl/insets.css" />
|
||||||
<link rel="stylesheet" href="styles/global.css" type="text/css">
|
<link rel="stylesheet" href="styles/global.css" type="text/css">
|
||||||
<link rel="stylesheet" href="styles/about.css" type="text/css">
|
<link rel="stylesheet" href="styles/about.css" type="text/css">
|
||||||
<link rel="stylesheet" href="styles/applist.css" type="text/css">
|
<link rel="stylesheet" href="styles/applist.css" type="text/css">
|
||||||
<link rel="stylesheet" href="styles/boot-hash.css" type="text/css">
|
<link rel="stylesheet" href="styles/boot-hash.css" type="text/css">
|
||||||
<link rel="stylesheet" href="styles/header.css" type="text/css">
|
<link rel="stylesheet" href="styles/header.css" type="text/css">
|
||||||
<link rel="stylesheet" href="styles/search_menu.css" type="text/css">
|
<link rel="stylesheet" href="styles/search_menu.css" type="text/css">
|
||||||
<link rel="stylesheet" type="text/css" href="/mmrl/insets.css" />
|
|
||||||
<script type="module" crossorigin src="scripts/main.js"></script>
|
<script type="module" crossorigin src="scripts/main.js"></script>
|
||||||
|
<script type="module" crossorigin src="scripts/about.js"></script>
|
||||||
|
<script type="module" crossorigin src="scripts/help.js"></script>
|
||||||
|
<script type="module" crossorigin src="scripts/vbmeta-digest.js"></script>
|
||||||
|
<script src="scripts/marked.min.js"></script>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<!-- Header -->
|
<!-- Header -->
|
||||||
<div class="header-block"></div>
|
<div class="header-block"></div>
|
||||||
<div class="header">
|
<div class="header">
|
||||||
<div id="title" data-i18n="header.title"></div>
|
<div id="title" data-i18n="header.title"></div><span id="module-version"></span>
|
||||||
<button id="help-button" class="help-button">
|
<button id="help-button" class="help-button">
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" height="21px" viewBox="0 -1060 960 990" width="21px" fill="#6E6E6E"><path d="M478-240q21 0 35.5-14.5T528-290q0-21-14.5-35.5T478-340q-21 0-35.5 14.5T428-290q0 21 14.5 35.5T478-240Zm-36-154h74q0-33 7.5-52t42.5-52q26-26 41-49.5t15-56.5q0-56-41-86t-97-30q-57 0-92.5 30T342-618l66 26q5-18 22.5-39t53.5-21q32 0 48 17.5t16 38.5q0 20-12 37.5T506-526q-44 39-54 59t-10 73Zm38 314q-83 0-156-31.5T197-197q-54-54-85.5-127T80-480q0-83 31.5-156T197-763q54-54 127-85.5T480-880q83 0 156 31.5T763-763q54 54 85.5 127T880-480q0 83-31.5 156T763-197q-54 54-127 85.5T480-80Zm0-80q134 0 227-93t93-227q0-134-93-227t-227-93q-134 0-227 93t-93 227q0 134 93 227t227 93Zm0-320Z" /></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" height="21px" viewBox="0 -1060 960 990" width="21px" fill="#6E6E6E"><path d="M478-240q21 0 35.5-14.5T528-290q0-21-14.5-35.5T478-340q-21 0-35.5 14.5T428-290q0 21 14.5 35.5T478-240Zm-36-154h74q0-33 7.5-52t42.5-52q26-26 41-49.5t15-56.5q0-56-41-86t-97-30q-57 0-92.5 30T342-618l66 26q5-18 22.5-39t53.5-21q32 0 48 17.5t16 38.5q0 20-12 37.5T506-526q-44 39-54 59t-10 73Zm38 314q-83 0-156-31.5T197-197q-54-54-85.5-127T80-480q0-83 31.5-156T197-763q54-54 127-85.5T480-880q83 0 156 31.5T763-763q54 54 85.5 127T880-480q0 83-31.5 156T763-197q-54 54-127 85.5T480-80Zm0-80q134 0 227-93t93-227q0-134-93-227t-227-93q-134 0-227 93t-93 227q0 134 93 227t227 93Zm0-320Z" /></svg>
|
||||||
</button>
|
</button>
|
||||||
@@ -29,7 +33,7 @@
|
|||||||
<div class="language-dropdown">
|
<div class="language-dropdown">
|
||||||
<button class="language-button">
|
<button class="language-button">
|
||||||
<i class="language-icon">
|
<i class="language-icon">
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px"><path d="M480-80q-82 0-155-31.5t-127.5-86Q143-252 111.5-325T80-480q0-83 31.5-155.5t86-127Q252-817 325-848.5T480-880q83 0 155.5 31.5t127 86q54.5 54.5 86 127T880-480q0 82-31.5 155t-86 127.5q-54.5 54.5-127 86T480-80Zm0-82q26-36 45-75t31-83H404q12 44 31 83t45 75Zm-104-16q-18-33-31.5-68.5T322-320H204q29 50 72.5 87t99.5 55Zm208 0q56-18 99.5-55t72.5-87H638q-9 38-22.5 73.5T584-178ZM170-400h136q-3-20-4.5-39.5T300-480q0-21 1.5-40.5T306-560H170q-5 20-7.5 39.5T160-480q0 21 2.5 40.5T170-400Zm216 0h188q3-20 4.5-39.5T580-480q0-21-1.5-40.5T574-560H386q-3 20-4.5 39.5T380-480q0 21 1.5 40.5T386-400Zm268 0h136q5-20 7.5-39.5T800-480q0-21-2.5-40.5T790-560H654q3 20 4.5 39.5T660-480q0 21-1.5 40.5T654-400Zm-16-240h118q-29-50-72.5-87T584-782q18 33 31.5 68.5T638-640Zm-234 0h152q-12-44-31-83t-45-75q-26 36-45 75t-31 83Zm-200 0h118q9-38 22.5-73.5T376-782q-56 18-99.5 55T204-640Z"/></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" height="22px" viewBox="0 -960 960 960" width="22px"><path d="M480-80q-82 0-155-31.5t-127.5-86Q143-252 111.5-325T80-480q0-83 31.5-155.5t86-127Q252-817 325-848.5T480-880q83 0 155.5 31.5t127 86q54.5 54.5 86 127T880-480q0 82-31.5 155t-86 127.5q-54.5 54.5-127 86T480-80Zm0-82q26-36 45-75t31-83H404q12 44 31 83t45 75Zm-104-16q-18-33-31.5-68.5T322-320H204q29 50 72.5 87t99.5 55Zm208 0q56-18 99.5-55t72.5-87H638q-9 38-22.5 73.5T584-178ZM170-400h136q-3-20-4.5-39.5T300-480q0-21 1.5-40.5T306-560H170q-5 20-7.5 39.5T160-480q0 21 2.5 40.5T170-400Zm216 0h188q3-20 4.5-39.5T580-480q0-21-1.5-40.5T574-560H386q-3 20-4.5 39.5T380-480q0 21 1.5 40.5T386-400Zm268 0h136q5-20 7.5-39.5T800-480q0-21-2.5-40.5T790-560H654q3 20 4.5 39.5T660-480q0 21-1.5 40.5T654-400Zm-16-240h118q-29-50-72.5-87T584-782q18 33 31.5 68.5T638-640Zm-234 0h152q-12-44-31-83t-45-75q-26 36-45 75t-31 83Zm-200 0h118q9-38 22.5-73.5T376-782q-56 18-99.5 55T204-640Z"/></svg>
|
||||||
</i>
|
</i>
|
||||||
</button>
|
</button>
|
||||||
<div class="language-menu"></div>
|
<div class="language-menu"></div>
|
||||||
@@ -59,7 +63,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="menu">
|
<div class="menu">
|
||||||
<input type="checkbox" id="menu-toggle" class="menu-toggle">
|
<input type="checkbox" id="menu-toggle" class="menu-toggle">
|
||||||
<label for="menu-toggle" id="menu-button">
|
<label for="menu-toggle" class="menu-button" id="menu-button">
|
||||||
<i class="menu-icon">
|
<i class="menu-icon">
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -1060 960 960" width="24px"><path d="M120-240v-80h720v80H120Zm0-200v-80h720v80H120Zm0-200v-80h720v80H120Z"/></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -1060 960 960" width="24px"><path d="M120-240v-80h720v80H120Zm0-200v-80h720v80H120Zm0-200v-80h720v80H120Z"/></svg>
|
||||||
</i>
|
</i>
|
||||||
@@ -84,15 +88,49 @@
|
|||||||
<!-- Applist Display -->
|
<!-- Applist Display -->
|
||||||
<div id="apps-list"></div>
|
<div id="apps-list"></div>
|
||||||
<div class="update-card" id="update-card">
|
<div class="update-card" id="update-card">
|
||||||
<p id="update-available" data-i18n="update_banner.update_available"></p>
|
<p id="update-available" data-i18n="update.update_available"></p>
|
||||||
<p id="redirect-to-release" data-i18n="update_banner.redirect_to_release"></p>
|
<p id="redirect-to-release" data-i18n="update.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">
|
<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="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>
|
||||||
|
<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>
|
||||||
|
</div>
|
||||||
<p class="name"></p>
|
<p class="name"></p>
|
||||||
<input type="checkbox" class="checkbox">
|
<div class="checkbox-wrapper">
|
||||||
|
<input type="checkbox" class="checkbox" id="checkbox1" disabled />
|
||||||
|
<label for="checkbox1" class="custom-checkbox">
|
||||||
|
<span class="tick-symbol">
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 -3 26 26" width="16px" height="16px" fill="#fff"><path d="M 22.566406 4.730469 L 20.773438 3.511719 C 20.277344 3.175781 19.597656 3.304688 19.265625 3.796875 L 10.476563 16.757813 L 6.4375 12.71875 C 6.015625 12.296875 5.328125 12.296875 4.90625 12.71875 L 3.371094 14.253906 C 2.949219 14.675781 2.949219 15.363281 3.371094 15.789063 L 9.582031 22 C 9.929688 22.347656 10.476563 22.613281 10.96875 22.613281 C 11.460938 22.613281 11.957031 22.304688 12.277344 21.839844 L 22.855469 6.234375 C 23.191406 5.742188 23.0625 5.066406 22.566406 4.730469 Z"/></svg>
|
||||||
|
</span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -162,7 +200,9 @@
|
|||||||
<!-- BootHash Input Overlay -->
|
<!-- BootHash Input Overlay -->
|
||||||
<div id="boot-hash-overlay" class="boot-hash-overlay"></div>
|
<div id="boot-hash-overlay" class="boot-hash-overlay"></div>
|
||||||
<div id="boot-hash-card" class="boot-hash-card">
|
<div id="boot-hash-card" class="boot-hash-card">
|
||||||
<textarea id="boot-hash-input" class="input-box" placeholder="Paste your verified Boot Hash here" data-i18n="reset_vbmeta.boot_hash_input_placeholder"></textarea>
|
<div class="boot-hash-value">
|
||||||
|
<textarea id="boot-hash-input" class="input-box" placeholder="Paste your verified Boot Hash here" data-i18n="reset_vbmeta.boot_hash_input_placeholder"></textarea>
|
||||||
|
</div>
|
||||||
<div class="button-container">
|
<div class="button-container">
|
||||||
<button id="boot-hash-save-button" class="boot-hash-save-button" data-i18n="reset_vbmeta.boot_hash_save_button"></button>
|
<button id="boot-hash-save-button" class="boot-hash-save-button" data-i18n="reset_vbmeta.boot_hash_save_button"></button>
|
||||||
</div>
|
</div>
|
||||||
@@ -194,6 +234,22 @@
|
|||||||
<br>
|
<br>
|
||||||
<p id="acknowledgment" data-i18n="about.acknowledgment"></p>
|
<p id="acknowledgment" data-i18n="about.acknowledgment"></p>
|
||||||
<p>j-hc/zygisk-detach: WebUI template</p>
|
<p>j-hc/zygisk-detach: WebUI template</p>
|
||||||
|
<p>markedjs/marked: Markdown Support</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Update Overlay -->
|
||||||
|
<div class="update-overlay">
|
||||||
|
<div class="update-menu">
|
||||||
|
<button class="close-update">✕</button>
|
||||||
|
<div class="update-content">
|
||||||
|
<h1 data-i18n="update.changelog"></h1>
|
||||||
|
<div class="changelog"></div>
|
||||||
|
<div class="update-button-container">
|
||||||
|
<button class="install" data-i18n="update.install"></button>
|
||||||
|
<button class="reboot" data-i18n="update.reboot"></button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"language": "English",
|
"language": "English",
|
||||||
"header": {
|
"header": {
|
||||||
"title": "Tricky Addon - Update Target List"
|
"title": "Tricky Addon"
|
||||||
},
|
},
|
||||||
"help": {
|
"help": {
|
||||||
"help_instructions": "Instructions",
|
"help_instructions": "Instructions",
|
||||||
@@ -14,15 +14,18 @@
|
|||||||
"select_denylist": "Select From DenyList",
|
"select_denylist": "Select From DenyList",
|
||||||
"select_denylist_description": "Available in Magisk only, select apps that are in the DenyList. Recommended.",
|
"select_denylist_description": "Available in Magisk only, select apps that are in the DenyList. Recommended.",
|
||||||
"deselect_unnecessary": "Deselect Unnecessary",
|
"deselect_unnecessary": "Deselect Unnecessary",
|
||||||
"deselect_unnecessary_description": "Unnecessary category: Xposed module, root manager, root-related apps, and general apps that never check bootloader status. This option requires an Internet connection.",
|
"deselect_unnecessary_description": "Unnecessary category: Xposed module, root manager, root-related apps, and general apps that never check bootloader status. This option requires Internet connection.",
|
||||||
"set_keybox": "Set AOSP & Valid Keybox",
|
"set_keybox": "Set AOSP & Valid Keybox",
|
||||||
"set_keybox_description": "Replace tricky store keybox.xml. AOSP keybox will be replaced if there's no more valid keybox. Valid keybox option requires Internet connection.",
|
"set_keybox_description": "Replace tricky store keybox.xml. AOSP keybox will be replaced if there's no more valid keybox. Valid keybox option requires Internet connection.",
|
||||||
"set_verified_boot_hash": "Set Verified Boot Hash",
|
"set_verified_boot_hash": "Set Verified Boot Hash",
|
||||||
"set_verified_boot_hash_description": "Get verifiedBootHash value from Key Attestation Demo. Fix abnormal boot state by resetting ro.boot.vbmeta.digest."
|
"set_verified_boot_hash_description": "Get verifiedBootHash value from Key Attestation Demo. Fix abnormal boot state by resetting ro.boot.vbmeta.digest."
|
||||||
},
|
},
|
||||||
"update_banner": {
|
"update": {
|
||||||
"update_available": "A new version is ready",
|
"update_available": "A new version is ready",
|
||||||
"redirect_to_release": "tap to download the latest version"
|
"redirect_to_release": "tap to download the latest version",
|
||||||
|
"changelog": "Changelog",
|
||||||
|
"install": "Install",
|
||||||
|
"reboot": "Reboot"
|
||||||
},
|
},
|
||||||
"search_bar": {
|
"search_bar": {
|
||||||
"search_placeholder": "Search"
|
"search_placeholder": "Search"
|
||||||
@@ -70,6 +73,14 @@
|
|||||||
"save_error": "Failed to save config",
|
"save_error": "Failed to save config",
|
||||||
"uninstall_prompt": "WebUI will be removed after reboot",
|
"uninstall_prompt": "WebUI will be removed after reboot",
|
||||||
"uninstall_failed": "Failed to uninstall WebUI",
|
"uninstall_failed": "Failed to uninstall WebUI",
|
||||||
"new_update": "A new update is available!"
|
"new_update": "A new update is available!",
|
||||||
|
"downloading": "Downloading new update...",
|
||||||
|
"downloaded": "Download completed",
|
||||||
|
"download_fail": "Fail to download update",
|
||||||
|
"installing": "Installing update...",
|
||||||
|
"installed": "Installed successfully, reboot now.",
|
||||||
|
"install_fail": "Fail to install, please update manual",
|
||||||
|
"rebooting": "Rebooting...",
|
||||||
|
"reboot_fail": "Fail to reboot, please reboot manually"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"language": "English",
|
"language": "English",
|
||||||
"header": {
|
"header": {
|
||||||
"title": "Tricky Addon - Update Target List"
|
"title": "Tricky Addon"
|
||||||
},
|
},
|
||||||
"help": {
|
"help": {
|
||||||
"help_instructions": "Instructions",
|
"help_instructions": "Instructions",
|
||||||
@@ -14,15 +14,18 @@
|
|||||||
"select_denylist": "Select From DenyList",
|
"select_denylist": "Select From DenyList",
|
||||||
"select_denylist_description": "Available in Magisk only, select apps that are in the DenyList. Recommended.",
|
"select_denylist_description": "Available in Magisk only, select apps that are in the DenyList. Recommended.",
|
||||||
"deselect_unnecessary": "Deselect Unnecessary",
|
"deselect_unnecessary": "Deselect Unnecessary",
|
||||||
"deselect_unnecessary_description": "Unnecessary category: Xposed module, root manager, root-related apps, and general apps that never check bootloader status. This option requires an Internet connection.",
|
"deselect_unnecessary_description": "Unnecessary category: Xposed module, root manager, root-related apps, and general apps that never check bootloader status. This option requires Internet connection.",
|
||||||
"set_keybox": "Set AOSP & Valid Keybox",
|
"set_keybox": "Set AOSP & Valid Keybox",
|
||||||
"set_keybox_description": "Replace tricky store keybox.xml. AOSP keybox will be replaced if there's no more valid keybox. Valid keybox option requires Internet connection.",
|
"set_keybox_description": "Replace tricky store keybox.xml. AOSP keybox will be replaced if there's no more valid keybox. Valid keybox option requires Internet connection.",
|
||||||
"set_verified_boot_hash": "Set Verified Boot Hash",
|
"set_verified_boot_hash": "Set Verified Boot Hash",
|
||||||
"set_verified_boot_hash_description": "Get verifiedBootHash value from Key Attestation Demo. Fix abnormal boot state by resetting ro.boot.vbmeta.digest."
|
"set_verified_boot_hash_description": "Get verifiedBootHash value from Key Attestation Demo. Fix abnormal boot state by resetting ro.boot.vbmeta.digest."
|
||||||
},
|
},
|
||||||
"update_banner": {
|
"update": {
|
||||||
"update_available": "A new version is ready",
|
"update_available": "A new version is ready",
|
||||||
"redirect_to_release": "tap to download the latest version"
|
"redirect_to_release": "tap to download the latest version",
|
||||||
|
"changelog": "Changelog",
|
||||||
|
"install": "Install",
|
||||||
|
"reboot": "Reboot"
|
||||||
},
|
},
|
||||||
"search_bar": {
|
"search_bar": {
|
||||||
"search_placeholder": "Search"
|
"search_placeholder": "Search"
|
||||||
@@ -70,6 +73,14 @@
|
|||||||
"save_error": "Failed to save config",
|
"save_error": "Failed to save config",
|
||||||
"uninstall_prompt": "WebUI will be removed after reboot",
|
"uninstall_prompt": "WebUI will be removed after reboot",
|
||||||
"uninstall_failed": "Failed to uninstall WebUI",
|
"uninstall_failed": "Failed to uninstall WebUI",
|
||||||
"new_update": "A new update is available!"
|
"new_update": "A new update is available!",
|
||||||
|
"downloading": "Downloading new update...",
|
||||||
|
"downloaded": "Download completed",
|
||||||
|
"download_fail": "Fail to download update",
|
||||||
|
"installing": "Installing update...",
|
||||||
|
"installed": "Installed successfully, reboot now.",
|
||||||
|
"install_fail": "Fail to install, please update manual",
|
||||||
|
"rebooting": "Rebooting...",
|
||||||
|
"reboot_fail": "Fail to reboot, please reboot manually"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"language": "Español",
|
"language": "Español",
|
||||||
"header": {
|
"header": {
|
||||||
"title": "Tricky Addon - Update Target List"
|
"title": "Tricky Addon"
|
||||||
},
|
},
|
||||||
"help": {
|
"help": {
|
||||||
"help_instructions": "Instrucciones",
|
"help_instructions": "Instrucciones",
|
||||||
@@ -20,9 +20,12 @@
|
|||||||
"set_verified_boot_hash": "Configurar Boot Hash Verificado",
|
"set_verified_boot_hash": "Configurar Boot Hash Verificado",
|
||||||
"set_verified_boot_hash_description": "Obtén el valor de verifiedBootHash del Key Attestation Demo. Corrige un estado de arranque anormal reiniciando ro.boot.vbmeta.digest."
|
"set_verified_boot_hash_description": "Obtén el valor de verifiedBootHash del Key Attestation Demo. Corrige un estado de arranque anormal reiniciando ro.boot.vbmeta.digest."
|
||||||
},
|
},
|
||||||
"update_banner": {
|
"update": {
|
||||||
"update_available": "Una nueva versión está lista",
|
"update_available": "Una nueva versión está lista",
|
||||||
"redirect_to_release": "toca para descargar la última versión"
|
"redirect_to_release": "toca para descargar la última versión",
|
||||||
|
"changelog": "Registro de cambios",
|
||||||
|
"install": "Instalar",
|
||||||
|
"reboot": "Reiniciar"
|
||||||
},
|
},
|
||||||
"search_bar": {
|
"search_bar": {
|
||||||
"search_placeholder": "Buscar"
|
"search_placeholder": "Buscar"
|
||||||
@@ -70,6 +73,14 @@
|
|||||||
"save_error": "Error al guardar la configuración",
|
"save_error": "Error al guardar la configuración",
|
||||||
"uninstall_prompt": "El WebUI se eliminará después de reiniciar",
|
"uninstall_prompt": "El WebUI se eliminará después de reiniciar",
|
||||||
"uninstall_failed": "Error al desinstalar el WebUI",
|
"uninstall_failed": "Error al desinstalar el WebUI",
|
||||||
"new_update": "¡Una nueva actualización está disponible!"
|
"new_update": "¡Una nueva actualización está disponible!",
|
||||||
|
"downloading": "Descargando nueva actualización...",
|
||||||
|
"downloaded": "Descarga completada",
|
||||||
|
"download_fail": "Error al descargar la actualización",
|
||||||
|
"installing": "Instalando actualización...",
|
||||||
|
"installed": "Instalado con éxito, reinicia ahora.",
|
||||||
|
"install_fail": "Error al instalar, actualiza manualmente",
|
||||||
|
"rebooting": "Reiniciando...",
|
||||||
|
"reboot_fail": "Error al reiniciar, reinicia manualmente"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"language": "日本語",
|
"language": "日本語",
|
||||||
"header": {
|
"header": {
|
||||||
"title": "Tricky Addon - Update Target List"
|
"title": "Tricky Addon"
|
||||||
},
|
},
|
||||||
"help": {
|
"help": {
|
||||||
"help_instructions": "使い方",
|
"help_instructions": "使い方",
|
||||||
@@ -20,9 +20,12 @@
|
|||||||
"set_verified_boot_hash": "確認付きブートハッシュを設定",
|
"set_verified_boot_hash": "確認付きブートハッシュを設定",
|
||||||
"set_verified_boot_hash_description": "Key Attestation Demo から確認付きブートハッシュの値を取得します。ro.boot.vbmeta.digest をリセットして異常なブート状態を修正します。"
|
"set_verified_boot_hash_description": "Key Attestation Demo から確認付きブートハッシュの値を取得します。ro.boot.vbmeta.digest をリセットして異常なブート状態を修正します。"
|
||||||
},
|
},
|
||||||
"update_banner": {
|
"update": {
|
||||||
"update_available": "新しいバージョンの準備完了",
|
"update_available": "新しいバージョンの準備完了",
|
||||||
"redirect_to_release": "タップで最新のバージョンをダウンロード"
|
"redirect_to_release": "タップで最新のバージョンをダウンロード",
|
||||||
|
"changelog": "変更履歴",
|
||||||
|
"install": "インストール",
|
||||||
|
"reboot": "再起動"
|
||||||
},
|
},
|
||||||
"search_bar": {
|
"search_bar": {
|
||||||
"search_placeholder": "検索"
|
"search_placeholder": "検索"
|
||||||
@@ -51,7 +54,7 @@
|
|||||||
},
|
},
|
||||||
"about": {
|
"about": {
|
||||||
"module_name_line1": "Tricky Addon",
|
"module_name_line1": "Tricky Addon",
|
||||||
"module_name_line2": "Update Target List",
|
"module_name_line2": "ターゲットリストを更新",
|
||||||
"by": "開発者: ",
|
"by": "開発者: ",
|
||||||
"telegram_channel": "Telegram チャンネル",
|
"telegram_channel": "Telegram チャンネル",
|
||||||
"github": "GitHub",
|
"github": "GitHub",
|
||||||
@@ -70,6 +73,14 @@
|
|||||||
"save_error": "設定の保存に失敗しました。",
|
"save_error": "設定の保存に失敗しました。",
|
||||||
"uninstall_prompt": "WebUI は再起動後に削除されます。",
|
"uninstall_prompt": "WebUI は再起動後に削除されます。",
|
||||||
"uninstall_failed": "WebUI のアンインストールに失敗しました。",
|
"uninstall_failed": "WebUI のアンインストールに失敗しました。",
|
||||||
"new_update": "新しいバージョンがあります!"
|
"new_update": "新しいバージョンがあります!",
|
||||||
|
"downloading": "新しい更新をダウンロード中...",
|
||||||
|
"downloaded": "ダウンロードが完了しました",
|
||||||
|
"download_fail": "更新のダウンロードに失敗しました",
|
||||||
|
"installing": "更新をインストール中...",
|
||||||
|
"installed": "正常にインストールされました。再起動してください。",
|
||||||
|
"install_fail": "インストールに失敗しました。手動で更新してください。",
|
||||||
|
"rebooting": "再起動中...",
|
||||||
|
"reboot_fail": "再起動に失敗しました。手動で再起動してください。"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"language": "Русский",
|
"language": "Русский",
|
||||||
"header": {
|
"header": {
|
||||||
"title": "Tricky Addon - Обновить список целей"
|
"title": "Tricky Addon"
|
||||||
},
|
},
|
||||||
"help": {
|
"help": {
|
||||||
"help_instructions": "Инструкции",
|
"help_instructions": "Инструкции",
|
||||||
@@ -20,9 +20,12 @@
|
|||||||
"set_verified_boot_hash": "Установить Verified Boot Hash",
|
"set_verified_boot_hash": "Установить Verified Boot Hash",
|
||||||
"set_verified_boot_hash_description": "Получите значение verifiedBootHash из Key Attestation Demo. Исправьте аномальное состояние загрузки, сбросив ro.boot.vbmeta.digest."
|
"set_verified_boot_hash_description": "Получите значение verifiedBootHash из Key Attestation Demo. Исправьте аномальное состояние загрузки, сбросив ro.boot.vbmeta.digest."
|
||||||
},
|
},
|
||||||
"update_banner": {
|
"update": {
|
||||||
"update_available": "Доступна новая версия",
|
"update_available": "Доступна новая версия",
|
||||||
"redirect_to_release": "нажмите, чтобы скачать последнюю версию"
|
"redirect_to_release": "нажмите, чтобы скачать последнюю версию",
|
||||||
|
"changelog": "Список изменений",
|
||||||
|
"install": "Установить",
|
||||||
|
"reboot": "Перезагрузить"
|
||||||
},
|
},
|
||||||
"search_bar": {
|
"search_bar": {
|
||||||
"search_placeholder": "Поиск"
|
"search_placeholder": "Поиск"
|
||||||
@@ -70,6 +73,14 @@
|
|||||||
"save_error": "Не удалось сохранить конфигурацию",
|
"save_error": "Не удалось сохранить конфигурацию",
|
||||||
"uninstall_prompt": "WebUI будет удален после перезагрузки",
|
"uninstall_prompt": "WebUI будет удален после перезагрузки",
|
||||||
"uninstall_failed": "Не удалось удалить WebUI",
|
"uninstall_failed": "Не удалось удалить WebUI",
|
||||||
"new_update": "Доступно новое обновление!"
|
"new_update": "Доступно новое обновление!",
|
||||||
|
"downloading": "Загрузка нового обновления...",
|
||||||
|
"downloaded": "Загрузка завершена",
|
||||||
|
"download_fail": "Не удалось загрузить обновление",
|
||||||
|
"installing": "Установка обновления...",
|
||||||
|
"installed": "Успешно установлено, перезагрузите устройство.",
|
||||||
|
"install_fail": "Не удалось установить, обновите вручную",
|
||||||
|
"rebooting": "Перезагрузка...",
|
||||||
|
"reboot_fail": "Не удалось перезагрузить, перезагрузите вручную"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"language": "Tagalog",
|
"language": "Tagalog",
|
||||||
"header": {
|
"header": {
|
||||||
"title": "Tricky Addon - I-update ang Target List"
|
"title": "Tricky Addon"
|
||||||
},
|
},
|
||||||
"help": {
|
"help": {
|
||||||
"help_instructions": "Mga Tagubilin",
|
"help_instructions": "Mga Tagubilin",
|
||||||
@@ -20,9 +20,12 @@
|
|||||||
"set_verified_boot_hash": "I-set ang Verified Boot Hash",
|
"set_verified_boot_hash": "I-set ang Verified Boot Hash",
|
||||||
"set_verified_boot_hash_description": "Kunin ang verifiedBootHash mula sa Key Attestation Demo. Ayusin ang abnormal na boot state sa pamamagitan ng pag-reset ng ro.boot.vbmeta.digest."
|
"set_verified_boot_hash_description": "Kunin ang verifiedBootHash mula sa Key Attestation Demo. Ayusin ang abnormal na boot state sa pamamagitan ng pag-reset ng ro.boot.vbmeta.digest."
|
||||||
},
|
},
|
||||||
"update_banner": {
|
"update": {
|
||||||
"update_available": "Handa na ang bagong bersyon",
|
"update_available": "Handa na ang bagong bersyon",
|
||||||
"redirect_to_release": "i-tap para i-download ang pinakabagong bersyon"
|
"redirect_to_release": "i-tap para i-download ang pinakabagong bersyon",
|
||||||
|
"changelog": "Mga Pagbabago",
|
||||||
|
"install": "I-install",
|
||||||
|
"reboot": "I-reboot"
|
||||||
},
|
},
|
||||||
"search_bar": {
|
"search_bar": {
|
||||||
"search_placeholder": "Maghanap"
|
"search_placeholder": "Maghanap"
|
||||||
@@ -70,6 +73,14 @@
|
|||||||
"save_error": "Nabigong i-save ang config",
|
"save_error": "Nabigong i-save ang config",
|
||||||
"uninstall_prompt": "Mawawala ang WebUI pagkatapos ng reboot",
|
"uninstall_prompt": "Mawawala ang WebUI pagkatapos ng reboot",
|
||||||
"uninstall_failed": "Nabigong i-uninstall ang WebUI",
|
"uninstall_failed": "Nabigong i-uninstall ang WebUI",
|
||||||
"new_update": "May bagong update na available!"
|
"new_update": "May bagong update na available!",
|
||||||
|
"downloading": "Nagda-download ng bagong update...",
|
||||||
|
"downloaded": "Natapos ang pag-download",
|
||||||
|
"download_fail": "Nabigo ang pag-download ng update",
|
||||||
|
"installing": "Nag-i-install ng update...",
|
||||||
|
"installed": "Matagumpay na na-install, mag-reboot na ngayon.",
|
||||||
|
"install_fail": "Nabigo ang pag-install, pakisubukang mag-update nang manu-mano",
|
||||||
|
"rebooting": "Nag-re-reboot...",
|
||||||
|
"reboot_fail": "Nabigo ang pag-reboot, pakisubukang mag-reboot nang manu-mano"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
86
module/webui/locales/tr-TR.json
Normal file
86
module/webui/locales/tr-TR.json
Normal file
@@ -0,0 +1,86 @@
|
|||||||
|
{
|
||||||
|
"language": "Türkçe",
|
||||||
|
"header": {
|
||||||
|
"title": "Tricky Addon"
|
||||||
|
},
|
||||||
|
"help": {
|
||||||
|
"help_instructions": "Talimatlar",
|
||||||
|
"save_and_update": "Kaydet",
|
||||||
|
"save_and_update_description": "Mevcut yapılandırmayı target.txt dosyasına kaydet.",
|
||||||
|
"refresh": "Yenile",
|
||||||
|
"refresh_description": "Uygulama ve hariç tutma listesini yenile.",
|
||||||
|
"select_deselect": "Tümünü Seç & Seçimi Kaldır",
|
||||||
|
"select_description": "Mevcut arayüzdeki tüm uygulamaları seç veya seçimini kaldır.",
|
||||||
|
"select_denylist": "Reddetme Listesinden Seç",
|
||||||
|
"select_denylist_description": "Yalnızca Magisk’te mevcut, Reddetme Listesindeki uygulamaları seç. Tavsiye edilir.",
|
||||||
|
"deselect_unnecessary": "Gereksizleri Seçme",
|
||||||
|
"deselect_unnecessary_description": "Gereksiz kategori: Xposed modülü, root yöneticisi, root ile ilgili uygulamalar ve asla bootloader durumunu kontrol etmeyen genel uygulamalar. Bu seçenek internet bağlantısı gerektirir.",
|
||||||
|
"set_keybox": "AOSP & Geçerli Keybox Ayarla",
|
||||||
|
"set_keybox_description": "Tricky Store'daki keybox.xml dosyasını değiştirir. Eğer geçerli bir keybox yoksa AOSP keybox ile değiştirilecektir. Geçerli keybox seçeneği internet bağlantısı gerektirir.",
|
||||||
|
"set_verified_boot_hash": "Doğrulanmış Boot Hash Ayarla",
|
||||||
|
"set_verified_boot_hash_description": "Key Attestation Demo’dan verifiedBootHash değerini alın. Abnormal boot durumunu ro.boot.vbmeta.digest’i sıfırlayarak düzeltin."
|
||||||
|
},
|
||||||
|
"update": {
|
||||||
|
"update_available": "Yeni bir sürüm hazır",
|
||||||
|
"redirect_to_release": "Son sürümü indirmek için dokunun",
|
||||||
|
"changelog": "Değişiklik Günlüğü",
|
||||||
|
"install": "Yükle",
|
||||||
|
"reboot": "Yeniden Başlat"
|
||||||
|
},
|
||||||
|
"search_bar": {
|
||||||
|
"search_placeholder": "Ara"
|
||||||
|
},
|
||||||
|
"functional_button": {
|
||||||
|
"save_and_update_button": "Kaydet",
|
||||||
|
"uninstall_webui": "WebUI’ı Kaldır"
|
||||||
|
},
|
||||||
|
"loading": {
|
||||||
|
"loading": "Yükleniyor..."
|
||||||
|
},
|
||||||
|
"menu": {
|
||||||
|
"refresh": "Yenile",
|
||||||
|
"select_all": "Tümünü Seç",
|
||||||
|
"deselect_all": "Tüm Seçimleri Kaldır",
|
||||||
|
"select_denylist": "Reddetme Listesinden Seç",
|
||||||
|
"deselect_unnecessary": "Gereksizleri Seçme",
|
||||||
|
"set_aosp_keybox": "AOSP Keybox Ayarla",
|
||||||
|
"set_valid_keybox": "Geçerli Keybox Ayarla",
|
||||||
|
"set_verified_boot_hash": "Doğrulanmış Boot Hash Ayarla",
|
||||||
|
"about": "Hakkında"
|
||||||
|
},
|
||||||
|
"reset_vbmeta": {
|
||||||
|
"boot_hash_input_placeholder": "Doğrulanmış Boot Hash’inizi buraya yapıştırın",
|
||||||
|
"boot_hash_save_button": "Kaydet"
|
||||||
|
},
|
||||||
|
"about": {
|
||||||
|
"module_name_line1": "Tricky Addon",
|
||||||
|
"module_name_line2": "Target List'i Güncelle",
|
||||||
|
"by": "tarafından",
|
||||||
|
"telegram_channel": "Telegram Kanalı",
|
||||||
|
"github": "GitHub",
|
||||||
|
"disclaimer": "Bu modül, Tricky Store modülünün bir parçası değildir. Herhangi bir sorun yaşarsanız, lütfen bunu Tricky Store’a rapor etmeyin.",
|
||||||
|
"acknowledgment": "Teşekkür"
|
||||||
|
},
|
||||||
|
"prompt": {
|
||||||
|
"no_internet": "Lütfen internet bağlantınızı kontrol edin",
|
||||||
|
"aosp_key_set": "AOSP keybox başarıyla ayarlandı",
|
||||||
|
"key_set_error": "Keybox güncellenemedi",
|
||||||
|
"valid_key_set": "Geçerli keybox başarıyla ayarlandı",
|
||||||
|
"no_valid_fallback": "Geçerli keybox bulunamadı, AOSP keybox ile değiştirildi.",
|
||||||
|
"boot_hash_set": "Doğrulanmış Boot Hash başarıyla kaydedildi",
|
||||||
|
"boot_hash_set_error": "Doğrulanmış Boot Hash güncellenemedi",
|
||||||
|
"saved_target": "Yapılandırma target.txt dosyasına kaydedildi",
|
||||||
|
"save_error": "Yapılandırma kaydedilemedi",
|
||||||
|
"uninstall_prompt": "WebUI yeniden başlatma sonrasında kaldırılacak",
|
||||||
|
"uninstall_failed": "WebUI kaldırılamadı",
|
||||||
|
"new_update": "Yeni bir güncelleme mevcut!",
|
||||||
|
"downloading": "Yeni güncelleme indiriliyor...",
|
||||||
|
"downloaded": "İndirme tamamlandı",
|
||||||
|
"download_fail": "Güncelleme indirilemedi",
|
||||||
|
"installing": "Güncelleme yükleniyor...",
|
||||||
|
"installed": "Başarıyla yüklendi, şimdi yeniden başlatın.",
|
||||||
|
"install_fail": "Yükleme başarısız oldu, lütfen manuel olarak güncelleyin",
|
||||||
|
"rebooting": "Yeniden başlatılıyor...",
|
||||||
|
"reboot_fail": "Yeniden başlatma başarısız, lütfen manuel olarak yeniden başlatın"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"language": "中文(简体)",
|
"language": "简体中文",
|
||||||
"header": {
|
"header": {
|
||||||
"title": "TS插件 - 更新目标列表"
|
"title": "TS 插件"
|
||||||
},
|
},
|
||||||
"help": {
|
"help": {
|
||||||
"help_instructions": "使用指南",
|
"help_instructions": "使用指南",
|
||||||
@@ -20,9 +20,12 @@
|
|||||||
"set_verified_boot_hash": "设置哈希值",
|
"set_verified_boot_hash": "设置哈希值",
|
||||||
"set_verified_boot_hash_description": "从 Key Attestation Demo 获取 verifiedBootHash(哈希值)。通过重置 ro.boot.vbmeta.digest 修复异常 boot 状态。"
|
"set_verified_boot_hash_description": "从 Key Attestation Demo 获取 verifiedBootHash(哈希值)。通过重置 ro.boot.vbmeta.digest 修复异常 boot 状态。"
|
||||||
},
|
},
|
||||||
"update_banner": {
|
"update": {
|
||||||
"update_available": "发现新的版本",
|
"update_available": "发现新的版本",
|
||||||
"redirect_to_release": "点击跳转 GitHub 下载最新版本"
|
"redirect_to_release": "点击下载最新版本",
|
||||||
|
"changelog": "更新日志",
|
||||||
|
"install": "安装",
|
||||||
|
"reboot": "重启"
|
||||||
},
|
},
|
||||||
"search_bar": {
|
"search_bar": {
|
||||||
"search_placeholder": "搜索"
|
"search_placeholder": "搜索"
|
||||||
@@ -70,6 +73,14 @@
|
|||||||
"save_error": "保存配置失败",
|
"save_error": "保存配置失败",
|
||||||
"uninstall_prompt": "WebUI 将在重启后被移除",
|
"uninstall_prompt": "WebUI 将在重启后被移除",
|
||||||
"uninstall_failed": "卸载 WebUI 失败",
|
"uninstall_failed": "卸载 WebUI 失败",
|
||||||
"new_update": "发现新的版本!"
|
"new_update": "发现新的版本!",
|
||||||
|
"downloading": "正在下载...",
|
||||||
|
"downloaded": "下载完成",
|
||||||
|
"download_fail": "下载失败",
|
||||||
|
"installing": "正常安装...",
|
||||||
|
"installed": "安装完成,重启生效",
|
||||||
|
"install_fail": "安装失败,请手动更新",
|
||||||
|
"rebooting": "正在重启...",
|
||||||
|
"reboot_fail": "重启失败,请手动重启"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"language": "中文(繁体)",
|
"language": "繁體中文",
|
||||||
"header": {
|
"header": {
|
||||||
"title": "TS插件 - 更新目標列表"
|
"title": "TS 插件"
|
||||||
},
|
},
|
||||||
"help": {
|
"help": {
|
||||||
"help_instructions": "使用指南",
|
"help_instructions": "使用指南",
|
||||||
@@ -13,19 +13,22 @@
|
|||||||
"select_description": "選擇或取消選擇當前界面中的所有應用。",
|
"select_description": "選擇或取消選擇當前界面中的所有應用。",
|
||||||
"select_denylist": "從排除列表中選擇",
|
"select_denylist": "從排除列表中選擇",
|
||||||
"select_denylist_description": "僅適用於 Magisk,選擇在排除列表中的應用。推薦使用。",
|
"select_denylist_description": "僅適用於 Magisk,選擇在排除列表中的應用。推薦使用。",
|
||||||
"deselect_unnecessary": "取消選擇非必應用",
|
"deselect_unnecessary": "取消選擇非必要應用",
|
||||||
"deselect_unnecessary_description": "非必要分類:Xposed 模塊、root 管理器、與 root 相關的應用,以及從不檢查 bootloader 狀態的通用應用。此功能需連網使用。",
|
"deselect_unnecessary_description": "非必要分類:Xposed 模組、root 管理器、與 root 相關的應用,以及從不檢查 bootloader 狀態的通用應用。此功能需連網使用。",
|
||||||
"set_keybox": "設置 AOSP & 有效密鑰",
|
"set_keybox": "設置 AOSP & 有效密鑰",
|
||||||
"set_keybox_description": "替換 Tricky Store 的密鑰(keybox.xml)。如果沒有有效密鑰,將替換為 AOSP 密鑰。有效密鑰選項需連網使用。",
|
"set_keybox_description": "替換 Tricky Store 的密鑰(keybox.xml)。如果沒有有效密鑰,將替換為 AOSP 密鑰。有效密鑰選項需連網使用。",
|
||||||
"set_verified_boot_hash": "設置哈希值",
|
"set_verified_boot_hash": "設置哈希值",
|
||||||
"set_verified_boot_hash_description": "從 Key Attestation Demo 獲取 verifiedBootHash(哈希值)。通過重置 ro.boot.vbmeta.digest 修復異常 boot 狀態。"
|
"set_verified_boot_hash_description": "從 Key Attestation Demo 獲取 verifiedBootHash(哈希值)。通過重置 ro.boot.vbmeta.digest 修復異常 boot 狀態。"
|
||||||
},
|
},
|
||||||
"update_banner": {
|
"update": {
|
||||||
"update_available": "發現新的版本",
|
"update_available": "發現新版本",
|
||||||
"redirect_to_release": "點擊跳轉至 GitHub 下載最新版本"
|
"redirect_to_release": "點擊下載最新版本",
|
||||||
|
"changelog": "更新日誌",
|
||||||
|
"install": "安裝",
|
||||||
|
"reboot": "重啟"
|
||||||
},
|
},
|
||||||
"search_bar": {
|
"search_bar": {
|
||||||
"search_placeholder": "搜尋"
|
"search_placeholder": "搜索"
|
||||||
},
|
},
|
||||||
"functional_button": {
|
"functional_button": {
|
||||||
"save_and_update_button": "保存",
|
"save_and_update_button": "保存",
|
||||||
@@ -39,27 +42,27 @@
|
|||||||
"select_all": "全選",
|
"select_all": "全選",
|
||||||
"deselect_all": "取消全選",
|
"deselect_all": "取消全選",
|
||||||
"select_denylist": "從排除列表中選擇",
|
"select_denylist": "從排除列表中選擇",
|
||||||
"deselect_unnecessary": "取消選擇非必應用",
|
"deselect_unnecessary": "取消選擇非必要應用",
|
||||||
"set_aosp_keybox": "設置 AOSP 密鑰",
|
"set_aosp_keybox": "設置 AOSP 密鑰",
|
||||||
"set_valid_keybox": "設置有效密鑰",
|
"set_valid_keybox": "設置有效密鑰",
|
||||||
"set_verified_boot_hash": "設置哈希值",
|
"set_verified_boot_hash": "設置哈希值",
|
||||||
"about": "關於"
|
"about": "關於"
|
||||||
},
|
},
|
||||||
"reset_vbmeta": {
|
"reset_vbmeta": {
|
||||||
"boot_hash_input_placeholder": "在此粘貼您的哈希值",
|
"boot_hash_input_placeholder": "在此貼上您的哈希值",
|
||||||
"boot_hash_save_button": "保存"
|
"boot_hash_save_button": "保存"
|
||||||
},
|
},
|
||||||
"about": {
|
"about": {
|
||||||
"module_name_line1": "TS插件",
|
"module_name_line1": "TS 插件",
|
||||||
"module_name_line2": "更新目標列表",
|
"module_name_line2": "更新目標列表",
|
||||||
"by": "作者:",
|
"by": "作者:",
|
||||||
"telegram_channel": "TG頻道",
|
"telegram_channel": "Telegram 頻道",
|
||||||
"github": "GitHub",
|
"github": "GitHub",
|
||||||
"disclaimer": "此 WebUI 不是 Tricky Store 的一部分,遇到任何問題請勿向 Tricky Store 作者反饋。",
|
"disclaimer": "此 WebUI 並非 Tricky Store 的一部分,如遇任何問題請勿向 Tricky Store 作者反饋。",
|
||||||
"acknowledgment": "特別鳴謝"
|
"acknowledgment": "特別鳴謝"
|
||||||
},
|
},
|
||||||
"prompt": {
|
"prompt": {
|
||||||
"no_internet": "請檢查您的網路連接",
|
"no_internet": "請檢查您的網絡連接",
|
||||||
"aosp_key_set": "成功設置 AOSP 密鑰",
|
"aosp_key_set": "成功設置 AOSP 密鑰",
|
||||||
"key_set_error": "更新密鑰失敗",
|
"key_set_error": "更新密鑰失敗",
|
||||||
"valid_key_set": "成功設置有效密鑰",
|
"valid_key_set": "成功設置有效密鑰",
|
||||||
@@ -70,6 +73,14 @@
|
|||||||
"save_error": "保存配置失敗",
|
"save_error": "保存配置失敗",
|
||||||
"uninstall_prompt": "WebUI 將在重啟後被移除",
|
"uninstall_prompt": "WebUI 將在重啟後被移除",
|
||||||
"uninstall_failed": "卸載 WebUI 失敗",
|
"uninstall_failed": "卸載 WebUI 失敗",
|
||||||
"new_update": "發現新的版本!"
|
"new_update": "發現新版本!",
|
||||||
|
"downloading": "正在下載...",
|
||||||
|
"downloaded": "下載完成",
|
||||||
|
"download_fail": "下載失敗",
|
||||||
|
"installing": "正在安裝...",
|
||||||
|
"installed": "安裝完成,重啟生效",
|
||||||
|
"install_fail": "安裝失敗,請手動更新",
|
||||||
|
"rebooting": "正在重啟...",
|
||||||
|
"reboot_fail": "重啟失敗,請手動重啟"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,10 +1,10 @@
|
|||||||
import { execCommand } from './main.js';
|
import { execCommand, linkRedirect } from './main.js';
|
||||||
|
|
||||||
const telegramLink = document.getElementById('telegram');
|
const telegramLink = document.getElementById('telegram');
|
||||||
const githubLink = document.getElementById('github');
|
const githubLink = document.getElementById('github');
|
||||||
|
|
||||||
// Function to show about overlay
|
// Function to show about overlay
|
||||||
export function aboutMenu() {
|
document.getElementById("about").addEventListener("click", () => {
|
||||||
const aboutOverlay = document.getElementById('about-overlay');
|
const aboutOverlay = document.getElementById('about-overlay');
|
||||||
const aboutMenu = document.getElementById('about-menu');
|
const aboutMenu = document.getElementById('about-menu');
|
||||||
const closeAbout = document.getElementById('close-about');
|
const closeAbout = document.getElementById('close-about');
|
||||||
@@ -35,20 +35,12 @@ export function aboutMenu() {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
menu.addEventListener('click', (event) => event.stopPropagation());
|
menu.addEventListener('click', (event) => event.stopPropagation());
|
||||||
}
|
});
|
||||||
|
|
||||||
// Event listener for link redirect
|
// Event listener for link redirect
|
||||||
telegramLink.addEventListener('click', async () => {
|
telegramLink.addEventListener('click', function() {
|
||||||
try {
|
linkRedirect('https://t.me/kowchannel');
|
||||||
await execCommand('am start -a android.intent.action.VIEW -d https://t.me/kowchannel');
|
|
||||||
} catch (error) {
|
|
||||||
console.error('Error opening Telegram link:', error);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
githubLink.addEventListener('click', async () => {
|
githubLink.addEventListener('click', function() {
|
||||||
try {
|
linkRedirect('https://github.com/KOWX712/Tricky-Addon-Update-Target-List');
|
||||||
await execCommand('am start -a android.intent.action.VIEW -d https://github.com/KOWX712/Tricky-Addon-Update-Target-List');
|
|
||||||
} catch (error) {
|
|
||||||
console.error('Error opening GitHub link:', error);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
@@ -1,8 +1,10 @@
|
|||||||
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');
|
||||||
|
export let modeActive = false;
|
||||||
|
|
||||||
// Fetch and render applist
|
// Fetch and render applist
|
||||||
export async function fetchAppList() {
|
export async function fetchAppList() {
|
||||||
@@ -13,6 +15,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,11 +38,11 @@ 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 | awk -F: '{print $2}'; pm list packages -s | awk -F: '{print $2}' | grep -Ex 'com.google.android.gms|com.google.android.gsf|com.android.vending'");
|
||||||
const appEntries = result
|
const appEntries = result
|
||||||
.split("\n")
|
.split("\n")
|
||||||
.map(line => {
|
.map(line => {
|
||||||
const packageName = line.replace("package:", "").trim();
|
const packageName = line.trim();
|
||||||
const appName = applistMap[packageName] || null;
|
const appName = applistMap[packageName] || null;
|
||||||
return { appName, packageName };
|
return { appName, packageName };
|
||||||
})
|
})
|
||||||
@@ -76,6 +79,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,13 +107,18 @@ 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(-120px)";
|
floatingBtn.style.transform = 'translateY(0)';
|
||||||
toggleableCheckbox();
|
toggleableCheckbox();
|
||||||
if (appListContainer.firstChild !== updateCard) {
|
if (appListContainer.firstChild !== updateCard) {
|
||||||
appListContainer.insertBefore(updateCard, appListContainer.firstChild);
|
appListContainer.insertBefore(updateCard, appListContainer.firstChild);
|
||||||
}
|
}
|
||||||
|
const checkboxes = appListContainer.querySelectorAll(".checkbox");
|
||||||
|
setupRadioButtonListeners();
|
||||||
|
setupModeMenu();
|
||||||
|
updateCheckboxColor();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Function to save app with ! and ? then process target list
|
// Function to save app with ! and ? then process target list
|
||||||
@@ -119,9 +147,116 @@ function toggleableCheckbox() {
|
|||||||
const content = card.querySelector(".content");
|
const content = card.querySelector(".content");
|
||||||
const checkbox = content.querySelector(".checkbox");
|
const checkbox = content.querySelector(".checkbox");
|
||||||
content.addEventListener("click", (event) => {
|
content.addEventListener("click", (event) => {
|
||||||
if (event.target !== checkbox) {
|
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 setupModeMenu() {
|
||||||
|
let holdTimeout;
|
||||||
|
function showMode(card) {
|
||||||
|
const modeElement = card.querySelector(".mode");
|
||||||
|
if (modeElement) {
|
||||||
|
modeActive = true;
|
||||||
|
modeElement.style.display = "flex";
|
||||||
|
modeOverlay.style.display = "flex";
|
||||||
|
setTimeout(() => {
|
||||||
|
modeElement.classList.add('show');
|
||||||
|
}, 10);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function hideAllModes() {
|
||||||
|
const allModeElements = appListContainer.querySelectorAll(".mode");
|
||||||
|
allModeElements.forEach((modeElement) => {
|
||||||
|
modeActive = false;
|
||||||
|
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));
|
||||||
|
});
|
||||||
|
|
||||||
|
document.addEventListener("click", (event) => {
|
||||||
|
if (!event.target.closest(".mode") || modeOverlay.contains(event.target)) {
|
||||||
|
hideAllModes();
|
||||||
|
} else if (event.target.closest(".status-indicator")) {
|
||||||
|
setTimeout(() => {
|
||||||
|
hideAllModes();
|
||||||
|
}, 300);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
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");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
@@ -3,28 +3,29 @@ const helpOverlay = document.getElementById('help-overlay');
|
|||||||
const closeHelp = document.getElementById('close-help');
|
const closeHelp = document.getElementById('close-help');
|
||||||
const helpList = document.getElementById('help-list');
|
const helpList = document.getElementById('help-list');
|
||||||
|
|
||||||
// Function to setup the help menu
|
// Open help menu
|
||||||
export function setupHelpOverlay() {
|
helpButton.addEventListener("click", () => {
|
||||||
helpButton.addEventListener("click", () => {
|
helpOverlay.classList.remove("hide");
|
||||||
helpOverlay.classList.remove("hide");
|
helpOverlay.style.display = "flex";
|
||||||
helpOverlay.style.display = "flex";
|
requestAnimationFrame(() => {
|
||||||
requestAnimationFrame(() => {
|
helpOverlay.classList.add("show");
|
||||||
helpOverlay.classList.add("show");
|
|
||||||
});
|
|
||||||
document.body.classList.add("no-scroll");
|
|
||||||
});
|
});
|
||||||
const hideHelpOverlay = () => {
|
document.body.classList.add("no-scroll");
|
||||||
helpOverlay.classList.remove("show");
|
});
|
||||||
helpOverlay.classList.add("hide");
|
|
||||||
document.body.classList.remove("no-scroll");
|
const hideHelpOverlay = () => {
|
||||||
setTimeout(() => {
|
helpOverlay.classList.remove("show");
|
||||||
helpOverlay.style.display = "none";
|
helpOverlay.classList.add("hide");
|
||||||
}, 200);
|
document.body.classList.remove("no-scroll");
|
||||||
};
|
setTimeout(() => {
|
||||||
closeHelp.addEventListener("click", hideHelpOverlay);
|
helpOverlay.style.display = "none";
|
||||||
helpOverlay.addEventListener("click", (event) => {
|
}, 200);
|
||||||
if (event.target === helpOverlay) {
|
};
|
||||||
hideHelpOverlay();
|
|
||||||
}
|
// Close help menu
|
||||||
});
|
closeHelp.addEventListener("click", hideHelpOverlay);
|
||||||
}
|
helpOverlay.addEventListener("click", (event) => {
|
||||||
|
if (event.target === helpOverlay) {
|
||||||
|
hideHelpOverlay();
|
||||||
|
}
|
||||||
|
});
|
||||||
@@ -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.");
|
||||||
@@ -91,8 +93,10 @@ export function setupLanguageMenu() {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
function openLanguageMenu() {
|
function openLanguageMenu() {
|
||||||
languageMenu.classList.add("show");
|
|
||||||
languageOverlay.style.display = 'flex';
|
languageOverlay.style.display = 'flex';
|
||||||
|
setTimeout(() => {
|
||||||
|
languageMenu.classList.add("show");
|
||||||
|
}, 10);
|
||||||
}
|
}
|
||||||
function closeLanguageMenu() {
|
function closeLanguageMenu() {
|
||||||
languageMenu.classList.remove("show");
|
languageMenu.classList.remove("show");
|
||||||
|
|||||||
@@ -1,39 +1,48 @@
|
|||||||
import { aboutMenu } from './about.js';
|
import { appListContainer, fetchAppList, modeActive } from './applist.js';
|
||||||
import { appListContainer, updateCard, fetchAppList } from './applist.js';
|
|
||||||
import { setupHelpOverlay } from './help.js';
|
|
||||||
import { initializeAvailableLanguages, detectUserLanguage, loadTranslations, setupLanguageMenu, translations } from './language.js';
|
import { initializeAvailableLanguages, detectUserLanguage, loadTranslations, setupLanguageMenu, translations } from './language.js';
|
||||||
import { selectAllApps, deselectAllApps, selectDenylistApps, deselectUnnecessaryApps, aospkb, extrakb } from './menu_option.js';
|
import { aospkb } from './menu_option.js';
|
||||||
import { searchMenuContainer, searchInput, clearBtn, setupMenuToggle } from './search_menu.js';
|
import { searchMenuContainer, searchInput, clearBtn, setupMenuToggle } from './search_menu.js';
|
||||||
import { setBootHash } from './vbmeta-digest.js';
|
import { updateCheck } from './update.js';
|
||||||
|
|
||||||
// Header Elements
|
// Header Elements
|
||||||
const headerBlock = document.querySelector('.header-block');
|
const headerBlock = document.querySelector('.header-block');
|
||||||
const title = document.querySelector('.header');
|
const title = document.querySelector('.header');
|
||||||
const noConnection = document.querySelector('.no-connection');
|
export const noConnection = document.querySelector('.no-connection');
|
||||||
|
|
||||||
// Menu Elements
|
|
||||||
const selectDenylistElement = document.getElementById('select-denylist');
|
|
||||||
|
|
||||||
// Loading, Save and Prompt Elements
|
// Loading, Save and Prompt Elements
|
||||||
const loadingIndicator = document.querySelector('.loading');
|
const loadingIndicator = document.querySelector('.loading');
|
||||||
const prompt = document.getElementById('prompt');
|
const prompt = document.getElementById('prompt');
|
||||||
|
const floatingCard = document.querySelector('.floating-card');
|
||||||
export const floatingBtn = document.querySelector('.floating-btn');
|
export const floatingBtn = document.querySelector('.floating-btn');
|
||||||
|
|
||||||
export const basePath = "set-path";
|
export const basePath = "set-path";
|
||||||
export const appsWithExclamation = [];
|
export const appsWithExclamation = [];
|
||||||
export const appsWithQuestion = [];
|
export const appsWithQuestion = [];
|
||||||
const ADDITIONAL_APPS = [ "com.google.android.gms", "io.github.vvb2060.keyattestation", "io.github.vvb2060.mahoshojo", "icu.nullptr.nativetest" ];
|
const ADDITIONAL_APPS = [ "android", "com.android.vending", "com.google.android.gms", "io.github.vvb2060.keyattestation", "io.github.vvb2060.mahoshojo", "icu.nullptr.nativetest" ]; // Always keep default apps in target.txt
|
||||||
|
const rippleClasses = ['.language-option', '.menu-button', '.menu-options li', '.search-card', '.card', '.update-card', '.link-icon', '.floating-btn', '.uninstall-container', '.boot-hash-save-button', '.boot-hash-value', '.reboot', '.install'];
|
||||||
|
|
||||||
// Variables
|
// Variables
|
||||||
let e = 0;
|
let e = 0;
|
||||||
let isRefreshing = false;
|
let isRefreshing = false;
|
||||||
|
|
||||||
|
// Function to load the version from module.prop
|
||||||
|
async function getModuleVersion() {
|
||||||
|
const moduleVersion = document.getElementById('module-version');
|
||||||
|
try {
|
||||||
|
const version = await execCommand(`grep '^version=' ${basePath}common/update/module.prop | cut -d'=' -f2`);
|
||||||
|
moduleVersion.textContent = version;
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Failed to read version from module.prop:", error);
|
||||||
|
updateVersion("Error");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Function to refresh app list
|
// Function to refresh app list
|
||||||
async function refreshAppList() {
|
async function refreshAppList() {
|
||||||
isRefreshing = true;
|
isRefreshing = true;
|
||||||
title.style.transform = 'translateY(0)';
|
title.style.transform = 'translateY(0)';
|
||||||
searchMenuContainer.style.transform = 'translateY(0)';
|
searchMenuContainer.style.transform = 'translateY(0)';
|
||||||
floatingBtn.style.transform = 'translateY(0)';
|
hideFloatingBtn();
|
||||||
searchInput.value = '';
|
searchInput.value = '';
|
||||||
clearBtn.style.display = "none";
|
clearBtn.style.display = "none";
|
||||||
appListContainer.innerHTML = '';
|
appListContainer.innerHTML = '';
|
||||||
@@ -43,56 +52,39 @@ async function refreshAppList() {
|
|||||||
window.scrollTo(0, 0);
|
window.scrollTo(0, 0);
|
||||||
if (noConnection.style.display === "flex") {
|
if (noConnection.style.display === "flex") {
|
||||||
try {
|
try {
|
||||||
await 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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
await fetchAppList();
|
await fetchAppList();
|
||||||
|
applyRippleEffect();
|
||||||
loadingIndicator.style.display = 'none';
|
loadingIndicator.style.display = 'none';
|
||||||
document.querySelector('.uninstall-container').classList.remove('hidden-uninstall');
|
document.querySelector('.uninstall-container').classList.remove('hidden-uninstall');
|
||||||
isRefreshing = false;
|
isRefreshing = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Function to run the update check
|
|
||||||
async function updateCheck() {
|
|
||||||
try {
|
|
||||||
const scriptPath = `sh ${basePath}common/get_extra.sh --update`;
|
|
||||||
const output = await execCommand(scriptPath);
|
|
||||||
console.log("update script executed successfully.");
|
|
||||||
noConnection.style.display = "none";
|
|
||||||
if (output.includes("update")) {
|
|
||||||
console.log("Update detected from extra script.");
|
|
||||||
showPrompt("prompt.new_update");
|
|
||||||
updateCard.style.display = "flex";
|
|
||||||
} else {
|
|
||||||
console.log("No update detected from extra script.");
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.error("Failed to execute update script:", error);
|
|
||||||
showPrompt("prompt.no_internet", false);
|
|
||||||
noConnection.style.display = "flex";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Function to check if Magisk
|
// Function to check if Magisk
|
||||||
async function checkMagisk() {
|
async function checkMagisk() {
|
||||||
|
const selectDenylistElement = document.getElementById('select-denylist');
|
||||||
try {
|
try {
|
||||||
const magiskEnv = await execCommand(`command -v magisk >/dev/null 2>&1 && echo "OK"`);
|
const magiskEnv = await execCommand(`command -v magisk >/dev/null 2>&1 || echo "NO"`);
|
||||||
if (magiskEnv.trim() === "OK") {
|
if (magiskEnv.trim() !== "NO") {
|
||||||
console.log("Denylist conditions met, displaying element.");
|
console.log("Denylist conditions met, displaying element.");
|
||||||
selectDenylistElement.style.display = "flex";
|
selectDenylistElement.style.display = "flex";
|
||||||
} else {
|
} else {
|
||||||
console.log("ksud or apd detected, 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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Function to show the prompt with a success or error message
|
// Function to show the prompt with a success or error message
|
||||||
export function showPrompt(key, isSuccess = true) {
|
export function showPrompt(key, isSuccess = true, duration = 3000) {
|
||||||
const message = key.split('.').reduce((acc, k) => acc && acc[k], translations) || key;
|
const message = key.split('.').reduce((acc, k) => acc && acc[k], translations) || key;
|
||||||
prompt.textContent = message;
|
prompt.textContent = message;
|
||||||
prompt.classList.toggle('error', !isSuccess);
|
prompt.classList.toggle('error', !isSuccess);
|
||||||
@@ -100,13 +92,25 @@ export function showPrompt(key, isSuccess = true) {
|
|||||||
clearTimeout(window.promptTimeout);
|
clearTimeout(window.promptTimeout);
|
||||||
}
|
}
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
prompt.classList.add('visible');
|
if (typeof ksu !== 'undefined' && ksu.mmrl) {
|
||||||
prompt.classList.remove('hidden');
|
prompt.style.transform = 'translateY(calc((var(--window-inset-bottom) + 60%) * -1))';
|
||||||
|
} else {
|
||||||
|
prompt.style.transform = 'translateY(-60%)';
|
||||||
|
}
|
||||||
window.promptTimeout = setTimeout(() => {
|
window.promptTimeout = setTimeout(() => {
|
||||||
prompt.classList.remove('visible');
|
prompt.style.transform = 'translateY(100%)';
|
||||||
prompt.classList.add('hidden');
|
}, duration);
|
||||||
}, 3000);
|
}, 100);
|
||||||
}, 200);
|
}
|
||||||
|
|
||||||
|
// Function to redirect link on external browser
|
||||||
|
export async function linkRedirect(link) {
|
||||||
|
try {
|
||||||
|
await execCommand(`am start -a android.intent.action.VIEW -d ${link}`);
|
||||||
|
} catch (error) {
|
||||||
|
toast("Failed!");
|
||||||
|
console.error('Error redirect link:', error);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Save configure and preserve ! and ? in target.txt
|
// Save configure and preserve ! and ? in target.txt
|
||||||
@@ -128,7 +132,7 @@ document.getElementById("save").addEventListener("click", async () => {
|
|||||||
return app;
|
return app;
|
||||||
});
|
});
|
||||||
const updatedTargetContent = modifiedAppsList.join("\n");
|
const updatedTargetContent = modifiedAppsList.join("\n");
|
||||||
await execCommand(`echo "${updatedTargetContent}" > /data/adb/tricky_store/target.txt`);
|
await execCommand(`echo "${updatedTargetContent}" | sort -u > /data/adb/tricky_store/target.txt`);
|
||||||
console.log("target.txt updated successfully.");
|
console.log("target.txt updated successfully.");
|
||||||
showPrompt("prompt.saved_target");
|
showPrompt("prompt.saved_target");
|
||||||
for (const app of appsWithExclamation) {
|
for (const app of appsWithExclamation) {
|
||||||
@@ -166,62 +170,131 @@ function adjustHeaderForMMRL() {
|
|||||||
const insetTopValue = parseInt(insetTop, 10);
|
const insetTopValue = parseInt(insetTop, 10);
|
||||||
searchMenuContainer.style.top = `${insetTopValue + 40}px`;
|
searchMenuContainer.style.top = `${insetTopValue + 40}px`;
|
||||||
headerBlock.style.display = 'block';
|
headerBlock.style.display = 'block';
|
||||||
|
floatingCard.style.bottom = 'calc(var(--window-inset-bottom) + 50px)';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Funtion to adapt floating button hide in MMRL
|
||||||
|
function hideFloatingBtn() {
|
||||||
|
if (typeof ksu !== 'undefined' && ksu.mmrl) {
|
||||||
|
floatingBtn.style.transform = 'translateY(calc(var(--window-inset-bottom) + 120px))';
|
||||||
|
} else {
|
||||||
|
floatingBtn.style.transform = 'translateY(120px)';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Function to apply ripple effect
|
||||||
|
function applyRippleEffect() {
|
||||||
|
rippleClasses.forEach(selector => {
|
||||||
|
document.querySelectorAll(selector).forEach(element => {
|
||||||
|
if (element.dataset.rippleListener !== "true") {
|
||||||
|
element.addEventListener("pointerdown", function (event) {
|
||||||
|
if (isScrolling) return;
|
||||||
|
if (modeActive) return;
|
||||||
|
|
||||||
|
const ripple = document.createElement("span");
|
||||||
|
ripple.classList.add("ripple");
|
||||||
|
|
||||||
|
// Calculate ripple size and position
|
||||||
|
const rect = element.getBoundingClientRect();
|
||||||
|
const width = rect.width;
|
||||||
|
const size = Math.max(rect.width, rect.height);
|
||||||
|
const x = event.clientX - rect.left - size / 2;
|
||||||
|
const y = event.clientY - rect.top - size / 2;
|
||||||
|
|
||||||
|
// Determine animation duration
|
||||||
|
let duration = 0.3 + (width / 800) * 0.3;
|
||||||
|
duration = Math.min(0.8, Math.max(0.2, duration));
|
||||||
|
|
||||||
|
// Set ripple styles
|
||||||
|
ripple.style.width = ripple.style.height = `${size}px`;
|
||||||
|
ripple.style.left = `${x}px`;
|
||||||
|
ripple.style.top = `${y}px`;
|
||||||
|
ripple.style.animationDuration = `${duration}s`;
|
||||||
|
ripple.style.transition = `opacity ${duration}s ease`;
|
||||||
|
|
||||||
|
// Adaptive color
|
||||||
|
const computedStyle = window.getComputedStyle(element);
|
||||||
|
const bgColor = computedStyle.backgroundColor || "rgba(0, 0, 0, 0)";
|
||||||
|
const textColor = computedStyle.color;
|
||||||
|
const isDarkColor = (color) => {
|
||||||
|
const rgb = color.match(/\d+/g);
|
||||||
|
if (!rgb) return false;
|
||||||
|
const [r, g, b] = rgb.map(Number);
|
||||||
|
return (r * 0.299 + g * 0.587 + b * 0.114) < 96; // Luma formula
|
||||||
|
};
|
||||||
|
ripple.style.backgroundColor = isDarkColor(bgColor) ? "rgba(255, 255, 255, 0.2)" : "";
|
||||||
|
|
||||||
|
// Append ripple and handle cleanup
|
||||||
|
element.appendChild(ripple);
|
||||||
|
const handlePointerUp = () => {
|
||||||
|
ripple.classList.add("end");
|
||||||
|
setTimeout(() => {
|
||||||
|
ripple.classList.remove("end");
|
||||||
|
ripple.remove();
|
||||||
|
}, duration * 1000);
|
||||||
|
element.removeEventListener("pointerup", handlePointerUp);
|
||||||
|
element.removeEventListener("pointercancel", handlePointerUp);
|
||||||
|
};
|
||||||
|
element.addEventListener("pointerup", handlePointerUp);
|
||||||
|
element.addEventListener("pointercancel", handlePointerUp);
|
||||||
|
});
|
||||||
|
element.dataset.rippleListener = "true";
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// Scroll event
|
// Scroll event
|
||||||
let lastScrollY = window.scrollY;
|
let lastScrollY = window.scrollY;
|
||||||
|
let isScrolling = false;
|
||||||
|
let scrollTimeout;
|
||||||
const scrollThreshold = 40;
|
const scrollThreshold = 40;
|
||||||
window.addEventListener('scroll', () => {
|
window.addEventListener('scroll', () => {
|
||||||
|
isScrolling = true;
|
||||||
|
clearTimeout(scrollTimeout);
|
||||||
|
scrollTimeout = setTimeout(() => {
|
||||||
|
isScrolling = false;
|
||||||
|
}, 200);
|
||||||
if (isRefreshing) return;
|
if (isRefreshing) return;
|
||||||
if (window.scrollY > lastScrollY && window.scrollY > scrollThreshold) {
|
if (window.scrollY > lastScrollY && window.scrollY > scrollThreshold) {
|
||||||
title.style.transform = 'translateY(-80px)';
|
title.style.transform = 'translateY(-80px)';
|
||||||
headerBlock.style.transform = 'translateY(-80px)';
|
headerBlock.style.transform = 'translateY(-80px)';
|
||||||
searchMenuContainer.style.transform = 'translateY(-40px)';
|
searchMenuContainer.style.transform = 'translateY(-40px)';
|
||||||
floatingBtn.style.transform = 'translateY(0)';
|
hideFloatingBtn();
|
||||||
} else if (window.scrollY < lastScrollY) {
|
} else if (window.scrollY < lastScrollY) {
|
||||||
headerBlock.style.transform = 'translateY(0)';
|
headerBlock.style.transform = 'translateY(0)';
|
||||||
title.style.transform = 'translateY(0)';
|
title.style.transform = 'translateY(0)';
|
||||||
searchMenuContainer.style.transform = 'translateY(0)';
|
searchMenuContainer.style.transform = 'translateY(0)';
|
||||||
floatingBtn.style.transform = 'translateY(-120px)';
|
floatingBtn.style.transform = 'translateY(0)';
|
||||||
}
|
}
|
||||||
lastScrollY = window.scrollY;
|
lastScrollY = window.scrollY;
|
||||||
});
|
});
|
||||||
|
|
||||||
// Initial load
|
// Initial load
|
||||||
document.addEventListener('DOMContentLoaded', async () => {
|
document.addEventListener('DOMContentLoaded', async () => {
|
||||||
|
hideFloatingBtn();
|
||||||
adjustHeaderForMMRL();
|
adjustHeaderForMMRL();
|
||||||
|
getModuleVersion();
|
||||||
await initializeAvailableLanguages();
|
await initializeAvailableLanguages();
|
||||||
const userLang = detectUserLanguage();
|
const userLang = detectUserLanguage();
|
||||||
await loadTranslations(userLang);
|
await loadTranslations(userLang);
|
||||||
setupMenuToggle();
|
setupMenuToggle();
|
||||||
setupLanguageMenu();
|
setupLanguageMenu();
|
||||||
setupHelpOverlay();
|
|
||||||
document.getElementById("refresh").addEventListener("click", refreshAppList);
|
|
||||||
document.getElementById("select-all").addEventListener("click", selectAllApps);
|
|
||||||
document.getElementById("deselect-all").addEventListener("click", deselectAllApps);
|
|
||||||
document.getElementById("select-denylist").addEventListener("click", selectDenylistApps);
|
|
||||||
document.getElementById("deselect-unnecessary").addEventListener("click", deselectUnnecessaryApps);
|
|
||||||
document.getElementById("aospkb").addEventListener("click", aospkb);
|
|
||||||
document.getElementById("extrakb").addEventListener("click", extrakb);
|
|
||||||
document.getElementById("boot-hash").addEventListener("click", setBootHash);
|
|
||||||
document.getElementById("about").addEventListener("click", aboutMenu);
|
|
||||||
await fetchAppList();
|
await fetchAppList();
|
||||||
|
applyRippleEffect();
|
||||||
checkMagisk();
|
checkMagisk();
|
||||||
updateCheck();
|
updateCheck();
|
||||||
loadingIndicator.style.display = "none";
|
loadingIndicator.style.display = "none";
|
||||||
|
floatingBtn.style.opacity = '1';
|
||||||
|
setTimeout(() => {
|
||||||
|
floatingBtn.style.transform = 'translateY(0)';
|
||||||
|
}, 10);
|
||||||
|
document.getElementById("refresh").addEventListener("click", refreshAppList);
|
||||||
|
document.getElementById("aospkb").addEventListener("click", aospkb);
|
||||||
document.querySelector('.uninstall-container').classList.remove('hidden-uninstall');
|
document.querySelector('.uninstall-container').classList.remove('hidden-uninstall');
|
||||||
});
|
});
|
||||||
|
|
||||||
// Redirect to GitHub release page
|
|
||||||
updateCard.addEventListener('click', async () => {
|
|
||||||
try {
|
|
||||||
await execCommand('am start -a android.intent.action.VIEW -d https://github.com/KOWX712/Tricky-Addon-Update-Target-List/releases/latest');
|
|
||||||
} catch (error) {
|
|
||||||
console.error('Error opening GitHub Release link:', error);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Function to execute shell commands
|
// Function to execute shell commands
|
||||||
export async function execCommand(command) {
|
export async function execCommand(command) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
@@ -243,3 +316,8 @@ export async function execCommand(command) {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Function to toast message
|
||||||
|
export function toast(message) {
|
||||||
|
ksu.toast(message);
|
||||||
|
}
|
||||||
6
module/webui/scripts/marked.min.js
vendored
Normal file
6
module/webui/scripts/marked.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
@@ -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) {
|
||||||
@@ -10,22 +10,17 @@ function toggleCheckboxes(shouldCheck) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Function to select all visible apps
|
// Function to select all visible apps
|
||||||
export function selectAllApps() {
|
document.getElementById("select-all").addEventListener("click", () => toggleCheckboxes(true));
|
||||||
toggleCheckboxes(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Function to deselect all visible apps
|
// Function to deselect all visible apps
|
||||||
export function deselectAllApps() {
|
document.getElementById("deselect-all").addEventListener("click", () => toggleCheckboxes(false));
|
||||||
toggleCheckboxes(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Function to read the denylist and check corresponding apps
|
// Function to read the denylist and check corresponding apps
|
||||||
export async function selectDenylistApps() {
|
document.getElementById("select-denylist").addEventListener("click", async () => {
|
||||||
try {
|
try {
|
||||||
const result = await execCommand(`magisk --denylist ls 2>/dev/null | awk -F'|' '{print $1}' | grep -v "isolated" | sort | uniq`);
|
const result = await execCommand(`magisk --denylist ls 2>/dev/null | awk -F'|' '{print $1}' | grep -v "isolated" | sort -u`);
|
||||||
const denylistApps = result.split("\n").map(app => app.trim()).filter(Boolean);
|
const denylistApps = result.split("\n").map(app => app.trim()).filter(Boolean);
|
||||||
const apps = document.querySelectorAll(".card");
|
const apps = document.querySelectorAll(".card");
|
||||||
await deselectAllApps();
|
|
||||||
apps.forEach(app => {
|
apps.forEach(app => {
|
||||||
const contentElement = app.querySelector(".content");
|
const contentElement = app.querySelector(".content");
|
||||||
const packageName = contentElement.getAttribute("data-package");
|
const packageName = contentElement.getAttribute("data-package");
|
||||||
@@ -34,14 +29,16 @@ export async function selectDenylistApps() {
|
|||||||
checkbox.checked = true;
|
checkbox.checked = true;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
await execCommand('touch "/data/adb/tricky_store/target_from_denylist"');
|
||||||
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);
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
|
|
||||||
// Function to read the exclude list and uncheck corresponding apps
|
// Function to read the exclude list and uncheck corresponding apps
|
||||||
export async function deselectUnnecessaryApps() {
|
document.getElementById("deselect-unnecessary").addEventListener("click", async () => {
|
||||||
try {
|
try {
|
||||||
const fileCheck = await execCommand(`test -f ${basePath}common/tmp/exclude-list && echo "exists" || echo "not found"`);
|
const fileCheck = await execCommand(`test -f ${basePath}common/tmp/exclude-list && echo "exists" || echo "not found"`);
|
||||||
if (fileCheck.trim() === "not found") {
|
if (fileCheck.trim() === "not found") {
|
||||||
@@ -69,16 +66,17 @@ export async function deselectUnnecessaryApps() {
|
|||||||
});
|
});
|
||||||
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);
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
|
|
||||||
// Function to replace aosp kb
|
// Function to replace aosp kb
|
||||||
export async function aospkb() {
|
export async function aospkb() {
|
||||||
try {
|
try {
|
||||||
const sourcePath = `${basePath}common/.default`;
|
const sourcePath = `${basePath}common/.default`;
|
||||||
const destinationPath = "/data/adb/tricky_store/keybox.xml";
|
const destinationPath = "/data/adb/tricky_store/keybox.xml";
|
||||||
await execCommand(`xxd -r -p ${sourcePath} | base64 -d > ${destinationPath}`);
|
await execCommand(`mv -f ${destinationPath} ${destinationPath}.bak && xxd -r -p ${sourcePath} | base64 -d > ${destinationPath}`);
|
||||||
console.log("AOSP keybox copied successfully.");
|
console.log("AOSP keybox copied successfully.");
|
||||||
showPrompt("prompt.aosp_key_set");
|
showPrompt("prompt.aosp_key_set");
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@@ -88,7 +86,7 @@ export async function aospkb() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Function to replace valid kb
|
// Function to replace valid kb
|
||||||
export async function extrakb() {
|
document.getElementById("extrakb").addEventListener("click", async () => {
|
||||||
setTimeout(async () => {
|
setTimeout(async () => {
|
||||||
await execCommand(`sh ${basePath}common/get_extra.sh --kb`);
|
await execCommand(`sh ${basePath}common/get_extra.sh --kb`);
|
||||||
}, 100);
|
}, 100);
|
||||||
@@ -100,7 +98,7 @@ export async function extrakb() {
|
|||||||
if (fileExists.trim() !== "exists") {
|
if (fileExists.trim() !== "exists") {
|
||||||
throw new Error(".extra file not found");
|
throw new Error(".extra file not found");
|
||||||
}
|
}
|
||||||
await execCommand(`xxd -r -p ${sourcePath} | base64 -d > ${destinationPath}`);
|
await execCommand(`mv -f ${destinationPath} ${destinationPath}.bak && xxd -r -p ${sourcePath} | base64 -d > ${destinationPath}`);
|
||||||
console.log("Valid keybox copied successfully.");
|
console.log("Valid keybox copied successfully.");
|
||||||
showPrompt("prompt.valid_key_set");
|
showPrompt("prompt.valid_key_set");
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@@ -108,4 +106,4 @@ export async function extrakb() {
|
|||||||
await aospkb();
|
await aospkb();
|
||||||
showPrompt("prompt.no_valid_fallback", false);
|
showPrompt("prompt.no_valid_fallback", false);
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
@@ -44,10 +44,7 @@ clearBtn.addEventListener("click", () => {
|
|||||||
|
|
||||||
// Function to toggle menu option
|
// Function to toggle menu option
|
||||||
export function setupMenuToggle() {
|
export function setupMenuToggle() {
|
||||||
let menuOpen = false;
|
|
||||||
let menuAnimating = false;
|
|
||||||
menuButton.addEventListener('click', (event) => {
|
menuButton.addEventListener('click', (event) => {
|
||||||
if (menuAnimating) return;
|
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
if (menuOptions.classList.contains('visible')) {
|
if (menuOptions.classList.contains('visible')) {
|
||||||
closeMenu();
|
closeMenu();
|
||||||
@@ -73,31 +70,15 @@ export function setupMenuToggle() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
function openMenu() {
|
function openMenu() {
|
||||||
menuAnimating = true;
|
|
||||||
menuOptions.style.display = 'block';
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
menuOptions.classList.remove('hidden');
|
|
||||||
menuOptions.classList.add('visible');
|
menuOptions.classList.add('visible');
|
||||||
menuIcon.classList.add('menu-open');
|
menuIcon.classList.add('menu-open');
|
||||||
menuIcon.classList.remove('menu-closed');
|
|
||||||
menuOverlay.style.display = 'flex';
|
menuOverlay.style.display = 'flex';
|
||||||
menuOpen = true;
|
|
||||||
menuAnimating = false;
|
|
||||||
}, 10);
|
}, 10);
|
||||||
}
|
}
|
||||||
function closeMenu() {
|
function closeMenu() {
|
||||||
if (menuOptions.classList.contains('visible')) {
|
menuOptions.classList.remove('visible');
|
||||||
menuAnimating = true;
|
menuIcon.classList.remove('menu-open');
|
||||||
menuOptions.classList.remove('visible');
|
menuOverlay.style.display = 'none';
|
||||||
menuOptions.classList.add('hidden');
|
|
||||||
menuIcon.classList.remove('menu-open');
|
|
||||||
menuIcon.classList.add('menu-closed');
|
|
||||||
menuOverlay.style.display = 'none';
|
|
||||||
setTimeout(() => {
|
|
||||||
menuOptions.style.display = 'none';
|
|
||||||
menuOpen = false;
|
|
||||||
menuAnimating = false;
|
|
||||||
}, 200);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
113
module/webui/scripts/update.js
Normal file
113
module/webui/scripts/update.js
Normal file
@@ -0,0 +1,113 @@
|
|||||||
|
import { basePath, execCommand, showPrompt, noConnection, linkRedirect } from './main.js';
|
||||||
|
import { updateCard } from './applist.js';
|
||||||
|
|
||||||
|
const updateCardText = document.getElementById('redirect-to-release');
|
||||||
|
const UpdateMenu = document.querySelector('.update-overlay');
|
||||||
|
const closeUpdate = document.querySelector('.close-update');
|
||||||
|
const releaseNotes = document.querySelector('.changelog');
|
||||||
|
const installButton = document.querySelector('.install');
|
||||||
|
const rebootButton = document.querySelector('.reboot');
|
||||||
|
|
||||||
|
// Function to run the update check
|
||||||
|
export async function updateCheck() {
|
||||||
|
try {
|
||||||
|
const output = await execCommand(`sh ${basePath}common/get_extra.sh --update`);
|
||||||
|
console.log("update script executed successfully.");
|
||||||
|
noConnection.style.display = "none";
|
||||||
|
if (output.includes("update")) {
|
||||||
|
console.log("Update detected from extra script.");
|
||||||
|
showPrompt("prompt.new_update", true, 2000);
|
||||||
|
updateCard.style.display = "flex";
|
||||||
|
setupUpdateMenu();
|
||||||
|
} else {
|
||||||
|
console.log("No update detected from extra script.");
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Failed to execute update script:", error);
|
||||||
|
showPrompt("prompt.no_internet", false);
|
||||||
|
noConnection.style.display = "flex";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Function to setup update menu
|
||||||
|
function setupUpdateMenu() {
|
||||||
|
function openUpdateMenu() {
|
||||||
|
UpdateMenu.style.display = "flex";
|
||||||
|
setTimeout(async () => {
|
||||||
|
UpdateMenu.style.opacity = "1";
|
||||||
|
}, 10);
|
||||||
|
document.body.classList.add("no-scroll");
|
||||||
|
}
|
||||||
|
function closeUpdateMenu() {
|
||||||
|
UpdateMenu.style.opacity = "0";
|
||||||
|
document.body.classList.remove("no-scroll");
|
||||||
|
setTimeout(async () => {
|
||||||
|
UpdateMenu.style.display = "none";
|
||||||
|
}, 200);
|
||||||
|
}
|
||||||
|
updateCard.addEventListener('click', async () => {
|
||||||
|
try {
|
||||||
|
const module = await execCommand(`[ -f ${basePath}common/tmp/module.zip ] || echo "false"`);
|
||||||
|
if (module.trim() === "false") {
|
||||||
|
showPrompt("prompt.downloading");
|
||||||
|
await new Promise(resolve => setTimeout(resolve, 200));
|
||||||
|
await execCommand(`sh ${basePath}common/get_extra.sh --get-update`);
|
||||||
|
showPrompt("prompt.downloaded");
|
||||||
|
}
|
||||||
|
const changelog = await execCommand(`sh ${basePath}common/get_extra.sh --release-note`);
|
||||||
|
window.linkRedirect = linkRedirect;
|
||||||
|
marked.setOptions({
|
||||||
|
sanitize: true,
|
||||||
|
walkTokens(token) {
|
||||||
|
if (token.type === 'link') {
|
||||||
|
const href = token.href;
|
||||||
|
token.href = "javascript:void(0);";
|
||||||
|
token.type = "html";
|
||||||
|
token.text = `<a href="javascript:void(0);" onclick="linkRedirect('${href}')">${token.text}</a>`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
const cleanedChangelog = changelog
|
||||||
|
.split('\n')
|
||||||
|
.filter(line => line.trim() !== '')
|
||||||
|
.join('\n');
|
||||||
|
const formattedChangelog = marked.parse(cleanedChangelog);
|
||||||
|
releaseNotes.innerHTML = formattedChangelog;
|
||||||
|
openUpdateMenu();
|
||||||
|
} catch (error) {
|
||||||
|
showPrompt("prompt.download_fail", false);
|
||||||
|
console.error('Error download module update:', error);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
closeUpdate.addEventListener("click", closeUpdateMenu);
|
||||||
|
UpdateMenu.addEventListener("click", (event) => {
|
||||||
|
if (event.target === UpdateMenu) {
|
||||||
|
closeUpdateMenu();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
installButton.addEventListener('click', async () => {
|
||||||
|
try {
|
||||||
|
showPrompt("prompt.installing");
|
||||||
|
setTimeout(async () => {
|
||||||
|
await execCommand(`su -c 'sh ${basePath}common/get_extra.sh --install-update'`);
|
||||||
|
showPrompt("prompt.installed");
|
||||||
|
installButton.style.display = "none";
|
||||||
|
rebootButton.style.display = "flex";
|
||||||
|
}, 300);
|
||||||
|
} catch (error) {
|
||||||
|
showPrompt("prompt.install_fail", false);
|
||||||
|
console.error('Fail to execute installation script:', error);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
rebootButton.addEventListener('click', async () => {
|
||||||
|
try {
|
||||||
|
showPrompt("prompt.rebooting");
|
||||||
|
setTimeout(async () => {
|
||||||
|
await execCommand("svc power reboot");
|
||||||
|
}, 1000);
|
||||||
|
} catch (error) {
|
||||||
|
showPrompt("prompt.reboot_fail", false);
|
||||||
|
console.error('Fail to reboot:', error);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
@@ -6,7 +6,7 @@ const inputBox = document.getElementById('boot-hash-input');
|
|||||||
const saveButton = document.getElementById('boot-hash-save-button');
|
const saveButton = document.getElementById('boot-hash-save-button');
|
||||||
|
|
||||||
// Function to handle Verified Boot Hash
|
// Function to handle Verified Boot Hash
|
||||||
export async function setBootHash() {
|
document.getElementById("boot-hash").addEventListener("click", async () => {
|
||||||
const showCard = () => {
|
const showCard = () => {
|
||||||
bootHashOverlay.style.display = "flex";
|
bootHashOverlay.style.display = "flex";
|
||||||
card.style.display = "flex";
|
card.style.display = "flex";
|
||||||
@@ -51,4 +51,4 @@ export async function setBootHash() {
|
|||||||
bootHashOverlay.addEventListener("click", (event) => {
|
bootHashOverlay.addEventListener("click", (event) => {
|
||||||
if (event.target === bootHashOverlay) closeCard();
|
if (event.target === bootHashOverlay) closeCard();
|
||||||
});
|
});
|
||||||
}
|
});
|
||||||
@@ -53,23 +53,34 @@
|
|||||||
|
|
||||||
#module_name_line1 {
|
#module_name_line1 {
|
||||||
font-size: 26px;
|
font-size: 26px;
|
||||||
|
user-select: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
#module_name_line2 {
|
#module_name_line2 {
|
||||||
font-size: 22px;
|
font-size: 22px;
|
||||||
|
user-select: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
#authored {
|
#authored {
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
|
user-select: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
#disclaimer {
|
#disclaimer {
|
||||||
font-style: italic;
|
font-family: serif;
|
||||||
|
width: calc(100% - 80px);
|
||||||
|
padding: 8px 10px;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
margin: auto;
|
||||||
|
border-radius: 10px;
|
||||||
|
background-color: #F5F5F5;
|
||||||
}
|
}
|
||||||
|
|
||||||
#acknowledgment {
|
#acknowledgment {
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
font-size: 18px;
|
font-size: 18px;
|
||||||
|
user-select: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.link-icon {
|
.link-icon {
|
||||||
@@ -79,6 +90,8 @@
|
|||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
margin-bottom: 5px;
|
margin-bottom: 5px;
|
||||||
transition: background-color 0.2s ease;
|
transition: background-color 0.2s ease;
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
.link-icon svg {
|
.link-icon svg {
|
||||||
@@ -93,10 +106,7 @@
|
|||||||
background-color: #38A7ED;
|
background-color: #38A7ED;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
fill: #fff;
|
fill: #fff;
|
||||||
}
|
user-select: none;
|
||||||
|
|
||||||
#telegram:active {
|
|
||||||
background-color: #1A78B3;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#github {
|
#github {
|
||||||
@@ -105,13 +115,9 @@
|
|||||||
background-color: #606060;
|
background-color: #606060;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
fill: #fff;
|
fill: #fff;
|
||||||
|
user-select: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
#github:active {
|
|
||||||
background-color: #4D4D4D;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#link-text {
|
#link-text {
|
||||||
font-size: 17px;
|
font-size: 17px;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
@@ -121,4 +127,8 @@
|
|||||||
.about-menu {
|
.about-menu {
|
||||||
background-color: #343434;
|
background-color: #343434;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#disclaimer {
|
||||||
|
background-color: #6E6E6E;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -23,43 +23,226 @@
|
|||||||
padding: 12px;
|
padding: 12px;
|
||||||
width: calc(100% - 30px);
|
width: calc(100% - 30px);
|
||||||
max-width: 900px;
|
max-width: 900px;
|
||||||
transition: background-color 0.2s ease;
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
#update-available {
|
#update-available {
|
||||||
font-size: 20px;
|
font-size: 20px;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
|
text-align: center;
|
||||||
margin-top: 15px;
|
margin-top: 15px;
|
||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
|
user-select: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
#redirect-to-release {
|
#redirect-to-release {
|
||||||
|
text-align: center;
|
||||||
margin-top: 5px;
|
margin-top: 5px;
|
||||||
margin-bottom: 15px;
|
margin-bottom: 15px;
|
||||||
|
user-select: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.update-overlay {
|
||||||
|
display: none;
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100vw;
|
||||||
|
height: 100vh;
|
||||||
|
background-color: rgba(0, 0, 0, 0.5);
|
||||||
|
z-index: 1800;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
opacity: 0;
|
||||||
|
transition: opacity 0.2s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.update-menu {
|
||||||
|
position: relative;
|
||||||
|
width: 90vw;
|
||||||
|
max-width: 800px;
|
||||||
|
background-color: white;
|
||||||
|
padding: 10px 0;
|
||||||
|
border-radius: 15px;
|
||||||
|
text-align: left;
|
||||||
|
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.3);
|
||||||
|
}
|
||||||
|
|
||||||
|
.close-update {
|
||||||
|
position: absolute;
|
||||||
|
top: 15px;
|
||||||
|
right: 12px;
|
||||||
|
background: none;
|
||||||
|
border: none;
|
||||||
|
font-size: 20px;
|
||||||
|
color: #ccc;
|
||||||
|
}
|
||||||
|
|
||||||
|
.update-content {
|
||||||
|
padding: 0 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.update-content h3 {
|
||||||
|
font-size: 22px;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.changelog {
|
||||||
|
max-height: 65vh;
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.changelog ul {
|
||||||
|
padding-left: 0;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.changelog ul li {
|
||||||
|
margin-left: 15px;
|
||||||
|
margin-bottom: 5px;
|
||||||
|
list-style-type: disc;
|
||||||
|
}
|
||||||
|
|
||||||
|
.changelog a {
|
||||||
|
color: #6E6E6E;
|
||||||
|
cursor: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.changelog a:active {
|
||||||
|
color: blue;
|
||||||
|
}
|
||||||
|
|
||||||
|
.update-button-container {
|
||||||
|
width: 100%;
|
||||||
|
padding-top: 10px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
}
|
||||||
|
|
||||||
|
.install,
|
||||||
|
.reboot {
|
||||||
|
margin-top: 10px;
|
||||||
|
margin-bottom: 15px;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #333;
|
||||||
|
background-color: #fff;
|
||||||
|
border: none;
|
||||||
|
padding: 10px 15px;
|
||||||
|
border: 1px solid #3B3B3B;
|
||||||
|
border-radius: 50px 50px;
|
||||||
|
font-size: 18px;
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
user-select: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reboot {
|
||||||
|
display: none;
|
||||||
|
color: #fff;
|
||||||
|
background-color: #007bff;
|
||||||
|
border: 1px solid #007bff;
|
||||||
}
|
}
|
||||||
|
|
||||||
.card {
|
.card {
|
||||||
background-color: white;
|
background-color: #fff;
|
||||||
border: none;
|
border: none;
|
||||||
border-radius: 12px;
|
border-radius: 12px;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
margin-bottom: 10px;
|
margin-bottom: 10px;
|
||||||
outline: none;
|
outline: none;
|
||||||
padding: 12px;
|
padding: 13px;
|
||||||
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;
|
||||||
}
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
.card:active,
|
|
||||||
.update-card:active {
|
|
||||||
background-color: #C8C8C8;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.content {
|
.content {
|
||||||
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 12px;
|
||||||
|
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: 50px 50px;
|
||||||
|
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: 40px;
|
||||||
|
height: 40px;
|
||||||
|
border-radius: 50px 50px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
border: 3px solid transparent;
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
#normal-indicator {
|
||||||
|
background-color: #007bff;
|
||||||
|
}
|
||||||
|
|
||||||
|
#hack-indicator {
|
||||||
|
background-color: #FF8400;
|
||||||
|
}
|
||||||
|
|
||||||
|
#generate-indicator {
|
||||||
|
background-color: #36DB2B;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mode-input[type="radio"]:checked ~ .mode-icon .status-indicator {
|
||||||
|
transform: scale(1.1);
|
||||||
|
border-color: #fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
.name {
|
.name {
|
||||||
@@ -69,11 +252,92 @@
|
|||||||
max-width: calc(100% - 30px);
|
max-width: calc(100% - 30px);
|
||||||
overflow-wrap: break-word;
|
overflow-wrap: break-word;
|
||||||
word-break: break-word;
|
word-break: break-word;
|
||||||
|
user-select: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.checkbox-wrapper {
|
||||||
|
position: relative;
|
||||||
|
display: inline-block;
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
margin-left: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.checkbox {
|
.checkbox {
|
||||||
margin-left: auto;
|
opacity: 0;
|
||||||
transform: scale(1.15);
|
position: absolute;
|
||||||
|
width: 0;
|
||||||
|
height: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.custom-checkbox {
|
||||||
|
position: relative;
|
||||||
|
display: inline-block;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
border: 2px solid #ccc;
|
||||||
|
border-radius: 4px;
|
||||||
|
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 {
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
transform: translate(-50%, -50%) scale(0);
|
||||||
|
opacity: 0;
|
||||||
|
transition: transform 0.2s ease-out, opacity 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.checkbox:checked + .custom-checkbox {
|
||||||
|
border-color: #007bff;
|
||||||
|
background-color: #007bff;
|
||||||
|
transition: border-color 0.1s ease;
|
||||||
|
animation: checked-bounce 0.3s ease-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.checkbox-checked-generate:checked + .custom-checkbox {
|
||||||
|
border-color: #36DB2B;
|
||||||
|
background-color: #36DB2B;
|
||||||
|
}
|
||||||
|
|
||||||
|
.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 {
|
||||||
|
transform: translate(-50%, -50%) scale(1);
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes checked-bounce {
|
||||||
|
0% {
|
||||||
|
transform: scale(1);
|
||||||
|
}
|
||||||
|
50% {
|
||||||
|
transform: scale(0.8);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
transform: scale(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes unchecked-bounce {
|
||||||
|
0% {
|
||||||
|
transform: scale(1);
|
||||||
|
}
|
||||||
|
50% {
|
||||||
|
transform: scale(0.8);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
transform: scale(1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (prefers-color-scheme: dark) {
|
@media (prefers-color-scheme: dark) {
|
||||||
@@ -85,8 +349,22 @@
|
|||||||
background-color: #4D4D4D;
|
background-color: #4D4D4D;
|
||||||
}
|
}
|
||||||
|
|
||||||
.card:active,
|
.mode {
|
||||||
.update-card:active {
|
background-color: #343434;
|
||||||
background-color: #616161;
|
border: 1px solid #6E6E6E;
|
||||||
|
}
|
||||||
|
|
||||||
|
.install {
|
||||||
|
color: #eee;
|
||||||
|
background-color: #343434;
|
||||||
|
border: 1px solid #C2C2C2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.update-menu {
|
||||||
|
background-color: #343434;
|
||||||
|
}
|
||||||
|
|
||||||
|
.update-content a {
|
||||||
|
color: #C2C2C2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -42,15 +42,30 @@
|
|||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.input-box {
|
.boot-hash-value {
|
||||||
width: calc(100% - 20px);
|
width: 100%;
|
||||||
height: 100px;
|
height: 100px;
|
||||||
resize: none;
|
|
||||||
padding: 9px;
|
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
background-color: #FFF;
|
background-color: #FFF;
|
||||||
border: 1px solid #ccc;
|
border: 1px solid #ccc;
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.input-box {
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
padding: 10px;
|
||||||
|
font-size: 16px;
|
||||||
|
border-radius: 9px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
background-color: transparent;
|
||||||
|
outline-color: #007bff;
|
||||||
}
|
}
|
||||||
|
|
||||||
.button-container {
|
.button-container {
|
||||||
@@ -67,11 +82,9 @@
|
|||||||
background-color: #007bff;
|
background-color: #007bff;
|
||||||
color: white;
|
color: white;
|
||||||
margin-left: auto;
|
margin-left: auto;
|
||||||
transition: background-color 0.2s ease;
|
position: relative;
|
||||||
}
|
overflow: hidden;
|
||||||
|
user-select: none;
|
||||||
.boot-hash-save-button:active {
|
|
||||||
background-color: #003d80;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (prefers-color-scheme: dark) {
|
@media (prefers-color-scheme: dark) {
|
||||||
@@ -81,6 +94,9 @@
|
|||||||
|
|
||||||
.input-box {
|
.input-box {
|
||||||
color: #fff;
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.boot-hash-value {
|
||||||
background-color: #343434;
|
background-color: #343434;
|
||||||
border: 1px solid #6E6E6E;
|
border: 1px solid #6E6E6E;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,10 +12,10 @@ body {
|
|||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
position: fixed;
|
position: fixed;
|
||||||
bottom: -70px;
|
bottom: 50px;
|
||||||
left: 50%;
|
left: 50%;
|
||||||
transform: translateX(-50%);
|
transform: translateX(-50%);
|
||||||
z-index: 3;
|
z-index: 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
.floating-btn {
|
.floating-btn {
|
||||||
@@ -27,15 +27,14 @@ body {
|
|||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
opacity: 0;
|
||||||
padding: 10px 20px;
|
padding: 10px 20px;
|
||||||
font-size: 20px;
|
font-size: 20px;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
transition: transform 0.3s ease-in-out, background-color 0.2s ease;
|
transition: transform 0.6s cubic-bezier(0.22, 1, 0.36, 1);
|
||||||
border-radius: 50px 50px;
|
border-radius: 50px 50px;
|
||||||
}
|
overflow: hidden;
|
||||||
|
user-select: none;
|
||||||
.floating-btn:active {
|
|
||||||
background-color: #003d80;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.prompt {
|
.prompt {
|
||||||
@@ -52,49 +51,13 @@ body {
|
|||||||
width: auto;
|
width: auto;
|
||||||
max-width: calc(100% - 40px);
|
max-width: calc(100% - 40px);
|
||||||
transform: translateY(100%);
|
transform: translateY(100%);
|
||||||
transition: transform 0.5s ease;
|
transition: transform 0.4s cubic-bezier(0.22, 1, 0.36, 1);
|
||||||
}
|
|
||||||
|
|
||||||
.prompt.visible {
|
|
||||||
animation: YbounceIn 0.4s forwards;
|
|
||||||
}
|
|
||||||
|
|
||||||
.prompt.hidden {
|
|
||||||
animation: YbounceOut 0.4s forwards;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.prompt.error {
|
.prompt.error {
|
||||||
background-color: #f44336;
|
background-color: #f44336;
|
||||||
}
|
}
|
||||||
|
|
||||||
@keyframes YbounceIn {
|
|
||||||
0% {
|
|
||||||
transform: translateY(100%);
|
|
||||||
}
|
|
||||||
|
|
||||||
50% {
|
|
||||||
transform: translateY(-80%);
|
|
||||||
}
|
|
||||||
|
|
||||||
100% {
|
|
||||||
transform: translateY(-60%);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes YbounceOut {
|
|
||||||
0% {
|
|
||||||
transform: translateY(-60%);
|
|
||||||
}
|
|
||||||
|
|
||||||
50% {
|
|
||||||
transform: translateY(-80%);
|
|
||||||
}
|
|
||||||
|
|
||||||
100% {
|
|
||||||
transform: translateY(100%);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.loading {
|
.loading {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
top: 0;
|
top: 0;
|
||||||
@@ -132,11 +95,8 @@ body {
|
|||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
background-color: #CE0000;
|
background-color: #CE0000;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
transition: background-color 0.2s ease;
|
overflow: hidden;
|
||||||
}
|
user-select: none;
|
||||||
|
|
||||||
.uninstall-container:active {
|
|
||||||
background-color: #830000;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.uninstall-container i {
|
.uninstall-container i {
|
||||||
@@ -153,6 +113,26 @@ body {
|
|||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.ripple {
|
||||||
|
position: absolute;
|
||||||
|
border-radius: 50%;
|
||||||
|
transform: scale(0);
|
||||||
|
opacity: 1;
|
||||||
|
animation: ripple-animation ease-out forwards;
|
||||||
|
pointer-events: none;
|
||||||
|
background: rgba(0, 0, 0, 0.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.ripple.end {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes ripple-animation {
|
||||||
|
to {
|
||||||
|
transform: scale(3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@media (prefers-color-scheme: dark) {
|
@media (prefers-color-scheme: dark) {
|
||||||
body {
|
body {
|
||||||
background-color: #121212;
|
background-color: #121212;
|
||||||
|
|||||||
@@ -8,12 +8,13 @@
|
|||||||
width: calc(100% - 10px);
|
width: calc(100% - 10px);
|
||||||
max-width: 1100px;
|
max-width: 1100px;
|
||||||
background-color: #F5F5F5;
|
background-color: #F5F5F5;
|
||||||
transition: transform 0.3s ease;
|
transition: transform 0.4s cubic-bezier(0.22, 1, 0.36, 1);
|
||||||
z-index: 1100;
|
z-index: 1100;
|
||||||
margin-left: auto;
|
margin-left: auto;
|
||||||
margin-right: auto;
|
margin-right: auto;
|
||||||
left: 0;
|
left: 0;
|
||||||
right: 0;
|
right: 0;
|
||||||
|
user-select: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.header-block {
|
.header-block {
|
||||||
@@ -24,10 +25,11 @@
|
|||||||
left: 0;
|
left: 0;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
z-index: 1100;
|
z-index: 1100;
|
||||||
transition: transform 0.3s ease;
|
transition: transform 0.4s cubic-bezier(0.22, 1, 0.36, 1);
|
||||||
height: var(--window-inset-top);
|
height: var(--window-inset-top);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#module-version,
|
||||||
#title {
|
#title {
|
||||||
padding-left: 5px;
|
padding-left: 5px;
|
||||||
font-size: 16.5px;
|
font-size: 16.5px;
|
||||||
@@ -59,49 +61,62 @@
|
|||||||
|
|
||||||
.language-menu {
|
.language-menu {
|
||||||
display: flex;
|
display: flex;
|
||||||
padding: 3px 10px;
|
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
right: 0;
|
right: 0;
|
||||||
background-color: #fff;
|
background-color: white;
|
||||||
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
|
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
|
||||||
z-index: 1800;
|
z-index: 1800;
|
||||||
border: 1px solid #ccc;
|
border: 1px solid #ccc;
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
|
box-sizing: border-box;
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
visibility: hidden;
|
|
||||||
max-height: calc(100vh - 50px);
|
max-height: calc(100vh - 50px);
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
transform: translateY(-10px);
|
transform: translateY(-30px) scale(0);
|
||||||
transition: opacity 0.2s ease, transform 0.2s ease, visibility 0.2s ease;
|
transform-origin: top right;
|
||||||
|
transition: all 0.4s cubic-bezier(0.22, 1, 0.36, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
.language-menu.show {
|
.language-menu.show {
|
||||||
display: block;
|
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
visibility: visible;
|
transform: translateY(0) scale(1);
|
||||||
transform: translateY(0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.language-option {
|
.language-option {
|
||||||
padding: 8px 5px;
|
padding: 8px 10px;
|
||||||
text-align: left;
|
text-align: left;
|
||||||
background: none;
|
color: #333;
|
||||||
|
background-color: white;
|
||||||
border: none;
|
border: none;
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
color: #333;
|
|
||||||
width: 100%;
|
width: 100%;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
border-bottom: 1px solid #ccc;
|
position: relative;
|
||||||
transition: background-color 0.2s ease;
|
overflow: hidden;
|
||||||
|
user-select: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.language-option::after {
|
||||||
|
content: "";
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
|
left: 10px;
|
||||||
|
width: calc(100% - 20px);
|
||||||
|
height: 1px;
|
||||||
|
background-color: #ccc;
|
||||||
|
}
|
||||||
|
|
||||||
|
.language-option:last-child::after {
|
||||||
|
content: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.language-option:first-child {
|
||||||
|
padding-top: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.language-option:last-child {
|
.language-option:last-child {
|
||||||
border-bottom: none;
|
padding-bottom: 10px;
|
||||||
}
|
|
||||||
|
|
||||||
.language-option:active {
|
|
||||||
background-color: #C8C8C8;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.language-overlay {
|
.language-overlay {
|
||||||
@@ -134,7 +149,7 @@
|
|||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
transition: opacity 0.2s ease;
|
transition: opacity 0.4s cubic-bezier(0.22, 1, 0.36, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
.help-overlay.show {
|
.help-overlay.show {
|
||||||
@@ -175,6 +190,7 @@
|
|||||||
|
|
||||||
.help-content p {
|
.help-content p {
|
||||||
font-size: 26px;
|
font-size: 26px;
|
||||||
|
user-select: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.help-content ul {
|
.help-content ul {
|
||||||
@@ -208,7 +224,6 @@
|
|||||||
background-color: #121212;
|
background-color: #121212;
|
||||||
}
|
}
|
||||||
|
|
||||||
.language-option,
|
|
||||||
.help-button {
|
.help-button {
|
||||||
color: #fff;
|
color: #fff;
|
||||||
}
|
}
|
||||||
@@ -217,7 +232,9 @@
|
|||||||
fill: #eee;
|
fill: #eee;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.language-option,
|
||||||
.help-menu {
|
.help-menu {
|
||||||
|
color: #eee;
|
||||||
background-color: #343434;
|
background-color: #343434;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -226,11 +243,7 @@
|
|||||||
border: 1px solid #6E6E6E;
|
border: 1px solid #6E6E6E;
|
||||||
}
|
}
|
||||||
|
|
||||||
.language-option {
|
.language-option::after {
|
||||||
border-bottom: 1px solid #6E6E6E;
|
background-color: #6E6E6E;
|
||||||
}
|
|
||||||
|
|
||||||
.language-option:active {
|
|
||||||
background-color: #616161;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -6,7 +6,7 @@
|
|||||||
width: calc(100% - 20px);
|
width: calc(100% - 20px);
|
||||||
max-width: 1100px;
|
max-width: 1100px;
|
||||||
z-index: 1000;
|
z-index: 1000;
|
||||||
transition: transform 0.3s ease;
|
transition: transform 0.4s cubic-bezier(0.22, 1, 0.36, 1);
|
||||||
margin-left: auto;
|
margin-left: auto;
|
||||||
margin-right: auto;
|
margin-right: auto;
|
||||||
left: 0;
|
left: 0;
|
||||||
@@ -24,6 +24,7 @@
|
|||||||
height: calc(100% - 2px);
|
height: calc(100% - 2px);
|
||||||
width: calc(100% - 60px);
|
width: calc(100% - 60px);
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
.search-icon {
|
.search-icon {
|
||||||
@@ -67,7 +68,7 @@
|
|||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
#menu-button {
|
.menu-button {
|
||||||
background-color: white;
|
background-color: white;
|
||||||
border: 1px solid #ccc;
|
border: 1px solid #ccc;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
@@ -75,40 +76,42 @@
|
|||||||
width: 48px;
|
width: 48px;
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
z-index: 200;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
.menu-icon {
|
.menu-icon {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
fill: #000;
|
fill: #000;
|
||||||
transition: transform 0.2s ease;
|
transform: rotate(0deg);
|
||||||
|
transition: transform 0.4s cubic-bezier(0.22, 1, 0.36, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
.menu-icon.menu-open {
|
.menu-icon.menu-open {
|
||||||
transform: rotate(90deg);
|
transform: rotate(90deg);
|
||||||
}
|
}
|
||||||
|
|
||||||
.menu-icon.menu-closed {
|
|
||||||
transform: rotate(0deg);
|
|
||||||
}
|
|
||||||
|
|
||||||
.menu-options {
|
.menu-options {
|
||||||
background-color: white;
|
background-color: white;
|
||||||
border: 1px solid #ccc;
|
border: 1px solid #ccc;
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
|
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
|
||||||
display: none;
|
box-sizing: border-box;
|
||||||
|
display: flex;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
padding: 5px 12px;
|
|
||||||
top: 110%;
|
top: 110%;
|
||||||
right: 0;
|
right: 0;
|
||||||
z-index: 1200;
|
z-index: 1200;
|
||||||
transform: translateX(120%);
|
|
||||||
transition: transform 0.2s ease;
|
|
||||||
width: auto;
|
width: auto;
|
||||||
max-height: calc(100vh - 120px);
|
max-height: calc(100vh - 120px);
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
|
visibility: hidden;
|
||||||
|
transform: translateX(120%);
|
||||||
|
transition: all 0.4s cubic-bezier(0.22, 1, 0.36, 1);
|
||||||
|
user-select: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
#select-denylist {
|
#select-denylist {
|
||||||
@@ -117,13 +120,10 @@
|
|||||||
|
|
||||||
.menu-options.visible {
|
.menu-options.visible {
|
||||||
display: block;
|
display: block;
|
||||||
|
visibility: visible;
|
||||||
transform: translateX(0);
|
transform: translateX(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
.menu-options.hidden {
|
|
||||||
transform: translateX(140%);
|
|
||||||
}
|
|
||||||
|
|
||||||
.menu-options ul {
|
.menu-options ul {
|
||||||
list-style: none;
|
list-style: none;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
@@ -131,19 +131,33 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.menu-options li {
|
.menu-options li {
|
||||||
cursor: default;
|
padding: 12px 15px;
|
||||||
padding: 12px 4px;
|
|
||||||
text-align: left;
|
text-align: left;
|
||||||
border-bottom: 1px solid #ccc;
|
background-color: white;
|
||||||
transition: background-color 0.2s ease;
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
.menu-options li:active {
|
.menu-options li::after {
|
||||||
background-color: #C8C8C8;
|
content: "";
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
|
left: 15px;
|
||||||
|
width: calc(100% - 30px);
|
||||||
|
height: 1px;
|
||||||
|
background-color: #ccc;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-options li:last-child::after {
|
||||||
|
content: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-options li:first-child {
|
||||||
|
padding-top: 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.menu-options li:last-child {
|
.menu-options li:last-child {
|
||||||
border-bottom: none;
|
padding-bottom: 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.menu-overlay {
|
.menu-overlay {
|
||||||
@@ -153,7 +167,7 @@
|
|||||||
width: 100vw;
|
width: 100vw;
|
||||||
height: 100vh;
|
height: 100vh;
|
||||||
background-color: none;
|
background-color: none;
|
||||||
z-index: 1000;
|
z-index: 100;
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -182,10 +196,10 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.menu-options li {
|
.menu-options li {
|
||||||
border-bottom: 1px solid #6E6E6E;
|
background-color: #343434;
|
||||||
}
|
}
|
||||||
|
|
||||||
.menu-options li:active {
|
.menu-options li::after {
|
||||||
background-color: #616161;
|
background-color: #6E6E6E
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"versionCode": 290,
|
"versionCode": 330,
|
||||||
"version": "v2.9",
|
"version": "v3.3",
|
||||||
"zipUrl": "https://github.com/KOWX712/Tricky-Addon-Update-Target-List/releases/download/v2.9/TrickyAddonModule-v2.9.zip",
|
"zipUrl": "https://github.com/KOWX712/Tricky-Addon-Update-Target-List/releases/download/v3.3/TrickyAddonModule-v3.3.zip",
|
||||||
"changelog": "https://raw.githubusercontent.com/KOWX712/Tricky-Addon-Update-Target-List/main/changelog.md"
|
"changelog": "https://raw.githubusercontent.com/KOWX712/Tricky-Addon-Update-Target-List/main/changelog.md"
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user